如何在不指定维度的情况下用Eigen声明张量



我有一个函数,它接受一个维度为n的张量作为输入,我必须存储这个张量以便以后重用。然而,我事先不知道张量的维数。我想这样做:

//in class.h
Eigen::Tensor<double, N> mytensor;
//in class.cpp 
mytensor = input; 

有办法做到这一点吗?

由于参数N是非类型模板参数,因此它必须是编译时已知的值。这意味着您不能真正将具有未指定NEigen::Tensor存储在变量中,因为具有不同大小的每个实例化都是不同的类型。

您可以使用std::variantstd::any等容器来解决此问题。它们可以分别存储来自封闭类型集或任何类型的某个类型的对象。例如,您可以使用std::any创建一个助手tensor_holder类,如下所示:

template <typename T>
class tensor_holder
{
private:
std::any _held;
size_t _size;
public:
template <int N>
constexpr tensor_holder(Eigen::Tensor<T, N> tensor) :
_held{std::move(tensor)},
_size{N}
{
}
constexpr tensor_holder(const tensor_holder&) = default;
constexpr tensor_holder(tensor_holder&&) = default;
template <size_t N>
Eigen::Tensor<T, N>& get()
{
return std::any_cast<Eigen::Tensor<T, N>&>(_held);
}
template <size_t N>
const Eigen::Tensor<T, N>& get() const
{
return std::any_cast<Eigen::Tensor<T, N>&>(_held);
}
constexpr int size() const noexcept
{
return _size;
}
};

它在std::any中存储任意大小的Eigen::Tensor。如果提供的大小不匹配,则成员函数get抛出std::bad_any_cast实际张量大小(请注意,大小作为编译时值的限制并没有消失(。

假设你有一小组可能的张量大小,你可以在函数中运行不同的分支,如下所示:

void use_tensor(const tensor_holder<double>& in)
{
static tensor_holder held = in; // it can be stored for later    
if (held.size() == 4)
{
auto& tensor = held.get<4>();
tensor(0, 1, 2, 3) = 115.5;
}
else if (held.size() == 3)
{
// some other logic
}
}

在这种情况下,您也可以使用switch而不是if。只有当你必须支持的不同张量大小的数量很小时,这个解决方案才是实用的。我不知道你打算如何使用张量,所以我很难说这个解决方案是否足够。

由于类tensor_holder的转换构造函数,您可以通过简单地为其提供任何大小的Eigen::Tensor来调用该函数:

use_tensor(Eigen::Tensor<double, 3>{});

(螺栓(

相关内容

最新更新