Boost logo

Boost :

Subject: Re: [boost] [qvm] few q's for emil
From: Emil Dotchevski (emildotchevski_at_[hidden])
Date: 2011-07-18 03:24:04


On Sun, Jul 17, 2011 at 9:16 PM, Jeffrey Lee Hellrung, Jr.
<jeffrey.hellrung_at_[hidden]> wrote:
> Emil, I have a few quick and random questions concerning (proposed)
> Boost.QVM, which I notice is still in the review queue without a review
> manager (I may be able to help in that regard if things go well with
> Lorenzo's (proposed) Boost.Local review).  I might be able to utilize this
> in some of my future work, so I'm interested.

Thanks for your interest and feedback. And yes, the library needs a
review manager.

> First, a very general question.  Can you explain where QVM fit within the
> large collection of linear algebra libraries?  What additional value is QVM
> providing that you feel other solutions are lacking?

I called the library QVM which stands for Quaternions, Vectors and
Matrices. This scope is practical for 3D graphics. While the library
does support dimensions greater than 4, that is outside of my focus,
and perhaps even my competence.

> Now, I've barely scratched the documentation and I already have some
> questions :/
>
> 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.

> 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.

> 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 guess it's possible to define ::w more abstractly. I decided to play
it safe for now, but that's not set in stone.

> 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?

> 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.

> 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 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.

Emil Dotchevski
Reverge Studios, Inc.
http://www.revergestudios.com/reblog/index.php?n=ReCode


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk