1 | initial version |
To calibrate two correlated functions simultaneously using Python's scipy.optimize, you can follow these steps:
f1
and f2
.Define a function that takes in two arrays of parameters (params1
and params2
) and returns the difference between the observed and predicted values of the two functions. This function will be the objective function that scipy.optimize will minimize. For example:
def objective(params):
params1 = params[:n1]
params2 = params[n1:]
# Calculate predicted values of f1 and f2 using params1 and params2
predicted_f1 = f1(params1, X)
predicted_f2 = f2(params2, X)
# Calculate the difference between the observed and predicted values of f1 and f2
diff_f1 = y1 - predicted_f1
diff_f2 = y2 - predicted_f2
# Return the sum of the squared differences
return np.sum(diff_f1**2) + np.sum(diff_f2**2)
In this example, n1
is the number of parameters in params1
, X
is the input data, y1
is the observed values of f1
, and y2
is the observed values of f2
.
Set the initial values of params1
and params2
.
Call scipy.optimize.minimize
with the objective
function and the initial parameter values. For example:
from scipy.optimize import minimize
n1 = 2 # number of parameters in params1
initial_params = np.concatenate((params1_init, params2_init))
result = minimize(objective, initial_params, method='Nelder-Mead')
In this example, params1_init
and params2_init
are the initial values of params1
and params2
, respectively. The method
argument specifies the optimization algorithm to use (in this case, Nelder-Mead).
Extract the optimized parameter values from result.x
and use them to generate the predicted values of f1
and f2
.
Here's some sample code that demonstrates this approach:
import numpy as np
from scipy.optimize import minimize
# Define the two functions to calibrate
def f1(params, X):
a, b = params
return a*X + b
def f2(params, X):
c, d = params
return c*X + d
# Define the objective function to minimize
def objective(params):
params1 = params[:2]
params2 = params[2:]
predicted_f1 = f1(params1, X)
predicted_f2 = f2(params2, X)
diff_f1 = y1 - predicted_f1
diff_f2 = y2 - predicted_f2
return np.sum(diff_f1**2) + np.sum(diff_f2**2)
# Set the initial parameter values
params1_init = [1, 0]
params2_init = [1, 0]
# Generate some toy data
X = np.linspace(0, 10, 11)
y1 = 2*X + 1 + np.random.normal(0, 1, size=len(X))
y2 = 3*X - 2 + np.random.normal(0, 1, size=len(X))
# Call scipy.optimize.minimize
n1 = len(params1_init)
initial_params = np.concatenate((params1_init, params2_init))
result = minimize(objective, initial_params, method='Nelder-Mead')
# Extract the optimized parameter values
params1_opt = result.x[:n1]
params2_opt = result.x[n1:]
# Generate the predicted values of f1 and f2 using the optimized parameter values
predicted_f1 = f1(params1_opt, X)
predicted_f2 = f2(params2_opt, X)
# Print the optimized parameter values and the predicted values of f1 and f2
print('Optimized params1:', params1_opt)
print('Optimized params2:', params2_opt)
print('Predicted f1:', predicted_f1)
print('Predicted f2:', predicted_f2)