|
Boost : |
Subject: Re: [boost] different matrix library?
From: DE (satan66613_at_[hidden])
Date: 2009-08-16 17:10:56
<WARNING! LOT OF LETTERS!>
to all
on 15.08.2009 at 13:14
joel wrote :
>> till now i actually don't see any critical flaws in the design
>> implementation will be altered in any way of course
> Well, the problem is not the design per itself. What usually happens
> with such lib is that you have tons of different user types
> that all want disjoint set of features.
about tons of user types
here is a train of thought (great album by Dream Theater by the way)
(general case) consider there are a matrix_expression class and a
matrix class which derives from matrix_expression<matrix<type> > (CRTP)
we can now write stuff like
matrix<type> m = m1*m2 + m3*a; //a is a scalar
then one must think that allocating matrix on the stack is a good idea
since such (compile time) decision must be implemented somewhere, why
not in a distinct type?
no problem!
static_matrix<type, 3, 3> m /*= m1*m2 + m3*a*/;
//^^here goes size of matrix
it derives from matrix_expression<static_matrix<type, 3, 3> > so all
operations fall to general case
it could actually be 'matrix<type, 3, 3>' but either it is perfectly
readable, easy to understand, easy to implement
you are welcome...
and also one can write
void foo(const static_matrix<type, 3, 3> &m);
clearly stating that "i really wanna get a 3 by 3 matrix specifically
of that type!"
of course he (the one) meant 'static_matrix' type
"but hey! i also have a symmetric matrix which must be handled a bit
special" the one may say
again, not a problem
lets define 'symmetric_matrix_expression' which derives from
matrix_expression
we can do this because actually they are connected with 'is-a'
relationship, in other words symmetric matrix is a matrix (but not vice
versa)
so we deliver 'symmetric_matrix' (which derives from
symmetric_matrix_expression) and now can optimize some operations:
symmetric_matrix<type> m = m1*m2 + m3*a; //m1, m2 & m3 are symmetric
now one can clearly state that he
void need_symmetric(const symmetric_matrix<type> &m);
for a particular operation
and if another user write
matrix<type> m;
//...
need_symmetric(m); //need to explicitly turn m to symmetric
it won't compile because 'm' is not necessarily symmetric
but in an expression
m = m1 + symmetric1*symmetric2;
operations will fall back to general case
isn't it nice?
why stopping? then one can define diagonal_matrix_expression which is
actually symmetric so it derives from symmetric_matrix_expression
bla bla bla... define diagonal_matrix... bla bla bla...
(by the way an identity matrix is diagonal)
then one can write
diagonal_matrix<type> d = identity<type>(v.size()) + diag(v); //v is a vector
while
symmetric1 - a*identity<type>(N)
is still a symmetric expression (and can be handled acordingly)
resume: in my opinion this all is convinient, delivers clarity of user
code, easy to understand and implement, easy to customize and extend
what do you think about it?
-- Pavel
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk