1

Eigen3 と組み込み型の相互互換性

こんにちは。私は、Eigen3 型 (行列と配列) と組み込み型の両方を処理できるルーチンを作成するという問題に悩まされています。例を挙げて説明すると、Meter<Type>実行時に統計を収集する機能を持つテンプレート クラスがあるとします。

Type クラスは、次の演算子をサポートする必要があります。

  • operator=(Scalar)
  • operator=(Type)
  • operator+(Type)
  • operator-(Type)
  • operator*(Type)
  • operator/(Type)
  • operator*(Scalar)
  • operator/(Scalar)

Eigen3types は、これらすべての演算子に 2 つの例外を指定して提供します。1 つ目は、が のサブクラスであるoperator*(Type)場合はドットプレダクトを表し、 が のサブクラスである場合は係数単位の積を表します。これは簡単に回避できます。第二に、どちらもゼロへの正しい初期化を保証するために必要なを実装していません。TypeEigen::MatrixBaseTypeEigen::ArrayBaseoperator=(Scalar)

次のファンクタークラスを実装して区別を処理しようとしましたが、それらを機能させることができません:

組み込み型とEigen3型の間の区別を処理するためのいくつかの構造体:

template < class _Type > struct is_scalar : true_type {
    using Scalar = _Type;
    using Type = _Type;

    static constexpr bool value = true;
};

template < class _Matrix >
struct is_scalar<Eigen::MatrixBase<_Matrix>> : false_type {
    using Scalar = typename Matrix::Scalar;
    static constexpr bool value = false;
};

template < class _Array >
struct is_scalar<Eigen::ArrayBase<_Array>>  : false_type {
    using Scalar = typename Array::Scalar;
    static constexpr bool value = false;
};

関数の実装自体

template < class Scalar, bool is_scalar = Math::is_scalar<Scalar>::value > 
struct set_const_impl;

template < class Scalar >
struct set_const_impl< Scalar, true > {
    static const void run(Scalar &_x, Scalar _y) noexcept { _x = _y; }
};

template < class EigenType >
struct set_const_impl<EigenType, false> {
    template < class Scalar >
    static const void run(Eigen::EigenBase<EigenType> &_x, Scalar _y) noexcept {
        _x.derived().setConstant(_y);
    }
};

template < class Type, class Scalar > void set_const(Type &_x, Scalar _y) noexcept {
    set_const_impl<Type>::run(_x, _y);
}

template < class Type > void set_zero(Type &_x) noexcept {
    set_const_impl<Type>::run(_x, 0);
}

特殊化されたバージョンset_const_impl<EigenType>はインスタンス化されません。たとえば、私が電話した場合

Eigen::Matrix<double, 3, 1> m1; 
set_zero(m1);

私はコンパイラにオンラインで不平を言うように0させます

set_const_impl<Type>::run(_x, 0);

つまり、ファン0クターEigen::Matrix<double, 3, 1>のバージョンを選択したことを意味しset_const_impl<Scalar, true>ます (両方の引数が共通の型を共有する場合Scalar)。is_scalarこれは、既に使用して他のクラスで問題なくテストしたとしても、この場合、私の構築が機能していないことも意味します。

他のいくつかのクラスでこの動作が必要ですが、それぞれを明示的に特化したくありません! これを修正するにはどうすればよいか知っている人はいますか?

助けてくれてありがとう!

4

3 に答える 3