在Ruby中反转矩阵时出错

时间:2016-02-15 12:09:53

标签: ruby matrix matrix-inverse

我有以下矩阵:

[
  [
    16.0,
    23251143833701.0,
    3.3788480598465756e+25,
    4.9101301394821435e+37
  ], 
  [
    23251143833701.0,
    3.3788480598465756e+25,
    4.9101301394821435e+37,
    7.135383882205603e+49
  ],
  [
    3.3788480598465756e+25,
    4.9101301394821435e+37,
    7.135383882205603e+ 49,
    1.0369114809614645e+62
  ], 
  [
    4.9101301394821435e+37,
    7.135383882205603e+49,
    1.0369114809614645e+62,
    1.5068361241656833e+74
  ]
]

此矩阵的行列式为-1.4536774485912138e+135,如果我调用regular?,则返回true。但是,当我调用方法inverse时,Ruby会引发以下异常:

matrix.rb:1079:in `block in inverse_from': Not Regular Matrix (ExceptionForMatrix::ErrNotRegular)
  from matrix.rb:1069:in `upto'
  from matrix.rb:1069:in `inverse_from'
  from matrix.rb:1061:in `inverse'

这是什么问题?

1 个答案:

答案 0 :(得分:6)

此矩阵在数值上是不合适的,并且不能使用浮点数通过通用算法反转。它对于给定的机器精度是唯一的:

A =  1e74 * [ 0, 0, 0, 0;
              0, 0, 0, 0;
              0, 0, 0, 0;
              0, 0, 0, 1.5068 ]

Ruby在计算行列式时非常乐观。如果-1.45e + 135是有效结果或数字人工制品,则无法确定。我倾向于相信Matlab和Octave的数值计算。他们都返回det(A) = 0

4x4矩阵的行列式是元素排列的乘积之和,每个乘积有4个元素(因子)。在这个矩阵的情况下,较小的产品将具有大约4 * 20 = 80的指数,较大的产品大约4 * 60 = 240.要计算更大和更小数字的总和而不会失去太多精度,您将需要浮动尾数长度至少为240-80 = 160位的点号。单精度浮点数有24位 - 大约9或10位,双精度有53位 - 大约16位。可能有更聪明的方法来计算,但是需要大约160个数字来用直接算法计算,例如,实施莱布尼茨公式。

即使逆矩阵可用且精确,如果它在实际应用中有用也是非常值得怀疑的。