/* complex.c implement complex arithmetic operations */ /* also elementary functions and vector, matrix operations */ #include "complex.h" #include #include #include "udrnrt.h" #undef abs #define abs(x) ((x)<0.0?(-(x)):(x)) complex cmplx(double a, double b) /* make a complex number */ { complex c; c.re = a; c.im = b; return c; } double real(complex a) /* get real part */ { return a.re; } double imag(complex a) /* get imaginary part */ { return a.im; } complex cxadd(complex a, complex b) /* add two complex numbers */ { complex c; c.re = a.re+b.re; c.im = a.im+b.im; return c; } complex cxsub(complex a, complex b) /* subtract b from a, complex */ { complex c; c.re = a.re-b.re; c.im = a.im-b.im; return c; } complex cxmul(complex a, complex b) /* multiply two complex numbers */ { complex c; c.re = a.re*b.re - a.im*b.im; c.im = a.re*b.im + a.im*b.re; return c; } complex cdmul(double a, complex b) /* multiply double times complex */ { complex c; c.re = a*b.re; c.im = a*b.im; return c; } complex cmuld(complex a, double b) /* multiply complex times double */ { complex c; c.re = a.re*b; c.im = a.im*b; return c; } complex cxdiv(complex a, complex b) /* divide complex by complex */ { complex c; double r; r = b.re*b.re+b.im*b.im; c.re = (a.re*b.re+a.im*b.im)/r; c.im = (a.im*b.re-a.re*b.im)/r; return c; } complex cdivd(complex a, double b) /* divide complex by double */ { complex c; c.re = a.re/b; c.im = a.im/b; return c; } double cxabs(complex a) /* return magnitude of complex munber */ { return sqrt(a.re*a.re+a.im*a.im); } double cxarg(complex a) /* return argument of complex munber */ { return atan2(a.im,a.re); } complex cxneg(complex a) /* negate a complex */ { complex c; c.re = -a.re; c.im = -a.im; return c; } complex cxconj(complex a) /* conjugate a complex */ { complex c; c.re = a.re; c.im = -a.im; return c; } double sumabs(complex a) /* abs re + abs im */ { return abs(a.re)+abs(a.im); } /* complex elementary functions */ complex cxsqrt(complex a) /* square root of a complex number*/ { complex c; double r, ra, sqre, sqim; r = cxabs(a); sqre = sqrt((r+a.re)/2.0); sqim = sqrt((r-a.re)/2.0); if(a.im<0.0) sqim = -sqim; return cmplx(sqre, sqim); } complex cxexp(complex a) /* e^a, exp of a complex number */ { complex v; double erea; erea = exp(a.re); v = cmplx(erea*cos(a.im),erea*sin(a.im)); return v; } complex cxlog(complex a) /* log base e of a complex number */ { complex v; double vmod, varg; vmod = cxabs(a); varg = cxarg(a); v = cmplx(log(vmod), varg); return v; } complex cxsin(complex a) /* sine of a complex number */ { complex v; v = cmplx(sin(a.re)*cosh(a.im), cos(a.re)*sinh(a.im)); return v; } complex cxcos(complex a) /* cosine of a complex number */ { complex v; v = cmplx(cos(a.re)*cosh(a.im), sin(a.re)*sinh(a.im)); return v; } complex cxtan(complex a) /* tangent of a complex number */ { complex v; v = cxdiv(cxsin(a),cxcos(a)); return v; } complex cxatan(complex a) /* arctangent of a complex number */ { complex t, v; t = cxatanh(a); v = cmplx(t.im, -t.re); return v; } complex cxsinh(complex a) /* hyperbolic sine of a complex number */ { complex v; v = cmplx(sinh(a.re)*cos(a.im), cosh(a.re)*sin(a.im)); return v; } complex cxcosh(complex a) /* hyperbolic cosine of a complex number */ { complex v; v = cmplx(cosh(a.re)*cos(a.im), sinh(a.re)*sin(a.im)); return v; } complex cxtanh(complex a) /* hyperbolic tangent of a complex number */ { complex v; v = cxdiv(cxsinh(a),cxcosh(a)); return v; } complex cxatanh(complex a) /* hyperbolic arctangent of a complex number */ { complex one, v; complex lap1, lam1; one = cmplx(1.0,0.0); lap1 = cxlog(cxadd(one,a)); lam1 = cxlog(cxsub(one,a)); v = cdivd(cxsub(lap1,lam1),2.0); return v; } /* complex vecotor, matrix operations */ void cxvadd(int n, complex A[n], complex B[n], complex C[n]) /* C = A + B */ { int i; for(i=0; i abs_pivot) { I_pivot = i; pivot = A[row[i]][k]; abs_pivot = cxabs(pivot); } } hold = row[k]; row[k] = row[I_pivot]; row[I_pivot] = hold; if(abs_pivot < 1.0E-15 ) /* singular, delete row */ { for(j=k+1; j abs_pivot ) { I_pivot = i; pivot = B[row[i]][k]; abs_pivot = cxabs(pivot); } } if(I_pivot != k) { hold = row[k]; row[k] = row[I_pivot]; row[I_pivot] = hold; D = cxneg(D); } if(abs_pivot < 1.0E-15) return zero; D = cxmul(D,B[row[k]][k]); for(j=k+1; j abs_pivot ) { I_pivot = i ; J_pivot = j ; pivot = AA[row[i]][col[j]] ; } } } if(cxabs(pivot) < 1.0E-15) { printf("MATRIX is SINGULAR !!! \n"); return; } hold = row[k]; row[k]= row[I_pivot]; row[I_pivot] = hold ; hold = col[k]; col[k]= col[J_pivot]; col[J_pivot] = hold ; AA[row[k]][col[k]] = cxdiv(one,pivot) ; for (j=0; j