Numeri complessi in MATLAB

Nella precedenti lezioni è stato introdotto il concetto di tipo e il tipo base fornito da MATLAB: i numeri reali. In particolare, il tipo double che viene usato per rappresentare i numeri reali.

In questa lezione parleremo, invece, di come usare i numeri complessi in MATLAB.

Tipo complex

Uno dei punti di forza di MATLAB è quello di supportare nativamente i numeri complessi.

Per introdurre un numero complesso è sufficiente utilizzare l'unità immaginaria. In MATLAB, esistono due modi per specificare l'unità immaginaria: i e j. Del resto, anche nei testi matematici, scientifici e ingegneristici esistono due notazioni per l'unità immaginaria: i e j. Questo perché, sui libri di ingegneria, si tende ad usare j per evitare di confondere i intesa come unità immaginaria da i che può rappresentare una corrente elettrica.

Proviamo a creare una variabile complessa del valore di 2 + 3i:

>> x = 2 + 3 * i

x =

   2.0000 + 3.0000i

Come si evince dall'esempio, è stato sufficiente inserire il numero complesso come un'espressione con l'unità immaginaria.

A questo punto è interessante osservare l'output di whos:

>> whos
  Name      Size            Bytes  Class     Attributes

  x         1x1                16  double    complex   

La prima cosa da notare è che la classe riportata è comunque double. Ciò significa che MATLAB utilizza, di default, per i numeri complessi la precisione doppia. L'attributo della variabile è però complex che ci indica trattarsi di un numero complesso.

La seconda, e più importante, cosa da notare è il numero di byte impiegati per memorizzare x: 16 byte, in altre parole il doppio rispetto ad un numero reale in doppia precisione. Del resto è normale questo risultato, in quanto, per ogni numero complesso MATLAB deve memorizzare due numeri: il primo rappresenta la parte reale, il secondo la parte immaginaria.

MATLAB, anche se può sembrar strano, utilizza comunque 16 byte per memorizzare anche i numeri immaginari, anche se quest'ultimi hanno la parte reale pari a 0 e, pertanto, ne potrebbero fare a meno. Questa è una scelta tecnica dei realizzatori di MATLAB che, senza entrare nel dettaglio, ha le sue buone ragioni. Come esempio, osserviamo questo output:

>> x = 3 * i;
>> whos
  Name      Size            Bytes  Class     Attributes

  x         1x1                16  double    complex   

Anche se x è un numero immaginario, MATLAB comunque utilizza 16 byte.

Nel caso dei numeri complessi, ovviamente, le funzioni realmax e realmin non hanno senso, in quanto non esiste un ordinamento tra i numeri complessi, i.e. non ha senso di parlare di "maggiore" o "minore" tra due numeri complessi.

Funzione complex

Esiste anche un metodo alternativo per la creazione di un numero complesso: la funzione complex. Basta passare a questa funzione, come parametri, la parte reale e immaginaria:

>> complex(2, 4)

ans =

   2.0000 + 4.0000i

Inoltre, se il numero da rappresentare ha la parte immaginaria pari a 0, è possibile invocare complex con un solo parametro:

>> complex(3.1)

ans =

   3.1000 + 0.0000i

Il risultato sarà sempre un numero complesso con la parte immaginaria pari a 0.

Funzioni real e imag

MATLAB mette a disposizione le due funzioni real e imag per estrarre la parte reale e la parte immaginaria, rispettivamente, di un numero complesso:

>> x = complex(8.1, 3.7)

x =

   8.1000 + 3.7000i

>> real(x)

ans =

    8.1000

>> imag(x)

ans =

    3.7000

Bisogna tener presente che il risultato di queste due funzioni è un numero reale. Del resto un numero complesso viene rappresentato con l'utilizzo di due numeri reali:

>> y = imag(x)

y =

    3.7000

>> whos
  Name      Size            Bytes  Class     Attributes

  x         1x1                16  double    complex   
  y         1x1                 8  double              

Funzione isreal

La funzione isreal può essere utilizzata per verificare se una variabile può essere assimilata ad un numero reale oppure no:

>> isreal(2.1)

ans =

  logical

   1

>> isreal(3 + 2 * i)

ans =

  logical

   0

>> isreal(i ^ 2)

ans =

  logical

   1

Il risultato è un logical, i.e. un tipo che può assumere il valore 1 (vero) o 0 (falso). Studieremo il tipo booleano nelle prossime lezioni.

