• Advertisement
Sign in to follow this  

Matrix multipication!! Quickly please!

This topic is 4618 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

//The 4x4 cMatrix class class cMatrix { public: union { struct { float _11, _12, _13, _14; float _21, _22, _23, _24; float _31, _32, _33, _34; float _41, _42, _43, _44; }; }; cMatrix operator*(const cMatrix &mat1); }; Can someone please write the operator for me! Okay I had to rewrite the majority of my old matrix class that i lost a very long time ago myself and I do not remember much about matrice arithmetic. I remember 2 for loops and running throw the array and do some math. Multiple each row by column then add... something like that... fast and effecient. I would be quite pleased if someone could simply provide me with their form of this function. I've seen a few examples but all of them use a 2D array, which makes more sense but is a pain in c.

Share this post


Link to post
Share on other sites
Advertisement
cMatrix operator *(cMatrix &mat1) {
cMatrix matTemp;
float *p_matTemp = (float*)&matTemp;
float *p_mat1 = (float*)&mat1;
float *p_matThis = (float*)this;

for (int j = 0; j < 4; j++) {
for (int i = 0; i < 4; i++) {
iIndex = (j*4)+i;

}
}
return matTemp;
}




I cannot go any farther without advice.

Share this post


Link to post
Share on other sites
Most matrix multiplication code I've seen just does it in place rather than using nested loops. Element ij of the resultant matrix is the dot product of the i'th row of the left-hand matrix and the j'th column of the right-hand matrix. For example:

result._32 = l._31 * r._12 + l._32 * r._22 + l._33 * r._32 + l._34 * r._42;

The rest of the elements are calculated similarly.

Share this post


Link to post
Share on other sites
Well I actually solved my problem and got it working with the nested loops, I actually needed three.

I'm curious to begin implimenting this dotproduct method would be faster than running 3 nested for loops.

DotProduct with a vector is simple AxBx + AyBy + AzBZ
By DotProduct with a matrix what is implied?

Share this post


Link to post
Share on other sites
|a,b||e,f| |a*e+b*g , a*f+b*h|
|c,d||g,h| |c*e+d*g , c*f+d*h|

row * column

Share this post


Link to post
Share on other sites
Hi, here's the code from my old engine:



/*!
Multiplies every element of the Matrix by the the value passed as a parameter.
\param matrix The Matrix to multiply by.
\return A reference to itself to allow chaining.
*/

Matrix& Matrix::operator*=(const Matrix& m2) throw()
{
Matrix result;

result.data[0] = m2.data[0] * data[0] + m2.data[1] * data[4] + m2.data[2] * data[8] + m2.data[3] * data[12];
result.data[1] = m2.data[0] * data[1] + m2.data[1] * data[5] + m2.data[2] * data[9] + m2.data[3] * data[13];
result.data[2] = m2.data[0] * data[2] + m2.data[1] * data[6] + m2.data[2] * data[10] + m2.data[3] * data[14];
result.data[3] = m2.data[0] * data[3] + m2.data[1] * data[7] + m2.data[2] * data[11] + m2.data[3] * data[15];

result.data[4] = m2.data[4] * data[0] + m2.data[5] * data[4] + m2.data[6] * data[8] + m2.data[7] * data[12];
result.data[5] = m2.data[4] * data[1] + m2.data[5] * data[5] + m2.data[6] * data[9] + m2.data[7] * data[13];
result.data[6] = m2.data[4] * data[2] + m2.data[5] * data[6] + m2.data[6] * data[10] + m2.data[7] * data[14];
result.data[7] = m2.data[4] * data[3] + m2.data[5] * data[7] + m2.data[6] * data[11] + m2.data[7] * data[15];

result.data[8] = m2.data[8] * data[0] + m2.data[9] * data[4] + m2.data[10] * data[8] + m2.data[11] * data[12];
result.data[9] = m2.data[8] * data[1] + m2.data[9] * data[5] + m2.data[10] * data[9] + m2.data[11] * data[13];
result.data[10]= m2.data[8] * data[2] + m2.data[9] * data[6] + m2.data[10] * data[10] + m2.data[11] * data[14];
result.data[11]= m2.data[8] * data[3] + m2.data[9] * data[7] + m2.data[10] * data[11] + m2.data[11] * data[15];

result.data[12]= m2.data[12] * data[0] + m2.data[13] * data[4] + m2.data[14] * data[8] + m2.data[15] * data[12];
result.data[13]= m2.data[12] * data[1] + m2.data[13] * data[5] + m2.data[14] * data[9] + m2.data[15] * data[13];
result.data[14]= m2.data[12] * data[2] + m2.data[13] * data[6] + m2.data[14] * data[10] + m2.data[15] * data[14];
result.data[15]= m2.data[12] * data[3] + m2.data[13] * data[7] + m2.data[14] * data[11] + m2.data[15] * data[15];

*this = result;
return *this;
}




I forget whether it perform pre or post multiplication. If you want to see it in context you can download my old (slightly crap) engine from www.sf.net/projects/thermite/

Hope that helps!

Share this post


Link to post
Share on other sites
Quote:
Original post by esuvs
Hi, here's the code from my old engine:


You could reduce that to 3 temp variables (1 vector) instead of 16 (4 vectors) [grin], observe (column major, pre-multiplication if i remember correctly):


#include <cstddef>

