Ask Your Question
2

How to calibrate two correlated functions simultaneously using Python's scipy.optimize?

asked 2021-09-25 11:00:00 +0000

djk gravatar image

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
2

answered 2023-03-07 23:00:00 +0000

david gravatar image

To calibrate two correlated functions simultaneously using Python's scipy.optimize, you can follow these steps:

  1. Define the two functions that you want to calibrate. Let's call them f1 and f2.
  2. 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.

  3. Set the initial values of params1 and params2.

  4. 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).

  5. 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)
edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account. This space is reserved only for answers. If you would like to engage in a discussion, please instead post a comment under the question or an answer that you would like to discuss

Add Answer


Question Tools

Stats

Asked: 2021-09-25 11:00:00 +0000

Seen: 13 times

Last updated: Mar 07 '23