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