Matrix vector multiplication problem

Greetings C++ pals!
I had an excercise in my assignment to read a vector and a matrix from 2 .txt files and than write the multiplication of the vector with the matrix into another .txt file. I succeded in creating the matrix and the vector through dynamic arrays but I had a problem with the multiplication. As the title describes the matrix only multiplicates with the first line/number of the vector. I can't seem to figure it out.
Any help would be appreciated.
Here's the code:

#include "stdafx.h"
#include <math.h>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

int main()
{
//Creating vector 'v' from "v.txt" file

ifstream vfile("v.txt");
if (!vfile.is_open()) {
cout << "Couldn't open v.txt" << endl;
}
int m, n;
double a;
vfile >> m >> n;
double *v = new double[m];
for (int i = 0; i < m; i++)
{
vfile >> a;
v[i] = a;
}


//Creating matrix 'A' from "A.txt" file

ifstream Afile("A.txt");
if (!Afile.is_open()) {
cout << "Couldn't open A.txt" << endl;
}
int k, l;
double z;
Afile >> k >> l;
double **A = new double*[k];
for (int i = 0; i < k; i++) A[i] = new double[l];
for (int i = 0; i < k; i++)
{
for (int j = 0; j < l; j++)
{
Afile >> z;
A[i][j] = z;
}
}


//Storing the product of matrix 'A' and vector 'v' in matrix 'p'

double **p = new double*[k];
for (int i = 0; i < k; i++) p[i] = new double[l];
for (int i = 0; i < k; i++) {
for (int j = 0; j < l; j++)
{
p[i][j] = A[i][j] * v[i];
}
}

return 0;
}
shouldnt it be += instead of = for p's assignment?
the matrix * vector product is row1[0] * v[0] + row1[1]*v[1] ... row1[n]*v[n] repeated for all rows. Seems p should also be initialized to zeros.

The result of this should always be a vector, not a 2-d, though you can of course store it as a 1XN or Nx1 2-d if you like.

Right?
From the code, it looks like the matrix file has the number of rows and columns first, followed by the each row. However, I'd expect the vector to have a single number, the number of entries; but you attempt to read number of rows/columns as you do for the vector. This means you'll loose the first vector value.

Check this out: https://en.wikipedia.org/wiki/Matrix_multiplication
The product of a matrix and a vector is another matrix, not a vector. You're producing a vector.

Have you covered structs, functions and/or classes? If you have done any of these, you can move the complexity out of main to create something that's easier to verify correct.
unless I am having a dumb moment (and I have plenty of them) ... matrix * vector is a vector, where each element of the result vector is a sum of several terms.

I think you can explode a vector * vector to a matrix (or a single value, depending on 1xN and Mx1 order becomes 1x1 or MxN ) but in general vector * matrix is undefined and matrix * vector reduces to a column.

Or, am I totally scrambled today?

... but in general vector * matrix is undefined ...

depends on their respective dimensions - in linear algebra, which seems to be the basis of OP's assignment, a vector of n elements is represented as a (n x 1) matrix (i.e. the default representation is that of a column vector) which can be pre-multiplied with any (n x m) matrix to produce another (n x m) matrix
OP: for file reading problems it generally helps to have the file data as well
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
//#include "stdafx.h"
#include <iostream>                    // <===== Remove unnecessary headers
#include <fstream>
#include <cstdlib>
using namespace std;


int main()
{
   // Creating vector 'v' from "v.txt" file
   ifstream vfile( "v.txt");
   if ( !vfile.is_open() )
   {
      cout << "Couldn't open v.txt" << endl;
      exit( 1 );                       // <===== In this circumstance ... stop!
   }
   int m, n;
   vfile >> m >> n;                    // <===== v will have m rows; n is redundant
   double *v = new double[m];
   for ( int i = 0; i < m; i++ )
   {
      vfile >> v[i];                   // <===== read direct into v
   }
   vfile.close();                      // <===== good to be tidy


   // Creating matrix 'A' from "A.txt" file
   ifstream Afile( "A.txt" );
   if ( !Afile.is_open() )
   {
      cout << "Couldn't open A.txt" << endl;
      exit( 1 );                  
   }
   int k, l;
   double z;                           // <===== A will have k rows and l columns
   Afile >> k >> l;
   if ( l != m )                       // <===== unless this is true we ain't goin' anywhere
   {
      cout << "Matrix and vector are incompatible for multiplication" << endl;
      exit( 1 );                  
   }
   double **A = new double*[k];
   for ( int i = 0; i < k; i++ ) A[i] = new double[l];

   for ( int i = 0; i < k; i++ )
   {
      for ( int j = 0; j < l; j++ )
      {
         Afile >> A[i][j];             // <===== Read straight into A
      }
   }
   Afile.close();


   // Storing the product of matrix 'A' and vector 'v' in VECTOR 'p'
   // Matrix ( k rows and l columns ) times a vector ( l rows ) gives a VECTOR ( k rows )
   double *p = new double[k];          // <===== Just one index

   // Do the multiply
   for ( int i = 0; i < k; i++ )
   {
      p[i] = 0;                        // <===== Needs initialising
      for ( int j = 0; j < l; j++ )
      {
         p[i] += A[i][j] * v[j];       // <===== Add terms to sum for ith element
      }
   }


   // Write out
   ofstream pfile( "p.txt" );
   pfile << k << " " << 1 << "\n\n";
   for ( int i = 0; i < k; i++ ) pfile << p[i] << endl;
   pfile.close();


   // Tidy up
   delete [] p;
   delete [] v;
   for ( int i = 0; i < k; i++ ) delete [] A[i];
   delete [] A;
}


//====================================================================== 


a.txt
3  2

1.0  2.0
3.0  4.0
5.0  6.0


v.txt
2 1

10.0
20.0


Result in p.txt
3 1

50
110
170


Last edited on
From the code, it looks like the matrix file has the number of rows and columns first, followed by the each row. However, I'd expect the vector to have a single number, the number of entries; but you attempt to read number of rows/columns as you do for the vector. This means you'll loose the first vector value.

Check this out: https://en.wikipedia.org/wiki/Matrix_multiplication
The product of a matrix and a vector is another matrix, not a vector. You're producing a vector.

Have you covered structs, functions and/or classes? If you have done any of these, you can move the complexity out of main to create something that's easier to verify correct.

Yes, the first two rows in both of the files have the number of rows and columns; so 500 500 for the matrix and 500 1 for the vector file.
No I still haven't covered functions, structs, etc that's why I stuffed everything in the main funct :)
Last edited on
shouldnt it be += instead of = for p's assignment?

Ok so ultimately this was the mistake. I forgot about the adding up part so the code I posted was supposed to just give the product of each matrix row with the vector for which (out of curiosity) I also found the mistake:
1
2
3
4
for (int j = 0; j < l; j++)
{
p[i][j] = A[i][j] * v[i];  //<----- it should be v[j] instead
}


Anyhoo big thanks to all of you especially @lastchance for also cleaning up the code and giving a really clear, detailed solution.
Unfortunately i think more of this is coming. #proceduralprogramming
Best wishes :D
Topic archived. No new replies allowed.