2

Tensor のテンプレート表現を使用して外積を実装しています。

テンソルの基本プロトタイプは次のようになります。

template <int N>
struct Tensor
{
    Tensor<N - 1> x;
    Tensor<N - 1> y;
    Tensor<N - 1> z;
};

Tensor<1>単純なベクトルに分解するための特殊化。私のOuter関数は次のように定義されています。

template <int N, int M>
Tensor<N + M> Outer(const Tensor<N> &lhs, const Tensor<M> &rhs)
{
    Tensor<N + M> result;

    result.x = Outer(lhs.x, rhs);
    result.y = Outer(lhs.y, rhs);
    result.z = Outer(lhs.z, rhs);

    return result;
}

template <int N>
Tensor<N + 1> Outer(const Tensor<N> &lhs, const Tensor<1> &rhs)
{
    Tensor<N + 1> result;

    result.x = Outer(lhs.x, rhs);
    result.y = Outer(lhs.y, rhs);
    result.z = Outer(lhs.z, rhs);

    return result;
}

template <>
Tensor<2> Outer(const Tensor<1> &lhs, const Tensor<1> &rhs)
{
    Tensor<2> result;

    result.x.x = lhs.x * rhs.x;
    result.x.y = lhs.x * rhs.y;
    result.x.z = lhs.x * rhs.z;

    // and so on

    return result;
}

次数のテンソルとAN数のテンソルの外積は、単純に の各要素とテンソルの外積です。任意の次数テンソルと次数テンソルの外積も同様に定義されます。BMABN1

1基本ケースは、単純に 2 次テンソル (ベクトル)の外積です。ただし、上記で定義したようにC1202、MSVC でエラーが発生します。

エラー C1202: 再帰型または関数の依存関係のコンテキストが複雑すぎます

外積の定義で何が間違っていましたか?

4

1 に答える 1

3

これは私にとってきれいに構築されます:

template<int N>
struct Tensor
{
    Tensor<N - 1> x;
    Tensor<N - 1> y;
    Tensor<N - 1> z;

    Tensor() { }

    Tensor(const Tensor<N-1>& X, const Tensor<N-1>& Y, const Tensor<N-1>& Z)
      : x(X), y(Y), z(Z)
    { }
};

template<>
struct Tensor<1>
{
    double x;
    double y;
    double z;

    Tensor() : x(), y(), z() { }
    Tensor(double x, double y, double z) : x(x), y(y), z(z)
    { }
};

template<int N, int M>
Tensor<N + M> Outer(const Tensor<N>& lhs, const Tensor<M>& rhs)
{
    Tensor<N + M> result;

    result.x = Outer(lhs.x, rhs);
    result.y = Outer(lhs.y, rhs);
    result.z = Outer(lhs.z, rhs);

    return result;
}

template<int N>
Tensor<N + 1> Outer(const Tensor<N>& lhs, const Tensor<1>& rhs)
{
    Tensor<N + 1> result;

    result.x = Outer(lhs.x, rhs);
    result.y = Outer(lhs.y, rhs);
    result.z = Outer(lhs.z, rhs);

    return result;
}

template<int N>
Tensor<N + 1> Outer(const Tensor<1>& lhs, const Tensor<N>& rhs)
{
    return Outer(rhs, lhs);
}

Tensor<2> Outer(const Tensor<1>& lhs, const Tensor<1>& rhs)
{
    Tensor<2> result;

    result.x.x = lhs.x * rhs.x;
    result.x.y = lhs.x * rhs.y;
    result.x.z = lhs.x * rhs.z;
    result.y.x = lhs.y * rhs.x;
    result.y.y = lhs.y * rhs.y;
    result.y.z = lhs.y * rhs.z;
    result.z.x = lhs.z * rhs.x;
    result.z.y = lhs.z * rhs.y;
    result.z.z = lhs.z * rhs.z;

    return result;
}

int main()
{
    Tensor<4> a;
    Tensor<4> b;
    Outer(a, b);
}

注目すべき変更点は次のとおりです。

  1. 特殊化は、オーバーロードのTensor<1>前に定義する必要がありますOuter
  2. Tensor<1>特殊化は、 、、およびデータ メンバーTensor<2>をデフォルトで構築しようとするため、デフォルトで構築可能である必要があります。xyz
  3. とのtemplate<int N> Tensor<N + 1> Outer(const Tensor<1> &lhs, const Tensor<N> &rhs)対称性のためにオーバーロードが必要か、 fortemplate<int N> Tensor<N + 1> Outer(const Tensor<N> &lhs, const Tensor<1> &rhs)を取るオーバーロードを追加する必要があります。doublelhs
  4. template<>オーバーロードから削除しTensor<2> Outer(const Tensor<1> &lhs, const Tensor<1> &rhs)ます –ここでは、特化ではなくオーバーロードしています。
于 2012-05-01T21:43:08.087 に答える