2016-03-31 7 views
1

Ich verwende lambdify, um einen Ausdruck zu kompilieren, der eine Funktion bestimmter Parameter ist. Jeder Parameter hat N Punkte. Also muss ich den Ausdruck N mal auswerten. Im Folgenden wird ein vereinfachtes Beispiel für die Vorgehensweise gezeigt.Python 3: Sympy: Listeninformationen zur Optimierung von Lambdify hinzufügen

import numpy as np 
from sympy.parsing.sympy_parser import parse_expr 
from sympy.utilities.lambdify import lambdify, implemented_function 
from sympy import S, Symbol 
from sympy.utilities.autowrap import ufuncify 


def CreateMagneticFieldsList(dataToSave,equationString,DSList): 

    expression = S(equationString) 
    numOfElements = len(dataToSave["MagneticFields"]) 

    #initialize the magnetic field output array 
    magFieldsArray = np.empty(numOfElements) 
    magFieldsArray[:] = np.NaN 

    lam_f = lambdify(tuple(DSList),expression,modules='numpy') 
    try: 
     for i in range(numOfElements): 
      replacementList = np.zeros(len(DSList)) 


      for j in range(len(DSList)): 
       replacementList[j] = dataToSave[DSList[j]][i] 

      try: 
       val = np.double(lam_f(*replacementList)) 

      except: 
       val = np.nan 
      magFieldsArray[i] = val 
    except: 
     print("Error while evaluating the magnetic field expression") 
    return magFieldsArray 


list={"MagneticFields":list(range(10000)), "Chx":list(range(10000))} 

out=CreateMagneticFieldsList(list,"MagneticFields*5+Chx",["MagneticFields","Chx"]) 

print(out) 

Gibt es eine Möglichkeit, diesen Anruf weiter zu optimieren? Genauer gesagt, ich meine, gibt es eine Möglichkeit, lambdify Include zu machen, die ich für eine Liste von Punkten berechne, so dass die Loop-Evaluierung optimiert werden kann?

+0

Wenn Sie lambdify mit modules = "numpy" verwenden, wird ein anonymer Ausdruck erstellt. Sie sollten in der Lage sein, numpy arrays als Argumente für Ihre Lambda-Funktion zu übergeben, und der Ausdruck wird über sie vektorisiert. – asmeurer

+0

@asmeurer Danke für die Info! Ich werde es versuchen! –

Antwort

1

Dank @asmeurer, er gab die Idee, wie es geht.

Da lambdify mit numpy kompiliert wird, könnte man die Listen einfach als Argumente übergeben! Das folgende ist ein funktionierendes Beispiel

#!/usr/bin/python3 

import numpy as np 
from sympy.parsing.sympy_parser import parse_expr 
from sympy.utilities.lambdify import lambdify, implemented_function 
from sympy import S, Symbol 
from sympy.utilities.autowrap import ufuncify 


def CreateMagneticFieldsListOpt(dataToSave,equationString,DSList): 

    expression = S(equationString) 
    numOfElements = len(dataToSave["MagneticFields"]) 

    #initialize the magnetic field output array 
    magFieldsArray = np.empty(numOfElements) 
    magFieldsArray[:] = np.NaN 

    lam_f = lambdify(tuple(DSList),expression,modules='numpy') 
    replacementList = [None]*len(DSList) 

    for j in range(len(DSList)): 
     replacementList[j] = np.array(dataToSave[DSList[j]]) 
    print(replacementList) 

    magFieldsArray = np.double(lam_f(*replacementList)) 


    return magFieldsArray 

list={"MagneticFields":[1,2,3,4,5],"ChX":[2,4,6,8,10]} 

out=CreateMagneticFieldsListOpt(list,"MagneticFields*5+ChX",["MagneticFields","ChX"]) 

print(out)