|
Packit |
67cb25 |
/* complex/math.c
|
|
Packit |
67cb25 |
*
|
|
Packit |
67cb25 |
* Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jorma Olavi T�htinen, Brian Gough
|
|
Packit |
67cb25 |
*
|
|
Packit |
67cb25 |
* This program is free software; you can redistribute it and/or modify
|
|
Packit |
67cb25 |
* it under the terms of the GNU General Public License as published by
|
|
Packit |
67cb25 |
* the Free Software Foundation; either version 3 of the License, or (at
|
|
Packit |
67cb25 |
* your option) any later version.
|
|
Packit |
67cb25 |
*
|
|
Packit |
67cb25 |
* This program is distributed in the hope that it will be useful, but
|
|
Packit |
67cb25 |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
67cb25 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
67cb25 |
* General Public License for more details.
|
|
Packit |
67cb25 |
*
|
|
Packit |
67cb25 |
* You should have received a copy of the GNU General Public License
|
|
Packit |
67cb25 |
* along with this program; if not, write to the Free Software
|
|
Packit |
67cb25 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
Packit |
67cb25 |
*/
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* Basic complex arithmetic functions
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
* Original version by Jorma Olavi T�htinen <jotahtin@cc.hut.fi>
|
|
Packit |
67cb25 |
*
|
|
Packit |
67cb25 |
* Modified for GSL by Brian Gough, 3/2000
|
|
Packit |
67cb25 |
*/
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* The following references describe the methods used in these
|
|
Packit |
67cb25 |
* functions,
|
|
Packit |
67cb25 |
*
|
|
Packit |
67cb25 |
* T. E. Hull and Thomas F. Fairgrieve and Ping Tak Peter Tang,
|
|
Packit |
67cb25 |
* "Implementing Complex Elementary Functions Using Exception
|
|
Packit |
67cb25 |
* Handling", ACM Transactions on Mathematical Software, Volume 20
|
|
Packit |
67cb25 |
* (1994), pp 215-244, Corrigenda, p553
|
|
Packit |
67cb25 |
*
|
|
Packit |
67cb25 |
* Hull et al, "Implementing the complex arcsin and arccosine
|
|
Packit |
67cb25 |
* functions using exception handling", ACM Transactions on
|
|
Packit |
67cb25 |
* Mathematical Software, Volume 23 (1997) pp 299-335
|
|
Packit |
67cb25 |
*
|
|
Packit |
67cb25 |
* Abramowitz and Stegun, Handbook of Mathematical Functions, "Inverse
|
|
Packit |
67cb25 |
* Circular Functions in Terms of Real and Imaginary Parts", Formulas
|
|
Packit |
67cb25 |
* 4.4.37, 4.4.38, 4.4.39
|
|
Packit |
67cb25 |
*/
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
#include <config.h>
|
|
Packit |
67cb25 |
#include <math.h>
|
|
Packit |
67cb25 |
#include <gsl/gsl_math.h>
|
|
Packit |
67cb25 |
#include <gsl/gsl_complex.h>
|
|
Packit |
67cb25 |
#include <gsl/gsl_complex_math.h>
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/**********************************************************************
|
|
Packit |
67cb25 |
* Complex numbers
|
|
Packit |
67cb25 |
**********************************************************************/
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_polar (double r, double theta)
|
|
Packit |
67cb25 |
{ /* return z = r exp(i theta) */
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, r * cos (theta), r * sin (theta));
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/**********************************************************************
|
|
Packit |
67cb25 |
* Properties of complex numbers
|
|
Packit |
67cb25 |
**********************************************************************/
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
double
|
|
Packit |
67cb25 |
gsl_complex_arg (gsl_complex z)
|
|
Packit |
67cb25 |
{ /* return arg(z), -pi < arg(z) <= +pi */
|
|
Packit |
67cb25 |
double x = GSL_REAL (z);
|
|
Packit |
67cb25 |
double y = GSL_IMAG (z);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (x == 0.0 && y == 0.0)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
return 0;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
return atan2 (y, x);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
double
|
|
Packit |
67cb25 |
gsl_complex_abs (gsl_complex z)
|
|
Packit |
67cb25 |
{ /* return |z| */
|
|
Packit |
67cb25 |
return hypot (GSL_REAL (z), GSL_IMAG (z));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
double
|
|
Packit |
67cb25 |
gsl_complex_abs2 (gsl_complex z)
|
|
Packit |
67cb25 |
{ /* return |z|^2 */
|
|
Packit |
67cb25 |
double x = GSL_REAL (z);
|
|
Packit |
67cb25 |
double y = GSL_IMAG (z);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
return (x * x + y * y);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
double
|
|
Packit |
67cb25 |
gsl_complex_logabs (gsl_complex z)
|
|
Packit |
67cb25 |
{ /* return log|z| */
|
|
Packit |
67cb25 |
double xabs = fabs (GSL_REAL (z));
|
|
Packit |
67cb25 |
double yabs = fabs (GSL_IMAG (z));
|
|
Packit |
67cb25 |
double max, u;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (xabs >= yabs)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
max = xabs;
|
|
Packit |
67cb25 |
u = yabs / xabs;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
max = yabs;
|
|
Packit |
67cb25 |
u = xabs / yabs;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* Handle underflow when u is close to 0 */
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
return log (max) + 0.5 * log1p (u * u);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/***********************************************************************
|
|
Packit |
67cb25 |
* Complex arithmetic operators
|
|
Packit |
67cb25 |
***********************************************************************/
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_add (gsl_complex a, gsl_complex b)
|
|
Packit |
67cb25 |
{ /* z=a+b */
|
|
Packit |
67cb25 |
double ar = GSL_REAL (a), ai = GSL_IMAG (a);
|
|
Packit |
67cb25 |
double br = GSL_REAL (b), bi = GSL_IMAG (b);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, ar + br, ai + bi);
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_add_real (gsl_complex a, double x)
|
|
Packit |
67cb25 |
{ /* z=a+x */
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, GSL_REAL (a) + x, GSL_IMAG (a));
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_add_imag (gsl_complex a, double y)
|
|
Packit |
67cb25 |
{ /* z=a+iy */
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, GSL_REAL (a), GSL_IMAG (a) + y);
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_sub (gsl_complex a, gsl_complex b)
|
|
Packit |
67cb25 |
{ /* z=a-b */
|
|
Packit |
67cb25 |
double ar = GSL_REAL (a), ai = GSL_IMAG (a);
|
|
Packit |
67cb25 |
double br = GSL_REAL (b), bi = GSL_IMAG (b);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, ar - br, ai - bi);
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_sub_real (gsl_complex a, double x)
|
|
Packit |
67cb25 |
{ /* z=a-x */
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, GSL_REAL (a) - x, GSL_IMAG (a));
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_sub_imag (gsl_complex a, double y)
|
|
Packit |
67cb25 |
{ /* z=a-iy */
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, GSL_REAL (a), GSL_IMAG (a) - y);
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_mul (gsl_complex a, gsl_complex b)
|
|
Packit |
67cb25 |
{ /* z=a*b */
|
|
Packit |
67cb25 |
double ar = GSL_REAL (a), ai = GSL_IMAG (a);
|
|
Packit |
67cb25 |
double br = GSL_REAL (b), bi = GSL_IMAG (b);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, ar * br - ai * bi, ar * bi + ai * br);
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_mul_real (gsl_complex a, double x)
|
|
Packit |
67cb25 |
{ /* z=a*x */
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, x * GSL_REAL (a), x * GSL_IMAG (a));
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_mul_imag (gsl_complex a, double y)
|
|
Packit |
67cb25 |
{ /* z=a*iy */
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, -y * GSL_IMAG (a), y * GSL_REAL (a));
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_div (gsl_complex a, gsl_complex b)
|
|
Packit |
67cb25 |
{ /* z=a/b */
|
|
Packit |
67cb25 |
double ar = GSL_REAL (a), ai = GSL_IMAG (a);
|
|
Packit |
67cb25 |
double br = GSL_REAL (b), bi = GSL_IMAG (b);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
double s = 1.0 / gsl_complex_abs (b);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
double sbr = s * br;
|
|
Packit |
67cb25 |
double sbi = s * bi;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
double zr = (ar * sbr + ai * sbi) * s;
|
|
Packit |
67cb25 |
double zi = (ai * sbr - ar * sbi) * s;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, zr, zi);
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_div_real (gsl_complex a, double x)
|
|
Packit |
67cb25 |
{ /* z=a/x */
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, GSL_REAL (a) / x, GSL_IMAG (a) / x);
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_div_imag (gsl_complex a, double y)
|
|
Packit |
67cb25 |
{ /* z=a/(iy) */
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, GSL_IMAG (a) / y, - GSL_REAL (a) / y);
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_conjugate (gsl_complex a)
|
|
Packit |
67cb25 |
{ /* z=conj(a) */
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, GSL_REAL (a), -GSL_IMAG (a));
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_negative (gsl_complex a)
|
|
Packit |
67cb25 |
{ /* z=-a */
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, -GSL_REAL (a), -GSL_IMAG (a));
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_inverse (gsl_complex a)
|
|
Packit |
67cb25 |
{ /* z=1/a */
|
|
Packit |
67cb25 |
double s = 1.0 / gsl_complex_abs (a);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, (GSL_REAL (a) * s) * s, -(GSL_IMAG (a) * s) * s);
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/**********************************************************************
|
|
Packit |
67cb25 |
* Elementary complex functions
|
|
Packit |
67cb25 |
**********************************************************************/
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_sqrt (gsl_complex a)
|
|
Packit |
67cb25 |
{ /* z=sqrt(a) */
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (GSL_REAL (a) == 0.0 && GSL_IMAG (a) == 0.0)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, 0, 0);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
double x = fabs (GSL_REAL (a));
|
|
Packit |
67cb25 |
double y = fabs (GSL_IMAG (a));
|
|
Packit |
67cb25 |
double w;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (x >= y)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
double t = y / x;
|
|
Packit |
67cb25 |
w = sqrt (x) * sqrt (0.5 * (1.0 + sqrt (1.0 + t * t)));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
double t = x / y;
|
|
Packit |
67cb25 |
w = sqrt (y) * sqrt (0.5 * (t + sqrt (1.0 + t * t)));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (GSL_REAL (a) >= 0.0)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
double ai = GSL_IMAG (a);
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, w, ai / (2.0 * w));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
double ai = GSL_IMAG (a);
|
|
Packit |
67cb25 |
double vi = (ai >= 0) ? w : -w;
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, ai / (2.0 * vi), vi);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_sqrt_real (double x)
|
|
Packit |
67cb25 |
{ /* z=sqrt(x) */
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (x >= 0)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, sqrt (x), 0.0);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, 0.0, sqrt (-x));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_exp (gsl_complex a)
|
|
Packit |
67cb25 |
{ /* z=exp(a) */
|
|
Packit |
67cb25 |
double rho = exp (GSL_REAL (a));
|
|
Packit |
67cb25 |
double theta = GSL_IMAG (a);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, rho * cos (theta), rho * sin (theta));
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_pow (gsl_complex a, gsl_complex b)
|
|
Packit |
67cb25 |
{ /* z=a^b */
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (GSL_REAL (a) == 0 && GSL_IMAG (a) == 0.0)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
if (GSL_REAL (b) == 0 && GSL_IMAG (b) == 0.0)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, 1.0, 0.0);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, 0.0, 0.0);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else if (GSL_REAL (b) == 1.0 && GSL_IMAG (b) == 0.0)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
return a;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else if (GSL_REAL (b) == -1.0 && GSL_IMAG (b) == 0.0)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
return gsl_complex_inverse (a);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
double logr = gsl_complex_logabs (a);
|
|
Packit |
67cb25 |
double theta = gsl_complex_arg (a);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
double br = GSL_REAL (b), bi = GSL_IMAG (b);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
double rho = exp (logr * br - bi * theta);
|
|
Packit |
67cb25 |
double beta = theta * br + bi * logr;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, rho * cos (beta), rho * sin (beta));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_pow_real (gsl_complex a, double b)
|
|
Packit |
67cb25 |
{ /* z=a^b */
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (GSL_REAL (a) == 0 && GSL_IMAG (a) == 0)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
if (b == 0)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, 1, 0);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, 0, 0);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
double logr = gsl_complex_logabs (a);
|
|
Packit |
67cb25 |
double theta = gsl_complex_arg (a);
|
|
Packit |
67cb25 |
double rho = exp (logr * b);
|
|
Packit |
67cb25 |
double beta = theta * b;
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, rho * cos (beta), rho * sin (beta));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_log (gsl_complex a)
|
|
Packit |
67cb25 |
{ /* z=log(a) */
|
|
Packit |
67cb25 |
double logr = gsl_complex_logabs (a);
|
|
Packit |
67cb25 |
double theta = gsl_complex_arg (a);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, logr, theta);
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_log10 (gsl_complex a)
|
|
Packit |
67cb25 |
{ /* z = log10(a) */
|
|
Packit |
67cb25 |
return gsl_complex_mul_real (gsl_complex_log (a), 1 / log (10.));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_log_b (gsl_complex a, gsl_complex b)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
return gsl_complex_div (gsl_complex_log (a), gsl_complex_log (b));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/***********************************************************************
|
|
Packit |
67cb25 |
* Complex trigonometric functions
|
|
Packit |
67cb25 |
***********************************************************************/
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_sin (gsl_complex a)
|
|
Packit |
67cb25 |
{ /* z = sin(a) */
|
|
Packit |
67cb25 |
double R = GSL_REAL (a), I = GSL_IMAG (a);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (I == 0.0)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
/* avoid returing negative zero (-0.0) for the imaginary part */
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, sin (R), 0.0);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, sin (R) * cosh (I), cos (R) * sinh (I));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_cos (gsl_complex a)
|
|
Packit |
67cb25 |
{ /* z = cos(a) */
|
|
Packit |
67cb25 |
double R = GSL_REAL (a), I = GSL_IMAG (a);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (I == 0.0)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
/* avoid returing negative zero (-0.0) for the imaginary part */
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, cos (R), 0.0);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, cos (R) * cosh (I), sin (R) * sinh (-I));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_tan (gsl_complex a)
|
|
Packit |
67cb25 |
{ /* z = tan(a) */
|
|
Packit |
67cb25 |
double R = GSL_REAL (a), I = GSL_IMAG (a);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (fabs (I) < 1)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
double D = pow (cos (R), 2.0) + pow (sinh (I), 2.0);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, 0.5 * sin (2 * R) / D, 0.5 * sinh (2 * I) / D);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
double D = pow (cos (R), 2.0) + pow (sinh (I), 2.0);
|
|
Packit |
67cb25 |
double F = 1 + pow(cos (R)/sinh (I), 2.0);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, 0.5 * sin (2 * R) / D, 1 / (tanh (I) * F));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_sec (gsl_complex a)
|
|
Packit |
67cb25 |
{ /* z = sec(a) */
|
|
Packit |
67cb25 |
gsl_complex z = gsl_complex_cos (a);
|
|
Packit |
67cb25 |
return gsl_complex_inverse (z);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_csc (gsl_complex a)
|
|
Packit |
67cb25 |
{ /* z = csc(a) */
|
|
Packit |
67cb25 |
gsl_complex z = gsl_complex_sin (a);
|
|
Packit |
67cb25 |
return gsl_complex_inverse(z);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_cot (gsl_complex a)
|
|
Packit |
67cb25 |
{ /* z = cot(a) */
|
|
Packit |
67cb25 |
gsl_complex z = gsl_complex_tan (a);
|
|
Packit |
67cb25 |
return gsl_complex_inverse (z);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/**********************************************************************
|
|
Packit |
67cb25 |
* Inverse Complex Trigonometric Functions
|
|
Packit |
67cb25 |
**********************************************************************/
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_arcsin (gsl_complex a)
|
|
Packit |
67cb25 |
{ /* z = arcsin(a) */
|
|
Packit |
67cb25 |
double R = GSL_REAL (a), I = GSL_IMAG (a);
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (I == 0)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
z = gsl_complex_arcsin_real (R);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
double x = fabs (R), y = fabs (I);
|
|
Packit |
67cb25 |
double r = hypot (x + 1, y), s = hypot (x - 1, y);
|
|
Packit |
67cb25 |
double A = 0.5 * (r + s);
|
|
Packit |
67cb25 |
double B = x / A;
|
|
Packit |
67cb25 |
double y2 = y * y;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
double real, imag;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
const double A_crossover = 1.5, B_crossover = 0.6417;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (B <= B_crossover)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
real = asin (B);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
if (x <= 1)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
double D = 0.5 * (A + x) * (y2 / (r + x + 1) + (s + (1 - x)));
|
|
Packit |
67cb25 |
real = atan (x / sqrt (D));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
double Apx = A + x;
|
|
Packit |
67cb25 |
double D = 0.5 * (Apx / (r + x + 1) + Apx / (s + (x - 1)));
|
|
Packit |
67cb25 |
real = atan (x / (y * sqrt (D)));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (A <= A_crossover)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
double Am1;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (x < 1)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
Am1 = 0.5 * (y2 / (r + (x + 1)) + y2 / (s + (1 - x)));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
Am1 = 0.5 * (y2 / (r + (x + 1)) + (s + (x - 1)));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
imag = log1p (Am1 + sqrt (Am1 * (A + 1)));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
imag = log (A + sqrt (A * A - 1));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, (R >= 0) ? real : -real, (I >= 0) ? imag : -imag);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_arcsin_real (double a)
|
|
Packit |
67cb25 |
{ /* z = arcsin(a) */
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (fabs (a) <= 1.0)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, asin (a), 0.0);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
if (a < 0.0)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, -M_PI_2, acosh (-a));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, M_PI_2, -acosh (a));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_arccos (gsl_complex a)
|
|
Packit |
67cb25 |
{ /* z = arccos(a) */
|
|
Packit |
67cb25 |
double R = GSL_REAL (a), I = GSL_IMAG (a);
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (I == 0)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
z = gsl_complex_arccos_real (R);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
double x = fabs (R), y = fabs (I);
|
|
Packit |
67cb25 |
double r = hypot (x + 1, y), s = hypot (x - 1, y);
|
|
Packit |
67cb25 |
double A = 0.5 * (r + s);
|
|
Packit |
67cb25 |
double B = x / A;
|
|
Packit |
67cb25 |
double y2 = y * y;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
double real, imag;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
const double A_crossover = 1.5, B_crossover = 0.6417;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (B <= B_crossover)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
real = acos (B);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
if (x <= 1)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
double D = 0.5 * (A + x) * (y2 / (r + x + 1) + (s + (1 - x)));
|
|
Packit |
67cb25 |
real = atan (sqrt (D) / x);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
double Apx = A + x;
|
|
Packit |
67cb25 |
double D = 0.5 * (Apx / (r + x + 1) + Apx / (s + (x - 1)));
|
|
Packit |
67cb25 |
real = atan ((y * sqrt (D)) / x);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (A <= A_crossover)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
double Am1;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (x < 1)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
Am1 = 0.5 * (y2 / (r + (x + 1)) + y2 / (s + (1 - x)));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
Am1 = 0.5 * (y2 / (r + (x + 1)) + (s + (x - 1)));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
imag = log1p (Am1 + sqrt (Am1 * (A + 1)));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
imag = log (A + sqrt (A * A - 1));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, (R >= 0) ? real : M_PI - real, (I >= 0) ? -imag : imag);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_arccos_real (double a)
|
|
Packit |
67cb25 |
{ /* z = arccos(a) */
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (fabs (a) <= 1.0)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, acos (a), 0);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
if (a < 0.0)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, M_PI, -acosh (-a));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, 0, acosh (a));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_arctan (gsl_complex a)
|
|
Packit |
67cb25 |
{ /* z = arctan(a) */
|
|
Packit |
67cb25 |
double R = GSL_REAL (a), I = GSL_IMAG (a);
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (I == 0)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, atan (R), 0);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
/* FIXME: This is a naive implementation which does not fully
|
|
Packit |
67cb25 |
take into account cancellation errors, overflow, underflow
|
|
Packit |
67cb25 |
etc. It would benefit from the Hull et al treatment. */
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
double r = hypot (R, I);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
double imag;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
double u = 2 * I / (1 + r * r);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* FIXME: the following cross-over should be optimized but 0.1
|
|
Packit |
67cb25 |
seems to work ok */
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (fabs (u) < 0.1)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
imag = 0.25 * (log1p (u) - log1p (-u));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
double A = hypot (R, I + 1);
|
|
Packit |
67cb25 |
double B = hypot (R, I - 1);
|
|
Packit |
67cb25 |
imag = 0.5 * log (A / B);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (R == 0)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
if (I > 1)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, M_PI_2, imag);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else if (I < -1)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, -M_PI_2, imag);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, 0, imag);
|
|
Packit |
67cb25 |
};
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, 0.5 * atan2 (2 * R, ((1 + r) * (1 - r))), imag);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_arcsec (gsl_complex a)
|
|
Packit |
67cb25 |
{ /* z = arcsec(a) */
|
|
Packit |
67cb25 |
gsl_complex z = gsl_complex_inverse (a);
|
|
Packit |
67cb25 |
return gsl_complex_arccos (z);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_arcsec_real (double a)
|
|
Packit |
67cb25 |
{ /* z = arcsec(a) */
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (a <= -1.0 || a >= 1.0)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, acos (1 / a), 0.0);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
if (a >= 0.0)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, 0, acosh (1 / a));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, M_PI, -acosh (-1 / a));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_arccsc (gsl_complex a)
|
|
Packit |
67cb25 |
{ /* z = arccsc(a) */
|
|
Packit |
67cb25 |
gsl_complex z = gsl_complex_inverse (a);
|
|
Packit |
67cb25 |
return gsl_complex_arcsin (z);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_arccsc_real (double a)
|
|
Packit |
67cb25 |
{ /* z = arccsc(a) */
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (a <= -1.0 || a >= 1.0)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, asin (1 / a), 0.0);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
if (a >= 0.0)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, M_PI_2, -acosh (1 / a));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, -M_PI_2, acosh (-1 / a));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_arccot (gsl_complex a)
|
|
Packit |
67cb25 |
{ /* z = arccot(a) */
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (GSL_REAL (a) == 0.0 && GSL_IMAG (a) == 0.0)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, M_PI_2, 0);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
z = gsl_complex_inverse (a);
|
|
Packit |
67cb25 |
z = gsl_complex_arctan (z);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/**********************************************************************
|
|
Packit |
67cb25 |
* Complex Hyperbolic Functions
|
|
Packit |
67cb25 |
**********************************************************************/
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_sinh (gsl_complex a)
|
|
Packit |
67cb25 |
{ /* z = sinh(a) */
|
|
Packit |
67cb25 |
double R = GSL_REAL (a), I = GSL_IMAG (a);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, sinh (R) * cos (I), cosh (R) * sin (I));
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_cosh (gsl_complex a)
|
|
Packit |
67cb25 |
{ /* z = cosh(a) */
|
|
Packit |
67cb25 |
double R = GSL_REAL (a), I = GSL_IMAG (a);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, cosh (R) * cos (I), sinh (R) * sin (I));
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_tanh (gsl_complex a)
|
|
Packit |
67cb25 |
{ /* z = tanh(a) */
|
|
Packit |
67cb25 |
double R = GSL_REAL (a), I = GSL_IMAG (a);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (fabs(R) < 1.0)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
double D = pow (cos (I), 2.0) + pow (sinh (R), 2.0);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, sinh (R) * cosh (R) / D, 0.5 * sin (2 * I) / D);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
double D = pow (cos (I), 2.0) + pow (sinh (R), 2.0);
|
|
Packit |
67cb25 |
double F = 1 + pow (cos (I) / sinh (R), 2.0);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, 1.0 / (tanh (R) * F), 0.5 * sin (2 * I) / D);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_sech (gsl_complex a)
|
|
Packit |
67cb25 |
{ /* z = sech(a) */
|
|
Packit |
67cb25 |
gsl_complex z = gsl_complex_cosh (a);
|
|
Packit |
67cb25 |
return gsl_complex_inverse (z);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_csch (gsl_complex a)
|
|
Packit |
67cb25 |
{ /* z = csch(a) */
|
|
Packit |
67cb25 |
gsl_complex z = gsl_complex_sinh (a);
|
|
Packit |
67cb25 |
return gsl_complex_inverse (z);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_coth (gsl_complex a)
|
|
Packit |
67cb25 |
{ /* z = coth(a) */
|
|
Packit |
67cb25 |
gsl_complex z = gsl_complex_tanh (a);
|
|
Packit |
67cb25 |
return gsl_complex_inverse (z);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/**********************************************************************
|
|
Packit |
67cb25 |
* Inverse Complex Hyperbolic Functions
|
|
Packit |
67cb25 |
**********************************************************************/
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_arcsinh (gsl_complex a)
|
|
Packit |
67cb25 |
{ /* z = arcsinh(a) */
|
|
Packit |
67cb25 |
gsl_complex z = gsl_complex_mul_imag(a, 1.0);
|
|
Packit |
67cb25 |
z = gsl_complex_arcsin (z);
|
|
Packit |
67cb25 |
z = gsl_complex_mul_imag (z, -1.0);
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_arccosh (gsl_complex a)
|
|
Packit |
67cb25 |
{ /* z = arccosh(a) */
|
|
Packit |
67cb25 |
gsl_complex z = gsl_complex_arccos (a);
|
|
Packit |
67cb25 |
z = gsl_complex_mul_imag (z, GSL_IMAG(z) > 0 ? -1.0 : 1.0);
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_arccosh_real (double a)
|
|
Packit |
67cb25 |
{ /* z = arccosh(a) */
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (a >= 1)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, acosh (a), 0);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
if (a >= -1.0)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, 0, acos (a));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, acosh (-a), M_PI);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_arctanh (gsl_complex a)
|
|
Packit |
67cb25 |
{ /* z = arctanh(a) */
|
|
Packit |
67cb25 |
if (GSL_IMAG (a) == 0.0)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
return gsl_complex_arctanh_real (GSL_REAL (a));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
gsl_complex z = gsl_complex_mul_imag(a, 1.0);
|
|
Packit |
67cb25 |
z = gsl_complex_arctan (z);
|
|
Packit |
67cb25 |
z = gsl_complex_mul_imag (z, -1.0);
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_arctanh_real (double a)
|
|
Packit |
67cb25 |
{ /* z = arctanh(a) */
|
|
Packit |
67cb25 |
gsl_complex z;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (a > -1.0 && a < 1.0)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, atanh (a), 0);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
GSL_SET_COMPLEX (&z, atanh (1 / a), (a < 0) ? M_PI_2 : -M_PI_2);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
return z;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_arcsech (gsl_complex a)
|
|
Packit |
67cb25 |
{ /* z = arcsech(a); */
|
|
Packit |
67cb25 |
gsl_complex t = gsl_complex_inverse (a);
|
|
Packit |
67cb25 |
return gsl_complex_arccosh (t);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_arccsch (gsl_complex a)
|
|
Packit |
67cb25 |
{ /* z = arccsch(a) */
|
|
Packit |
67cb25 |
gsl_complex t = gsl_complex_inverse (a);
|
|
Packit |
67cb25 |
return gsl_complex_arcsinh (t);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_complex
|
|
Packit |
67cb25 |
gsl_complex_arccoth (gsl_complex a)
|
|
Packit |
67cb25 |
{ /* z = arccoth(a) */
|
|
Packit |
67cb25 |
gsl_complex t = gsl_complex_inverse (a);
|
|
Packit |
67cb25 |
return gsl_complex_arctanh (t);
|
|
Packit |
67cb25 |
}
|