2011-12-26 47 views
6

Estoy en la posición un tanto desafortunada de intentar convertir un programa de las profundidades de CERN ROOT a python. En el código ROOT (CINT en sí mismo es una abominación imo), uno puede almacenar funciones matemáticas como una "cadena" y pasarlas a ROOT para su ajuste, trazado, etc., debido a cómo ROOT las define como "cadenas".Python/Numpy/Scipy - Conversión de cadena a función matemática

Por el momento, las funciones matemáticas se almacenan en archivos de texto simple como una línea, es decir,

(1+[1])^(1+[1])/TMath::Gamma(1+[1]) * x^[1]/[0]^(1+[1]) * exp(-(1+[1])*x/[0]) 

y luego se extraen como cadenas de C++ al leer el archivo. ¿Hay algo similar en Python? Sé de numexpr, pero me parece que no puede conseguir que funcione con el equivalente de lo anterior, es decir

(1+p[1])**(1+p[1])/scipy.special.Gamma(1+p[1]) * x**p[1]/p[0]**(1+p[1]) * numpy.exp(-(1+p[1])*x/p[0]) 

Muchísimas gracias por adelantado.

+0

puede llamar función raíz de pitón, para que pueda crear un 'ROOT.TF1' en Python, como en C++ –

Respuesta

8

Dado que, presumiblemente, puede confiar en que las cadenas no serán maliciosas, podría construir una cadena que defina una función que evalúe la expresión y use exec para ejecutar esa cadena como una instrucción. Por ejemplo,

import numpy as np 
import scipy.special as special 

expr='(1+p[1])**(1+p[1])/special.gamma(1+p[1]) * x**p[1]/p[0]**(1+p[1]) * np.exp(-(1+p[1])*x/p[0])' 

def make_func(expr): 
    funcstr='''\ 
def f(x,p): 
    return {e} 
    '''.format(e=expr) 
    exec(funcstr) 
    return f 

f=make_func(expr) 
print(f(1,[2,3])) 

vuelve

0.360894088631