Templated Matrix Class

Started by
4 comments, last by snk_kid 19 years, 2 months ago
On a creative whim, I created a templated matrix class of the form
template<int ROW, int COL> class CMatrix
The idea is that you can create vectors (CMatrix<4, 1>), and regular matrices of any dimensions without having to make a bunch of different classes. The problem lies in multiplying. Will I have to make a templated multiply function
template<int TARGET_ROW, int TARGET_COL> CMatrix<TARGET_ROW, COL> Multiply(CMatrix<TARGET_ROW, TARGET_COL> TargetMatrix) { ... }
and then do
MyMatrix4X4.Multiply<4, 4>(MyTarget4X4);
Or is there an easier way to do it that would be somewhat less cumbersome? Or should I just screw it and go back to my regular math classes?
#include <stdio.h> /* MagpieOfDoom BF Interpreter Sig */void main(){char a[1337],b[1337];int c,d,e[1337],f,g,h;d=g=f=c=h=0;scanf("%s",a);for(;c<1337;c++){b[c]=0;}c=0;while(1){if(!f){b[d]+=(a[c]=='+')-(a[c]=='-');d+=(a[c]=='>')-(a[c]=='<');if(a[c]=='.'){printf("%c",b[d]);}if(a[c]==','){scanf("%c",&b[d]);}h=(b[d]==0);if(a[c]=='['){if(h){f=1;}else{e[g]=c;g++;}}if(a[c]==']'){if(!h){c=e[g-1];}}}else{if(a[c]==']'){f=0;}}c++;if(a[c]=='0'){break;}}} /* C++ Compile! */
Advertisement
I can't answer the template question, but I have some general thoughts.

I've actually seen a math library implemented as general NxM matrices, and IMHO it was pretty impenetrable - certainly not something I'd want to work with. Doesn't mean it couldn't be done better though.

One issue is that it seems functions such as dot products and general multiplications would have to be implemented as loops in terms of N and M, whereas most vector and matrix classes I've seen just write everything out longhand to avoid the loops and resulting overhead. I suppose compilers might unroll short loops, such as the dot product, but I don't know enough about that to say for sure.

Also, you'd have specific functions, such as the cross product, which you'd probably only want to implement for one NxM combination (3x1 or 1x3 in this case). I suppose in that case you could derive Vector3 from Matrix<3, 1> and implement cross for that only.

I guess I don't have that much to contribute :-) But, I will be curious as to what the more experienced c++ programmers here have to say about this.
Matrix multiplication is only defined when the number of rows of the left matrix matches the number of columns for the right matrix, so there's no point in defining an operation for other arrangements. An m x n matrix multiplied by a n x p matrix will yield a m x p matrix.

template <size_t m, size_t n, size_t p>Matrix<m,p> operator* (Matrix<m,n> const& lhs, Matrix<n,p> const& rhs) {  ...}


You could take a look at muer's excellent HSTL, which implements nice policy based matrix and vector classes to get some ideas (or just decide to use it instead :-P)

Hope this helps some.

-bodisiw
-bodisiw
Quote:Original post by NoahAdler
template <size_t m, size_t n, size_t p>Matrix<m,p> operator* (Matrix<m,n> const& lhs, Matrix<n,p> const& rhs) {  ...}

How would this work? I have never seen an operator templated...
Would it be, like, MyMatrix4X4 *<4, 4, 4> MyTarget4X4?

And, jyk -- I am using VC++ 6, which is pretty solid. It will probably unroll the loops.
#include <stdio.h> /* MagpieOfDoom BF Interpreter Sig */void main(){char a[1337],b[1337];int c,d,e[1337],f,g,h;d=g=f=c=h=0;scanf("%s",a);for(;c<1337;c++){b[c]=0;}c=0;while(1){if(!f){b[d]+=(a[c]=='+')-(a[c]=='-');d+=(a[c]=='>')-(a[c]=='<');if(a[c]=='.'){printf("%c",b[d]);}if(a[c]==','){scanf("%c",&b[d]);}h=(b[d]==0);if(a[c]=='['){if(h){f=1;}else{e[g]=c;g++;}}if(a[c]==']'){if(!h){c=e[g-1];}}}else{if(a[c]==']'){f=0;}}c++;if(a[c]=='0'){break;}}} /* C++ Compile! */
It's a template function, which works similarly to template classes (with a few minor caveats). You don't need to specifically state the template parameters, since the argument types implicitly specify them. For instance:

Matrix<4,2> A;Matrix<2,3> B;Matrix<4,3> product = A*B;


The compiler matches the arguments to the template function, just as it would a normal function. In the above code, attempting to do B*A would result in a compile time error, since it wouldn't be able to find a match for operator(Matrix<2,3>, Matrix<4,2>), since 3 != 4.

I hope this is starting to make some sense. Let me know if you have further questions.

-bodisiw
-bodisiw
Quote:Original post by MagpieOfDoom
Quote:Original post by NoahAdler
template <size_t m, size_t n, size_t p>Matrix<m,p> operator* (Matrix<m,n> const& lhs, Matrix<n,p> const& rhs) {  ...}

How would this work? I have never seen an operator templated...
Would it be, like, MyMatrix4X4 *<4, 4, 4> MyTarget4X4?


No, it will deduce the types, it would work as:

Matrix<4,1> m;Matrix<1, 4> n;Matrix<4,4> p = m * n;


Quote:Original post by MagpieOfDoom
And, jyk -- I am using VC++ 6, which is pretty solid.


Err no its actually the worse compiler to work with templates in, regardless of un-rolling loops or not.

You should also know that a naive implementation when used with complex expressions of arbitrary sized matrices & vectors will result in serious performance problems because of the over-head temporaries introduce, if your seriously going to do this then you should look into expression templates they over come the problems of temporaries but i'm warning you its really advance template stuff so you should consider using a library instead and get an up to date compiler thats more standard compliant.

I don't know if muer's code handles this case i have not looked at his code.

Another thing you can unroll loops via meta-template programming (among other things [smile]) but you may actually degrade performance if you go over-board with unrolling loops.

[Edited by - snk_kid on February 12, 2005 5:58:11 PM]

This topic is closed to new replies.

Advertisement