Vitality
Vitality

Reputation: 21495

Implementing the A(:,k)=b; Matlab-like syntax in a C++ matrix library

I have developed an expression templates-based C++ matrix class of my own. I have overloaded the () operator so that I can read or write element matrices as, for example,

cout << A(i,j) << endl;

and

A(i,j)=b;

respectively. I have also implemented a Range class to enable Matlab-like reads as

cout << A(Range(3,5),Range(0,10)) << endl;

The template Matrix class is exemplified as

template <typename OutType>
class Matrix
{
    private:
        int Rows_;          //number of Rows
        int Columns_;       //number of Columns
        OutType *data_;     //row-major order allocation
    public:

        // --- Access operators 
        inline OutType & operator()(const int i, const int j)       { return data_[IDX2R(i,j,GetColumns())]; }
        inline OutType   operator()(const int i, const int j) const { return data_[IDX2R(i,j,GetColumns())]; }

        // --- SubExpressions - Range Range
        inline Expr<SubMatrixExpr<const OutType*,OutType>,OutType> operator()(Range range1, Range range2)
        {   typedef SubMatrixExpr<const OutType*,OutType> SExpr; 
                return Expr<SExpr,OutType>(SExpr(data_,Rows_,Columns_,range1.numelements_,range2.numelements_,range1.start_,range1.step_,range2.start_,range2.step_),
                        range1.numelements_,range2.numelements_); 
        }
}

I would now like to enable Matlab-like assignments as

A(Range(3,5),Range(0,10))=B;

where B is an appropriate matrix.

I think that, to achieve the Matlab-like syntax above, two possibilities would be

  1. overloading the () operator, so that it returns an array of pointers, and then overloading the = operator so that the latter could act between an array of pointers and a Matrix;
  2. exploit the already performed overload of the () operator indicated above and overloading the = operator so that the latter could act between an expression and a Matrix.

Maybe the first option is not very convenient, especilly for very large matrices. Am I correct? Are there other more efficient/effective possibilities using perhaps more sophisticated C++ features (e.g., move semantics)?

Thank you very much for your help.

Upvotes: 1

Views: 268

Answers (1)

Mark B
Mark B

Reputation: 96281

I think your best bet is to have a non-const version of operator()(Range, Range) return a proxy object that has an overloaded assignment operator that knows how to assign to a range (back into the original matrix for example).

Upvotes: 1

Related Questions