2016-11-07 5 views
0

Я хочу, чтобы вычислить эту функцию более k, как k = 6,7,8... и т.д.:Что я могу сделать, чтобы сделать этот код короче?

F (к, а) = (-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

Try обзора кода, если ваш код работает, но вы хотите его оптимизировать. –

+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 

Помните, что это не единственное решение. Возможны и другие способы получения аналогичного результата.

Update Встроенный для цикла с использованием 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 correct Я имел в виду mex-level for-loop :) – NKN

3

Т.Л., др - Вот как компактный и векторизация способ:

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. То же самое верно для функции b0, b01 и т. Д., Вы можете определить анонимную функцию (самый короткий тип функций), которая это делает, и называть ее снова и снова. Если вы просто делаете это 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, поэтому она вычисляется по ее значениям внутри функции.

Далее вы можете использовать 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, и заменить константу pi/t на 0.5. Кроме того, это более ясно писать 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

Смежные вопросы