我正在尝试使用 Julia 进行自相关并将其与 Python 的结果进行比较。他们怎么会给出不同的结果?
朱莉娅代码
using StatsBase
t = range(0, stop=10, length=10)
test_data = sin.(exp.(t.^2))
acf = StatsBase.autocor(test_data)
Run Code Online (Sandbox Code Playgroud)
给
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
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
给
array([ 1. , 0.14589844, -0.10412699, 0.07817509, -0.12916543,
-0.03469143, -0.129255 , -0.15982435, -0.02067688, -0.14633346])
Run Code Online (Sandbox Code Playgroud)
Jak*_*sen 26
这是因为你test_data的不同:
Python:
array([ 0.84147098, -0.29102733, 0.96323736, 0.75441021, -0.37291918,
0.85600145, 0.89676529, -0.34006519, -0.75811102, -0.99910501])
Run Code Online (Sandbox Code Playgroud)
朱莉娅:
[0.8414709848078965, -0.2910273263243299, 0.963237364649543, 0.7544102058854344,
-0.3729191776326039, 0.8560014512776061, 0.9841238290665676, 0.1665709194875013,
-0.7581110212957692, -0.9991050130774393]
Run Code Online (Sandbox Code Playgroud)
发生这种情况是因为您正在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
Run Code Online (Sandbox Code Playgroud)
Python:
>>> import struct
>>> s = struct.pack('>d', np.linspace(0,10,10)[-3])
>>> struct.unpack('>q', s)[0]
4620443017702830536
Run Code Online (Sandbox Code Playgroud)
我们确实可以看到他们的分歧正好是一台机器 epsilon。如果我们使用 Juliasin获取 Python 获得的值:
julia> sin(exp(reinterpret(Float64, 4620443017702830536)^2))
-0.3400651855865199
Run Code Online (Sandbox Code Playgroud)
我们得到了与 Python 相同的值。
Bog*_*ski 10
只是为了扩展一下答案(添加为答案,因为评论太长了)。在 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
Run Code Online (Sandbox Code Playgroud)
在 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])
Run Code Online (Sandbox Code Playgroud)
并且您会看到 Python 中的第 8 个数字是 的不准确近似值70/9,而在这种情况下,在 Julia 中您会得到10*i/9using的最接近的近似值序列Float64。
因此,似乎因为原始序列与您不同,其余部分遵循@Jakob Nissen 的评论。
然而事情并没有那么简单。由于expJulia 和 Python 中的函数在生成的内容上略有不同。见Python:
>>> from math import exp
>>> from mpmath import mp
>>> mp.dps = 1000
>>> float(mp.exp((20/3)**2) - exp((20/3)**2))
-1957.096392544307
Run Code Online (Sandbox Code Playgroud)
在朱莉娅时:
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
Run Code Online (Sandbox Code Playgroud)
(您可以检查在 Julia 和 Python中(20/3)^2是否相同Float64)。
所以在这种情况下,expPython 比 Julia 稍微准确一些。因此,即使修复t(通过在 Python 中使用推导式而不是 很容易linspace)也不会使 ACF 相等。
总而言之,@Jakob Nissen 评论了如此大的值,结果将受到数值不准确性的强烈影响。
| 归档时间: |
|
| 查看次数: |
1597 次 |
| 最近记录: |