/* Complex math module */

/* much code borrowed from mathmodule.c */

#include "Python.h"

#include "mymath.h"

#ifdef i860
/* Cray APP has bogus definition of HUGE_VAL in <math.h> */
#undef HUGE_VAL
#endif

#ifdef HUGE_VAL
#define CHECK(x) if (errno != 0) ; \
	else if (-HUGE_VAL <= (x) && (x) <= HUGE_VAL) ; \
	else errno = ERANGE
#else
#define CHECK(x) /* Don't know how to check */
#endif

#ifndef M_PI
#define M_PI (3.141592653589793239)
#endif

/* First, the C functions that do the real work */

/* constants */
static Py_complex c_1 = {1., 0.};
static Py_complex c_half = {0.5, 0.};
static Py_complex c_i = {0., 1.};
static Py_complex c_i2 = {0., 0.5};
#if 0
static Py_complex c_mi = {0., -1.};
static Py_complex c_pi2 = {M_PI/2., 0.};
#endif

/* forward declarations */
staticforward Py_complex c_log();
staticforward Py_complex c_prodi();
staticforward Py_complex c_sqrt();


static Py_complex c_acos(x)
	Py_complex x;
{
	return c_neg(c_prodi(c_log(c_sum(x,c_prod(c_i,
		    c_sqrt(c_diff(c_1,c_prod(x,x))))))));
}

static char c_acos_doc [] =
"acos(x)\n\
\n\
Return the arc cosine of x.";


static Py_complex c_acosh(x)
	Py_complex x;
{
	return c_log(c_sum(x,c_prod(c_i,
		    c_sqrt(c_diff(c_1,c_prod(x,x))))));
}

static char c_acosh_doc [] =
"acosh(x)\n\
\n\
Return the hyperbolic cosine of x.";


static Py_complex c_asin(x)
	Py_complex x;
{
	return c_neg(c_prodi(c_log(c_sum(c_prod(c_i,x),
		    c_sqrt(c_diff(c_1,c_prod(x,x)))))));
}

static char c_asin_doc [] =
"asin(x)\n\
\n\
Return the arc sine of x.";


static Py_complex c_asinh(x)
	Py_complex x;
{
	return c_neg(c_log(c_diff(c_sqrt(c_sum(c_1,c_prod(x,x))),x)));
}

static char c_asinh_doc [] =
"asinh(x)\n\
\n\
Return the hyperbolic arc sine of x.";


static Py_complex c_atan(x)
	Py_complex x;
{
	return c_prod(c_i2,c_log(c_quot(c_sum(c_i,x),c_diff(c_i,x))));
}

static char c_atan_doc [] =
"atan(x)\n\
\n\
Return the arc tangent of x.";


static Py_complex c_atanh(x)
	Py_complex x;
{
	return c_prod(c_half,c_log(c_quot(c_sum(c_1,x),c_diff(c_1,x))));
}

static char c_atanh_doc [] =
"atanh(x)\n\
\n\
Return the hyperbolic arc tangent of x.";


static Py_complex c_cos(x)
	Py_complex x;
{
	Py_complex r;
	r.real = cos(x.real)*cosh(x.imag);
	r.imag = -sin(x.real)*sinh(x.imag);
	return r;
}

static char c_cos_doc [] =
"cos(x)\n\
\n\
Return the cosine of x.";


static Py_complex c_cosh(x)
	Py_complex x;
{
	Py_complex r;
	r.real = cos(x.imag)*cosh(x.real);
	r.imag = sin(x.imag)*sinh(x.real);
	return r;
}

static char c_cosh_doc [] =
"cosh(x)\n\
\n\
Return the hyperbolic cosine of x.";


static Py_complex c_exp(x)
	Py_complex x;
{
	Py_complex r;
	double l = exp(x.real);
	r.real = l*cos(x.imag);
	r.imag = l*sin(x.imag);
	return r;
}

static char c_exp_doc [] =
"exp(x)\n\
\n\
Return the exponential value e**x.";


static Py_complex c_log(x)
	Py_complex x;
{
	Py_complex r;
	double l = hypot(x.real,x.imag);
	r.imag = atan2(x.imag, x.real);
	r.real = log(l);
	return r;
}

static char c_log_doc [] =
"log(x)\n\
\n\
Return the natural logarithm of x.";


static Py_complex c_log10(x)
	Py_complex x;
{
	Py_complex r;
	double l = hypot(x.real,x.imag);
	r.imag = atan2(x.imag, x.real)/log(10.);
	r.real = log10(l);
	return r;
}

static char c_log10_doc [] =
"log10(x)\n\
\n\
Return the base-10 logarithm of x.";


/* internal function not available from Python */
static Py_complex c_prodi(x)
     Py_complex x;
{
	Py_complex r;
	r.real = -x.imag;
	r.imag = x.real;
	return r;
}


static Py_complex c_sin(x)
	Py_complex x;
{
	Py_complex r;
	r.real = sin(x.real)*cosh(x.imag);
	r.imag = cos(x.real)*sinh(x.imag);
	return r;
}

static char c_sin_doc [] =
"sin(x)\n\
\n\
Return the sine of x.";


static Py_complex c_sinh(x)
	Py_complex x;
{
	Py_complex r;
	r.real = cos(x.imag)*sinh(x.real);
	r.imag = sin(x.imag)*cosh(x.real);
	return r;
}

static char c_sinh_doc [] =
"sinh(x)\n\
\n\
Return the hyperbolic sine of x.";


