6

大規模な数値シミュレーション (有限要素法、有限差分法、トポロジー最適化など) を実行するために、私の研究グループで新しい C++ コードを実装しようとしています。このソフトウェアは、学界と産業界の両方の人々によって使用されます。

ソフトウェアの密な線形代数部分については、Eigen または Armadillo のいずれかを使用したいと考えています。これらのパッケージのラッパーを作成する理由は 2 つあります。1. サードパーティの API ではなく、独自の API をユーザーに公開するため。2. 将来ライブラリを切り替える必要がある場合。理由 2 は非常に高額な保険であることは承知していますが、以前のシミュレーション ソフトウェアでこのような状況に遭遇しました。

サードパーティ ライブラリのラッピングに関して私が遭遇した情報は、次の情報源からのものです。

私の質問は、このラッパー クラスを構築する最良の方法に関するものです。理想的には、次のように薄層ラッパーが最適です。

template< typename T >
class my_vec {
private:
    arma::Col< T > _arma_vec;
};

または固有ベクトルと同等のもの。

次に、私のクラスはサードパーティのライブラリ クラスを次のように呼び出します。

my_vec::foo() { return _arma_vec.foo(); }

この薄いレイヤーの問題は、これらのライブラリが内部で実装した式テンプレートから得られる速度が失われることだと思います (これについて確認したいと思います)。たとえば、Armadillo では、次の操作を行います。

// Assuming these vectors were already populated.
a =  b + c + d;

次のようになります。

for ( std::size_t i = 0; i < a.size(); ++i ) {
    a[i] = b[i] + c[i] + d[i];
}

式テンプレートが実装されているため、一時変数を作成する必要はありません。同じ状況がアイゲンにも当てはまります。

私の知る限り、式テンプレートの力を失った理由は、Armadillo や Eigen が独自の一時変数を作成しないのに対し、私のクラス my_vec は作成するためです。これを回避する唯一の方法は、式テンプレートの周りにも薄いレイヤー ラッパーを構築することです。ただし、現時点では、これは YAGNI 原則に違反しているようです。

この関連する質問は次のとおりです。

次のようなものを使用することをお勧めします。

my_vec a, b, c;
// ... populate vectors
a._arma_vec = b._arma_vec + c._arma_vec;

代わりにこのようなものを使用することは可能ですか?

template< typename T >
arma::Col< T > &
my_vec< T >::data() { return _arma_vec; }

a.data() = b.data() + c.data();

または、演算子のオーバーロードを使用して data() をユーザーから隠しますか? ライブラリを直接使用したくない場合、他にどのような選択肢がありますか? マクロを使用していますか?C++11 を使用する場合、エイリアスを使用しますか?

または、このラッパー クラスを構築する最も便利な方法は何でしょうか?

4

1 に答える 1