Python / Numpy / Scipy - Преобразование строки в математическую функцию - PullRequest
6 голосов
/ 27 декабря 2011

Я несколько неудачно пытаюсь перевести программу из глубины CERN ROOT в python.В ROOT-коде (CINT сам по себе является мерзостью imo) можно хранить математические функции в виде «строки» и передавать их в ROOT для подгонки, построения и т. Д., Поскольку ROOT определяет их как «строки».

В настоящий момент математические функции хранятся в простых текстовых файлах в виде строки, т.е.

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

, и затем извлекаются в виде строк C ++ при чтении в файле.Есть ли что-то подобное в питоне?Я знаю о Numberxpr, но я не могу заставить его работать с эквивалентом вышеупомянутого, то есть

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

Заранее большое спасибо.

1 Ответ

8 голосов
/ 27 декабря 2011

Поскольку, по-видимому, вы можете доверять строкам, чтобы они не были вредоносными, вы можете создать строку, которая определяет функцию, которая оценивает выражение, и использовать exec для выполнения этой строки в качестве оператора.Например,

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

возвращает

0.360894088631
...