I am doing an addition of matrices using classes.I have declared a class 'Matrix'.now i need to pass an object of Matrix to a function.how do i do that?
Actually, the best way (IMHO) is to overload operator+(). Thus in your code, you'll need to use only +:
class Matrix {
private:
// Your code
public:
// Your code
friend Matrix operator+(const Matrix &c1, const Matrix &c2);
}
friend Matrix operator+(const Matrix &c1, const Matrix &c2) { <--- passing by reference
// Your code to add matrices
}
int main() {
Matrix A, B;
Matrix C = A + B;
}
In the case of the passing by value Matrix sum(Matrix a, Matrix b), you will need to write a copy constructor if memory for matrix is allocated dynamically.
Passing by pointer Matrix sum(Matrix *a, Matrix *b) is a C style coding, so it is still correct, but not preferable for C++.
Matrix object;
// ...
f(object);
You have quite a few ways to do it.
By Value:
void func (Matrix m);
By Reference:
void func (Matrix& m);
Or By Pointer:
void func (Matrix* m);
Which one you use depends on your needs and semantics of the operation.
Related
I am writing this c++ code to multiply two 2d matrices and return the resultant 2d matrix.
The error is cannot convert ll (*)[2] to ll**
ll** multiply(ll a[2][2],ll b[2][2])
{
ll ans[2][2];
ans[0][0]=((a[0][0]*b[0][0])%mod+(a[0][1]*b[1][0])%mod)%mod;
ans[0][1]=((a[0][0]*b[0][1])%mod+(a[0][1]*b[1][1])%mod)%mod;
ans[1][0]=((a[1][0]*b[0][0])%mod+(a[1][1]*b[1][0])%mod)%mod;
ans[1][1]=((a[1][0]*b[0][1])%mod+(a[1][1]*b[1][1])%mod)%mod;
return ans;
}
You have a fallen into a trap that seems to get a lot of newcomers to the language.
Passing 2D arrays to a function and returning 2D arrays to a function leads to error prone code. Using a strut/class removes those errors.
In your case, since the size of the arrays is fixed, you can easily use a struct
struct MyMatrix
{
ll data[2][2];
};
then, update multiply to use MyMatrix instead of 2D arrays.
MyMatrix multiply(MyMatrix const& a, MyMatrix const& b)
{
MyMatrix ans;
...
return ans;
}
You can change the function to an overloaded operator too.
MyMatrix operator*(MyMatrix const& a, MyMatrix const& b)
{
MyMatrix ans;
...
return ans;
}
and simplify usage to:
MyMatrix a{ fill in the data for a};
MyMatrix b{ fill in the data for b};
MyMatrix c = a*b;
I want to implement the Euler method in two dimensions and I don´t want to use any library (for practice).
Therefore I want to use my own linear algebra with overloaded functions.
The two first overloads seem to work but there´s still a problem with the multiplication matrix * vector i.e a (2x2)*(2x1).
class vector{
public:
double a;
double b;
vector::vector();
vector::vector(double a, double b){
this->a = a;
this->b = b;
};
vector operator+(vector &a);
vector operator*(double factor);
vector operator*(matrix &B);
};
class matrix{
public:
double a1;
double a2;
double b1;
double b2;
matrix::matrix();
matrix::matrix(double a1, double a2, double b1, double b2) {
this->a1 = a1;
this->a2 = a2;
this->b1 = b1;
this->b2 = b2;
};
};
vector vector::operator+(vector& v){
return vector(this->a+v.a,this->b+v.b);
};
vector vector::operator*(double factor){
return vector(this->a*factor, this->b*factor);
};
vector vector::operator*(matrix& B){
vector newv(this->a*B.a1 + B.a2*b, this->a*B.a1 + B.b2*b);
return newv;
};
Errors when I compile it:
'vector vector::operator *(matrix &)' : overloaded member function not found in 'vector'
unable to resolve function overload
Since you're a bit short on details, I must fill in the gap with guesses. My guess is that you try to support something like the following:
matrix m;
vector v, w;
// fill m and v with values
w = m*v;
I'm also guessing that your matrix has the following form:
( a1 a2 )
( b1 b2 )
You now have two options: Either implement matrix-vector multiplication in the class matrix, or implement it as a free function.
If you want to put if in the matrix class, you'd change the code as follows (note that there are many more things for the code that should be changed, but those are unrelated to the question):
class vector
{
// omit the operator* for matrix, otherwise unchanged
};
class matrix
{
// all that's already in the class
vector operator*(vector const& v) const;
};
vector matrix::operator*(vector const& v) const
{
return vector(a1*v.a + a2*v.b, b1*v.a + b2*v.b);
}
// the rest of your code
If you want to make it a free function (I personally would do it that way, but I'm sure that opinion is not universally held), you'd write
class vector
{
// omit the operator* for matrix, otherwise unchanged
};
class matrix
{
// completely unchanged
};
vector operator*(matrix const& m, vector const& v)
{
return vector(m.a1*v.a + m.a2*v.b, m.b1*v.a + m.b2*v.b);
}
// the rest of your code
I would prefer a BLAS library as an implementation in long term against reinvent the wheel again for basic matrix operations. Additionally some of the BLAS libraries are multithreaded and/or GPU based; they are widely used and tested.
In terms of design I would introduce functions what could be easily implemented by BLAS against operators:
C = α * A + β * B
C = α * A * B + β *C
So as a header:
...
bool blasAdd(const double alfa_, const Matrix& A_, const double beta_, const Matrix& B_, Matrix& C_);
bool blasMultiply(const double alfa_, const Matrix& A_, const Matrix& B_, const double beta_, Matrix& C_);
...
In this way your code automatically could be optimized for BLAS.
My favorite BLAS implementation is Intel MKL, but there are also many free BLAS implementations in the market (e.g.: boost BLAS).
I want to implement a representation of matrices.
for that I have two types of matrices - regular and sparse, which differ in their
implementation - one holds a vector, and the second a map of indices and value,
both inherit from Matrix class.
I want to implement the + operator, which operates on Matrix and receives another Matrix.
but when I implement the + operator, I might receive as parameter sparse/regular matrix.
is there any way to receive a matrix, which I don't know what type of the 2 it is,
and perform the + operator?
meaning, if in class SparseMatrix I receive sparse/regular matrix, how can I implement the operator such that no matter which of the two types I get, it will work?
Matrix & operator+ (Matrix other)
{
...
}
I would probably implement two versions of operator+, and let them call a helper template method:
template <typename ITER>
Matrix add (ITER other_it) {
//...
}
Matrix operator+ (RegularMatrix other)
{
return add(other.begin());
}
Matrix operator+ (SparseMatrix other)
{
return add(other.begin());
}
You could make operator+ a template, but this way makes sure you only allow those Matrix types.
As was pointed out to me, you should not return a reference from +, as the result needs to be point to an instance that exists after the operation returns.
We can use polymorphism to create different implementations of a Matrix. Through the common interface of Matrix, each implementation can interact.
class Matrix
{
class iterator { ... }
friend Matrix operator+(const Matrix &lhs, const Matrix &rhs)
{
// iterate, add, and return new matrix
}
};
class SpareMatrix : public Matrix
{
iterator begin() { ... }
};
class Matrix
{
public:
virtual ~Matrix() {}
virtual Matrix& operator+(Matrix& other) = 0;
};
class MatrixSparse : public Matrix
{
public:
virtual ~MatrixSparse() {}
virtual Matrix& operator+(Matrix& other)
{
MatrixSparse* sparse = dynamic_cast<MatrixSparse*>(&other);
// TODO
}
};
class MatrixRegular : public Matrix
{
public:
virtual ~MatrixRegular() {}
virtual Matrix& operator+(Matrix& other)
{
MatrixRegular* regular = dynamic_cast<MatrixRegular*>(&other);
// TODO
}
};
Also, here is another SO thread dealing with the problem of overloading operators from abstract classes.
class matrix
{
int n;
double **a; //the "matrix"
public:
matrix(int);
~matrix();
int getN();
matrix& operator=(matrix&);
double& operator()(int,int);
friend matrix& operator+(matrix,matrix);
friend matrix& operator-(matrix,matrix);
friend matrix& operator*(matrix,matrix);
friend ostream& operator<<(ostream &,const matrix &);
};
matrix& operator+(matrix A,matrix B)
{
int i,j,n=A.getN();
assert(A.getN()==B.getN());
matrix *C=new matrix(A.getN());
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
{
(*C)(i,j)=A(i,j)+B(i,j);
}
}
return *C;
}
Is this the correct way to overload arithmetic operators?
Are there memory leaks in my code?
The constructor allocates memory in heap, first for an array of double pointers, then for each pointer an array of double.
You should be returning the new matrix by value, and passing (at leas one of) the arguments by const reference:
matrix operator+(const matrix& A, const matrix& B);
This means that you should not allocate it dynamically inside the body of the operator.
If you only call public member methods or member operators, then there is no need to declare the non-member operators as friend.
Also note that is is common practice to implement +=, *= etc. as member operators, and then implement the non-members in terms of those:
matrix operator+(matrix A, const matrix& B)
{
return A+=B;
}
As an aside, you have to check that the dimensions of the matrices are correct. With your design it is only possible to do this at run-time. Another approach is to enforce dimensional correctness at compile time by making the matrices class templates:
template <typename T, size_t ROWS, size_t COLS> matrix;
The trade-off is that matrices of different dimensions are different types.
That sort of design will quickly be inefficient. Think of what happens when you do:
matrix D = A + B + C ;
Template meta programming gives you some really nice possibilities to avoid making useless temporaries. Armadillo is a really good implementation of the idea.
I'm using a 2D matrix in one of my projects. It's something like it is suggested at C++ FAQ Lite.
The neat thing is that you can use it like this:
int main()
{
Matrix m(10,10);
m(5,8) = 106.15;
std::cout << m(5,8);
...
}
Now, I have a graph composed of vertices and each vertex has a public (just for simplicity of the example) pointer to 2D matrix like above. Now I do have a pretty ugly syntax to access it.
(*sampleVertex.some2DTable)(0,0) = 0; //bad
sampleVertex.some2DTable->operator()(0,0) = 0; //even worse...
Probably I'm missing some syntactic sugar here due to my inexperience with operator overloading. Is there a better solution?
Consider using references instead of pointers (provided, it can't be null and you can initialize in the constructor).
Consider making a getter or an instance of a matrix wrapper class for a vertex that returns a reference to 2D matrix (provided, it can't be null).
sampleVertex.some2DTable()(0,0) = 0;
sampleVertex.some2DTableWrap(0,0) = 0;
However, to me it sounds like a non-issue to justify going through all the trouble.
If you have a pointer to a Matrix, e.g. as a function parameter that you can't make a reference (legacy code, e.g.), you can still make a reference to it (pseudo code):
struct Matrix {
void operator () (int u, int v) {
}
};
int main () {
Matrix *m;
Matrix &r = *m;
r (1,1);
}
You're basically limited to (*sampleVertex.some2DTable)(0,0). Of course, if you don't need reseating, why not store the actual values in the matrix instead?
Alternatively, make the pointer private and make an accessor (note: the following examples assume a matrix of EntryTypes):
Matrix& Vertex::GetTableRef()
{
return *some2DTable;
}
// or
Matrix::EntryType& Vertex::GetTableEntry(int row, int col)
{
return (*some2DTable)(row,col);
}
// way later...
myVertex.GetTableRef()(0,0) = 0;
// or...
myVertex.GetTableEntry(0,0) = 0;
Or, just define an inline function to do this for you if you can't change the class Vertex:
// in some header file
inline Matrix& GetTableRef(Vertex& v)
{
return *v.some2DTable;
}
// or you could do this
inline Matrix::EntryType& GetTableEntry(Vertex& v, int row, int col)
{
return (*v.some2DTable)(row, col);
}
// later...
GetTableRef(myVertex)(0, 0) = 0;
// or
GetTableEntry(myVertex, 0, 0) = 0;
Finally, don't forget that you don't have to use operator overloading. STL collections implement an at() member function, which is checked, as opposed to operator[] which is unchecked. If you don't mind the overhead of bounds checking, or if you just want to be nonstandard, you could implement at() and then just call myVertex.some2DTable->at(0,0), saving a bit of a syntactic headache altogether.
There is no C++ syntactic sugar that will ease the pain of what you describe:
(*sampleVertex.some2DTable)(0,0) = 0; //bad
sampleVertex.some2DTable->operator()(0,0) = 0; //even worse...
In this situation, I would either have the graph return a reference instead of a pointer, or have the matrix define a function which calls the operator():
inline matrixType &Matrix::get( int x, int y ){ return operator()(x,y); }
Then, the syntax isn't quite as ugly for the vertex example:
sampleVertex.some2DTable->get(0,0) = 0;
I would add a function that returns you a ref like rlbond recommends. For a quick fix or if you don't have control over the source of it, i would go with this:
sampleVertex.some2DTable[0](0,0) = 0; // more readable
That's actually equivalent, because the following holds if a is a pointer to a defined class:
*a == *(a + 0) == a[0]
See this long discussion on comp.lang.c++ about that same problem with good answers.
This is the best way without changing your code:
//some2DTable is a pointer to a matrix
(*sampleVertex.some2DTable)(0,0)
You could also instead make some2DTable a reference to a matrix instead of a pointer to a matrix. Then you would have simplified syntax as in your first code sniplet.
//some2DTable is a reference to a matrix instead of a pointer to a matrix
sampleVertex.some2DTable(0,0)
Or you could keep some2DTable a pointer to a reference and simply store a reference variable to it and use that in the context of your code block.
I'd change the way you get hold of "sampleVertex.some2DTable" so it returns a reference.
Either that or create the reference yourself:
Matrix& m = *sampleVertex.some2DTable;
m(1,2) = 3;
I don't know if it's worth the trouble, but you could do:
class MatrixAccessor {
private:
Matrix2D* m_Matrix;
public:
MatrixAccessor(Matrix2D* matrix) : m_matrix(matrix) { }
double& operator()(int i, int j) const { return (*m_Matrix)(i,j); }
Matrix2D* operator->() const { return m_Matrix; }
void operator=(Matrix2D* matrix) { m_Matrix = matrix; }
};
Provided the original operator() returns a reference (as it is in many matrix classes).
Then you provide that MatrixAccessor in your vertex class:
class Vertex {
Matrix2D* myMatrix;
public:
MatrixAccessor matrix;
Vertex(Matrix2D *theMatrix) : myMatrix(theMatrix), matrix(theMatrix) { }
};
Then you can write:
Vertex v;
v.matrix(1,0) = 13;
v.matrix->SomeOtherMatrixOperation();
EDIT
I added const keywords (thanks to #phresnel for bringing up the topic) in order to make the solution semantically equivalent to a solution only presenting a public Matrix2D-pointer.
An advantage of this solution is that constness could be transferred to the matrix object by adding two non-const versions of the operator()() and operator->() (i.e. the matrix cannot be modified on const vertices) and changing the const ones to return a const double& and const Matrix2D* respectively.
That would not be possible when using a public pointer to the matrix object.
You could implement Matrix::operator (int,int) by calling a member function and use that one directly when dealing with pointers.
class Matrix
{
public:
float ElementAt( int i, int j ) const { /*implement me*/ }
float operator() ( int i, int j ) const { return ElementAt( i, j ); }
...
};
void Foo(const Matix* const p)
{
float value = p->ElementAt( i, j );
...
}
void Bar(const Matrix& m)
{
float value = m(i,j);
}