Is a vector <vector <double> a good way to create a matrix class?
I am a student of mathematics and completely new to C ++, and to help in learning, I want to create a matrix class (I do not want to use a library class). I was thinking of doing something like
int iRows = 5; int iColumns = 6; double** pMatrix = new double*[iRows]; for (int i = 0; i < iRows; ++i) { pMatrix[i] = new double[iColumns]; } (I'm not sure if this is the correct syntax - I wanted to get advice here before trying), but I see here at Stackoverflow that using pointers that are not like shared_ptr is not recommended. Is it better to use vector<vector<double>> , so I donβt have to worry about memory deletion? I am worried that the vector is not a good choice, because the length can be changed using push_back, and I want the matrix to be fixed in size. I can not use
double dMatrix[iRows][iColumns]; since the dimensions are not constant. What would be the best choice for me?
I would ask first: what are you trying to achieve? Do you want to create something as a training exercise, or do you need a decent implementation of the matrix?
If you want to do this as an exercise for learning, I would suggest using only the 1d double vector inside with elements of MxN. Create a class that stores this internally, but hides the implementation from callers - they do not need to know or care about how they are stored. As part of an interface, you usually want to access it through the (m, n) operator, for example
double& MyMatrix::operator()(int m, int n) { return m_Array[m*numColumns + n]; } As soon as you try to do more interesting things with it, such as addition and multiplication, you will realize that you will have to overload the arithmetic operators. Not only operator+ , operator- , but also the operators *, /, * =, + =, - = / =, ++, -. When you do the multiplication, you may find that your implementation may be too slow to be useful, as you may find that you are making many redundant copies. Ymmv
So, if you need a fast matrix library, you will need a library that uses BLAS inside, for example, the Boost Basic Linear Algebra library .
Perhaps first try it yourself to get an idea of ββthe problems with getting a good design, and then take a look at the promotion as you will learn a lot by learning it.
No, definitely not. Neither
vector<vector<double>> matrix; neither
double** matrix; - good layouts for the matrix class. Although your class may work well to become familiar with programming, the performance of such a matrix class will be worse. The problem is that you are losing data locality. Just review your code
for (int i = 0; i < iRows; ++i) { pMatrix[i] = new double[iColumns]; } For effective matrix-vector multiplication, the cache must have as many matrix values ββas possible, otherwise the memory transfer will take too much time. When you acquire one block of memory per line, there is no guarantee that these data demans are close to each other in memory. For simple matrix vector multiplication, this may not be so bad, because the elements of the row are still stored contiguously, and the "only" transition from one row to the next leads to a cache miss.
However, working on a transposed matrix is ββindeed a problem, because the values ββalong the column can be stored anywhere in memory, and there is no reasonable way to determine the step between those elements that can be used to prefetch the cache.
Thus, as suggested by other authors, use one large block of memory for your matrix. This requires a little more effort on your part, but it will pay off for users of your matrix class.