The objects in my == function for some reason have the values 0 and i get a bad excess code in my comparison when I try to run the program try comparing two different objects. I don't know what i did wrong
In my main I have
#include "vector.h"
int main()
{
Matrix<int> A;//Assume all three objects have inital values beacuse thats not the main issue
Matrix<int> B;//
Matrix<int> D;//
if(A+B==A*D)
cout<<"A+B==A*D is true"<<endl;
else
cout<<"A+B==A*D is false"<<endl;
}
In my header I have:
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
template <class T>
class Matrix{
public:
Matrix();
Matrix(T diagonal);
template<class H>
friend bool operator ==(const Matrix<H>& A,const Matrix<H>& B);
private:
const static int n=3;
T a[n][n];
};//class declaration
template <class T>
Matrix<T>::Matrix(){
for (int i=0;i<n;i++)
for (int j=0;j<n;j++)
a[i][j]=0;
}
template <class T>
Matrix<T>::Matrix(T diagonal){
for (int i=0;i<n;i++)
for (int j=0;j<n;j++)
if (i==j)
a[i][j]=diagonal;
else
a[i][j]=0;
}
bool operator ==(const Matrix<T> &A,const Matrix<T> &B)
{
int i,j;
for(int i=0;i<A.n;i++)
for(int j=0;j<B.n;j++)
//cout<<"here's a: "<<A.a[i][j]<<endl;
cout<<B.a[i][j]<<endl;
if(A.a[i][j]!=B.a[i][j])//i get a bad access code and idk y
{
return false;
}
return true;
}
Related
I created class Matrix and overloaded operator* for matrix multiplication. Inside the operator the calculations are correct but the returned result is different than this.
I tried changing this function from a friend function to a method but I got the same result.
Moreover I overloaded operators like +, - and they work fine
#include <iostream>
#include <math.h>
template<typename T> class Matrix;
template<typename T> Matrix<T> operator * (const Matrix<T>&, const Matrix<T>&);
template <typename T> class Matrix
{
public:
T *arr = nullptr;
int r, c;
friend Matrix<T> operator * <> (const Matrix<T>&, const Matrix<T>&);
Matrix(T *a, int r, int c) //parametrized constructor
{
this->arr = a;
this->r = r;
this->c = c;
}
void Print()
{
for(int i=0; i<r; i++)
{
std::cout<<"|";
for(int j=0; j<c; j++)
{
std::cout<<*(this->arr+i*c+j)<<" ";
}
std::cout<<'\b';
std::cout<<"|";
std::cout<<std::endl;
}
std::cout<<std::endl;
}
};
template <typename T> Matrix<T> operator * (const Matrix<T> &M1, const Matrix<T> &M2)
{
int r = M2.r;
int c = M1.c;
int l = M1.r;
T arr[r*c];
for(int i=0; i<r; i++)
{
for(int j=0; j<c; j++)
{
arr[i*r+j]=0;
for(int k=0; k<l; k++)
{
arr[i*r+j]+=(M1.arr[k*r+j]*M2.arr[i*l+k]);
}
std::cout<<std::endl;
}
}
//Matrix<T> x(arr, r, c);
//x.Print(); -this returns correct matrix
return Matrix<T>(arr, r, c);
}
Main
int main()
{
//here I created matrixes a and b but skipped this part of code
Matrix<int> c = a*b;
c.Print(); // - this returns wrong matrix
}
As you can see, c and x are matrices created from the same data, but I'm getting two different results.
|22 28|
|49 64|
from x.Print(), and
|4761920 4557403|
|4199040 7011960|
from c.Print().
The issue is that the Matrix constructor retains a pointer to an object that's allocated on the stack (arr). Once arr goes out of scope, any attempt to dereference the pointer will result in undefined behaviour.
You need to find a different way to manage the lifetime of the matrix data (for example, by having the matrix class keep its own copy of it).
Thanks for answers, it let me (at least partially) understand this situation.
Changing T *arr to std::vector<T> arr solved the problem.
I have an object Matrix and I overloaded the unary minus operator and I can't manage to make my program work. If I put the return type as reference it does not allow me to return the object I created inside the function, if I put the return type as Matrix then I get segmentation fault.
in the H file :
Matrix operator - () const;
in the cpp file:
Matrix Matrix::operator - () const
{
if (isValid==false)//just a validity check
return *this;
Matrix mat(*this);//copy ctor
for (int i=0;i<row;i++)
for (int j=0;j<col;j++)
mat.matrix[i][j]=-matrix[i][j];
return mat;
}
I tried many permutations of that (adding const, adding by reference) and nothing seems to work. How do I fix this ?
What follows works without any segmentation faults. You should minimize your code by removing anything unneccessary, then gradually transform it to the code below, and see at what stage your segmentation fault vanishes.
#include <iostream>
#include <vector>
using namespace std;
class Matrix {
public:
Matrix() : isValid(true), row(0), col(0) {}
Matrix(int r, int c, int val);
Matrix(const Matrix&);
Matrix operator - () const;
private:
bool isValid;
int row, col;
vector<vector<int> > matrix;
};
Matrix::Matrix(int r, int c, int val) : isValid(true), row(r), col(c) {
matrix.resize(r);
for (int i=0; i<r; i++)
matrix[i].resize(c, val);
}
Matrix::Matrix(const Matrix& m) : isValid(true), row(m.row), col(m.col), matrix(m.matrix) {}
Matrix Matrix::operator - () const
{
if (isValid==false)//just a validity check
return *this;
Matrix mat(*this);//copy ctor
for (int i=0;i<row;i++)
for (int j=0;j<col;j++)
mat.matrix[i][j]=-matrix[i][j];
return mat;
}
main() {
int r=10, c=5;
Matrix m(r, c, 1);
Matrix m1;
m1 = -m;
}
Trying to achieve Matrix multiplication through overloaded * operator with class templates.The code works on CodeBlocks (with some warnings) in Windows ,but while compiling through g++ in Ubuntu it shows some issues.Furthurmore running the './a.out' yields segmentation fault.
#include <iostream>
#define TOLERANCE 0.0001
using namespace std;
template <class T>class Matrix;
template <class T>ostream &operator<<(ostream &out,const Matrix<T>&);
//Matrix can be of any data type
template <class T> Matrix<T> &operator*( Matrix<T>&);
template <class T>
class Matrix{
private:
int rows,columns;
T **A;
public:
//Default Constructor
Matrix(){rows=0;columns=0;}
//Parameterised Constructor
Matrix(int Rows,int Cols){
rows=Rows;
columns=Cols;
A=new T*[rows];
for(int i=0; i<rows; i++)
A[i]=new T[columns];
}
void displayMatrix();
void fillMatrix(T x);
Matrix<T>& operator* ( Matrix<T> &X);//Matrix Multiply
friend ostream &operator<< <T>(ostream &out ,const Matrix<T> &X);
};
template <class T>
void Matrix<T>::displayMatrix(){
for(int i=0;i<rows ;i++ ){
for(int j=0 ;j<columns ;j++ )
cout<<A[i][j]<<" ";
cout<<endl;
}
}
template <class T>
void Matrix<T>::fillMatrix(T x){
for(int i=0; i<rows; i++)
for(int j=0; j<columns; j++)
A[i][j]=x;
}
template <class T>
Matrix<T> &Matrix<T>::operator*( Matrix<T> &X){
T sum=0;
if(columns=X.rows){
Matrix<T> Q(rows,X.columns);
for(int i=0; i<rows ;i++){
for(int j=0; j<X.columns; j++){
for(int k=0 ;k<columns ;k++ )
sum+=A[i][k]*(X.A[k][j]);
Q.A[i][j]=sum;
sum=0;
}
}
return Q;
}else{
cout<<"Something's wrong!";
return *this;
}
}
int main(){
Matrix<double> x,y,z;
x.fillMatrix(1.2);
y.fillMatrix(2.3);
z=x*y;
z.displayMatrix();
return 0;
}
I want to achieve Matrix Multiplication for generalized template in cpp.
This yields the following :
myProj.cpp: In instantiation of ‘Matrix& Matrix::operator*(Matrix&) [with T = int]’:
myProj.cpp:75:5: required from here
myProj.cpp:52:13: warning: reference to local variable ‘Q’ returned [-Wreturn-local-addr]
Matrix Q(rows,X.columns);
Local variables, or variables in nested scopes, disappear once they go out of scope. For example, in your operator* function you have the local variable Q. When you return from the function, the variable no longer exists, and the Q object will be destructed. Returning a reference to it will lead to undefined behavior.
The problem here isn't actually returning Q but that you return by reference. The solution is to return by value. It's the same for the operator+ overloaded function, it should also return by value.
Returning by value of course requires you to follow the rules of three, five or zero, which you don't do now since you don't have any assignment operator, copy- or move-constructors, or even a destructor (the last which will lead to memory leaks).
First I have Matrix template Matrix< typename T, int Roz> and specialization of this template Matrix. But the specialization is create with constructor where argument is a size of matrix. So in example code A and Z have the same dimension. So I want to make add operator work with it. But complier say: error: no match for 'operator+' in 'Z + A'. So how I need to write operator+ for Matrix wich will be work with Matrix?
Code of Matrix templates below:
template<typename T,int Roz>
class Matrix
{
public:
T tab[Roz][Roz];
int z=Roz;
Matrix()
{
for(int i=0;i<Roz;++i)
for(int j=0;j<Roz;++j)
tab[i][j]=0;
}
T& operator()(int x,int y){
return tab[x-1][y-1];
}
//Problematic operator
Matrix& operator+(Matrix<T,Roz> b)
{
Matrix<T,Roz> tmp;
for(int i=0;i<Roz;++i)
for(int j=0;j<Roz;++j)
tmp.tab[i][j]=this->tab[i][j]+b.tab[i][j];
}
friend ostream& operator<<(ostream& out, Matrix<T,Roz> &v)
{
for(int i=0;i<v.z;++i)
{
for(int j=0;j<v.z;++j)
out<<v.tab[i][j]<<" ";
out<<endl;
}
return out;
}
};
//Specialization template
template<class T>
class Matrix<T,0>
{
private:
Matrix()
{
}
public:
vector<vector<T> > tab;
int z=0;
Matrix(int z)
{
for(int i=0;i<z;++i)
tab.push_back(vector<T>(z));
this->z = z;
for(int i=0;i<z;++i)
for(int j=0;j<z;++j)
tab[i][j]=0;
}
T& operator()(int x,int y){
return tab[x-1][y-1];
}
//Problematic operator
Matrix& operator+(Matrix<T,0> b)
{
Matrix<T,0> tmp(b.z);
for(int i=0;i<z;++i)
for(int j=0;j<z;++j)
tmp.tab[i][j]=this->tab[i][j]+b.tab[i][j];
}
//Problematic operator
Matrix& operator+(Matrix<T,0> &b)
{
Matrix<T,0> tmp(b.z);
for(int i=0;i<z;++i)
for(int j=0;j<z;++j)
tmp.tab[i][j]=this->tab[i][j]+b.tab[i][j];
}
friend ostream& operator<<(ostream& out, Matrix<T,0> &v)
{
for(int i=0;i<v.z;++i)
{
for(int j=0;j<v.z;++j)
out<<v.tab[i][j]<<" ";
out<<endl;
}
return out;
}
};
When I try add for example Matrix < int,3 > and Matrix < int, 0 > this make error. How I must definie operator+ in both templates they will work together?May I have to overload operator+ in specialization template?
The code below makes error when I try add A + Z.
int main()
{
Matrix<int,3> A, B;
Matrix<int, 4> C;
Matrix<int, 0> Z(3);
A(1,1)=1;
B(1,1)=2;
Z(1,1)=1;
Z + A;//<------- here error between diffrent instance of Matrix template
}
I don't really know why you wish to add up matrices of different dimensions, but in order to do it, you must turn the method into a method template on the dimension of the matrix argument:
#include <type_traits>
template <int Roz2>
Matrix& operator+(Matrix<T,Roz2> b)
{
// check matrix argument size compatibility
std::static_assert(Roz2 >= Roz, "incompatible matrices for operator+()");
Matrix<T,Roz> tmp;
for(int i=0;i<Roz;++i)
for(int j=0;j<Roz;++j)
tmp.tab[i][j]=this->tab[i][j]+b.tab[i][j];
}
Since Matrix<T,0> is a specialization to handle dynamic dimension, you must specialize the operator for it:
// in the generic template
Matrix& operator+(Matrix<T,0> b)
{
assert (b.z < Roz, "incompatible dynamic matrix for operator+");
Matrix<T,0> tmp(b.Roz);;
for(int i=0;i<Roz;++i)
for(int j=0;j<Roz;++j)
tmp.tab[i][j]=this->tab[i][j]+b.tab[i][j];
}
and in Matrix<T,0>:
template <int Roz>
Matrix& operator+(Matrix<T,Roz> b)
{
assert(Roz >= z,"....");
Matrix<T,0> tmp(b.z);
for(int i=0;i<z;++i)
for(int j=0;j<z;++j)
tmp.tab[i][j]=this->tab[i][j]+b.tab[i][j];
}
In the above solution, however, the operator is not commutative. In order to make it so, we need to do some change:
// define a min operator as constexpr in case the existing one is not
template<typename T> constexpr
T const& rmin(T const& a, T const& b) {
return a > b ? b : a;
}
// generic operator
template <int Roz2>
Matrix<T,rmin(Roz,Roz2)>& operator+(Matrix<T,Roz2> b)
{
constexpr int R = min(Roz,Roz2);
Matrix<T,R> tmp;
for(int i=0;i<R;;++i)
for(int j=0;j<R;++j)
tmp.tab[i][j]=this->tab[i][j]+b.tab[i][j];
}
// specialized operator on Roz=0 argument
Matrix<T,0>& operator+(Matrix<T,0> b)
{
const int r = min(z,b.z);
Matrix<T,0> tmp(r);
for(int i=0;i<r;;++i)
for(int j=0;j<r;++j)
tmp.tab[i][j]=this->tab[i][j]+b.tab[i][j];
}
// specialized operator in Roz=0 template
Matrix& operator+(Matrix<T,Roz> b)
{
return b + *this;
}
You will have to duplicate the code for const & parameters taking operators (or perhaps simply get rid of the non const parameter versions which don't seem very useful in that context).
Note the use of a static assert to limit the use of the operator with matrices of equal or larger dimension (this is a C++11 feature) in the non commutative version of the operators.
See this question on the topic of min not being a constexpr function template for further details.
My Matrx class is defined as
class Matrx
{
double A[50][50];
int m,n;
public:
Matrx(void);
Matrx(int a, int b)
{
m=a;
n=b;
}
Matrx operator +(Matrx b);
Matrx Transpose(Matrx b);
Matrx operator *(Matrx b);
CString printMatrx();
void readMatrx(double a[][]);
Matrx TransposeMat(Matrx b);
};
void Matrx::readMatrx(double a[][])
{
for(int i=0;i< m;i++)
{
for(int j=0;j< n;j++)
A[i][j]=a[i][j];
}
}
The intellisense gives error like the below
1 IntelliSense: an array may not have elements of this type d:\bmadaptive_dd_v1.02\matrx.h 17 27 TestServer
Why?
How to pass a two dimensional array as argument of the function?
The problem is that when passing multidimensional arrays as parameters in C++, you must specify the dimension of the outermost array. For example:
void ThisIsIllegal(int arr[][]); // Wrong!
void ThisIsAlsoIllegal(int arr[10][]); // Also wrong
void ThisIsLegal(int arr[][10]); // Okay
If you want to be able to have a function that takes in an array of any size, you can use templates:
template <size_t N, size_t M>
void ThisIsAlsoLegal(int (&arr)[M][N]);
This last version accepts any multidimensional array of the right type, and is probably what you're looking for.
You need to properly learn about arrays and pointers. This includes the lesson "huh! They are not as useful as I thought they were". After you've gotten familiar with how arrays and pointers work exactly you should rethink your design.
For example, in my opinion, the following design has lots of advantages:
#ifndef MATRIX_HPP_INCLUDED
#define MATRIX_HPP_INCLUDED
#include <vector>
#include <algorithm>
class matrix
{
public:
typedef std::vector<double>::size_type st;
matrix() : rows_(0), cols_(0) {}
matrix(int r, int c) : rows_(r), cols_(c), coeffs_(st(r)*c,0.0) {}
void reset(int r, int c)
{ rows_=r; cols_=c; coeffs_.clear(); coeffs_.resize(st(r)*c,0.0); }
int rows() const {return rows_;}
int cols() const {return cols_;}
double const& operator()(int i, int j) const {return coeffs_[indexof(i,j)];}
double & operator()(int i, int j) {return coeffs_[indexof(i,j)];}
double const* operator[](int i) const {return &coeffs_[indexof(i,0)];}
double * operator[](int i) {return &coeffs_[indexof(i,0)];}
void swap(matrix& that)
{
std::swap(this->rows_,that.rows_);
std::swap(this->cols_,that.cols_);
this->coeffs_.swap(that.coeffs_));
}
private:
int rows_, cols_;
std::vector<double> coeffs_;
st indexof(int i, int j) const {return st(i)*cols+j;} // row major storage
};
inline void swap(matrix& a, matrix& b) {a.swap(b);}
matrix& operator+=(matrix& lhs, matrix const& rhs);
matrix operator+(matrix const& lhs, matrix const& rhs);
matrix operator*(matrix const& lhs, matrix const& rhs);
inline matrix& operator*=(matrix& lhs, matrix const& rhs)
{ matrix tmp = lhs * rhs; swap(tmp,lhs); return lhs; }
...
#endif
This way you won't waste any space for small matrices, and you can support large matrices. Also, the use of std::vector instead of a pointer member which points to dynamically allocated memory removes the need to define your own copy constructor, assignment operator and destructor.
Of course, you could use boost::multi_array as a matrix replacement but using a custom matrix class allows you to declare overloaded operators in your own namespace which is desirable due to ADL (argument dependent lookup).
You might think that this doesn't really answer your question. In that case, let me stress that I think you don't fully understand how arrays and pointers work / behave. This is something you should look up in a decent C++ book. One could write many pages about this topic. You can't expect to see a short answer explaining all the quirks.
Check out the Definite C++ Book Guide thread.
You need to specify all but the first dimension, e.g.
void Matrx::readMatrx(double a[][50])
From this you should be able to see that you have a fundamental problem with the way you have implemented your class, but at least you should now be able to get the code to compile.
You can to specify all dimensions or only last dimension to pass an array:
void Matrx::readMatrx(double a[][50])
{
for(int i=0;i< m;i++)
{
for(int j=0;j< n;j++)
A[i][j]=a[i][j];
}
}
Thanks to all of you people...you were really helping...I have found myself a new definition of the class and the function definition for the matrix that fitted my need. I need you r comment on it...Below is the example of the class declaration..
#include<iostream>
#include"stdafx.h"
using namespace std;
const int M=100; const int N=100;
class Matrix
{
double A[M][N];
int m,n;
public:
Matrix(void);
Matrix(int a, int b)
{
m=a;
n=b;
for(int i=0;i<m;i++)
{
for(int j=0;j<m;j++)
A[i][j]=0.0;
}
}
Matrix operator +(Matrix b);
Matrix operator -(Matrix b);
Matrix operator *(Matrix b);
void TransPose(Matrix b);
CString printMatrix();
void readMatrix(double*);
};
and then the function implementation
#include "stdafx.h"
#include "Matrix.h"
Matrix::Matrix(void)
{
}
Matrix Matrix::operator *(Matrix b)
{
Matrix c(m,m);
if(n!=b.m)
{
HWND hndOwner(0);
MessageBoxW(hndOwner,L"Multiplication not possible row and column does not match",L"Error",NULL);
Matrix errMat(1,0);
double er[1][1]={0}; errMat.readMatrix((double *)er);
return errMat;
}
for(int i=0;i< m;i++)
{
for(int k=0;k< m;k++)
{
c.A[i][k]=0;
for(int j=0;j< n;j++)
{
c.A[i][k] = c.A[i][k]+(A[i][j] * b.A[j][k]) ;
}
}
}
return c;
}
Matrix Matrix::operator +(Matrix b)
{
Matrix c(m,n);
if((n!=b.n)||(m!=b.m))
{
HWND hndOwner(0);
MessageBoxW(hndOwner,L"Addition not possible row and column does not match",L"Error",NULL);
Matrix errMat(1,0);
double er[1][1]={0}; errMat.readMatrix((double *)er);
return errMat;
}
for(int i=0;i<m;i++)
{
for(int j=0;j< n;j++)
{
c.A[i][j]=0.0;
}
}
for(int i=0;i< m;i++)
{
for(int j=0;j< n;j++)
{
c.A[i][j]=A[i][j]+b.A[i][j];
}
}
return c;
}
CString Matrix::printMatrix()
{
CString strB(" "),strDisp;
for(int iRow=0;iRow<m;iRow++)
{
for(int iColumn=0;iColumn<n;iColumn++)
{
strB.Format(L"%lf ",A[iRow][iColumn]);
strDisp+=strB;
}
strDisp+="\r\n";
}
return strDisp;
}
void Matrix::readMatrix(double *ptrarr)
{
for(int i=0;i< m;i++)
{
for(int j=0;j< n;j++)
A[i][j]=*(ptrarr+i*n+j);
}
}
void Matrix::TransPose(Matrix b)
{
for(int i=0;i<b.n;i++)
{
for(int j=0;j<b.m;j++)
A[i][j]=b.A[j][i];
}
}
The simple codes in the above are working well till now...if you have any suggestion for the improvement please suggest..
You're lucky, then because:
for(int j=0;j<m;j++)
A[i][j]=0.0;
should probably be:
for(int j=0;j<**n**;j++)
A[i][j]=0.0;