Numpy Синус-поведение для разных массивов - PullRequest
0 голосов
/ 31 января 2020

Привет, в зависимости от массива, который я помещаю в синус, я получаю совершенно другой вывод. test1, test3 - примеры, где это не работает. Что здесь происходит?

test1 = np.sin(50.*2.*np.pi*np.arange(0., 512., dtype=np.float64))
test2 = np.sin(50.*2.*np.pi*np.linspace(0., 512., 512, endpoint=True, dtype=np.float64))
test3 = np.sin(50.*2.*np.pi*np.linspace(0., 512., 512, endpoint=False, dtype=np.float64))

plt.plot(np.arange(0, 512), test1)
plt.plot(np.arange(0, 512), test2)
plt.plot(np.arange(0, 512), test3)
plt.show()

Редактировать: Хорошо, после некоторых дальнейших исследований, возникает актуальная проблема: Используя test1 и test3, я нарушаю теорему Найквиста и выбираю только значения около нуля , Чтобы решить эту проблему, нужно либо увеличить частоту дискретизации, либо уменьшить частоту.

Ответы [ 2 ]

1 голос
/ 31 января 2020

Я думаю, что короткий ответ заключается в том, что вы ожидаете, что numpy.sin будет принимать угол в degrees в качестве аргумента, но в документации указано, что он принимает значение radians.

Это похоже на числа строятся как положено Один из способов визуализации всех трех графиков, т. Е. Test1, test2 и test3, заключается в использовании вспомогательных графиков:

import numpy as np
import matplotlib.pyplot as plt

test1 = np.sin(50.*2.*np.pi*np.arange(0., 512., dtype=np.float64))
test2 = np.sin(50.*2.*np.pi*np.linspace(0., 512., 512, endpoint=True, dtype=np.float64))
test3 = np.sin(50.*2.*np.pi*np.linspace(0., 512., 512, endpoint=False, dtype=np.float64))

fig, axs = plt.subplots(3, sharex=True, sharey=True, gridspec_kw={'hspace': 0})

axs[0].plot(np.arange(0, 512), test1)
axs[1].plot(np.arange(0, 512), test2)
axs[2].plot(np.arange(0, 512), test3)
plt.show()

Когда вы делаете следующее:

print(f"Max of test1: {max(test1)}\nMin of test1: {min(test1)}")
print(f"Max of test2: {max(test2)}\nMin of test2: {min(test2)}")
print(f"Max of test3: {max(test3)}\nMin of test3: {min(test3)}")

Выход

Max of test1: 1.4412955306804755e-11
Min of test1: -1.2978086425591747e-11
Max of test2: 0.9999952753720377
Min of test2: -0.9999952753719793
Max of test3: 1.4412955306804755e-11
Min of test3: -1.2978086425591747e-11

Возможное решение

Для меня проблема выглядит так, будто пределы y на графике находятся в диапазоне от -1 до 1, что слишком высоко для визуализации test1 и test3 ( разборчиво). Если вы хотите взглянуть на test1 и test3 более подробно (на графике), вы можете сделать это:

test1 = np.sin(50.*2.*np.pi*np.arange(0., 512., dtype=np.float64))
test2 = np.sin(50.*2.*np.pi*np.linspace(0., 512., 512, endpoint=True, dtype=np.float64))
test3 = np.sin(50.*2.*np.pi*np.linspace(0., 512., 512, endpoint=False, dtype=np.float64))

fig, axs = plt.subplots(3, sharex=True, sharey=True, gridspec_kw={'hspace': 0})

axs[0].set_ylim((min(test1), max(test1)))
axs[0].plot(np.arange(0, 512), test1)
axs[1].plot(np.arange(0, 512), test2)
axs[2].set_ylim((min(test1), max(test1)))
axs[2].plot(np.arange(0, 512), test3)
plt.show()

Дополнительное объяснение

Согласно документация из numpy.sin, аргумент, принимаемый в качестве x, равен углу в radians, не путать с degrees.

Еще один момент, который следует отметить из numpy.linspace документация заключается в том, что

Обратите внимание, что размер шага изменяется, когда конечная точка имеет значение False.

Вот краткий пример:

np.linspace(0., 512., 5, endpoint=True, dtype=np.float64)

Выход

array([  0., 128., 256., 384., 512.])  

и

np.linspace(0., 512., 5, endpoint=False, dtype=np.float64)

Выход

array([  0. , 102.4, 204.8, 307.2, 409.6])

Теперь, если сделать быструю проверку на numpy.sin для самых высоких значений в каждом массиве, т. Е. 512. и 409.6

np.sin(409.6)

Выход

0.9294631796005904

и

np.sin(512)

Выход

0.07951849401287635

Отсюда и разница.

0 голосов
/ 31 января 2020

Это не синусовое поведение. Я уменьшил размер и напечатал массивы, которые вы передаете, до np.sin().

import numpy as np

SIZE = 4

print(np.arange(0., float(SIZE), dtype=np.float64))
print(np.linspace(0., float(SIZE), SIZE, endpoint=True, dtype=np.float64))
print(np.linspace(0., float(SIZE), SIZE, endpoint=False, dtype=np.float64))

Разница теперь довольно очевидна. Изменяя конечную точку, вы изменяете границы значений, поэтому вы меняете шаг и, следовательно, все значения.

[0. 1. 2. 3.]
[0. 1.33333333 2.66666667 4.]
[0. 1. 2. 3.]

Таким образом, синус дает различный результат.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...