-
Notifications
You must be signed in to change notification settings - Fork 97
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
Distinguishing affine and vector quantities #289
Comments
My initial thoughts are that this should be a higher level than Thermodynamic temperature/temperature interval is another case similar to dates/durations and Lines 479 to 497 in 66a0546
Do you see use for affine/vector quantities beyond length? Are there cases in your simulation where |
I think that there are two separate concerns here, which both use the word 'vector', with different meanings, and we should be careful not to confuse:
Temperature difference and duration, both form vector rather than affine spaces, but those spaces have only 1 dimension, and hence are scalars rather than vectors: vector not affine, but scalar not vector! I don't think that the N-D stuff belongs in The difference between absolute time and duration seems obvious to everyone, because you don't need to be a scientist to be aware, at least implicitly, that 2:45 pm + 1:25 am makes no sense, while 2:45 pm + 1h25m and 2h45m + 1h25m both do make sense. Some of our natural languages distinguish between them, which helps with the intuition: "3 o' clock" vs "3 hours"; "3 Uhr" vs "3 Stunden". The difference between thermodynamic temperature and temperature interval seems to be the next most obvious thing. It feels right to me that it should, but I can't quite put my finger on the reason why. Oddly enough, I suspect that if you start being sufficiently pedantic (or precise or careful) about units, the distinction between absolute and relative quantities will emerge everywhere, not just in a small selection of quantities.
If you are talking about the N-D aspect, no. If you are talking about the relative-absolute aspect, yes.
In this particular part of our code I care predominantly about time and space, so these examples are most obvious to me. But there are other parts of the code (which I haven't looked at yet) where we will have to deal with charges a voltages. Voltages strike me as something else that will obviously benefit from the affine-absolute vs vector-relative distinction: any quantity which has 'potential' in its name (gravitational potential) is begging for this distinction! The part of the code that has to deal with the charges is really not my area, but I imagine that it might be useful to have the type system distinguish absolute charges from differences between absolute charges. In brief, I suspect that having an absolute version and a relative version of any quantity, would make sense.
Yes, I came across Is the design or structure of
Reiterating what I said at the top: it looks like this statement mixes two orthogonal concerns: vector-vs-scalar and vector-vs-affine, in other words dimensionality and relative-vs-absolute. I don't think that the dimensionality aspect is |
One problem I see for expressing the absolute/relative distinction at the type level is that having numerical values for absolute values requires a choice of origin as the numeric values are always based on the vector space elements via the free and transitive action of it on the point set. For example, there are multiple absolute temperature scales based on the absolute zero, the triple point of water or the average human body temperature. Similarly, our dates are basically durations w.r.t. a certain calendar of which multiple are in use. So tracking absolutes in the type system would also require tracking the references in the type system which seems feasible when a few "official" ones exist but would require dependent types AFAIU for arbitrary references like the detector geometry of an experimental setup. |
Which is why I was hoping that the BTW, I ended up asking the same question on the Rust forum, and this reply makes a similar point. I wonder whether there's a perfect-is-enemy-of-good effect here. Isn't it better to have protection against confusing relative for absolute (even if it comes without protection against confusing different absolutes), than having no such protection at all? Do we lose anything by adding this incomplete solution? Does adding this protection remove some pre-existing protection? In the case where an official absolute already exists (such as thermodynamic temperature) perhaps we do. In the case of thermodynamic temperature, there is an objective origin. There can't be many other absolute quantities for which this is the case (none come to mind immediately [edit: there are plenty: mass, amount of substance, resistance, conductivity ... in fact, I'd now say these are in the majority!]), which probably explains why thermodynamic temperature is the only absolute quantity implemented in But maybe I'm overlooking some details which make it impossible to implement an absolute at all, without making a choice of origin, i.e. your original point. Can
Hmm. |
I've been thinking about this more the last couple days. My initial thinking was to just add an My next thought is to add trait bounds, similar to how type Output = Quantity<
$quantities<$($crate::typenum::$AddSubAlias<Dl::$symbol, Dr::$symbol>,)+, $MulDivAlias<Dl::Kind, Dr::Kind>>,
Ul, V>; My next thought is that overloading kind is not the appropriate method and there should instead be Another thought would be to add an additional sibling type parameter next to @jacg Do you have any kind of intuitive sense at this point the right point to add this abstraction? I think I need to spend more time studying the subject which may take a while given the limited time I'm able to dedicate to Current code: Lines 466 to 491 in 66a0546
|
I'm afraid that I'm not yet sufficiently familiar with the structure of |
@jacg I'll start with that avenue of investigation when I eventually get to this! |
This comment has helped me focus my thoughts. In summary, I believe that every quantity should have a vector and an affine version. They should admit different operations. Using the shorthand
vector quantities should allow
while for affine quantities we have
Additionally, as discussed in #403, both affine and vector quantities should support Note that
Additionally
The closure property of the vector operations is important, because it means that the vector side of things is self-contained: you can continue using it and completely ignore the existence of affines, which is useful in the two cases listed just above. On the other hand, in situations where you care about the affine/vector distinction, you can opt into using the affine machinery. Put another way,
need not interfere with any of the already existing The notable exception is We shouldn't forget @adamreichold's pertinent comment about the choice of origin in affine quantities. Ideally the affine side would support distinct choices of origin, and either prevent mixing of affine quantities with different origins, or automatically convert between them. This ties in with the |
I'd be a huge fan of an implementation of @jacg's vector and affine quantities. |
Edit: I am now pretty much convinced that there should be an affine and a vector version of every
Quantity
, as described in this comment further down in the thread.I'm not sure if this is an appropriate place to ask this question. If not, I apologize and do feel free to close the issue.
In trying to use
uom
to get the Rust type system to help me understand my simulation code better and to reduce the bugs in it, I'm wondering to what extent I should distinguish between 3D Points and 3D Vectors. For examplePoint - Point
should giveVector
Point + Point
should not be allowedVector - Vector
should giveVector
Vector + Vector
should giveVector
Point + Vector
should givePoint
Scalar * Vector
should giveVector
Scalar * Point
should not be allowedand I'd like the type system to be aware of it. This can be done without much trouble (beyond verbosity) by defining separate
Vector
andPoint
types and implementing the relevantstd::ops
traits accordingly.But it's not clear to me whether these
Vector
s andPoint
s should have the sameuom
types representing their components: should the above rules apply to the components ofPoint
andVector
at the type level, too? For example, shouldpoint.x
be some affine version ofLength
,point1.x - point2.x
return some vector version ofLength
,point1.x + point2.x
be disallowed by the type system,Length
s?This, in turn, makes me wonder about the distinction when it comes to other scalar quantities that appear in my code, and that leads me to wonder more generally about the distinction of affine and vector quantities in physical units.
It seems that the distinction has been recognized as important by the software development community in the context of dates and times: most languages' date/time libraries distinguish between (affine) dates, and (vector) durations, tough they don't use the affine/vector nomenclature explicitly.
But I don't see any evidence of this distinction being used much in scientific code.
Do you have any thoughts or relevant experience? Would it be worthwhile to explain these differences to the type system? Would it be more trouble than it is worth? How would it fit in with
uom
?The text was updated successfully, but these errors were encountered: