diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index c7410441..efbcaf94 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -89,6 +89,7 @@ set(unitsSphinxDocs "${CMAKE_CURRENT_SOURCE_DIR}/faq.rst" "${CMAKE_CURRENT_SOURCE_DIR}/framework.rst" + "${CMAKE_CURRENT_SOURCE_DIR}/framework/arithmetics.rst" "${CMAKE_CURRENT_SOURCE_DIR}/framework/basic_concepts.rst" "${CMAKE_CURRENT_SOURCE_DIR}/framework/constants.rst" "${CMAKE_CURRENT_SOURCE_DIR}/framework/conversions_and_casting.rst" diff --git a/docs/framework.rst b/docs/framework.rst index 494f7150..ba17d2e2 100644 --- a/docs/framework.rst +++ b/docs/framework.rst @@ -17,6 +17,7 @@ Framework Basics framework/quantity_kinds framework/dimensions framework/units + framework/arithmetics framework/constants framework/conversions_and_casting framework/text_output diff --git a/docs/framework/arithmetics.rst b/docs/framework/arithmetics.rst new file mode 100644 index 00000000..22030a10 --- /dev/null +++ b/docs/framework/arithmetics.rst @@ -0,0 +1,148 @@ +.. namespace:: units + +Arithmetics +=========== + +Quantities +---------- + +Quantities of the same dimension can be easily added or subtracted with +each other and the result will always be a quantity of the same dimension: + +.. code-block:: + :emphasize-lines: 3-4 + + Length auto dist1 = 2 * m; + Length auto dist2 = 1 * m; + Length auto res1 = dist1 + dist2; + Length auto res2 = dist1 - dist2; + +Additionally, we can always multiply or divide a quantity by a +:term:`scalable number` and in such a case the quantity's dimension will also +not change: + +.. code-block:: + :emphasize-lines: 2-4 + + Length auto dist = 2 * m; + Length auto res1 = dist * 2; // 4 m + Length auto res2 = 3 * res1; // 12 m + Length auto res3 = res2 / 2; // 6 m + +However, if we try to multiply or divide quantities of the same or +different dimensions, or we will divide a scalable number by a quantity, we most +probably will always end up in a quantity of a yet another dimension: + +.. code-block:: + :emphasize-lines: 4-6 + + Length auto dist1 = 2 * m; + Length auto dist2 = 3 * m; + Time auto dur1 = 2 * s; + Area auto res1 = dist1 * dist2; // 6 m² + Speed auto res2 = dist1 / dur1; // 1 m/s + Frequency auto res3 = 10 / dur1; // 5 Hz + +However, please note that there is an exception from the above rule. +In case we divide the same dimensions, or multiply by the inverted +dimension, than we will end up with just a dimensionless quantity: + +.. code-block:: + :emphasize-lines: 4-5 + + Time auto dur1 = 10 * s; + Time auto dur2 = 2 * s; + Frequency auto fr1 = 5 * Hz; + Dimensionless auto v1 = dur1 / dur2; // quantity(5) + Dimensionless auto v2 = dur1 * fr1; // quantity(50) + +Quantity Kinds +-------------- + +Quantity kinds behave the same as quantities for all operations, +except that the quantity types in the operators' declarations +are quantity kind types instead. +Additionally, for the dimensional analysis operators, +you can use a quantity argument instead of a quantity kind. + +.. code-block:: + :emphasize-lines: 8-9 + + struct height_kind : kind {}; + struct rate_of_climb_kind : derived_kind {}; + + template using height = quantity_kind; + template using rate_of_climb = quantity_kind; + + height h{100 * m}; + rate_of_climb rate = h / (25 * s); + // quantity_kind(4 * m / s) + +.. code-block:: + :emphasize-lines: 8-12 + + struct width_kind : kind {}; + struct horizontal_area_kind : derived_kind {}; + + template using width = quantity_kind; + template using horizontal_area = quantity_kind; + + width w{5 * m}; + horizontal_area area1 = w * w; + // quantity_kind(25 * m * m) + width w2 = area1 / w; // quantity_kind(5 * m) + auto q1 = w / w; // Dimensionless quantity kinds related to width + auto q2 = w / (5 * m); // with .common() equal to quantity{1} + +Quantity Points +--------------- + +Quantity points have a more restricted set of operations. +Quantity can be added to or subtracted +from a quantity point of the same origin. +The result will always be a quantity point of the same origin: + +.. code-block:: + :emphasize-lines: 3-5 + + Length auto dist1 = 2 * m; + Length auto dist2 = 1 * m; + QuantityPoint auto res1 = quantity_point{dist1} + dist2; + QuantityPoint auto res2 = dist1 + quantity_point{dist2}; + QuantityPoint auto res3 = quantity_point{dist1} - dist2; + +We can also subtract two quantity points. +The result is a relative quantity of the same dimension: + +.. code-block:: + :emphasize-lines: 3 + + Length auto dist1 = 2 * m; + Length auto dist2 = 1 * m; + Length auto res1 = quantity_point{dist1} - quantity_point{dist2}; + +.. note:: + + It is not allowed to: + + - add quantity points, + - subtract a quantity point from a quantity, + - multiply nor divide quantity points with anything else, and + - mix quantity points with different origins: + + .. code-block:: + :emphasize-lines: 3-5 + + Length auto dist1 = 2 * m; + Length auto dist2 = 1 * m; + auto res1 = quantity_point{dist1} + quantity_point{dist2}; // ERROR + auto res2 = dist1 - quantity_point{dist2}; // ERROR + auto res3 = quantity_point{dist1} / (2 * s); // ERROR + auto res4 = quantity_point{std::chrono::utc_second{1s}} + + quantity_point{std::chrono::sys_second{1s}}; // ERROR + +Quantity Point Kinds +-------------------- + +The same restrictions of a quantity point with respect to its quantity +apply to a quantity point kind with respect to its quantity kind. diff --git a/docs/framework/dimensions.rst b/docs/framework/dimensions.rst index 4a8ab10a..9a01044f 100644 --- a/docs/framework/dimensions.rst +++ b/docs/framework/dimensions.rst @@ -8,154 +8,6 @@ In the previous chapter we briefly introduced the notion of a physical Length, time, speed, area, energy are only a few examples of physical dimensions. -Arithmetics ------------ - -Quantities -++++++++++ - -Quantities of the same dimension can be easily added or subtracted with -each other and the result will always be a quantity of the same dimension: - -.. code-block:: - :emphasize-lines: 3-4 - - Length auto dist1 = 2 * m; - Length auto dist2 = 1 * m; - Length auto res1 = dist1 + dist2; - Length auto res2 = dist1 - dist2; - -Additionally, we can always multiply or divide a quantity by a -:term:`scalable number` and in such a case the quantity's dimension will also -not change: - -.. code-block:: - :emphasize-lines: 2-4 - - Length auto dist = 2 * m; - Length auto res1 = dist * 2; // 4 m - Length auto res2 = 3 * res1; // 12 m - Length auto res3 = res2 / 2; // 6 m - -However, if we try to multiply or divide quantities of the same or -different dimensions, or we will divide a scalable number by a quantity, we most -probably will always end up in a quantity of a yet another dimension: - -.. code-block:: - :emphasize-lines: 4-6 - - Length auto dist1 = 2 * m; - Length auto dist2 = 3 * m; - Time auto dur1 = 2 * s; - Area auto res1 = dist1 * dist2; // 6 m² - Speed auto res2 = dist1 / dur1; // 1 m/s - Frequency auto res3 = 10 / dur1; // 5 Hz - -However, please note that there is an exception from the above rule. -In case we divide the same dimensions, or multiply by the inverted -dimension, than we will end up with just a dimensionless quantity: - -.. code-block:: - :emphasize-lines: 4-5 - - Time auto dur1 = 10 * s; - Time auto dur2 = 2 * s; - Frequency auto fr1 = 5 * Hz; - Dimensionless auto v1 = dur1 / dur2; // quantity(5) - Dimensionless auto v2 = dur1 * fr1; // quantity(50) - -Quantity Kinds -++++++++++++++ - -Quantity kinds behave the same as quantities for all operations, -except that the quantity types in the operators' declarations -are quantity kind types instead. -Additionally, for the dimensional analysis operators, -you can use a quantity argument instead of a quantity kind. - -.. code-block:: - :emphasize-lines: 8-9 - - struct height_kind : kind {}; - struct rate_of_climb_kind : derived_kind {}; - - template using height = quantity_kind; - template using rate_of_climb = quantity_kind; - - height h{100 * m}; - rate_of_climb rate = h / (25 * s); - // quantity_kind(4 * m / s) - -.. code-block:: - :emphasize-lines: 8-12 - - struct width_kind : kind {}; - struct horizontal_area_kind : derived_kind {}; - - template using width = quantity_kind; - template using horizontal_area = quantity_kind; - - width w{5 * m}; - horizontal_area area1 = w * w; - // quantity_kind(25 * m * m) - width w2 = area1 / w; // quantity_kind(5 * m) - auto q1 = w / w; // Dimensionless quantity kinds related to width - auto q2 = w / (5 * m); // with .common() equal to quantity{1} - -Quantity Points -+++++++++++++++ - -Quantity points have a more restricted set of operations. -Quantity can be added to or subtracted -from a quantity point of the same origin. -The result will always be a quantity point of the same origin: - -.. code-block:: - :emphasize-lines: 3-5 - - Length auto dist1 = 2 * m; - Length auto dist2 = 1 * m; - QuantityPoint auto res1 = quantity_point{dist1} + dist2; - QuantityPoint auto res2 = dist1 + quantity_point{dist2}; - QuantityPoint auto res3 = quantity_point{dist1} - dist2; - -We can also subtract two quantity points. -The result is a relative quantity of the same dimension: - -.. code-block:: - :emphasize-lines: 3 - - Length auto dist1 = 2 * m; - Length auto dist2 = 1 * m; - Length auto res1 = quantity_point{dist1} - quantity_point{dist2}; - -.. note:: - - It is not allowed to: - - - add quantity points, - - subtract a quantity point from a quantity, - - multiply nor divide quantity points with anything else, and - - mix quantity points with different origins: - - .. code-block:: - :emphasize-lines: 3-5 - - Length auto dist1 = 2 * m; - Length auto dist2 = 1 * m; - auto res1 = quantity_point{dist1} + quantity_point{dist2}; // ERROR - auto res2 = dist1 - quantity_point{dist2}; // ERROR - auto res3 = quantity_point{dist1} / (2 * s); // ERROR - auto res4 = quantity_point{std::chrono::utc_second{1s}} + - quantity_point{std::chrono::sys_second{1s}}; // ERROR - -Quantity Point Kinds -++++++++++++++++++++ - -The same restrictions of a quantity point with respect to its quantity -apply to a quantity point kind with respect to its quantity kind. - - Base Dimensions ---------------