Boost logo

Ublas :

From: Paul C. Leopardi (leopardi_at_[hidden])
Date: 2005-07-11 18:29:46


Hi all, My reply below. Best regards

On Mon, 11 Jul 2005 08:48 pm, Dima Sorkin wrote:
> Quoting Andrew Rieck <arieck_at_[hidden]>:
> > Function templates would naturally solve this issue and stop you having
> > to duplicate calls. In this way, the compiler is doing all the hard
> > work. A traits class should not have any member functions which do actual
> > work.
> >
> > Kind regards,
> > Andrew
>
> Hi.
> The use of "abs" etc. in traits class may be worth, if you decide to
> enable "contexts" in calls to ublas:
>
> May be this example is too "corner case" , but anyway :) .
> Suppose that I have a "scalar" class C , which is internally isomorphic
> to 2x2 matrix.
> I have two versions of what can be called "abs" for C: normA() and
> normB(). I want to calculate a norm of matrix of C , once by using normA()
> for C, once by normB(), in the same program. By using traits , it is easy
> task, without traits -- less easy (because you can have only one "abs"
> function for C,
> or make it a functor object with state) .
> I am not sure that I can think of something more serious now,that will
> demand "abs" in traits.

Your example reminds me of a few points I have raised before, which I re-state
in a different context. If your C class is isomorphic to a 2x2 matrix, let's
make it a little more concrete and consider a 2x2 matrix of double.

You want to use C as a scalar class with uBLAS. It would not be safe to do
this if:
1) uBLAS assumed that every non-zero element of class C has a multiplicative
inverse. See http://mathworld.wolfram.com/DivisionAlgebra.html

Your class C would have to cope with elements of C which do not have an
inverse. Maybe it would return a NaN result, or throw an exception when asked
for 1/c, where c is in C and c has no inverse. Then uBLAS would have to cope
with NaN (or an exception) as a result of 1/c.

2) uBLAS assumed that multiplication is commutative.
See http://mathworld.wolfram.com/CommutativeRing.html

If you hand uBLAS two scalars, a and b of type C, where a*b != b*a, then you
would want to be sure that there are no places in uBLAS which assume that
a*b == b*a.

Then again, maybe either or both of these assumptions allow some significant
optimization somewhere in uBLAS. In this case, you would want uBLAS to
provide some sort of ring_traits, such as is_division_ring<T>,
is_commutative_ring<T>. Then uBLAS would be able to have different code for
the different cases, allowing both correct operation and optimization where
possible.

The same ideas apply to the other field and ring axioms, although I would
personally draw the line at addition. AFAICT, it is reasonable to assume that
any scalar class K used with addition in uBLAS would be such that K models an
Abelian group under addition (possibly subject to IEEE arithmetic and
rounding error).

Maybe the best idea would be to assume that any scalar class K which is used
with the algebraic operations of uBLAS would be such that K models a ring,
and then supply ring_traits to cover the extra axioms between ring and field.
See http://mathworld.wolfram.com/Ring.html
http://mathworld.wolfram.com/Field.html
http://mathworld.wolfram.com/FieldAxioms.html