Stefan Steinerberger defines “an amusing sequence of functions” in [1] by
Here’s a plot of f30(x):
As you can see, fn(x) has a lot of local minima, and the number of local minima increases rapidly with n.
Here’s a naive attempt to produce the plot above using Python.
from numpy import sin, pi, linspace import matplotlib.pyplot as plt def f(x, n): return sum( abs(sin(k*pi*x))/k for k in range(1, n+1) ) x = linspace(0, 1) plt.show()
This produces the following.
The code above doesn’t specify how finely to divide the interval [0, 1], and by default linspace
will produce 50 evenly spaced points. In the example above we need a lot more points. But how many? This is not a simple question.
You could try more points, adding a third argument to linspace
, say 1000. That will produce something that looks more like the first plot, but is the first plot right?
The first plot was produced by the Mathematica statements
f[x_, n_] := Sum[Abs[Sin[Pi k x]/k], {k, 1, n}] Plot[f[x, 30], {x, 0, 1}]
Mathematica adaptively determines how many plotting points to use. It tries to detect when a function is changing rapidly in some region and allocate more points there. The function that is the subject of this post makes a good test case for such automated refinement.
Often Mathematica does a good enough job automatically, but sometimes it needs help. The Plot
function takes additional parameters like PlotPoints
and MaxRecursion
that you can use to tell Mathematica to work harder.
It would be an interesting exercise to make a high quality plot of fn for some moderately large n, making sure you’ve captured all the local minima.
[1] Stefan Steinerberger. An Amusing Sequence of Functions. Mathematics Magazine, Vol. 91, No. 4 (October 2018), pp. 262–266
The post Plotting a function with a lot of local minima first appeared on John D. Cook.