docs: "Character of a Quantity" chapter added

This commit is contained in:
Mateusz Pusz
2023-07-08 13:13:40 +02:00
parent 3a94ca89fd
commit efb89c9f7b

View File

@@ -2,8 +2,8 @@
!!! warning !!! warning
Features described in this chapter are experimental and are subject to change or removal. Please This chapter's features are experimental and subject to change or removal. Please share your feedback
share your feedback if something doesn't seem right or could be improved. if something seems wrong or could be improved.
## Scalars, vectors, and tensors ## Scalars, vectors, and tensors
@@ -15,24 +15,24 @@
whereas each scalar component of a vector or a tensor and each component vector and component whereas each scalar component of a vector or a tensor and each component vector and component
tensor depend on that choice. tensor depend on that choice.
While defining quantities ISO 80000 explicitly mentions when a specific quantity has a vector or tensor Such distinction is important because each quantity character represents different properties
character. Such distinction is important because each quantity character represent different properties and allows different operations to be done on its quantities.
and allows different operations to be done on their quantities.
For example, imagine a physical units library that allows to create a `speed` quantity from both For example, imagine a physical units library that allows the creation of a `speed` quantity from both
`length / time` and `length * time`. It wouldn't be too safe to use such a product, right? `length / time` and `length * time`. It wouldn't be too safe to use such a product, right?
Now we have to realize that both of the above operations (multiplication and division) are even not Now we have to realize that both of the above operations (multiplication and division) are not even
mathematically defined for linear algebra types such as vector or tensors. On the other hand, two vectors mathematically defined for linear algebra types such as vectors or tensors. On the other hand, two vectors
can be passed as arguments to dot (`⋅`) and cross (`×`) product operations. The result of the first one is can be passed as arguments to dot and cross-product operations. The result of the first one is
a scalar. The second one results with a vector that is perpendicular to both vectors passed as arguments. a scalar. The second one results in a vector that is perpendicular to both vectors passed as arguments.
Again, it wouldn't be safe to allow replacing those two operations with each other or expect the same Again, it wouldn't be safe to allow replacing those two operations with each other or expect the same
results from both cases. This simply can't work. results from both cases. This simply can't work.
## Examples from the ISQ ## ISQ defines quantities of all characters
To provide some examples for further discussion let's pick a few quantities defined in the ISO 80000: While defining quantities ISO 80000 explicitly mentions when a specific quantity has a vector or tensor
character. Here are some examples:
| Quantity | Character | Quantity Equation | | Quantity | Character | Quantity Equation |
|------------------------|:------------:|:-------------------------------------------------:| |------------------------|:------------:|:-------------------------------------------------:|
@@ -55,17 +55,27 @@ To provide some examples for further discussion let's pick a few quantities defi
| `angular_momentum` | **vector** | `position_vector × momentum` | | `angular_momentum` | **vector** | `position_vector × momentum` |
| `moment_of_inertia` | **_tensor_** | `angular_momentum ⊗ angular_velocity` | | `moment_of_inertia` | **_tensor_** | `angular_momentum ⊗ angular_velocity` |
In the above equations:
- `a * b` - regular multiplication where one of the arguments has to be scalar
- `a / b` - regular division where the divisor has to be scalar
- `a ⋅ b` - dot product of two vectors
- `a × b` - cross product of two vectors
- `|a|` - magnitude of a vector
- `{unit-vector}` - a special vector with the magnitude of `1`
- `a ⊗ b` - tensor product of two vectors or tensors
!!! note !!! note
As of now, all of the C++ physical units libraries on the market besides **mp-units** do not As of now, all of the C++ physical units libraries on the market besides **mp-units** do not
support above-mentioned operations. They expose only multiplication and division operators which support the operations mentioned above. They expose only multiplication and division operators,
do not work for proper linear-algebra-based representation types. In case one would like to which do not work for linear algebra-based representation types. If a user of those libraries
construct the quantities provided in the above table with those libraries, this would result with would like to create the quantities provided in the above table properly, this would result in
a compile-time error stating that multiplication and division of two linear-algebra vectors is not a compile-time error stating that multiplication and division of two linear algebra vectors is
possible. impossible.
## Characters apply to quantities but not dimensions or units ## Characters don't apply to dimensions and units
ISO 80000 explicitly states that dimensions are orthogonal to quantity characters: ISO 80000 explicitly states that dimensions are orthogonal to quantity characters:
@@ -89,9 +99,17 @@ inline constexpr struct position_vector : quantity_spec<length, quantity_charact
inline constexpr struct displacement : quantity_spec<length, quantity_character::vector> {} displacement; inline constexpr struct displacement : quantity_spec<length, quantity_character::vector> {} displacement;
``` ```
From now on all the quantities derived from `position_vector` or `displacement` will have a correct With the above, all the quantities derived from `position_vector` or `displacement` will have a correct
character consistent with the operations performed in the [quantity equation](../../../appendix/glossary/#quantity-equation) character determined according to the kind of operations included in the
on their arguments. [quantity equation](../../../appendix/glossary/#quantity-equation) defining a
[derived quantity](../../../appendix/glossary/#derived-quantity).
For example, `velocity` in the below definition will be defined as a vector quantity (no explicit
character override is needed):
```cpp
inline constexpr struct velocity : quantity_spec<speed, position_vector / duration> {} velocity;
```
## Representation types for vector and tensor quantities ## Representation types for vector and tensor quantities
@@ -102,12 +120,14 @@ on their arguments.
a representation type for vector and tensor quantities. This is why users are on their own here a representation type for vector and tensor quantities. This is why users are on their own here
:worried:. :worried:.
To provide examples and implement unit tests our library uses the types proposed in the [P1385](https://wg21.link/p1385) To provide examples and implement unit tests, our library uses the types proposed in
and available as [a Conan package in the Conan Center](https://conan.io/center/wg21-linear_algebra). the [P1385](https://wg21.link/p1385) and available as
[a Conan package in the Conan Center](https://conan.io/center/wg21-linear_algebra).
However, thanks to the provided customization points, any linear algebra library types can be used
as a vector or tensor quantity representation type.
In order to enable the usage of a user-defined type as a representation type for vector or tensor To enable the usage of a user-defined type as a representation type for vector or tensor quantities,
quantities you need to provide a partial specialization of `is_vector` or `is_tensor` customization you need to provide a partial specialization of `is_vector` or `is_tensor` customization points.
points.
For example, here is how it can be done for the [P1385](https://wg21.link/p1385) types: For example, here is how it can be done for the [P1385](https://wg21.link/p1385) types:
@@ -123,12 +143,12 @@ inline constexpr bool mp_units::is_vector<la_vector> = true;
## Hacking the character ## Hacking the character
Sometimes you want to use a vector quantity but you do not care about its direction. For example, Sometimes you want to use a vector quantity, but you don't care about its direction. For example,
the standard gravity acceleration constant is always pointing down and you might not care about this the standard gravity acceleration constant always points down, so you might not care about this
in a particular case. In such a case you may want to "hack" the library to allow scalar types in a particular scenario. In such a case, you may want to "hack" the library to allow scalar types
to be used as a representation type for scalar quantities. to be used as a representation type for scalar quantities.
For example, you can do something like this: For example, you can do the following:
```cpp ```cpp
template<class T> template<class T>
@@ -136,7 +156,7 @@ template<class T>
inline constexpr bool mp_units::is_vector<T> = true; inline constexpr bool mp_units::is_vector<T> = true;
``` ```
which says that every type that can be used a scalar representation is also allowed for vector which says that every type that can be used as a scalar representation is also allowed for vector
quantities. quantities.
Doing the above is actually not such a big "hack" as the ISO 80000 explicitly allows it: Doing the above is actually not such a big "hack" as the ISO 80000 explicitly allows it:
@@ -146,13 +166,5 @@ Doing the above is actually not such a big "hack" as the ISO 80000 explicitly al
A vector is a tensor of the first order and a scalar is a tensor of order zero. A vector is a tensor of the first order and a scalar is a tensor of order zero.
However, for type-safety reasons, we do not want to allow of such a behavior by default. Despite it being allowed by ISO 80000, for type-safety reasons, we do not allow such a behavior
by default, and a user has to opt into such scenarios explicitly.
## Different shades of vector and tensor quantities
Instead of treating each coordinate of a vector as a physical quantity value (i.e. a number multiplied by
a unit), the vector could be written as a numerical vector multiplied by a unit.
The same considerations apply to tensors of second and higher orders.