First of all it's an exercise given to me so i can't change things and have to work with it.
I have a 2d vector aka a matrix. My header file looks like this
#include <vector>
#include <iostream>
using namespace std;
class Matrix{
private:
vector<vector<double>> 2d;
public:
explicit Matrix(unsigned int sizeY=0,unsigned int sizeX=0,double value= 0.0);
~Matrix() = default;
Matrix(const Matrix &other);
Matrix(Matrix &&other) = default;
Matrix& operator=(const Matrix &other);
Matrix& operator=(Matrix &&other) = default;
//other + - operators
//INDEX
vector<double>& at(unsigned int i);
const vector<double>& at(unsigned int i)const;
const vector<double>& operator[] (double m) const;
vector<double>& operator[] (double m);
};
Matrix operator+(const Matrix& d1, const Matrix& d2);
Matrix operator-(const Matrix& d1, const Matrix& d2);
ostream& operator<<(ostream &o, const Matrix& v);
istream& operator>>(istream &i, Matrix& v);
So now I implemented everything except the << and >> operator.
Now the question if i want to go through the 2d vec matrix is there another way to get the "depth"
outside the Matrix class except writing a getter ?
If the Matrix is N X M e.g. 4x4 i can get the 2nd 4 the "width" with something like 2d[0].size() but i cant figure out how I can get the "depth" otherwise then use a getter.
Also i cant change 2d to public or use templates.
I tried for around 2-3 hours myself and couldnt find any solution and maybe its not possible under the given conditions.
2d[0].size() is giving you the length of the first vector stored in 2d. To get the length of 2d you can just call the same directly on 2d.
2d.size() = length of 2d
2d[0].size() = length of first vector stored in 2d
Related
I am thinking on how can i define a class of real matrices NxN with the operations Add (Subtract) and Multiply. I am looking for Efficient Memory Usage.
class Matrix {
private:
std::size_t _size_n;
double **_pMatrix;
public:
Matrix(const size_t n);
~Matrix();
double &operator()(size_t, const size_t);
double operator()(size_t, const size_t) const;
size_t size_n() const { return _size_n; }
};
std::ostream &operator<<(std::ostream &, const Matrix &);
Matrix operator+(const Matrix&, const Matrix&);
Matrix operator-(const Matrix&, const Matrix&);
Matrix operator*(const Matrix&, const Matrix&);
Yes you can have additional overloads
Matrix/*&&*/ operator+(const Matrix&, Matrix&&);
Matrix/*&&*/ operator+(Matrix&&, const Matrix&);
Matrix/*&&*/ operator+(Matrix&&, Matrix&&);
To reuse memory of one of the temporary.
They can all be implemented with Matrix& operator += (Matrix&, const Matrix&)
by changing the order as + is symmetrical. operator - would require dedicated code.
Another way to optimize memory is to use expression templates instead of computing directly the result.
It has its drawback about lifetime issue (especially with auto) though.
I am trying to make matrix structure with overloading operators '+' and '='.
Matrix structure:
struct Matrix{
int rows;
int cols;
std::vector<int> data;
Matrix(int rows, int cols, int val); //creates matrix row*col and fills every position with val
Matrix(const Matrix &m); //copy constructor
Matrix(int rowcol = 0); //creates matrix rowcol*rowcol filled with zeros
Matrix & operator=(const Matrix &m);
void printMatrix(); //prints the matrix
...
};
Operators:
Matrix & Matrix::operator=(const Matrix &m) //assings matrix m to the new matrix
{
}
Matrix operator+(const Matrix &a, const Matrix &b) //sums two matrices
{
//I know how to make the algorithm for summing two matrices, however i don´t know how
//to return the result into existing matrix
}
And main function:
int main(){
Matrix A(3,3,1);
Matrix B(3,3,2);
Matrix C(3,3,0);
C = A + B;
C.printMatrix();
...
return 0;
}
I don´t know how to make it work. I tried something like this for the '=' operator:
Matrix & Matrix::operator=(const Matrix &m)
{
static matrix d(m); //using copy constructor
return d;
}
but it didn´t work. It created new matrix with dimensions 0x0. Any advice on how to implement it?
A working way to implement that operator= would be as follows:
Matrix& Matrix::operator=(const Matrix &m)
{
this->rows = m.rows;
this->cols = m.cols;
this->data = m.data;
return *this;
}
I won't approach the algorithm needed for operator+, but the surrounding machinery is also surprisingly simple:
Matrix operator+(const Matrix &a, const Matrix &b) //sums two matrices
{
Matrix result(<num of rows>, <num of cols>, 0);
// do things with result here, using your algorithm, a, and b
// e.g. result.data[?] = a.data[?] ? b.data[?]
return result;
}
To make this easier, since your data is one-dimensional (good! this is efficient!), you may want to implement an accessor that takes x and y dimensions and returns an index into data. For example:
int& Matrix::val(const int x, const int y)
{
assert(x < cols);
assert(y < rows);
return data[x + y*cols];
}
The result of this may be both read and written, like this:
result.val(x1, y1) = a.val(x2, y2) + b.val(x3, y3);
Where those co-ordinates and the + are just things I made up, and should come from your algorithm.
If you also want an operator+=, to affect an existing matrix, then:
Matrix& Matrix::operator+(const Matrix &b) //sums two matrices
{
// do things with your object here, using your algorithm and b
return *this;
}
Where I return *this for the member operators, that's not strictly necessary, though it is conventional, and it allows for easy chaining of operations (if you're into that kind of thing). You can find more information on operator overloading in your book.
Assume I have a general Matrix class, for which I have already implemented the operator * which performs the usual matrix multiplication.
Such an operator has the following signature :
Matrix operator*(const Matrix & ) const;
I now wish to implement another * operator for an inherited class Matrix3 that represents 3x3 matrices.
It would have the following signature :
Matrix3 operator*(const Matrix3 &) const;
I am looking for the proper way of implementing this operator in order to re-use the code already written for the base class, and to minimize cost (i.e. copying).
This should work just fine:
// Either return base class
Matrix operator*(const Matrix3& other) const
{
return Matrix::operator*(other);
}
// Or construct from a Matrix
Matrix3 operator*(const Matrix3& other) const
{
return Matrix3(Matrix::operator*(other));
}
// Either construct the Matrix data in the Matrix3
Matrix3(const Matrix& other)
{
// Initialize Matrix specifics
// Initialize Matrix3 specifics
}
// Or pass the Matrix to it's base class so it can take care of the copy
Matrix3(const Matrix& other) : Matrix(other)
{
// Initialize Matrix3 specifics
}
I'm having some trouble implementing an assignment operator for a matrix class. It seems that the compiler doesn't want to recognize my overloaded assignment operator (I think?) and I'm not sure why. I know there are some internet articles on the various issues with implementing matrix classes in c++ (which have helped me get this far) but this time I can't seem to parallel my current predicament with any other help already out there. Anyway, I would greatly appreciate it if someone could help explain what I'm doing wrong. Thanks!
Here are my error messages:
In file included from Matrix.cpp:10:
./Matrix.h:20:25: error: no function named 'operator=' with type 'Matrix &(const Matrix &)'
was found in the specified scope
friend Matrix& Matrix::operator=(const Matrix& m);
^
Matrix.cpp:79:17: error: definition of implicitly declared copy assignment operator
Matrix& Matrix::operator=(const Matrix& m){ //m1 = m2
^
Matrix.cpp:89:13: error: expression is not assignable
&p[x][y] = m.Element(x,y);
~~~~~~~~ ^
3 errors generated.
Here is my assignment operator code in my .cpp file:
Matrix& Matrix::operator=(const Matrix& m){ //m1 = m2
if (&m == this){
return *this;
}
else if((Matrix::GetSizeX() != m.GetSizeX()) || (Matrix::GetSizeY()) != m.GetSizeY()){
throw "Assignment Error: Matrices must have the same dimensions.";
}
for (int x = 0; x < m.GetSizeX(); x++)
{
for (int y = 0; y < m.GetSizeY(); y++){
&p[x][y] = m.Element(x,y);
}
}
return *this;
here is my matrix header file:
class Matrix
{
public:
Matrix(int sizeX, int sizeY);
Matrix(const Matrix &m);
~Matrix();
int GetSizeX() const { return dx; }
int GetSizeY() const { return dy; }
long &Element(int x, int y) const ; // return reference to an element
void Print() const;
friend std::ostream &operator<<(std::ostream &out, Matrix m);
friend Matrix& Matrix::operator=(const Matrix& m);
long operator()(int i, int j);
friend Matrix operator*(const int factor, Matrix m); //factor*matrix
friend Matrix operator*(Matrix m, const int factor); //matrix*factor
friend Matrix operator*(Matrix m1, Matrix m2); //matrix*matrix
friend Matrix operator+(Matrix m1, Matrix m2);
Your assignment operator should be a member function, not a friend. Your other operators should take parameters as const Matrix &, otherwise you'll make a copy of the Matrix objects used by the operator.
You're taking the address of the element:
&p[x][y] = m.Element(x,y);
when you want to assign to it, like this:
p[x][y] = m.Element(x,y);
friend Matrix& Matrix::operator=(const Matrix& m);
This above part makes little sense since operator= must be defined as a member function within the class.
Actually I think your life would be a lot easier if you avoided the need for friends here (or at least so many of them). A self-sufficient public interface for a matrix should allow you to implement all the desired operators, whether or not they're members of the class.
Perhaps the first thing you should seek is that self-sufficient public interface so that you don't actually need something like a matrix multiplication operator to be a friend, since otherwise the likely temptation would be to make every operation involving matrices require access to the matrix internals.
I'm new to using .h/.cpp files and I'm trying to convert my .cpp to .h and .cpp and I'm running into this issue. It's erroring and I'm not sure how to resolve it. In Primitives.h I have:
friend Matrix operator+(const Matrix&, const Matrix&);
and in Primitives.cpp I had:
friend Matrix operator+ (const double b, const Matrix& a)
But thus far my attempts to change the format have not worked. Any tips?
You should do it like this:
// header
class Matrix
{
public:
friend Matrix operator+(const Matrix&, const Matrix&);
};
// source
Matrix operator+(const Matrix&, const Matrix&) { ... }
For short operators it may be more convenient to define the operator directly in the header file:
// header
class Matrix
{
public:
friend Matrix operator+(const Matrix&, const Matrix&) {
// code here
}
};
You should not use friend in implementation (.cpp file). You should use it at declaration (in .h file) only.
Try this
///your.h
class Matrix
{
//your class
friend Matrix operator+ (const double b, const Matrix& a);
};
////your.cpp
Matrix operator+ (const double b, const Matrix& a)
{
//your code
return yourobject;
}