2017-12-16 7 views
1

与えられた係数の範囲で、このような係数を持つ多項式を構成し、すべての根のリストを出力する関数を作成しました。しかし、Numbaはそれを好まない。それはこのようなものだ:Python Numba多項式根の下限エラー(Sympy)

import math 
import numpy as np 
import itertools 
from numba import jit 
from sympy.solvers import solve 
from sympy import Symbol 
from sympy import Poly 

@jit 
def polyn(ranges=[[-20,20],[-20,20],[-20,20],[-20,20]],step=4): 
    l = [] 
    x = Symbol('x') 
    rangl = [np.linspace(i[0],i[1],math.floor((i[1]-i[0])/step)) for i in ranges] 
    coeffl = iter(itertools.product(*rangl)) 
    leng = 1 
    for i in rangl: 
     leng *= len(i) 
    for i in range(0, leng): 
     a = solve(Poly(list(next(coeffl)),x),x) 
     for j in a: 
      l.append(j) 
    return np.array(l) 

私はこれを実行しようとすると、それは不可解な出力: てAssertionError:オブジェクトに失敗しました(オブジェクト・モードのフロントエンド)私は理解していない ...誰か手伝ってくれるの?

+0

Numbaは、SymPyコードをスピードアップすることはできません。それがボトルネックならば、数値ソルバーを試してみてください。もう1つの試みは、一般的な3次方程式(記号係数を持つ)を解くことであり、一般的な解の値を差し込みます。 – asmeurer

+0

いいえ、私は知っています - しかし、それは大きな配列の上でそのような操作の反復をスピードアップしませんか? (sympy解決) –

+0

もしそれがnogilオプションと並行して実行されるのを除いて、それが可能ならば疑いがあります。 – asmeurer

答えて

1

あなたのコードにはNumbaが現在対処できないものがいくつかあります。最初は、あなたがranglを構築リスト内包である:

[np.linspace(i[0],i[1],math.floor((i[1]-i[0])/step)) for i in ranges] 

あなたが好きnumpyのソリューションでこれを置き換える必要があります。

rangl = np.empty((len(ranges), step)) 
for i in ranges: 
    rangl[i] = np.linspace(i[0],i[1],math.floor((i[1]-i[0])/step)) 

Numbaは対応できない二つ目はitertools.productです。それをNumPyとforループで置き換えることもできます。

一般に、Numbaに受け入れられるまで下の部分をコメントアウトしてコードを減らしてから、上から下に向かって作業し、コンパイルできない部分を確認してください。方法論的で、一歩一歩進み、単純な構造のループや配列のような単純な構造に固執してみてください。

+0

ありがとう! itertools.productを任意の数の配列に置き換えることをどのように提案しますか? –

+0

@IskyMathews:固定数で動作させてから、一般化してください。 itertools実装からインスピレーション(おそらくコードの一部)を取ることができます。 –