In C, if I wanted to create a matrix struct, I would use:
struct matrix { int col, row; double data[1]; // I want the matrix entries stored // right after this struct }
Then I can allocate it with
matrix* allocate_matrix(int row, int col) { matrix* m = malloc(sizeof(matrix) + sizeof(double) * (row * col - 1)); m->row = row; m->col = col; return m; }
Now do I do the equiv in C++?
EDIT:
I want to know the cannonical way to implement a matrix class in C++.
The Matrix class is a class contained by all actual classes in the Matrix package. It is a “virtual” class.
A simple mathematical matrix class written in C++ to be reused for future assignments in my Computational Linear Algebra class. The Matrix class comes loaded with basic operations such as addition, multiplication, element access, input and output, identity matrix creation, and simple linear system solving methods.
A matrix can have a number of rows and columns and each cell of a matrix can be represented by their combination. For instance, the above matrix is a 4x5 matrix. It means it has 4 rows and 5 columns. If you want to represent 11, you can write it in this form: V(1,5).
This answer has 20 upvotes now, but it is not intended as an endorsement of std::valarray
.
In my experience, time is better spent installing and learning to use a full-fledged math library such as Eigen. Valarray has fewer features than the competition, but it isn't more efficient or particularly easier to use.
If you only need a little bit of linear algebra, and you are dead-set against adding anything to your toolchain, then maybe valarray
would fit. But, being stuck unable to express the mathematically correct solution to your problem is a very bad position to be in. Math is relentless and unforgiving. Use the right tool for the job.
The standard library provides std::valarray<double>
. std::vector<>
, suggested by a few others here, is intended as a general-purpose container for objects. valarray
, lesser known because it is more specialized (not using "specialized" as the C++ term), has several advantages:
vector
rounds up to the nearest power of two when allocating, so you can resize it without reallocating every time. (You can still resize a valarray
; it's just still as expensive as realloc()
.)Of course, the advantage over using C is that you don't need to manage memory. The dimensions can reside on the stack, or in a slice object.
std::valarray<double> matrix( row * col ); // no more, no less, than a matrix matrix[ std::slice( 2, col, row ) ] = pi; // set third column to pi matrix[ std::slice( 3*row, row, 1 ) ] = e; // set fourth row to e
C++ is mostly a superset of C. You can continue doing what you were doing.
That said, in C++, what you ought to do is to define a proper Matrix class that manages its own memory. It could, for example be backed by an internal std::vector
, and you could override operator[]
or operator()
to index into the vector appropriately (for example, see: How do I create a subscript operator for a Matrix class? from the C++ FAQ).
To get you started:
class Matrix { public: Matrix(size_t rows, size_t cols); double& operator()(size_t i, size_t j); double operator()(size_t i, size_t j) const; private: size_t mRows; size_t mCols; std::vector<double> mData; }; Matrix::Matrix(size_t rows, size_t cols) : mRows(rows), mCols(cols), mData(rows * cols) { } double& Matrix::operator()(size_t i, size_t j) { return mData[i * mCols + j]; } double Matrix::operator()(size_t i, size_t j) const { return mData[i * mCols + j]; }
(Note that the above doesn't do any bounds-checking, and I leave it as an exercise to template it so that it works for things other than double
.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With