Я пытаюсь реализовать оптимизацию параметров для двух связанных ODE в Python с двумя реагентами.Я хочу использовать стандартизированный остаток в качестве моей целевой функции.
Реакции:
da/dt = - k1 * a + k2 * b
db/dt = k1 * a - k2 * b
Начальные значения: a(0) = 1
и b(0) = 0
.
Начальные константы реакции: k1 = 1
и k2 = 0.1
.Константы реакции находятся в диапазоне 1e-3 < k < 10
.Это параметры для оптимизации.
Мне удалось написать свои ODE и целевую функцию.
Вот мой код.
import numpy as np
from scipy.integrate import odeint
import operator
# My test data
data_b = [0.0244, 0.0842, 0.1208, 0.1724, 0.2315, 0.2634, 0.2831, 0.3084, 0.3079, 0.3097, 0.3324]
data_x = np.linspace(0, 10, 11) # Time points at which the data was measured
# Initial values
x = [1, 0]
k = [1, 0.1]
# My coupled ODE functions with constant reaction constants
def f(x, t):
k = [1, 0.1]
a = x[0]
b = x[1]
k1 = k[0]
k2 = k[1]
dadt = - k1 * a + k2 * b
dbdt = k2 * a - k2 * b
return(dadt, dbdt)
# Trying the function.
y = odeint(f, x, data_x)
print(y)
# My objective function. Only the concentration of `b` is taken into account.
def objective(sim, measured):
# The standard deviation of the data.
# The error is normal distributed with mean zero and `sd = 0.015`
sigma = np.repeat(0.015, len(sim))
j = list(map(operator.sub, sim, measured)) # Pairwise subtraction
j = list(map(operator.truediv, j, sigma)) # Division by sigma
j = list(map(operator.pow, j, np.repeat(2,len(j)))) # Squaring
j = sum(j)
return(j)
# Trying the objective function
j = objective(y[:,1], data_b)
print(j)
# The same ODEs but with reaction constants as parameters
def fb(x, k, t):
a = x[0]
b = x[1]
k1 = k[0]
k2 = k[1]
# The ODEs
dadt = - k1 * a + k2 * b
dbdt = k1 * a - k2 * b
return(dadt, dbdt)
Эта функция возвращает следующую ошибку:
error: Extra arguments must be in a tuple
Как исправить эту ошибку и как мне поступить?Я знаю, что мне нужно объединить функцию ODE и целевую функцию и оптимизировать с помощью функции scipy.optimize.curve_fit
.Но я не знаю, как на самом деле это сделать.