I'm trying to fit a double broken profile function which consists of the arctangent function. My code doesn't seem to be working:
XX=np.linspace(7.5,9.5,16)
YY=np.asarray([7,7,7,7.1,7.3,7.5,8.4,9,9.3,9.6,10.3,10.2,10.4,10.5,10.5,10.5])
def func_arc(x,a1,a2,a3,b1,b2,b3,H1,H2):
beta=0.001
w1=np.zeros(len(x))
w2=np.zeros(len(x))
for i in np.arange(0,len(x)):
w1[i]=(((math.pi/2)+atan((x[i]-H1)/beta))/math.pi)
w2[i]=(((math.pi/2)+atan((x[i]-H2)/beta))/math.pi)
y=(a1*x[i]+b1)*(1-w1[i])+(a2*x[i]+b2)*w1[i]*(1-w2[i])+(a3*x+b3)*w2[i]
return(y)
Where the a
and b
terms are slope and zero-point values of the linear regressions.
The w
terms are used to switch the domain.
I take into account the following restrictions for continuity (H1 y H2) and restrict parameters:
mask=(XX<=8.2)
mask2=(XX>8.2) & (XX<9)
mask3=(XX>=9)
l1=np.polyfit(XX[mask], YY[mask], 1)
l2=np.polyfit(XX[mask2], YY[mask2], 1)
l3=np.polyfit(XX[mask3], YY[mask3], 1)
H1=(l2[1]-l1[1])/(l1[0]-l2[0])
H2=(l3[1]-l2[1])/(l2[0]-l3[0])
p0=[l1[0],l2[0],l3[0],l1[1],l2[1],l3[1],H1,H2]
popt_arc1, pcov_arc1 =curve_fit(func_arc, XX, YY,p0)
I obtain a single line instead of a broken profile (S-shape).
What I obtain:
Here is my version. Due to the fact that the linear functions should connect continuously, the parameters are actually less. The offsets
b2
andb3
, hence, are not fitted, but are a result of reacquiring the linear function to meet at the transitions. Moreover, one might argue that the data does not justify a slope in the beginning or end. This could be justified / checked via the reduced chi-square or other statistical methods.Results look okey for me.