在Ruby中反转矩阵时出错

Tru*_*los 2 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
  ]
]
Run Code Online (Sandbox Code Playgroud)

这个矩阵的决定因素是-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'
Run Code Online (Sandbox Code Playgroud)

这里有什么问题?

bog*_*ogl 6

该矩阵在数值上是不合适的,并且不能使用浮点数通过通用算法来反转.给定的机器精度是奇异的:

A =  1e74 * [ 0, 0, 0, 0;
              0, 0, 0, 0;
              0, 0, 0, 0;
              0, 0, 0, 1.5068 ]
Run Code Online (Sandbox Code Playgroud)

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个数字,例如实施Leibniz公式.

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