Home > Enterprise >  Implementing Matrix operations in C
Implementing Matrix operations in C

Time:11-12

I am trying to write a simple C header-only library that implements some basic numerical algorithms. It's a hobbyist project, that I wish to do in my personal time.

I created a C MatrixX class that represents dynamic-size matrices, that is its dimensions can be supplied at run-time. Say, we create a MatrixX object as follows :

MatrixXd m {
{1, 0, 0},
{0, 1, 0},
{0, 0, 1}
};

My MatrixX<scalarType> templated class uses std::vector<scalarType> as the container to store data.

Currently, if I write m.row(i), it returns the i'th row vector of the matrix. What I'd also like is, to be able to have m.row(i) on the left-hand side of an assignment statement. Something like:

m.row(i) = {{1, 2, 3}};
m.row(j) = m.row(j) - 2*m.row(i);

Does anyone have any hints/tips on how to go about this task in C ? I am including my source code, unit tests and documentation as links below, and not pasting it inline for the sake of brevity.

CodePudding user response:

A common approach for this type of situation is to have the row() method return a proxy object that represents the row without being the row itself.

You are then free to implement how this RowProxy behaves by having its operations inspect and maninupulate the matrix it was created from.

Here's a rough starting point:

template<typename T>
class RowProxy {
public:
  template<std::size_t N>
  RowProxy& operator=(const std::array<T, N>& rhs) {
    assert(N == row_index_.columns());
    // ...
  }

  RowProxy& operator=(const RowProxy& rhs) {
    assert(matrix_.columns() == rhs.matrix_.columns());
    // ...
  }

  RowProxy& operator=(const Vector<T>& rhs) {
    assert(matrix_.columns() == rhs.matrix_.columns());
    // ...
  }

  Vector<T>& operator*(const T& scalar) const {
    return ...;
  }

  // more operators...

private:
  MatrixX<T>& matrix_;
  std::size_t row_;
  
  template<typename T>
  friend class MatrixX;

  RowProxy(MatrixX<T>& m, std::size_t r) : matrix_(m), row_(r) {}
};

template<typename T>
struct MatrixX {
public:
  // ...
  
  RowProxy<T> row(std::size_t index) {
    return RowProxy<T>{*this, index};
  }

  // ...
};

template<typename T>
Vector<T>& operator*(const T& scalar, const RowProxy* rhs) const {
    return rhs * scalar;
}
  • Related