2017-12-16 7 views
1

Ich habe eine Funktion erstellt, die gegebenen Koeffizientenbereiche Polynome mit solchen Koeffizienten konstruiert und eine Liste aller ihrer Wurzeln ausgibt. Numba mag es jedoch nicht. Es ist so:Python Numba Polynom Root Lower Fehler mit 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) 

Wenn ich versuche, dies zu laufen, es gibt eine kryptische: AssertionError: Fehler bei Objekt (Objekt-Modus Frontend) , die ich nicht verstehe ... Kann mir jemand helfen?

+0

Numba wird nicht in der Lage sein, den SymPy-Code zu beschleunigen. Wenn das ein Flaschenhals ist, könnten Sie versuchen, einen numerischen Solver zu verwenden. Eine andere Sache zu versuchen ist, ein allgemeines Kubik (mit symbolischen Koeffizienten) zu lösen und die Werte die allgemeinen Lösungen anzuschließen. – asmeurer

+0

Nein, ich weiß - aber würde es nicht die Iteration einer solchen Operation über ein großes Array beschleunigen? (sympy Lösung) –

+0

Ich bin zweifelhaft, ob es, außer vielleicht, wenn Sie es parallel zu den Nogil-Optionen ausführen würde. – asmeurer

Antwort

1

Es gibt eine Reihe von Dingen in Ihrem Code, denen Numba derzeit nicht gewachsen ist. Die erste ist die Liste Verständnis, wo Sie rangl bauen:

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

du wie mit einer NumPy Lösung ersetzen sollte:

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)) 

Die zweite Sache Numba nicht bewältigen kann, ist itertools.product. Sie können das durch NumPy und eine for-Schleife ersetzen.

Im Allgemeinen versuchen Sie, Ihren Code zu reduzieren, indem Sie den unteren Teil auskommentieren, bis Sie Numba akzeptieren, dann von oben nach unten arbeiten und sehen, welche Teile es nicht kompilieren kann. Seien Sie methodisch, gehen Sie Schritt für Schritt und versuchen Sie, sich an einfache Konstrukte wie einfache for Loops und Arrays zu halten.

+0

Danke! Wie würden Sie vorschlagen, das itertools.product für eine beliebige Anzahl von Arrays zu ersetzen? –

+0

@IskyMathews: Machen Sie es für eine feste Zahl arbeiten, dann verallgemeinern. Sie können Inspiration (vielleicht sogar einen Teil des Codes) aus der itertools-Implementierung entnehmen. –