summaryrefslogtreecommitdiff
path: root/numpy/core
diff options
context:
space:
mode:
authorMatti Picus <matti.picus@gmail.com>2022-10-06 09:17:15 +0300
committerGitHub <noreply@github.com>2022-10-06 09:17:15 +0300
commit562c80a9fb6ffae6f8d02abf6687437830bb6615 (patch)
treec1b3b962c22f5a18352e28d9dd4bc0cae1cd0a67 /numpy/core
parent5ecaf36cd34aff6886e95a6fb10715b27ecdaa3e (diff)
parent05e213e85d165a74b11fe38a7fb95a48494f8c5f (diff)
downloadnumpy-562c80a9fb6ffae6f8d02abf6687437830bb6615.tar.gz
Merge pull request #22161 from mattip/simplify-npy_math2
MAINT: simplify complex math function handling in npymath
Diffstat (limited to 'numpy/core')
-rw-r--r--numpy/core/feature_detection_cmath.h41
-rw-r--r--numpy/core/setup.py12
-rw-r--r--numpy/core/setup_common.py9
-rw-r--r--numpy/core/src/npymath/npy_math_complex.c.src462
4 files changed, 73 insertions, 451 deletions
diff --git a/numpy/core/feature_detection_cmath.h b/numpy/core/feature_detection_cmath.h
new file mode 100644
index 000000000..ce9a3d4c9
--- /dev/null
+++ b/numpy/core/feature_detection_cmath.h
@@ -0,0 +1,41 @@
+#include <complex.h>
+
+#if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
+#define cfloat _Fcomplex
+#define cdouble _Dcomplex
+#define cldouble _Lcomplex
+#else
+#define cfloat complex float
+#define cdouble complex double
+#define cldouble complex long double
+#endif
+
+cfloat csinf(cfloat);
+cfloat ccosf(cfloat);
+cfloat ctanf(cfloat);
+cfloat csinhf(cfloat);
+cfloat ccoshf(cfloat);
+cfloat ctanhf(cfloat);
+float crealf(cfloat);
+float cimagf(cfloat);
+cfloat conjf(cfloat);
+
+cdouble csin(cdouble);
+cdouble ccos(cdouble);
+cdouble ctan(cdouble);
+cdouble csinh(cdouble);
+cdouble ccosh(cdouble);
+cdouble ctanh(cdouble);
+double creal(cdouble);
+double cimag(cdouble);
+cdouble conj(cdouble);
+
+cldouble csinl(cldouble);
+cldouble ccosl(cldouble);
+cldouble ctanl(cldouble);
+cldouble csinhl(cldouble);
+cldouble ccoshl(cldouble);
+cldouble ctanhl(cldouble);
+long double creall(cldouble);
+long double cimagl(cldouble);
+cldouble conjl(cldouble);
diff --git a/numpy/core/setup.py b/numpy/core/setup.py
index 3a239a70e..17dc8438e 100644
--- a/numpy/core/setup.py
+++ b/numpy/core/setup.py
@@ -134,7 +134,7 @@ def check_math_capabilities(config, ext, moredefs, mathlibs):
def check_func(
func_name,
decl=False,
- headers=["feature_detection_math.h"],
+ headers=["feature_detection_math.h", "feature_detection_cmath.h"],
):
return config.check_func(
func_name,
@@ -145,8 +145,10 @@ def check_math_capabilities(config, ext, moredefs, mathlibs):
headers=headers,
)
- def check_funcs_once(funcs_name, headers=["feature_detection_math.h"],
- add_to_moredefs=True):
+ def check_funcs_once(
+ funcs_name,
+ headers=["feature_detection_math.h", "feature_detection_cmath.h"],
+ add_to_moredefs=True):
call = dict([(f, True) for f in funcs_name])
call_args = dict([(f, FUNC_CALL_ARGS[f]) for f in funcs_name])
st = config.check_funcs_once(
@@ -161,7 +163,9 @@ def check_math_capabilities(config, ext, moredefs, mathlibs):
moredefs.extend([(fname2def(f), 1) for f in funcs_name])
return st
- def check_funcs(funcs_name, headers=["feature_detection_math.h"]):
+ def check_funcs(
+ funcs_name,
+ headers=["feature_detection_math.h", "feature_detection_cmath.h"]):
# Use check_funcs_once first, and if it does not work, test func per
# func. Return success only if all the functions are available
if not check_funcs_once(funcs_name, headers=headers):
diff --git a/numpy/core/setup_common.py b/numpy/core/setup_common.py
index 0100906d0..a8497fe75 100644
--- a/numpy/core/setup_common.py
+++ b/numpy/core/setup_common.py
@@ -102,12 +102,14 @@ def set_sig(sig):
args = args.rpartition(")")[0]
funcname = prefix.rpartition(" ")[-1]
args = [arg.strip() for arg in args.split(",")]
- FUNC_CALL_ARGS[funcname] = ", ".join("(%s) 0" % arg for arg in args)
+ # We use {0} because 0 alone cannot be cast to complex on MSVC in C:
+ FUNC_CALL_ARGS[funcname] = ", ".join("(%s){0}" % arg for arg in args)
for file in [
"feature_detection_locale.h",
"feature_detection_math.h",
+ "feature_detection_cmath.h",
"feature_detection_misc.h",
"feature_detection_stdio.h",
]:
@@ -128,6 +130,8 @@ MANDATORY_FUNCS = [
"rint", "trunc", "exp2",
"copysign", "nextafter", "strtoll", "strtoull", "cbrt",
"log2", "pow", "hypot", "atan2",
+ "csin", "csinh", "ccos", "ccosh", "ctan", "ctanh",
+ "creal", "cimag", "conj"
]
OPTIONAL_LOCALE_FUNCS = ["strtold_l"]
@@ -147,8 +151,7 @@ C99_COMPLEX_TYPES = [
]
C99_COMPLEX_FUNCS = [
"cabs", "cacos", "cacosh", "carg", "casin", "casinh", "catan",
- "catanh", "ccos", "ccosh", "cexp", "cimag", "clog", "conj", "cpow",
- "cproj", "creal", "csin", "csinh", "csqrt", "ctan", "ctanh"
+ "catanh", "cexp", "clog", "cpow", "csqrt",
]
OPTIONAL_HEADERS = [
diff --git a/numpy/core/src/npymath/npy_math_complex.c.src b/numpy/core/src/npymath/npy_math_complex.c.src
index ce2772273..696495dab 100644
--- a/numpy/core/src/npymath/npy_math_complex.c.src
+++ b/numpy/core/src/npymath/npy_math_complex.c.src
@@ -158,9 +158,7 @@ npy_carg@c@(@ctype@ z)
#define SCALED_CEXP_LOWERL 11357.216553474703895L
#define SCALED_CEXP_UPPERL 22756.021937783004509L
-#if !defined(HAVE_CSINH@C@) || \
- !defined(HAVE_CCOSH@C@) || \
- !defined(HAVE_CEXP@C@)
+#if !defined(HAVE_CEXP@C@)
static
@ctype@
@@ -523,443 +521,6 @@ npy_cpow@c@ (@ctype@ a, @ctype@ b)
#endif
}
-
-#ifndef HAVE_CCOS@C@
-@ctype@
-npy_ccos@c@(@ctype@ z)
-{
- /* ccos(z) = ccosh(I * z) */
- return npy_ccosh@c@(npy_cpack@c@(-npy_cimag@c@(z), npy_creal@c@(z)));
-}
-#endif
-
-#ifndef HAVE_CSIN@C@
-@ctype@
-npy_csin@c@(@ctype@ z)
-{
- /* csin(z) = -I * csinh(I * z) */
- z = npy_csinh@c@(npy_cpack@c@(-npy_cimag@c@(z), npy_creal@c@(z)));
- return npy_cpack@c@(npy_cimag@c@(z), -npy_creal@c@(z));
-}
-#endif
-
-#ifndef HAVE_CTAN@C@
-@ctype@
-npy_ctan@c@(@ctype@ z)
-{
- /* ctan(z) = -I * ctanh(I * z) */
- z = npy_ctanh@c@(npy_cpack@c@(-npy_cimag@c@(z), npy_creal@c@(z)));
- return (npy_cpack@c@(npy_cimag@c@(z), -npy_creal@c@(z)));
-}
-#endif
-
-#ifndef HAVE_CCOSH@C@
-/*
- * Taken from the msun library in FreeBSD, rev 226599.
- *
- * Hyperbolic cosine of a complex argument z = x + i y.
- *
- * cosh(z) = cosh(x+iy)
- * = cosh(x) cos(y) + i sinh(x) sin(y).
- *
- * Exceptional values are noted in the comments within the source code.
- * These values and the return value were taken from n1124.pdf.
- *
- * CCOSH_BIG is chosen such that
- * spacing(0.5 * exp(CCOSH_BIG)) > 0.5*exp(-CCOSH_BIG)
- * although the exact value assigned to CCOSH_BIG is not so important
- */
-@ctype@
-npy_ccosh@c@(@ctype@ z)
-{
-#if @precision@ == 1
- const npy_float CCOSH_BIG = 9.0f;
- const npy_float CCOSH_HUGE = 1.70141183e+38f;
-#endif
-#if @precision@ == 2
- const npy_double CCOSH_BIG = 22.0;
- const npy_double CCOSH_HUGE = 8.9884656743115795e+307;
-#endif
-#if @precision@ >= 3
-#if NPY_SIZEOF_LONGDOUBLE == NPY_SIZEOF_DOUBLE
- const npy_longdouble CCOSH_BIG = 22.0L;
- const npy_longdouble CCOSH_HUGE = 8.9884656743115795e+307L;
-#else
- const npy_longdouble CCOSH_BIG = 24.0L;
- const npy_longdouble CCOSH_HUGE = 5.94865747678615882543e+4931L;
-#endif
-#endif
-
- @type@ x, y, h, absx;
- npy_int xfinite, yfinite;
-
- x = npy_creal@c@(z);
- y = npy_cimag@c@(z);
-
- xfinite = npy_isfinite(x);
- yfinite = npy_isfinite(y);
-
- /* Handle the nearly-non-exceptional cases where x and y are finite. */
- if (xfinite && yfinite) {
- if (y == 0) {
- return npy_cpack@c@(npy_cosh@c@(x), x * y);
- }
- absx = npy_fabs@c@(x);
- if (absx < CCOSH_BIG) {
- /* small x: normal case */
- return npy_cpack@c@(npy_cosh@c@(x) * npy_cos@c@(y),
- npy_sinh@c@(x) * npy_sin@c@(y));
- }
-
- /* |x| >= 22, so cosh(x) ~= exp(|x|) */
- if (absx < SCALED_CEXP_LOWER@C@) {
- /* x < 710: exp(|x|) won't overflow */
- h = npy_exp@c@(absx) * 0.5@c@;
- return npy_cpack@c@(h * npy_cos@c@(y),
- npy_copysign@c@(h, x) * npy_sin@c@(y));
- }
- else if (absx < SCALED_CEXP_UPPER@C@) {
- /* x < 1455: scale to avoid overflow */
- z = _npy_scaled_cexp@c@(absx, y, -1);
- return npy_cpack@c@(npy_creal@c@(z),
- npy_cimag@c@(z) * npy_copysign@c@(1, x));
- }
- else {
- /* x >= 1455: the result always overflows */
- h = CCOSH_HUGE * x;
- return npy_cpack@c@(h * h * npy_cos@c@(y), h * npy_sin@c@(y));
- }
- }
-
- /*
- * cosh(+-0 +- I Inf) = dNaN + I sign(d(+-0, dNaN))0.
- * The sign of 0 in the result is unspecified. Choice = normally
- * the same as dNaN. Raise the invalid floating-point exception.
- *
- * cosh(+-0 +- I NaN) = d(NaN) + I sign(d(+-0, NaN))0.
- * The sign of 0 in the result is unspecified. Choice = normally
- * the same as d(NaN).
- */
- if (x == 0 && !yfinite) {
- return npy_cpack@c@(y - y, npy_copysign@c@(0, x * (y - y)));
- }
-
- /*
- * cosh(+-Inf +- I 0) = +Inf + I (+-)(+-)0.
- *
- * cosh(NaN +- I 0) = d(NaN) + I sign(d(NaN, +-0))0.
- * The sign of 0 in the result is unspecified.
- */
- if (y == 0 && !xfinite) {
- return npy_cpack@c@(x * x, npy_copysign@c@(0, x) * y);
- }
-
- /*
- * cosh(x +- I Inf) = dNaN + I dNaN.
- * Raise the invalid floating-point exception for finite nonzero x.
- *
- * cosh(x + I NaN) = d(NaN) + I d(NaN).
- * Optionally raises the invalid floating-point exception for finite
- * nonzero x. Choice = don't raise (except for signaling NaNs).
- */
- if (xfinite && !yfinite) {
- return npy_cpack@c@(y - y, x * (y - y));
- }
-
- /*
- * cosh(+-Inf + I NaN) = +Inf + I d(NaN).
- *
- * cosh(+-Inf +- I Inf) = +Inf + I dNaN.
- * The sign of Inf in the result is unspecified. Choice = always +.
- * Raise the invalid floating-point exception.
- *
- * cosh(+-Inf + I y) = +Inf cos(y) +- I Inf sin(y)
- */
- if (npy_isinf(x)) {
- if (!yfinite) {
- return npy_cpack@c@(x * x, x * (y - y));
- }
- return npy_cpack@c@((x * x) * npy_cos@c@(y), x * npy_sin@c@(y));
- }
-
- /*
- * cosh(NaN + I NaN) = d(NaN) + I d(NaN).
- *
- * cosh(NaN +- I Inf) = d(NaN) + I d(NaN).
- * Optionally raises the invalid floating-point exception.
- * Choice = raise.
- *
- * cosh(NaN + I y) = d(NaN) + I d(NaN).
- * Optionally raises the invalid floating-point exception for finite
- * nonzero y. Choice = don't raise (except for signaling NaNs).
- */
- return npy_cpack@c@((x * x) * (y - y), (x + x) * (y - y));
-}
-#undef CCOSH_BIG
-#undef CCOSH_HUGE
-#endif
-
-#ifndef HAVE_CSINH@C@
-/*
- * Taken from the msun library in FreeBSD, rev 226599.
- *
- * Hyperbolic sine of a complex argument z = x + i y.
- *
- * sinh(z) = sinh(x+iy)
- * = sinh(x) cos(y) + i cosh(x) sin(y).
- *
- * Exceptional values are noted in the comments within the source code.
- * These values and the return value were taken from n1124.pdf.
- */
-@ctype@
-npy_csinh@c@(@ctype@ z)
-{
-#if @precision@ == 1
- const npy_float CSINH_BIG = 9.0f;
- const npy_float CSINH_HUGE = 1.70141183e+38f;
-#endif
-#if @precision@ == 2
- const npy_double CSINH_BIG = 22.0;
- const npy_double CSINH_HUGE = 8.9884656743115795e+307;
-#endif
-#if @precision@ >= 3
-#if NPY_SIZEOF_LONGDOUBLE == NPY_SIZEOF_DOUBLE
- const npy_longdouble CSINH_BIG = 22.0L;
- const npy_longdouble CSINH_HUGE = 8.9884656743115795e+307L;
-#else
- const npy_longdouble CSINH_BIG = 24.0L;
- const npy_longdouble CSINH_HUGE = 5.94865747678615882543e+4931L;
-#endif
-#endif
-
- @type@ x, y, h, absx;
- npy_int xfinite, yfinite;
-
- x = npy_creal@c@(z);
- y = npy_cimag@c@(z);
-
- xfinite = npy_isfinite(x);
- yfinite = npy_isfinite(y);
-
- /* Handle the nearly-non-exceptional cases where x and y are finite. */
- if (xfinite && yfinite) {
- if (y == 0) {
- return npy_cpack@c@(npy_sinh@c@(x), y);
- }
- absx = npy_fabs@c@(x);
- if (absx < CSINH_BIG) {
- /* small x: normal case */
- return npy_cpack@c@(npy_sinh@c@(x) * npy_cos@c@(y),
- npy_cosh@c@(x) * npy_sin@c@(y));
- }
-
- /* |x| >= 22, so cosh(x) ~= exp(|x|) */
- if (absx < SCALED_CEXP_LOWER@C@) {
- /* x < 710: exp(|x|) won't overflow */
- h = npy_exp@c@(npy_fabs@c@(x)) * 0.5@c@;
- return npy_cpack@c@(npy_copysign@c@(h, x) * npy_cos@c@(y),
- h * npy_sin@c@(y));
- }
- else if (x < SCALED_CEXP_UPPER@C@) {
- /* x < 1455: scale to avoid overflow */
- z = _npy_scaled_cexp@c@(absx, y, -1);
- return npy_cpack@c@(npy_creal@c@(z) * npy_copysign@c@(1, x),
- npy_cimag@c@(z));
- }
- else {
- /* x >= 1455: the result always overflows */
- h = CSINH_HUGE * x;
- return npy_cpack@c@(h * npy_cos@c@(y), h * h * npy_sin@c@(y));
- }
- }
-
- /*
- * sinh(+-0 +- I Inf) = sign(d(+-0, dNaN))0 + I dNaN.
- * The sign of 0 in the result is unspecified. Choice = normally
- * the same as dNaN. Raise the invalid floating-point exception.
- *
- * sinh(+-0 +- I NaN) = sign(d(+-0, NaN))0 + I d(NaN).
- * The sign of 0 in the result is unspecified. Choice = normally
- * the same as d(NaN).
- */
- if (x == 0 && !yfinite) {
- return npy_cpack@c@(npy_copysign@c@(0, x * (y - y)), y - y);
- }
-
- /*
- * sinh(+-Inf +- I 0) = +-Inf + I +-0.
- *
- * sinh(NaN +- I 0) = d(NaN) + I +-0.
- */
- if (y == 0 && !xfinite) {
- if (npy_isnan(x)) {
- return z;
- }
- return npy_cpack@c@(x, npy_copysign@c@(0, y));
- }
-
- /*
- * sinh(x +- I Inf) = dNaN + I dNaN.
- * Raise the invalid floating-point exception for finite nonzero x.
- *
- * sinh(x + I NaN) = d(NaN) + I d(NaN).
- * Optionally raises the invalid floating-point exception for finite
- * nonzero x. Choice = don't raise (except for signaling NaNs).
- */
- if (xfinite && !yfinite) {
- return npy_cpack@c@(y - y, x * (y - y));
- }
-
- /*
- * sinh(+-Inf + I NaN) = +-Inf + I d(NaN).
- * The sign of Inf in the result is unspecified. Choice = normally
- * the same as d(NaN).
- *
- * sinh(+-Inf +- I Inf) = +Inf + I dNaN.
- * The sign of Inf in the result is unspecified. Choice = always +.
- * Raise the invalid floating-point exception.
- *
- * sinh(+-Inf + I y) = +-Inf cos(y) + I Inf sin(y)
- */
- if (!xfinite && !npy_isnan(x)) {
- if (!yfinite) {
- return npy_cpack@c@(x * x, x * (y - y));
- }
- return npy_cpack@c@(x * npy_cos@c@(y),
- NPY_INFINITY@C@ * npy_sin@c@(y));
- }
-
- /*
- * sinh(NaN + I NaN) = d(NaN) + I d(NaN).
- *
- * sinh(NaN +- I Inf) = d(NaN) + I d(NaN).
- * Optionally raises the invalid floating-point exception.
- * Choice = raise.
- *
- * sinh(NaN + I y) = d(NaN) + I d(NaN).
- * Optionally raises the invalid floating-point exception for finite
- * nonzero y. Choice = don't raise (except for signaling NaNs).
- */
- return npy_cpack@c@((x * x) * (y - y), (x + x) * (y - y));
-}
-#undef CSINH_BIG
-#undef CSINH_HUGE
-#endif
-
-#ifndef HAVE_CTANH@C@
-/*
- * Taken from the msun library in FreeBSD, rev 226600.
- *
- * Hyperbolic tangent of a complex argument z = x + i y.
- *
- * The algorithm is from:
- *
- * W. Kahan. Branch Cuts for Complex Elementary Functions or Much
- * Ado About Nothing's Sign Bit. In The State of the Art in
- * Numerical Analysis, pp. 165 ff. Iserles and Powell, eds., 1987.
- *
- * Method:
- *
- * Let t = tan(x)
- * beta = 1/cos^2(y)
- * s = sinh(x)
- * rho = cosh(x)
- *
- * We have:
- *
- * tanh(z) = sinh(z) / cosh(z)
- *
- * sinh(x) cos(y) + i cosh(x) sin(y)
- * = ---------------------------------
- * cosh(x) cos(y) + i sinh(x) sin(y)
- *
- * cosh(x) sinh(x) / cos^2(y) + i tan(y)
- * = -------------------------------------
- * 1 + sinh^2(x) / cos^2(y)
- *
- * beta rho s + i t
- * = ----------------
- * 1 + beta s^2
- *
- * Modifications:
- *
- * I omitted the original algorithm's handling of overflow in tan(x) after
- * verifying with nearpi.c that this can't happen in IEEE single or double
- * precision. I also handle large x differently.
- */
-
-#define TANH_HUGE 22.0
-#define TANHF_HUGE 11.0F
-#define TANHL_HUGE 42.0L
-
-@ctype@
-npy_ctanh@c@(@ctype@ z)
-{
- @type@ x, y;
- @type@ t, beta, s, rho, denom;
-
- x = npy_creal@c@(z);
- y = npy_cimag@c@(z);
-
- /*
- * ctanh(NaN + i 0) = NaN + i 0
- *
- * ctanh(NaN + i y) = NaN + i NaN for y != 0
- *
- * The imaginary part has the sign of x*sin(2*y), but there's no
- * special effort to get this right.
- *
- * ctanh(+-Inf +- i Inf) = +-1 +- 0
- *
- * ctanh(+-Inf + i y) = +-1 + 0 sin(2y) for y finite
- *
- * The imaginary part of the sign is unspecified. This special
- * case is only needed to avoid a spurious invalid exception when
- * y is infinite.
- */
- if (!npy_isfinite(x)) {
- if (npy_isnan(x)) {
- return npy_cpack@c@(x, (y == 0 ? y : x * y));
- }
- return npy_cpack@c@(npy_copysign@c@(1,x),
- npy_copysign@c@(0,
- npy_isinf(y) ?
- y : npy_sin@c@(y) * npy_cos@c@(y)));
- }
-
- /*
- * ctanh(x + i NAN) = NaN + i NaN
- * ctanh(x +- i Inf) = NaN + i NaN
- */
- if (!npy_isfinite(y)) {
- return (npy_cpack@c@(y - y, y - y));
- }
-
- /*
- * ctanh(+-huge + i +-y) ~= +-1 +- i 2sin(2y)/exp(2x), using the
- * approximation sinh^2(huge) ~= exp(2*huge) / 4.
- * We use a modified formula to avoid spurious overflow.
- */
- if (npy_fabs@c@(x) >= TANH@C@_HUGE) {
- @type@ exp_mx = npy_exp@c@(-npy_fabs@c@(x));
- return npy_cpack@c@(npy_copysign@c@(1, x),
- 4 * npy_sin@c@(y) * npy_cos@c@(y) *
- exp_mx * exp_mx);
- }
-
- /* Kahan's algorithm */
- t = npy_tan@c@(y);
- beta = 1 + t * t; /* = 1 / cos^2(y) */
- s = npy_sinh@c@(x);
- rho = npy_sqrt@c@(1 + s * s); /* = cosh(x) */
- denom = 1 + beta * s * s;
- return (npy_cpack@c@((beta * rho * s) / denom, t / denom));
-}
-#undef TANH_HUGE
-#undef TANHF_HUGE
-#undef TANHL_HUGE
-#endif
-
#if !defined (HAVE_CACOS@C@) || !defined (HAVE_CASINH@C@)
/*
* Complex inverse trig functions taken from the msum library in FreeBSD
@@ -1752,10 +1313,8 @@ npy_@kind@@c@(@ctype@ z)
/**end repeat1**/
/**begin repeat1
- * #kind = cexp,clog,csqrt,ccos,csin,ctan,ccosh,csinh,ctanh,
- * cacos,casin,catan,cacosh,casinh,catanh#
- * #KIND = CEXP,CLOG,CSQRT,CCOS,CSIN,CTAN,CCOSH,CSINH,CTANH,
- * CACOS,CASIN,CATAN,CACOSH,CASINH,CATANH#
+ * #kind = cexp,clog,csqrt,cacos,casin,catan,cacosh,casinh,catanh#
+ * #KIND = CEXP,CLOG,CSQRT,CACOS,CASIN,CATAN,CACOSH,CASINH,CATANH#
*/
#ifdef HAVE_@KIND@@C@
@ctype@
@@ -1770,5 +1329,20 @@ npy_@kind@@c@(@ctype@ z)
#endif
/**end repeat1**/
+/* Mandatory complex functions */
+
+/**begin repeat1
+ * #kind = csin,csinh,ccos,ccosh,ctan,ctanh#
+ */
+@ctype@
+npy_@kind@@c@(@ctype@ z)
+{
+ __@ctype@_to_c99_cast z1;
+ __@ctype@_to_c99_cast ret;
+ z1.npy_z = z;
+ ret.c99_z = @kind@@c@(z1.c99_z);
+ return ret.npy_z;
+}
+/**end repeat1**/
/**end repeat**/