Implementation of methods of interface - c++

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.
For that, I'm using the strategy pattern, where I create the base abstract class Matrix, two classes that inherit from Matrix - RegMatrix and SparseMatrix, and MyMatrix that holds a pointer to a Matrix.
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.
so I have 2 questions:
The only hint I have is to create an iterator of type "matrix", and implement the iterator for each type of matrix (regular and sparse).
how can I do such a thing?
Let's say I implemented an iterator for both types of "matrix". how can I use the different iterators, in case I have to add two different types of matrices? do I have to implement all 4 different cases?
The operator+ looks like:
Matrix& operator+(const Matrix& other)
{
.....
}

Prefer not to implement the functionality in the base class.
Implement the functionality in each of the child classes. This will allow for use of optimal algorithms.
Or you could declare getters and setters as abstract in the Base class and use them in your base class implementation:
struct Matrix_Base
{
virtual int get_value(unsigned int row, unsigned int column) = 0;
virtual void set_value(int value, unsigned int row, unsigned int column) = 0;
Matrix_Base operator+(const Matrix_Base& other)
{
// perform addition
int sum = get_value(row, column) + other.get_value(column, row);
set_value(sum, row, column);
//...
}
};
Remember, when passing a Matrix, the receiving function can only use common functions (interface) of the Matrix. For specifics, functions will have to use specialized (descendants) in the parameter lists.

You may implement + operator only for RegMatrix and 2 conversion operators:
1. From RegMatrix to SparseMatrix
2. From SparseMatrix to RegMatrix
What are performance requirements?

Related

How Can I Overload The == Operator to Compare Armadillo Vectors?

In my program, I use many arma::uvecs, and check equality between them like this
#include <armadillo>
using Vec = typename arma::uvec;
Vec v1({0, 0});
Vec v2({0, 1});
bool are_equal = arma::all(v1 == v2);
as I couldn't find any better equality operator in the Armadillo docs. Now that works perfectly fine, but to save some space, and as an exercise in subclassing and operator overloading, I want to define the equality sign directly between the vectors like this:
class Vec : public arma::uvec {
friend bool operator==(const Collapsed& lhs, const Collapsed& rhs) {
return arma::all(lhs == rhs);
}
};
But sadly, I can't get it to work like that. I'm grateful about any hints!
Operator overloads do not need to be part of a class. I would suggest implementing your comparison operator as a free function like this:
bool operator==(const arma::uvec& lhs, const arma::uvec& rhs) {
return arma::all(lhs == rhs);
}
Regarding the friend in your question: As a quick summary, it provides the function that is befriended access to private and protected members of the class where the friend declaration is located. It it is not used to implement functions.
You can read more about it on cppreference or on this SO question
EDIT
Since the above only works if operator== is not already defined, here is a version that overrides it's implementation for a custom subclass:
class Vec : public arma::uvec
{
public:
bool operator==(const Vec& other)
{
// depending on wether arma implemets operator== as member or free function
// return arma::all(this->arma::uvec::operator==(other));
return arma::all(arma::operator==(*this, other));
}
};
Problem is library itself:
Armadillo: C++ library for linear algebra & scientific computing
operators:  +  −  *  %  /  ==  !=  <=  >=  <  >  &&  ||
Overloaded operators for Mat, Col, Row and Cube classes
Operations:
+ addition of two objects
− subtraction of one object from another or negation of an object
* matrix multiplication of two objects; not applicable to the Cube class unless multiplying by a scalar
% element-wise multiplication of two objects (Schur product)
/ element-wise division of an object by another object or a scalar
== element-wise equality evaluation of two objects; generates a matrix/cube of type umat/ucube
!= element-wise non-equality evaluation of two objects; generates a matrix/cube of type umat/ucube
and uvec is:
uvec = ucolvec = Col<uword>
so operator== is already there and its functionality is strange/unexpected.
My recommendation is: do not fight with a library. Do not try provide own operator. Just provide a named function areEqual.
Defining a class just to provide own equal operator is not a best choice and if doing that then IMO it is better to use composition not inheritance (depending on requirement it will be more boiler plate code in class itself, but it will be easier to avoid unexpected behaviors).

What is a good pattern/implementation for this inheritence-like situation?

