Come lavorare con numeri complessi in C?

Come posso lavorare con numeri complessi in C? Vedo che c’è un file complex.h , ma non mi dà molte informazioni su come usarlo. Come accedere a parti reali e immaginarie in modo efficiente? Esistono funzioni native per ottenere modulo e fase?

Questo codice ti aiuterà, ed è abbastanza auto-esplicativo:

 #include  /* Standard Library of Input and Output */ #include  /* Standard Library of Complex Numbers */ int main() { double complex z1 = 1.0 + 3.0 * I; double complex z2 = 1.0 - 4.0 * I; printf("Working with complex numbers:\n\v"); printf("Starting values: Z1 = %.2f + %.2fi\tZ2 = %.2f %+.2fi\n", creal(z1), cimag(z1), creal(z2), cimag(z2)); double complex sum = z1 + z2; printf("The sum: Z1 + Z2 = %.2f %+.2fi\n", creal(sum), cimag(sum)); double complex difference = z1 - z2; printf("The difference: Z1 - Z2 = %.2f %+.2fi\n", creal(difference), cimag(difference)); double complex product = z1 * z2; printf("The product: Z1 x Z2 = %.2f %+.2fi\n", creal(product), cimag(product)); double complex quotient = z1 / z2; printf("The quotient: Z1 / Z2 = %.2f %+.2fi\n", creal(quotient), cimag(quotient)); double complex conjugate = conj(z1); printf("The conjugate of Z1 = %.2f %+.2fi\n", creal(conjugate), cimag(conjugate)); return 0; } 

con:

creal(z1) : ottieni la parte reale (per float crealf(z1) , per long double creall(z1) )

cimag(z1) : ottieni la parte immaginaria (per float cimagf(z1) , per lungo doppio cimagl(z1) )

Un altro punto importante da ricordare quando si lavora con numeri complessi è che funzioni come cos() , exp() e sqrt() devono essere sostituite con le loro forms complesse, ad esempio ccos() , cexp() , csqrt() .

I tipi complessi sono in linguaggio C dallo standard C99 ( -std=c99 opzione -std=c99 di GCC). Alcuni compilatori possono implementare tipi complessi anche in modalità più precedenti, ma questa è un’estensione non standard e non portatile (ad esempio, IBM XL, GCC, potrebbe essere intel, …).

Puoi iniziare da http://en.wikipedia.org/wiki/Complex.h – fornisce una descrizione delle funzioni da complex.h

Questo manuale http://pubs.opengroup.org/onlinepubs/009604499/basedefs/complex.h.html fornisce anche alcune informazioni sulle macro.

Per dichiarare una variabile complessa, utilizzare

  double _Complex a; // use c* functions without suffix 

o

  float _Complex b; // use c*f functions - with f suffix long double _Complex c; // use c*l functions - with l suffix 

Per dare un valore in un complesso, usa la macro _Complex_I da _Complex_I :

  float _Complex d = 2.0f + 2.0f*_Complex_I; 

(in realtà possono esserci alcuni problemi con i numeri (0,-0i) e i NaN nella metà singola del complesso)

Modulo è cabs(a) / cabsl(c) / cabsf(b) ; La parte reale è creal(a) , Imaginary è cimag(a) . carg(a) è per argomenti complessi.

Per accedere direttamente (leggi / scrivi) a una parte reale e immag è ansible utilizzare questa estensione GCC non importabile :

  __real__ a = 1.4; __imag__ a = 2.0; float b = __real__ a; 

Complex.h

 #include  /* Standard Library of Input and Output */ #include  /* Standart Library of Complex Numbers */ int main() { double complex z1 = 1.0 + 3.0 * I; double complex z2 = 1.0 - 4.0 * I; printf("Working with complex numbers:\n\v"); printf("Starting values: Z1 = %.2f + %.2fi\tZ2 = %.2f %+.2fi\n", creal(z1), cimag(z1), creal(z2), cimag(z2)); double complex sum = z1 + z2; printf("The sum: Z1 + Z2 = %.2f %+.2fi\n", creal(sum), cimag(sum)); } 

La nozione di numeri complessi è stata introdotta in matematica, dalla necessità di calcolare radici quadratiche negative. Il concetto di numero complesso è stato preso da una varietà di campi ingegneristici.

Oggi quei numeri complessi sono ampiamente usati in domini avanzati di ingegneria come fisica, elettronica, meccanica, astronomia, ecc …

Parte reale e immaginaria, di un esempio di radice quadrata negativa:

 #include  #include  int main() { int negNum; printf("Calculate negative square roots:\n" "Enter negative number:"); scanf("%d", &negNum); double complex negSqrt = csqrt(negNum); double pReal = creal(negSqrt); double pImag = cimag(negSqrt); printf("\nReal part %f, imaginary part %f" ", for negative square root.(%d)", pReal, pImag, negNum); return 0; } 

Per comodità, si può includere la libreria tgmath.h per il tipo generare macro. Crea lo stesso nome di funzione della versione doppia per tutti i tipi di variabile. Ad esempio, ad esempio, definisce una macro sqrt() che si espande alla funzione sqrtf() , sqrt() o sqrtl() , a seconda del tipo di argomento fornito.

Quindi non è necessario ricordare il nome della funzione corrispondente per diversi tipi di variabili!

 #include  #include //for the type generate macros. #include //for easier declare complex variables and complex unit I int main(void) { double complex z1=1./4.*M_PI+1./4.*M_PI*I;//M_PI is just pi=3.1415... double complex z2, z3, z4, z5; z2=exp(z1); z3=sin(z1); z4=sqrt(z1); z5=log(z1); printf("exp(z1)=%lf + %lf I\n", creal(z2),cimag(z2)); printf("sin(z1)=%lf + %lf I\n", creal(z3),cimag(z3)); printf("sqrt(z1)=%lf + %lf I\n", creal(z4),cimag(z4)); printf("log(z1)=%lf + %lf I\n", creal(z5),cimag(z5)); return 0; } 

Per estrarre la parte reale di un’espressione con valore complesso z , utilizzare la notazione come __real__ z . Allo stesso modo, usa __imag__ attributo __imag__ sulla z per estrarre la parte immaginaria.

Per esempio;

 __complex__ float z; float r; float i; r = __real__ z; i = __imag__ z; 

r è la parte reale del numero complesso “z” i è la parte immaginaria del numero complesso “z”