MATLAB LanguageIniziare con MATLAB Language


Versioni

Versione pubblicazione Data di rilascio
1.0 1984-01-01
2 1986-01-01
3 1987-01-01
3.5 1990-01-01
4 1992/01/01
4.2c 1994-01-01
5.0 Volume 8 1996/12/01
5.1 Volume 9 1997/05/01
5.1.1 R9.1 1997/05/02
5.2 R10 1998/03/01
5.2.1 R10.1 1998/03/02
5.3 R11 1999-01-01
5.3.1 r11.1 1999/11/01
6.0 R12 2000/11/01
6.1 r12.1 2001-06-01
6.5 R13 2002-06-01
6.5.1 R13SP2 2003-01-01
6.5.2 R13SP2 2003-01-02
7 R14 2006-06-01
7.0.4 R14SP1 2004-10-01
7.1 R14SP3 2005-08-01
7.2 R2006a 2006-03-01
7.3 R2006b 2006-09-01
7.4 R2007a 2007-03-01
7.5 R2007b 2007-09-01
7.6 R2008a 2008-03-01
7.7 R2008b 2008-09-01
7.8 R2009a 2009-03-01
7.9 R2009b 2009-09-01
7.10 R2010a 2010-03-01
7.11 R2010b 2010-09-01
7.12 R2011a 2011-03-01
7.13 R2011b 2011-09-01
7.14 R2012a 2012-03-01
8.0 R2012b 2012-09-01
8.1 R2013a 2013/03/01
8.2 R2013b 2013/09/01
8.3 R2014a 2014/03/01
8.4 R2014b 2014/09/01
8.5 R2015a 2015/03/01
8.6 R2015b 2015/09/01
9.0 R2016a 2016/03/01
9.1 R2016b 2016/09/14
9.2 R2017a 2017/03/08

Vedi anche: storia del rilascio di MATLAB su Wikipedia .

Funzioni anonime e maniglie di funzione

Nozioni di base

Le funzioni anonime sono un potente strumento del linguaggio MATLAB. Sono funzioni che esistono localmente, ovvero: nello spazio di lavoro corrente. Tuttavia, non esistono sul percorso MATLAB come una normale funzione, ad esempio in un m-file. Questo è il motivo per cui sono chiamati anonimi, sebbene possano avere un nome come una variabile nello spazio di lavoro.

L'operatore @

Utilizzare l'operatore @ per creare funzioni anonime e handle di funzione. Ad esempio, per creare un handle per la funzione sin (sinusoidale) e usarlo come f :

>> f = @sin
f = 
    @sin
 

Ora f è una maniglia per la funzione sin . Proprio come (nella vita reale) la maniglia di una porta è un modo di usare una porta, una maniglia di funzione è un modo di usare una funzione. Per usare f , gli vengono passati argomenti come se fosse la funzione sin :

>> f(pi/2)
ans =
     1
 

f accetta qualsiasi argomento di input accettato dalla funzione sin . Se il sin fosse una funzione che accetta argomenti di input pari a zero (cosa che non fa, ma altri lo fanno, ad esempio la funzione peaks ), f() verrebbe usato per chiamarlo senza argomenti di input.

Funzioni anonime personalizzate

Funzioni anonime di una variabile

Ovviamente non è utile creare un handle per una funzione esistente, come il sin nell'esempio sopra. È un po 'ridondante in quell'esempio. Tuttavia, è utile creare funzioni anonime che facciano cose personalizzate che altrimenti avrebbero bisogno di essere ripetute più volte o creato una funzione separata per. Come esempio di una funzione anonima personalizzata che accetta una variabile come suo input, somma il seno e il coseno quadrato di un segnale:

>> f = @(x) sin(x)+cos(x).^2
f = 
    @(x)sin(x)+cos(x).^2
 

Ora f accetta un argomento di input chiamato x . Questo è stato specificato usando parentesi (...) direttamente dopo l'operatore @ . f ora è una funzione anonima di x : f(x) . È usato passando un valore di x in f :

>> f(pi)
ans =
    1.0000
 

Un vettore di valori o una variabile può anche essere passato a f , a condizione che vengano utilizzati in modo valido all'interno di f :

>> f(1:3) % pass a vector to f
ans =
    1.1334    1.0825    1.1212
>> n = 5:7;
>> f(n) % pass n to f
ans =
   -0.8785    0.6425    1.2254
 

Funzioni anonime di più di una variabile

Allo stesso modo è possibile creare funzioni anonime per accettare più di una variabile. Un esempio di una funzione anonima che accetta tre variabili:

>> f = @(x,y,z) x.^2 + y.^2 - z.^2
f = 
    @(x,y,z)x.^2+y.^2-z.^2
>> f(2,3,4)
ans =
    -3
 

Parametrizzare le funzioni anonime

Le variabili nello spazio di lavoro possono essere utilizzate all'interno della definizione di funzioni anonime. Questo è chiamato parametrizzazione. Ad esempio, per utilizzare una costante c = 2 in una funzione anonima:

>> c = 2;
>> f = @(x) c*x
f = 
    @(x)c*x
>> f(3)
ans =
     6
 

f(3) usato la variabile c come parametro per moltiplicare con la x fornita. Nota che se il valore di c è impostato su qualcosa di diverso a questo punto, allora viene chiamato f(3) , il risultato non sarebbe diverso. Il valore di c è il valore al momento della creazione della funzione anonima:

>> c = 2;
>> f = @(x) c*x;
>> f(3)
ans =
     6
