2D配列を表すためにダブルポインタを多用するコードを継承しました。Eigenの使用経験はほとんどありませんが、ダブルポインターよりも使いやすく、堅牢なようです。
どちらが望ましいかについて誰かが洞察を持っていますか?
Eigenには、データの連続した配列にEigen行列を作成できるマップ機能があることを忘れないでください。継承したコードを完全に変更することが難しい場合は、少なくともEigenマトリックスにマッピングすると、生のポインターとの相互運用が容易になる可能性があります。
Eigen と Boost.uBLAS はどちらも、特定の制約を満たす任意のストレージ クラスを使用できる式の階層と抽象行列データ構造を定義します。これらのライブラリは、線形代数演算を明確に表現し、非常に高いレベルで効率的に評価できるように作成されています。どちらのライブラリも式テンプレートを多用し、かなり複雑なコンパイル時の式変換を行うことができます。特に、Eigen は SIMD 命令も使用でき、いくつかのベンチマークで非常に優れています。
密行列の場合、一般的なアプローチは、単一のポインターを使用して、追加の行、列、およびストライド変数を追跡することです (3 番目の変数が必要になる理由は、x * y * sizeof(value_type)
要素を格納するために実際に必要な量よりも多くのメモリを割り当てた可能性があるためです。アライメントの)。ただし、範囲外のアクセスをチェックするメカニズムはなく、デバッグに役立つコードもありません。たとえば、教育目的で線形代数演算を実装する必要がある場合にのみ、この種のアプローチを使用する必要があります。(その場合でも、実装するアルゴリズムを最初に検討してから、 、 、 、および演算子のオーバーロードを検討することをお勧めしstd::unique_ptr
ますstd::move
) std::allocator
。
確かに、最新の C++ では、生のポインターではなくコンテナーを使用する必要があります。
Eigen を使用する場合、固定サイズのクラス ( などVector3d
) は、適切に配置する必要がある最適化を使用することに注意してください。これらの固定サイズの固有値を構造体またはクラスのメンバーとして含める場合、これには特別な注意が必要です。また、値で渡すことはできず、参照によってのみ渡すことができます。
そのような最適化を気にしない場合は、それを無効にするのは簡単です: 単純に追加します
#define EIGEN_DONT_ALIGN
Eigen を使用するすべてのソース ファイル (.h、.cpp、...)の最初の行として。
他の 2 つのオプションは次のとおりです。
#include <boost/numeric/ublas/matrix.hpp>
boost::numeric::ublas::matrix<double> m (3, 3);
#include <vector>
std::vector<std::vector<double> > m(3, std::vector<double>(3));