
On Mon, Jul 18, 2011 at 12:24 AM, Emil Dotchevski <emildotchevski@gmail.com>wrote:
On Sun, Jul 17, 2011 at 9:16 PM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
[...]
First, it doesn't look like you support read-only or write-only structures,
The library doesn't require that ::w is defined. The library itself does define some types that are read-only.
Ah, okay; that wasn't clear in the docs on v_traits, IIRC :/
or structures for which writing is effected through a proxy reference.
E.g., v_traits<V>::r<I>(v) and v_traits<V>::w<I>(v) must always be supported, and v_traits<V>::w<I>(v) must return a reference-to-non-const.
Yes, ::w must return a mutable reference. However, it is not required that ::w is defined for each and every element. For example, diag_m maps a vector as a square matrix that has the vector as its diagonal, and zeroes in all other elements. In this case, ::r is defined for all elements, but ::w is defined only for the diagonal elements, returning mutable references to the vector elements.
Make sense.
as could proxy structures (c*v could be a proxy vector where w<0>(c*v) = 1 is equivalent to w<0>(v) = 1/c).
This requirement means that none of the boost::qvm functions can return temporary objects for proxies. The mutable proxies Boost QVM avoid temporary objects by clever type casting. This helps control the abstraction penalty of the library.
I don't understand. Can you elaborate?
Why do you require the dimension of vectors (and, likely, matrices; I haven't checked) to be strictly greater than 0? Sometimes a 0-dimensional vector is convenient to have when writing dimension-independent code.
I wasn't aware of that. What can you do with a zero dimensional vector?
Not much, to be sure (all zero-dim vectors of a given scalar type, at least, would be equal). I can't give a concrete example at the moment, but I seem to remember some recursion on dimension I've done where the base case was simpler to express at 0 than at 1.
I noticed that among the vector operations is a cross product for 3-vectors, but no cross product for vectors of other dimensions. Such a construct is useful for computing normals to hyperplanes in D-dimensional space. I can help you add it if you think it fits.
Sure.
I'll browse the code.
What algorithm do you use for computing determinants?
The general case is pretty straight forward recursion, defined in boost/qvm/detail/determinant_impl.hpp. However, the library comes with a code generator (libs/qvm/gen.cpp) capable of defining overloads for any specific size, unrolling the recursion.
The code generator is used instead of template metaprogramming, again to control the abstraction penalty of the library.
I'll take a look. I ask because I believe for 4x4 and larger matrices, a dynamic programming solution ends up significantly reducing the number of operations over the O(n!) recursive solution. But, I believe, for matrices larger than 5x5, still other techniques take fewer operations. Still, dynamic programming might improve the 4x4 and 5x5 cases. But maybe you've already looked into this...?
I think a signed volume function would fit in well with the matrix
operations. I can help you add this, too.
OK.
Hmmm...how do you compute the magnitude of a vector given the scalar requirements defined at
http://www.revergestudios.com/boost-qvm/scalar_requirements.html
? Seems like you would need a square root function, and possibly even a conjugation function if you want to support complex scalar types...
I guess that the documentation isn't clear but boost/qvm/math.hpp defines function templates that correspond to the functions from <math.h>. The templates are specialized for float and double, but can be specialized for any other scalar. That said, I don't have tests using any other scalar type. Perhaps a fixed point scalar should be implemented to make sure there isn't something missing.
Are complex scalar types within the scope of the library? - Jeff