Ricerca…


Osservazioni

Iterare sul vettore di colonna

Una fonte comune di bug sta tentando di eseguire il loop sugli elementi di un vettore di colonna. Un vettore di colonna viene trattato come una matrice con una colonna. (In Matlab non esiste alcuna distinzione.) Il ciclo for viene eseguito una volta con la variabile loop impostata sulla colonna.

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

Modifica della variabile di iterazione

La modifica della variabile di iterazione modifica il suo valore per l'iterazione corrente, ma non ha alcun impatto sul suo valore nelle iterazioni successive.

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

Prestazione speciale di a:b caso a:b nella parte destra

L'esempio di base tratta 1:n come una normale istanza di creazione di un vettore di riga e quindi iterando su di esso. Per motivi di prestazioni, Matlab tratta in realtà qualsiasi a:b o a:c:b specialmente non creando il vettore riga interamente, ma creando invece ogni elemento uno alla volta.

Questo può essere rilevato modificando leggermente la sintassi.

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

Passare da 1 a n

Il caso più semplice consiste nel preformare un task per un numero fisso noto di volte. Diciamo che vogliamo visualizzare i numeri tra 1 e n, possiamo scrivere:

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

Il ciclo eseguirà l'istruzione interna (s), tutto tra il for e la end , per n volte (5 in questo esempio):

1
2
3
4
5

Ecco un altro esempio:

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

questa volta usiamo sia il n che il k nel ciclo, per creare un display "annidato":

 5     4     3     2     1

 4     3     2     1

 3     2     1

 2     1

 1

Iterare su elementi del vettore

Il lato destro dell'assegnazione in un ciclo for può essere qualsiasi vettore di riga. Il lato sinistro del compito può essere un nome di variabile valido. Il ciclo for assegna un elemento diverso di questo vettore alla variabile ogni corsa.

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

L'output verrebbe visualizzato

4
3
5
1
2

(La versione 1:n è un caso normale, perché in Matlab 1:n è solo sintassi per la costruzione di un vettore di riga di [1, 2, ..., n] .)

Quindi, i due seguenti blocchi di codice sono identici:

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

e

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

E anche i seguenti sono identici:

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

e

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

Qualsiasi vettore di riga funzionerà. Non devono essere numeri.

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

uscirà

a
b
c
d
e

Iterare su colonne di matrice

Se il lato destro dell'assegnazione è una matrice, in ogni iterazione alla variabile vengono assegnate le successive colonne di questa matrice.

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

(La versione vettoriale riga è un caso normale di questo, perché in Matlab un vettore riga è solo una matrice le cui colonne sono la dimensione 1.)

L'output verrebbe visualizzato

1
4
2
5
3
6

cioè ogni colonna della matrice iterata visualizzata, ogni colonna stampata su ogni chiamata di display .

Loop over indexes

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

Le operazioni più semplici eseguite con i cicli for possono essere eseguite più rapidamente e più facilmente dalle operazioni vettorializzate. Ad esempio, il ciclo precedente può essere sostituito da my_vector = my_vector + 1 .

Cicli annidati

I loop possono essere annidati, per preformare l'attività iterata all'interno di un'altra attività iterata. Considera i seguenti cicli:

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

usiamo 2 iteratori per visualizzare tutte le combinazioni di elementi da abc e 1:m , che produce:

a1
a2
a3
b1
b2
b3
c1
c2
c3

Possiamo anche utilizzare cicli annidati per combinare le attività da svolgere ogni volta e le attività da eseguire una volta in più iterazioni:

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

Qui vogliamo calcolare tutte le serie di Fibonacci , ma mostrare ogni volta solo il n elemento, quindi otteniamo

   3
   13
   55
   233
   987
   4181
   17711
   75025
   317811
   1346269

Un'altra cosa che possiamo fare è usare il primo iteratore (esterno) all'interno del ciclo interno. Ecco un altro esempio:

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

Questa volta usiamo il ciclo annidato per formattare l'output e freniamo la linea solo quando è stato introdotto un nuovo spazio ( j ) tra gli elementi. Passiamo attraverso la larghezza del gap nel loop esterno e lo usiamo all'interno del loop interno per scorrere il vettore:

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 

Avviso: strani loop con lo stesso contatore.

Questo non è qualcosa che vedrai in altri ambienti di programmazione. L'ho incontrato qualche anno fa e non riuscivo a capire perché stava succedendo, ma dopo aver lavorato con MATLAB per un po 'sono riuscito a capirlo. Guarda il frammento di codice qui sotto:

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

non ti aspetteresti che funzioni correttamente ma lo fa, producendo il seguente output:

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,

Il motivo è che, come per tutto il resto in MATLAB, anche il contatore x è una matrice, un vettore per la precisione. In quanto tale, x è solo un riferimento a un 'array' (una struttura di memoria coerente e consecutiva) che è opportunamente referenziato con ogni ciclo conseguente (nidificato o non). Il fatto che il ciclo annidato utilizzi lo stesso identificatore non fa alcuna differenza sul modo in cui i valori di quell'array sono referenziati. L'unico problema è che all'interno del ciclo annidato la x esterna è nascosta dal nidificato (locale) x e quindi non può essere referenziata. Tuttavia, la funzionalità della struttura del ciclo nidificata rimane intatta.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow