'Finding the zeros of a two term exponential function with python
I am attempting to find the how long it takes for a signal to decay from 90% of its maximum initial value to 10% of its maximum value using python. I have used curve fit and found what appears to be a pretty good fit to my scaled up data (data is depicted as red dots, the plot of the curve fit equation is depicted as the dotted blue line).
However the decay times themselves seem a little bit off when calculated by the program; I have gone through and checked the math for my data individually for these signals and the value should be something around 350 ms. The reported values coming out of the program are around 800 ms.
Plot and code are below
import numpy as np
import os
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from scipy.optimize import fsolve
from scipy.optimize import brentq
import statistics
def func (t,ts,b,c,d,f,g):# this code fits the data to a fucniton with two exponential terms
#ts= start time, time= time from data, a,b,c,d are coefficients to be found.
#return a+b*np.exp(-c*(time-ts))+d*np.exp(-d*(time-ts))old equation, disabled 5 06 2022
y=b*np.exp(-c*(t-ts))+d*np.exp(-f*(t-ts))+g
return y
def func2(t,ts,b,c,d,f,g,time):
y=b*np.exp(-c*(t-ts))+d*np.exp(-f*(t-ts))+g-time
return y
#0.0005*10**-11
def fitting (array):
for m in range(len(array)):
smoothX=np.linspace(array[m][0],array[m][0]+1.2,1000) #range of points over which fit function is to be plotted
if m%2==0:
initTime=array[m][0]# intial time value on plot
valArray=np.array(array[m+1])#raw singal values
valArray*=10**10#scaled signal values
listForPlot=list(valArray)#convert scaled signal values to list for plotting
popt,pcov=curve_fit(func,array[m],listForPlot,
p0=[initTime,1,40,0.5,1,2],bounds=(-100,100))
#fitting data to curve
plt.figure()
plt.title('Curve fit')
plt.ylabel('current x 10^10 (A)')
plt.xlabel('time (s)')
plt.plot(array[m],listForPlot,'ro',label='data')
plt.plot(array[m],func(array[m],popt[0],popt[1]\
,popt[2],popt[3],popt[4],\
popt[5]),linestyle='--',linewidth=2,color='black')
plt.plot(smoothX,func(smoothX,popt[0],popt[1]\
,popt[2],popt[3],popt[4],\
popt[5]),linestyle='--',linewidth=2,color='blue',label="smooth fit")
initVal=listForPlot[0]
perCent90=brentq(func2,initTime,initTime+0.6,\
args=(initTime,popt[1],popt[2],popt[3],popt[4],popt\[5],initVal*0.1))
#finds the time for the current to decrease to 10% initial value
perCent10=brentq(func2,initTime,initTime+0.6,\
args=(initTime,popt[1],popt[2],popt[3],popt[4],popt\[5],initVal*0.9))
#finds the time for the current to decreease to 90% initial value
plt.axhline(y=0.9*initVal, color='g',linestyle='-',label='90%')#known 90% value
plt.axhline(y=0.1*initVal,color='k', linestyle='-',label='10%')#known 10% value
decaytime=func(perCent10,popt[0],popt[1],popt[2],popt[3],popt[4],popt[5])\
-func(perCent90,popt[0],popt[1],popt[2],popt[3],popt[4],popt[5])
#decay time calculation
plt.plot(perCent10,func(perCent10,initTime,popt[1],popt[2],popt[3],popt[4],popt[5]),'go',label='90% (calculated)')
plt.plot(perCent90,func(perCent90,initTime,popt[1],popt[2],popt[3],popt[4],popt[5]),'ko',label='10% (calculated)')
decaytimes.append(decaytime)
plt.legend()
dataSort(t,datax,datay,fallMasterList,count)
fitting(fallMasterList)][2]
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
