簡體   English   中英

MATLAB:在另一個函數中使用for循環

[英]MATLAB: Using a for loop within another function

我正在嘗試連接幾個結構。 我從每個結構中獲取的內容取決於需要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”。”

如何在串聯函數中執行for循環? 我可以在Matlab的其他函數中執行循環嗎? 除了復制/粘貼行並手動更改1個數字以外,還有其他方法可以做到嗎?

您快要做好了! 這將做您想要的。

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循環具有1百萬次迭代,這可能會非常慢。 如果小於1000左右,您根本不會注意到它。

最后,HBHB無法在頂部運行您的結構創建代碼的原因是,除非在工作空間中已經定義了a,否則它無法工作。 如果初始化這樣的話:

%% 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

然后它會首次為任何人運行。

作為gariepy答案的附錄:

矩陣級聯

A = [A k];

作為附加的一種方法實際上很慢。 每次連接到N大小的向量時,最終都會重新分配N個元素。 如果您要做的只是在其末尾添加元素,則最好使用以下語法

A(end+1) = k;

在MATLAB中對此進行了優化,因此平均而言,您僅需重新分配矩陣中約80%的元素。 這可能不會接縫太多,但是對於10k元素來說,這在時間上相差了一個數量級(至少對我而言)。

log

切記,這僅適用於MATLAB 2012b及更高版本,如本主題中所述: Octave / Matlab:向向量添加新元素

這是我使用的代碼。 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');

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM