Минимальный пример:
import numpy as np
import matplotlib.pyplot as plt
x_ = np.arange(2000)
frequency = 2 * np.pi
sine = np.sin(x_*frequency)
plt.plot(x_, sine)
plt.show()
производит следующий сюжет:
Умножение np.sin(x_*frequency)
приводит к очень запутанному поведению. Как выходной сигнал синусоидальной функции может быть меньше -1 и показывать несколько амплитуд?
Если np.sin(x_/frequency)
, то это показывает ожидаемое поведение:
Внимательно прочтите ось. Там написано 1e-12
. Все эти значения близки к 0. Теоретически все значения должны быть ровно 0.
Отвечая на вопрос в заголовке: Нет. 😁
Обратите внимание, что оно не равно нулю, поскольку входное значение не совсем равно 2*PI*x_
, а немного меньше или больше из-за округления FP. Чем больше значение, тем больше округление, тем больше погрешность вывода, даже если Numpy вычисляет sin
с точностью 1 ULP (и округляет числа идеально).
@tamtam_ Пожалуйста, внимательно прочитайте комментарий Lastchance (подробнее), так как в нем есть ответ: sin(2.pi.n)=0 for integer n
Математически sin(pi) = 0
, но для точного значения числа Пи требуется бесконечное количество цифр. Другими словами, np.pi
, имеющее конечное число цифр, представляет собой несколько неточное значение числа Пи. Это вызывает ошибку. И когда вы умножаете np.pi
на n, эта ошибка также умножается на n.
Возможно, для вас будет полезнее никогда не предполагать, что причиной ваших проблем является библиотечная функция, которая существует уже много лет и используется миллионами людей. Делая такое предположение, вы блокируете свой разум, пытаясь найти истинную причину в вашем собственном коде и логике.
Вы думаете, что рисуете непрерывную функцию, но все точки вектора x_
имеют форму (integer) * 2 pi
. А грех кратного 2пи равен 0.
Таким образом, баллы, которым вы присваиваете plt.plot
, — это только баллы, где грех равен 0.
Они не равны 0, потому что np.pi
— это не совсем число «пи», и вы умножаете эту ошибку на 2000.
Вы наблюдаете, что ошибка np.sin(2000 * 2 * np.pi)
имеет порядок 1e-12
или 0,000000000001, если вы предпочитаете такое обозначение.
Если вы хотите наблюдать кривую, которая больше похожа на кривую греха, попробуйте включить в вектор x нецелые числа:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0,10,1000) # 1000 points in interval [0, 10]
y = np.sin(x * 2 * np.pi)
plt.plot(x,y)
С точностью до плавающей запятой ваши первые результаты будут меньше -1e-12, но не меньше -1. Посмотрите внимательно на верхнюю часть шкалы оси Y на вашем графике. sin(2.pi.n)=0 для целого числа n.