我正在尝试用 C 语言创建一个高斯消除器。为此,我需要不时检查矩阵是否在数字上是单数的:如果某个数字(双精度(非常小。
我的问题是,如果我尝试这样做:
if(0 == matrix->items[from]){
fprintf(stderr,"Matrix is still singular after attempting pivot. Exitig.n");
}
这永远不会产生真实结果。由于双精度的不准确性,它永远不会正好是 0。但是,当尝试运行程序时,像这样的情况会用 inf 或 NaN 填充数字,具体取决于是乘以还是除以它及其组合。
为了过滤这些,我需要这样的东西:
#define EPSILON very_small
// rest of the code
if(matrix->items[from] < EPSILON){
...singular
}
此 EPSILON 的推荐值是多少?是绝对精度的双倍,还是更大的值?
顺便说一下,哪个会更好,将其定义为上面的宏,或者像这样使用它:
const double EPSILON = ...;
对不起,如果我不够清楚,英语不是我的母语。
感谢您的回复。
我需要检查矩阵是否是数字单数
通常,这是通过防止double
溢出来检测的。
// Check if 1.0/determinant will overflow.
if (fabs(determinant) <= 1.0/(0.99*DBL_MAX)) {
Handle_Singular_Case()
} else {
one_over_det = 1.0/determinant;
}
使用DBL_EPSILON
(例如:2e-16(通常是错误的解决方案。 double
数学需要相对比较,以确保远离1.0量级的良好计算。
// Rarely the right thing to do.
#define EPSILON DBL_EPSILON
if(fabs(matrix->items[from]) < EPSILON){
然而,这对 Vane @Weather上下文非常敏感。
然而,OP的真正问题肯定在这里:"当尝试运行程序时,像这样的情况会用inf或NaN填充数字,这取决于是乘以还是除以它及其组合。 可以使用各种技术来避免此问题,例如使用部分枢轴进行消除。
若要解决此问题,最好发布代码和示例数据。