MATLAB:在另一个函数中使用for循环

时间:2016-01-28 04:01:53

标签: matlab

我试图连接几个结构。我从每个结构中获取的内容取决于需要for循环的函数。这是我的简化数组:

t = 1;
for t = 1:5              %this isn't the for loop I am asking about
    a(t).data = t^2;     %it just creates a simple struct with 5 data entries
end

这里我手动连接:

A = [a(1:2).data a(1:3).data a(1:4).data a(1:5).data]     %concatenation function

正如您所看到的,范围(1:2)(1:3)(1:4)(1:5)可以循环播放,我尝试这样做:

t = 2;
A = [for t = 2:5
         a(1:t).data
     end]

这会导致“非法使用保留关键字”错误“。”

如何在连接函数中执行for循环?我可以在Matlab中的其他函数中做循环吗?除了复制/粘贴线并手动更改1号之外,还有其他方法吗?

2 个答案:

答案 0 :(得分:3)

你接近正确!这将做你想要的。

A = [];  %% note: no need to initialize t, the for-loop takes care of that
for t = 2:5
   A = [A a(1:t).data] 
end

这看起来很奇怪......你一遍又一遍地连接相同的元素......在这个例子中,你得到了结果:

A =
     1     4     1     4     9     1     4     9    16     1     4     9    16    25

如果真正需要的只是将.data元素连接成一个数组,那么这很简单:

A = [a.data]

关于此的一些注意事项:为什么括号必须?因为表达式

a.data, a(1:t).data
不像许多函数那样返回单个数组中的所有数字。它们为结构数组的每个元素返回一个单独的答案。您可以这样测试:

>> [b,c,d,e,f] = a.data
b =
     1
c =
     4
d =
     9
e =
    16
f =
    25

那里有五个不同的答案。但是MATLAB给你一个骗子 - 方括号!将类似a.data的表达式放在方括号内,突然将这些单独的答案压缩成单个数组。它是魔法

另一个注意事项:对于非常大的数组,此处的for循环版本将非常慢。最好为A提前分配内存。在这里的for循环中,MATLAB每次都会动态调整数组的大小,如果你的for循环有100万次迭代,那么这可能会非常慢。如果它不到1000左右,你根本就不会注意到它。

最后,HBHB无法在顶层运行结构创建代码的原因是,除非已在工作区中定义了代码,否则它无法正常工作。如果您初始化如下:

%% t = 1;  %% by the way, you don't need this, the t value is overwritten by the loop below
a = [];   %% always initialize!
for t = 1:5              %this isn't the for loop I am asking about
    a(t).data = t^2;     %it just creates a simple struct with 5 data entries
end

然后它第一次运行给任何人。

答案 1 :(得分:2)

作为gariepy答案的附录:

矩阵连接

A = [A k];

作为一种追加它的方式实际上很慢。每次连接到N尺寸矢量时,最终都会重新分配N个元素。如果你所做的只是在它的末尾添加元素,最好使用以下语法

A(end+1) = k;

在MATLAB中,这是优化的,平均而言,您只需要重新分配矩阵中大约80%的元素。这可能不会很多,但对于10k元素,这相当于时间差异的一个数量级(至少对我而言)。

log

请记住,这仅适用于MATLAB 2012b及更高版本,如本文所述:Octave/Matlab: Adding new elements to a vector

这是我使用的代码。 tic / toc语法不是在MATLAB中进行性能分析的最准确方法,但它说明了这一点。

close all; clear all; clc;
t_cnc = []; t_app = [];
N = 1000;
for n = 1:N;
    % Concatenate
    tic;
    A = [];
    for k = 1:n;
        A = [A k];
    end
    t_cnc(end+1) = toc;
    % Append
    tic;
    A = [];
    for k = 1:n;
        A(end+1) = k;
    end
    t_app(end+1) = toc;
end
t_cnc = t_cnc*1000; t_app = t_app*1000; % Convert to ms

% Fit a straight line on a log scale
P1 = polyfit(log(1:N),log(t_cnc),1); P_cnc = @(x) exp(P1(2)).*x.^P1(1);
P2 = polyfit(log(1:N),log(t_app),1); P_app = @(x) exp(P2(2)).*x.^P2(1);

% Plot and save
loglog(1:N,t_cnc,'.',1:N,P_cnc(1:N),'k--',...
       1:N,t_app,'.',1:N,P_app(1:N),'k--');
grid on;
xlabel('log(N)');
ylabel('log(Elapsed time / ms)');
title('Concatenate vs. Append in MATLAB 2014b');
legend('A = [A k]',['O(N^{',num2str(P1(1)),'})'],...
       'A(end+1) = k',['O(N^{',num2str(P2(1)),'})'],...
       'Location','northwest');
saveas(gcf,'Cnc_vs_App_test.png');