Search code examples
pythonmatlabscipyleast-squares

Matlab fit NonlinearLeastSquares for Python


I rewrite code written in Matlab for Python and I can´t resolve correctly the fit function in Python. Code in Matlab:

y = *Array 361x1*;
x = *Array 361x1*;
y1 = *Single value 1x1*;
x1 = *Single value 1x1*;

fo = fitoptions('Method','NonlinearLeastSquares','Lower',[-Inf,-Inf],'Upper',[Inf, Inf],'Startpoint',[0.0,0.0]);

ft = fittype( @(A,B, x) A.*x.^2 + B.*x + y1 - A.*x1.^2 - B.*x1, 'independent','x','dependent','y','options',fo);

[fitobject,gof,out] = fit(x,y,ft);

A = fitobject.A;
B = fitobject.B;

I tried the solution in Python through Scipy Least Squares and based on this article. I wrote the following code:

ft = least_squares(lambda coeffs: coeffs[0]*x**2 + coeffs[1]*x + y1 - coeffs[0]*x1**2 - coeffs[1]*x1, [0, 0], bounds=([-np.inf, -np.inf], [np.inf, np.inf]))
print(ft('x'))

Obviously it is not correct (array y is not considered in Python code) and I get different values for coefficients A and B. I´ve already tried difrferent functions like curve%fit, etc. But with no result...


Solution

  • You could use scipy.optimize's curve_fit. Assuming x and y are numpy.ndarrays containing the data:

    from scipy.optimize import curve_fit
    
    def fitme(x, *coeffs_and_args):
        A, B, x1, y1 = coeffs_and_args
        return A*x**2 + B*x + y1 - A*x1**2 - B*x1 
    
    popt, pcov = curve_fit(lambda  x, A, B: fitme(x, A, B, x1, y1), x, y)
    

    Then the array popt contains the optimal values for the parameters and pcov the estimated covariance of popt.