I am simulating a signal with numpy.sin in python, and i wanna simulate different sampling frequencies, the code is as follows:
import numpy as np
import matplotlib.pyplot as plt
frequencies = [10, 20, 40, 49, 100, 101, 102, 103, 104, 301, 526, 1222] # different sampling frequencies
T = 1 #amount of time for which to simulate the signal in seconds
f = 50 #frequency of the signal
for i in frequencies:
fig, ax1 = plt.subplots(1)
N = T * i # number of samples needed at the sampling frequency for the elapsed time of the signal
linear = np.linspace(0, T, N) # create the data points at which to evaluate the sin
y = np.sin(2 * np.pi * f * linear) # evaluate the sin for the amount of sample points
#creat the graph
ax1.scatter(linear, y)
ax1.set(ylabel = 'Amplitude', xlabel = 'Time in s')
fig.savefig('Freq{}.png'.format(i))
plt.close(fig)
The problem arises with the sampling frequency 101, here the sin function evaluates to ridiculously tiny values, something around 10^(-14) (for all the other values normal graphs come out) (Sin function Evaluated with a sampling frequency of 101 Hz) whilst if I evaluate the sine func by hand by printing out the linear array for sampling frequency 101 Hz, I get normal values. Does somebody know the problem? Maybe and approximation problem of np.sin? maybe the dtype float64 somehow breaks, because the values are kinda sus.
CodePudding user response:
When i
is 101, f * linear
is [0.0, 0.5, 1.0, 1.5, ...]
, so the expression np.sin(2 * np.pi * f * linear)
is sampling the sin
function at multiples of pi
. If you were working with infinite precision, the values would all be 0. These sample points, however, will not be exact multiples of pi
, because of normal floating point imprecision, so the values returned by that expression should be close to 0, but they won't necessarily be exactly 0.