推荐的双倍epsilon是多少?

时间:2017-03-20 21:05:27

标签: c floating-accuracy

我试图在C中创建一个高斯消除器。为此,我需要不时地检查矩阵是否是数字奇异的:如果某个数字(双精度)非常非常小。 / p>

我的问题是,如果我尝试这样做:

if(0 == matrix->items[from]){
        fprintf(stderr,"Matrix is still singular after attempting pivot. Exitig.\n");
}

这永远不会成真。由于double的不准确性,它永远不会精确为0.但是,当尝试运行程序时,这样的情况会用inf或NaN填充数字,具体取决于是否乘以或除以它及其组合。

为了过滤这些,我需要这样的东西:

#define EPSILON very_small
// rest of the code
if(matrix->items[from] < EPSILON){
     ...singular
}

此EPSILON的推荐值是多少?这是绝对准确度的两倍,还是可能有点大一点?

顺便说一句,哪个会更好,将其定义为上面的宏,或者使用它:

const double EPSILON = ...;

对不起,如果我不够清楚,英语不是我的母语。

感谢您的回复。

1 个答案:

答案 0 :(得分:2)

  

我需要检查矩阵是否是数字奇异

通常可以通过阻止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){

然而,这非常依赖于语境@Weather Vane

然而,OP的真正问题当然在这里:&#34;当试图运行该程序时,这样的情况会用inf或NaN填充数字,具体取决于是否乘以或除以它及其组合。 &#34 ;.可以使用各种技术来避免此问题,例如使用partial pivoting进行删除。

要解决 问题,最好发布代码和示例数据。