Поиск…


замечания

Итерация над вектором столбца

Общий источник ошибок пытается перебрать элементы вектора столбца. Вектор столбца обрабатывается как матрица с одним столбцом. (В Matlab фактически нет различий.) Цикл for выполняется один раз, когда переменная цикла устанавливается в столбец.

% Prints once: [3, 1]
my_vector = [1; 2; 3];
for i = my_vector
    display(size(i))
end

Изменение переменной итерации

Изменение переменной итерации изменяет ее значение для текущей итерации, но не влияет на ее значение в последующих итерациях.

% Prints 1, 2, 3, 4, 5
for i = 1:5
    display(i)
    i = 5; % Fail at trying to terminate the loop
end

Специальные характеристики a:b в правой части

В базовом примере рассматривается 1:n как обычный экземпляр создания вектора строки, а затем итерации по нему. По соображениям производительности Matlab фактически обрабатывает любые a:b или a:c:b специально, не создавая вектор строки полностью, а вместо этого создавая каждый элемент по одному за раз.

Это можно обнаружить, слегка изменив синтаксис.

% Loops forever
for i = 1:1e50
end
% Crashes immediately
for i = [1:1e50]
end

Петля от 1 до n

Самый простой случай - это просто выполнить задачу для фиксированного известного количества раз. Скажем, мы хотим отображать числа от 1 до n, мы можем написать:

n = 5;
for k = 1:n
    display(k)
end

Цикл будет выполнять внутренний оператор (ы), все между символами for и end , в течение n раз (5 в этом примере):

1
2
3
4
5

Вот еще один пример:

n = 5;
for k = 1:n
    disp(n-k+1:-1:1) % DISP uses more "clean" way to print on the screen
end

на этот раз мы используем как n и k в цикле, чтобы создать «вложенный» дисплей:

 5     4     3     2     1

 4     3     2     1

 3     2     1

 2     1

 1

Итерации над элементами вектора

Правая часть задания в цикле for может быть любым вектором строки. Левая часть задания может быть любым допустимым именем переменной. Цикл for присваивает другому элементу этого вектора переменной каждый пробег.

other_row_vector = [4, 3, 5, 1, 2];
for any_name = other_row_vector
    display(any_name)
end

Вывод будет отображаться

4
3
5
1
2

(Версия 1:n является нормальным случаем этого, потому что в Matlab 1:n - просто синтаксис для построения вектор-строки из [1, 2, ..., n] .)

Следовательно, два следующих блока кода идентичны:

A = [1 2 3 4 5];
for x = A
  disp(x);
end

а также

for x = 1:5
  disp(x);
end

И следующие идентичны:

A = [1 3 5 7 9];
for x = A
  disp(x);
end

а также

for x = 1:2:9
  disp(x);
end

Любой вектор строки будет делать. Они не должны быть цифрами.

my_characters = 'abcde';
for my_char = my_characters
    disp(my_char)
end

выйдет

a
b
c
d
e

Итерация по столбцам матрицы

Если правая часть присваивания является матрицей, то в каждой итерации переменной присваиваются последующие столбцы этой матрицы.

some_matrix = [1, 2, 3; 4, 5, 6]; % 2 by 3 matrix
for some_column = some_matrix
    display(some_column)
end

(Версия вектора строки является нормальным случаем этого, потому что в Matlab вектор строки является просто матрицей, столбцы которой имеют размер 1.)

Вывод будет отображаться

1
4
2
5
3
6

т.е. каждый столбец отображенной итерационной матрицы отображается, каждый столбец печатается при каждом вызове display .

Перечислять индексы

my_vector = [0, 2, 1, 3, 9];
for i = 1:numel(my_vector)
    my_vector(i) = my_vector(i) + 1;
end

Наиболее простые вещи, выполняемые for циклов, могут выполняться быстрее и проще с помощью векторизованных операций. Например, приведенный выше цикл можно заменить на my_vector = my_vector + 1 .

Вложенные петли

Петли могут быть вложенными, чтобы преформировать итерированную задачу в другую итерационную задачу. Рассмотрим следующие петли:

ch = 'abc';
m = 3;
for c = ch
    for k = 1:m
        disp([c num2str(k)]) % NUM2STR converts the number stored in k to a charachter,
                             % so it can be concataneted with the letter in c
    end
end

мы используем 2 итератора для отображения всех комбинаций элементов из abc и 1:m , что дает:

a1
a2
a3
b1
b2
b3
c1
c2
c3

Мы также можем использовать вложенные циклы для объединения между задачами, которые должны выполняться каждый раз, и задачи, которые необходимо выполнить один раз в нескольких итерациях:

N = 10;
n = 3;
a1 = 0; % the first element in Fibonacci series
a2 = 1; % the secound element in Fibonacci series
for j = 1:N
    for k = 1:n
        an = a1 + a2; % compute the next element in Fibonacci series
        a1 = a2;      % save the previous element for the next iteration
        a2 = an;      % save ht new element for the next iteration
    end
    disp(an) % display every n'th element
end

Здесь мы хотим вычислить все ряды Фибоначчи , но каждый раз отображать только n й элемент, поэтому мы получаем

   3
   13
   55
   233
   987
   4181
   17711
   75025
   317811
   1346269

Другое дело, что мы можем использовать первый (внешний) итератор во внутреннем цикле. Вот еще один пример:

N = 12;
gap = [1 2 3 4 6];
for j = gap
    for k = 1:j:N
        fprintf('%d ',k) % FPRINTF prints the number k proceeding to the next the line
    end
    fprintf('\n')        % go to the next line
end

На этот раз мы используем вложенный цикл для форматирования вывода и торможем линию только тогда, когда был введен новый пробел ( j ) между элементами. Мы пробиваем ширину зазора во внешнем контуре и используем его внутри внутреннего цикла для итерации по вектору:

1 2 3 4 5 6 7 8 9 10 11 12 
1 3 5 7 9 11 
1 4 7 10 
1 5 9 
1 7 

Примечание. Странные те же самые вложенные контуры.

Это не то, что вы увидите в других средах программирования. Я наткнулся на это несколько лет назад, и я не мог понять, почему это происходит, но после некоторого времени работы с MATLAB я смог понять это. Посмотрите на фрагмент кода ниже:

for x = 1:10
    for x = 1:10
        fprintf('%d,', x);
    end
    fprintf('\n');
end

вы не ожидаете, что это будет работать должным образом, но это произойдет, производя следующий вывод:

1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,

Причина в том, что, как и все остальное в MATLAB, счетчик x также является матрицей - вектором, который будет точным. Таким образом, x является только ссылкой на «массив» (когерентная, последовательная структура памяти), которая соответствующим образом ссылается на каждый последующий цикл (вложенный или нет). Тот факт, что вложенный цикл использует один и тот же идентификатор, не имеет никакого отношения к тому, как ссылаются значения из этого массива. Единственная проблема заключается в том, что внутри вложенного цикла внешний x скрывается вложенным (локальным) x и поэтому не может быть ссылкой. Однако функциональность структуры вложенных циклов остается неповрежденной.



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow