Re: [boost] Any Interest in a 3-D Vector library?

--- Stefan Koch <maillist@isolda.com> wrote:
Any interest in a templatized class for 3-Dimensional vectors? (Similar in style to std::complex or boost math/octonion and math/quaternion.)
FYI: A few years ago I put together cooperating classes for 3-dim vectors, 3x3 matrices and 3x3 symmetric matrices (storing only the six unique elements): http://cvs.sourceforge.net/viewcvs.py/cctbx/scitbx/include/scitbx/vec3.h?vie... http://cvs.sourceforge.net/viewcvs.py/cctbx/scitbx/include/scitbx/mat3.h?vie... http://cvs.sourceforge.net/viewcvs.py/cctbx/scitbx/include/scitbx/sym_mat3.h... See also: http://cctbx.sourceforge.net/ It is all open source (BSD style). Feel free to take what you find useful. Cheers, Ralf __________________________________ Do you Yahoo!? Yahoo! Small Business - Try our new resources site! http://smallbusiness.yahoo.com/resources/

"Ralf W. Grosse-Kunstleve" <rwgk@yahoo.com> writes:
Any interest in a templatized class for 3-Dimensional vectors? (Similar in style to std::complex or boost math/octonion and math/quaternion.)
FYI: A few years ago I put together cooperating classes for 3-dim vectors, 3x3 matrices and 3x3 symmetric matrices (storing only the six unique elements):
http://cvs.sourceforge.net/viewcvs.py/cctbx/scitbx/include/scitbx/vec3.h?vie...
http://cvs.sourceforge.net/viewcvs.py/cctbx/scitbx/include/scitbx/mat3.h?vie...
http://cvs.sourceforge.net/viewcvs.py/cctbx/scitbx/include/scitbx/sym_mat3.h...
See also: http://cctbx.sourceforge.net/
Thanks for the information and link. That is an interesting class with lots of functionality. In contrast my class is much more focused on providing just an interface for a 3D vector ADT as needed (for example) in a physics problem. I think this makes it easier and in at least one case safer to use. I also believe that this simplicity makes it more appropriate for inclusion into boost, and for standardization. Specific examples of where your class seems to have extra functionality that I do not think is appropriate for a 3D vector ADT include the each_update_min/each_update_max, and the sum, and product methods. I cannot think of a context where these would be used on a 3-Dimensional vector. (They seem to be more useful for a general purpose n-dimensional vector.) One place where I think the over general approach limits the class directly is in the length member function. You have this implemented as sqrt( x^2 + y^2 + z^2 ). The preferred way to implement this for vectors of floating point types is as m * sqrt( (x/m)^2 + (y/m)^2 + (z/m)^2 ) where m is max( x,y,z). This way there is no chance of internal overflow in the calculations when the components approach the limit of the floating point type used. Of course, if the vector type is also to be used with integers as the components (as I assume you support due to the presence of the % operator, and the comment of this class also supporting color representations) this trick does not work. You also made an interesting design choice in allowing the * operator to be used as the dot product between two vectors. I choose not do do this, but to provide a non operator function of dot (much like cross for cross products). The reason for this is that there are three types of vector products that can be useful between two vectors x, y: 1. dot product r = sum x_i * y_i 2. element by element product r_i = x_i * y_i 3. cross product. For generic vectors the cross product is not appropriate, but the first two are. The dot product of the obvious choice from a linear algebra standpoint. For generic n-dimensional vectors, it has been my experience that it is more common to want to element wise product. Matrix programs like maple and octave define two operators ( * and .* ) to provide both. Numerical Python provides only the element wise product as an operator. For these reasons there did not seem to be an obvious choice for the * operator between two 3-D vectors, so I chose to make it a separate function. Feel free to look at my implementation. It is available at http://isolda.com/vector3/index.html Stefan

Stefan Koch wrote:
"Ralf W. Grosse-Kunstleve" <rwgk@yahoo.com> writes:
One place where I think the over general approach limits the class directly is in the length member function. You have this implemented as sqrt( x^2 + y^2 + z^2 ). The preferred way to implement this for vectors of floating point types is as m * sqrt( (x/m)^2 + (y/m)^2 + (z/m)^2 ) where m is max( x,y,z). This way there is no chance of internal overflow in the calculations when the components approach the limit of the floating point type used. Of course, if the vector type is also to be used with integers as the components (as I assume you support due to the presence of the % operator, and the comment of this class also supporting color representations) this trick does not work.
There are a million different ways to define a norm. It should be up to the user to specify which norm he actually wants to use instead of being hardcoded IMHO.
You also made an interesting design choice in allowing the * operator to be used as the dot product between two vectors. I choose not do do this, but to provide a non operator function of dot (much like cross for cross products). The reason for this is that there are three types of vector products that can be useful between two vectors x, y:
1. dot product r = sum x_i * y_i 2. element by element product r_i = x_i * y_i 3. cross product.
You forgot the inner product where: r = sum conjugate(x_i) * y_i.
For generic vectors the cross product is not appropriate, but the first two are. The dot product of the obvious choice from a linear algebra standpoint. For generic n-dimensional vectors, it has been my experience that it is more common to want to element wise product. Matrix programs like maple and octave define two operators ( * and .* ) to provide both. Numerical Python provides only the element wise product as an operator.
For these reasons there did not seem to be an obvious choice for the * operator between two 3-D vectors, so I chose to make it a separate function.
And I think the inner-product is more appropriate '-). Just to say that it rather depends on personal preference. The problem is that there are not enough operators available but on the other side: is it necessary to overload operator* ?
Feel free to look at my implementation. It is available at http://isolda.com/vector3/index.html

Toon Knapen <toon.knapen@fft.be> writes:
One place where I think the over general approach limits the class directly is in the length member function. You have this implemented as sqrt( x^2 + y^2 + z^2 ). The preferred way to implement this for vectors of floating point types is as m * sqrt( (x/m)^2 + (y/m)^2 + (z/m)^2 ) where m is max( x,y,z). This way there is no chance of internal overflow in the calculations when the components approach the limit of the floating point type used. Of course, if the vector type is also to be used with integers as the components (as I assume you support due to the presence of the % operator, and the comment of this class also supporting color representations) this trick does not work.
There are a million different ways to define a norm. It should be up to the user to specify which norm he actually wants to use instead of being hardcoded IMHO.
Actually the ones I an aware of are of the form ( sum |x_i|^p )^(1/p). With p = 2 this is the most common case (especially for 3-D vectors) as given above. It can also be easily reformed (as above) to make sure there is no intermediate overflow. This is sometimes is called the length (especially for 3-D Vectors). Unfortunately the length of a generic vector already means the number of elements, so that is not a good name. I is certainly possible to overload the norm member function to take an additional argument for p.
You also made an interesting design choice in allowing the * operator
to be used as the dot product between two vectors. I choose not do do this, but to provide a non operator function of dot (much like cross for cross products). The reason for this is that there are three types of vector products that can be useful between two vectors x, y: 1. dot product r = sum x_i * y_i
2. element by element product r_i = x_i * y_i 3. cross product.
You forgot the inner product where: r = sum conjugate(x_i) * y_i.
And also outer product r_{i,j} = x_i * y_j. But, this is probably the least useful of them all. But, you bring up a good point. Should the 3-D vector class (implicitly) support vectors with complex coordinates. Certainly this should be the case for a general n-dimensional vector. For a 3-D vector specifically targeted for geometrical rotations and reflections, I do not think this is appropriate.
For generic vectors the cross product is not appropriate, but the first two are. The dot product of the obvious choice from a linear algebra standpoint. For generic n-dimensional vectors, it has been my experience that it is more common to want to element wise product. Matrix programs like maple and octave define two operators ( * and .* ) to provide both. Numerical Python provides only the element wise product as an operator. For these reasons there did not seem to be an obvious choice for the *
operator between two 3-D vectors, so I chose to make it a separate function.
And I think the inner-product is more appropriate '-). Just to say that it rather depends on personal preference. The problem is that there are not enough operators available but on the other side: is it necessary to overload operator* ?
I could not agree more. That is why I did not define the * operator for two vectors.
participants (3)
-
Ralf W. Grosse-Kunstleve
-
Stefan Koch
-
Toon Knapen