簡體   English   中英

Python 與 Julia 自相關

[英]Python vs Julia autocorrelation

我正在嘗試使用 Julia 進行自相關並將其與 Python 的結果進行比較。 他們怎么會給出不同的結果?

朱莉婭代碼

using StatsBase

t = range(0, stop=10, length=10)
test_data = sin.(exp.(t.^2))

acf = StatsBase.autocor(test_data)

10-element Array{Float64,1}:
  1.0                   
  0.13254954979179642   
 -0.2030283419321465    
  0.00029587850872956104
 -0.06629381497277881   
  0.031309038331589614  
 -0.16633393452504994   
 -0.08482388975165675   
  0.0006905628640697538 
 -0.1443650483145533

Python代碼

from statsmodels.tsa.stattools import acf
import numpy as np

t = np.linspace(0,10,10)
test_data = np.sin(np.exp(t**2))

acf_result = acf(test_data)

array([ 1.        ,  0.14589844, -0.10412699,  0.07817509, -0.12916543,
       -0.03469143, -0.129255  , -0.15982435, -0.02067688, -0.14633346])

這是因為您的test_data不同:

Python:

array([ 0.84147098, -0.29102733,  0.96323736,  0.75441021, -0.37291918,
        0.85600145,  0.89676529, -0.34006519, -0.75811102, -0.99910501])

朱莉婭:

[0.8414709848078965, -0.2910273263243299, 0.963237364649543, 0.7544102058854344,
 -0.3729191776326039, 0.8560014512776061, 0.9841238290665676, 0.1665709194875013,
 -0.7581110212957692, -0.9991050130774393]

發生這種情況是因為你正在承擔大量的sin 例如, t的最后一個數字是 10, exp(10^2)是 ~2.7*10^43。 在這種規模下,浮點誤差約為 3*10^9。 因此,即使 Python 和 Julia 的最低有效位不同, sin值也會相差很遠。

事實上,我們可以檢查初始數組t的底層二進制值。 例如,它們在倒數第三個值上有所不同:

朱莉婭:

julia> reinterpret(Int, range(0, stop=10, length=10)[end-2])
4620443017702830535

Python:

>>> import struct
>>> s = struct.pack('>d', np.linspace(0,10,10)[-3])
>>> struct.unpack('>q', s)[0]
4620443017702830536

我們確實可以看到他們的分歧正好是一台機器 epsilon。 如果我們使用朱莉婭采取sin被Python得到的值:

julia> sin(exp(reinterpret(Float64, 4620443017702830536)^2))
-0.3400651855865199

我們得到了與 Python 相同的值。

只是為了擴展一下答案(添加為答案,因為評論太長了)。 在 Julia 中,您有以下內容:

julia> t = collect(range(0, stop=10, length=10))
10-element Array{Float64,1}:
  0.0               
  1.1111111111111112
  2.2222222222222223
  3.3333333333333335
  4.444444444444445 
  5.555555555555555 
  6.666666666666667 
  7.777777777777778 
  8.88888888888889  
 10.0               

julia> t .- [10*i / 9 for i in 0:9]
10-element Array{Float64,1}:
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0

在 Python 中:

>>> t = np.linspace(0,10,10)
>>> t - [10*i/9 for i in range(10)]
array([0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00,
       0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 8.8817842e-16,
       0.0000000e+00, 0.0000000e+00])

並且您會看到 Python 中的第 8 個數字是70/9的不准確近似值,而在這種情況下,在 Julia 中您使用Float64獲得10*i/9的最接近近似值序列。

因此,似乎因為原始序列與您不同,其余部分遵循@Jakob Nissen 的評論。

然而事情並沒有那么簡單。 由於 Julia 和 Python 中的exp函數產生的內容略有不同。 見Python:

>>> from math import exp
>>> from mpmath import mp
>>> mp.dps = 1000
>>> float(mp.exp((20/3)**2) - exp((20/3)**2))
-1957.096392544307

在朱莉婭時:

julia> setprecision(1000)
1000

julia> Float64(exp(big((20/3)^2)) - exp((20/3)^2))
2138.903607455693

julia> Float64(exp(big((20/3)^2)) - nextfloat(exp((20/3)^2)))
-1957.096392544307

(您可以檢查(20/3)^2在 Julia 和 Python 中是否是相同的Float64 )。

所以在這種情況下,使用exp Python 比 Julia 稍微准確一些。 因此,即使修復t (通過在 Python 中使用linspace而不是linspace很容易)也不會使 ACF 相等。

總而言之,結論是@Jakob Nissen 對如此大的值的評論,結果將受到數值不准確性的強烈影響。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM