2016-11-07 68 views
0

我想計算此功能進行更多k,像k = 6,7,8...等:我能做些什麼來縮短這段代碼?

F(K,A)=( - 1)ķ一個 - ( - 1)ķ(Kπ/噸)

然後,我想繪製它的所有k的。我只是想以更短的形式。我試圖寫k作爲一個載體,但這是行不通的。這裏是我的代碼:

clear all 
close all 
clc 
w = linspace(-1,10,5000); 
t = 2*pi; 

k = 0; 
a0 = w.^2; 
b0 = (-1).^k.*a0-((-1).^k).*(k*pi/t).^2; 
b = a0*0; 
k1 = 1; 
a01 = w.^2; 
b01 = (-1).^k1.*a01-((-1).^k1).*(k1*pi/t).^2; 

k2 = 2; 
a02 = w.^2; 
b02 = (-1).^k2.*a02-((-1).^k2).*(k2*pi/t).^2; 

k3 = 3; 
a03 = w.^2; 
b03 = (-1).^k3.*a03-((-1).^k3).*(k3*pi/t).^2; 

k4 = 4; 
a04 = w.^2; 
b04 = (-1).^k4.*a04-((-1).^k4).*(k4*pi/t).^2; 

k5 = 5; 
a05 = w.^2; 
b05 = (-1).^k5.*a05-((-1).^k5).*(k5*pi/t).^2; 

plot(a0,b,'.') 
hold on 
plot(a0,b0,'.') 
hold on 
grid on 
plot(a01,b01,'.') 
+0

嘗試代碼審查,如果你的代碼正在工作,但你想優化它。 –

+0

上面的評論是指http://codereview.stackexchange.com/ –

+1

不起作用?這就是你應該告訴你所嘗試和沒有工作的東西以及你收到的錯誤信息。還要熟悉特別是循環的文檔。 –

回答

0

您可以從編程中的函數定義中受益。可以這樣做:

function main 
w=linspace(-1,10,5000); 
t=2*pi; 

figure;hold on 
for k=0:5 
    [a,b] = getNext(k,w,t); 
    plot(a,b,'.'); 
end 

function [a,b] = getNext(k,w,t) 
a = w.^2; 
b = (-1).^k.*a-((-1).^k).*(k*pi/t).^2; 
end 
end 

請記住,這不是唯一的解決方案。其他獲得類似結果的方法也是可能的。

更新 內置的for循環使用arrayfun是這樣的:

w = linspace(-1,10,5000); 
t = 2*pi; 
a = w.^2; 
K = [0 1 2 3 4 5 6 7]; 
S = arrayfun(@(k)((-1).^k.*a-((-1).^k).*(k*pi/t).^2),K,'UniformOutput',false); 
figure;hold on 
for ii=1:numel(K) 
    plot(a,S{ii},'.'); 
end 
+2

技術上'arrayfun'只是'for'循環的一個包裝,'for'循環本身當然不是很有向量化的。使用單元格意味着你不能矢量化事物,因爲單元格的不規則性質與所包含的數據類型和大小有關,MATLAB必須分別評估每個子單元格。 – Adriaan

+0

@Adriaan正確我的意思是一個mex級別的循環:) – NKN

3

TL;博士 - 這是一種體積小,矢量方式:

t = 2*pi; 
myfun = @(k,a) (-1).^k.*a-((-1).^k).*(k*pi/t).^2; 
k = 0:30; % here you can add as many k's you like 
w = linspace(-1,10,5000).^2.'; 
b0 = zeros(size(w)); 
B = bsxfun(myfun,k,w); 
plot(w,[b0 B],'.') 
grid on 

的結果:

enter image description here

說明:

你的代碼演示瞭如何不應該使用一個變量。如果a01==a02==a03...那麼你可以只使用a所有這些,不需要定義所有這些a的。對於函數b0b01等也是如此,您可以定義一個匿名函數(最短類型的函數),然後一遍又一遍地調用它。如果你只是做兩件事情你上面的代碼(沒有繪製)變爲:

w = linspace(-1,10,5000); 
t = 2*pi; 
b_fun = @(k,a) (-1).^k.*a-((-1).^k).*(k*pi/t).^2; 
a = w.^2; 
k = 0; 
b0 = b_fun(k,a); 
b = a*0; 
k1 = 1; 
b01 = b_fun(k1,a); 
k2=2; 
b02 = b_fun(k2,a); 
k3=3; 
b03 = b_fun(k3,a); 
k4 = 4; 
b04 = b_fun(k4,a); 
k5 = 5; 
b05 = b_fun(k5,a); 

這是短,更具可讀性。請注意,我們在函數之前定義了t,因此它是通過函數內的值計算的。

接下來,你可以使用singleton expansion來計算所有成對元素從a和你k的一個命令的組合(和一個矢量方式):

k = 0:5 
B = bsxfun(b_fun,k,a.'); 

這將創建一個矩陣,其中每列所有結果值爲b_fun(k(i),a)bsxfun的第一個輸入是任何基於元素的二進制操作,如我們的功能b_fun。接下來總是有2個數組(其中一個數組可以是標量),第一個數組包含函數中第一個參數的所有值,第二個數組用於第二個參數。如果其中一個陣列具有單個維度,而另一個維度大於一個,則比bsxfun擴大較小的一個以適合較大的一個。在我們的例子中,k是單行的,而a是單列的,因此結果爲no。列號從k,和號碼。來自a的行。

所以到這裏我們得到:

w = linspace(-1,10,5000); 
t = 2*pi; 
b_fun = @(k,a) (-1).^k.*a-((-1).^k).*(k*pi/t).^2; 
a = w.^2; 
k = 0:5; 
B = bsxfun(b_fun,k,a.'); 
b = a*0; 

我們可以走得更遠,並刪除了一些重複的變量 - 使用w.^2代替a,並通過0.5更換常數pi/t。此外,它更清楚寫b = zeros(size(w)),而不是a*0

w = linspace(-1,10,5000).'; 
b_fun = @(k,a) (-1).^k.*a-((-1).^k).*(k*0.5).^2; 
k = 0:5; 
B = bsxfun(b_fun,k,w.^2); 
b = zeros(size(w)); 

現在的繪圖。 plot可以採取幾個系列數據的一個矩陣的列,並顯示他們都對同一個變量,所以我們可以直接使用我們的B,只是CONCAT它b

plot(w.^2,[b B],'.') 
+0

@knightom,如果這回答你的問題,請考慮[接受它](http://stackoverflow.com/help/someone-answers)。 – EBH