I'm trying to use matrix multiplication to multiply b onto a. Using the method I've written below, changes the values of matrix A which I've then realised messes up later calculations.

Would the best way to get around this be to make two copies of the matrices A and B in two second vectors?

Or does anyone know of a more efficient method?

Thanks in advance!

``````void Matrix::Multiply(Matrix b)
{
for (int i = 0; i < cols; i++)
{
for (int j = 1; j <= cols; j++)
{
data_[i] = (data_[(i % cols)+(j-1)*cols])*(b.data_[(i/cols)+(j-1)]);
}
}
}
//Multiply b to this matrix``````
4
Contributors
10
Replies
11
Views
7 Years
Discussion Span
Last Post by sexyzebra19
Featured Replies
• 1

I wouldn't make duplicates of A and B, but put the results in matrix C so that A and B are left unchanged.

• 2

Rewrite [inlinecode]void Matrix::Multiply(Matrix b) ;[/inlinecode] as [inlinecode]Matrix Matrix::Multiply( const Matrix& b ) const ;[/inlinecode] In the implementation, do not modify either of the two Matrix objects involved in the multiply. Construct a new result Matrix object of the appropriate size, populate it and return it. Ok, I see that Dragon …

• 1
jonsca 1,059   7 Years Ago

Take a closer look at your index on your b.data_ vector on line 15. The pattern that you have is this: [code] i,j,index of A,index of B 0,1 0 0 0,2 2 1 1,1 1 0 1,2 3 1 2,1 0 1 2,2 2 2 3,1 1 1 3,2 3 …

• 1
jonsca 1,059   7 Years Ago

That's not what I got, I just tried it you run off the end of the array. I had along the lines of [icode] copy[i] = copy[i]+ (A[(i % cols)+(j-1)*cols])*(B[(i/cols)+(j-1)+(i+1)%cols]); [/icode] Since the i value is the same you don't need to change that first array indexes at all but …

I wouldn't make duplicates of A and B, but put the results in matrix C so that A and B are left unchanged.

Rewrite `void Matrix::Multiply(Matrix b) ;` as `Matrix Matrix::Multiply( const Matrix& b ) const ;` In the implementation, do not modify either of the two Matrix objects involved in the multiply. Construct a new result Matrix object of the appropriate size, populate it and return it.

Ok, I see that Dragon has preempted me.

Votes + Comments
Was thinking the same thing

My code doesn't seem to be giving me the correct answer...

Testing it with matrix A

1 2
3 4

and Matrix B

5 6
7 8

which should give

19 22
43 50

I have worked the first two out with paper and pencil, and get:

copy[0] = copy[0] + data[0]*b.data[0] = 5
copy[0] = 5 + data[2]*b.data[1] = 19

copy[1] = copy[1] + data[1]*b.data[0] = 15
copy[1] = 15 + data[3]*b.data[1] = 43

However I am getting 23 34 27 40 ?? Can anyone see please explain why?

Thanks in advance!

``````void Matrix::Multiply(Matrix b)
{
vector<double> copy;
data_.resize (cols*b.cols);
copy.resize (cols*b.cols);
for (int i = 0; i < data_.size(); i++)
{
copy[i] = 0;
}

for (int i = 0; i < data_.size(); i++)
{
for (int j = 1; j <= cols; j++)
{
copy[i] = copy[i] + (data_[(i % cols)+(j-1)*cols])*(b.data_[(i/cols)+(j-1)]);
}
}

for (int i = 0; i < data_.size(); i++)
{
data_[i] = copy[i];
cout<<" "<<data_[i]<<" ";
}
}``````

Edited by sexyzebra19: n/a

Take a closer look at your index on your b.data_ vector on line 15.
The pattern that you have is this:

``````i,j,index of A,index of B
0,1 0 0
0,2 2 1
1,1 1 0
1,2 3 1
2,1 0 1
2,2 2 2
3,1 1 1
3,2 3 2``````

