Home > OS >  Calculating the summation parameters separately
Calculating the summation parameters separately

Time:10-15

I am trying to use curve_fitting for a defined function of the form below:

Z = (Rth(1 - np.exp(- x/tau))

I want to calculate 1st four values of parameters Rth and tau. At the moment, it works fine If i use the whole function like this:

 Z = (a * (1- np.exp (- x / b)))   (c * (1- np.exp (- x / d)))  (e * (1- np.exp (- x / f)))    (g * (1- np.exp (- x / f)))

But this is certainly not the nice way to do it for example if i have a really long function with more than 4 exponential terms and I want to get all the parameters. How can I adjust it so that it returns specific number of values of Rth and tau after curve fitting?

For example, If I want to get 16 parameters from a 8 term exponential function, I don't have to write full 8 terms but just a general form and it gives the desired output.

Thank you.

CodePudding user response:

Using least_squares it is quite simple to get an arbitrary sum of functions.

import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import least_squares

def partition( inList, n ):
    return zip( *[ iter( inList ) ] * n )

def f( x, a, b ):
    return a * ( 1 - np.exp( -b * x ) )

def multi_f( x, params ):
    if len( params) % 2:
        raise TypeError
    subparams = partition( params, 2 )
    out = np.zeros( len(x) )
    for p in subparams:
        out  = f( x, *p )
    return out

def residuals( params, xdata, ydata ):
    return multi_f( xdata, params ) - ydata


xl = np.linspace( 0, 8, 150 )
yl = multi_f( xl, ( .21, 5, 0.5, 0.1,2.7, .01 ) )

res = least_squares( residuals, x0=( 1,.9, 1, 1, 1, 1.1 ), args=( xl, yl ) )

print( res.x )
yth = multi_f( xl, res.x )
fig = plt.figure()
ax = fig.add_subplot( 1, 1, 1 )

ax.plot( xl, yl )
ax.plot( xl, yth )

plt.show( )

CodePudding user response:

I managed to solve it by the following way, maybe not the smart way but it works for me.

def func(x,*args):
Z=0
for i in range(0,round(len(args)/2)):
    Z  = (args[i*2] * (1- np.exp (- x / args[2*i 1])))
return Z

Then calling the parameters in a separate function, I can adjust the number of parameters.

def func2(x,a,b,c,d,e,f,g,h):
return func(x,a,b,c,d,e,f,g,h)
popt , pcov = curve_fit(func2,x,y, method = 'trf', maxfev = 100000)

and it works fine for me.

  • Related