I am trying to find the local maxima of the function f(x) = (sin(x)/x)^2.
For approximate solutions, I initialised two variables x and y and first plotted a graph to have a visual representation.
x = np.linspace(-20.0, 20.0, num=int((20+20)/0.01))
y = np.power(np.sin(x)/x, 2)
plt.plot(x, y, 'r.', markersize= 1)
plt.show()
This shows graph.
I then tried to create an algorithm to find the Maxima:
def returnMaxima(num, x, y):
"""
number, np.array, np.array -> list
num: number of maxima needed | x: x 1D array | y: y 1D array
returns [[x1,y1], [x2,y2]...] in descending order of y
"""
allMaximaPoints = [] # stores all Maxima points
reqMaximaPoints = [] # stores num Maxima points
for i in range(y.size):
# for first y value
if i == 0:
if y[i] > y[i+1]:
allMaximaPoints += [[x[i], y[i]], ]
# for last y value
elif i == y.size - 1:
if y[i] > y[i-1]:
allMaximaPoints += [[x[i], y[i]], ]
# for rest y values
else:
if y[i] > y[i-1] and y[i] > y[i+1]:
allMaximaPoints += [[x[i], y[i]], ]
# extract largest maximas from allMaximaPoints
while num > 0:
reqMaximaPoints += [max(allMaximaPoints, key=lambda item:item[1]),]
del allMaximaPoints[allMaximaPoints.index(max(allMaximaPoints, key=lambda item:item[1]))]
num -= 1
return reqMaximaPoints
When I tried returnMaxima(2, x, y) I get [[-4.4961240310077528, 0.04719010162459622],
[4.4961240310077528, 0.04719010162459622]].
This is incorrect as it skipped the local maxima at x = 0. I suspect it is because the y[i-1] and y[i+1] values adjacent to the maxima at y[i] at x=0 is approximately equal to y[i] causing the code
else:
if y[i] > y[i-1] and y[i] > y[i+1]:
allMaximaPoints += [[x[i], y[i]], ]
to not account for that point. This is because when I changedx = np.linspace(-20.0, 20.0, num=int((20+20)/0.01)) to say x = np.linspace(-20.0, 20.0, num=int((20+20)/0.1)) i.e. larger steps in x, the local maxima at x=0 is correctly found. However, even if I changed the > signs in the above code to >=, that maxima at x=0 is still not counted.
Why is that so? How should I improve my code to get the correct results? Thanks!

peakutils: pypi.python.org/pypi/PeakUtils . It allows you to select sensitivity and threshold to make it robust to noise.