2016-11-07 10 views
0

Iはk = 6,7,8...などのように、kより、この関数を計算する:このコードを短縮するにはどうすればよいですか?

F(K、A)=(-1)K - ( - 1)K(Kπ/ T)

次に、私はすべて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レベルのfor-loopを意味しました:) – NKN

3

TL; DR - ここでコンパクトでベクトル化方法の両方である:

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を使用することができます。そのすべてを定義する必要はありません。ab0b01なども同様ですが、それを行う無名関数(関数の最短タイプ)を定義して繰り返し呼び出すことができます。上記の2つのことを行うと、上のコード(プロットなし)は次のようになります。

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を定義しているので、関数内の値によって計算されます。

次は、一つのコマンドで(とベクトル化の方法で)すべてのペアごとのaからの要素の組み合わせとあなたのk年代を計算するためにsingleton expansionを使用することができます。

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

これは、各列がある行列を作成しますすべての結果はb_fun(k(i),a)です。 bsxfunへの最初の入力は、私たちの関数b_funのような要素ごとのバイナリ操作です。次に、常に2つの配列(そのうちの1つはスカラーでもよい)があり、最初のものは関数の最初の引数のすべての値を保持し、2番目の引数は2番目の引数のためのものです。いずれかの配列のシングルトンディメンションが1より大きい場合、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を交換してください。また、それは代わりにa*0の、b = zeros(size(w))を書くことより明らかだ:

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は1つの行列の列のデータのいくつかのシリーズを取り、同じ変数に対してそれらのすべてを表示するので、我々は、直接私たちのBを使用することができ、そしてそれbにCONCATことができます。

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

@knightomこれがあなたの質問に答えるなら、それを考慮してください(http://stackoverflow.com/help/someone-answers)。 – EBH

関連する問題