- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我已经使用 Eigen 库在 C++ 中实现了 MCMC 算法。该算法的主要部分是一个循环,其中首先执行一些矩阵计算,然后获得结果矩阵的行列式并将其添加到输出中。例如:
MatrixXd delta0;
NumericVector out(3);
out[0] = 0;
out[1] = 0;
for (int i = 0; i < s; i++) {
...
delta0 = V*(A.cast<double>()-(A+B).cast<double>()*theta.asDiagonal());
...
I = delta0.determinant()
out[1] += I;
out[2] += std::sqrt(I);
}
return out;
不幸的是,现在在某些矩阵上我观察到数值下溢,因此行列式输出为零(实际上不是)。
如何避免这种下溢?
一种解决方案是获取行列式的对数,而不是行列式。然而,
非常感谢任何帮助。
最佳答案
我想到了两个主要选项:
方阵的特征值的乘积是这个矩阵的行列式,因此每个特征值的对数之和就是这个矩阵的行列式的对数。假设 det(A) = a
和 det(B) = b
用于紧凑符号。在应用上述 2 个矩阵 A
和 B
之后,我们最终得到 log(a)
和 log(b)
,那么实际上以下内容为真:
log(a + b) = log(a) + log(1 + e ^ (log(b) - log(a)))
是的,我们得到总和的对数。接下来你会用它做什么?我不知道,取决于你必须做什么。如果你必须通过 e ^ log(a + b) = a + b
去除对数,那么你可能很幸运 a + b
的值现在没有下溢,但在某些情况下它仍然会下溢。
执行巧妙的预处理;这里可能有很多选择,你最好从一些可信的来源阅读它们,因为这是一个严肃的话题。这个特定问题的最简单(并且可能是最便宜的)预处理示例可能是记忆一下 det(c * A) = (c ^ n) * det(A)
,其中 A
是 n
乘以 n
矩阵,用一些 c
预乘你的矩阵,计算行列式,然后除以它通过 c ^ n
得到实际的。
我想到了另一种选择。如果在#1 或#2 的最后阶段您仍然经常遇到下溢,那么专门为这些最后的操作提高精度可能是个好主意,例如,通过利用 GNU MPFR .
关于c++ - 在 Eigen 中获取大矩阵的行列式时避免数值下溢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20529407/
我试图找到这 3 个函数的 Wronskian 行列式,但代码有“TypeError: No loop matching the specified signature and casting was
我需要编写一个在编译时计算行列式的 constexpr 函数。最明显的解决方案是使用拉普拉斯展开。支持 C++14。 #include #include constexpr int get_cof
是否有任何类似 A * A-1 = I 的数学性质可用于测试类似格式的单元测试中行列式的计算? 最佳答案 手动计算一个(或多个)已知数组的行列式,并将您的结果与该数字进行比较。 尝试不同大小、排列方式
我有一个大的 numpy 数组 arr,形状为 (N, D, M, D) 其中 D 是两个或三。该数组可以被认为是 (D,D) 矩阵 block ,这些矩阵在 N 和 M 维度中被阻塞在一起。我想取这
我是一名优秀的程序员,十分优秀!