Python Forum

Full Version: Is there similar function to lsqnonlin (in matlab) in python?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I have done the curve fitting for a specific equation in matlab. I have got the coefficients of the equation. And when I plotted the implicit equation in matlab, it shows a difference between plotted equation and data points. Could anyone explain why?

And the code I used in matlab is

function res = FUN(x,xdata,ydata,zdata)

n = 8
% A = ydata
% B = -xdata
% C = xdata. - ydata
% H = zdata

a1 = x(1)*ydata - x(3)*(xdata - ydata)
b1 = x(2)*(-xdata) - x(1)*(ydata)
c1 = x(3)*(xdata - ydata) - x(2)*(-xdata)
h1 = x(4)*(zdata)

I3 = ((a1.* b1.*c1)/(54))-((b1.*(h1.^2))/(6))
I2 = ((h1.^2)/(3))+((a1.^2 + b1.^2 + c1.^2)/(54))

th = acos(I3/(I2.^(3/2)))
v1 = ((2*th)+pi)/6

an1 = (abs(2*cos(v1)))^n
an2 = (abs(2*cos((2*th+3*pi)/6)))^n
an3 = (abs(2*cos((2*th+5*pi)/6)))^n

res = ((3*I2).^(n/2)) * (an1 + an2 + an3) - (2*(189.32)^8);
%res = ((3*I2).^(n/2)) * (an1 + an2 + an3) - (1);
end

x_10 = [212.60,0,36.03,186.45,231.366,198.50,0,-36.25,-185.20,-210.71,-230.14,-197.98];
y_10 =[0,-211.50,-186.48,-37.51,199.48,231.98,213.38,187.72,37.30,0,-198.96,-230.79];
zdata = [0,0,0,0,0,0,0,0,0,0,0,0];
x0 = [1 1 1 0]; % initial values for a, b and c
[x] = lsqnonlin(@(x)FUN(x,x_10,y_10,zdata),x0)

I got the coefficients of the equation as 0.8198 0.8253 0.8760 0


Then I want to try the same thing in python. I used the following code in python
[xdata =  [2.12536531e+02 -5.25762033e-37  3.76934845e+01 1.86245922e+02 2.32034637e+02  1.99421349e+02 -5.29372192e-37 -3.78800319e+01 -1.84965199e+02 -2.10596796e+02 -2.30791199e+02 -1.98935694e+02]
ydata = [-2.29764844e-36 -2.11076049e+02 -1.85513163e+02 -3.74651905e+01 2.00243718e+02  2.32547563e+02  2.12989518e+02 1.86788046e+02 3.72506794e+01 -2.37575344e-36 -1.99735494e+02 2.31310086e+02]
zdata = [0,0,0,0,0,0,0,0,0,0,0,0]

def barlat(x,p,q,r,s):

    n  = 8
#     % A  = ydata
#     % B  = -xdata
#     % C  = xdata. - ydata
#     % H  = zdata

    a1 = p*ydata - r*(xdata - ydata)
    b1 = q*(-xdata) - p*(ydata)
    c1 = r*(xdata - ydata) - q*(-xdata)

    h1 = s*zdata

#     I3 = ((a1.* b1.*c1)/(54))-((b1.*(h1.^2))/(6))
#     I2 = ((h1.^2)/(3))+((a1.^2 + b1.^2 + c1.^2)/(54))

    a2 = np.multiply(a1,b1)
    a3 = np.multiply(a2,c1)
    h2 = np.multiply(h1,h1)
    a4 = np.multiply(a1,a1)
    b4 = np.multiply(b1,b1)
    c4 = np.multiply(c1,c1)


    I3 = ((a3)/(54))
    I2 = ((a4 + b4 + c4)/(54))  

    th = np.arccos(np.divide(I3,I2**(3/2)))
    v1 = ((2*th)+ np.pi)/6

    an1 = (np.abs(2*np.cos(v1)))**n
    an2 = (np.abs(2*np.cos((2*th+3*np.pi)/6)))**n
    an3 = (np.abs(2*np.cos((2*th+5*np.pi)/6)))**n

    res = ((3*I2)**(n/2)) * (an1 + an2 + an3) - (2*(189.32)**8);
#     %res = ((3*I2)^(n/2)) * (an1 + an2 + an3) - (1);

    return res

popt, pcov = curve_fit(barlat, xdata, ydata,p0= (1,1,1,0))
popt
Error:
[py:26: RuntimeWarning: invalid value encountered in arccos py:794: OptimizeWarning: Covariance of the parameters could not be estimated category=OptimizeWarning) ]

(May-04-2019, 11:51 AM)Jay_Nerella Wrote: [ -> ]I have done the curve fitting for a specific equation in matlab. I have got the coefficients of the equation. And when I plotted the implicit equation in matlab, it shows a difference between plotted equation and data points. Could anyone explain why?

And the code I used in matlab is

function res = FUN(x,xdata,ydata,zdata)

n = 8
% A = ydata
% B = -xdata
% C = xdata. - ydata
% H = zdata

a1 = x(1)*ydata - x(3)*(xdata - ydata)
b1 = x(2)*(-xdata) - x(1)*(ydata)
c1 = x(3)*(xdata - ydata) - x(2)*(-xdata)
h1 = x(4)*(zdata)

