2017-11-08 9 views
1

私はPythonで小数点モジュールを使用して新しくなりました。キューブルーツ(または実際にはルート)を計算する最も効率的な方法は何ですか?私はnum ** (Decimal(1)/Decimal(3)を試しましたが、かなりの時間がかかりました。たとえば、以下のコードはインテルのi5プロセッサー走行のpython 3に約20秒かかります:pythonで十進数を使ってキューブルーツを計算するには

from decimal import * 

getcontext().prec = 10000 
a0 = Decimal(3.0) 

import time 
beg = time.time() 
cuber = a0**(Decimal(1)/Decimal(3)) 
end = time.time() 
print(end-beg) 

私は単純なニュートンアルゴリズムを書くために行うことができ、より良いものを知っているが、はるかに短い実行時間を与えます(以下のコードを参照してください) 。 私の質問は、小数点の整数の根を取るための良い方法(組み込み式が好ましい)は何ですか?

はるかに高速である迅速なニュートン法は、(〜0.2秒)以下である:

def cube_root(A): 
    guess = (A-Decimal(1))/Decimal(3) 
    x0 = (Decimal(2) * guess + A/Decimal(guess*guess))/Decimal(3.0) 
    while 1: 
     xn =(Decimal(2) * x0 + A/Decimal(x0*x0))/Decimal(3.0) 
     if xn == x0: 
      break 
     x0 = xn 
    return xn 

beg = time.time() 
print(cuber - cube_root(a0)) 
end = time.time() 
print(end-beg) 

上記のコードの全てのサンプル出力、私のシステムでは、次のとおりです。

23.898984670639038 
0E-9999 
0.10790443420410156 
+1

Hmは、ニュートンの勝利のようです。それは理にかなっている、私はそれが 'sqrt'を実装する方法だと思う。 –

+0

彼らは本当に 'integer_root'関数を提供するべきです。 –

+0

@ juan.arrivillaga:integer_rootはどういう意味ですか? –

答えて

1

このような低次のキューブルートについては、ニュートンズが最善の策になるでしょう。私は内側のテストを取り除くことによってループをより効率的にし、約5%の速度改善を得ました。冗長なDecimalのコンバージョンを削除するとさらに2-3%のコンバージョンが発生します。

def cube_root(A): 
    d1 = Decimal(1) 
    d2 = Decimal(2) 
    d3 = Decimal(3) 

    x0 = (A-d1)/d3 
    xn = (d2 * x0 + A/Decimal(x0*x0))/d3 

    while xn != x0: 
     x0 = xn 
     xn = (d2 * x0 + A/Decimal(x0*x0))/d3 

    return xn 
関連する問題