-
Notifications
You must be signed in to change notification settings - Fork 88
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Operations on vector quantities #646
Comments
The first signature still looks good. |
Well, we could argue if that is a valid formula. In the link you provided, it is explicitly stated that But yes, we could implement this as well as: constexpr QuantityOf<isq::speed> auto avg_speed(QuantityOf<isq::length> auto d,
QuantityOf<isq::time> auto t)
{
return quantity_cast<norm(isq::displacement)>(d) / t;
} This makes it easy to use but less correct in the physical sense. |
I would like to mention that without introducing |
We also probably should refactor our tree of quantities of kind length to something like: flowchart TD
length["<b>length</b><br>[m]"]
length --- width["<b>width</b> / <b>breadth</b>"]
length --- height["<b>height</b> / <b>depth</b> / <b>altitude</b>"]
width --- thickness["<b>thickness</b>"]
width --- diameter["<b>diameter</b>"]
width --- radius["<b>radius</b>"]
radius --- radius_of_curvature["<b>radius_of_curvature</b>"]
length --- path_length["<b>path_length</b>"]
path_length --- distance["<b>distance</b>"]
distance --- displacement["<b>displacement</b><br>{vector}"]
distance --- radial_distance["<b>radial_distance</b>"]
radial_distance --- position_vector["<b>position_vector</b><br>{vector}"]
length --- wavelength["<b>wavelength</b>"]
The primary changes are:
|
Perhaps each vectorial quantity should be named '..._vector'. |
We can't rename ISQ quantities. Their names are standardized. A user can always provide an alternative name with: constexpr auto velocity_vector = velocity; Also, a helper for constexpr auto displ_norm = norm(isq::displacement); With the above the avg_speed(displ_norm(distance), time); |
Looking at the tree above and discussing the problem with automotive experts in the ISO C++ Committee who know mp-units really well already, we decided to redefine inline constexpr velocity final : quantity_spec<displacement / duration> {} velocity;
inline constexpr speed final : quantity_spec<path_length / duration> {} speed; It is inconsistent with ISQ but is more correct and useful. As a result, we still have to To summarize, our new constexpr QuantityOf<isq::speed> auto avg_speed(QuantityOf<isq::path_length> auto d,
QuantityOf<isq::duration> auto t)
{
return d / t;
}
|
Now the question is, does passing a Despite
Maybe it should not be in the same but parallel branch to Any thoughts... |
What exactly does the arrow in the tree represent? |
Yes, it means exactly that. Separate tree is not an option. Displacement and position vector are still quantities of length and they are measured in metres. I considered putting them in a separate branch (this is exactly what we have until 2.4.0) but I think it's wrong as well. There are at least two reasons for that:
|
How about: constexpr auto distance_traveled = norm(isq::displacement);
constexpr QuantityOf<isq::speed> auto avg_speed(QuantityOf<distance_traveled> auto d, QuantityOf<isq::time> auto t)
{
return d / t;
} ? We can also consider adding |
The term 'distance_traveled' reminds me a lot of 'path_length'. Can we delete the old 'path_length' and introduce a new 'path_length' as a specialization of 'displacement'? I think I remain confused by "Specialization can change the 'character'". |
Let's describe the elements in the branch here:
A magnitude/norm of
|
Just a side note as it has been mentioned twice already: taking the norm of a position vector should / can not be a valid operation. You can only take the norm of a displacement vector not of a single point / position vector. |
@dwith-ts, thanks for feedback. I was not aware of this. This complicates things a bit, but I think I know how to make it work. Do you also suggest that we limit |
Many thanks for the patient discussion. |
@dwith-ts, is this true even for polar or spherical coordinate systems? I thought that the norm of a position vector would be a radial distance in such cases. |
|
Well, with both Cartesian and polar / spherical coordinate systems you could decide to use a position vector interchangeably with its displacement from the origin, then allowing the norm operation could be justified. However, in math terms a norm is always defined on a vector space and the definition of such a vector space contains (mathematical) points and vectors. The norm operation can then be applied only to such vectors and is independent of the chosen origin. I don’t know all the library details so I can’t say much about whether a
And now the question is which of the combinations should be allowed / are meaningful:
I hope I got the library-related terminology right, if not feel free to clarify. |
Is this definition from an ISO draft? |
No, I just improvised a bit 😉 The actual definitions are:
|
@dwith-ts, I am afraid that, according to the above definitions, we can't disallow taking the magnitude of a position vector. |
I am unsure if I agree with that. If I drive a car that has a speed-o-meter and some G-sensors, I can make a measurement/readout from those instruments. I think that it is OK to model this with a
According to the ISQ, |
Yes, you raise an excellent point here: In the most general form, we would need what is called a 3-frame notation to describe the full problem (https://rpg.ifi.uzh.ch/docs/teaching/2024/FurgaleTutorial.pdf, not sure if I already linked that). The 3 frames indicate
Now your example correctly points out that we cannot add the velocity of frame C (your car in the example) relative to the earth at time t_1 to the velocity of the same frame at time t_2, even if they are expressed in the same basis vectors. However, we can add the velocity of frame D (a second car) relative to frame C (the first car) to the velocity of frame C relative to the earth which would give us the velocity of frame D relative to the earth (this only works if both use the same basis vectors for the representation). Now we could make the same point for displacement vectors: it is also not very meaningful to add the displacement between points / frames C and D to the displacement between A and B. This addition is only meaningful if we would add the displacement of C relative to B and the displacement of B relative to A which gives us the displacement of C relative to A (again assuming that the unmentioned 3rd frame describing the basis vectors is identical). So both velocities and displacement have a similar issue here that they cannot be added in the general case, only in special cases. However, it seems that this distinction is more obvious and better known for velocities than for displacements. So what does this help us? I think that we most likely will have to make certain approximations / simplifications of the full problem space, the only question is which simplification exactly. What I have done in my library:
|
Is ISO here maybe putting the distinction between
where the ones marked with * don't seem meaningful to me because they are somehow self-contradictory. |
In the entire ISO/IEC 80000 series that defines ISQ, you will not find any mention of the affine space abstractions, points, or deltas. I mentioned it even in the blog post. Also, as mentioned in #647, even if we can sense some point/delta properties they are they by accident and are inconsistent.
This is exactly why I ask if we should limit:
Then, it should be clearer. I am right now working to allow the following happen automatically: quantity_point<isq::position_vector[m]> qp1(100 * m);
quantity_point<isq::position_vector[m]> qp2(50 * m);
auto q = qp1 - qp2; // results with quantity<isq::displacement[m]> The same would work for Please note that as of today, also the following would work: quantity<isq::position_vector[m]> q1(100 * m);
quantity<isq::position_vector[m]> q2(50 * m);
auto q = q1 - q2; // results with quantity<isq::displacement[m]> but as you wrote already, it contradicts itself. Also, using However, as I wrote in #646:
|
The limiting suggestion you made is still a bit different from what I'd imagine ideally. For a clean-sheet design I'd go with either something like inversing the relation by using We could use aliases for both
This also has the advantage that we can do the exact same thing for velocity vectors with
Is this something that has some fundamental contradiction to ISO or could this be used? If all of the above is not possible, then I'd say the option you outlined (restricting what can be put inside quantity / quantity_point) is something worth considering as it is slightly better that what is currently implemented in the library. On the other hand, this could also be a source of confusion for users as it makes usage a bit more difficult. |
With such a design, we have several issues:
|
Yes, if ISO/IEC 80000 would be aware of affine spaces as a primary design construct, we could use: using displacement = quantity<m, vector<3, double>>;
using position_vector = quantity_point<m, default_point_origin(kind_of<isq::length>), vector<3, double>>; or using displacement = quantity<isq::displacement[m], vector<3, double>>;
using position_vector = quantity_point<isq::position_vector[m], default_point_origin(isq::position_vector), vector<3, double>>; Yes, I know, the second line in both cases is inconvenient to type for a custom type 😢 |
We do it now as follows: using velocity = quantity<m / s, vector<3, double>>;
using position_vector = quantity_point<m / s, default_point_origin(kind_of<isq::length / isq::time>), vector<3, double>>; or using velocity = quantity<isq::velocity[m/s], vector<3, double>>;
using position_vector = quantity_point<isq::velocity[m/s], default_point_origin(isq::velocity), vector<3, double>>; So this is also compatible in both cases. |
No contradictions. It is exactly how it may be used now. My question is if we should prevent creating clearly "point-like" ISQ quantity types (e.g., |
Not the main point of this thread (still reviewing the rest) but one question I had while looking at the first example in the original post: why are we spelling this function |
That is a very good question. For now,
Does anyone have a good overview of LA libraries on the market? Which one is the most common for vectors? We want to use whatever is the most popular to enable generic programming. Anyway, our CPO accounts for the most common options already: mp-units/src/core/include/mp-units/framework/customization_points.h Lines 115 to 129 in bda1124
|
I am in the process of improving the support for vector quantities. We have had many simplifications and errors in this subject so far, and we should try to improve here. The question here is how strict we should be.
Let's see the following example.
We were defining
speed
andvelocity
aswhich was a simplification, wrong, and inconsistent with ISQ definitions. ISQ defines them in the following way:
Well,
velocity
is actually defined in terms ofdelta position_vector
, but that is adisplacement
and should be fixed in our definitions.Note that
speed
andvelocity
are not in the same tree, and the real definition order (dependency) is reversed to what we had before.Moreover, our flagship example for many years looked like this:
This is a simplification as
length
does not necessarily have to describe a displacement. What kind of speed will I get by dividing the height of the building by time? The building does not move or change its height. But this is how we are used to do it in the engineering.Of course, if I drop a rock from the top of the roof and observe it falling down, I may use the height of this building to measure the displacement of the rock on its way down.
Also, a
displacement
is a vector quantity and should be described by the vector representation type. However, when we want to getspeed
and notvelocity,
we should not care.To summarize, a proper function template should look like:
and we should call it with:
The question is, is that not too much? Does requiring a
quantity_cast
to anorm(displacement)
not sacrifice usability for physical safety/correctness too much? What can we do to improve that?The text was updated successfully, but these errors were encountered: