Deterministic python script behaves in non-deterministic way

♀尐吖头ヾ 提交于 2019-12-04 00:48:29

In general, linalg libraries on Windows give different answers on different runs at machine precision level. I never heard of an explanation why this happens only or mainly on Windows.

If your matrix is ill conditioned, then the inv will be largely numerical noise. On Windows the noise is not always the same in consecutive runs, on other operating systems the noise might be always the same but can differ depending on the details of the linear algebra library, on threading options, cache usage and so on.

I've seen on and posted to the scipy mailing list several examples for this on Windows, I was using mostly the official 32 bit binaries with ATLAS BLAS/LAPACK.

The only solution is to make the outcome of your calculation not depend so much on floating point precision issues and numerical noise, for example regularize the matrix inverse, use generalized inverse, pinv, reparameterize or similar.

percusse

As pv noted in the comments to user333700's answer, the previous formulation of the Riccati solvers were, though being theoretically correct, not numerically stable. This issue is fixed on the development version of SciPy and the solvers support generalized Riccati equations too.

The Riccati solvers are updated and resulting solvers will be available from version 0.19 and onwards. You can check the development branch docs here.

If, using the given example in the question I replace the last loop with

for _ in range(5):
    x = scipy.linalg.solve_continuous_are(A, B, Q, R)
    Res = x@a + a.T@x + q - x@b@ np.linalg.solve(r,b.T)@ x
    print(Res)

I get (windows 10, py3.5.2)

[[  2.32314924e-05  -2.55086270e-05  -7.66709854e-06  -9.01878229e-06]
 [ -2.62447211e-05   2.61182140e-05   8.27328768e-06   1.00345896e-05]
 [ -7.92257197e-06   8.57094892e-06   2.50908488e-06   3.05714639e-06]
 [ -9.51046241e-06   9.80847472e-06   3.13103374e-06   3.60747799e-06]]
[[  2.32314924e-05  -2.55086270e-05  -7.66709854e-06  -9.01878229e-06]
 [ -2.62447211e-05   2.61182140e-05   8.27328768e-06   1.00345896e-05]
 [ -7.92257197e-06   8.57094892e-06   2.50908488e-06   3.05714639e-06]
 [ -9.51046241e-06   9.80847472e-06   3.13103374e-06   3.60747799e-06]]
[[  2.32314924e-05  -2.55086270e-05  -7.66709854e-06  -9.01878229e-06]
 [ -2.62447211e-05   2.61182140e-05   8.27328768e-06   1.00345896e-05]
 [ -7.92257197e-06   8.57094892e-06   2.50908488e-06   3.05714639e-06]
 [ -9.51046241e-06   9.80847472e-06   3.13103374e-06   3.60747799e-06]]
[[  2.32314924e-05  -2.55086270e-05  -7.66709854e-06  -9.01878229e-06]
 [ -2.62447211e-05   2.61182140e-05   8.27328768e-06   1.00345896e-05]
 [ -7.92257197e-06   8.57094892e-06   2.50908488e-06   3.05714639e-06]
 [ -9.51046241e-06   9.80847472e-06   3.13103374e-06   3.60747799e-06]]
[[  2.32314924e-05  -2.55086270e-05  -7.66709854e-06  -9.01878229e-06]
 [ -2.62447211e-05   2.61182140e-05   8.27328768e-06   1.00345896e-05]
 [ -7.92257197e-06   8.57094892e-06   2.50908488e-06   3.05714639e-06]
 [ -9.51046241e-06   9.80847472e-06   3.13103374e-06   3.60747799e-06]]

For reference, the solution returned is

array([[-3449.15531305,  4097.1707738 ,  1142.52971904,  1566.51333847],
       [ 4097.1707738 , -4863.70533241, -1356.66524959, -1860.15980716],
       [ 1142.52971904, -1356.66524959,  -378.32586814,  -518.71965102],
       [ 1566.51333847, -1860.15980716,  -518.71965102,  -711.21062988]])
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!