I3 = ((a1.* b1.*c1)/(54))-((b1.*(h1.^2))/(6))
I2 = ((h1.^2)/(3))+((a1.^2 + b1.^2 + c1.^2)/(54))

th = acos(I3/(I2.^(3/2)))
v1 = ((2*th)+pi)/6

an1 = (abs(2*cos(v1)))^n
an2 = (abs(2*cos((2*th+3*pi)/6)))^n
an3 = (abs(2*cos((2*th+5*pi)/6)))^n

res = ((3*I2).^(n/2)) * (an1 + an2 + an3) - (2*(189.32)^8);
%res = ((3*I2).^(n/2)) * (an1 + an2 + an3) - (1);
end

x_10 = [212.60,0,36.03,186.45,231.366,198.50,0,-36.25,-185.20,-210.71,-230.14,-197.98];
y_10 =[0,-211.50,-186.48,-37.51,199.48,231.98,213.38,187.72,37.30,0,-198.96,-230.79];
zdata = [0,0,0,0,0,0,0,0,0,0,0,0];
x0 = [1 1 1 0]; % initial values for a, b and c
[x] = lsqnonlin(@(x)FUN(x,x_10,y_10,zdata),x0)

I got the coefficients of the equation as 0.8198 0.8253 0.8760 0


Then I want to try the same thing in python. I used the following code in python
[xdata =  [2.12536531e+02 -5.25762033e-37  3.76934845e+01 1.86245922e+02 2.32034637e+02  1.99421349e+02 -5.29372192e-37 -3.78800319e+01 -1.84965199e+02 -2.10596796e+02 -2.30791199e+02 -1.98935694e+02]
ydata = [-2.29764844e-36 -2.11076049e+02 -1.85513163e+02 -3.74651905e+01 2.00243718e+02  2.32547563e+02  2.12989518e+02 1.86788046e+02 3.72506794e+01 -2.37575344e-36 -1.99735494e+02 2.31310086e+02]
zdata = [0,0,0,0,0,0,0,0,0,0,0,0]

def barlat(x,p,q,r,s):

    n  = 8
#     % A  = ydata
#     % B  = -xdata
#     % C  = xdata. - ydata
#     % H  = zdata

    a1 = p*y - r*(x - y)
    b1 = q*(-x) - p*(y)
    c1 = r*(x - y) - q*(-x)

    h1 = s*zdata

#     I3 = ((a1.* b1.*c1)/(54))-((b1.*(h1.^2))/(6))
#     I2 = ((h1.^2)/(3))+((a1.^2 + b1.^2 + c1.^2)/(54))

    a2 = np.multiply(a1,b1)
    a3 = np.multiply(a2,c1)
    h2 = np.multiply(h1,h1)
    a4 = np.multiply(a1,a1)
    b4 = np.multiply(b1,b1)
    c4 = np.multiply(c1,c1)


    I3 = ((a3)/(54))
    I2 = ((a4 + b4 + c4)/(54))  

    th = np.arccos(np.divide(I3,I2**(3/2)))
    v1 = ((2*th)+ np.pi)/6

    an1 = (np.abs(2*np.cos(v1)))**n
    an2 = (np.abs(2*np.cos((2*th+3*np.pi)/6)))**n
    an3 = (np.abs(2*np.cos((2*th+5*np.pi)/6)))**n

    res = ((3*I2)**(n/2)) * (an1 + an2 + an3) - (2*(189.32)**8);
#     %res = ((3*I2)^(n/2)) * (an1 + an2 + an3) - (1);

    return res

popt, pcov = curve_fit(barlat, xdata, ydata,p0= (1,1,1,0))
popt
Error:
[py:26: RuntimeWarning: invalid value encountered in arccos py:794: OptimizeWarning: Covariance of the parameters could not be estimated category=OptimizeWarning) ]
Hello Jay_Nerella,

presently I also use the curve_fit function of python so I thought I may possibly help you. First, I detected some syntax faults in your python code:

"[xdata" in the beginning should be only "xdata".

You should use np.arrays instead of lists for the x-, y-, zdata:
xdata =  np.array([2.12536531e+02,-5.25762033e-37, 3.76934845e+01,1.86245922e+02,2.32034637e+02, 1.99421349e+02,-5.29372192e-37,-3.78800319e+01,-1.84965199e+02,-2.10596796e+02,-2.30791199e+02,-1.98935694e+02])
(At least with my python2.7 interpreter I had change these lines.)

Then I realised that your function barlat(x,p,q,r,s) does not use the variable x within its definition, which it definitely should. For me is also unclear what data the output of the function should correspond to. Normally this is ydata. But you use ydata within your definition of barlat(x,p,q,r,s), so it cannot also be the data corresponding to the output. Again you also use xdata within the definition of barlat(x,p,q,r,s), normally you use xdata only when performing the curve_fit function.

So think about the procedure of curve fitting again. First you have a function f(x,p,q,r,s), where x can be multidimensional and p, q, r, s are parameters. Then you have data xdata (input) and ydata (output) which you want to describe by the function. So in other words you want to find parameters p, q, r, s such that f(xdata,p,q,r,s) = ydata "holds as best as it can be".

Hope this is useful.

feli_x