|
kusano |
7d535a |
|
|
kusano |
7d535a |
/*! @file dcomplex.c
|
|
kusano |
7d535a |
* \brief Common arithmetic for complex type
|
|
kusano |
7d535a |
*
|
|
kusano |
7d535a |
*
|
|
kusano |
7d535a |
* -- SuperLU routine (version 2.0) --
|
|
kusano |
7d535a |
* Univ. of California Berkeley, Xerox Palo Alto Research Center,
|
|
kusano |
7d535a |
* and Lawrence Berkeley National Lab.
|
|
kusano |
7d535a |
* November 15, 1997
|
|
kusano |
7d535a |
*
|
|
kusano |
7d535a |
* This file defines common arithmetic operations for complex type.
|
|
kusano |
7d535a |
*
|
|
kusano |
7d535a |
*/
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
#include <math.h></math.h>
|
|
kusano |
7d535a |
#include <stdlib.h></stdlib.h>
|
|
kusano |
7d535a |
#include <stdio.h></stdio.h>
|
|
kusano |
7d535a |
#include "slu_dcomplex.h"
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/*! \brief Complex Division c = a/b */
|
|
kusano |
7d535a |
void z_div(doublecomplex *c, doublecomplex *a, doublecomplex *b)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
double ratio, den;
|
|
kusano |
7d535a |
double abr, abi, cr, ci;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
if( (abr = b->r) < 0.)
|
|
kusano |
7d535a |
abr = - abr;
|
|
kusano |
7d535a |
if( (abi = b->i) < 0.)
|
|
kusano |
7d535a |
abi = - abi;
|
|
kusano |
7d535a |
if( abr <= abi ) {
|
|
kusano |
7d535a |
if (abi == 0) {
|
|
kusano |
7d535a |
fprintf(stderr, "z_div.c: division by zero\n");
|
|
kusano |
7d535a |
exit(-1);
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
ratio = b->r / b->i ;
|
|
kusano |
7d535a |
den = b->i * (1 + ratio*ratio);
|
|
kusano |
7d535a |
cr = (a->r*ratio + a->i) / den;
|
|
kusano |
7d535a |
ci = (a->i*ratio - a->r) / den;
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
ratio = b->i / b->r ;
|
|
kusano |
7d535a |
den = b->r * (1 + ratio*ratio);
|
|
kusano |
7d535a |
cr = (a->r + a->i*ratio) / den;
|
|
kusano |
7d535a |
ci = (a->i - a->r*ratio) / den;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
c->r = cr;
|
|
kusano |
7d535a |
c->i = ci;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/*! \brief Returns sqrt(z.r^2 + z.i^2) */
|
|
kusano |
7d535a |
double z_abs(doublecomplex *z)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
double temp;
|
|
kusano |
7d535a |
double real = z->r;
|
|
kusano |
7d535a |
double imag = z->i;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
if (real < 0) real = -real;
|
|
kusano |
7d535a |
if (imag < 0) imag = -imag;
|
|
kusano |
7d535a |
if (imag > real) {
|
|
kusano |
7d535a |
temp = real;
|
|
kusano |
7d535a |
real = imag;
|
|
kusano |
7d535a |
imag = temp;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
if ((real+imag) == real) return(real);
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
temp = imag/real;
|
|
kusano |
7d535a |
temp = real*sqrt(1.0 + temp*temp); /*overflow!!*/
|
|
kusano |
7d535a |
return (temp);
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/*! \brief Approximates the abs. Returns abs(z.r) + abs(z.i) */
|
|
kusano |
7d535a |
double z_abs1(doublecomplex *z)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
double real = z->r;
|
|
kusano |
7d535a |
double imag = z->i;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
if (real < 0) real = -real;
|
|
kusano |
7d535a |
if (imag < 0) imag = -imag;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
return (real + imag);
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/*! \brief Return the exponentiation */
|
|
kusano |
7d535a |
void z_exp(doublecomplex *r, doublecomplex *z)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
double expx;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
expx = exp(z->r);
|
|
kusano |
7d535a |
r->r = expx * cos(z->i);
|
|
kusano |
7d535a |
r->i = expx * sin(z->i);
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/*! \brief Return the complex conjugate */
|
|
kusano |
7d535a |
void d_cnjg(doublecomplex *r, doublecomplex *z)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
r->r = z->r;
|
|
kusano |
7d535a |
r->i = -z->i;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/*! \brief Return the imaginary part */
|
|
kusano |
7d535a |
double d_imag(doublecomplex *z)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
return (z->i);
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/*! \brief SIGN functions for complex number. Returns z/abs(z) */
|
|
kusano |
7d535a |
doublecomplex z_sgn(doublecomplex *z)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
register double t = z_abs(z);
|
|
kusano |
7d535a |
register doublecomplex retval;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
if (t == 0.0) {
|
|
kusano |
7d535a |
retval.r = 1.0, retval.i = 0.0;
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
retval.r = z->r / t, retval.i = z->i / t;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
return retval;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
/*! \brief Square-root of a complex number. */
|
|
kusano |
7d535a |
doublecomplex z_sqrt(doublecomplex *z)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
doublecomplex retval;
|
|
kusano |
7d535a |
register double cr, ci, real, imag;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
real = z->r;
|
|
kusano |
7d535a |
imag = z->i;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
if ( imag == 0.0 ) {
|
|
kusano |
7d535a |
retval.r = sqrt(real);
|
|
kusano |
7d535a |
retval.i = 0.0;
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
ci = (sqrt(real*real + imag*imag) - real) / 2.0;
|
|
kusano |
7d535a |
ci = sqrt(ci);
|
|
kusano |
7d535a |
cr = imag / (2.0 * ci);
|
|
kusano |
7d535a |
retval.r = cr;
|
|
kusano |
7d535a |
retval.i = ci;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
return retval;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
|