template < typename Tp >
struct vector4 {

typedef std::size_t size_type;

typedef Tp value_type;

value_type x, y, z, w;

private:

typedef value_type vector4<value_type>::* const p4[4]; //<--- pointer to data members

static const p4 v;

public:

vector4(const Tp& x_ = Tp(),
const Tp& y_ = Tp(),
const Tp& z_ = Tp(),
const Tp& w_ = Tp())
: x(x_), y(y_), z(z_), w(w_) {}

const Tp& operator[](size_type index) const {
return this->*v[index];
}

Tp& operator[](size_type index) {
return this->*v[index];
}

Tp dot(const vector4<Tp>& v) const {
return ((x * u.x) + (y * u.y) + (z * u.z) + (w * u.w));
}

};

template < typename Tp >
const typename vector4<Tp>::p4 vector4<Tp>::v = { &vector4<Tp>::x, &vector4<Tp>::y,
&vector4<Tp>::z, &vector4<Tp>::w };

template < typename Tp >
struct matrix4 {

typedef std::size_t size_type;
typedef vector4<Tp> vector_type;

vector_type i, j, k, l;

private:

typedef vector_type matrix4<Tp>::* const vec[4]; //<--- pointer to data members

static const vec v4;

public:

matrix4(const vector_type& i_ = vector_type(),
const vector_type& j_ = vector_type(),
const vector_type& k_ = vector_type(),
const vector_type& l_ = vector_type())
: i(i_), j(j_), k(k_), l(l_) {}

const vector_type& operator[](size_type index) const {
return this->*v4[index];
}

vector_type& operator[](size_type index) {
return this->*v4[index];
}

matrix4<Tp>& operator*=(const matrix4<Tp>&);

matrix4<Tp> operator*(const matrix4<Tp>&) const;

};

template < typename Tp >
const typename matrix4<Tp>::vec matrix4<Tp>::v4 = { &matrix4<Tp>::i, &matrix4<Tp>::j, &matrix4<Tp>::k, &matrix4<Tp>::l };

template < typename Tp >
inline matrix4<Tp>& matrix4<Tp>::operator*=(const matrix4<Tp>& m) {

vector_type tmp(i.x, j.x, k.x, l.x);

i.x = tmp.dot(m.i);
j.x = tmp.dot(m.j);
k.x = tmp.dot(m.k);
l.x = tmp.dot(m.l);

tmp.x = i.y; tmp.y = j.y; tmp.z = k.y; tmp.w = l.y;

i.y = tmp.dot(m.i);
j.y = tmp.dot(m.j);
k.y = tmp.dot(m.k);
l.y = tmp.dot(m.l);

tmp.x = i.z; tmp.y = j.z; tmp.z = k.z; tmp.w = l.z;

i.z = tmp.dot(m.i);
j.z = tmp.dot(m.j);
k.z = tmp.dot(m.k);
l.z = tmp.dot(m.l);

tmp.x = i.w; tmp.y = j.w; tmp.z = k.w; tmp.w = l.w;

i.w = tmp.dot(m.i);
j.w = tmp.dot(m.j);
k.w = tmp.dot(m.k);
l.w = tmp.dot(m.l);

return *this;
}

template < typename Tp >
inline matrix4<Tp> matrix4<Tp>::operator *(const matrix4<Tp>& m) const {
return matrix4<Tp>(*this) *= m;
}

Share this post


Link to post
Share on other sites
Quote:
Original post by snk_kid
You could reduce that to 3 temp variables (1 vector) instead of 16 (4 vectors) [grin], observe (column major, pre-multiplication if i remember correctly):


Thats interesting, though presumably slightly slower (ignoring the fact that mine is inlined and avoids function calls)? Actually maybe not, i'd have to count adds, mults and assigns to be sure. Probably not a lot in it.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by Halsafar
Can someone please write the operator for me!

I would be quite pleased if someone could simply provide me with their form of this function. I've seen a few examples but all of them use a 2D array, which makes more sense but is a pain in c.


give a man a fish...

Share this post


Link to post
Share on other sites
Quote:
Original post by Halsafar
I would be quite pleased if someone could simply provide me with their form of this function. I've seen a few examples but all of them use a 2D array, which makes more sense but is a pain in c.


Here's some code I wrote a while ago:


/*
NOTES:
- This takes 1D arrays, not 2D arrays, so don't try to use them.
- The number of rows in matrixB is not required, that is because it *should*
be equivelant to the number of columns in matrixA.
- The 'type' is merely for type casting.
*/

#define multiplyMatrices(result,matrixA,rowsInA,colsInA,matrixB,colsInB,type){ int resultMRow; int resultMCol; int matrixAInd; /* a 'long double' is excessive, but should handle everything OK */ long double matrixMultSum; for (resultMRow = 0;resultMRow < rowsInA;resultMRow++){ for (resultMCol = 0;resultMCol < colsInB;resultMCol++){ matrixMultSum = 0.0f; for (matrixAInd = 0;matrixAInd < colsInA;matrixAInd++){ matrixMultSum += ( matrixA[(resultMRow*colsInA)+matrixAInd] * matrixB[resultMCol+(colsInB*matrixAInd)] ); } result[(resultMRow*colsInB)+resultMCol] = (type)matrixMultSum; } } }



It's normally a *lot* prettier than this, but it should be what you're looking for.

Share this post


Link to post
Share on other sites
Quote:
Original post by esuvs
(ignoring the fact that mine is inlined and avoids function calls)?


Defining member functions inside a class is implicitly inline meaning you don't need to add the keyword inline for hints, if your referring to "dot" member function.

I highly doubt mine will be slower as it results in the same as yours with-out the redundant variables.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement