我有一个不使用随机化的脚本,运行时会给我不同的答案。我希望每次运行脚本时答案都是一样的。该问题似乎仅针对某些(病态)输入数据发生。
该代码段来自一种算法,用于为线性系统计算特定类型的控制器,并且主要由线性代数(矩阵求逆,Riccati方程,特征值)组成。
显然,这对我来说是一个大问题,因为我现在不相信自己的代码可以给我正确的结果。我知道条件不佳的数据的结果可能是错误的,但我希望始终是错误的。为什么答案在我的Windows计算机上并不总是相同?为什么Linux和Windows计算机没有给出相同的结果?
我正在使用Python 2.7.9 (default, Dec 10 2014, 12:24:55) [MSC v.1500 32 bit (Intel)] on win 32
Numpy版本1.8.2和Scipy 0.14.0。(Windows 8、64位)。
代码如下。我也尝试过在两台Linux机器上运行代码,并且脚本始终给出相同的答案(但是机器给出的答案不同)。其中一个运行的是Python 2.7.8,Numpy 1.8.2和Scipy 0.14.0。第二个是运行带有Numpy 1.6.1和Scipy 0.12.0的Python 2.7.3。
我对Riccati方程求解了三次,然后打印答案。我每次都希望得到相同的答案,而是得到序列'1.75305103767e-09; 3.25501787302e-07; 3.25501787302e-07'。
import numpy as np
import scipy.linalg
matrix = np.matrix
A = matrix([[ 0.00000000e+00, 2.96156260e+01, 0.00000000e+00,
-1.00000000e+00],
[ -2.96156260e+01, -6.77626358e-21, 1.00000000e+00,
-2.11758237e-22],
[ 0.00000000e+00, 0.00000000e+00, 2.06196064e+00,
5.59422224e+01],
[ 0.00000000e+00, 0.00000000e+00, 2.12407340e+01,
-2.06195974e+00]])
B = matrix([[ 0. , 0. , 0. ],
[ 0. , 0. , 0. ],
[ -342.35401351, -14204.86532216, 31.22469724],
[ 1390.44997337, 342.33745324, -126.81720597]])
Q = matrix([[ 5.00000001, 0. , 0. , 0. ],
[ 0. , 5.00000001, 0. , 0. ],
[ 0. , 0. , 0. , 0. ],
[ 0. , 0. , 0. , 0. ]])
R = matrix([[ -3.75632852e+04, -0.00000000e+00, 0.00000000e+00],
[ -0.00000000e+00, -3.75632852e+04, 0.00000000e+00],
[ 0.00000000e+00, 0.00000000e+00, 4.00000000e+00]])
counter = 0
while counter < 3:
counter +=1
X = scipy.linalg.solve_continuous_are(A, B, Q, R)
print(-3449.15531628 - X[0,0])
我的numpy配置如下 print np.show_config()
lapack_opt_info: 库= ['mkl_blas95','mkl_lapack95','mkl_intel_c','mkl_intel_thread','mkl_core','libiomp5md','mkl_blas95','mkl_lapack95','mkl_intel_c','mkl_core' ] library_dirs = ['c:/程序文件(x86)/ Intel / Composer XE 2013 SP1 / mkl / lib / ia32','C:/程序文件(x86)/ Intel / Composer XE 2013 SP1 / compiler / lib / ia32' ] define_macros = [('SCIPY_MKL_H',None)] include_dirs = ['c:/ Program Files(x86)/ Intel / Composer XE 2013 SP1 / mkl / include'] blas_opt_info: 库= ['mkl_blas95','mkl_lapack95','mkl_intel_c','mkl_intel_thread','mkl_core','libiomp5md'] library_dirs = ['c:/程序文件(x86)/ Intel / Composer XE 2013 SP1 / mkl / lib / ia32','C:/程序文件(x86)/ Intel / Composer XE 2013 SP1 / compiler / lib / ia32' ] define_macros = [('SCIPY_MKL_H',None)] include_dirs = ['c:/ Program Files(x86)/ Intel / Composer XE 2013 SP1 / mkl / include'] openblas_info: 无法使用 lapack_mkl_info: 库= ['mkl_blas95','mkl_lapack95','mkl_intel_c','mkl_intel_thread','mkl_core','libiomp5md','mkl_blas95','mkl_lapack95','mkl_intel_c','mkl_core' ] library_dirs = ['c:/程序文件(x86)/ Intel / Composer XE 2013 SP1 / mkl / lib / ia32','C:/程序文件(x86)/ Intel / Composer XE 2013 SP1 / compiler / lib / ia32' ] define_macros = [('SCIPY_MKL_H',None)] include_dirs = ['c:/ Program Files(x86)/ Intel / Composer XE 2013 SP1 / mkl / include'] blas_mkl_info: 库= ['mkl_blas95','mkl_lapack95','mkl_intel_c','mkl_intel_thread','mkl_core','libiomp5md'] library_dirs = ['c:/程序文件(x86)/ Intel / Composer XE 2013 SP1 / mkl / lib / ia32','C:/程序文件(x86)/ Intel / Composer XE 2013 SP1 / compiler / lib / ia32' ] define_macros = [('SCIPY_MKL_H',None)] include_dirs = ['c:/ Program Files(x86)/ Intel / Composer XE 2013 SP1 / mkl / include'] mkl_info: 库= ['mkl_blas95','mkl_lapack95','mkl_intel_c','mkl_intel_thread','mkl_core','libiomp5md'] library_dirs = ['c:/程序文件(x86)/ Intel / Composer XE 2013 SP1 / mkl / lib / ia32','C:/程序文件(x86)/ Intel / Composer XE 2013 SP1 / compiler / lib / ia32' ] define_macros = [('SCIPY_MKL_H',None)] include_dirs = ['c:/ Program Files(x86)/ Intel / Composer XE 2013 SP1 / mkl / include'] 没有
(编辑以减少问题)
通常,Windows上的linalg库在机器精度级别的不同运行上给出不同的答案。我从未听说过为什么仅在Windows上或主要在Windows上发生这种情况的解释。
如果矩阵条件不好,则inv很大程度上将是数值噪声。在Windows上,连续运行时的噪声并不总是相同的,在其他操作系统上,噪声可能总是相同的,但可能会有所不同,具体取决于线性代数库的详细信息,线程选项,缓存使用情况等。
我已经在Windows上看到了几个示例并将其张贴到scipy邮件列表上,我主要在ATLAS BLAS / LAPACK中使用官方的32位二进制文件。
唯一的解决方案是使计算结果在很大程度上不取决于浮点精度问题和数值噪声,例如,正则化矩阵逆,使用广义逆,pinv,重新参数化或类似方法。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句