我試圖使用numpy對以numpy陣串列示的矩陣進行操作。 我在這些矩陣中使用了分數作為元素。
似乎一切都很正常,直到我試圖找到逆的時候。
這時出現了錯誤。
這是不是numpy的一個錯誤?
我的意思是,如果numpy允許我們對這種充滿分數的矩陣進行乘法,那么它也應該允許我們找到逆,對嗎?
import numpy as np
from分數 import Fraction as F。
c = np. array([[F(2),F(-1), F(-1],[F(3), F(4), F(-2)], [F(3),F(-2), F(4) ] ]
c @ c
np.dot(c, c)
np.linalg.inv(c)
錯誤:
---------------------------------------------------------------------------
TypeError 回溯(最近的一次呼叫)。
<ipython-input-45-5ed58b2836e1> in < module>
----> 1 np.linalg.inv(c)
<__array_function__ internals> in inv(*args, **kwargs)
C:ProgramsAnaconda3libsite-packages
umpylinalglinalg.py in inv(a)
544 signature = 'D->D' if isComplexType(t) else 'd->d'
545 extobj = get_linalg_error_extobj(_raise_linalgerror_singular)
--> 546 ainv = _umath_linalg.inv(a, signature=signature, extobj=extobj)
547 return wrap(ainv.astype(result_t, copy=False)
548
TypeError。沒有找到與指定簽名和鑄造相匹配的回圈 for ufunc inv
我的numpy版本是
1.19.2
1.19.2
uj5u.com熱心網友回復:
我同意其他的答案。Numpy是用于數值計算的,意思是用浮點數進行不完美的計算。如果你想做精確的,又稱符號計算。你應該用sympy來代替。例如,試試:
import sympy
from分數 import Fraction as F
c = sympy. 矩陣([[F(2),F(-1), F(-1)],[F(3) 。 F(4), F(-2)], [F(3),F(-2), F(4) ] ]
c.inv()
uj5u.com熱心網友回復:
不知道你是否可以稱其為一個bug,似乎是按計劃作業。Numpy的linalg模塊是Scipy的linalg模塊的輕量級版本;Numpy只支持浮點數或復雜的浮點數(編輯:除非你使用Numpy內部所說的 "精確型別",如int;那些是被投射的)。甚至Scipy也不支持分數。從Scipy的linalg(強調是我的)的源代碼中:
許多SciPy的線性代數函式確實支持任意的類似陣列的 輸入引數。通常不支持的輸入的例子包括 包含inf/nan的矩陣,稀疏的矩陣表示,和 具有復雜元素的矩陣
。
閱讀源代碼,Numpy的限制性更強;Scipy接受任何呼叫np.array(A)不會產生一個dtype為object的陣列。這是否有意義是主觀的;似乎有一些不重要的兼容性(與現有的C演算法)或性能權衡,允許陣列中的一般物件。
uj5u.com熱心網友回復:
在[291]。import 分數
在[292]。F = fractions.Fraction
在[293]中:C = np.Counter() array([[F(2),F(-1), F(-1],[F(3), F(4), F(-2)], [F(3),F(-2), F(4) ] ]
...:
在[294]: c
輸出[294]。
array([[Fraction(2, 1), Fraction(-1, 1), Fraction(-1, 1) ] 。
[Fraction(3, 1), Fraction(4, 1), Fraction(-2, 1) ] 。
[Fraction(3, 1), Fraction(-2, 1) 。Fraction(4, 1)], dtype=object)
在[295]:c@c
輸出[295]。
array([[Fraction(-2, 1), Fraction(-4, 1), Fraction(-4, 1) ] 。
[Fraction(12, 1), Fraction(17, 1), Fraction(-19, 1) ] 。
[Fraction(12, 1), Fraction(-19, 1) 。Fraction(17, 1)], dtype=object)
這樣做是因為c的元素支持簡單的乘法和加法。
在[298]。c[0,0]*c[1,1]
輸出[298]。Fraction(8, 1)
比較這個物件d型別的矩陣乘法的時間:
在[300]:timeit c@c
123 μs ± 523 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
用float dtype乘法的時間:
在 [301]: c1=c.astype(float)
在[302]: c1
輸出[302]。
array([[ 2., -1., -1.]。
[3., 4., -2.] 。
[3., -2., 4.]])
在[303]:timeit c1@c1
4.19 μs ± 28.7 ns per loop (mean ± std. dev. of 7 runs, 100000 loop each)
對于數字dtype,@/dot將任務傳遞給快速編譯的庫。 對于物件型別,它必須執行一個較慢的python級別的計算。
inv具有快速的數字模式,但是沒有實作緩慢的物件版本。
在輸入物件dtype的情況下,完整的錯誤資訊是:
UFuncTypeError: Cannot cast ufunc 'inv' input from dtype('O')到dtype('float64') with casting rule 'same_kind
用一個浮動的dtype:
在[304]: np.linalg.inv(c1)
輸出[304]。
array([[0.2 , 0.1 , 0.1 ],
[-0.3 , 0.183333, 0.01666667]。
[-0.3 , 0.01666667, 0.18333333]])
在[305]: timeit np.linalg.inv(c1)
16.4 μs ± 339 ns per loop (mean ± std. dev. of 7 runs, 100000 loop each)
與https://stackoverflow.com/a/69239281/901925提供的sympy版本相比,
在[308]。import sympy
在[309]。from fractions import Fraction as F
...:
...: c = sympy. Matrix([[F(2),F(-1), F(-1)],[F(3) 。 F(4), F(-2)], [F(3),F(-2), F(4) ] ]
在[310]: c
輸出[310]。
矩陣([
[2, -1, -1] 。
[3, 4, -2] 。
[3, -2, 4]])
在[311]: c.inv()
輸出[311]。
矩陣([
[1/5, 1/10, 1/10] 。
[-3/10, 11/60, 1/60] 。
[-3/10, 1/60, 11/60]] )
在[312]: timeit c.inv()
801 μs ± 23.2 μs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
scipy更明確
在[315]。from scipy import linalg
在 [316]: linalg.inv(c)
回溯(最近一次呼叫)。
檔案"<ipython-input-316-48147545516b>",行1,in<module>。
linalg.inv(c)
檔案 "/usr/local/lib/python3.8/dist-packages/scipy/linalg/basic.py", line 939, in inv
a1 = _asarray_validated(a, check_finite=check_finite)
檔案 "/usr/local/lib/python3.8/dist-packages/scipy/_lib/_util.py", 行 296, in _asarray_validated
raise ValueError('物件陣列不被支持')
ValueError。object陣列不支持。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/326872.html
標籤:

