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:
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];
}
}
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.
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.
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.
... 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
//#include "stdafx.h"
#include <iostream> // <===== Remove unnecessary headers
#include <fstream>
#include <cstdlib>
usingnamespace 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 = newdouble[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 = newdouble*[k];
for ( int i = 0; i < k; i++ ) A[i] = newdouble[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 = newdouble[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;
}
//======================================================================
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.
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 :)
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