I have a matrix and scalar, lets call the matrix A. if I multiply the scalar to the matrix , when the scalar is on the right(2*A) it multiply all the indexes of the matrix by 2. BUT when I multiply the matrix with scalar on the left(A*2) it doesn't work!.(its should do as 2*A).
This is part of class(with members):
class Mat
{
private:
int **matArray;
int rows;
int cols;
bool validMat;
public:
.../*functions*/
};
this is the function when of the right multiply:
Mat Mat::operator*(int scalarToMultiply){
if(!validMat)
{
Mat resultOperator(0,0);
return (resultOperator);
}
//Mat resultOperator(matToAdd.cols,matToAdd.rows);
Mat resultOperator(cols,rows);
for (int i=0; i<rows; i++){
for (int j=0; j<cols; j++){
resultOperator.matArray[i][j]=matArray[i][j]*scalarToMultiply;
}
}
return (resultOperator);
}
How do I do the other way?
You just need to write the right-hand-side operator:
Mat operator*(int scalar, const Mat& rhs) {
return rhs * scalar;
}
You can define operator* as a free function (after the class):
Mat operator*(int scalarToMultiply, const Mat& mat) { ... }
And if you need access to the private members, make it a friend of your class by adding
friend Mat operator*(int scalarToMultiply, const Mat& mat);
to your class.
If you plan to write operator*, you probably also want to support operator*=. To make your life easier, you can use libraries like Boost.Operators or df.operators. That way you only need to implement the basic operators and the libraries take care of generating the rest for you.
In order to have the int on the left hand side you need to have free function that has two parameters. The you can call the Mat overloaded function inside free function.
Mat operator*(int lhs, Mat rhs)
{
return rhs * lhs;
}
Related
I have a class that defines a matrix of dimensions mxn like this:
class Matrix{
protected:
int m;
int n;
double* mat:
public:
// accessors, constructors, destructors, etc.
void assignvalue(int, int, double);
}
Right now if I need to assign a value on position i,j I have a function assignvalue that takes the positions i, j and does the magic and assigns a double value to that position. However, it would be really nice if I could assign a value like you do in matlab or in R.
mymatrix(i,j) = 1.0;
Can you give me a hint on what operator(s) I need to overload? Thanks.
Assuming your m represents the height of your Matrix and n represents the width, overloading operator() this way should do the trick:
double& Matrix::operator()(size_t i, size_t j)
{
return mat[i*m+j];
}
const double& Matrix::operator()(size_t i, size_t j) const
{
return mat[i*m+j];
}
This way, you can write something like this:
void f(Matrix & mymatrix ) {
mymatrix(2, 3) = 5.0; // Calls the first function
// ...
}
void f(Matrix const & m) {
double a = m(1, 5); // Calls the second one
//...
}
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 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.
I need a Matrix class for a project I'm doing in C++ but I don't know how to declare the constructor.
I know I need a height and a width. But how do I go about the part where I store the values? What's the best practice?
I thought about having my constructor be:
Matrix::Matrix(int height, int width, int[] values)
and so the private attributes of my class would be height, width and? How can I say that I want to store a number of values that I don't have yet?
I hope this makes sense... I'm finding it very hard to explain and that's probably because I'm very confuse. I'm very new with C++, so any extra help will be appreciated.
Just for an illustration list of constructors for OpenCV's cv::Mat class:
// constructors
Mat();
// constructs matrix of the specified size and type
// (_type is CV_8UC1, CV_64FC3, CV_32SC(12) etc.)
Mat(int _rows, int _cols, int _type);
Mat(Size _size, int _type);
// constucts matrix and fills it with the specified value _s.
Mat(int _rows, int _cols, int _type, const Scalar& _s);
Mat(Size _size, int _type, const Scalar& _s);
// copy constructor
Mat(const Mat& m);
// constructor for matrix headers pointing to user-allocated data
Mat(int _rows, int _cols, int _type, void* _data, size_t _step=AUTO_STEP);
Mat(Size _size, int _type, void* _data, size_t _step=AUTO_STEP);
// creates a matrix header for a part of the bigger matrix
Mat(const Mat& m, const Range& rowRange, const Range& colRange);
Mat(const Mat& m, const Rect& roi);
// converts old-style CvMat to the new matrix; the data is not copied by default
Mat(const CvMat* m, bool copyData=false);
// converts old-style IplImage to the new matrix; the data is not copied by default
Mat(const IplImage* img, bool copyData=false);
// builds matrix from std::vector with or without copying the data
template<typename _Tp> explicit Mat(const vector<_Tp>& vec, bool copyData=false);
// helper constructor to compile matrix expressions
Mat(const MatExpr_Base& expr);
// assignment operators
Mat& operator = (const Mat& m);
Mat& operator = (const MatExpr_Base& expr);
I think this is good place to get inspiration or use it for your project, hover I'd recommend following constructors:
// Will declare whether to fill allocated data with zeros, ones or leave it be
enum MatrixFill { NO_INITIALIZATION, ZERO_FILL, ONES_FILL};
Matrix( const int width, const int height, const MatrixFill fill = NO_INITIALIZATION);
// To initialize from T data[] = {1,2,3,1,2,3,1,2,3};
Matrix( const int width, const int height, const T *data);
// To initialize from T data[][3] = {{1,2,3},{1,2,3},{1,2,3}};
Matrix( const int width, const int height, const T **data);
// To initialize from other matrix
Matrix( const Matrix &orig);
// Don't forget assign operator
Matrix &operator=(const Matrix &orig);
I'd also create type SubMatrix which wouldn't contain any data just link to parent data and range which would allow you to do this:
Matrix my( old.getSubMatrix( row, col, rowsCount, colsCount));
// And of course it'd have constructor like this:
Matrix( const SubMatrix &orig);
You may add many more constructors but I'd start with those five. Ask questions if you have any.
I'd learn from the pros: http://www.boost.org/doc/libs/1_48_0/libs/numeric/ublas/doc/matrix.htm#matrix
You should probably have a number of constructors, based on how you expect to use the class.
Assuming you plan to use Matrix for some kind of linear algebra, you should have a constructor which initializes the elements to zero:
Matrix(int height, int width); // initializes elements to 0
You should have constructors that initialize the elements from whatever data source you expect to find convenient (below, the type T is the element type of your Matrix):
Matrix(int height, int width, const std::vector<T> &data); // init from vector
Matrix(int height, int width, const T *data); // init from array
If you want to be able to declare an array of matrices, you need a default constructor:
Matrix(); // uninitialized or default array (to be initialized later)
You should also either define or disable copy constructors and assignment operators (or C++ will define them for you, badly):
Matrix(const Matrix &orig); // copy constructor
Matrix& operator=(const Matrix &orig); // assignment operator
I would really try to look for a book about OO design and their application in C++. As this question (besides hard to understand) shows a general misunderstanding of how object oriented languages work. I could explain it here in this topic; but that would be redundant and book authors can do it much better than me.
Basically what I understood from this question is that you know the sizes of your matrix, yet don't know the values they will get when you create them?
In that case simply make a constructor with only the sizes. And initialize the matrix to some "NULL" value. (Possibly even set a private member to false, indicating it isn't completely usable yet). The class and constructor would look like:
class Matrix() {
public:
Matrix(int nRows, int nColumns);
private:
int numRows;
int numColums;
std::vector<VALUE_TYPE> val;
};
Matrix::Matrix(int nRows, int nColums) {
int numRows = nRows;
int numColumns = nColums;
std::vector<VALUE_TYPE> val(nRows * nColums);
}
Simply said: the constructor only makes sure the memory is "allocated". Then you use other functions to fill in the actual values.
If you wish to provide "something", where you don't know exactly what "something" is. But you do know it is a container of data - you should use standard iterators (or templates). This is the manner how c++ handles inserting of data to standard containers. The function would be like this:
template <typename InIt>
Matrix::Matrix(int nRows, int nColums, InIt begin, InIt end) {
int numRows = nRows;
int numColumns = nColums;
//[begin, end) now holds the data - manipulate it at will.
std::vector<VALUE_TYPE> val(begin, end);
val.resize(nColums * nRows);
}
But once again: I'd take a book as the question to me seems unclear and answered by books.
Not strictly related to cpstructors but ... are you matrix expected to be resized during their life? If not, consider the idea not to have numRows and numCols as "variables" (they will never vary) but as template parameters.
Your matrix can be so declared as
Matrix<int,3,3> a; //a 3x3 integers
Matrix<double,3,2> a; //a 3x2 doubles
This will let impossible operations (like adding matrix with different sizes) impossible to compile.
I'm teaching myself c++ by creating my own data structure class (a matrix, to be exact) and I've changed it to a template class of type <T> from only using doubles. The overloaded matrix operators were pretty standard
// A snippet of code from when this matrix wasn't a template class
// Assignment
Matrix& operator=( const Matrix& other );
// Compound assignment
Matrix& operator+=( const Matrix& other ); // matrix addition
Matrix& operator-=( const Matrix& other ); // matrix subtracton
Matrix& operator&=( const Matrix& other ); // elem by elem product
Matrix& operator*=( const Matrix& other ); // matrix product
// Binary, defined in terms of compound
Matrix& operator+( const Matrix& other ) const; // matrix addition
Matrix& operator-( const Matrix& other ) const; // matrix subtracton
Matrix& operator&( const Matrix& other ) const; // elem by elem product
Matrix& operator*( const Matrix& other ) const; // matrix product
// examples of += and +, others similar
Matrix& Matrix::operator+=( const Matrix& rhs )
{
for( unsigned int i = 0; i < getCols()*getRows(); i++ )
{
this->elements.at(i) += rhs.elements.at(i);
}
return *this;
}
Matrix& Matrix::operator+( const Matrix& rhs ) const
{
return Matrix(*this) += rhs;
}
But now that Matrix can have a type, I'm having trouble determining which of the matrix references should be type <T> and what the consequences would be. Should I allow dissimilar types operate on each other (eg., Matrix<foo> a + Matrix<bar> b is valid)? I'm also a little fuzzy on how
One reason I'm interested in dissimilar types is to facilitate the use of complex numbers in the future. I'm a newbie at c++ but am happy to dive in over my head to learn. If you're familiar with any free online resources that deal with this problem I would find that most helpful.
Edit: no wonder no one thought this made sense all of my angle brackets in the body were treated as tags! I can't figure out how to escape them, so I'll inline code them.
I figure that I should illustrate my comment about parameterizing matrix dimensions, since you might not have seen this technique before.
template<class T, size_t NRows, size_t NCols>
class Matrix
{public:
Matrix() {} // `data` gets its default constructor, which for simple types
// like `float` means uninitialized, just like C.
Matrix(const T& initialValue)
{ // extra braces omitted for brevity.
for(size_t i = 0; i < NRows; ++i)
for(size_t j = 0; j < NCols; ++j)
data[i][j] = initialValue;
}
template<class U>
Matrix(const Matrix<U, NRows, NCols>& original)
{
for(size_t i = 0; i < NRows; ++i)
for(size_t j = 0; j < NCols; ++j)
data[i][j] = T(original.data[i][j]);
}
private:
T data[NRows][NCols];
public:
// Matrix copy -- ONLY valid if dimensions match, else compile error.
template<class U>
const Matrix<T, NRows, NCols>& (const Matrix<U, NRows, NCols>& original)
{
for(size_t i = 0; i < NRows; ++i)
for(size_t j = 0; j < NCols; ++j)
data[i][j] = T(original.data[i][j]);
return *this;
}
// Feel the magic: Matrix multiply only compiles if all dimensions
// are correct.
template<class U, size_t NOutCols>
Matrix<T, NRows, NOutCols> Matrix::operator*(
const Matrix<T, NCols, NOutCols>& rhs ) const
{
Matrix<T, NRows, NOutCols> result;
for(size_t i = 0; i < NRows; ++i)
for(size_t j = 0; j < NOutCols; ++j)
{
T x = data[i][0] * T(original.data[0][j]);
for(size_t k = 1; k < NCols; ++k)
x += data[i][k] * T(original.data[k][j]);
result[i][j] = x;
}
return result;
}
};
So you'd declare a 2x4 matrix of floats, initialized to 1.0, as:
Matrix<float, 2, 4> testArray(1.0);
Note that there is no requirement for the storage to be on the heap (i.e. using operator new) since the size is fixed. You could allocate this on the stack.
You can create another couple matrices of ints:
Matrix<int, 2, 4> testArrayIntA(2);
Matrix<int, 4, 2> testArrayIntB(100);
For copying, dimensions must match though types do not:
Matrix<float, 2, 4> testArray2(testArrayIntA); // works
Matrix<float, 2, 4> testArray3(testArrayIntB); // compile error
// No implementation for mismatched dimensions.
testArray = testArrayIntA; // works
testArray = testArrayIntB; // compile error, same reason
Multiplication must have the right dimensions:
Matrix<float, 2, 2> testArrayMult(testArray * testArrayIntB); // works
Matrix<float, 4, 4> testArrayMult2(testArray * testArrayIntB); // compile error
Matrix<float, 4, 4> testArrayMult2(testArrayIntB * testArray); // works
Note that, if there's a botch, it is caught at compile time. This is only possible if the matrix dimensions are fixed at compile time, though. Also note that this bounds checking results in no additional runtime code. It's the same code that you'd get if you just made the dimensions constant.
Resizing
If you don't know your matrix dimensions at compile time, but must wait until runtime, this code may not be of much use. You'll have to write a class that internally stores the dimensions and a pointer to the actual data, and it will need to do everything at runtime. Hint: write your operator [] to treat the matrix as a reshaped 1xN or Nx1 vector, and use operator () to perform multiple-index accesses. This is because operator [] can only take one parameter, but operator () has no such limit. It's easy to shoot yourself in the foot (force the optimizer to give up, at least) by trying to support a M[x][y] syntax.
That said, if there's some kind of standard matrix resizing that you do to resize one Matrix into another, given that all dimensions are known at compile time, then you could write a function to do the resize. For example, this template function will reshape any Matrix into a column vector:
template<class T, size_t NRows, size_t NCols>
Matrix<T, NRows * NCols, 1> column_vector(const Matrix<T, NRows, NCols>& original)
{ Matrix<T, NRows * NCols, 1> result;
for(size_t i = 0; i < NRows; ++i)
for(size_t j = 0; j < NCols; ++j)
result.data[i * NCols + j][0] = original.data[i][j];
// Or use the following if you want to be sure things are really optimized.
/*for(size_t i = 0; i < NRows * NCols; ++i)
static_cast<T*>(result.data)[i] = static_cast<T*>(original.data)[i];
*/
// (It could be reinterpret_cast instead of static_cast. I haven't tested
// this. Note that the optimizer may be smart enough to generate the same
// code for both versions. Test yours to be sure; if they generate the
// same code, prefer the more legible earlier version.)
return result;
}
... well, I think that's a column vector, anyway. Hope it's obvious how to fix it if not. Anyway, the optimizer will see that you're returning result and remove the extra copy operations, basically constructing the result right where the caller wants to see it.
Compile-Time Dimension Sanity Check
Say we want the compiler to stop if a dimension is 0 (normally resulting in an empty Matrix). There's a trick I've heard called "Compile-Time Assertion" which uses template specialization and is declared as:
template<bool Test> struct compiler_assert;
template<> struct compiler_assert<true> {};
What this does is let you write code such as:
private:
static const compiler_assert<(NRows > 0)> test_row_count;
static const compiler_assert<(NCols > 0)> test_col_count;
The basic idea is that, if the condition is true, the template turns into an empty struct that nobody uses and gets silently discarded. But if it's false, the compiler can't find a definition for struct compiler_assert<false> (just a declaration, which isn't enough) and errors out.
Better is Andrei Alexandrescu's version (from his book), which lets you use the declared name of the assertion object as an impromptu error message:
template<bool> struct CompileTimeChecker
{ CompileTimeChecker(...); };
template<> struct CompileTimeChecker<false> {};
#define STATIC_CHECK(expr, msg) { class ERROR_##msg {}; \
(void)sizeof(CompileTimeChecker<(expr)>(ERROR_##msg())); }
What you fill in for msg has to be a valid identifier (letters, numbers, and underscores only), but that's no big deal. Then we just replace the default constructor with:
Matrix()
{ // `data` gets its default constructor, which for simple types
// like `float` means uninitialized, just like C.
STATIC_CHECK(NRows > 0, NRows_Is_Zero);
STATIC_CHECK(NCols > 0, NCols_Is_Zero);
}
And voila, the compiler stops if we mistakenly set one of the dimensions to 0. For how it works, see page 25 of Andrei's book. Note that in the true case, the generated code gets discarded so long as the test has no side effects, so there's no bloat.
I'm not sure I understand what you're asking.
But I would point out that your operator declarations are incorrect and/or incomplete.
Firstly, the assignment operator should return the same type as its parameter; viz:
const Matrix& operator=(const Matrix& src);
Secondly, binary operators return a new object, so you can't return a reference. All binary operators should be declared thus:
Matrix operator+( const Matrix& other ) const; // matrix addition
Matrix operator-( const Matrix& other ) const; // matrix subtracton
Matrix operator&( const Matrix& other ) const; // elem by elem product
Matrix operator*( const Matrix& other ) const; // matrix product
Actually, it is considered better style to declare and implement binary operators as global friend functions instead:
class Matrix { ... };
inline Matrix operator+(const Matrix& lhs,const Matrix& rhs)
{ return Matrix(lhs)+=rhs; }
Hope this helps.
Now I understand what you're asking.
Presumably your implementation of various operators will in this case consist of operations on the composite types. So really the question of whether Matrix op Matrix is meaningful depends on whether string op int is meaningful (and whether such a thing might be useful). You would also need to determine what the return type might be.
Assuming the return type is the same as the LHS operand, the declarations would look something like:
template <typename T>
class Matrix
{
template <typename U>
Matrix<T>& operator+=(const Matrix<U>& rhs);
};
template <typename T,typename U>
Matrix<T> operator+(const Matrix<T>& lhs,const Matrix<U>& rhs)
{ return Matrix<T>(lhs)+=rhs; }
Matrix<double> x = ...;
Matrix<int> y = ...;
cout << x + y << endl; // prints a Matrix<double>?
OK, that's doable, but the problem gets tricky quickly.
Matrix<double> x = ...
Matrix<complex<float>> y = ...
cout << x + y << endl; // Matrix<complex<double>>?
You will most likely be happiest if you require that your binary operators use like-type operands and force your application builders to explicitly type-cast their values. For the latter case:
cout << ((Matrix<complex<double>>) x) + ((Matrix<complex<double>>) y) << endl;
You can provide a member template constructor (or a type conversion operator) to support the conversions.
template <typename T>
class Matrix {
...
public:
template <typename U>
Matrix(const Matrix<U>& that) {
// initialize this by performing U->T conversions for each element in that
}
...
};
The alternative, having your binary operator template deduce the correct Matrix return type based on the element types of the two operands, requires some moderately complex template meta-programming, probably not what you're looking to get into.
First of all, the copy assignment operator should not have const Matrix& as its return type; your interface is correct.
Grant's suggestion of how binary operators are implemented is the generally accepted way of doing these things.
It's a nice exercise, but one quickly sees why doing linear algebra in C++ is a bad idea to begin with. Operations like A+B and A*B are valid only if the dimensions of the matrices match up.
You don't have to add much at all, because inside a template, the class name itself refers to the current template parameter. So the following are equivalent:
template <typename T> struct Foo
{
Foo<T> bar(const Foo<T> &);
Foo bar2(const Foo *); // same
};
So all your operations just go through without change. What you should add is a constructor that converts one matrix type into another:
temlate <typename T> class Matrix
{
template <typename U> Matrix(const Matrix<U> &); // construct from another matrix
/*...*/
};
Using that conversion constructor, you can mix matrices in your operators, as Matrix<T>::operator+(Matrix<U>) will use the conversion to create an argument of type Matrix<T>, and then you use your already implemented operator.
In C++11 you can add static_assert(std::is_convertible<U, T>::value, "Boo"); to your converting constructor to give you a useful compile-time diagnostic if you call it with an incompatible type.