在线性方程组(Ax = b)的解中检测零点

时间:2017-01-20 09:56:51

标签: r floating-point equation-solving rounding-error

假设以下方程组Ax = b包含:

> A <- matrix(c(2,0,-1,0,0,2,2,1,-1,2,0,0,0,1,0,0), ncol = 4)
> A
     [,1] [,2] [,3] [,4]
[1,]    2    0   -1    0
[2,]    0    2    2    1
[3,]   -1    2    0    0
[4,]    0    1    0    0

> b <- c(-2,5,0,0)

solve()求解这些方程得到:

> x <- solve(A,b)
> x
[1] 6.66e-16 4.44e-16 2.00e+00 1.00e+00

这只是一个示例,但Ab可以是任何形式。

我需要检测x的任何组件是否为0.现在,前两个组件实际应该为0,但它们都高于机器epsilon .Machine$double.eps = 2.22e-16,这使它们非常小,但不等于零。

我想我明白这是由solve()内的浮点运算中的舍入错误引起的。我需要知道的是(从实际的角度来看)是否有可能确定这些错误的上限,因此可以检测到0。例如,而不是

> x == 0
[1] FALSE FALSE FALSE FALSE

可以使用这样的东西:

> x > -1e-15 & x < 1e-15
[1]  TRUE  TRUE FALSE FALSE

将更加深入地了解这个问题。

1 个答案:

答案 0 :(得分:1)

如果我们假设组件为零,检查我们是否可以找到更好的线性系统解决方案。为此,我们希望从A[3:4]%*%y=b开始解决A%*%c(0,0,x[3],x[4])=A[3:4]%*%c(x[3],x[4])。这是一个超定系统,因此我们无法使用solve来找到解决方案。但是,我们可以使用qr.solve

> x.new = c(0,0,qr.solve(A[,3:4],b))

仍需检查此解决方案是否真的更好:

> norm(A%*%x.new - b) < norm(A%*%x - b)
[1] TRUE

因此,我们有充分的理由怀疑x[1]==x[2]==0

在这个简单的例子中,通过查看近似解决方案显然可以猜出真正的解决方案:

> x.true = c(0,0,2,1)
> norm(A%*%x.true - b)
[1] 0

然而,这在一般情况下并不是很有用。