>> c = 3;
>> f(3)
ans =
     6
 

Gli argomenti di input per una funzione anonima non si riferiscono alle variabili di workspace

Si noti che l'utilizzo del nome di variabili nell'area di lavoro come uno degli argomenti di input di una funzione anonima (ad esempio, utilizzando @(...) ) non utilizzerà i valori di tali variabili. Invece, vengono trattati come variabili diverse nell'ambito della funzione anonima, ovvero: la funzione anonima ha il proprio spazio di lavoro privato in cui le variabili di input non si riferiscono mai alle variabili dallo spazio di lavoro principale. L'area di lavoro principale e l'area di lavoro della funzione anonima non conoscono i rispettivi contenuti. Un esempio per illustrare questo:

>> x = 3 % x in main workspace
x =
     3
>> f = @(x) x+1; % here x refers to a private x variable
>> f(5)
ans =
     6
>> x
x =
     3
 

Il valore di x dallo spazio di lavoro principale non viene utilizzato all'interno di f . Inoltre, nello spazio di lavoro principale x è rimasto intatto. Nell'ambito di f , i nomi delle variabili tra parentesi dopo l'operatore @ sono indipendenti dalle variabili dello spazio di lavoro principale.

Le funzioni anonime sono memorizzate in variabili

Una funzione anonima (o, più precisamente, la funzione handle che punta a una funzione anonima) è memorizzata come qualsiasi altro valore nello spazio di lavoro corrente: In una variabile (come abbiamo fatto sopra), in un array di celle ( {@(x)x.^2,@(x)x+1} ), o anche in una proprietà (come h.ButtonDownFcn per la grafica interattiva). Ciò significa che la funzione anonima può essere trattata come qualsiasi altro valore. Quando lo si archivia in una variabile, ha un nome nello spazio di lavoro corrente e può essere modificato e cancellato proprio come le variabili che contengono i numeri.

Metti diversamente: un handle di funzione (sia nella forma @sin che per una funzione anonima) è semplicemente un valore che può essere memorizzato in una variabile, proprio come può esserlo una matrice numerica.

Uso avanzato

Passaggio delle funzioni alle altre funzioni

Poiché gli handle di funzione sono trattati come variabili, possono essere passati a funzioni che accettano handle di funzione come argomenti di input.

Un esempio: una funzione viene creata in un m-file che accetta un handle di funzione e un numero scalare. Quindi chiama la funzione handle passandogli 3 e quindi aggiunge il numero scalare al risultato. Il risultato è restituito.

Contenuto di funHandleDemo.m :

function y = funHandleDemo(fun,x)
y = fun(3);
y = y + x;
 

Salvalo da qualche parte nel percorso, ad esempio nella cartella corrente di MATLAB. Ora funHandleDemo può essere usato come segue, ad esempio:

>> f = @(x) x^2; % an anonymous function
>> y = funHandleDemo(f,10) % pass f and a scalar to funHandleDemo
y =
    19
 

L'handle di un'altra funzione esistente può essere passato a funHandleDemo :

>> y = funHandleDemo(@sin,-5)
y =
   -4.8589
 

Nota come @sin era un modo rapido per accedere alla funzione sin senza prima averlo memorizzato in una variabile usando f = @sin .

Utilizzo di bsxfun , cellfun e funzioni simili con funzioni anonime

MATLAB ha alcune funzioni integrate che accettano le funzioni anonime come input. Questo è un modo per eseguire molti calcoli con un numero minimo di linee di codice. Ad esempio bsxfun , che esegue operazioni binarie elemento per elemento, vale a dire: applica una funzione su due vettori o matrici in modo elemento per elemento. Normalmente, ciò richiederebbe l'uso di for -loops, che spesso richiede la preallocazione per la velocità. Usando bsxfun questo processo è velocizzato. Nell'esempio seguente viene illustrato questo utilizzo di tic e toc , due funzioni che possono essere utilizzate per calcolare quanto tempo richiede il codice. Calcola la differenza di ogni elemento della matrice dalla media della colonna della matrice.

A = rand(50); % 50-by-50 matrix of random values between 0 and 1

% method 1: slow and lots of lines of code
tic
meanA = mean(A); % mean of every matrix column: a row vector
% pre-allocate result for speed, remove this for even worse performance
result = zeros(size(A));
for j = 1:size(A,1)
    result(j,:) = A(j,:) - meanA;
end
toc
clear result % make sure method 2 creates its own result

% method 2: fast and only one line of code
tic
result = bsxfun(@minus,A,mean(A));
toc
 

L'esecuzione dell'esempio sopra comporta due output:

Elapsed time is 0.015153 seconds.
Elapsed time is 0.007884 seconds.
 

Queste linee provengono dalle funzioni di toc , che stampano il tempo trascorso dall'ultima chiamata alla funzione tic .

La chiamata bsxfun applica la funzione nel primo argomento di input agli altri due argomenti di input. @minus è un nome lungo per la stessa operazione che farebbe il segno meno. È possibile che sia stata specificata una funzione anonimo o handle ( @ ) diversa per qualsiasi altra funzione, purché accetta A e mean(A) come input per generare un risultato significativo.

Soprattutto per grandi quantità di dati in matrici di grandi dimensioni, bsxfun può velocizzare molto le cose. Rende anche il codice più pulito, anche se potrebbe essere più difficile da interpretare per le persone che non conoscono MATLAB o bsxfun . (Si noti che in MATLAB R2016a e versioni successive, molte operazioni che precedentemente utilizzavano bsxfun non ne hanno più bisogno: la A-mean(A) funziona direttamente e in alcuni casi può anche essere più veloce).

Matrici cellulari

Elementi della stessa classe possono spesso essere concatenati in array (con alcune rare eccezioni, ad esempio i manici di funzione). Gli scalari numerici, per impostazione predefinita del double della classe, possono essere memorizzati in una matrice.

>> A = [1, -2, 3.14, 4/5, 5^6; pi, inf, 7/0, nan, log(0)]
A =
   1.0e+04 *
    0.0001   -0.0002    0.0003    0.0001    1.5625
    0.0003       Inf       Inf       NaN      -Inf
 

I caratteri, che sono di classe char in MATLAB, possono anche essere archiviati in array usando una sintassi simile. Tale array è simile a una stringa in molti altri linguaggi di programmazione.

>> s = ['MATLAB ','is ','fun']
s =
MATLAB is fun
 

Si noti che nonostante entrambi utilizzino le parentesi [ e ] , le classi di risultati sono diverse. Pertanto le operazioni che possono essere eseguite su di loro sono anche diverse.

>> whos
  Name      Size            Bytes  Class     Attributes

  A         2x5                80  double              
  s         1x13               26  char                
 

In effetti, l'array s non è un array di 'MATLAB ' , 'is ' e 'fun' delle stringhe, è solo una stringa - una matrice di 13 caratteri. Otterresti gli stessi risultati se fosse definito da uno dei seguenti:

>> s = ['MAT','LAB ','is f','u','n'];
>> s = ['M','A','T','L','A','B,' ','i','s',' ','f','u','n'];
 

Un vettore MATLAB regolare non consente di memorizzare un mix di variabili di classi diverse o alcune stringhe diverse. Questo è dove l'array di cell è utile. Questa è una matrice di celle che ciascuna può contenere alcuni oggetti MATLAB, la cui classe può essere diversa in ogni cella, se necessario. Usa le parentesi graffe { e } intorno agli elementi per archiviarli in un array di celle.

>> C = {A; s}
C = 
    [2x5 double]
    'MATLAB is fun'
>> whos C
  Name      Size            Bytes  Class    Attributes

  C         2x1               330  cell 
 

Gli oggetti MATLAB standard di qualsiasi classe possono essere memorizzati insieme in un array di celle. Nota che gli array di celle richiedono più memoria per archiviare il loro contenuto.

L'accesso ai contenuti di una cella viene eseguito utilizzando parentesi graffe { e } .

>> C{1}
ans =
   1.0e+04 *
    0.0001   -0.0002    0.0003    0.0001    1.5625
    0.0003       Inf       Inf       NaN      -Inf
 

Si noti che C(1) è diverso da C{1} . Mentre il secondo restituisce il contenuto della cella (e ha un esempio di classe double in out), il primo restituisce un array di celle che è un sottoarray di C Allo stesso modo, se D fosse un array di 10 per 5 celle, D(4:8,1:3) restituirebbe un sub-array di D cui dimensione è 5 per 3 e la cui classe è cell . E la sintassi C{1:2} non ha un singolo oggetto restituito, ma rater restituisce 2 oggetti diversi (simile a una funzione MATLAB con più valori di ritorno):

>> [x,y] = C{1:2}
x =
                         1                        -2                      3.14                       0.8                     15625
          3.14159265358979                       Inf                       Inf                       NaN                      -Inf
y =
MATLAB is fun
 

Tipi di dati

Ci sono 16 tipi di dati fondamentali , o classi, in MATLAB. Ognuna di queste classi è sotto forma di matrice o matrice. Ad eccezione degli handle di funzione, questa matrice o array ha un minimo di 0 per 0 e può crescere fino a un array n-dimensionale di qualsiasi dimensione. Un handle di funzione è sempre scalare (1 per 1).

Momento importante in MATLAB è che non è necessario utilizzare dichiarazioni di tipo o dichiarazioni di dimensioni per impostazione predefinita. Quando si definisce una nuova variabile, MATLAB lo crea automaticamente e alloca lo spazio di memoria appropriato.

Esempio:

a = 123;
b = [1 2 3];
c = '123';

>> whos
  Name      Size            Bytes  Class     Attributes

  a         1x1                 8  double              
  b         1x3                24  double              
  c         1x3                 6  char    
 

Se la variabile esiste già, MATLAB sostituisce i dati originali con uno nuovo e alloca il nuovo spazio di archiviazione, se necessario.

Tipi di dati fondamentali

I tipi di dati fondamentali sono: numerico, logical , char , cell , struct , table e function_handle .

Tipi di dati numerici :

  • Numeri a virgola mobile ( predefinito )

    MATLAB rappresenta numeri in virgola mobile in formato a precisione doppia o precisione singola. L'impostazione predefinita è la precisione doppia, ma puoi eseguire qualsiasi numero con precisione singola con una semplice funzione di conversione:

    a = 1.23;
    b = single(a);
    
    >> whos
      Name      Size            Bytes  Class     Attributes
    
      a         1x1                 8  double              
      b         1x1                 4  single     
     
  • Interi

    MATLAB ha quattro classi firmate e quattro classi non firmate. I tipi firmati consentono di lavorare con numeri interi negativi e positivi, ma non possono rappresentare un intervallo di numeri come i tipi senza segno poiché un bit viene utilizzato per designare un segno positivo o negativo per il numero. I tipi senza segno ti offrono una gamma più ampia di numeri, ma questi numeri possono essere solo zero o positivi.

    MATLAB supporta la memorizzazione a 1, 2, 4 e 8 byte per i dati interi. È possibile risparmiare memoria e tempo di esecuzione per i programmi se si utilizza il tipo di numero più piccolo che ospita i dati. Ad esempio, non è necessario un numero intero a 32 bit per memorizzare il valore 100.

    a = int32(100);
    b = int8(100);
    
    >> whos
      Name      Size            Bytes  Class    Attributes
    
      a         1x1                 4  int32              
      b         1x1                 1  int8               
     

    Per memorizzare i dati come numero intero, è necessario convertire da doppio a tipo intero desiderato. Se il numero che viene convertito in un numero intero ha una parte frazionaria, MATLAB arrotonda il numero intero più vicino. Se la parte frazionaria è esattamente 0.5 , allora dai due interi ugualmente vicini, MATLAB sceglie quello per il quale il valore assoluto è maggiore in grandezza.

    a  = int16(456);
     
  • char

    Gli array di caratteri forniscono spazio per i dati di testo in MATLAB. In linea con la terminologia di programmazione tradizionale, una matrice (sequenza) di caratteri è definita come una stringa. Non esiste un tipo di stringa esplicito nelle versioni di vendita di MATLAB.

  • logico: valori logici di 1 o 0, rappresentano rispettivamente true e false. Utilizzare per condizioni relazionali e indicizzazione di array. Perché è solo VERO o FALSO ha una dimensione di 1 byte.

    a = logical(1);
     
  • struttura. Un array di strutture è un tipo di dati che raggruppa le variabili di diversi tipi di dati utilizzando contenitori di dati chiamati campi . Ogni campo può contenere qualsiasi tipo di dati. Accedere ai dati in una struttura utilizzando la notazione dei punti del nome structName.fieldName.

    field1 = 'first';
    field2 = 'second';
    value1 = [1 2 3 4 5];
    value2 = 'sometext';
    s = struct(field1,value1,field2,value2);
     

    Per accedere a value1, ciascuna delle seguenti sintassi è equivalente

    s.first or s.(field1) or s.('first')
     

    Possiamo accedere esplicitamente a un campo che sappiamo esistere con il primo metodo o passare una stringa o creare una stringa per accedere al campo nel secondo esempio. Il terzo esempio dimostra che la notazione punto genitore prende una stringa, che è la stessa memorizzata nella variabile field1.

  • le variabili di tabella possono essere di dimensioni e tipi di dati diversi, ma tutte le variabili devono avere lo stesso numero di righe.

    Age = [15 25 54]';
    Height = [176 190 165]';
    Name = {'Mike', 'Pete', 'Steeve'}';
    T = table(Name,Age, Height);
     
  • cellula. È molto utile il tipo di dati MATLAB: l'array di celle è un array in cui ogni elemento può essere di tipo e dimensioni di dati diversi. È uno strumento molto potente per manipolare i dati come desideri.

    a = { [1 2 3], 56, 'art'};
     

    o

    a = cell(3);
     
  • la funzione gestisce memorizza un puntatore a una funzione (ad esempio, alla funzione anonima). Ti consente di passare una funzione a un'altra funzione o di chiamare funzioni locali dall'esterno della funzione principale.

Ci sono molti strumenti per lavorare con ogni tipo di dati e anche funzioni di conversione dei tipi di dati incorporate ( str2double , table2cell ).

Altri tipi di dati

Esistono diversi tipi di dati aggiuntivi che sono utili in alcuni casi specifici. Loro sono:

  • Data e ora: matrici per rappresentare le date, l'ora e la durata. datetime('now') restituisce 21-Jul-2016 16:30:16 .

  • Array categoriali: è il tipo di dati per la memorizzazione di dati con valori da un insieme di categorie discrete. Utile per la memorizzazione di dati non numerici (memoria efficace). Può essere utilizzato in una tabella per selezionare gruppi di righe.

    a = categorical({'a' 'b' 'c'});
     
  • I contenitori di mappe sono una struttura di dati che ha una capacità unica di indicizzazione non solo attraverso i valori numerici scalari ma il vettore di caratteri. Gli indici negli elementi di una mappa sono chiamati chiavi. Queste chiavi, insieme ai valori dei dati associati ad esse, sono memorizzate all'interno della Mappa.

  • Le serie temporali sono vettori di dati campionati nel tempo, in ordine, spesso a intervalli regolari. È utile memorizzare i dati connessi ai timestep e ha molti metodi utili con cui lavorare.

Ciao mondo

Apri un nuovo documento vuoto nell'editor MATLAB (nelle versioni recenti di MATLAB, fai questo selezionando la scheda Home della barra degli strumenti e facendo clic su Nuovo script). La scorciatoia da tastiera predefinita per creare un nuovo script è Ctrl-n .

In alternativa, digitando edit myscriptname.m si aprirà il file myscriptname.m per la modifica o si offrirà di creare il file se non esiste sul percorso MATLAB.

Nell'editor, digitare quanto segue:

disp('Hello, World!');
 

Seleziona la scheda Editor della barra degli strumenti e fai clic su Salva come. Salva il documento in un file nella directory corrente chiamato helloworld.m . Salvando un file senza titolo verrà visualizzata una finestra di dialogo per denominare il file.

Nella finestra di comando MATLAB, digitare quanto segue:

>> helloworld
 

Dovresti vedere la seguente risposta nella finestra di comando MATLAB:

Hello, World!
 

Vediamo che nella finestra di comando, siamo in grado di digitare i nomi delle funzioni o dei file di script che abbiamo scritto, o che sono forniti con MATLAB, per eseguirli.

Qui, abbiamo eseguito lo script 'helloworld'. Si noti che la digitazione dell'estensione ( .m ) non è necessaria. Le istruzioni contenute nel file di script sono eseguite da MATLAB, qui viene stampato 'Hello, World!' usando la funzione disp .

I file di script possono essere scritti in questo modo per salvare una serie di comandi da riutilizzare in seguito.

Aiutare te stesso

MATLAB è dotato di molti script e funzioni incorporati che vanno dalla semplice moltiplicazione a toolbox per il riconoscimento di immagini. Per ottenere informazioni su una funzione che si desidera utilizzare digitare: help functionname nella riga di comando. Consente di prendere l' help funzione di come esempio.

Informazioni su come usarlo possono essere ottenute digitando:

>> help help

nella finestra di comando. Ciò restituirà informazioni sull'uso della funzione di help . Se le informazioni che stai cercando non sono ancora chiare, puoi provare la pagina di documentazione della funzione. Basta digitare:

>> doc help

nella finestra di comando. Questo aprirà la documentazione sfogliabile nella pagina per l' help funzioni fornendo tutte le informazioni necessarie per capire come funziona l''aiuto'.

Questa procedura funziona per tutte le funzioni e i simboli incorporati.

Quando sviluppi le tue funzioni puoi lasciare che abbiano la loro sezione di aiuto aggiungendo commenti nella parte superiore del file di funzione o subito dopo la dichiarazione della funzione.

Esempio per una funzione semplice multiplyby2 salvata nel file multiplyby2.m

function [prod]=multiplyby2(num)
% function MULTIPLYBY2 accepts a numeric matrix NUM and returns output PROD 
% such that all numbers are multiplied by 2

    prod=num*2;
end
 

o

% function MULTIPLYBY2 accepts a numeric matrix NUM and returns output PROD 
% such that all numbers are multiplied by 2

function [prod]=multiplyby2(num)
    prod=num*2;
end
 

Questo è molto utile quando raccogli il codice settimane / mesi / anni dopo averlo scritto.

La funzione help e doc fornisce molte informazioni, imparando come utilizzare queste funzionalità per progredire rapidamente e utilizzare MATLAB in modo efficiente.

Matrici e matrici di indicizzazione

MATLAB consente diversi metodi per indicizzare (accedere) elementi di matrici e matrici:

  • Indicizzazione del pedice - dove si specifica la posizione degli elementi che si desidera in ciascuna dimensione della matrice separatamente.
  • Indicizzazione lineare - in cui la matrice viene trattata come un vettore, indipendentemente dalle sue dimensioni. Ciò significa che si specifica ciascuna posizione nella matrice con un singolo numero.
  • Indicizzazione logica : in cui si utilizza una matrice logica (e una matrice di valori true e false ) con le dimensioni identiche della matrice che si tenta di indicizzare come maschera per specificare quale valore restituire.

Questi tre metodi sono ora spiegati in maggior dettaglio usando la seguente matrice 3 per 3 M come esempio:

>> M = magic(3)

ans = 

       8    1    6
       3    5    7
       4    9    2
 

Indicizzazione degli indici

Il metodo più diretto per accedere a un elemento consiste nel specificare il suo indice di riga-colonna. Ad esempio, accedendo all'elemento sulla seconda riga e sulla terza colonna:

>> M(2, 3)

ans =

      7
 

Il numero di pedici forniti corrisponde esattamente al numero di dimensioni che M ha (due in questo esempio).

Si noti che l'ordine degli indici è lo stesso della convenzione matematica: l'indice di riga è il primo. Inoltre, gli indici MATLAB iniziano con 1 e non 0 come la maggior parte dei linguaggi di programmazione.

È possibile indicizzare più elementi contemporaneamente passando un vettore per ogni coordinata anziché un singolo numero. Ad esempio per ottenere l'intera seconda riga, possiamo specificare che vogliamo la prima, la seconda e la terza colonna:

>> M(2, [1,2,3])

ans =

       3    5    7
 

In MATLAB, il vettore [1,2,3] è più facilmente creato usando l'operatore colon, ovvero 1:3 . Puoi usare questo anche nell'indicizzazione. Per selezionare un'intera riga (o colonna), MATLAB fornisce una scorciatoia consentendo semplicemente di specificare : Ad esempio, il codice seguente restituirà anche l'intera seconda riga

>> M(2, :)

ans =

       3    5    7
 

MATLAB fornisce anche una scorciatoia per specificare l'ultimo elemento di una dimensione nella forma della parola chiave di end . La parola chiave end funzionerà esattamente come se fosse il numero dell'ultimo elemento in quella dimensione. Quindi se vuoi che tutte le colonne dalla colonna 2 all'ultima colonna, puoi usare scrivi quanto segue:

>> M(2, 2:end)

ans =

       5    7
 

L'indicizzazione del pedice può essere restrittiva in quanto non consente di estrarre singoli valori da diverse colonne e righe; estrarrà la combinazione di tutte le righe e colonne.

>> M([2,3], [1,3])
ans =

       3    7
       4    2
 

Ad esempio, l'indicizzazione del pedice non può estrarre solo gli elementi M(2,1) o M(3,3) . Per fare ciò, dobbiamo considerare l'indicizzazione lineare.

Indicizzazione lineare

MATLAB consente di trattare gli array n-dimensionali come matrici unidimensionali quando si indice utilizzando solo una dimensione. Puoi accedere direttamente al primo elemento:

>> M(1)

ans = 

       8
 

Nota che gli array sono memorizzati nell'ordine delle colonne in MATLAB, il che significa che accederai agli elementi facendo prima scendere le colonne. Quindi M(2) è il secondo elemento della prima colonna che è 3 e M(4) sarà il primo elemento della seconda colonna cioè

>> M(4)

ans = 

        1
 

Esistono funzioni incorporate in MATLAB per convertire gli indici degli indici in indici lineari e viceversa: sub2ind e ind2sub rispettivamente. Puoi convertire manualmente i pedici ( r , c ) in un indice lineare di

idx = r + (c-1)*size(M,1)
 

Per capire questo, se siamo nella prima colonna, l'indice lineare sarà semplicemente l'indice di riga. La formula sopra riportata vale per questo perché per c == 1 , (c-1) == 0 . Nelle colonne successive, l'indice lineare è il numero di riga più tutte le righe delle colonne precedenti.

Si noti che la parola chiave di end si applica ancora e ora si riferisce all'ultimo elemento della matrice cioè M(end) == M(end, end) == 2 .

Puoi anche indicizzare più elementi usando l'indicizzazione lineare. Nota che se lo fai, la matrice restituita avrà la stessa forma della matrice dei vettori di indice.

M(2:4) restituisce un vettore di riga perché 2:4 rappresenta il vettore di riga [2,3,4] :

>> M(2:4)

ans =

        3    4    1
 

Come altro esempio, M([1,2;3,4]) restituisce una matrice 2 per 2 perché [1,2;3,4] è anche una matrice 2 per 2. Vedi il codice qui sotto per convincerti:

>> M([1,2;3,4])

ans =

       8        3
       4        1
 

Si noti che l'indicizzazione con : da sola restituirà sempre un vettore di colonna:

>> M(:)

ans = 

        8
        3
        4
        1
        5
        9
        6
        7
        2
 

Questo esempio illustra anche l'ordine in cui MATLAB restituisce elementi quando si utilizza l'indicizzazione lineare.

Indicizzazione logica

Il terzo metodo di indicizzazione consiste nell'utilizzare una matrice logica, ovvero una matrice contenente solo valori true o false , come maschera per filtrare gli elementi che non si desidera. Ad esempio, se vogliamo trovare tutti gli elementi di M maggiori di 5 , possiamo usare la matrice logica

>> M > 5

ans =

    1    0    1
    0    0    1
    0    1    0
 

per indicizzare M e restituire solo i valori superiori a 5 come segue:

>> M(M > 5)

ans =

        8
        9
        6
        7
 

Se si desidera che questi numeri rimangano in posizione (ovvero mantengano la forma della matrice), è possibile assegnare il complimento logico

>> M(~(M > 5)) = NaN

ans = 

    8      NaN    6
    NaN    NaN    7
    NaN    9      Nan
 

Possiamo ridurre complicati blocchi di codice contenenti if e for istruzioni utilizzando l'indicizzazione logica.

Prendi il non vettorizzato (già abbreviato in un singolo ciclo usando l'indicizzazione lineare):

for elem = 1:numel(M)
  if M(elem) > 5
    M(elem) = M(elem) - 2;
  end
end
 

Questo può essere abbreviato con il seguente codice usando l'indicizzazione logica:

idx = M > 5;
M(idx) = M(idx) - 2;
 

O ancora più corto:

M(M > 5) = M(M > 5) - 2;
 

Maggiori informazioni sull'indicizzazione

Matrici di dimensione superiore

Tutti i metodi sopra menzionati si generalizzano in n-dimensioni. Se usiamo la matrice tridimensionale M3 = rand(3,3,3) come esempio, allora puoi accedere a tutte le righe e le colonne della seconda porzione della terza dimensione scrivendo

>> M(:,:,2)
 

È possibile accedere al primo elemento della seconda sezione utilizzando l'indicizzazione lineare. L'indicizzazione lineare passerà alla seconda sezione solo dopo tutte le righe e tutte le colonne della prima sezione. Quindi l'indice lineare per quell'elemento è

>> M(size(M,1)*size(M,2)+1)
 

Infatti, in MATLAB, ogni matrice è n-dimensionale: è solo che le dimensioni della maggior parte delle altre n-dimensioni sono una. Quindi, se a = 2 allora a(1) == 2 (come ci si aspetterebbe), ma anche a(1, 1) == 2 , così come a(1, 1, 1) == 2 , a(1, 1, 1, ..., 1) == 2 e così via. Queste dimensioni "extra" (di dimensione 1 ), sono indicate come dimensioni singleton . Il comando squeeze li rimuoverà e uno può usare permute per scambiare l'ordine delle dimensioni intorno (e introdurre le dimensioni singleton se necessario).

Una matrice n-dimensionale può anche essere indicizzata usando m subscripts (dove m <= n). La regola è che i primi indici m-1 si comportano normalmente, mentre l'ultimo (m'th) indice fa riferimento alle restanti dimensioni (n-m + 1), proprio come un indice lineare farebbe riferimento a un (n-m + 1) dimensionale array. Ecco un esempio:

>> M = reshape(1:24,[2,3,4]);
>> M(1,1)
ans =
     1
>> M(1,10)
ans =
    19
>> M(:,:)
ans =
     1     3     5     7     9    11    13    15    17    19    21    23
     2     4     6     8    10    12    14    16    18    20    22    24
 

Restituire intervalli di elementi

Con l'indicizzazione del pedice, se si specifica più di un elemento in più di una dimensione, MATLAB restituisce ciascuna coppia possibile di coordinate. Ad esempio, se provi M ([1,2], [1,3]) MATLAB restituirà M(1,1) e M(2,3) ma restituirà anche M(1,3) e M(2,1) . Questo può sembrare non intuitivo quando si cercano gli elementi per un elenco di coppie di coordinate, ma si consideri l'esempio di una matrice più grande, A = rand(20) (la nota A è ora 20 -by- 20 ), dove si desidera ottenere il quadrante in alto a destra. In questo caso invece di dover specificare ogni coppia di coordinate in quel quadrante (e questo in questo caso sarebbe 100 coppie), devi solo specificare le 10 righe e le 10 colonne che vuoi così A(1:10, 11:end) . Affettare una matrice come questa è molto più comune che richiedere un elenco di coppie di coordinate.

Nel caso in cui si desideri ottenere un elenco di coppie di coordinate, la soluzione più semplice è quella di convertire in indicizzazione lineare. Si consideri il problema in cui si ha un vettore di indici di colonna che si desidera restituire, in cui ogni riga del vettore contiene il numero di colonna che si desidera restituire per la riga corrispondente della matrice. Per esempio

colIdx = [3;2;1]
 

Quindi in questo caso in realtà vuoi recuperare gli elementi a (1,3) , (2,2) e (3,1) . Quindi usando l'indicizzazione lineare:

>> colIdx = [3;2;1];
>> rowIdx = 1:length(colIdx);
>> idx = sub2ind(size(M), rowIdx, colIdx);
>> M(idx)

ans = 

        6    5    4
 

Restituzione di un elemento più volte

Con indice e indicizzazione lineare puoi anche restituire un elemento più volte ripetendo il suo indice in modo tale

>> M([1,1,1,2,2,2])

ans = 

        8    8    8    3    3    3
 

Puoi usarlo per duplicare intere righe e colonne, per esempio per ripetere la prima riga e l'ultima colonna

>> M([1, 1:end], [1:end, end])

ans = 

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

Per ulteriori informazioni, vedere qui .

Matrici e matrici

In MATLAB, il tipo di dati più semplice è l'array numerico. Può essere uno scalare, un vettore 1-D, una matrice 2-D o un array multidimensionale ND.

% a 1-by-1 scalar value
x = 1;
 

Per creare un vettore riga, inserisci gli elementi tra parentesi, separati da spazi o virgole:

% a 1-by-4 row vector
v = [1, 2, 3, 4];
v = [1 2 3 4];
 

Per creare un vettore colonna, separa gli elementi con punto e virgola:

% a 4-by-1 column vector
v = [1; 2; 3; 4];
 

Per creare una matrice, inseriamo le righe come prima separate da punto e virgola:

% a 2 row-by-4 column matrix
M = [1 2 3 4; 5 6 7 8];

% a 4 row-by-2 column matrix
M = [1 2; ...
     4 5; ...
     6 7; ...
     8 9];
 

Si noti che non è possibile creare una matrice con dimensioni di riga / colonna non uguali. Tutte le righe devono avere la stessa lunghezza e tutte le colonne devono avere la stessa lunghezza:

% an unequal row / column matrix
M = [1 2 3 ; 4 5 6 7]; % This is not valid and will return an error

% another unequal row / column matrix
M = [1 2 3; ...
     4   5; ...
     6 7 8; ...
     9   10];     % This is not valid and will return an error
 

Per trasporre un vettore o una matrice, usiamo il .' -operatore, o ' operatore a prendere il suo coniugato ermetico, che è il complesso coniugato della sua trasposizione. Per le matrici reali, questi due sono gli stessi:

% create a row vector and transpose it into a column vector
v = [1 2 3 4].';              % v is equal to [1; 2; 3; 4];

% create a 2-by-4 matrix and transpose it to get a 4-by-2 matrix
M = [1 2 3 4; 5 6 7 8].';     % M is equal to [1 5; 2 6; 3 7; 4 8]

% transpose a vector or matrix stored as a variable
A = [1 2; 3 4];
B = A.';                      % B is equal to [1 3; 2 4]
 

Per matrici di più di due dimensioni, non esiste una sintassi di linguaggio diretta per inserirle letteralmente. Invece dobbiamo usare le funzioni per costruirle (come ones , zeros , rand ) o manipolando altri array (usando funzioni come cat , reshape , permute ). Qualche esempio:

% a 5-by-2-by-4-by-3 array (4-dimensions)
arr = ones(5, 2, 4, 3);

% a 2-by-3-by-2 array (3-dimensions)
arr = cat(3, [1 2 3; 4 5 6], [7 8 9; 0 1 2]);

% a 5-by-4-by-3-by-2 (4-dimensions)
arr = reshape(1:120, [5 4 3 2]);
 

Lettura di input e scrittura

Proprio come tutti i linguaggi di programmazione, Matlab è progettato per leggere e scrivere in un'ampia varietà di formati. La libreria nativa supporta un gran numero di formati di testo, immagini, video, audio, dati con più formati inclusi in ogni aggiornamento di versione - controlla qui per vedere l'elenco completo dei formati di file supportati e quale funzione utilizzare per importarli.

Prima di tentare di caricare il file, è necessario chiedersi cosa si desidera che i dati diventino e in che modo si aspetta che il computer organizzi i dati per conto dell'utente. Supponi di avere un file txt / csv nel seguente formato:

Fruit,TotalUnits,UnitsLeftAfterSale,SellingPricePerUnit
Apples,200,67,$0.14
Bananas,300,172,$0.11
Pineapple,50,12,$1.74
 

Possiamo vedere che la prima colonna è nel formato di stringhe, mentre la seconda, la terza è numerica, l'ultima colonna è in forma di valuta. Diciamo che vogliamo scoprire quante entrate abbiamo fatto oggi usando Matlab e prima vogliamo caricare in questo file txt / csv. Dopo aver controllato il collegamento, possiamo vedere che il tipo String e Numeric di file txt sono gestiti da textscan . Quindi potremmo provare:

fileID = fopen('dir/test.txt'); %Load file from dir
C = textscan(fileID,'%s %f %f %s','Delimiter',',','HeaderLines',1); %Parse in the txt/csv
 

dove %s suggerisce che l'elemento sia di tipo String, %f suggerisce che l'elemento sia di tipo Float e che il file sia Delimitato da ",". L'opzione HeaderLines chiede a Matlab di saltare le prime righe N mentre l'1 immediatamente dopo significa saltare la prima riga (la linea dell'intestazione).

Ora C è il dato che abbiamo caricato che ha la forma di una matrice di celle di 4 celle, ciascuna contenente la colonna di dati nel file txt / csv.

Quindi per prima cosa vogliamo calcolare quanti frutti abbiamo venduto oggi sottraendo la terza colonna dalla seconda colonna, questo può essere fatto da:

sold = C{2} - C{3}; %C{2} gives the elements inside the second cell (or the second column)
 

Ora vogliamo moltiplicare questo vettore per il Prezzo per unità, quindi prima dobbiamo convertire quella colonna di stringhe in una colonna di numeri, quindi convertirla in una matrice numerica usando la cell2mat di Matlab la prima cosa che dobbiamo fare è strisciare- fuori dal segno "$", ci sono molti modi per farlo. Il modo più diretto è usare una semplice regex:

D = cellfun(@(x)(str2num(regexprep(x, '\$',''))), C{4}, 'UniformOutput', false);%cellfun allows us to avoid looping through each element in the cell.
 

Oppure puoi usare un loop:

for t=1:size(C{4},1)
   D{t} = str2num(regexprep(C{4}{t}, '\$',''));
end

E = cell2mat(D)% converts the cell array into a Matrix
 

La funzione str2num trasforma la stringa che ha i segni "$" spogliati in tipi numerici e cell2mat trasforma la cella di elementi numerici in una matrice di numeri

Ora possiamo moltiplicare le unità vendute per il costo per unità:

revenue = sold .* E; %element-wise product is denoted by .* in Matlab

totalrevenue = sum(revenue);
 

Script e funzioni

Il codice MATLAB può essere salvato in m-files da riutilizzare. m-files hanno l'estensione .m che viene automaticamente associata a MATLAB. Un m-file può contenere uno script o funzioni.

Script

Gli script sono semplicemente file di programma che eseguono una serie di comandi MATLAB in un ordine predefinito.

Gli script non accettano input, né gli script restituiscono l'output. Funzionalmente, gli script sono equivalenti a digitare comandi direttamente nella finestra di comando di MATLAB ed essere in grado di riprodurli.

Un esempio di script:

length = 10;
width = 3;
area = length * width;
 

Questo script definirà la length , la width e l' area nello spazio di lavoro corrente con i valori 10 , 3 e 30 rispettivamente.

Come detto prima, lo script di cui sopra è funzionalmente equivalente a digitare gli stessi comandi direttamente nella finestra di comando.

>> length = 10;
>> width = 3;
>> area = length * width;
 

funzioni

Le funzioni, se confrontate con gli script, sono molto più flessibili ed estensibili. A differenza degli script, le funzioni possono accettare input e restituire l'output al chiamante. Una funzione ha il proprio spazio di lavoro, ciò significa che le operazioni interne delle funzioni non modificheranno le variabili dal chiamante.

Tutte le funzioni sono definite con lo stesso formato di intestazione:

function [output] = myFunctionName(input)
 

La parola chiave function inizia ogni intestazione di funzione. Segue la lista delle uscite. L'elenco di output può anche essere un elenco separato da virgole di variabili da restituire.

function [a, b, c] = myFunctionName(input)
 

Il prossimo è il nome della funzione che verrà utilizzata per la chiamata. Questo è generalmente lo stesso nome del nome del file. Ad esempio, salveremmo questa funzione come myFunctionName.m .

Seguendo il nome della funzione è presente l'elenco degli input. Come le uscite, anche questa può essere una lista separata da virgole.

function [a, b, c] = myFunctionName(x, y, z)
 

Possiamo riscrivere lo script di esempio di prima come una funzione riutilizzabile come la seguente:

function [area] = calcRecArea(length, width)
   area = length * width;
end
 

Possiamo chiamare funzioni da altre funzioni o anche da file di script. Ecco un esempio della nostra funzione precedente utilizzata in un file di script.

l = 100;
w = 20;
a = calcRecArea(l, w);
 

Come prima, creiamo l , w e a nello spazio di lavoro con i valori rispettivamente di 100 , 20 e 2000 .