避免在特征值中使用对角矩阵进行分配

问题描述 投票:0回答:2

问题

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

背景

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

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

如果 N <= 512 by using a buffer on the stack:

我想避免分配
double W_buffer[512];

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

Map

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

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

InnerStrideAtCompileTime
不是
Eigen::DiagonalMatrix
的成员。

将 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>:
c++ optimization eigen eigen3
2个回答
0
投票

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

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

例如,以下内容相当于您尝试使用外部缓冲区执行的操作:

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

显然,尝试使用大于

MaxSizeAtCompileTime
的大小来初始化它会在运行时失败(使用断言),但这并不比使用
Map
时必须处理的情况更糟糕。


0
投票

您可以按照您描述和使用

Map
方法的“正常”方式进行操作,而不是尝试
DiagonalMatrix
asDiagonal()

可能稍微不太干净,必须输入

y.asDiagonal()
而不是仅仅
y
...也许你可以用
Eigen::Ref
做一些事情来保留对来自向量的对角矩阵的引用,但我不确定是否那会起作用的。

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

© www.soinside.com 2019 - 2024. All rights reserved.