【发布时间】:2021-02-24 08:27:37
【问题描述】:
我目前正在尝试计算多个生成的正弦波的总和,生成如下:
np.sin(2 * np.pi * freq * np.arange(N) / SAMPLE_RATE)
其中N 是我要生成的样本数,SAMPLE_RATE 是以 Hz 为单位的采样率。我意识到的一件巧妙的事情是,如果我为freq 传递一个列向量,它会由于广播而生成一个样本矩阵,其中每一行对应于单个频率的单个正弦波,每列对应于每个频率的单个采样点。举个例子:
freq = np.array([[1,2,3,4]]).T
SAMPLE_RATE = 1
N = 5
print(np.sin(2 * np.pi * freq * np.arange(N) / 20))
输出
[[ 0. 0.30901699 0.58778525 0.80901699 0.95105652]
[ 0. 0.58778525 0.95105652 0.95105652 0.58778525]
[ 0. 0.80901699 0.95105652 0.30901699 -0.58778525]
[ 0. 0.95105652 0.58778525 -0.58778525 -0.95105652]]
如果沿 0 轴求和,则产生所有正弦波的总和。但是,这会占用O(N * len(freq)) 空间,当 N 和 freq 很大时,这是不可接受的。有没有办法在O(N) 空间中做到这一点而不牺牲最后的矢量化求和?这个问题应该推广到如果一个矩阵是通过任何广播操作生成的,只是立即被求和折叠。
【问题讨论】:
-
用
numba之类的东西编写你自己的代码。您描述的权衡是使用一组有限的标准工具的成本。 -
如果
freq是单调的,可能会有一些傅立叶级数或泰勒级数展开会有所帮助,但对于Mathematics 堆栈来说,这更像是一个问题——刚刚拿出我的旧书和我的眼睛上釉。