I’m implementing the outer product using a templated representation of a Tensor.
The basic prototype of the tensor looks like:
template <int N>
struct Tensor
{
Tensor<N - 1> x;
Tensor<N - 1> y;
Tensor<N - 1> z;
};
With a specialization for Tensor<1> to degrade to a simple vector. My Outer function is defined as:
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;
}
The outer product of a tensor A of order N and of a tensor B of order M is simply the outer product of each element of A with the B tensor. The outer product of any tensor of order N with a tensor of order 1 is defined similarly.
The base case is simply the outer product of two order 1 tensors (vectors). Except, as defined above I’m getting a C1202 error in MSVC:
error C1202: recursive type or function dependency context too complex
What did I do wrong in my definition of an outer product?
This builds cleanly for me:
The notable changes are:
Tensor<1>specialization needs to be defined before any of theOuteroverloads.Tensor<1>specialization needs to be default-constructible, sinceTensor<2>will attempt to default-construct itsx,y, andzdata members.template<int N> Tensor<N + 1> Outer(const Tensor<1> &lhs, const Tensor<N> &rhs)overload is needed for symmetry withtemplate<int N> Tensor<N + 1> Outer(const Tensor<N> &lhs, const Tensor<1> &rhs), or you need to add an overload that takes adoubleforlhs.template<>from theTensor<2> Outer(const Tensor<1> &lhs, const Tensor<1> &rhs)overload – we’re overloading here, not specializing.