I am working on improving my C++ skills - specifically the use of templates. I am creating a filtering mathematical library that through the use of templates is compatible for different vector/matrix classes including Boost and Eigen. So far I am very happy with the library, but am encountering issues as I am expanding functionality.
Eigen and Boost are different in that for example the latter does not have multiply operators (see 1) so this presented a choice in my implementation. I decided to make sure that the matrix/vector methods and operators used within the template library use those that are defined for Eigen so that at least one library works really well with the mathematical library. In my library I would use * to multiply matrices which is unavailable for boost. For boost I created a wrapper class for both matrix and vector to allow the use of * through custom operators. Example of wrapper for matrix is below:
class matrixBoost{
private:
boost::numeric::ublas::matrix<double> value;
public:
matrixBoost(){
}
matrixBoost(boost::numeric::ublas::matrix<double> value):value(value){}
static matrixBoost Identity(int dimension,int dimension2){
return matrixBoost(boost::numeric::ublas::identity_matrix<double>(dimension,dimension2));
}
matrixBoost transpose(){
matrixBoost t(boost::numeric::ublas::trans(value));
return t;
}
boost::numeric::ublas::matrix<double> getSystemValue() const{
return value;
}
};
//example operator - one of many
matrixBoost operator*(const matrixBoost &lhs, const matrixBoost &rhs){
matrixBoost res(boost::numeric::ublas::prod(lhs.getSystemValue(),rhs.getSystemValue()));
return res;
}
I am now trying to add Eigen's block to boost's wrapper class that allows for the following behaviour in Eigen's library:
Eigen::MatrixXd m(2,2);m<<1,2,3,4;
Eigen::MatrixXd n = m.block(0, 0, 1, 2) + m.block(0,0,1,2);
m.block(0,0,1,2) = n;
with m
now equalling
2 4
3 4
My first question is can someone please link or show examples of how the block function would be coded (without considering a wrapper class even). I have tried googling but either Google has gotten worse or I am not using the right key words - the results are swarmed with operator[] results. I am having difficulty understanding. I tried searching within the Eigen library source and imagine the code must be located here but the template language is a little difficult for me to parse easily.
I know that boost also has a similar concept as shown in here:
project(A, r1, r2) = C; // assign the submatrix of A specified by the two index ranges r1 and r2
C = project(A, r1, r2); // the submatrix of A specified by the two index ranges r1 and r2
I am not sure if adding a block function to my wrapper class is even possible. For now I have the following:
matrixBoost block(int index1,int index2, int length1, int length2){
boost::numeric::ublas::range r1(i1,l1);
boost::numeric::ublas::range r2(i2,l2);
return matrixBoost(boost::numeric::ublas::project(value,r1,r2));
}
This will work for when the method is on the right hand side of the the equal sign. However, I am having difficulty as to how to proceed to allowing for the method being called on the left hand side. Perhaps I should make use of boost's project method. Any help would be much appreciated!
Thank you.