矩阵/线性代数库周围的多态包装 - C ++,从Eigen开始

时间:2014-05-01 19:18:34

标签: c++ windows linear-algebra eigen

我正在编写一个很大程度上依赖于线性代数例程的自定义C ++数值库。我也在使用Eigen来满足实际的矩阵运算。我想将我的库与Eigen实现分离,以便它不知道Eigen。这将允许我将Eigen引用保存在一个地方,并且可以在不久的将来轻松地将线性代数库更改为另一个实现。

在java中,这会相对简单。但是我在使用模板时遇到了困难。特别是我使用MatrixXd和VectorXd类型。有没有人建议围绕这些类构建一个包装器,它将在Eigen和我的库之间提供一个可靠的边界?

我的第一次尝试是使用合成实现的,因此对MyBaseMatrix的调用将定向到所包含类型(例如MatrixXd)中的调用,如下所示:https://forum.kde.org/viewtopic.php?f=74&t=87072&p=154014&hilit=wrap+eigen#p154014。但是我怀疑我会保留Eigen的引擎优化吗?

这里建议另外两个解决方案:http://eigen.tuxfamily.org/dox-devel/TopicCustomizingEigen.html#ExtendingMatrixBase,(扩展MatrixBase或继承Matrix)。然而,他们似乎并没有允许我在特征类型和我的数值库之间的严格边界。扩展MatrixBase似乎也不允许运算符重载?

我考虑过继承Matrix和MyBaseMatrix(多重继承),但是当试图保持一个干净的边界时,模板让我头疼。

有没有人对这个特殊问题或C ++中类似问题的解决方案有任何经验?

1 个答案:

答案 0 :(得分:0)

我不建议从代码设计的角度来做这件事,因为线性代数库不是你可能会替换的东西。因此封装它很可能不会有益,并会使您的代码更复杂。但是,如果您真的想这样做,您将使用模板专业化。以下内容:

template< typename InternalMatrixType>
class Matrix
{
private:
    InternalMatrixType _matrix;
public:
   // Example function
   float operator[](unsigned index)
   {
      return _matrix[index];
   }
};

对于特定的线性代数库:

template<>
class Matrix<EigenMatrixType>
{
private:
    EigenMatrixType _matrix;
public:
   // Example function
   float operator[](unsigned index)
   {
      return _matrix.get(index);
   }
};

编辑:添加了有关typedef的信息以阐明用法。基于moodle的以下评论。

然后在整个库中,您可以键入dede模板类。这样您就可以使用cMatrix vs Matrix<InternalMatrixType>

之类的内容
typedef Matrix<InternalMatrixType> cMatrix;