避免在特征中用对角线矩阵分配

发布于 2025-01-20 17:58:23 字数 2545 浏览 4 评论 0 原文

问题

如何避免特征中小对角矩阵的动态分配?

上下文

我正在使用 Eigen 3.4。我有一个 N × N 对角矩阵 W:

auto W = Eigen::DiagonalMatrix<double, Dynamic>(N);

如果 N <= 512,我想通过使用堆栈上的缓冲区来避免分配:

double W_buffer[512];

对于法线向量和矩阵,我知道我可以使用 Map

double y_buff[512];
auto y = Eigen::Map<VectorXd>( y_buff, N );

但是,当我对对角矩阵尝试相同的操作时,它会给我一个错误,因为 InnerStrideAtCompileTime 不是特征::对角矩阵

将 Map 与 DiagonalMatrix 结合使用时出现错误消息

In file included from eigen/Eigen/Core:311,
                 from eigen/Eigen/Dense:1,
                 from build/release/CMakeFiles/bench.dir/cmake_pch.hxx:5,
                 from <command-line>:
eigen/Eigen/src/Core/Map.h: In instantiation of ‘struct Eigen::internal::traits<Eigen::Map<Eigen::DiagonalMatrix<double, -1> > >’:
eigen/Eigen/src/Core/util/ForwardDeclarations.h:34:48:   required from ‘struct Eigen::internal::accessors_level<Eigen::Map<Eigen::DiagonalMatrix<double, -1> > >’
eigen/Eigen/src/Core/util/ForwardDeclarations.h:101:75:   required from ‘class Eigen::Map<Eigen::DiagonalMatrix<double, -1> >’
include/volar/estimators.hpp:203:18:   required from ‘static volar::R volar::PolyLE<Degree>::estimate(volar::R, volar::ViewR, volar::ViewR, const Kernel&) [with Kernel = volar::UniformK; int Degree = 1; volar::R = double; volar::ViewR = volar::View<double>]’
include/volar/kernel_smoothing.hpp:81:64:   required from ‘volar::R volar::LocalRFT<Estimator, Kernel>::operator()(volar::R) const [with Estimator = volar::EigenLinearLE; Kernel = volar::UniformK; volar::R = double]’
bench/core.cpp:43:23:   required from ‘void localRF(benchmark::State&) [with Method = volar::EigenLinearLE; Kernel = volar::UniformK]’
bench/core.cpp:96:1:   required from here
eigen/Eigen/src/Core/Map.h:30:53: error: ‘InnerStrideAtCompileTime’ is not a member of ‘Eigen::DiagonalMatrix<double, -1>’
   30 |                              ? int(PlainObjectType::InnerStrideAtCompileTime)
      |                                                     ^~~~~~~~~~~~~~~~~~~~~~~~
In file included from eigen/Eigen/Core:163,
                 from eigen/Eigen/Dense:1,
                 from build/release/CMakeFiles/bench.dir/cmake_pch.hxx:5,
                 from <command-line>:

Question

How can I avoid dynamic allocation for small Diagonal Matrices in Eigen?

Context

I'm using Eigen 3.4. I have a N by N Diagonal Matrix W:

auto W = Eigen::DiagonalMatrix<double, Dynamic>(N);

I'd like to avoid allocation if N <= 512 by using a buffer on the stack:

double W_buffer[512];

With normal vectors and matricies, I know I can use Map:

double y_buff[512];
auto y = Eigen::Map<VectorXd>( y_buff, N );

However, when I try the same thing with a Diagonal Matrix, it gives me an error because InnerStrideAtCompileTime isn't a member of Eigen::DiagonalMatrix.

Error message when using Map with DiagonalMatrix

In file included from eigen/Eigen/Core:311,
                 from eigen/Eigen/Dense:1,
                 from build/release/CMakeFiles/bench.dir/cmake_pch.hxx:5,
                 from <command-line>:
