Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
algebrica.
*************************************
* dichiarare e usare numeri complessi
...proprio come se fossero dei double o float:
Es.
--double x, y;
double v[10];
x = y;
Complex x, y;
Complex v[10];
x = y;
double *p=&x;
double *q;
p = new double;
q = new double[10];
Complex
Complex
p = new
q = new
delete p;
delete [] q;
delete p;
delete [] q;
*p=&x;
*q;
Complex;
Complex[10];
******************************
* dichiararli e inizializzarli
Complex
Complex
Complex
Complex
Complex
x;
x();
x=Complex();
*x = new Complex;
*x = new Complex();
//
//
//
//
//
inizializzato a 0+0j
idem
idem
idem
idem
*******************************************************
* per conoscere modulo, fase, parte reale e immaginaria
Complex x;
Complex *y = new Complex;
float a;
if (x.Re == y->Im)
...
a = x.Modulus();
// oppure x.Phase()
a = y->Modulus();
// oppure y.Phase()
usate la sintassi che pi
a = Modulus(x);
a = Phase(*y);
// sintassi
// tradizionale
************************************
* operazioni algebriche fondamentali
le operazioni pi semplici (somma, sottrazione) sono implementate
come macro (cio funzioni inline) per ragioni di efficienza.
*********************
* somma e sottrazione
Complex
Complex
Complex
c = a +
Complex
d=-d;
d=+d;
a (1, 2);
b (3, 4);
c;
b;
d=b-a;
//
//
//
//
ora
ora
ora
ora
c
d
d
d
4+6j
2+2j
-2-2j
invariato
d+=a;
d-=a;
// ora d
// ora d
-1+0j
di nuovo -2-2j
********************
* moltiplicazione e divisione
Complex a (1, 2);
Complex b (3, 4);
Complex c=a*b;
Complex d=a/b;
d/=5; b*=a;
// ora c -5+10j
// ora d 0.44+0.08j
// operazioni lecite
***********
* confronti
ecco i confronti che hanno senso con i numeri complessi
if (a==b)
...
if (a!=b)
...
if (a==Complex(1,2))
...
// se a
uguale a 1+2j
if (a!=0)
...
// se a non
if (a!=Complex(0,3))
...
// se a
il complesso nullo
diverso da 3j
**************
* coniugazione
Complex a(1,2);
a=~a;
// a 1+2j
// ora a
1-2j
*****************
* radice quadrata
basta chiamare la funzione sqrt, come si fa con i double;
a differenza di sqrt(double), la sqrt(Complex) non pone
mai problemi, poich
sempre calcolabile.
I risultati sono sempre due. sqrt restituisce una radice,
l'altra
la radice sostituita cambiata di segno:
Complex a(1,2);
Complex rad1=sqrt(a);
Complex rad2=-rad1;
Se volete usare una sintassi meno vicino a quella del C,
e pi vicina alla programmazione ad oggetti,
potete richiamare la stessa funzione anche come metodo:
Complex a(1,2);
a=a.sqrt();
// adesso a vale circa 1.27+0.78j
*******************************
* conversioni in double o float
La classe non
provvista di operatori di cast per la conversione
(anche implicita) di un numero complesso in double o float.
La conversione potrebbe essere definita semplicemente scartando la
parte immaginaria. Ma questo non stato fatto, perch introduce
ambiguit : una espressione tipo 5-a dove a un Complex produce
un errore, poich il compilatore non sa se applicare la conversione
di a in double ed effettuare poi:
5-parte reale di a
oppure se convertire 5 in un numero complesso ed effettuare la
sottrazione di numeri complessi. Il problema una ambiguit
dovuta all'overloading. Ecco i messaggi di errore prodotti
da gcc quando un 5-a viene incontrato ed
stato definito
l'operatore di cast:
operator float() { return Re; }
Error: ambiguous overload for `int - Complex &'
Error: candidates are: operator -(int, float) <builtin>
Error: struct Complex operator -(const Complex &, const Complex &)
Un cast nell'espressione risolverebbe l'ambiguit :
(Complex)5-a
tuttavia ho preferito non implementare gli operatori di cast
ritenendo noioso per l'utente utilizzare questi cast.
Del resto la conversione Complex->double o float rara e
comunque meglio che sia indicata esplicitamente dove richiesta,
riferendosi direttamente alla parte reale o immaginaria.
Ovviamente nella conversione in float pu verificarsi perdita di
precisione, essendo la rappresentazione interna in double.
void foo (float f)
{
printf ("%f\n", f);
}
{
Complex a (4, -1);
// a 4-j
double r=a.Re, i=a.Im; // r 4, i -1
float b = (float) a.Re; // b
4
float c = a.Re;
// c 4
foo ((float) a.Re);
// viene passato un 4
foo (a.Re);
// lo stesso
}
Se decidete di implementare gli operatori di cast, le definizioni
sono gi pronte in complex.h (basta uncommentarle).
*************************
* input/output facilities
In matematica i modi in cui vengono rappresentati i numeri complessi
sono molteplici. Eccone alcuni (Re indica la parte reale, Im quella
il coefficiente dell'immaginario, che alcuni usano indicare con i,
altri con j):
(Re, Im)
Re+jIm o
Re + Imj
jIm + Re
Re + jIm