我在python中有一个函数,它可以在标量输入上运行,但在过程中乘以矩阵。确切的代码如下所示:
def f(t, n):
T = np.pi
a_0 = 0.5
n = np.arange(1, n + 1)
# Calculate the Fourier series of f(t)
a_n = np.sin(n*T) / (n * np.pi)
b_n = (1 - np.cos(n * T)) / (n * np.pi)
res = a_0 + np.sum(a_n * np.cos(n*t)) + np.sum(b_n * np.sin(n*t))
return res
现在,我希望这对输入t的向量进行操作,并使实现保持向量化(不用于循环)。我可以看到,制作一个维度len(t) x n
的矩阵,其中初始向量n只是垂直叠加len(t)次,然后用t进行元素乘法将是一个解决方案,但是适当的是什么实现此功能的方式?
答案 0 :(得分:1)
这是一个公式化的“矢量化”。请注意,只需要进行少量更改。第一行,最后一行。
第一行:asanyarray
允许接受类似数组的输入,即标量,数组,嵌套列表等,并对它们进行相同的处理。索引在最后添加一个轴。这是傅里叶系数的空间。方便的是,这些将自动广播,因为它们占据最后一个尺寸,并且缺少轴插入左侧。这就是代码几乎没有变化的原因。
只有最后的总和必须限制在傅立叶轴上,这就是..., axis=-1)
kwargs所做的。
def f(t, n):
t = np.asanyarray(t)[..., None]
T = np.pi
a_0 = 0.5
n = np.arange(1, n + 1)
# Calculate the Fourier series of f(t)
a_n = np.sin(n*T) / (n * np.pi)
b_n = (1 - np.cos(n * T)) / (n * np.pi)
res = a_0 + np.sum(a_n * np.cos(n*t), axis=-1) + np.sum(b_n * np.sin(n*t), axis=-1)
return res
答案 1 :(得分:1)
这是一种矢量化方法,使用broadcasting
接受输入向量t
,使用np.dot
和最后一步使用{{3}} -
def f_vectorized(t, n): # where t is an array
t2D = t[:,None]
T = np.pi
a_0 = 0.5
n = np.arange(1, n + 1)
a_n = np.sin(n*T) / (n * np.pi)
b_n = (1 - np.cos(n * T)) / (n * np.pi)
nt2D = n*t2D
return a_0 + np.cos(nt2D).dot(a_n) + np.sin(nt2D).dot(b_n)
示例运行 -
In [142]: t
Out[142]: array([8, 1, 8, 0, 2, 7, 8, 8])
In [143]: n = 5
In [144]: f_vectorized(t,n)
Out[144]:
array([ 1.03254608, 0.94354963, 1.03254608, 0.5 , 0.95031599,
1.04127659, 1.03254608, 1.03254608])