I have to sum of two matrices (tridiagonal), everything works, but I don't know how to call function sum in main. I tried but it reports an error. Any help or recommendations would be appreciated.
.h:
class matrix
{
public:
matrix();
~matrix();
matrix(int i, int j);
void insert();
void iz();
void sum(matrix m1, matrix m2);
private:
int i;
int j;
vector<vector<int> > v;
};
.cpp
matrix::matrix()
{
}
matrix::matrix()
{
}
matrix::matrix(int i, int j){
v.resize(i);
for (int k = 0; k < i; k++)
v[k].resize(j);
this->i = i;
this->j = j;
}
void matrix::insert()
{
int x;
for (int a = 0; a < i; a++){
for (int b = 0; b < j; b++){
if (abs(a-b) <= 1){
x = rand() % 100+1;
v[a][b] = x;
}
else
v[a][b] = 0;
}
}
}
void matrix::iz()
{
for (int a = 0; a < i; a++){
for (int b = 0; b < j; b++)
cout << v[a][b] << " ";
cout << endl;
}
}
void matrix::sum(matrix m1, matrix m2)
{
matrix m3;
int c = m1.i;
int d = m1.j;
if (m1.i == m2.i && m1.j == m2.j)
{
for (int a = 0; a < c; a++)
{
for (int b = 0; b < d; b++){
m3.v[a][b] = m1.v[a][b] + m2.v[a][b];
}
cout << endl;
}
}
else
cout << "Error" << endl;
}
main
matrix m1(6, 6);
m1.insert();
m1.iz();
cout << endl << endl;
matrix m2(6, 6);
m2.insert();
m2.iz();
Here is the problem:
/*
matrix m3;
m3.sum(m1, m2);
m3.iz();
*/
cin.ignore();
cin.get();
return 0;
The problem lies in the sum function where you create a new object matrix m3, and perfor the addition on that object, instead of this.
Do: this->v[a][b] = m1.v[a][b] + m2.v[a][b];
instead of: m3.v[a][b] = m1.v[a][b] + m2.v[a][b];
Also, you need to set the this->i and this->j variables to m1.i and m1.j, plus you should also do all your resizing of this->v too.
Related
I wrote a program to add, subtract and multiply two matrices together. I overloaded the operators +, -, and * for this purpose, but when I use them in the main, I get an error which says:
no operator "+" matches these operands I can't figure out the problem. Maybe I used incorrect logic to overload the operators for class and now I'm stuck with it. The Code is below
#include <iostream>
#include <conio.h>
#include <string>
#include <ctime>
using namespace std;
class ERROR
{
public:
string E = "Number of Columns of Matrix A is not Equal to Number of Rows of Matrix B";
};
class MATRIX
{
private:
static const int number = 100;
int matrix[number][number];
int n;
int m;
public:
MATRIX();
MATRIX(int,int);
void display();
MATRIX operator+(MATRIX x[]);
MATRIX operator-(MATRIX x[]);
MATRIX operator*(MATRIX x[]);
MATRIX operator=(MATRIX x[]);
};
int main()
{
srand(time(0));
MATRIX x(2, 2), y(2, 2);
cout << "Matrix 1 " << endl;
x.display();
cout << endl;
cout << "Matrix 2 " << endl;
y.display();
cout << endl;
MATRIX z(2, 2);
z = x + y;
}
// Constructors of Class Matrix
MATRIX::MATRIX()
{
n = number; m = number;
for (int loop = 0; loop < number; loop++)
{
for (int loop2 = 0; loop2 < number; loop2++)
{
matrix[loop][loop2] = 1 + rand() % 50;
}
}
}
MATRIX::MATRIX(int rows, int col)
{
n = rows; m = col;
for (int loop = 0; loop < n; loop++)
{
for (int loop2 = 0; loop2 < m; loop2++)
{
matrix[loop][loop2] = 1 + rand() % 50;
}
}
}
// Display function for Class
void MATRIX::display()
{
for (int loop = 0; loop < n; loop++)
{
for (int loop2 = 0; loop2 < m; loop2++)
{
cout << matrix[loop][loop2] << " ";
}
cout << endl;
}
cout << endl;
}
// Operators Overloaded for Array
MATRIX MATRIX::operator+(MATRIX x[])
{
MATRIX z(n,m);
for (int loop = 0; loop < n; loop++)
{
for (int loop2 = 0; loop2 < m; loop2++)
{
z.matrix[loop][loop2]= matrix[loop][loop2] + x->matrix[loop][loop2];
}
}
return z;
}
MATRIX MATRIX::operator-(MATRIX* x)
{
MATRIX z(n, m);
for (int loop = 0; loop < n; loop++)
{
for (int loop2 = 0; loop2 < m; loop2++)
{
z.matrix[loop][loop2] = matrix[loop][loop2] - x->matrix[loop][loop2];
}
}
return z;
}
MATRIX MATRIX::operator*(MATRIX x[])
{
try
{
if (m == x->n)
{
MATRIX *y[number][number];
for (int loop = 0; loop < n; loop++)
{
for (int loop2 = 0; loop2 < m; loop2++)
{
for (int loop3 = 0; loop3 < m; loop3++)
{
y[loop][loop2] += matrix[loop][loop3] * x->matrix[loop3][loop2];
}
}
}
return *this;
}
throw;
}
catch (ERROR e)
{
cout << e.E << endl;
_getch();
exit(1);
}
}
MATRIX MATRIX::operator=(MATRIX x[])
{
for (int loop = 0; loop < n; loop++)
{
for (int loop2 = 0; loop2 < m; loop2++)
{
matrix[loop][loop2] = x->matrix[loop][loop2];
}
}
return *this;
}
You've defined the operator + between a MATRIX and a MATRIX[] (i.e., an array of MATRIXs). You should amend the definition to operate on a MATRIX and another MATRIX:
MATRIX operator+(MATRIX x);
and of course, amend the implementation accordingly.
EDIT:
As Fabien mentioned in the comments, using a const reference will save copying the second operand when using this operator:
MATRIX operator+(const MATRIX& x);
A great deal of unexpected numbers outputted on my console window when I compiled and ran the program.
The class "matrix" is declared as below:
class matrix
{
public:
vector<vector<int> > M;
matrix();
matrix(int m, int n);
matrix(vector<vector<int> > &m);
matrix Mul(matrix m1);
void Inverse();
bool SquareMatrix();
void GetDet();
int Det(vector<vector<int> > &m);
void Print();
};
the member function "Mul":
matrix matrix::Mul(matrix m1)
{
vector<vector<int> > Temp(M.size(), vector<int>(m1.M[0].size(), 0));
if (M[0].size() != m1.M.size())
{
cout << "Cannot do multiplication!" << endl;
return matrix();
}
else
{
for (int i = 0; i < M.size(); i++)
{
for (int j = 0; j < m1.M[0].size(); j++)
{
int ele_buf = 0;
for (int k = 0; k < M[0].size(); k++)
{
ele_buf += M[i][k] * m1.M[k][j];
}
Temp[i][j] = ele_buf;
}
}
}
int d1 = M.size(), d2 = m1.M[0].size();
for (int i = 0; i < M.size(); i++)
{
M[i].clear();
}
M.clear();
M.resize(Temp.size(), vector<int>(Temp[0].size(), 0));
for (int i = 0; i < d1; i++)
{
for (int j = 0; j < d2; j++)
{
M[i][j] = Temp[i][j];
}
}
}
M[i][j] hold the expected value at this point.
the member function "Print":
void matrix::Print()
{
for (int i = 0; i < M.size(); i++) {
for (int j = 0; j < M[0].size(); j++) {
cout << M[i][j] << " ";
}
cout << endl;
}
}
Output wrong M.
main:
/*
call constructor to initialize m1 and m2
*/
//...
matrix m3 = m1.Mul(m2);
m3.Print();
//...
How can I fix it?
I'm new here, plz let me know if I didn't make my question clear.
Editted:
matrix matrix::Mul(matrix m1)
{
vector<vector<int> > Temp(M.size(), vector<int>(m1.M[0].size(), 0));
if (M[0].size() != m1.M.size())
{
cout << "Cannot do multiplication!" << endl;
return matrix();
}
else
{
//TO_DO: Multiply two matrixes and print the result.
for (int i = 0; i < M.size(); i++)
{
for (int j = 0; j < m1.M[0].size(); j++)
{
int ele_buf = 0;
for (int k = 0; k < M[0].size(); k++)
{
ele_buf += M[i][k] * m1.M[k][j];
}
Temp[i][j] = ele_buf;
}
}
}
int d1 = M.size(), d2 = m1.M[0].size();
for (int i = 0; i < M.size(); i++)
{
M[i].clear();
}
M.clear();
return matrix(Temp);
}
Functionning properly,
thanks.
You forgot to add a return statement, which is trivial to fix. However, your code is not written in a good OO manner, so here come few suggestions for the improvement:
don't pass matrix m1 by value, because you are paying an expensive copy each time you invoke this function; use const matrix& m1 instead
in the body of Mul you are modifying member M, which is a serious side effect; remove the part of code:
int d1 = M.size(), d2 = m1.M[0].size();
for (int i = 0; i < M.size(); i++)
{
M[i].clear();
}
M.clear();
instead of implementing a separate function called Mul, overload the * operator (see e.g. here and here)
You are promised to return matrix from the Mul function
matrix matrix::Mul(matrix m1);
^^^^^^
and you did not keep the promise. This can cause undefined behaviour to your program.
Add an proper return statement in the function.
matrix matrix::Mul(matrix m1)
{
// ... code
return *this; // matrix(Temp) itself
}
I am trying to write a class that do matrix multiplication. The
class matrix declared like below:
class matrix
{
public:
vector<vector<int> > M;
matrix();
matrix(int m, int n);
matrix(vector<vector<int> > &m);
matrix Mul(matrix m1);
void Inverse();
bool SquareMatrix();
void GetDet();
int Det(vector<vector<int> > &m);
void Print();
};
I initialize and enter the elements of the matrix M in this constructor:
matrix::matrix(int m, int n)
{
vector<vector<int> > M(m, vector<int>(n, 0));
cout << "Enter the elements: " << endl;
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
cin >> M[i][j];
}
}
}
However, the member function "Mul" do not receive the data I input through the constructor.
matrix matrix::Mul(matrix m1)
{
int **ppInt;
ppInt = new int *[M.size()];
for (int i = 0; i < M.size(); i++)
{
ppInt[i] = new int[m1.M[0].size()];
}
if (M[0].size() != m1.M.size())
{
cout << "Cannot do multiplication!" << endl;
return matrix();
}
else
{
for (int i = 0; i < M.size(); i++)
{
for (int j = 0; j < m1.M[0].size(); j++)
{
int ele_buf = 0;
for (int k = 0; k < M[0].size(); k++)
{
ele_buf += M[i][k] * m1.M[k][j];
}
ppInt[i][j] = ele_buf;
}
}
}
int d1 = M.size(), d2 = m1.M[0].size();
for (int i = 0; i < M.size(); i++)
{
M[i].clear();
}
M.clear();
for (int i = 0; i < d1; i++)
{
for (int j = 0; j < d2; j++)
{
M[i][j] = ppInt[i][j];
}
}
}
How can I fix it?
Please let me know if my problem is not clear enough.
I initialize and enter the elements of the matrix M in this
constructor!
No! You are working with a local M, not with the member M.
In the constructor
matrix::matrix(int m, int n)
{
vector<vector<int> > M(m, vector<int>(n, 0)); // local to the constructor only!
// .........
}
the M is local to the scope of the constructor, which shadows the member you defined with the same name M. Therefore it (i.e the one in the constructor) will be destroyed after the constructor scope. In effect, the member M will never get initialized.
How can I fix it?
In order to fix, you might want to std::vector::resize the member M
matrix(int m, int n)
{
M.resize(m, vector<int>(n, 0)); // resize M with `m` and `n`
std::cout << "Enter the elements: " << std::endl;
for (std::vector<int>& row : M)
for (int& ele : row)
std::cin >> ele; // fill the elements
}
I initialize and enter the elements of the matrix M in this constructor:
No you don't. You are initializing a vector called M that shadows the member with the same name. The M in the constructor is a different vector that is local to the constructor.
To initialize members, use the initializer list:
matrix::matrix(int m, int n) : M(m, vector<int>(n, 0)) {
cout << "Enter the elements: " << endl;
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
cin >> M[i][j];
}
}
}
My program compiles but has these problems:
It's not using the member function fill (now). When i got the fill function to work (a while ago), it didn't do adding, subtracting, and multiplication correctly because it didn't record the second matrix it was supposed to do those things with. I got it to work the way you see it now, but this is the result:
ubuntu:~/Desktop$ ./matrix
2
2
enter the matrix element by element(starting from the first row)
1
2
1
2
Segmentation fault (core dumped)
If someone can point out the mistakes, it would be greatly appreciated:
#include <iostream>
#include <cmath>
using namespace std;
class matrix
{
private:
int r;
int c;
double** arr;
double** arr2;
public:
matrix()
{
r = 1;
c = 1;
arr = 0;
arr2 = 0;
}
matrix(int rows, int columns)
{
r = row(r);
c = column(c);
arr = new double* [r];
for(int i =0; i<r; i++)
{
arr[i] = new double[c];
}
}
matrix(matrix& a)
{
r = a.row(r);
c = a.column(c);
arr = new double* [r];
for(int i =0; i<r; i++)
{
arr[i] = new double[c];
}
}
~matrix()
{
for( int i = 0 ; i < r ; i++ )
{
delete [] arr[i];
}
delete [] arr;
}
void copy()
{
arr2 = new double* [r];
for(int i =0; i<r; i++)
{
arr2[i] = new double[c];
}
for (int i=0; i<r; i++)
{
for(int j=0; j<c; j++)
{
arr2[i][j] = arr[i][j];
}
}
}
int row(int r)
{
return r;
}
int column(int c)
{
return c;
}
void fill(const int& r, const int& c)
{
for (int i=0; i<r; i++)
{
for(int j=0; j<c; j++)
{
cin>>arr[i][j];
}
}
}
void print()
{
for (int i=0; i < r; i++)
{
for (int j=0; j<c; j++)
{
cout<<arr[i][j]<<" ";
}
cout<<endl;
}
}
void sum()
{
double ** arr2 = arr;
cout << "enter the matrix you want to add" << endl;
fill(r, c);
for (int i=0; i<r; i++)
{
for(int j=0; j<c; j++)
{
arr[i][j] = (arr2[i][j] + arr[i][j]);
}
}
print();
}
void sub()
{
double ** arr2 = arr;
cout << "enter the matrix you want to subtract" << endl;
fill(r,c);
for (int i=0; i<r; i++)
{
for(int j=0; j<c; j++)
{
arr[i][j] = (arr2[i][j]) - (arr[i][j]);
}
}
print();
}
void multiplication()
{
double ** arr2 = arr;
cout << "enter the matrix you want to multiply by" << endl;
fill(r,c);
int k =0;
double ** arrm = arr;
for(int i=0;i< r;i++)
{
for(int j=0;j< c;j++)
{
arrm[i][j] = 0;
for(k=0;k< r;k++)
{
arrm[i][j] = arrm[i][j] + arr2[i][k] * arr[k][j];
}
}
}
print();
}
bool check(const int r, const int c)
{
if(r==c)
{return true;}
else
{return false;}
}
void get_det(const int r, const int c)
{
if(check(r,c) == true)
{
int n = r;
Determinant(arr,n);
cout <<"the determinant is: "<< endl;
}
else
{
cout << "can't" << endl;
}
}
double Determinant(double** arr, int n)
{
double det = 0;
double** m = NULL;
if (n == 1)
{ det = arr[0][0];}
else if (n == 2)
{
det = arr[0][0] * arr[1][1] - arr[1][0] * arr[0][1];
}
else if (n == 3)
{
det = arr[0][0]*(arr[1][1]*arr[2][2] - arr[1][2]*arr[2][1])
+ arr[0][1]*(arr[1][2]*arr[2][0] - arr[1][0]*arr[2][2])
+ arr[0][2]*(arr[1][0]*arr[2][1] - arr[1][1]*arr[2][0]);
}
else if (n > 3)
{
for (int j1=0;j1<n;j1++)
{
m = new double* [n-1];
for (int i=0;i<n-1;i++)
m[i] = new double[n-1];
for (int i=1;i<n;i++)
{
int j2 = 0;
for (int j=0;j<n;j++)
{
if (j == j1) continue;
m[i-1][j2] = arr[i][j];
j2++;
}
}
det += pow(-1,1+j1+1) * arr[0][j1] * Determinant(m,n-1);
for (int i=0;i<(n-1);i++)
delete m[i];
delete m;
}
}
return(det);
}
};
int main()
{
int r,c,answer;
cin >> r >> c;
matrix g(r,c);
cout << "enter the matrix element by element(starting from the first row)" << endl;
g.fill(r,c);
cout << "do you want add (1=yes / 0=no)" << endl;
cin >> answer;
if(answer == 1)
{
g.sum();
}
else{}
cout << "do you want subtract (1=yes / 0=no)" << endl;
cin >> answer;
if(answer == 1)
{
g.sub();
}
else{}
cout << "do you want multiply (1=yes / 0=no)" << endl;
cin >> answer;
if(answer == 1)
{
g.multiplication();
}
else{}
cout << "do you want to know the determinant (1=yes / 0=no)" << endl;
cin >> answer;
if(answer == 1)
{
g.get_det(r,c);
}
else{}
return 0;
}
I have a program that is suppose to add together two matrices but when it gets to the add part in the main it just gets stuck and does nothing. I have messed with this for quite some time but to no avail. Any help or recommendations would be appreciated.
#include <iostream>
using namespace std;
class matrix
{
private:
int **p, m, n;
public:
matrix(int row, int col)
{
m = row;
n = col;
p = new int*[m];
for (int i = 0; i < m; i++)
p[i] = new int[n];
}
~matrix()
{
for (int i = 0; i < m; i++)
delete p[i];
delete p;
}
void fill()
{
cout<<"Enter the matrix elements:";
for(int i = 0; i < m; i++)
{
for(int j = 0; j < n; j++)
{
cin >> p[i][j];
}
}
}
void display()
{
cout <<"The matrix is:";
for(int i = 0; i < m; i++)
{
cout << endl;
for(int j = 0; j < n; j++)
{
cout << p[i][j] <<" ";
}
}
cout << endl;
}
matrix operator +(matrix m2)
{
matrix T(m, n);
for(int i = 0; i < m; i++)
{
for(int j = 0; j < n; j++)
{
T.p[i][j] = p[i][j] + m2.p[i][j];
}
}
return T;
}
matrix operator =(matrix eq)
{
m = eq.m;
n = eq.n;
p = eq.p;
return *this;
}
friend matrix operator *(matrix, matrix);
};
matrix operator *(matrix a , matrix b)
{
matrix B(1,1);
if(a.n == b.m)
{
matrix T(a.m, b.n);
for(int i = 0; i < a.m; i++)
{
for(int k = 0; k < b.n; k++)
{
T.p[i][k] = 0;
for(int j = 0; j < a.n; j++)
{
T.p[i][k]+= a.p[i][j] * b.p[j][k];
}
}
}
B = T;
}
return B;
}
int main()
{
matrix a(3,3), b(3,3);
a.fill();
a.display();
b.fill();
b.display();
cout << "addition of a and b\n";
b = b + a;
b.display();
cout << "multiplication of a and b\n";
b = (a * b);
b.display();
}
Your program is violating the rule of big three: it has a destructor but no assignment operator and no copy constructor. It keeps the data using raw pointers, but it's not managing proper ownership with copies are done and assignments are performed.
When your matrix class is copied and assigned your program is entering the Undefined Behavior territory so anything can happen. In this code copy construction is done implicitly when passing a matrix parameter by value, and assignment is done explicitly in main.