2013-11-01 87 views
0
k_1=100; 

while (abs(k_1-k)>0.0001) 

k=k_1; 
y_hat=x*b; 
r=(y-y_hat); 
s_squared=norm(r)/(n-p-1); 

k_1=p*s_squared/(b'*b); 
pseudo = sqrt(k_1) * eye(p); 
x_ridge = [x;pseudo]; 
y_ridge = [y;zeros(p,1)]; 

b = x_ridge\y_ridge; 


end 

我有一段代碼,試圖迭代k值,直到它收斂(即後續迭代小於一定的距離)。 while循環必須至少運行一次:初始k_ {t}值已經被計算出來,while循環的第一次迭代提供了第一個k_ {t + 1},理論上這可以在while循環。儘管在Matlab中循環

上面的代碼工作但效率不高。所以我非常期待最佳實踐/提高效率。

當前k在第一行設置爲k_1。如果需要更多迭代,這很好,但如果第一個k_1收斂,那麼以這種方式設置代碼將需要不必要的額外循環。

理想情況下,我會有一個do_while而不是while_do的結構,因爲它是在Matlab中設置的。這樣它會計算出初始k_ {t + 1},然後測試條件。因此,如果它在第一個循環上收斂(並且確實有很多似乎是),那麼它將只循環一次。

我可以通過使用一個if結構來解決這個問題,並告訴它在符合收斂條件的情況下發生,否則設置k_t = k_ {t + 1}。但是這看起來相當複雜,可能實際上增加了計算負擔,更不用說每次循環只進行一次收斂測試就會進行兩次。

什麼是這種情況下最好的matlab解決方案?

+1

你說你的'while'循環有效,但效率不高。「你的問題主要是關於如何避免在最後一次迭代中進行不必要的計算?在你可以嘗試重新排序你的計算的過程中,需要在'while'循環之外的第一次迭代中取一些位,並在之前對它們進行評估。 – horchler

+0

啊是的,我可以在外面進行k_ {t + 1}的第一次計算,並且如果需要進一步的迭代,只進入while循環,這可能會有所幫助。但是不必要的循環問題只會從k_ {t + 1}迭代到k_ {t + 2}迭代(當需要迭代時)。如果他們只是在Matlab中允許do/while循環,會更簡單! – Bazman

+1

我不一定是指在循環之外進行整個迭代 - 只是讓它開始。然後你需要看看你如何重新排列'while'循環中的行。由於您的示例代碼不可運行,因此我無法圍繞自己玩弄這種事情是否可行。 – horchler

回答

1

由於在每次迭代中需要k_1來計算k,因此無法對此循環進行矢量化,爲此,您需要執行循環中的步驟。

在matlab中,你可以矢量化並行循環,效率更高,但在這種情況下,你有一個普通的舊循環,你可以做任何事情。

此外,不要擔心迭代更少或更多。除非你在裏面運行的計算是非常昂貴的,否則一次迭代不會有什麼區別。

但是,請嘗試在while以外存儲eye(p)zeros(p,1)。我擔心Matlab會在每次迭代中銷燬變量並分配內存,這非常昂貴。由於p已修復,因此可以將它們存儲在變量中並反覆使用它們。 實際上,似乎可以避免在循環內計算y_ridge