从给定函数生成周期函数

时间:2015-04-15 08:07:05

标签: matlab loops vectorization

让我们说从给定的函数f(t)开始,我们想用这样的方法构造从现有函数给出的新函数

enter image description here

其中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.首先是什么是错误,为什么它显示我的错误

  1. 我怎么能在excel中做到这一点?我可以以某种方式简化它吗?提前谢谢
  2. 已编辑:

    我已经通过这种方式更改了我的代码

    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
    

    没关系?

1 个答案:

答案 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创建一个包含tk*T之间所有组合的矩阵,它们都使用f(...)进行评估,最后,sum沿着第二个进行评估维度总和所有k


<强>基准

让我们比较这些解决方案:

  1. for循环和sum(原始问题)的组合:

      

    经过的时间是0.043969秒。

  2. 完成2个for循环中的所有组合(已编辑的问题):

      

    经过的时间是1.367181秒。

  3. arrayfun的矢量化方法:

      

    经过的时间是0.063748秒。

  4. @Divakar提出的bsxfun矢量化方法:

      

    经过的时间是0.099399秒。

  5. 所以(遗憾的是)包含for循环的第一个解决方案胜过两个矢量化方法。对于较大的k向量(-10000:1:9999),可以重现此行为。结论似乎是MATLAB确实学会了如何优化for循环。