Home > other >  How to deal with functions that approach infinity in NumPy?
How to deal with functions that approach infinity in NumPy?

Time:12-28

In a book on matplotlib I found a plot of 1/sin(x) that looks similar to this one that I made:

enter image description here

I used the domain

input = np.mgrid[0 : 1000 : 200j]

What confuses me here to an extreme extent is the fact that the sine function is just periodic. I don't understand why the maximal absolute value is decreasing. Plotting the same function in wolfram-alpha does not show this decreasing effect. Using a different step-amount

input = np.mgrid[0 : 1000 : 300j]

delivers a different result:

enter image description here

where we also have this decreasing tendency in maximal absolute value.

So my questions are:

  1. How can I make a plot like this consistent i.e. independent of step-size/step-amount?
  2. Why does one see this decreasing tendency even though the function is purely periodic?

CodePudding user response:

The period of the sine function is rather higher than what is plotted, so what you’re seeing is aliasing from the difference in the sampling frequency and some multiple of the true frequency. Since one of the roots is at 0, the smallest discrepancy that happens to exist between the first few samples and a multiple of π itself scales linearly away from 0, producing a 1/x envelope.

It’s possible for some one of the quasi-periodic sample sequences to eventually land even closer to nπ, producing a more complicated pattern like that in the second plot.

CodePudding user response:

Why does one see this decreasing tendency even though the function is purely periodic?

Keep in mind that actually at every multiple of pi the function goes to infinity. And the size of the jump displayed actually only reflects the biggest value of the sampled values where the function still made sense. Therefore you get a big jump if you happen to sample a value were the function is big but not too big to be a float.

To be able to plot anything matplotlib throws away values that do not make sense. Like the np.nan you get at multiples of pi and ±np.infs you get for values very close to that. I believe what happens is that one step size away from zero you happen to get a value small enough not to be thrown away but still very large. While when you get to pi and multiples of it the largest value gets thrown away.

How can I make a plot like this consistent i.e. independent of step-size/step-amount?

You get strange behaviour around the values where your function becomes unreasonable large. Just pick a ylimit to avoid plotting those crazy large values.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.transforms import Bbox

x = np.linspace(10**-10,50, 10**4)
plt.plot(x,1/np.sin(x))
plt.ylim((-15,15))

enter image description here

  • Related