Matlab 从给定函数生成周期函数
假设从给定的函数f(t)出发,我们想用这种方法构造从已有函数出发的新函数Matlab 从给定函数生成周期函数,matlab,loops,vectorization,Matlab,Loops,Vectorization,假设从给定的函数f(t)出发,我们想用这种方法构造从已有函数出发的新函数 k=-1000:1:999; F=zeros(1,length(k)); T=3; for t=1:length(k) result=0; for l=1:length(k) result=result+f(t+k(l)*T); end F(t)=result; end 其中T是一个常数,假设T=3;当然,k在现实中不可能从无穷大到无穷大,因为我们不能用计算机进行无穷和,
k=-1000:1:999;
F=zeros(1,length(k));
T=3;
for t=1:length(k)
result=0;
for l=1:length(k)
result=result+f(t+k(l)*T);
end
F(t)=result;
end
其中T是一个常数,假设T=3;当然,k在现实中不可能从无穷大到无穷大,因为我们不能用计算机进行无穷和,所以这是我的第一次尝试
首先让我们定义我们的函数
function y=f(t);
y=-1/(t^2);
end
第二程序
k=-1000:1:999;
F=zeros(1,length(k));
T=3;
for t=1:length(k)
F(t)=sum(f(t+k*T));
end
但当我运行第二个程序时,我会
>> program
Error using ^
Inputs must be a scalar and a square matrix.
To compute elementwise POWER, use POWER (.^) instead.
Error in f (line 2)
y=-1/(t^2);
Error in program (line 5)
F(t)=sum(f(t+k*T));
所以我有两个关于这个项目的问题:
1.首先,什么是错误?为什么我会犯错误
k=-1000:1:999;
F=zeros(1,length(k));
T=3;
for t=1:length(k)
result=0;
for l=1:length(k)
result=result+f(t+k(l)*T);
end
F(t)=result;
end
可以吗?要以矢量化的方式解决问题,您必须更改函数
f
,以便可以使用矢量作为输入调用它。正如@patrik所建议的,这是通过使用元素操作符*/^
(Afaik,不存在+。-
实现的)。不幸的是,@rayryeng的评论并不完全正确,这可能会导致混淆。正确的方法是对除法/
和平方^
使用元素运算符:
function y = f(t)
y = -1 ./ (t.^2);
end
您现有的代码(第一个版本)
然后按预期工作(并且比您在编辑中发布的版本快得多)
您甚至可以消除for循环并改用。对于简单函数f
,也可以使用而不是创建单独的文件。这给
f = @(t) -1 ./ (t.^2);
k = -1000:1:999;
t = 1:2000;
T = 3;
F = arrayfun(@(x)sum(f(x+k*T)), t);
而且速度更快,而且是一个简单的单行程序arrayfun
将任何函数句柄作为第一个输入。我们创建一个函数句柄,它接受一个参数x
,并对所有k
进行求和:@(x)sum(f(x+k*T)
。第二个参数,向量T
,包含对函数句柄求值的所有值
正如@Divakar在评论中提出的,您还可以使用bsxfun
功能:
f = @(t) -1 ./ (t.^2);
k = -1000:1:999;
t = 1:2000;
T = 3;
F = sum(f(bsxfun(@plus,k*T,t.')),2);
当bsxfun
创建一个包含t
和k*t
之间的所有组合的矩阵时,它们都使用f(…)
进行评估,最后,沿着第二维度的和在所有k
上求和
基准测试
让我们比较一下这些解决方案:
循环和求和的组合(原始问题):
运行时间为0.043969秒
检查2个循环中的所有组合(编辑问题):
运行时间为1.367181秒
使用arrayfun的矢量化方法
:
运行时间为0.063748秒
@Divakar提出的带有bsxfun
的矢量化方法:
运行时间为0.099399秒
因此(遗憾的是)第一个解决方案包括一个for
循环,它击败了两种向量化方法。对于更大的k
向量(-10000:1:9999
),这种行为可以复制。结论似乎是MATLAB确实已经学会了如何为
循环优化。要以矢量化的方式解决您的问题,您必须更改函数f
,以便可以用矢量作为输入来调用它。正如@patrik所建议的,这是通过使用元素级的运算符*/^
(当然,不存在+.-
)。遗憾的是@rayryeng的注释不完全正确,这可能会导致混淆。正确的方法是对除法/
和平方^
使用元素运算符:
function y = f(t)
y = -1 ./ (t.^2);
end
您现有的代码(第一个版本)
然后按预期工作(并且比您在编辑中发布的版本快得多)
您甚至可以消除for循环并改用。对于简单函数f
,您也可以使用而不是创建单独的文件。这将
f = @(t) -1 ./ (t.^2);
k = -1000:1:999;
t = 1:2000;
T = 3;
F = arrayfun(@(x)sum(f(x+k*T)), t);
甚至更快,而且是一个简单的单行程序。arrayfun
将任何函数句柄作为第一个输入。我们创建一个函数句柄,它接受一个参数x
,并对所有k
进行求和:@(x)sum(f(x+k*T)
。第二个参数,向量t
,包含函数句柄计算的所有值
正如@Divakar在评论中提出的,您还可以使用bsxfun
功能:
f = @(t) -1 ./ (t.^2);
k = -1000:1:999;
t = 1:2000;
T = 3;
F = sum(f(bsxfun(@plus,k*T,t.')),2);
当bsxfun
创建一个包含t
和k*t
之间的所有组合的矩阵时,它们都使用f(…)
进行评估,最后,沿着第二维度的和在所有k
上求和
基准测试
让我们比较一下这些解决方案:
循环和求和的组合(原始问题):
运行时间为0.043969秒
检查2个循环中的所有组合(编辑问题):
运行时间为1.367181秒
使用arrayfun的矢量化方法
:
运行时间为0.063748秒
@Divakar提出的带有bsxfun
的矢量化方法:
运行时间为0.099399秒
因此(遗憾的是)第一个解决方案包括一个for
循环,它击败了两种向量化方法。对于更大的k
向量(-10000:1:9999
),这种行为可以复制。结论似乎是,MATLAB确实已经学会了如何优化循环。运算符+,-,*,/,^,
是矩阵运算符。如果要进行元素运算,需要使用相应的元素运算符,+,.-,.*,./,.^,
,其中de>+
和-
当然不是必需的。我已经更新了我的代码,请查看它。您的函数y
需要对