Commit c3f2d977 authored by Robert Bradshaw's avatar Robert Bradshaw

Distinguish between math suffix and type suffix for complex arithmetic.

This closes #1433.
parent 9e641a60
......@@ -11116,7 +11116,7 @@ class PowNode(NumBinopNode):
if self.type.real_type.is_float:
self.operand1 = self.operand1.coerce_to(self.type, env)
self.operand2 = self.operand2.coerce_to(self.type, env)
self.pow_func = "__Pyx_c_pow" + self.type.real_type.math_h_modifier
self.pow_func = self.type.binary_op('**')
else:
error(self.pos, "complex int powers not supported")
self.pow_func = "<error>"
......
......@@ -1968,14 +1968,11 @@ class CComplexType(CNumericType):
def __init__(self, real_type):
while real_type.is_typedef and not real_type.typedef_is_external:
real_type = real_type.typedef_base_type
if real_type.is_typedef and real_type.typedef_is_external:
# The below is not actually used: Coercions are currently disabled
# so that complex types of external types can not be created
self.funcsuffix = "_%s" % real_type.specialization_name()
elif hasattr(real_type, 'math_h_modifier'):
self.funcsuffix = real_type.math_h_modifier
self.funcsuffix = "_%s" % real_type.specialization_name()
if real_type.is_float:
self.math_h_modifier = real_type.math_h_modifier
else:
self.funcsuffix = "_%s" % real_type.specialization_name()
self.math_h_modifier = "_UNUSED"
self.real_type = real_type
CNumericType.__init__(self, real_type.rank + 0.5, real_type.signed)
......@@ -2059,7 +2056,8 @@ class CComplexType(CNumericType):
'type': self.empty_declaration_code(),
'type_name': self.specialization_name(),
'real_type': self.real_type.empty_declaration_code(),
'm': self.funcsuffix,
'func_suffix': self.funcsuffix,
'm': self.math_h_modifier,
'is_float': int(self.real_type.is_float)
}
......@@ -2118,6 +2116,7 @@ complex_ops = {
(2, '-'): 'diff',
(2, '*'): 'prod',
(2, '/'): 'quot',
(2, '**'): 'pow',
(2, '=='): 'eq',
}
......
......@@ -115,39 +115,39 @@ static {{type}} __Pyx_PyComplex_As_{{type_name}}(PyObject* o) {
/////////////// Arithmetic.proto ///////////////
#if CYTHON_CCOMPLEX
#define __Pyx_c_eq{{m}}(a, b) ((a)==(b))
#define __Pyx_c_sum{{m}}(a, b) ((a)+(b))
#define __Pyx_c_diff{{m}}(a, b) ((a)-(b))
#define __Pyx_c_prod{{m}}(a, b) ((a)*(b))
#define __Pyx_c_quot{{m}}(a, b) ((a)/(b))
#define __Pyx_c_neg{{m}}(a) (-(a))
#define __Pyx_c_eq{{func_suffix}}(a, b) ((a)==(b))
#define __Pyx_c_sum{{func_suffix}}(a, b) ((a)+(b))
#define __Pyx_c_diff{{func_suffix}}(a, b) ((a)-(b))
#define __Pyx_c_prod{{func_suffix}}(a, b) ((a)*(b))
#define __Pyx_c_quot{{func_suffix}}(a, b) ((a)/(b))
#define __Pyx_c_neg{{func_suffix}}(a) (-(a))
#ifdef __cplusplus
#define __Pyx_c_is_zero{{m}}(z) ((z)==({{real_type}})0)
#define __Pyx_c_conj{{m}}(z) (::std::conj(z))
#define __Pyx_c_is_zero{{func_suffix}}(z) ((z)==({{real_type}})0)
#define __Pyx_c_conj{{func_suffix}}(z) (::std::conj(z))
#if {{is_float}}
#define __Pyx_c_abs{{m}}(z) (::std::abs(z))
#define __Pyx_c_pow{{m}}(a, b) (::std::pow(a, b))
#define __Pyx_c_abs{{func_suffix}}(z) (::std::abs(z))
#define __Pyx_c_pow{{func_suffix}}(a, b) (::std::pow(a, b))
#endif
#else
#define __Pyx_c_is_zero{{m}}(z) ((z)==0)
#define __Pyx_c_conj{{m}}(z) (conj{{m}}(z))
#define __Pyx_c_is_zero{{func_suffix}}(z) ((z)==0)
#define __Pyx_c_conj{{func_suffix}}(z) (conj{{m}}(z))
#if {{is_float}}
#define __Pyx_c_abs{{m}}(z) (cabs{{m}}(z))
#define __Pyx_c_pow{{m}}(a, b) (cpow{{m}}(a, b))
#define __Pyx_c_abs{{func_suffix}}(z) (cabs{{m}}(z))
#define __Pyx_c_pow{{func_suffix}}(a, b) (cpow{{m}}(a, b))
#endif
#endif
#else
static CYTHON_INLINE int __Pyx_c_eq{{m}}({{type}}, {{type}});
static CYTHON_INLINE {{type}} __Pyx_c_sum{{m}}({{type}}, {{type}});
static CYTHON_INLINE {{type}} __Pyx_c_diff{{m}}({{type}}, {{type}});
static CYTHON_INLINE {{type}} __Pyx_c_prod{{m}}({{type}}, {{type}});
static CYTHON_INLINE {{type}} __Pyx_c_quot{{m}}({{type}}, {{type}});
static CYTHON_INLINE {{type}} __Pyx_c_neg{{m}}({{type}});
static CYTHON_INLINE int __Pyx_c_is_zero{{m}}({{type}});
static CYTHON_INLINE {{type}} __Pyx_c_conj{{m}}({{type}});
static CYTHON_INLINE int __Pyx_c_eq{{func_suffix}}({{type}}, {{type}});
static CYTHON_INLINE {{type}} __Pyx_c_sum{{func_suffix}}({{type}}, {{type}});
static CYTHON_INLINE {{type}} __Pyx_c_diff{{func_suffix}}({{type}}, {{type}});
static CYTHON_INLINE {{type}} __Pyx_c_prod{{func_suffix}}({{type}}, {{type}});
static CYTHON_INLINE {{type}} __Pyx_c_quot{{func_suffix}}({{type}}, {{type}});
static CYTHON_INLINE {{type}} __Pyx_c_neg{{func_suffix}}({{type}});
static CYTHON_INLINE int __Pyx_c_is_zero{{func_suffix}}({{type}});
static CYTHON_INLINE {{type}} __Pyx_c_conj{{func_suffix}}({{type}});
#if {{is_float}}
static CYTHON_INLINE {{real_type}} __Pyx_c_abs{{m}}({{type}});
static CYTHON_INLINE {{type}} __Pyx_c_pow{{m}}({{type}}, {{type}});
static CYTHON_INLINE {{real_type}} __Pyx_c_abs{{func_suffix}}({{type}});
static CYTHON_INLINE {{type}} __Pyx_c_pow{{func_suffix}}({{type}}, {{type}});
#endif
#endif
......@@ -155,22 +155,22 @@ static {{type}} __Pyx_PyComplex_As_{{type_name}}(PyObject* o) {
#if CYTHON_CCOMPLEX
#else
static CYTHON_INLINE int __Pyx_c_eq{{m}}({{type}} a, {{type}} b) {
static CYTHON_INLINE int __Pyx_c_eq{{func_suffix}}({{type}} a, {{type}} b) {
return (a.real == b.real) && (a.imag == b.imag);
}
static CYTHON_INLINE {{type}} __Pyx_c_sum{{m}}({{type}} a, {{type}} b) {
static CYTHON_INLINE {{type}} __Pyx_c_sum{{func_suffix}}({{type}} a, {{type}} b) {
{{type}} z;
z.real = a.real + b.real;
z.imag = a.imag + b.imag;
return z;
}
static CYTHON_INLINE {{type}} __Pyx_c_diff{{m}}({{type}} a, {{type}} b) {
static CYTHON_INLINE {{type}} __Pyx_c_diff{{func_suffix}}({{type}} a, {{type}} b) {
{{type}} z;
z.real = a.real - b.real;
z.imag = a.imag - b.imag;
return z;
}
static CYTHON_INLINE {{type}} __Pyx_c_prod{{m}}({{type}} a, {{type}} b) {
static CYTHON_INLINE {{type}} __Pyx_c_prod{{func_suffix}}({{type}} a, {{type}} b) {
{{type}} z;
z.real = a.real * b.real - a.imag * b.imag;
z.imag = a.real * b.imag + a.imag * b.real;
......@@ -178,7 +178,7 @@ static {{type}} __Pyx_PyComplex_As_{{type_name}}(PyObject* o) {
}
#if {{is_float}}
static CYTHON_INLINE {{type}} __Pyx_c_quot{{m}}({{type}} a, {{type}} b) {
static CYTHON_INLINE {{type}} __Pyx_c_quot{{func_suffix}}({{type}} a, {{type}} b) {
if (b.imag == 0) {
return {{type_name}}_from_parts(a.real / b.real, a.imag / b.real);
} else if (fabs{{m}}(b.real) >= fabs{{m}}(b.imag)) {
......@@ -198,7 +198,7 @@ static {{type}} __Pyx_PyComplex_As_{{type_name}}(PyObject* o) {
}
}
#else
static CYTHON_INLINE {{type}} __Pyx_c_quot{{m}}({{type}} a, {{type}} b) {
static CYTHON_INLINE {{type}} __Pyx_c_quot{{func_suffix}}({{type}} a, {{type}} b) {
if (b.imag == 0) {
return {{type_name}}_from_parts(a.real / b.real, a.imag / b.real);
} else {
......@@ -210,30 +210,30 @@ static {{type}} __Pyx_PyComplex_As_{{type_name}}(PyObject* o) {
}
#endif
static CYTHON_INLINE {{type}} __Pyx_c_neg{{m}}({{type}} a) {
static CYTHON_INLINE {{type}} __Pyx_c_neg{{func_suffix}}({{type}} a) {
{{type}} z;
z.real = -a.real;
z.imag = -a.imag;
return z;
}
static CYTHON_INLINE int __Pyx_c_is_zero{{m}}({{type}} a) {
static CYTHON_INLINE int __Pyx_c_is_zero{{func_suffix}}({{type}} a) {
return (a.real == 0) && (a.imag == 0);
}
static CYTHON_INLINE {{type}} __Pyx_c_conj{{m}}({{type}} a) {
static CYTHON_INLINE {{type}} __Pyx_c_conj{{func_suffix}}({{type}} a) {
{{type}} z;
z.real = a.real;
z.imag = -a.imag;
return z;
}
#if {{is_float}}
static CYTHON_INLINE {{real_type}} __Pyx_c_abs{{m}}({{type}} z) {
static CYTHON_INLINE {{real_type}} __Pyx_c_abs{{func_suffix}}({{type}} z) {
#if !defined(HAVE_HYPOT) || defined(_MSC_VER)
return sqrt{{m}}(z.real*z.real + z.imag*z.imag);
#else
return hypot{{m}}(z.real, z.imag);
#endif
}
static CYTHON_INLINE {{type}} __Pyx_c_pow{{m}}({{type}} a, {{type}} b) {
static CYTHON_INLINE {{type}} __Pyx_c_pow{{func_suffix}}({{type}} a, {{type}} b) {
{{type}} z;
{{real_type}} r, lnr, theta, z_r, z_theta;
if (b.imag == 0 && b.real == (int)b.real) {
......@@ -251,14 +251,14 @@ static {{type}} __Pyx_PyComplex_As_{{type_name}}(PyObject* o) {
case 1:
return a;
case 2:
z = __Pyx_c_prod{{m}}(a, a);
return __Pyx_c_prod{{m}}(a, a);
z = __Pyx_c_prod{{func_suffix}}(a, a);
return __Pyx_c_prod{{func_suffix}}(a, a);
case 3:
z = __Pyx_c_prod{{m}}(a, a);
return __Pyx_c_prod{{m}}(z, a);
z = __Pyx_c_prod{{func_suffix}}(a, a);
return __Pyx_c_prod{{func_suffix}}(z, a);
case 4:
z = __Pyx_c_prod{{m}}(a, a);
return __Pyx_c_prod{{m}}(z, z);
z = __Pyx_c_prod{{func_suffix}}(a, a);
return __Pyx_c_prod{{func_suffix}}(z, z);
}
}
if (a.imag == 0) {
......@@ -268,7 +268,7 @@ static {{type}} __Pyx_PyComplex_As_{{type_name}}(PyObject* o) {
r = a.real;
theta = 0;
} else {
r = __Pyx_c_abs{{m}}(a);
r = __Pyx_c_abs{{func_suffix}}(a);
theta = atan2{{m}}(a.imag, a.real);
}
lnr = log{{m}}(r);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment