Any interest in dimensional analysis for orientational dimensions and Euclidean vectors?

Just in case any one is curious, a euclidean vector is represented by its Cartesian coordinates: (*p*0, *p*1,..., *p*d - 1) (in a d-dimensional vectorial space). It can be defined by the difference between two points (Locations), A and B: if A has coordinates (*a*0, *a*1,..., *a*d - 1) and B (*b*0, *b*1,..., *b*d - 1), then vector [image: $ \bf AB$] = *B* - *A* has coordinates (*b*0 - *a*0, *b*1 - *a*1,..., *b*d - 1 - *a*d - 1). The requirements of Euclidean Vector are very similar to those of Location, and could actually have been represented by a Location. However, an euclidean vector is very different from a point, or location, (from a mathematical point of view) and it would have been confusing to represent these two entities by the same *concept*. Yes, I'd be interested. Looking forward to reviewing your library. I'm not shur that I have any comments right now other than to say that it would be a great addition.

Tom Brinkman schrieb:
Just in case any one is curious, a euclidean vector is represented by its Cartesian coordinates: (*p*0, *p*1,..., *p*d - 1) (in a d-dimensional vectorial space). [Snip] However, an euclidean vector is very different from a point, or location, (from a mathematical point of view) and it would have been confusing to represent these two entities by the same *concept*.
Thanks for the feedback. Yes, at the end of the day we're talking about Cartesian products here. The naming is rather ad hoc and certainly needs to be tune. I'm particular uncomfortable with the current use of the term dimension. It is actually a quantity in terms of dimensional analysis, an what DA calls a dimension is here just an unsigned integer. So, thinking about it, using the names cartesian::coord; cartesian::point; rather then dimensions and vectors might not be a bad choice either; The name space would make clear that other representations like polar coordinates are not included. On the other hand, a point is not a very interesting object. For example, can points be added or multiplied with a scalar? Strictly speaking, that makes sense only for distances, i.e. vectors. You're right, there is a difference between points and vectors. A point, for example, has a dimension of zero, while a vector has always a dimension of one, regardless what the dimension of the vector space is. (So when talking about a three-dimensional vector, we're actually talking about a one-dimensional object in a three-dimensional space.) But this distinction is hardly ever made in mathematics, unless in introductions and maybe in very special discussions. Typically a point and it's position vector are treated synonymously, so I wonder if we really need to make the distinction here? We could cleanly separate both concepts, like: namespace cartesian { template<typename T, unsigned int D> coord; // was dim template<typename T, unsigned int D> point; // was vec // point now without vector operations }; namespace euclid { template<typename T, unsigned int D> vector { cartesian::point<T,D> point; public: // vector operations go in here }; }; maybe with implicit conversion between points and vectors. Looks charming but a bit like an overkill to me. What do you think? Best regards, Andreas

On the other hand, a point is not a very interesting object. For example, can points be added or multiplied with a scalar? Strictly speaking, that makes sense only for distances, i.e. vectors.
You're right, there is a difference between points and vectors. A point, for example, has a dimension of zero, while a vector has always a dimension of one, regardless what the dimension of the vector space is. (So when talking about a three-dimensional vector, we're actually talking about a one-dimensional object in a three-dimensional space.) But this distinction is hardly ever made in mathematics, unless in introductions and maybe in very special discussions. Typically a point and it's position vector are treated synonymously, so I wonder if we really need to make the distinction here? We could cleanly separate both
This issue also arises in the context of unit conversions. A salient example is the case of converting between temperatures in Fahrenheit and those in Kelvin : How do we convert 32 degrees Fahrenheit to Kelvin? If we are talking about absolute temperatures (points), then the correct expression is Absolute temperature (K) = (Absolute temperature (F) - 32)*5/9 +273.15 However, if we're talking about temperature differences (vectors), then the correct expression is Temperature difference (K) = Temperature difference (F)*5/9 The same issue arises in times (time point vs. time difference). It is unfortunately very difficult to come up with a completely generic solution to this problem - you can define an algebra that behaves sensibly on points and vectors, which for many applications will be fine. This sort of value type will also work with our units library. However, in order to correctly implement conversions, the unit and the value type become entangled. It is possible to do this by specializing the quantity conversion helper, but requires separate specializations for each unit having affine conversion factors (demo coming). Matthias

