2015-12-11 93 views
-1

我發現下面的答案在這裏#2:如何計算的浮點數Python的浮動數個根

https://stackoverflow.com/a/356187/1829329

但它僅適用於整數,如n次方根N:

import gmpy2 as gmpy 

result = gmpy.root((1/0.213), 31.5).real 
print('result:', result) 

結果:

--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
<ipython-input-14-eb4628226deb> in <module>() 
     8 
----> 9 result = gmpy.root((1/0.213), 31.5).real 
    10 
    11 print('result:', result) 

TypeError: root() requires 'mpfr','int' arguments 

什麼是一個度的計算和良好精確的方式這樣的根? (這是一些公式推,我需要使用一個講座來計算的Python代碼表示。)

編輯#1

這裏是基於Spektre的答案和信息從我的解決辦法超過here at http://math.stackexchange.com的人。

import numpy as np 

def naive_root(nth, a, datatype=np.float128): 
    """This function can only calculate the nth root, if the operand a is positive.""" 
    logarithm = np.log2(a, dtype=datatype) 
    exponent = np.multiply(np.divide(1, nth, dtype=datatype), logarithm, dtype=datatype) 
    result = np.exp2(exponent, dtype=datatype) 
    return result 

def nth_root(nth, a, datatype=np.float128): 
    if a == 0: 
     print('operand is zero') 
     return 0 
    elif a > 0: 
     print('a > 0') 
     return naive_root(nth, a, datatype=datatype) 
    elif a < 0: 
     if a % 2 == 1: 
      print('a is odd') 
      return -naive_root(nth, np.abs(a)) 
     else: 
      print('a is even') 
      return naive_root(nth, np.abs(a)) 
+0

當a小於0並且您取非整數根時,結果爲複數。你的'n_root'函數沒有這樣做。我認爲你已經使它比需要更復雜。 – casevh

回答

1

看到Power by squaring for negative exponents

反正我不代碼Python或先在這裏gmpy一些定義:

  • pow(x,y)意味着x搭載y
  • root(x,y)意味着x的個根y

由於這些反函數,我們可以重寫:

  • pow(root(x,y),x)=y

equation

你可以用這個來檢查的正確性。由於函數互爲逆你也可以這樣寫:

  • pow(x,1/y)=root(y,x)
  • root(1/x,y)=pow(y,x)

所以,如果你有小數(理性)根或電源就可以計算它與逆整數對口功能。

此外,如果你有例如像root(2/3,5),那麼你需要分開,整數操作數第一:

root(2/3,5)=pow(root(2,5),3) 
~11.18034 = ~2.236068 ^3 
~11.18034 = ~11.18034 

對於irational根和權力,你不能獲得準確的結果。相反,您可以根據最近的可能表示法將根或權力四捨五入,以最大限度地減少錯誤或使用pow(x,y) = exp2(y*log2(x))方法。如果你使用任何浮點或定點十進制數,那麼你可以忘記精確的結果,並從一開始就去尋找pow(x,y) = exp2(y*log2(x)) ...

[注意事項]

我以爲只有正操作數 ...如果你有負數供電或紮根,那麼你需要處理整根和權力(奇/偶)的標誌。對於irational根和權力的標誌沒有意義(或者至少我們還沒有理解)。

+0

感謝數學背景知識。天真地做一個壞主意(簡單地輸入「牛頓方法的推導」下的那個表達式)使用高精度浮點數來實現來自https://en.wikipedia.org/wiki/Nth_root_algorithm的牛頓算法?如果我理解正確,它也可以處理負面根,所以我不必處理該標誌,如果我想要有一個負面的根。 – Zelphir

+0

@ Zelphir這不是一個好主意(從我的觀點來看),因爲根可以通過單一權力直接計算。在牛頓算法中,通過多次調用使用iteartion,與直接計算相比,進一步增加了近似誤差:'root(x,y)= pow(y,1/x)= exp2(x * log2(1/y)'如果'1/y'或'y'是奇數('y mod 2 == 1'或'1/y mod'),則用'| y |'計算負值'y'並將結果設置爲負值2 == 1')函數'exp2,log2'直接在大多數FPU上執行,也可以直接計算... – Spektre

1

如果你願意使用Python 3.x,本地pow()將只使用root(x,y) = pow(x,1/y)來完成你想要的功能。如果合適的話,它會自動返回一個複雜的結果。

Python 3.4.3 (default, Sep 27 2015, 20:37:11) 
[GCC 5.2.1 20150922] on linux 
Type "help", "copyright", "credits" or "license" for more information. 
>>> pow(1/0.213, 1/31.5) 
1.0503191465568489 
>>> pow(1/0.213, -1/31.5) 
0.952091565004975 
>>> pow(-1/0.213, -1/31.5) 
(0.9473604081457588-0.09479770688958634j) 
>>> pow(-1/0.213, 1/31.5) 
(1.045099874779588+0.10457801566102139j) 
>>> 

返回一個複雜的結果反而提高了一個ValueError的是在Python 3的變化之一,如果你想與Python 2相同的行爲,你可以使用gmpy2,使複雜的結果。

>>> import gmpy2 
>>> gmpy2.version() 
'2.0.5' 
>>> gmpy2.get_context().allow_complex=True 
>>> pow(1/gmpy2.mpfr("0.213"), 1/gmpy2.mpfr("31.5")) 
mpfr('1.0503191465568489') 
>>> pow(-1/gmpy2.mpfr("0.213"), 1/gmpy2.mpfr("31.5")) 
mpc('1.0450998747795881+0.1045780156610214j') 
>>> pow(-1/gmpy2.mpfr("0.213"), -1/gmpy2.mpfr("31.5")) 
mpc('0.94736040814575884-0.094797706889586358j') 
>>> pow(1/gmpy2.mpfr("0.213"), -1/gmpy2.mpfr("31.5")) 
mpfr('0.95209156500497505') 
>>> 
+0

呵呵,我期望在使用'pow'時會有更大的精度損失,也許我應該試試這種方式首先,我已經更新了我的問題以包含我爲計算第n個根所編寫的函數,實際上我總是使用Python 3. Python是否內部使用任何高速高精度庫進行計算?現在我使用NumPy和float128精度因爲我可以:) – Zelphir

+0

我知道PyPi上還有Python 3的gmpy2 - 偶然發現了你在搜索過程中寫過的一些帖子。我不確定NumPy如何在內部工作,以及與gmpy2有多相似。我也嘗試了一些gmpy2,看不出有什麼區別,除了gmpy讀起來有些複雜(imo)。 – Zelphir

+1

'numpy'經過優化,可以與底層硬件平臺識別的類型的數組/向量一起工作。 float128中的'128'表示存儲在數組中時數據類型使用的內存量。它通常對應於較小的硬件類型。請參閱http://stackoverflow.com/questions/9062562/what-is-the-internal-precision-of-numpy-float128。'gmpy2'執行任意精度計算,不依賴於平臺的本地浮點類型。 – casevh

0

下面是我用這似乎與任何數量的就好了工作:

root = number**(1/nthroot) 
print(root) 

它適用於任何數量的數據類型。