将特征矩阵的下 Cholesky 因子作为函数参数传递
Passing the Lower Cholesky Factor of an Eigen matrix as a function parameter
首先我想说我是 C++ 新手,所以请在您的评论中详细说明 and/or 建议。
我正在尝试重构一些代码。我执行的操作之一涉及从列表中获取(记忆化的)Eigen::LLT<Eigen::MatrixXd>
类型对象并使用它执行一些计算。
我想将这个计算重构为一个更小的函数,但是我在将 Eigen::LLT<Eigen::MatrixXd>
类型作为参数传递时遇到了问题(我承认我对 ) Eigen documentation here.
中的建议
我尝试了以下方法:
#define _USE_MATH_DEFINES
#include <Eigen/LU>
#include <Eigen/Dense>
#include <math.h>
#include <unsupported/Eigen/SpecialFunctions>
Eigen::MatrixXd conditionalCov(
Eigen::Ref<const Eigen::MatrixXd> kxstarxstar,
Eigen::Ref<const Eigen::LLT<Eigen::MatrixXd>> lxx,
Eigen::Ref<const Eigen::MatrixXd> kxxstar
)
{
return (
kxstarxstar.array() - (kxxstar.transpose() * lxx.solve(kxxstar)).array()
).matrix().selfadjointView<Eigen::Lower>();
}
但这不会编译,因为 lxx
,即 Eigen::Ref<const Eigen::LLT<Eigen::MatrixXd>>
的类型定义是错误的。海湾合作委员会说:
[<path_to_file>] error: ‘IsVectorAtCompileTime’ is not a member of ‘const Eigen::LLT<Eigen::Matrix<double, -1, -1>, 1>’
5 | Eigen::Ref<const Eigen::LLT<Eigen::MatrixXd>> lxx,
此处 lxx
(较低的 Cholesky 因子)的类型应该是什么以避免在调用函数时创建临时矩阵?
只需将 LLT
对象作为标准 C++ 常量引用传递。
通过 Eigen::Ref
传递 kxstarxstar
和 kxxstar
也只有在您打算传递其他矩阵的子块时才有意义。如果不是,只需将它们作为 const Eigen::MatrixXd &
传递。如果您想将它们作为 Eigen::Ref
传递,建议将其本身作为 const &
:
传递
Eigen::MatrixXd conditionalCov(
const Eigen::Ref<const Eigen::MatrixXd>& kxstarxstar,
const Eigen::LLT<Eigen::MatrixXd> &lxx,
const Eigen::Ref<const Eigen::MatrixXd>& kxxstar
)
N.B.: 在你的函数中不需要在 Matrix 和 Array 类型之间进行转换,下面的代码应该给出相同的结果:
return (
kxstarxstar - kxxstar.transpose() * lxx.solve(kxxstar)
).selfadjointView<Eigen::Lower>();
首先我想说我是 C++ 新手,所以请在您的评论中详细说明 and/or 建议。
我正在尝试重构一些代码。我执行的操作之一涉及从列表中获取(记忆化的)Eigen::LLT<Eigen::MatrixXd>
类型对象并使用它执行一些计算。
我想将这个计算重构为一个更小的函数,但是我在将 Eigen::LLT<Eigen::MatrixXd>
类型作为参数传递时遇到了问题(我承认我对 ) Eigen documentation here.
我尝试了以下方法:
#define _USE_MATH_DEFINES
#include <Eigen/LU>
#include <Eigen/Dense>
#include <math.h>
#include <unsupported/Eigen/SpecialFunctions>
Eigen::MatrixXd conditionalCov(
Eigen::Ref<const Eigen::MatrixXd> kxstarxstar,
Eigen::Ref<const Eigen::LLT<Eigen::MatrixXd>> lxx,
Eigen::Ref<const Eigen::MatrixXd> kxxstar
)
{
return (
kxstarxstar.array() - (kxxstar.transpose() * lxx.solve(kxxstar)).array()
).matrix().selfadjointView<Eigen::Lower>();
}
但这不会编译,因为 lxx
,即 Eigen::Ref<const Eigen::LLT<Eigen::MatrixXd>>
的类型定义是错误的。海湾合作委员会说:
[<path_to_file>] error: ‘IsVectorAtCompileTime’ is not a member of ‘const Eigen::LLT<Eigen::Matrix<double, -1, -1>, 1>’
5 | Eigen::Ref<const Eigen::LLT<Eigen::MatrixXd>> lxx,
此处 lxx
(较低的 Cholesky 因子)的类型应该是什么以避免在调用函数时创建临时矩阵?
只需将 LLT
对象作为标准 C++ 常量引用传递。
通过 Eigen::Ref
传递 kxstarxstar
和 kxxstar
也只有在您打算传递其他矩阵的子块时才有意义。如果不是,只需将它们作为 const Eigen::MatrixXd &
传递。如果您想将它们作为 Eigen::Ref
传递,建议将其本身作为 const &
:
Eigen::MatrixXd conditionalCov(
const Eigen::Ref<const Eigen::MatrixXd>& kxstarxstar,
const Eigen::LLT<Eigen::MatrixXd> &lxx,
const Eigen::Ref<const Eigen::MatrixXd>& kxxstar
)
N.B.: 在你的函数中不需要在 Matrix 和 Array 类型之间进行转换,下面的代码应该给出相同的结果:
return (
kxstarxstar - kxxstar.transpose() * lxx.solve(kxxstar)
).selfadjointView<Eigen::Lower>();