我正在嘗試將 MATLAB 腳本的數值輸出與 numpy 的數值輸出進行比較。
來自家庭作業的任務是將 10^-N 的值與自身相加 10^N 次。
目標是證明計算機具有會在這種計算中復合的局限性。結果應始終為 1,但隨著 N 的增加,誤差也會增加。對于這個問題,N 應該是 0, 1, 2, ..., 8。
我的 MATLAB 腳本運行迅速,沒有任何問題:
solns = zeros(1, 9);
for N = 0:8
for ii = 1:(10^N)
solns(N 1) = solns(N 1) 10^-N;
end
end
但是,在帶有 numpy 的 Anaconda 安裝上使用 Python 3.8.12,此代碼不會終止(請參閱更新,代碼會執行):
import numpy as np
solns = np.zeros((9, 1))
for N in range(len(solns)):
for _ in range(10**N):
solns[N] = (10**-N)
Python 代碼中是否存在錯誤,或者創建此結果的語言之間是否存在一些顯著差異。
編輯:
我讓 python 代碼運行了一段時間,它最終在 230 秒后終止。整個陣列列印為 [1., 1., 1., etc.]。
作為參考,使用tic tocMATLAB上的命令,程式在0.155760秒內執行
uj5u.com熱心網友回復:
你寧愿在那里濫用 NumPy。特別是 =帶有陣列元素的似乎幾乎花費了所有時間。
我就是這樣做的,大約需要 0.5 秒:
from itertools import repeat
for N in range(9):
print(sum(repeat(10**-N, 10**N)))
輸出(在線嘗試!):
1
0.9999999999999999
1.0000000000000007
1.0000000000000007
0.9999999999999062
0.9999999999980838
1.000000000007918
0.99999999975017
1.0000000022898672
正如@AndrasDeak 評論的那樣,由于多項優化,它很快。讓我們也嘗試更少的優化。
首先,只擺脫 NumPy,使用簡單的 Python 浮點數。你原來的順便說一句也花了我大約 230 秒。這只有大約 29 秒:
for N in range(9):
total = 0
for _ in range(10**N):
total = (10**-N)
print(total)
接下來,不要一遍又一遍地重新計算附加值。大約需要 11 秒:
for N in range(9):
total = 0
add = 10**-N
for _ in range(10**N):
total = add
print(total)
接下來,range不要無緣無故地產生大量 int 物件。讓我們使用itertools.repeat,這是我所知道的最快的可迭代物件。大約需要 9 秒:
from itertools import repeat
for N in range(9):
total = 0
add = 10**-N
for _ in repeat(None, 10**N):
total = add
print(total)
或者,大約相同的速度:
from itertools import repeat
for N in range(9):
total = 0
for add in repeat(10**-N, 10**N):
total = add
print(total)
只需將其放入函式中即可受益于區域變數比全域變數更快。然后大約需要 3.3 秒:
from itertools import repeat
def run():
for N in range(9):
total = 0
for add in repeat(10**-N, 10**N):
total = add
print(total)
run()
這可能是我用普通的干凈回圈所能做的最快的for(回圈展開會有所幫助,但是呃......)。
My sum(repeat(...)) version lets C code do all the work (and sum even optimizes the summation of floats), making it still quite a bit faster.
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/426533.html
下一篇:具有符號變數和rref的增強矩陣