Now if you go through the calculation by hand that's not the right order for the i = 2 and 3's (it happens to work for the i = 0 and i = 1 cases)
For those you need something like this:

``````i,j,index of A,index of B
2,1 0 2
2,2 2 3
3,1 1 2
3,2 3 3``````

See what you get for the equation and then we can compare.

Also, you need to clear copy before each time you go through the js, that's why your answers were so high.

Edited by jonsca: n/a

Take a closer look at your index on your b.data_ vector on line 15.
The pattern that you have is this:

``````i,j,index of A,index of B
0,1 0 0
0,2 2 1
1,1 1 0
1,2 3 1
2,1 0 1
2,2 2 2
3,1 1 1
3,2 3 2``````

Now if you go through the calculation by hand that's not the right order for the i = 2 and 3's (it happens to work for the i = 0 and i = 1 cases)
For those you need something like this:

``````i,j,index of A,index of B
2,1 0 2
2,2 2 3
3,1 1 2
3,2 3 3``````

See what you get for the equation and then we can compare.

Hi Jonsca, thanks for pointing out it didn't work for the latter cases, should have spotted that.

The new formula I have for line 15 is:

copy = copy + (data_[(i % cols)+(j-1)*cols])*(b.data_[(i/cols)+(i+(j-1))]);

Hope this is better!

That's not what I got, I just tried it you run off the end of the array. I had along the lines of `copy[i] = copy[i]+ (A[(i % cols)+(j-1)*cols])*(B[(i/cols)+(j-1)+(i+1)%cols]);` Since the i value is the same you don't need to change that first array indexes at all but you have to follow that 2/3/2/3 pattern for the second array.

Ahhhh i see, thank you very much Jonsca.

On second thoughts, I don't think

copy = copy+ (A[(i % cols)+(j-1)*cols])*(B[(i/cols)+(j-1)+(i+1)%cols]);

works as it would give

copy[0] = copy[0] (A[0]*B[1])

when I need

copy[0] = copy[0] (A[0]*B[0])

beginning to think this formula is impossible...!

cols = 2, right? I had made a goof on my cout (I had the old value for the formula) but I had it right when I was actually doing the manipulations. See my test program.

Attachments
``````#include<iostream>
#include<vector>
using namespace std;

int main()
{
int copy [] = {0};
vector<int> A;
vector<int> B;
A.push_back(1);
A.push_back(3);
A.push_back(2);
A.push_back(4);
B.push_back(5);
B.push_back(7);
B.push_back(6);
B.push_back(8);
int cols = 2;
for (size_t i = 0; i < A.size(); i++)
{
copy[i] = 0;
for (int j = 1; j <= cols; j++)

{
cout<<i<<","<<j<<" "<<i%cols +(j-1)*cols<<" "<<i/cols+(j-1)+(i+1)%cols<<endl;
//had left off the +(i+1)%cols                                ^^^^^^^

copy[i] = copy[i]+ (A[(i % cols)+(j-1)*cols])*(B[(i/cols)+(j-1)+(i+1)%cols]);

}

}
for (int i =0;i<4;i++)
cout<<copy[i]<<" ";
cout<<endl;

}

//2,1 0 2
//2,2 2 3
//3,1 1 2
//3,2 3 3``````

cols = 2, right? I had made a goof on my cout (I had the old value for the formula) but I had it right when I was actually doing the manipulations. See my test program.

Hi Jonsca,

Thanks for that, I just looked at your test program, however it is giving the last element wrongly, it should be

19 43 22 50

but your formula is showing

19 43 22 45.

I've managed to get it working for the above case using

``copy[i] = copy[i] + (data_[(i % ndim_)+(j-1)*ndim_])*(b.data_[(i/ndim_)+(j-1)+(i/ndim_)]);``

however I tested it for a 3x2 matrix multiplied by a 2x2 matrix and it didn't work....this is driving me crazy :'(

Edited by sexyzebra19: n/a

This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.