让我们说从给定的函数f(t)开始,我们想用这样的方法构造从现有函数给出的新函数
其中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
没关系?
答案 0 :(得分:4)
要以矢量化方式解决问题,您必须更改函数f
,以便可以使用矢量作为输入调用它。正如@patrik建议的那样,这是通过使用元素方式运算符.* ./ .^
(Afaik,no .+ .-
存在)来实现的。不幸的是@rayryeng的评论并不完全正确,这可能导致混乱。正确的方法是对分区./
和分区.^
使用元素运算符:
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
然后按预期工作(并且比您在编辑中发布的版本快得多)。
您甚至可以取消for循环并使用arrayfun
代替。对于简单函数f
,您还可以使用function handles而不是创建单独的文件。这给了
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)
进行求和。第二个参数vector 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(...)
进行评估,最后,sum
沿着第二个进行评估维度总和所有k
。
<强>基准强>
让我们比较这些解决方案:
for
循环和sum
(原始问题)的组合:
经过的时间是0.043969秒。
完成2个for
循环中的所有组合(已编辑的问题):
经过的时间是1.367181秒。
arrayfun
的矢量化方法:
经过的时间是0.063748秒。
@Divakar提出的bsxfun
矢量化方法:
经过的时间是0.099399秒。
所以(遗憾的是)包含for
循环的第一个解决方案胜过两个矢量化方法。对于较大的k
向量(-10000:1:9999
),可以重现此行为。结论似乎是MATLAB确实学会了如何优化for
循环。