0

I'm trying to fit a sine curve to data I imported from a .mat file.

from scipy.io import loadmat
data=loadmat('TP4.mat')
x_data=data['x']
y_data=data['y']
def TEST(x,a,b):
return (a*np.sin(b*x))
params2,params_covariance2=optimize.curve_fit(TEST,x_data,y_data)

I've been searching why for an hour now, but it returns me the error :

 params2,params_covariance2=optimize.curve_fit(TEST,x_data,y_data)
File "D:\python\lib\site-packages\scipy\optimize\minpack.py", line 784, in curve_fit
res = leastsq(func, p0, Dfun=jac, full_output=1, **kwargs)

 File "D:\python\lib\site-packages\scipy\optimize\minpack.py", line 414, in leastsq
raise TypeError('Improper input: N=%s must not exceed M=%s' % (n, m))

TypeError: Improper input: N=2 must not exceed M=1

Does someone have the answer to why it keeps doing that with the curve_fit ?

x_data is a array (1,50) :

[[-5.         -4.79591837 -4.59183673 -4.3877551  -4.18367347 -3.97959184
  -3.7755102  -3.57142857 -3.36734694 -3.16326531 -2.95918367 -2.75510204
  -2.55102041 -2.34693878 -2.14285714 -1.93877551 -1.73469388 -1.53061224
  -1.32653061 -1.12244898 -0.91836735 -0.71428571 -0.51020408 -0.30612245
  -0.10204082  0.10204082  0.30612245  0.51020408  0.71428571  0.91836735
   1.12244898  1.32653061  1.53061224  1.73469388  1.93877551  2.14285714
   2.34693878  2.55102041  2.75510204  2.95918367  3.16326531  3.36734694
   3.57142857  3.7755102   3.97959184  4.18367347  4.3877551   4.59183673
   4.79591837  5.        ]]

and y_data is an array (1,50) too :

[[ 1.93850755  3.90748334  0.74775799  3.80239638  3.32772828  2.71107852
   2.85786376  2.50109072  2.62484054  0.11701355 -1.34835766 -1.03896612
  -1.82007581 -1.49086175 -2.56849896 -4.68713822 -3.15843002 -2.77910422
  -2.87940036  1.73778484  0.31566242  1.81945211  2.58367122  3.26765109
   1.79831117  3.35824518  4.25703245  0.96006812  1.24266396  0.75338212
  -0.70009445 -1.12690812 -1.09354647 -3.46942727 -3.67550846 -4.53297036
  -2.55420957 -2.87671367 -2.33624323 -1.37104854  1.36564919  1.61563281
   2.46671249  2.6525523   2.4522091   2.96971773  2.56662355  3.35746594
   2.03000529  2.81887444]]
Mr. T
  • 8,325
  • 9
  • 23
  • 44
J-v Foury
  • 1
  • 1
  • Since this problem does not occur with random test data, I suggest you provide a toy dataset that reproduces this error. Are you sure your input data are 1D arrays and of sufficient length? – Mr. T Dec 11 '20 at 12:25
  • x_data is an array (1,50) : and so is y_data – J-v Foury Dec 11 '20 at 12:30
  • Ah, that's why. [Reshape your data](https://stackoverflow.com/questions/30668223/how-to-change-array-shapes-in-in-numpy#30668375) to `(50,)`, and all will be good. Well, not all. But this specific error message will not appear. It would be better to read in the data differently from the start but I don't know `loadmat`, so no advice from my side. [Here is a good explanation of array shapes.](https://stackoverflow.com/a/22074424/8881141) – Mr. T Dec 11 '20 at 12:51

1 Answers1

0

Your arrays are in an unexpected shape, so we have to reshape them. Since np.reshape() creates a different view, we have to use np.shape()

from scipy import optimize
import numpy as np
from matplotlib import pyplot as plt

def TEST(x,a,b):
    return a*np.sin(b*x)

#random test data
np.random.seed(1234)
n=100
x_data = np.linspace(0, 10, n)
y_data = TEST(x_data, 0.2, -0.4) + np.random.normal(scale=0.01,size=n)    
#your data structure
x_data.shape = (1, n)
y_data.shape = (1, n)
#print(x_data)
#print(y_data)

#changing the shape of the data for scipy
#if you remove this block you can reproduce your error message
x_data.shape = (n,)
y_data.shape = (n,)
#print(x_data)
#print(y_data)    

params2,params_covariance2=optimize.curve_fit(TEST,x_data,y_data, p0=[0.1, 0.1])    
print(params2)

y_fit = TEST(x_data, *params2)    
plt.plot(x_data, y_data, label="values")
plt.plot(x_data, y_fit, label="fit")

plt.legend()
plt.show()

Output

[ 0.1992707  -0.40013289]

enter image description here

Mr. T
  • 8,325
  • 9
  • 23
  • 44
  • It worked perfectly ! Thank you ! :) – J-v Foury Dec 11 '20 at 14:06
  • Glad this problem was solved so easily. [Please consider accepting the answer](https://stackoverflow.com/help/someone-answers). I hope you noticed also that I changed the start values by providing `p0`. Often necessary when the fit does not converge with the standard start value of `1`. – Mr. T Dec 11 '20 at 14:15