大規模な数値シミュレーション (有限要素法、有限差分法、トポロジー最適化など) を実行するために、私の研究グループで新しい 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 を使用する場合、エイリアスを使用しますか?
または、このラッパー クラスを構築する最も便利な方法は何でしょうか?