I'm implementing matrices according to the strategy pattern.
for that I have MyMatrix, which holds a pointer to Matrix, and two subclasses that inherit from Matrix - SparseMatrix & RegMatrix.
when adding two matrices, because I can't know which matrix I'm adding to which matrix, I implemented a base function which uses an inner method of each inheriting class, and when adding - I just add the new elements to the lefthand matrix.
This works fine.
my problem is - I now want to perform matrix multiplication.
I want to implement this method in the base class - Matrix.
this is what I have until now:
Matrix& multiple(Matrix &other)
{
double result = 0;
int newMatrixRowSize = getRowSize();
int newMatrixColSize = other.getColSize();
double *resultArray = new double[newMatrixRowSize*newMatrixColSize];
for (int i = 1; i <= getColSize(); i++)
{
for (int j = 1; j <= other.getColSize(); j++)
{
for (int k = 1; k <= other.getRowSize(); k++)
{
Pair firstPair(i,k);
Pair secondPair(k,j);
result += getValue(firstPair)*other.getValue(secondPair);
}
Pair resultIndex(i,j);
resultArray[getNumIndex(resultIndex, newMatrixRowSize, newMatrixColSize)] = result;
result = 0;
}
}
delete [] resultArray;
}
only problem is, now I can't just add the new elements to the lefthand matrix, I have to create a new RegMatrix or SparseMatrix, and according to the number of zeros in the matrix - swap to the legit representation of matrix.
so my question is - is it "legal" or good practice to create an instance of the base class' derived class inside the base class?
I want to avoid using the factory pattern, and more willing to do something polymorphic without knowing the kind of matrix in hand
You have to use a factory if you want to create objects of different types depending on condition. If you don't want Matrix to know about its descendants, you have several options. Apart from implementations using interfaces, in C++11 you can use std::function:
class Matrix {
typedef std::function<Matrix*(const double*, int, int)> Factory;
Factory factory;
public:
Matrix(const Factory& f) : factory(f) {}
Matrix* multiple(Matrix &other) {
....
return factory(resultArray, newMatrixRowSize, newMatrixColSize);
}
};
It gives you the advantage that you can pass any function-like object as a factory:
Matrix* matrixFactoryFunc(const double* data, int rowSize, int colSize) {
return nullptr;
}
class MatrixFactoryCallable {
public:
Matrix* operator()(const double* data, int rowSize, int colSize) {
return nullptr;
}
};
class MatrixFactoryWithMemFun {
public:
Matrix* createMatrix(const double* data, int rowSize, int colSize) {
}
};
void testFactory() {
std::function<Matrix*(const double*, int, int)> factory;
factory = matrixFactoryFunc;
factory = MatrixFactoryCallable();
MatrixFactoryWithMemFun mi;
factory = std::bind(&MatrixFactoryWithMemFun::createMatrix, &mi, _1, _2, _3);
Matrix m(factory);
}
Related
I want to create a matrix of complex numbers. Point is that i want to create the matrix dynamically. I am stuck when i want to call the overloaded constructor.
I have 2 classes:
- nrComplex representing the complex numbers;
- mMatrix representing the matrix of complex numbers;
In the code i first create the rows then i want to create the columns for every row but i dont know how to initialize the class using the overloaded constructor
Any idea? Thanks
Ive done some research but i couldnt find anything that can fit my needs
class nrComplex
{
private:
float mReala, mImaginara;
public:
nrComplex ();
nrComplex (float, float);
friend class mMatrix;
};
nrComplex::nrComplex()
{
mReala = 0;
mImaginara = 0;
}
nrComplex::nrComplex(float a, float b)
{
mReala = a;
mImaginara = b;
}
class mMatrix
{
private:
int rows, columns;
nrComplex **matrice;
public:
mMatrix ();
mMatrix (float, float);
};
mMatrix::mMatrix()
{
rows = 0;
columns = 0;
matrice = NULL;
}
mMatrix::mMatrix (float n, float m)
{
rows = n;
columns = m;
matrice = new nrComplex*[rows];
for(int i=0;i<rows;i++)
{
matrice[i] = new nrComplex[columns];
}
// here is the part ^^^ where i get stuck
}
The square brackets will cause you to create an array of nrComplex objects. They will be initialized using the default constructor. If you want to re-initialize the nrComplex object, you can use placement new. I don't think you can create an array of objects and call anything other than the default constructor at the same time.
Since you're okay with friend'ing, you could just set the internal variables
happy new year!
I'm relatively new to both C++ and its community, so sorry for any mistake.
I'm implementing a mat (matrix) class with mat static Zeros(const int rows, const int cols) function, with mat return type. I want to implement a subclass sqmat (square matrix) with the same Zeros function, but returning sqmat.
I've come to this solution:
class mat{
private:
int rows;
int cols;
double* data;
public:
mat(int rows, int cols){
this -> rows = rows;
this -> cols = cols;
data = new double[rows*cols];
}
virtual ~mat(){ delete data; }
static mat Zeros(int rows, int cols){
mat matrix(rows, cols);
matrix.zero();
return matrix;
}
mat& zero(){
for(int i = 0; i < rows*cols; i++)
data[i] = 0;
return *this;
}
}
class sqmat : public mat {
public:
sqmat(int dim) : mat(dim){};
static sqmat Zeros(int dim){
sqmat matrix(dim);
matrix.zero();
return matrix;
}
}
In other words, I've used a backup member function zero that makes all the calculations, while I've used the static functions in the parent and child classes to handle the return type. This avoids code repetitions, but it doesn't feel right.
This requires, in fact, to create a backup member function for every static function that I want to implement for both the parent and the child classes, only to return the appropriate data type. Is there a more efficient way to handle this?
Unfortunately, both on my textbook and on the internet, polymorphism is explained using void returning functions, and so I don't have many examples.
PS avoid templates or "advanced" methods please
I have SquareMatrix defined as such
SquareMatrix.h
#ifndef SQUAREMATRIX_H
#define SQUAREMATRIX_H
#include "Matrix.h"
#include <vector>
class SquareMatrix : public Matrix
{
public:
SquareMatrix();
SquareMatrix(std::vector<std::vector<long double> >);
//~SquareMatrix(); //just in case there is dynamic memory explicitly used
//convenient member functions exclusive to SquareMatrix
bool isUpperDiagonalMatrix() const;
static SquareMatrix identityMatrix(unsigned);
void LUDecompose();
SquareMatrix *Lptr, *Uptr, *Pptr; //should be initialized by LUDecompose before using
protected:
void validateData();
private:
};
#endif // SQUAREMATRIX_H
and I am trying to set Lptr, Uptr (and maybe Pptr) with a call to SquareMatrix::LUDecompose(). It is defined below:
void SquareMatrix::LUDecompose()
{
unsigned rowCount = this->getRowCount();
//initialize L to identityMatrix
*this->Lptr = SquareMatrix::identityMatrix(rowCount);
//initialize U to sparse matrix with the first row containing the sole non-zero elements
std::vector<std::vector<long double> > UData(1, this->matrixData[0]); //making first rowVector the first rowVector of this
UData.insert(UData.end(), rowCount - 1, std::vector<long double>(rowCount,0)); //making all other rowVectors zero vectors
*Uptr = SquareMatrix(UData);
// attempting to perform LU decomposition
for (unsigned j = 0; j < rowCount; j++)
{
long double pivot = Uptr->matrixData[j][j];
//the pivot should be non-zero; throwing exception that should effectively cause function to return
if (pivot == 0)
throw MatrixArithmeticException(LU_DECOMPOSITION_FAILURE);
for (unsigned k = j+1; k < rowCount; k++)
{
if (j == 0)
{
//using *this to compute entries for L,U
this->Lptr->matrixData[k][j] = (this->matrixData[k][j])/pivot; //setting columns of L
long double multiplier = this->Lptr->matrixData[k][j];
//setting row of U
for (unsigned l = k; l < rowCount; l++)
{
Uptr->matrixData[k][l] = (this->matrixData[k][l])-multiplier*(this->matrixData[0][l]);
}
}
else
{
//using U to compute entries for L,U
//same procedure as before
this->Lptr->matrixData[k][j] = (Uptr->matrixData[k][j])/pivot;
long double multiplier = this->Lptr->matrixData[k][j];
for (unsigned l = k; l < rowCount; l++)
{
Uptr->matrixData[k][l] -= multiplier*(Uptr->matrixData[0][l]);
}
}
}
}
}
Upon trying to test out this function, it throws a segmentation fault at me, with the last line being the first line where I attempt to manipulate Lptr.
I attempt to change the object pointed by Lptr, and I know that I will not be able to reference the function and set the pointer equal to that reference. In other words, my compiler (GNU GCC compiler) will not allow this->Lptr = &SquareMatrix::identityMatrix(rowCount); as it will throw an -fpermissive type error.
Note: SquareMatrix::identityMatrix(unsigned) is defined as:
SquareMatrix SquareMatrix::identityMatrix(unsigned size)
{
std::vector<long double> rowVector(size, 0L);
std::vector<std::vector<long double> > identityMatrixData;
for (int i = 0; i < size; i++)
{
//setting the rowVector to zero-one vector
rowVector[i] = 1L;
if (i > 0) rowVector[i-1] = 0L;
//pushing rowVector into identityMatrixData
identityMatrixData.push_back(rowVector);
}
return SquareMatrix(identityMatrixData);
}
What do you think you CAN do about it?
I think I have two options:
throw the object on the heap, and then try to set it with the function (that would seem useless as you are redefining the object you just defined by throwing it on the heap)
get c++11 (or something similar)
Make the function a helper function that returns a std::vector<SquareMatrix*> of size two (containing pointers to the two desired SquareMatrix values), and create a function that calls the helper function and sets Lptr, Uptr to the respective elements of the returned vector.
Are my options this limited??
*Uptr = SquareMatrix(UData); in LUDecompose() is the problem.
You cannot set the pointer to an object that is being destroyed when the function returns. Then the pointer is a dangling pointer and whenever you attempt to use it, it'll segfault.
You need to do Uptr = new SquareMatrix(UData);. Then in your destructor, call delete Uptr;.
If you have access to C++11, you can use std::unique_ptr or any pointer containers/wrappers.
Examples of your options:
#include <memory>
class Matrix
{
public:
Matrix() {}
virtual ~Matrix() {}
};
class SqMatrix : public Matrix //using raw pointers. You must remember to delete your pointers.
{
private:
SqMatrix* UPtr = nullptr;
public:
SqMatrix() : Matrix() {}
void InitPtrs() {delete UPtr; UPtr = new SqMatrix();}
~SqMatrix() {delete UPtr;}
};
class OMatrix : public Matrix //No need to worry about clean up.
{
private:
std::unique_ptr<OMatrix> OPtr;
public:
OMatrix() : Matrix() {}
void InitPtrs() {OPtr.reset(new OMatrix());}
~OMatrix() {}
};
Another option is to just store it in a vector.
I need help in something really simple, which C++ makes very difficult. I created a class, lattice, with the aim to initialize and treat a matrix. There are the following private members:
private unsigned dim;
private double matrix [dim][dim];
I would like to initialize the variable dim in the constructor of the class through a parameter, but the compiler continue to return errors. I tried to make dim public and static and initializing it in the main program, but there are still problems. How could I create this simple class?
Moreover, I also implemented some methods in the class in order to update the values of the matrix. Is it true that, initializing an object of the class in a main program and then using its "updating" methods, the values of the matrix are stored only once?
Thank you for your help.
There are (at least) three ways to create such a class:
with a template
template<size_t dim>
class Matrix
{
private:
double matrix[dim][dim];
}
with the use of built in types such as std::vector (e.g. valarray would work too)
#include <vector>
class Matrix
{
private:
size_t dim;
std::vector<std::vector<double> > matrix;
public:
Matrix(size_t dim_) : dim(dim_), matrix()
{
matrix.resize(dim);
for ( size_t i = 0; i < dim; ++i )
matrix[i].resize(dim);
}
}
with the use of plain arrays (I do not recommend that!)
class Matrix
{
private:
size_t dim;
double** matrix;
public:
Matrix(size_t dim_) : dim(dim_), matrix()
{
matrix = new double*[dim];
for ( size_t i = 0; i < dim; ++i )
matrix[i] = new double[dim];
}
~Matrix() // you need a destructor!
{
for ( size_t i = 0; i < dim; ++i )
delete [] matrix[i];
delete [] matrix;
}
}
Use template:
template<int dim>
class Lattice{
double matrix[dim][dim];
}
and initialize dim in the constructor:
Lattice<10> sampleLattice;
Then dim = 10;
You might use pointer, or vector of a vector, but template is what I would use because it is less confusing and convenient.
BTW you will have to use private: and public: (with colon).
I'm guessing your "problems" are the compiler complaining about array initialization with non const size.
You should do something like this:
class MyClass {
public:
MyClass(unsigned pdim);
private:
MyClass();
const unsigned dim;
const double matrix [dim][dim];
};
MyClass::MyClass(unsigned pdim) : dim(pdim) {
// Other things
}
You can have const members inside a class but they need to be initialized using the : syntax.
I need to get an input N from the user and generate a N*N matrix. How can I declare the matrix? Generally, the size of the array and matrix should be fixed at the declaration, right?
What about vector<vector<int>> ? I never use this before so I need suggestion from veteran.
A vector<vector<int>> (or vector<vector<int> >, for older compilers) can work well, but it's not necessarily the most efficient way to do things1. Another that can work quite nicely is a wrapper around a single vector, that keeps track of the "shape" of the matrix being represented, and provides a function or overloaded operator to access the data:
template <class T>
class matrix {
int columns_;
std::vector<T> data;
public:
matrix(int columns, int rows) : columns_(columns), data(columns*rows) {}
T &operator()(int column, int row) { return data[row*columns_+column]; }
};
Note that the C++ standard only allows operator[] to take a single operand, so you can't use it for this job, at least directly. In the example above, I've (obviously enough) used operator() instead, so subscripts look more like Fortran or BASIC than you're accustomed to in C++. If you're really set on using [] notation, you can do it anyway, though it's mildly tricky (you overload it in the matrix class to return a proxy, then have the proxy class also overload operator[] to return (a reference to) the correct element -- it's mildly ugly internally, but works perfectly well anyway).
Here's an example of how to implement the version using multiple overloads of operator[]. I wrote this (quite a while) before most compilers included std::vector, so it statically allocates an array instead of using a vector. It's also for the 3D case (so there are two levels of proxies involved), but with a bit of luck, the basic idea comes through anyway:
template<class T, int size>
class matrix3 {
T data[size][size][size];
friend class proxy;
friend class proxy2;
class proxy {
matrix3 &m_;
int index1_, index2_;
public:
proxy(matrix3 &m, int i1, int i2)
: m_(m), index1_(i1), index2_(i2)
{}
T &operator[](int index3) {
return m_.data[index1_][index2_][index3];
}
};
class proxy2 {
matrix3 &m_;
int index_;
public:
proxy2(matrix3 &m, int d) : m_(m), index_(d) { }
proxy operator[](int index2) {
return proxy(m_, index_, index2);
}
};
public:
proxy2 operator[](int index) {
return proxy2(*this, index);
}
};
Using this, you can address the matrix with the normal C++ syntax, such as:
matrix3<double, size> m;
for (int x=0; x<size; x++)
for (int y = 0; y<size; y++)
for (int z = 0; z<size; z++)
m[x][y][z] = x*100 + y * 10 + z;
An std::vector is normally implemented as a pointer to some dynamically allocated data, so something like a vector<vector<vector<int>>> will dereference two levels of pointers to get to each piece of data. This means more memory references, which tend to be fairly slow on most modern processors. Since each vector contains separately allocated data, it also leads to poor cache locality as a rule. It can also waste some space, since each vector stores both its allocated size and the size in use.
Boost implements matrices (supporting mathematical operations) in its uBLAS library, and provides usage syntax like the following.
#include <boost/numeric/ublas/matrix.hpp>
int main(int argc, char* argv[])
{
unsigned int N = atoi(argv[1]);
boost::matrix<int> myMatrix(N, N);
for (unsigned i = 0; i < myMatrix.size1 (); ++i)
for (unsigned j = 0; j < myMatrix.size2 (); ++j)
myMatrix(i, j) = 3 * i + j;
return 0;
}
Sample Code:
template<class T>
class Array2D
{
public:
Array2D(int a, int b)
{
num1 = (T**)new int [a*sizeof(int*)];
for(int i = 0; i < a; i++)
num1[i] = new int [b*sizeof(int)];
for (int i = 0; i < a; i++) {
for (int j = 0; j < b; j++) {
num1[i][j] = i*j;
}
}
}
class Array1D
{
public:
Array1D(int* a):temp(a) {}
T& operator[](int a)
{
return temp[a];
}
T* temp;
};
T** num1;
Array1D operator[] (int a)
{
return Array1D(num1[a]);
}
};
int _tmain(int argc, _TCHAR* argv[])
{
Array2D<int> arr(20, 30);
std::cout << arr[2][3];
getchar();
return 0;
}
enter code here