Let's say I have two different implementations of mathematical vectors (and other mathematical structures such as matrices):
class SparseVector {
double dotproduct(SparseVector& other);
};
class DenseVector {
double dotproduct(DenseVector& other);
};
I would like to implement algorithm that are using either exclusively sparse or dense algebra. Of course I would like to only implement a generic version of the algorithm what can deal with either of the two.
The first idea was to create a virtual vector class (code below for the concept, it wouldn't actually work this way):
class Vector {
virtual double dotproduct(Vector& other);
};
class SparseVector : public Vector {
double dotproduct(SparseVector& other) override;
};
class DenseVector : public Vector {
double dotproduct(DenseVector& other) override;
};
However that doesn't work because each of the Vector implementations can only work with other vectors of the same type. (That is, the implementation should not allow a dotproduct between a sparse and a dense vector).
Is there a good implementation strategy or design pattern that prevents me having to implement algorithms twice?
The question is not the same as this one, as I do not want to support dotproducts between a sparse and a dense vector.
I was thinking about using templates:
template<class T>
class algorithm {
}
but I don't know how to restrict T to be one of SparseVector/DenseVector, so the compiler knows that there exists a suitable dotproduct() function.
The thing you're looking for is called Visitor Pattern or Double Dispatch. You should be able to easily locate further infor online. However, the gist is basically this: With regular virtual functions or OOP, the invoked code depends on the type of one object. With the Visitor Pattern, you get to pick the code depending on two objects (hence also the name Double Dispatch), which is basically what you need.

use of std:swap (in implementation of assignment operator)

I have seen in some place an implementation of assignemt operator of class matrix looks like this:
class Matrix
{
private:
int rows;
int cols;
int **mat;
public:
Matrix& operator=(const Matrix& m)
{
if ( this != &m )
{
Matrix temp(m);
std::swap(temp.rows, rows);
std::swap(temp.cols, cols);
std::swap(temp.mat, mat);
}
return *this;
}
}
Now, suppose I want to use swap function for that matter , what is the alternative way to use it without writing std:swap? Am I suppose in such case to build a friend-function that implementing swap of two matrix?
Now, suppose I want to use swap function for that matter , what is the alternative way to use it without writing std:swap? Am I suppose in such case to build a friend-function that implementing swap of two matrix?
You have to swap the two Matrix objects. Whether you do it in the operator= function or another function is secondary.
As a matter of practice, I would recommend creating a function that swaps two Matrix objects and use it the implementation of the operator= function. You have various options for that.
Make it a non-member friend function.
Make it a static member function.
Make it a non-static member function.
I would probably pick a static member function but I don't see any downsides to using one of the other two.
One thing to note is that you will end up using std::swap to swap the member variables of the Matrix objects in that function. It came across to me as though that is a concern for you.

Best way to return an inherited class from a function in c++

I'm looking for advice as to how to proceed with this class hierarchy I'm building in C++.
Base class is Matrix:
class Matrix
{
protected:
int rows;
int columns;
double* values;
public:
\\lots of stuff goes here. bla di bla di bla.
virtual Matrix operator+(const Matrix& addend) const;
\\etc.
}
Squarematrix is inherited from Matrix
class Squarematrix : public Matrix
{
public:
Squarematrix operator+(const Squarematrix& addend) const;
}
Operator+ returns a matrix or a squarematrix respectively. Since operator+ is a virtual function this wont compile, as it must have the same return type in all classes.
So what are my options?
I could use an ordinary function instead of virtual. This is a bit annoying, but wouldn't cause a problem under most circumstances.
I could return a matrix in all cases. This would basically make my squarematrix class a right pain in the *** to use, as I would have to constantly downcast from matrix to squarematrix.
I could return a reference to a squarematrix. Then the matrix would have to be stored on the heap and there's no way to make sure its deleted safely. Especially if I do something like this:
squarematrix a=b+(c+d);
(c+d) will be stored on the heap and have no pointer to it so will be leaked.
Is there any way to keep virtual functions and still have different return types?
What would you advise in this situation?
Thanks for your help. Looking forward to hearing from you.
I would recommend:
Remove Squarematrix.
Add a constructor to Matrix to construct a square matrix.
If the knowledge of whether a matrix is square matrix is helpful for your application, add a member function in Matrix to answer that query.
class Matrix
{
public:
Matrix(int r); // Construct a square matrix.
Matrix(int r, int c); // Construct a rectangular matrix.
bool isSquareMatrix() const { return (rows == columns); }
Matrix operator+(const Matrix& addend) const;
private:
int rows;
int columns;
double* values;
}
This is known as return type covariance (https://en.wikipedia.org/wiki/Covariant_return_type).
It was not supported by old compilers, but is supported by many now. For example my code compiles fine in Visual Studio 2017. Here is an article on its use and limitations in c++: https://aycchen.wordpress.com/2009/08/17/covariant-return-type-in-cpp/.
It is not supported in C# yet, but is being considered for a future version. See https://github.com/dotnet/csharplang/issues/49.
It is also supported by newer versions of Java. See https://blogs.oracle.com/sundararajan/covariant-return-types-in-java.
Other than implementation issues, as far as I know there is no reason for it not to be added to a polymorphic language. I don't believe it can cause errors, although due to an imperfect implementation in Java it can cause bugs-see https://dzone.com/articles/covariant-return-type-abyssal.

Operator+ to add instances of different classes

Problem statement: Let Matrix be a base class which is subclassed by DenseMatrix and SparseMatrix (and possibly others). What I would like to achieve is the following:
Matrix *A = new DenseMatrix();
Matrix *B = new SparseMatrix();
Matrix C = (*A) + (*B); // dense + sparse
Matrix D = (*A) + (*A); // dense + dense
Matrix E = (*B) + (*B); // sparse + sparse
Even better, I would like to have the following:
DenseMatrix C = (*A) + (*B);
DenseMatrix D = (*A) + (*A);
SparseMatrix E = (*B) + (*B);
Now, when adding a DenseMatrix with a SparseMatrix having declared both as Matrix implies that there must be an operator+ definition in Matrix.
I have already read this answer which makes use of an interface AddEnabled<Foo>, but doesn't seem to be a good solution when (almost) any possible combination of summands. I could possibly define in DenseMatrix the following functions:
friend DenseMatrix operator+ (DenseMatrix const& left, DenseMatrix const& right);
But then again it will be impossible to add two instances of DenseMatrix declared as Matrix (i.e., Matrix *A = new DenseMatrix();).
From various similar questions and answers I suspect that the pimpl idiom could be relevant, but I don't see how.
Note: I'm coding in C++98, not C++11.
Update: As Dieter Lücking suggested in his answer an opeator+ needs to be introduced in the base class. This makes sense, but the problem is that Matrix, being abstract, does not allow methods which return abstract types. However, it is possible to return a pointer or a reference to Matrix; this way we would have a definition like:
Matrix& operator+(const Matrix& right) const;
To an extent this would work, but users of my code would expect a + to return a Matrix instead of a reference to one.
You may give the base class a state indicating the matrix layout - having that, dispatch matrix operations (on the base class) accordingly. Keep the special matrices classes for construction, but they will elide to the base matrix after applying an operation.
Example:
Matrix = IdentityMatrix operation DiagonalMatrix
This would elide the argument types and result in a matrix having a state 'Diagonal'
You might need to declare your Matrix::operator+ as virtual if you re-define it in your sub-classes and you initialize them as
Matrix *A = new DenseMatrix();
Also why is operator+ not a member of DenseMatrix? What I mean is
DenseMatrix DenseMatrix::operator+ (DenseMatrix const& right) const;
instead of
friend DenseMatrix operator+ (DenseMatrix const& left, DenseMatrix const& right);
Are you sure you need to re-overload operator+ in you derived classes again?
Can't you just inherit operator+ from your base class Matrix?
Edit:
If your base class does not have an operator+, but your derived ones do, you still need to declare (but not define) one as virtual in the base class, otherwise the derived classes cannot override it when they are pointed to by a Matrix* and not a DenseMatrix*.
Not sure why you want multiple + operators. Matrix addition is the same, no matter what the matrix representation:
1. Ensure the matrices being added have the same dimensions.
2. Add corresponding entries from the input matrices to produce the values in the output matrix.
These operations will be done in the base class operator +.
Then all you need is to implement getDimensions() in each subclass and, if they are equal, perform:
result.put(x, y, inputA.get(x, y) + inputB.get(x, y));
for each entry in the matrices.