eigen/Eigen/src/Core/Map.h: In instantiation of ‘struct Eigen::internal::traits<Eigen::Map<Eigen::DiagonalMatrix<double, -1> > >’:
eigen/Eigen/src/Core/util/ForwardDeclarations.h:34:48:   required from ‘struct Eigen::internal::accessors_level<Eigen::Map<Eigen::DiagonalMatrix<double, -1> > >’
eigen/Eigen/src/Core/util/ForwardDeclarations.h:101:75:   required from ‘class Eigen::Map<Eigen::DiagonalMatrix<double, -1> >’
include/volar/estimators.hpp:203:18:   required from ‘static volar::R volar::PolyLE<Degree>::estimate(volar::R, volar::ViewR, volar::ViewR, const Kernel&) [with Kernel = volar::UniformK; int Degree = 1; volar::R = double; volar::ViewR = volar::View<double>]’
include/volar/kernel_smoothing.hpp:81:64:   required from ‘volar::R volar::LocalRFT<Estimator, Kernel>::operator()(volar::R) const [with Estimator = volar::EigenLinearLE; Kernel = volar::UniformK; volar::R = double]’
bench/core.cpp:43:23:   required from ‘void localRF(benchmark::State&) [with Method = volar::EigenLinearLE; Kernel = volar::UniformK]’
bench/core.cpp:96:1:   required from here
eigen/Eigen/src/Core/Map.h:30:53: error: ‘InnerStrideAtCompileTime’ is not a member of ‘Eigen::DiagonalMatrix<double, -1>’
   30 |                              ? int(PlainObjectType::InnerStrideAtCompileTime)
      |                                                     ^~~~~~~~~~~~~~~~~~~~~~~~
In file included from eigen/Eigen/Core:163,
                 from eigen/Eigen/Dense:1,
                 from build/release/CMakeFiles/bench.dir/cmake_pch.hxx:5,
                 from <command-line>:

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧城空念 2025-01-27 17:58:23

Eigen::DiagonalMatrix 的第三个模板参数 MaxSizeAtCompileTime 可以让您做到这一点。

Eigen::Dynamic结合使用时,DiagonalMatrix将具有足够大的内部缓冲区以容纳MaxSizeAtCompileTime,但其大小仍会动态调整。

例如,以下内容与您尝试对外部缓冲区执行的操作等效:

auto W = Eigen::DiagonalMatrix<double, Eigen::Dynamic, 512>(N)

显然,尝试使用大于 MaxSizeAtCompileTime 的大小对其进行初始化将在运行时失败(使用断言),但是这并不比您使用 Map 时必须处理的情况更糟糕。

The third template parameter of Eigen::DiagonalMatrix, MaxSizeAtCompileTime lets you do just that.

When combined with Eigen::Dynamic, the DiagonalMatrix will have an internal buffer large enough for MaxSizeAtCompileTime, but it will still be dynamically sized.

For example, the following is the equivalent of what you were trying to do with an external buffer:

auto W = Eigen::DiagonalMatrix<double, Eigen::Dynamic, 512>(N)

Obviously, attempting to initialize it with a size greater than MaxSizeAtCompileTime will fail at runtime (with an assert), but that's not any worse than what you have to deal with when using Map.

伏妖词 2025-01-27 17:58:23

而不是尝试 MAP a DiagonalMatrix 您可以以“正常”方式来描述和使用 asdiagonal()方法。

也许必须少一些干净才能键入 y.asdiagonal()而不是 y ...也许您可以使用 eigen :: ref 请参考来自您的向量的对角线矩阵,但我不确定是否可以使用。

asdiagonal()

Instead of trying to Map a DiagonalMatrix you can do it the "normal" way that you describe and use the asDiagonal() method.

Maybe slightly less clean to have to type y.asDiagonal() instead of just y...Maybe you could do something with Eigen::Ref to keep a reference to the diagonal matrix that came from your vector but I'm not sure if that would work.

asDiagonal():
https://eigen.tuxfamily.org/dox/classEigen_1_1MatrixBase.html#a14235b62c90f93fe910070b4743782d0

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文