我正在尝试编写一个模板化方法,用于计算多元正态分布的给定输入的概率密度。它将输入、均值向量和协方差矩阵作为输入。
我想在 Ceres 成本函子中使用此方法,其中输入变量和均值/协方差是固定的。目前,该方法如下所示:
template <int Dim, class Scalar>
Scalar mvn_norm_pdf(const Eigen::Matrix<Scalar, Dim, 1> & input,
const Eigen::Matrix<float, Dim, 1> & mean,
const Eigen::Matrix<float, Dim, Dim> & covariance)
{
static const Scalar log_sqrt_2_pi = Scalar(0.5 * std::log(2 * M_PI));
typedef Eigen::LLT<Eigen::Matrix<Scalar, Dim, Dim>> Cholesky;
Cholesky chol(covariance.template cast<Scalar>());
if (chol.info() != Eigen::Success) throw "Decomposition failed!";
const typename Cholesky::Traits::MatrixL & L = chol.matrixL();
Scalar quad_form = (L.solve(input - mean.template cast<Scalar>())).squaredNorm();
Scalar det = L.determinant();
return ceres::exp(Scalar(-input.rows()) * log_sqrt_2_pi - 0.5 * quad_form) / det;
}
但是,这会在 Eigen 中引发编译错误,特别det
是在设置为L.determinant()
. 消息:
Eigen/src/Core/TriangularMatrix.h:371:16: error: could not convert ‘1’ from ‘int’ to ‘Eigen::TriangularView<const Eigen::Matrix<ceres::Jet<double, 7>, 3, 3, 0, 3, 3>, 1u>::Scalar {aka ceres::Jet<double, 7>}’
return 1;
^
Eigen/src/Core/TriangularMatrix.h:373:16: error: could not convert ‘0’ from ‘int’ to ‘Eigen::TriangularView<const Eigen::Matrix<ceres::Jet<double, 7>, 3, 3, 0, 3, 3>, 1u>::Scalar {aka ceres::Jet<double, 7>}’
return 0;
查看提到的 Eigen 源文件,我发现:
Scalar determinant() const
{
if (Mode & UnitDiag)
return 1;
else if (Mode & ZeroDiag)
return 0;
else
return m_matrix.diagonal().prod();
}
因此,据我了解,问题出在 Eigen 可以返回 1 或 0(它们是int
s),并且 int 不能转换为 a的事实ceres::Jet
。我在这里吗,如果是的话,处理这个问题的正确方法是什么?