現在、サードパーティ ライブラリのマトリックス クラスのラッパーであるテンプレート クラス Mat を実装しました (T はコンポーネントの型です: double、int など)。ここで、ストレージに 1 つの Mat を使用し、インデックスのマッピングに 2 つ目の Mat を使用する Tensor クラスを実装したいと考えています。
Tensor クラスを Tensor としてテンプレート化しました。ここで、T は Mat クラスと同じです。Order と Dim は整数であり、テンソルの次数 (またはランク) と次元 (2 または 3) です。Sym は、対称性を表すブール フラグです。
Tensor クラスは Voigt 表記法を使用して、高次のテンソルを行列に圧縮します (たとえば、3 x 3 x 3 x 3 のテンソルは 6 x 6 の行列にマッピングできます。これはインデックスの各ペアを単一のインデックスにマッピングすることによって行われます)。Voigt 表記法では、3 行 3 列のテンソルを 6 行 1 列のベクトル (行列) にマッピングできますが、テンソルの (0,0) 成分をベクトルの 0 位置に移動します。類似 (1,1) -> 1、(2,2) -> 2、(1,2) -> 3、(0,2) -> 4、および (0,1) -> 5. 類似のルール2 行 2 列のテンソルを終了します (これらは 3 行 1 列の行列にマップされます)。
この目的のために、Tensor クラスが行列を所有するようにしたいと思います。
0 5 4
5 1 3
4 3 2
Dim == 3 かつ Sym == true の場合。非対称テンソルと 2D テンソル (全部で 4 つ) に対応するマップがあります。これらは、他のテンプレート パラメーター (T および Order) に依存しません。
したがって、どの時点でそれらを専門化するのでしょうか? (ここで、質問は、部分的な特殊化のみに static const メンバーを必要とするテンプレート化されたクラスを持つすべての人に適用されます)。
ここでこの質問をチェックアウトしました:テンプレート クラスの静的 const メンバー変数を定義する場所。ただし、部分的な特殊化については説明していません。
これまでのところ、同じヘッダー ファイルに前方宣言とクラス定義があります。
//cl_Tensor.hpp
namespace myNamespace
{
template< typename T, int Order, int Dim, bool Sym >
class Tensor;
}
template< typename T, int Order, int Dim, bool Sym >
class myNamespace::Tensor
{
protected:
myNamespace::Mat< T> mMat; // storage
static const myNamespace::Mat < uint > mTensorMap;
public:
// member functions and the like...
}
Tensor クラスの単体テストでは、次のように入力できます。
template<> const moris::Mat< moris::uint> moris::Tensor< moris::real, 1, 2, true>::mTensorMap = { { 0, 2}, {2, 1} };
template<> const moris::Mat< moris::uint> moris::Tensor< moris::real, 1, 2, false>::mTensorMap = { { 0, 3}, {2, 1} };
template<> const moris::Mat< moris::uint> moris::Tensor< moris::real, 1, 3, true>::mTensorMap = { { 0, 5, 4}, {5, 1, 3}, {4, 3, 2} };
template<> const moris::Mat< moris::uint> moris::Tensor< moris::real, 1, 3, false>::mTensorMap = { { 0, 5, 4}, {8, 1, 3}, {7, 6, 2} };
問題は、すべての注文 (1、2、3、および 4) に対してこれを行う必要があることです。また、他の型のテンソル (ここでは、real は long double の typdef) を使用すると、重複するコードが多すぎます。
どこでマップを初期化できますか?