I am trying to fit the following function: Detrended SNR into my data. C1, C2 and h are the parameters I need to obtain from the leastsq's method. C1 and C2 are simple but the problem is that my h(t) is in reality: . What I want to obtain are the coefficients hj inside that function (in my case there are 35 different hj's ). This function is the sum of different basis B-Splines each one weighted different and the number of coefficients is equal to the number of knots of the B-Spline. As I want to obtain C1, C2 and h1..35 I do the following:
funcLine = lambda tpl, eix_x: (tpl[0]*np.sin((4*math.pi*np.sum(bsplines_evaluades * np.transpose([tpl[2],tpl[3],tpl[4],tpl[5],tpl[6],tpl[7],tpl[8],tpl[9],tpl[10],tpl[11],tpl[12],tpl[13],tpl[14],tpl[15],tpl[16],tpl[17],tpl[18],tpl[19],tpl[20],tpl[21],tpl[22],tpl[23],tpl[24],tpl[25],tpl[26],tpl[27],tpl[28],tpl[29],tpl[30],tpl[31],tpl[32],tpl[33],tpl[34],tpl[35],tpl[36],tpl[37]]) , axis=0))*eix_x/lambda1) + tpl[1]*np.cos((4*math.pi*np.sum(bsplines_evaluades * np.transpose([tpl[2],tpl[3],tpl[4],tpl[5],tpl[6],tpl[7],tpl[8],tpl[9],tpl[10],tpl[11],tpl[12],tpl[13],tpl[14],tpl[15],tpl[16],tpl[17],tpl[18],tpl[19],tpl[20],tpl[21],tpl[22],tpl[23],tpl[24],tpl[25],tpl[26],tpl[27],tpl[28],tpl[29],tpl[30],tpl[31],tpl[32],tpl[33],tpl[34],tpl[35],tpl[36],tpl[37]]) , axis=0))*eix_x/lambda1))*np.exp(-4*np.power(k, 2)*lambda_big*np.power(eix_x, 2))
func = funcLine
ErrorFunc = lambda tpl, eix_x, ydata: np.power(func(tpl, eix_x) - ydata,2)
tplFinal1, success = leastsq(ErrorFunc, [2, -2, 8.2*np.ones(35)], args=(eix_x, ydata))
tpl(0)=C1, tpl(1)=C2 and tpl(2..35)=my coefficients. bsplines_evaluades is a matrix [35,86000] where each row is the temporal function of each basis b-spline so I weight each row with its individual coefficient, 86000 is the length of eix_x. ydata(eix_x) is the function I want to aproximate. lambda1= 0.1903 ; lambda_big= 2; k=2*pi/lambda1. The output is the same initial parameters which is not logic.
Can anyone help me? I have tried with curvefit too but it does not work.
Data is in : http://www.filedropper.com/data_5>http://www.filedropper.com/download_button.png width=127 height=145 border=0/>
http://www.filedropper.com >online backup storage
EDIT The code right now is:
lambda1 = 0.1903
k = 2 * math.pi / lambda1
lambda_big = 2
def funcLine(tpl, eix_x):
C1, C2, h = tpl[0], tpl(1), tpl[2:]
hsum = np.sum(bsplines_evaluades * h, axis=1) # weight each
theta = 4 * np.pi * np.array(hsum) * np.array(eix_x) / lambda1
return (C1*np.sin(theta)+C2*np.cos(theta))*np.exp(-4*lambda_big*(k*eix_x)**2) # lambda_big = 2
if len(eix_x) != 0:
ErrorFunc = lambda tpl, eix_x, ydata: funcLine(tpl, eix_x) - ydata
param_values = 7.5 * np.ones(37)
param_values[0] = 2
param_values(1) = -2
tplFinal2, success = leastsq(ErrorFunc, param_values, args=(eix_x, ydata))
The problem is that the output parameters don't change with respect the initial ones. Data (x_axis,ydata,bsplines_evaluades): gist.github.com/hect1995/dcd36a4237fe57791d996bd70e7a9fc7 gist.github.com/hect1995/39ae4768ebb32c27f1ddea97e24d96af gist.github.com/hect1995/bddd02de567f8fcbedc752371b47ff71
It's always helpful (to yourself as well as us) to provide a readable example that is complete enough to be runnable. Your example with lambda
s and very long line is definitely not readable, making it very easy for you to miss simple mistakes. One of the points of using Python is to make code easier to read.
It is fine to have spline coefficients as fit variables, but you want to have the np.ndarray of variables to be exactly 1-dimensional. So your parameter array should be
param_values = 8.2 * np.ones(37)
param_values[0] = 2
param_values[1] = -2.
result_params, success = leastsq(errorFunc, param_values, ....)
It should be fine to use curve_fit() too. Beyond that, it's hard to give much help, as you give neither a complete runnable program (leaving lots of terms undefined), nor the output or error messages from running your code.