我最近遇到了一個問題,就是NumPy中的矩陣乘法不準確。請看我下面的例子也是在這里https://trinket.io/python3/6a4c22e450
import numpy as np
para = np.array([[3.28522453e 08, -1.36339334e 08, 1.36339334e 08] 。
[-1.36339334e 08, 5.65818682e 07, -5.65818682e 07] 。
[1.36339334e 08, -5.65818672e 07, 5.65818682e 07]]
in1 = np.array([ [285.91695469],
[262.3]。
[-426.64380594]])
in2 = np.array([ [285.91695537],
[262.3] 。
[-426.64380443]])
(in1 - in2)/in1
>>> array([-2.37831286e-09],
[0.00000000e 00]。
[3.53925214e-09]])
in1和in2之間的差異非常小,是~10^-9
res1 = para @ in1
>>> array([-356.2361908],
[443.16068268]。
[-180.86068344]])
res2 = para @ in2
>>> array([[73.03147125],
[265.01131439],
[-2.71131516]])
但是在矩陣乘法之后,為什么輸出的res1和res2之間的差異變化如此之大?
(res1 - res2)/res1
>>> array([1.20500857]。
[0.40199723],
[0.98500882]])
uj5u.com熱心網友回復:
這不是一個bug;對于像你這樣的矩陣來說,這是可以預期的。
你的矩陣(是對稱的)有一個大的和兩個小的特征值:
你的矩陣(是對稱的)有一個大的和兩個小的特征值。
在 [34]: evals, evecs = np.linalg.eigh(para)
在[35]: evals
Out[35]: array([-1.06130078e-01, 1.00000000e 00, 4.41686189e 08])
因為矩陣是對稱的,所以它可以用正交基礎進行對角化。 這只是意味著我們可以定義一個新的坐標系,在這個坐標系中,矩陣是對角線的,而對角線的值就是那些特征值。在這些坐標中,矩陣乘以一個矢量的效果是簡單地將每個坐標乘以相應的特征值,即第一個坐標乘以-0.106,第二個坐標沒有變化,第三個坐標乘以大系數4.4e8。
當把原始矩陣para乘以in1和in2時,你會得到如此劇烈的變化,原因是在新坐標中,轉換后的in1的第三個分量是正的,而轉換后的in2的第三個分量是負的。 (也就是說,這些點位于與兩個較小的特征值相關的二維特征空間的兩側)。) 有幾種方法可以找到這些轉換后的坐標;一種是計算inv(V)@x,其中V是特征向量的矩陣:
在[36]: np.linalg.solve(evcs, in1)
輸出[36]。
array([[ 5.64863071e 02]。
[-1.16208620e 02],
[8.55527517e-07]])
在[37]: np.linalg.solve(evcs, in2)
輸出[37]。
array([[ 5.64863070e 02]。
[-1.16208619e 02],
[-2.71381169e-07]])
注意第三部分的不同標志。 這些值很小,但是當你乘以對角線矩陣時,它們被乘以4.4e8,分別得到377.87和-119.86。 這個大的變化顯示為你在原始坐標中觀察到的結果。
。
對于一個更粗略的計算:注意para的元素是~10^8,所以當你計算para @ x時,會發生這個數量級的乘法。 那么,鑒于in1和in2之間的相對差異是~10^-9,res1和res2的相對差異將是~10^-9*~10^8或~0.1,這就不奇怪了。
uj5u.com熱心網友回復:
這看起來像是一個bug......numpy是用C語言撰寫的,所以這可能是一個將數字轉換成更小的浮點的問題,在這種情況下會導致大的浮點錯誤
。轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/309444.html
標籤:
