Создать функциональный объект из функции и частичной функции - PullRequest
0 голосов
/ 22 октября 2019

Я новичок в использовании генераторов функций. Я работаю со следующей функцией:

def math_model(n: float):
    def crrcn(x, t0: float, amp: float, tau: float, offset: float, dt: float, k: float):
        crrcn = np.zeros(np.shape(x))
        for i, a in enumerate(x):
            if a < (t0 + dt):
                crrcn[i] = offset
            else: 
                crrcn[i] = offset + k * amp * (math.exp(n) / (n ** n)) * ((a - (t0 + dt)) / tau) ** n * math.exp( - (a - (t0 + dt)) / tau) 
        return crrcn
    return crrcn

, которая определяет математическую модель, которую я буду использовать позже для подгонки некоторых данных с помощью scipy curve_fit. Я хотел использовать эту же модель, чтобы построить более сложную модель со следующей строкой:

model = partial(math_model(N), dt = 0, k = 1) + math_model(N)

, что дает мне:

TypeError: unsupported operand type(s) for +: 'functools.partial' and 'function'

Из чего я понимаю, что я не могу построить функцию из двух функций, используя этот оператор, и, насколько я знаю, в python нет операндов функций. Как можно построить функцию из других функций без явной оценки их?

Ответы [ 2 ]

2 голосов
/ 22 октября 2019

ПРЕДЫДУЩИЙ ОТВЕТ:

Это похоже на недопонимание partial.

partial(...) возвращает новую функцию. Он не выполняет его, он просто создает его.

Таким образом, ваша строка model = partial(math_model(N), dt = 0, k = 1) + math_model(N) недействительна, потому что вы в основном выполняете операцию a + b, где a - это ... функция:)

То, что вы можете сделать, это просто применить модель. Это можно сделать, используя math_model(N)(dt = 0, k = 1).

Так что

model = math_model(N)(dt = 0, k = 1) + math_model(N)

может сделать трюк

НОВОЕ РЕДАКТИРОВАНИЕ: Кажется, чтоЯ не так тебя поняла. Вы действительно хотите создать функцию, объединив две функции. Поэтому это какое-то символическое рассуждение. Для этого есть несколько библиотек, самая продвинутая из известных мне SymPy. Или, если ваши функции имеют только один аргумент, вы можете использовать мой mini_lambda

Например, с мини-лямбда-выражением:

from mini_lambda import x

f1 = x ** 2
f2 = 5 * x
f3 = f1 + f2

print(f3.to_string())
print(f3.evaluate(1))

выход

x ** 2 + 5 * x
6
1 голос
/ 23 октября 2019

Учитывая, что функция зависит от нескольких переменных, mini_lambda не была опцией. Но с симпой это было приятно и легко.

def math_model():
    a, o, t, t0, tau, dt, k = sympy.symbols('a, o, t, t0, tau, dt, k')
    semi = a * sympy.exp(-(t - t0)/ tau)
    reflex = k * a * sympy.exp(-(t -(t0 + dt))/ tau)
    double = sympy.Piecewise((o, t < t0),(o + semi, (t0 <= t) & (t < t0 + dt)), (o + semi + reflex, t0 + dt <= t))
    return sympy.lambdify([t, t0, dt, k, o, a, tau], double, 'scipy')

Спасибо, что предложили Sympy. После использования lambdify в результате получается функция python, которая в этом случае опирается на грубые определения математических функций.

...