static Py_complex c_sqrt(x)
	Py_complex x;
{
	Py_complex r;
	double s,d;
	if (x.real == 0. && x.imag == 0.)
		r = x;
	else {
		s = sqrt(0.5*(fabs(x.real) + hypot(x.real,x.imag)));
		d = 0.5*x.imag/s;
		if (x.real > 0.) {
			r.real = s;
			r.imag = d;
		}
		else if (x.imag >= 0.) {
			r.real = d;
			r.imag = s;
		}
		else {
			r.real = -d;
			r.imag = -s;
		}
	}
	return r;
}

static char c_sqrt_doc [] =
"sqrt(x)\n\
\n\
Return the square root of x.";


static Py_complex c_tan(x)
	Py_complex x;
{
	Py_complex r;
	double sr,cr,shi,chi;
	double rs,is,rc,ic;
	double d;
	sr = sin(x.real);
	cr = cos(x.real);
	shi = sinh(x.imag);
	chi = cosh(x.imag);
	rs = sr*chi;
	is = cr*shi;
	rc = cr*chi;
	ic = -sr*shi;
	d = rc*rc + ic*ic;
	r.real = (rs*rc+is*ic)/d;
	r.imag = (is*rc-rs*ic)/d;
	return r;
}

static char c_tan_doc [] =
"tan(x)\n\
\n\
Return the tangent of x.";


static Py_complex c_tanh(x)
	Py_complex x;
{
	Py_complex r;
	double si,ci,shr,chr;
	double rs,is,rc,ic;
	double d;
	si = sin(x.imag);
	ci = cos(x.imag);
	shr = sinh(x.real);
	chr = cosh(x.real);
	rs = ci*shr;
	is = si*chr;
	rc = ci*chr;
	ic = si*shr;
	d = rc*rc + ic*ic;
	r.real = (rs*rc+is*ic)/d;
	r.imag = (is*rc-rs*ic)/d;
	return r;
}

static char c_tanh_doc [] =
"tanh(x)\n\
\n\
Return the hyperbolic tangent of x.";


/* And now the glue to make them available from Python: */

static PyObject *
math_error()
{
	if (errno == EDOM)
		PyErr_SetString(PyExc_ValueError, "math domain error");
	else if (errno == ERANGE)
		PyErr_SetString(PyExc_OverflowError, "math range error");
	else    /* Unexpected math error */
		PyErr_SetFromErrno(PyExc_ValueError); 
	return NULL;
}

static PyObject *
math_1(args, func)
	PyObject *args;
	Py_complex (*func) Py_FPROTO((Py_complex));
{
	Py_complex x;
	if (!PyArg_ParseTuple(args, "D", &x))
		return NULL;
	errno = 0;
	PyFPE_START_PROTECT("complex function", return 0)
	x = (*func)(x);
	PyFPE_END_PROTECT(x)
	CHECK(x.real);
	CHECK(x.imag);
	if (errno != 0)
		return math_error();
	else
		return PyComplex_FromCComplex(x);
}

#define FUNC1(stubname, func) \
	static PyObject * stubname(self, args) PyObject *self, *args; { \
		return math_1(args, func); \
	}

FUNC1(cmath_acos, c_acos)
FUNC1(cmath_acosh, c_acosh)
FUNC1(cmath_asin, c_asin)
FUNC1(cmath_asinh, c_asinh)
FUNC1(cmath_atan, c_atan)
FUNC1(cmath_atanh, c_atanh)
FUNC1(cmath_cos, c_cos)
FUNC1(cmath_cosh, c_cosh)
FUNC1(cmath_exp, c_exp)
FUNC1(cmath_log, c_log)
FUNC1(cmath_log10, c_log10)
FUNC1(cmath_sin, c_sin)
FUNC1(cmath_sinh, c_sinh)
FUNC1(cmath_sqrt, c_sqrt)
FUNC1(cmath_tan, c_tan)
FUNC1(cmath_tanh, c_tanh)


static char module_doc [] =
"This module is always available. It provides access to mathematical\n\
functions for complex numbers.";


static PyMethodDef cmath_methods[] = {
	{"acos", cmath_acos, 1, c_acos_doc},
	{"acosh", cmath_acosh, 1, c_acosh_doc},
	{"asin", cmath_asin, 1, c_asin_doc},
	{"asinh", cmath_asinh, 1, c_asinh_doc},
	{"atan", cmath_atan, 1, c_atan_doc},
	{"atanh", cmath_atanh, 1, c_atanh_doc},
	{"cos", cmath_cos, 1, c_cos_doc},
	{"cosh", cmath_cosh, 1, c_cosh_doc},
	{"exp", cmath_exp, 1, c_exp_doc},
	{"log", cmath_log, 1, c_log_doc},
	{"log10", cmath_log10, 1, c_log10_doc},
	{"sin", cmath_sin, 1, c_sin_doc},
	{"sinh", cmath_sinh, 1, c_sinh_doc},
	{"sqrt", cmath_sqrt, 1, c_sqrt_doc},
	{"tan", cmath_tan, 1, c_tan_doc},
	{"tanh", cmath_tanh, 1, c_tanh_doc},
	{NULL,		NULL}		/* sentinel */
};

DL_EXPORT(void)
initcmath()
{
	PyObject *m, *d, *v;
	
	m = Py_InitModule3("cmath", cmath_methods, module_doc);
	d = PyModule_GetDict(m);
	PyDict_SetItemString(d, "pi",
			     v = PyFloat_FromDouble(atan(1.0) * 4.0));
	Py_DECREF(v);
	PyDict_SetItemString(d, "e", v = PyFloat_FromDouble(exp(1.0)));
	Py_DECREF(v);
}
