Z
Zoran Stipanicev
Hi!
The question is product of laziness. I want to write generic operators for
matrix computation which would adapt to different types of matrices i.e.
when
adding square matrix and lower triangle matrix it would add only elements on
and
under main diagonal and copy the rest from square matrix. Basically it would
allow adding new matrix type (shape) without writing new operators (I'm to
lazy
for that ). Here is the code I hope could do that:
//Matrix Trait
template <int r, int c, class Matrix>
struct IsZero
{
enum { ret = false };
};
class LowerTriangMatrix;
//all elements above main diagonal in LTM are 0
template <int r, int c>
struct IsZero<r, c, LowerTriangMatrix>
{
enum { ret = (c > r) ? true : false; };
};
//expresion tree node
template <class Lhs, class OpTag, class Rhs>
struct Expression
{
typedef Type typename Lhs::T;
Expression(Lhs const& lhs, Rhs const& rhs)
: l(lhs), r(rhs)
{
}
template <int row, int col>
Type Apply(/*unsigned row, unsigned col*/) const
{
return IsZero<row, col, Lhs>::ret ?
IsZero<row, col, Rhs>::ret ?
(Type)0 : OpTag<Type>::Apply((Type)0, r(row,col))
: IsZero<row, col, Rhs>::ret ?
OpTag<Type>::Apply(l(row,col), (Type)0)
: OpTag<Type>::Apply( l(row, col), r(row,col) );
//return OpTag::apply( l(row, col), r(row,col) );
}
Lhs const& l;
Rhs const& r;
};
//OpTag
template <typename Lhs>
struct Plus
{
static Lhs Apply(Lhs& lhs, Lhs& rhs)
{
return lhs + rhs;
}
};
And the question is can this be done? And can I do it this way? I really don't
have time to try it only to find out that it's impossible and I'll be really
grateful for any suggestion/advice.
P.S. I'm aware that this probably requires unwinding for loops and that it
would generate a lot of code, but it can still be used for small matrices.
Best regards,
Zoran Stipanicev
The question is product of laziness. I want to write generic operators for
matrix computation which would adapt to different types of matrices i.e.
when
adding square matrix and lower triangle matrix it would add only elements on
and
under main diagonal and copy the rest from square matrix. Basically it would
allow adding new matrix type (shape) without writing new operators (I'm to
lazy
for that ). Here is the code I hope could do that:
//Matrix Trait
template <int r, int c, class Matrix>
struct IsZero
{
enum { ret = false };
};
class LowerTriangMatrix;
//all elements above main diagonal in LTM are 0
template <int r, int c>
struct IsZero<r, c, LowerTriangMatrix>
{
enum { ret = (c > r) ? true : false; };
};
//expresion tree node
template <class Lhs, class OpTag, class Rhs>
struct Expression
{
typedef Type typename Lhs::T;
Expression(Lhs const& lhs, Rhs const& rhs)
: l(lhs), r(rhs)
{
}
template <int row, int col>
Type Apply(/*unsigned row, unsigned col*/) const
{
return IsZero<row, col, Lhs>::ret ?
IsZero<row, col, Rhs>::ret ?
(Type)0 : OpTag<Type>::Apply((Type)0, r(row,col))
: IsZero<row, col, Rhs>::ret ?
OpTag<Type>::Apply(l(row,col), (Type)0)
: OpTag<Type>::Apply( l(row, col), r(row,col) );
//return OpTag::apply( l(row, col), r(row,col) );
}
Lhs const& l;
Rhs const& r;
};
//OpTag
template <typename Lhs>
struct Plus
{
static Lhs Apply(Lhs& lhs, Lhs& rhs)
{
return lhs + rhs;
}
};
And the question is can this be done? And can I do it this way? I really don't
have time to try it only to find out that it's impossible and I'll be really
grateful for any suggestion/advice.
P.S. I'm aware that this probably requires unwinding for loops and that it
would generate a lot of code, but it can still be used for small matrices.
Best regards,
Zoran Stipanicev