Search code examples
pythonnon-linear-regression

python non-linear regression: choosing of function depended on param


I am currently using "scipy.optimize.curve_fit"

In the equation (piecewise) I fit with, "theta" is calculated by one of the params ("D") first, then the choosing of equations is dependent on "theta" (therefore, dependent on "D"). However, it seems that scipy input the params as a list or something, so it does not choose the right equation for each "D" individually. Instead, it asks me to use "theta.any()" or "theta.all()" which is not what I want.

Is there any module that can do what I want?

Many thanks,

Christopher

import numpy as np
from scipy.optimize import curve_fit
def MahonOldham(t,D:'m^2/s',c:'mM'):
    n=1
    F=96485     #A s / mol
    pi=3.14
    a=12.5*10**-6           # m
    D*=10**-10
    theta=D*t/a**2
    if theta <=1.281: #HERE!!!
        factor=1/(np.sqrt(pi*theta))+1+np.sqrt(theta/(4*pi))-3*theta/25+(3*theta**(3/2))/226
        I=n*pi*F*c*D*a*factor #nA
    else:
        factor=4/pi+8/np.sqrt(pi**5*theta)+25*theta**(-3/2)/2792-theta**(-5/2)/3880-theta**(-7/2)/4500
        I=n*pi*F*c*D*a*factor #nA
        
    return I*10**9

Solution

  • This is the module that you want, you just need to adapt to it's API. The function curve_fit passes to your function arrays for D and c rather than single values, so you need to vectorize MahonOldham (and, please, rename to mahon_oldham, PEP8).

    In particular replace if statement by np.where:

    I = np.where(
        theta <= 1.281, 
        1/(np.sqrt..., # first case
        4/pi+8/np(..., # second case
    )