[英]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元素來說,這在時間上相差了一個數量級(至少對我而言)。
切記,這僅適用於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.