Interessante da notare è l'ultimo risultato. Infatti, sebbene abbiamo usato l'unità immaginaria (che matlab rappresenta come numero complesso a 16 byte) nell'espressione, il risultato di isreal è 1. Questo perché, dato che i ^ {2} = -1, MATLAB si accorge che il risultato ha la parte immaginaria pari a 0 e, pertanto, salva il risultato in un double anziché in un complex riducendo la memoria richiesta. Questa ottimizzazione automatica è una delle tante che MATLAB esegue sotto il cofano. In altri linguaggi, infatti, ciò non avviene. Come ulteriore esempio, osservate l'output mostrato di sotto:

>> x = 1 + 2 * i

x =

   1.0000 + 2.0000i

>> y = 3 - 2 * i

y =

   3.0000 - 2.0000i

>> z = x + y

z =

     4

>> whos
  Name      Size            Bytes  Class     Attributes

  x         1x1                16  double    complex   
  y         1x1                16  double    complex   
  z         1x1                 8  double              

Dato che il risultato dell'espressione che andremo a memorizzare in z ha la parte immaginaria pari a 0, MATLAB sceglie di usare come tipo per z il double.

Funzioni abs e angle

Normalmente MATLAB rappresenta i numeri complessi utilizzando la rappresentazione cartesiana, ossia salvando la parte reale e immaginaria.

Matematicamente, tuttavia, è possibile rappresentare un numero complesso utilizzando la rappresentazione polare o esponenziale:

a + b \cdot \mathrm{i} = \rho \cdot \left( \cos \theta + \mathrm{i} \cdot \sin \theta \right) = \rho \cdot e ^ {\mathrm{i} \cdot \theta}

dove \rho rappresenta il modulo e \theta l'argomento o fase.

In MATLAB, un numero complesso sarà sempre rappresentato internamente in forma cartesiana, tuttavia è possibile utilizzare le funzioni abs e angle per estrarre, rispettivamente, modulo e fase:

>> x = 3 + 4 * i

x =

   3.0000 + 4.0000i

>> modulo = abs(x)

modulo =

     5

>> fase = angle(x)

fase =

    0.9273

Passare, invece, dalla rappresentazione polare a quella cartesiana è molto semplice. Basta introdurre l'espressione canonica della rappresentazione polare (o esponenziale):

>> modulo * (cos(fase) + i * sin(fase))

ans =

   3.0000 + 4.0000i

>> modulo * exp(i * fase)

ans =

   3.0000 + 4.0000i

funzione conj

Un'altra utile funzione che MATLAB mette a disposizione per i numeri complessi è la funzione conj.

Questa funzione calcola il complesso coniugato di un numero complesso:

z = \left(a + \mathrm{i} \cdot b \right)
z ^ {*} = \left(a - \mathrm{i} \cdot b \right)

Per cui, ad esempio:

>> x = 3 + 4i

x =

   3.0000 + 4.0000i

>> conj(x)

ans =

   3.0000 - 4.0000i

Ovviamente, se l'argomento di conj è un numero reale, la funzione non avrà effetto:

>> conj(4)

ans =

     4

Tipo single complex

Come abbiamo visto nel corso di questa lezione, MATLAB rappresenta i numeri complessi utilizzando due numeri double, quindi utilizzando 16 byte (o 128 bit).

Analogamente al discorso fatto nella lezione sui tipi double e single, anche per i numeri complessi è possibile dimezzare la dimensione utilizzata. Basta utilizzare sempre la funzione single:

>> x = single(complex(3, 4))

x =

  single

   3.0000 + 4.0000i

>> whos
  Name      Size            Bytes  Class     Attributes

  x         1x1                 8  single    complex   

Come si può vedere dall'esempio il numero di byte utilizzati da un single complex è pari a 8, ossia due single da 4 byte ciascuno. Anche in questo caso valgono le stesse considerazioni sui single che abbiamo fatto nell'altra lezione.

Riassumendo

In questa lezione abbiamo esaminato come sia possibile in MATLAB adoperare i numeri complessi attraverso il tipo complex. In particolare, abbiamo visto come inserire l'unità immaginaria utilizzando sia i che j.

Abbiamo anche visto alcune utili funzioni che lavorano sui complessi:

  • isreal: che restituisce 1 o 0 a seconda se l'argomento possa essere ridotto o meno ad un numero reale.
  • real e imag per estrarre, rispettivamente, la parte reale e immaginaria di un numero complesso.
  • abs e angle per estrarre, rispettivamente, modulo e fase di un numero complesso.
  • complex per creare un numero complesso a partire da due numeri reali che rappresentano parte reale e parte immaginaria.

Nella prossima lezione parleremo, invece, dei Numeri interi, un altro tipo che MATLAB mette a disposizione.