crin
crin

Reputation: 73

Matrix and vector multiplication, outputting incorrect product

I've created a Vector and Matrix class and I am trying to perform operations such as the multiplication of a matrix and vector, the multiplication of a matrix and matrix, and the multiplication of a matrix and a float (scalar). I seem to be having problem getting the right product for the matrix * vector and matrix * matrix. Here is the part of Matrix class meant to handle those operations:

// Matrix * vector, result vector
Vector Matrix::operator*(const Vector & other) const
{
if (other.getDimensions() == 4)
{
    float floats[4];
    const float* temp = other.getData();
    for (int j = 0; j < 4; j++)
    {
        Vector myCol = column(j);
        floats[j] = (temp[0] * myCol.getData(0)) + (temp[1] * myCol.getData(1)) + (temp[2] * myCol.getData(2)) + (temp[3] * myCol.getData(3));
    }
    return Vector(floats[0], floats[1], floats[2], floats[3]);
}
else
{
    return Vector();
}
}

// Matrix * scalar, result matrix
Matrix Matrix::operator*(float c) const 
{
Matrix myMatrix;
for (int i = 0; i < 16; i++)
{
    myMatrix.data[i] = this->data[i] * c;
}
return myMatrix;
}

In my main.cpp,

Matrix m = Matrix(Vector(1, 0, 0, 1), Vector(0, 1, 0, 2), Vector(0, 0, 1, 3), Vector(0, 0, 0, 1));

Is the value of the matrix and

    v = Vector(1, 0, -1, 1);

Is the value of the vector. When I multiply m * v I get <1, 0, -1, -1>, but the answer is <2, 2, 2, 1>.

And when doing the matrix * scalar with the same m matrix above and vector v with the values

v = Vector(1, 0, -1, 0);

I get m*v to be <1, 0, -1, 2> when it should be <1, 0, -1, 0>. My Vector class works fine so I'm suspecting I messed up somewhere with the math for implementing the matrix operations.

Upvotes: 0

Views: 281

Answers (2)

Klaus
Klaus

Reputation: 538

I calculated your example by hand now, and if you expect the result to be <2, 2, 2, 1>, then you definitely swapped rows and columns in your matrix. When you multiply a matrix with a vector you want to put the products of the rows of the matrix and the vector in a result vector. Kind of:

Vector Matrix::operator*(const Vector & other) const
{
    float floats[4];
    const float* temp = other.getData();
    for (int j = 0; j < 4; j++)
    {
        Vector my_row = row(j);
        floats[j] = 0;
        for(int i=0; i!=4; ++i)
            floats[j]+=temp[i] * myCol.getData(i);
    }
    //(maybe provide a better constructor to take an array)
    return Vector(floats[0], floats[1], floats[2], floats[3]);
}

For the example with the scalar, I don't get the point. I don't understand how you expect a multiplication of a matrix with a scalar if you are multiplying a matrix with a vector.

Also you could improve the error handling by only accepting vectors of size 4 (imposing that as a requirement in your vector class), if you just use vectors of size 4.

PS: maybe you should also put your addition code in the loop, into a second loop, so that it is more readable and expandable.

Upvotes: 1

user58697
user58697

Reputation: 7923

To expand on @Klaus answer, mathematically in the expression M*V the vector V is a column, and the elements of the result are (dot-)products of matrix rows and V. Replace column(j) with row(j).

Upvotes: 1

Related Questions