您可以使用dtype = object
和fractions.Fraction
課程做一些非常酷的事情,例如,
>>> A = np.array([fractions.Fraction(1, j) for j in xrange(1, 13)]).reshape(3, 4)
>>> A
array([[1, 1/2, 1/3, 1/4],
[1/5, 1/6, 1/7, 1/8],
[1/9, 1/10, 1/11, 1/12]], dtype=object)
>>> B = np.array([fractions.Fraction(1, j) for j in xrange(1, 13)]).reshape(4, 3)
>>> B
array([[1, 1/2, 1/3],
[1/4, 1/5, 1/6],
[1/7, 1/8, 1/9],
[1/10, 1/11, 1/12]], dtype=object)
>>> np.dot(A, B)
array([[503/420, 877/1320, 205/432],
[3229/11760, 751/4620, 1217/10080],
[1091/6930, 1871/19800, 1681/23760]], dtype=object)
不幸的是,np.linalg
模塊將一切float
做任何事情之前,所以你不能指望獲得直接的解決方案爲整數或有理數。但是,你總是可以做以下的計算後:
def scale_to_int(x) :
fracs = [fractions.Fraction(j) for j in x.ravel()]
denominators = [j.denominator for j in fracs]
lcm = reduce(lambda a, b: max(a, b)/fractions.gcd(a, b) * min(a, b),
denominators)
fracs = map(lambda x : lcm * x, fracs)
gcd = reduce(lambda a, b: fractions.gcd(a, b), fracs)
fracs = map(lambda x: x/gcd, fracs)
return np.array(fracs).reshape(x.shape)
這將是緩慢的,並四捨五入誤差非常敏感:
>>> scale_to_int(np.linspace(0, 1, 5)) # [0, 0.25, 0.5, 0.75, 1]
array([0, 1, 2, 3, 4], dtype=object)
>>> scale_to_int(np.linspace(0, 1, 4)) # [0, 0.33333333, 0.66666667, 1]
array([0, 6004799503160661, 12009599006321322, 18014398509481984], dtype=object)
你可以減輕一些,使用的limit_denominator
方法Fraction
,但可能不會那麼健壯。
我想你指的是什麼是模數有限域上?如果是這樣,那麼NumPy不能這樣做,因爲NumPy是用於Numerics的。 –
感謝您的評論!不,我不這樣做。由於矩陣的特徵向量被確定爲乘法常數,因此我正在尋找一種方法來獲取特徵向量,使得所有條目都是整數。例如,對於我的問題中的矩陣,Numpy會返回'numpy.array([[ - 0.70710678],[0.70710678]])'作爲答案,其中0.70710678確實是srqt(2)/ 2,使其成爲一個單位向量。對於一個任意的特徵向量,是否有一種很好的方法來知道如何重新調整向量使其成爲整數值? – Lei