Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Matrix Class

Tags:

c++

matrix

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++.

like image 716
anon Avatar asked Jan 16 '10 07:01

anon


People also ask

What is the class of a matrix?

The Matrix class is a class contained by all actual classes in the Matrix package. It is a “virtual” class.

Is there a matrix class in C++?

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.

How do you define a matrix class in C++?

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).


2 Answers

nota bene.

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:

  • It does not allocate extra space. A 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().)
  • You may slice it to access rows and columns easily.
  • Arithmetic operators work as you would expect.

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 
like image 66
Potatoswatter Avatar answered Oct 02 '22 21:10

Potatoswatter


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.)

like image 40
jamesdlin Avatar answered Oct 02 '22 21:10

jamesdlin