Here's some code demonstrating point and vector quantity conversions for Fahrenheit->Kelvin (unit_example_20.cpp). This code works correctly and is included in the most recent release of mcs::units in the Vault (mcs_units_v0.7.0_alpha_7)... The point<> and vector<> classes are toys for demo purposes only. quantity<fahrenheit::temperature,point<> > T1p(point<>(32) *fahrenheit::degrees); quantity<fahrenheit::temperature,vector<> > T1v(vector<>(32) *fahrenheit::degrees); quantity<SI::temperature,point<> > T2p(T1p); quantity<SI::temperature,vector<> > T2v(T1v); std::cout << T1p << std::endl << T2p << std::endl << T1v << std::endl << T2v << std::endl << std::endl; Outputting : { 32 } F { 273.16 } K [ 32 ] F [ 17.7778 ] K The main shenanigans happen in the specialization for conversion_helper to point and vector quantities of temperatures... Matthias ---------------------------------------------------------------- Matthias Schabel 2859 Glen Oaks Drive Salt Lake City, UT 84109 801-706-5760 (cell) 801-484-0811 (home) matthias at stanfordalumni dot org ---------------------------------------------------------------- 

Matthias Schabel schrieb: [Snip]
How do we convert 32 degrees Fahrenheit to Kelvin? [Snip] Absolute temperature (K) = (Absolute temperature (F) - 32)*5/9 +273.15
However, if we're talking about temperature differences (vectors), then the correct expression is
Temperature difference (K) = Temperature difference (F)*5/9 [Snip]
Hi Matthias, I had a similar problem to distinguish between coordinate systems starting to count at one and those starting to count at zero (which is the standard case). Here is my (very simple) solution: template<class T, unsigned int D> class coord { // a coordinate is a dimension starting to count at 1 T v; public: coord(euclid::dim<T, D> d) : v(d()+1) {} coord(T v0): v( v0>0 ? v0 : 1 ) {} coord(const coord &v0) : v(v0.v) {} coord& operator=(const coord &v0) { v = v0.v; return *this; } euclid::dim<T, D> operator ()() { return euclid::dim<T, D>(v-1); } }; It's intentionally that you can't do anything with a non standard coordinate but transform it into the standard representation (i.e. a dimension). I just couldn't think of any other meaningful operation. Both coordinate systems are technically different vector spaces. Both describe the same points in space, but the vector operations lead to different results when interpreted back into the real world. It seems, only the standard representation can be interpreted in a meaningful way. I think it's the same thing with different temperature units. Each unit defines its own (in this case one-dimensional) vector space. You can add Kelvin to Kelvin and Celsius to Celsius, but you can't mix them. The corresponding results are either in Kelvin or in Celsius respectively and are mathematically two different things. The same applies to differences. That they have the same physical interpretation is rather a coincident. 293.15 Kelvin represent the same temperature as 20 degrees Celsius, but doubling both will lead to very different results. It's up to the user to decide, what 'doubling a temperatures' is supposed to mean in the real world and pick a vector space, i.e. a unit, accordingly; be it Kelvin, Celsius, Fahrenheit or something entirely different. So I'd stick to offer a transformation between absolute temperatures. Differences are meaningful only within a particular vector space. Theoretically you could introduce a notation of a norm, that would be origin invariant but depending on the scale. So Kelvin and Celsius would have the same norm while the norm of Fahrenheit needs to be scaled by 5/9. This, however, is probably much to much hassle. Greetings, Andreas

representation (i.e. a dimension). I just couldn't think of any other meaningful operation.
I believe that vector operator-(point,point) is sensible...
space. You can add Kelvin to Kelvin and Celsius to Celsius, but you can't mix them. The corresponding results are either in
In this case, since the metric is degenerate, they can be implicitly converted to one another if you're talking about temperature differences.
293.15 Kelvin represent the same temperature as 20 degrees Celsius, but doubling both will lead to very different results.
If you mean 293.15K in absolute temperature, you're right. However, doubling a temperature difference makes perfect sense in either unit system.
something entirely different. So I'd stick to offer a transformation between absolute temperatures.
But in most ways differences behave more like what we expect when we use units. That is a length, for example, is really a difference between the two endpoints of an object, etc... Since people are likely to expect reasonable handling of both absolute temperatures and temperature differences, we may end up adding the absolute<> wrapper to the units library to allow that intent to be indicated and caught. Relative values are basically degenerate with bare value type and probably don't need a special wrapper. Then the operations that need to be supported are : absolute<T> operator+(absolute<T>,T) absolute<T> operator+(T,absolute<T>) absolute<T> operator-(absolute<T>,T) absolute<T> operator-(T,absolute<T>) T operator-(absolute<T>,absolute<T>) I think that's about it. You can't multiply absolute values by scalars or add them to themselves, obviously. Of course, this functionality certainly has relevance beyond the dimensional analysis/units domain, but I don't know if it's possible to find a sufficiently generic solution that meets every reasonable need and is implementable... Matthias

Anyone interested in this should read up on affine spaces. Absolute temperature is an affine point; difference between affine points are vectors.The same goes for positions in space or time. Note that Boost already touches on these ideas in Boost.Date_Time ( http://www.boost.org/doc/html/date_time.html). A Time is an affine point, a Time Duration is a vector. (I believe a Time Period could be called a "bound vector".) See also http://en.wikipedia.org/wiki/Affine_space http://benfrantzdale.livejournal.com/206467.html – what I wrote about this when first heard about affine spaces. —Ben On 3/9/07, Matthias Schabel <boost@schabel-family.org> wrote:
representation (i.e. a dimension). I just couldn't think of any other meaningful operation.
I believe that vector operator-(point,point) is sensible...
space. You can add Kelvin to Kelvin and Celsius to Celsius, but you can't mix them. The corresponding results are either in
In this case, since the metric is degenerate, they can be implicitly converted to one another if you're talking about temperature differences.
293.15 Kelvin represent the same temperature as 20 degrees Celsius, but doubling both will lead to very different results.
If you mean 293.15K in absolute temperature, you're right. However, doubling a temperature difference makes perfect sense in either unit system.
something entirely different. So I'd stick to offer a transformation between absolute temperatures.
But in most ways differences behave more like what we expect when we use units. That is a length, for example, is really a difference between the two endpoints of an object, etc...
Since people are likely to expect reasonable handling of both absolute temperatures and temperature differences, we may end up adding the absolute<> wrapper to the units library to allow that intent to be indicated and caught. Relative values are basically degenerate with bare value type and probably don't need a special wrapper. Then the operations that need to be supported are :
absolute<T> operator+(absolute<T>,T) absolute<T> operator+(T,absolute<T>) absolute<T> operator-(absolute<T>,T) absolute<T> operator-(T,absolute<T>) T operator-(absolute<T>,absolute<T>)
I think that's about it. You can't multiply absolute values by scalars or add them to themselves, obviously. Of course, this functionality certainly has relevance beyond the dimensional analysis/units domain, but I don't know if it's possible to find a sufficiently generic solution that meets every reasonable need and is implementable...
Matthias _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Ben: I would add to your reading list the article A Coordinate Free Geometry ADT (1997) by Stephen Mann, Nathan Litke, Tony DeRose http://citeseer.ist.psu.edu/191514.html in which they argue a point that has been made in computer graphics over and over, that confusing affine and vector spaces, or even two different coordinate systems of a common affine space, leads to hard- to-catch errors. Apparently, this has been a steady source of bugs in Computer Graphics as well as any other applications. -- Herve On Mar 12, 2007, at 2:04 PM, Ben FrantzDale wrote:
Anyone interested in this should read up on affine spaces. Absolute temperature is an affine point; difference between affine points are vectors.The same goes for positions in space or time.
Note that Boost already touches on these ideas in Boost.Date_Time ( http://www.boost.org/doc/html/date_time.html). A Time is an affine point, a Time Duration is a vector. (I believe a Time Period could be called a "bound vector".)
See also http://en.wikipedia.org/wiki/Affine_space http://benfrantzdale.livejournal.com/206467.html – what I wrote about this when first heard about affine spaces. —Ben

Hervé Brönnimann schrieb:
Ben: I would add to your reading list the article
A Coordinate Free Geometry ADT (1997) by Stephen Mann, Nathan Litke, Tony DeRose http://citeseer.ist.psu.edu/191514.html
Yes, that's exactly what we've been discussing. I still think, however, that the topic is out of the scope of the library. (The discussion is still quite informative though.) The library provides a tool suitable to represent objects of Euclidean geometry. Objects of Euclidean geometry are points in space. Choosing an orthonormal basis (i.e. an origin and a set of orthogonal base vectors), points can be represented by their Cartesian coordinates, i.e. as tuples of numbers. Defining vector operations makes Cartesian coordinates a vector space. Further, defining a norm introduces the idea of a length and makes it also a normed vector space, which is, due to the similarities to Euclidean geometry, often called an Euclidean vector space. Objects of an Euclidean geometry and members of a vector space are still very different. The former are real world objects, the later abstract representations. The former exit per se, the later are defined only by choosing a basis. The objective of the library is to provide a type save implementation of the vector space of Cartesian coordinates. As such, it implements an abstract concept. The instantiation of that concept to a particular representation, i.e. choosing a basis, is application specific. The user is free to define several representations, but it will be the users responsibility to distinguish between them. It might be reasonable to support this by type checking very similar to dimensional analysis, but this doesn't need to be the case. In my recent application (and probably many similar graphical applications) this is done by a hierarchy of widgets. Each widget defines its own vector space as a reference to the drawing operations it offers. The main functionality of a parent widget is to arrange its child widgets and transform their coordinates into this representation. Since widgets are typically created at run time, this can't be subject of static type checking. Other applications will have different requirements, so the ADT presented in the paper or a similar implementation in templates might be the appropriate solution. In any case, however, it will be independent of the vector implementation and should consequently not be part of the vector library. Andreas

Andreas; The cgal kernel makes a distinction between point and vector at compile time, and provides a CGAL_ORIGIN constant of type cgal::Origin with linear-to-affine conversions overloads cgal::Point operator+(cgal::Origin const&, cgal::Vector const&); cgal::Point operator+(cgal::Point const&, cgal::Vector const&); where the second overload involves component-wise addition, but the first is runtime-free. Perhaps it is what you already described, I haven't followed the whole discussion. In any case, it probably would be a good idea to check the CGAL kernel out. Nevertheless, it is still up to the CGAL programmer to keep track of to which affine frame (coordinate system) any point belongs. It would be a nice project to register frames and automatically handle the conversions between the frames via the registered transformations (and even combine transformations transitively), but that might be too much of the automated... plus for high-performance applications, I believe the compile-time safety such afforded would only be worthwhile if it could be done at no (or extremely little) cost to runtime performance. A tall order. My two cents, -- Herve On 3/9/07, Matthias Schabel <boost@schabel-family.org> wrote:
representation (i.e. a dimension). I just couldn't think of any other meaningful operation.
I believe that vector operator-(point,point) is sensible...
space. You can add Kelvin to Kelvin and Celsius to Celsius, but you can't mix them. The corresponding results are either in
In this case, since the metric is degenerate, they can be implicitly converted to one another if you're talking about temperature differences.
293.15 Kelvin represent the same temperature as 20 degrees Celsius, but doubling both will lead to very different results.
If you mean 293.15K in absolute temperature, you're right. However, doubling a temperature difference makes perfect sense in either unit system.
something entirely different. So I'd stick to offer a transformation between absolute temperatures.
But in most ways differences behave more like what we expect when we use units. That is a length, for example, is really a difference between the two endpoints of an object, etc...
Since people are likely to expect reasonable handling of both absolute temperatures and temperature differences, we may end up adding the absolute<> wrapper to the units library to allow that intent to be indicated and caught. Relative values are basically degenerate with bare value type and probably don't need a special wrapper. Then the operations that need to be supported are :
absolute<T> operator+(absolute<T>,T) absolute<T> operator+(T,absolute<T>) absolute<T> operator-(absolute<T>,T) absolute<T> operator-(T,absolute<T>) T operator-(absolute<T>,absolute<T>)
I think that's about it. You can't multiply absolute values by scalars or add them to themselves, obviously. Of course, this functionality certainly has relevance beyond the dimensional analysis/units domain, but I don't know if it's possible to find a sufficiently generic solution that meets every reasonable need and is implementable...
Matthias _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Ben FrantzDale schrieb:
Anyone interested in this should read up on affine spaces. Absolute temperature is an affine point; difference between affine points are vectors.The same goes for positions in space or time.
Hi Ben, interesting stuff, it just leaves one question to me: How can you represent an affine point in a computer program? My guess is: you can't. But you can implement vector spaces and you can map an affine space to a vector space by choosing a basis, i.e. an origin and a set of orthogonal unit vectors. So, the basis is not a property of the affine space, but a necessary vehicle to get an image of it you can deal with. The choice you made will restrict you in one way, but also introduce new concepts (like multiplying with a scalar), that might not have a meaning in the original space. On the other hand, each vector space is an affine space itself, so one special representative of a more general affine space. I'm not sure if the following is correct, but may be we can define affinity as the whole of all possible representations. So if you want to deal with it, you need to make your choice explicit, be it by an additional type tag or by a variable. Affine spaces and vector spaces are two different things that live without each other, but affine spaces can not be represented in programming without vector spaces or a similar vehicle. Consequently, IMHO, vector space implementations should be considered isolated from affinity and affinity should be implemented in terms of and as extension to vector spaces. Note, that numbers (including complex numbers), Cartesian coordinates, physical units, etc. all form vector spaces and consequently affine spaces, so however an implementation of affinity might look like, it probably should consider all of them. Andreas

Hi, On 3/15/07, Andreas Harnack <ah.boost.04@justmail.de> wrote:
Hi Ben, interesting stuff, it just leaves one question to me: How can you represent an affine point in a computer program? My guess is: you can't.
You can, as you describe yourself in the following sentence:
But you can implement vector spaces and you can map an affine space to a vector space by choosing a basis, i.e. an origin and a set of orthogonal unit vectors.
...except that this is a (Cartesian) _coordinate system_, not a basis. A basis is a minimal set spanning a vector space.
I'm not sure if the following is correct, but may be we can define affinity as the whole of all possible representations
Just as you could define a vector space as the whole of all its bases (although one is certainly sufficient ;-).
Affine spaces and vector spaces are two different things that live without each other, [...]
Not quite; you need a vector space to define an affine space, for the difference between two points lives in that vector space. Regards, Michael

Matthias Schabel schrieb: [Snip]
But in most ways differences behave more like what we expect when we use units. That is a length, for example, is really a difference between the two endpoints of an object, etc...
Exactly, a voltage is a difference between two potentials and a potential is a voltage measured against ground... The point I'm trying to make is that quantities of the same unit form a vector space and a vector space always has an basis. Selecting a particular basis is typically application dependent. Kelvin and Celsius seem to be two of the rare exceptions where a unit implies an origin. The wrapper class seems to be a good approach, but the problem of distinguishing several bases applies to all vector spaces, so we should be able to find a general solution. Andreas

On 3/7/07, Andreas Harnack <ah.boost.04@justmail.de> wrote:
maybe with implicit conversion between points and vectors. Looks charming but a bit like an overkill to me. What do you think?
Are there any situations where points can't be adequately handled as vectors from the origin? Trying to do points and vectors "properly" seems like it could quickly lead to messy circular dependencies for no great gain. ~ Scott

me22 schrieb:
Are there any situations where points can't be adequately handled as vectors from the origin?
Probably not; I'm not a mathematician, but I think you can even prove that there are non. Tom is right in pointing out, that points are not vectors; the question is, is this relevant for a vector (or physical dimension) library. I'm getting more and more convinced that it isn't for the implementation, but for its scope. Discussing this issues might help to draw the line between things that should go into the library and the thinks that shouldn't. Points can't be handled directly since they are real world objects. We can, however, define a vector space by picking an origin (and a set of base vectors) and represent the resulting positional vectors by tuples of numbers. Crucial here is, that the vector space doesn't exist per se, but is the result of our choice. Different choices will lead to different vector spaces and to more or less complicated representations of the things we want to describe. Typically we'll pick an origin, that makes calculations as simple as possible. Points are not vectors. You can't, for instance, add points and you can't multiply them with a scalar, that works only with their positional vectors. It would be nice to have a representation of points that is independent of any choice we make, but this is impossible. Since any coordinate system needs an origin, there's indeed no need to abandon the 'richer' concept of vectors in favour of simple coordinates other then the wish to make this distinction explicit. Members of different vector spaces can't generally be combined, vector operations are defined only for members of the same vector space. That might explain the problems arising when dealing with different units for the same physical dimension, like temperature. Kelvin, Celsius and Fahrenheit define different vector spaces with different origins, which might (like Kelvin and Celsius) or might not (like Fahrenheit) use the same base vectors. Transforming one into another is a vector space transformation and a chapter of it's own. Tuples form a vector space that's capable of representing all vector spaces that can be created by picking an origin in any space of geometrical points. The job of the library is to provide a representation for that tuple vector space. That includes neither the selection of a suitable vector space in the application domain nor the transformation between different possible choices. Both is part of the application design process. Each instance forms a single tuple vector space. The user is free to use several instances in an application, but its the users job to keep them apart and define relations between them. An excellent example how this might work is (physical) dimensional analysis. All values of a single unit (!) form a vector space, that can be represented by an instance of a tuple vector space. Dimensional analysis actually performs vector space transformation by mapping, for example, a member of a vector space distance and a member of a vector space time to a member of a vector space velocity. Dimensional analysis, however, does not necessarily (and probably should not) make a particular choice for vector spaces in the dimensional domains. That again is application specific an should be left to the user. Best regards, Andreas
participants (7)
-
Andreas Harnack
-
Ben FrantzDale
-
Hervé Brönnimann
-
Matthias Schabel
-
me22
-
Michael Walter
-
Tom Brinkman