简体   繁体   中英

Matlab polyval function with three outputs equivalent in Python/ Numpy

I have that code in Matlab that I need to bring to Python.

x_cord = [58.2986 39.5842 23.0044 10.9427 3.0465]
y_cord = [0.9600 0.9700 0.9800 0.9900 1.0000]
[p,S,mu]=polyfit(x_cord, y_cord, 3); % p = [-0.002120716372462 0.004361710897014 -0.014104050472739 0.977080254892409]
result=polyval(p, 16.574651718139650, [], mu); % result = 0.9848

When I use numpy.polyfit(x_cord, y_cord, 3) I get different result than in example. Also I couldn't find that kind of polyval (with more than two input parameters) in Numpy.

Matlab and Numpy results are identical when I ask one return parameter.

The numpy and scipy functions for fitting a polynomial do not include the option of automatically scaling the input like the Matlab function does.

First, here's how you can fit your data without the scaling:

In [39]: x_cord = [58.2986, 39.5842, 23.0044, 10.9427, 3.0465]

In [40]: y_cord = [0.9600, 0.9700, 0.9800, 0.9900, 1.0000]

In [41]: c = np.polyfit(x_cord, y_cord, 3)

In [42]: c
Out[42]: 
array([ -1.91755884e-07,   2.43049234e-05,  -1.52570960e-03,
         1.00431483e+00])

In [43]: p = np.poly1d(c)

In [44]: p(16.574651718139650)
Out[44]: 0.98483061114799408

In [45]: xx = np.linspace(0, 60, 500)

In [46]: plot(xx, p(xx))
Out[46]: [<matplotlib.lines.Line2D at 0x110c8d0f0>]

In [47]: plot(x_cord, y_cord, 'o')
Out[47]: [<matplotlib.lines.Line2D at 0x10d6f8390>]

情节

The numpy calculation agrees with Wolfram Alpha .


Here's how you can get pretty close to the actual Matlab calculation.

For convenience, convert x_cord from a list to a numpy array.

In [64]: x_cord = np.array(x_cord)

Compute the mean and standard deviation of x_cord .

In [65]: mu = np.mean(x_cord)

In [66]: std = np.std(x_cord, ddof=1)

Call np.polyfit() , using the shifted and scaled version of x_cord .

In [67]: cscaled = np.polyfit((x_cord - mu)/std, y_cord, 3)

These values are pretty close to the array p shown in the comment in the Matlab code.

In [68]: cscaled
Out[68]: array([-0.00212068,  0.00436168, -0.01410409,  0.97708027])

Create a poly1d object that can be called.

In [69]: pscaled = np.poly1d(cscaled)

Inputs to pscaled must be shifted and scaled using mu and std .

In [70]: pscaled((16.574651718139650 - mu)/std)
Out[70]: 0.98483061114799486

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM