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

Polymorphic wrapper around matrix/linear algebra libraries - C++, starting with Eigen

本文关键字:-C++ Eigen 开始 包装 线性代数 多态 矩阵      更新时间:2023-10-16

我正在编写一个严重依赖线性代数例程的自定义C++数值库。我也在使用Eigen来满足实际的矩阵运算。我想将我的库与Eigen实现解耦,这样它就不知道Eigen了。这将使我能够将Eigen引用保留在一个位置,并在不久的将来轻松地将线性代数库更改为另一个实现。

在java中,这将相对简单。然而,我在使用Eigen时遇到了困难,因为它使用模板。特别是,我使用的类型是MatrixXd和VectorXd。有人对围绕这些类构建一个包装器有什么建议吗?这个包装器将在Eigen和我的库之间提供一个坚实的边界?

我的第一次尝试是使用composition实现的,因此对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++中类似问题的解决方案吗?

从代码设计的角度来看,我不建议这样做,因为线性代数库不可能被替换。因此,封装它很可能没有好处,而且会使代码变得更加复杂。但是,如果您真的想这样做,您可以使用模板专门化。大致如下:

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);
   }
};

编辑:添加了有关typedefs的信息以澄清用法。基于moodle的以下评论。

在整个库中,您可以对模板类进行typedef。这将允许您使用类似cMatrixMatrix<InternalMatrixType>的内容。

typedef Matrix<InternalMatrixType> cMatrix;