我能做些什么来缩短这段代码?

我能做些什么来缩短这段代码?

问题描述:

我想计算此功能进行更多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

不起作用?这就是你应该告诉你所尝试和没有工作的东西以及你收到的错误信息。还要熟悉特别是循环的文档。 –

您可以从编程中的函数定义中受益。可以这样做:

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

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://*.com/help/someone-answers)。 – EBH