Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Gwenaël Samain
cython
Commits
dd37f81e
Commit
dd37f81e
authored
Oct 13, 2009
by
Lisandro Dalcin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Seamless C99/C++ complex numbers support (ticket #398)
parent
61e95f53
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
260 additions
and
116 deletions
+260
-116
Cython/Compiler/Code.py
Cython/Compiler/Code.py
+0
-1
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+12
-15
Cython/Compiler/ModuleNode.py
Cython/Compiler/ModuleNode.py
+5
-5
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+1
-1
Cython/Compiler/Options.py
Cython/Compiler/Options.py
+1
-1
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+187
-75
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+1
-1
tests/run/complex_numbers_T305.pyx
tests/run/complex_numbers_T305.pyx
+27
-17
tests/run/complex_numbers_c89_T398.h
tests/run/complex_numbers_c89_T398.h
+1
-0
tests/run/complex_numbers_c89_T398.pyx
tests/run/complex_numbers_c89_T398.pyx
+2
-0
tests/run/complex_numbers_c99_T398.h
tests/run/complex_numbers_c99_T398.h
+14
-0
tests/run/complex_numbers_c99_T398.pyx
tests/run/complex_numbers_c99_T398.pyx
+2
-0
tests/run/complex_numbers_cxx_T398.h
tests/run/complex_numbers_cxx_T398.h
+5
-0
tests/run/complex_numbers_cxx_T398.pyx
tests/run/complex_numbers_cxx_T398.pyx
+2
-0
No files found.
Cython/Compiler/Code.py
View file @
dd37f81e
...
@@ -396,7 +396,6 @@ class GlobalState(object):
...
@@ -396,7 +396,6 @@ class GlobalState(object):
code_layout = [
code_layout = [
'h_code',
'h_code',
'complex_numbers_utility_code',
'utility_code_proto_before_types',
'utility_code_proto_before_types',
'type_declarations',
'type_declarations',
'utility_code_proto',
'utility_code_proto',
...
...
Cython/Compiler/ExprNodes.py
View file @
dd37f81e
...
@@ -544,9 +544,8 @@ class ExprNode(Node):
...
@@ -544,9 +544,8 @@ class ExprNode(Node):
elif
src
.
type
.
is_pyobject
:
elif
src
.
type
.
is_pyobject
:
src
=
CoerceFromPyTypeNode
(
dst_type
,
src
,
env
)
src
=
CoerceFromPyTypeNode
(
dst_type
,
src
,
env
)
elif
(
dst_type
.
is_complex
elif
(
dst_type
.
is_complex
and
src_type
!=
dst_type
and
src_type
!=
dst_type
and
dst_type
.
assignable_from
(
src_type
)
and
dst_type
.
assignable_from
(
src_type
)):
and
not
env
.
directives
[
'c99_complex'
]):
src
=
CoerceToComplexNode
(
src
,
dst_type
,
env
)
src
=
CoerceToComplexNode
(
src
,
dst_type
,
env
)
else
:
# neither src nor dst are py types
else
:
# neither src nor dst are py types
# Added the string comparison, since for c types that
# Added the string comparison, since for c types that
...
@@ -1007,8 +1006,6 @@ class ImagNode(AtomicExprNode):
...
@@ -1007,8 +1006,6 @@ class ImagNode(AtomicExprNode):
def
calculate_result_code
(
self
):
def
calculate_result_code
(
self
):
if
self
.
type
.
is_pyobject
:
if
self
.
type
.
is_pyobject
:
return
self
.
result
()
return
self
.
result
()
elif
self
.
c99_complex
:
return
"%rj"
%
float
(
self
.
value
)
else
:
else
:
return
"%s(0, %r)"
%
(
self
.
type
.
from_parts
,
float
(
self
.
value
))
return
"%s(0, %r)"
%
(
self
.
type
.
from_parts
,
float
(
self
.
value
))
...
@@ -1020,8 +1017,6 @@ class ImagNode(AtomicExprNode):
...
@@ -1020,8 +1017,6 @@ class ImagNode(AtomicExprNode):
float
(
self
.
value
),
float
(
self
.
value
),
code
.
error_goto_if_null
(
self
.
result
(),
self
.
pos
)))
code
.
error_goto_if_null
(
self
.
result
(),
self
.
pos
)))
code
.
put_gotref
(
self
.
py_result
())
code
.
put_gotref
(
self
.
py_result
())
else
:
self
.
c99_complex
=
code
.
globalstate
.
directives
[
'c99_complex'
]
...
@@ -3014,7 +3009,7 @@ class AttributeNode(ExprNode):
...
@@ -3014,7 +3009,7 @@ class AttributeNode(ExprNode):
else
:
else
:
return
self
.
member
return
self
.
member
elif
obj
.
type
.
is_complex
:
elif
obj
.
type
.
is_complex
:
return
"__Pyx_
%s_PART
(%s)"
%
(
self
.
member
.
upper
(),
obj_code
)
return
"__Pyx_
C%s
(%s)"
%
(
self
.
member
.
upper
(),
obj_code
)
else
:
else
:
return
"%s%s%s"
%
(
obj_code
,
self
.
op
,
self
.
member
)
return
"%s%s%s"
%
(
obj_code
,
self
.
op
,
self
.
member
)
...
@@ -4071,7 +4066,7 @@ class UnaryMinusNode(UnopNode):
...
@@ -4071,7 +4066,7 @@ class UnaryMinusNode(UnopNode):
else
:
else
:
self
.
type_error
()
self
.
type_error
()
if
self
.
type
.
is_complex
:
if
self
.
type
.
is_complex
:
self
.
infix
=
env
.
directives
[
'c99_complex'
]
self
.
infix
=
False
def
py_operation_function
(
self
):
def
py_operation_function
(
self
):
return
"PyNumber_Negative"
return
"PyNumber_Negative"
...
@@ -4498,7 +4493,7 @@ class NumBinopNode(BinopNode):
...
@@ -4498,7 +4493,7 @@ class NumBinopNode(BinopNode):
if
not
self
.
type
:
if
not
self
.
type
:
self
.
type_error
()
self
.
type_error
()
return
return
if
self
.
type
.
is_complex
and
not
env
.
directives
[
'c99_complex'
]
:
if
self
.
type
.
is_complex
:
self
.
infix
=
False
self
.
infix
=
False
if
not
self
.
infix
:
if
not
self
.
infix
:
self
.
operand1
=
self
.
operand1
.
coerce_to
(
self
.
type
,
env
)
self
.
operand1
=
self
.
operand1
.
coerce_to
(
self
.
type
,
env
)
...
@@ -5146,9 +5141,11 @@ class CmpNode(object):
...
@@ -5146,9 +5141,11 @@ class CmpNode(object):
richcmp_constants
[
op
],
richcmp_constants
[
op
],
code
.
error_goto_if_null
(
result_code
,
self
.
pos
)))
code
.
error_goto_if_null
(
result_code
,
self
.
pos
)))
code
.
put_gotref
(
result_code
)
code
.
put_gotref
(
result_code
)
elif
operand1
.
type
.
is_complex
and
not
code
.
globalstate
.
directives
[
'c99_complex'
]:
elif
operand1
.
type
.
is_complex
:
if
op
==
"!="
:
negation
=
"!"
if
op
==
"!="
:
else
:
negation
=
""
negation
=
"!"
else
:
negation
=
""
code
.
putln
(
"%s = %s(%s%s(%s, %s));"
%
(
code
.
putln
(
"%s = %s(%s%s(%s, %s));"
%
(
result_code
,
result_code
,
coerce_result
,
coerce_result
,
...
@@ -5684,8 +5681,8 @@ class CoerceToComplexNode(CoercionNode):
...
@@ -5684,8 +5681,8 @@ class CoerceToComplexNode(CoercionNode):
def
calculate_result_code
(
self
):
def
calculate_result_code
(
self
):
if
self
.
arg
.
type
.
is_complex
:
if
self
.
arg
.
type
.
is_complex
:
real_part
=
"__Pyx_
REAL_PART
(%s)"
%
self
.
arg
.
result
()
real_part
=
"__Pyx_
CREAL
(%s)"
%
self
.
arg
.
result
()
imag_part
=
"__Pyx_
IMAG_PART
(%s)"
%
self
.
arg
.
result
()
imag_part
=
"__Pyx_
CIMAG
(%s)"
%
self
.
arg
.
result
()
else
:
else
:
real_part
=
self
.
arg
.
result
()
real_part
=
self
.
arg
.
result
()
imag_part
=
"0"
imag_part
=
"0"
...
...
Cython/Compiler/ModuleNode.py
View file @
dd37f81e
...
@@ -559,12 +559,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -559,12 +559,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
putln
(
"#include <math.h>"
)
code
.
putln
(
"#include <math.h>"
)
code
.
putln
(
"#define %s"
%
Naming
.
api_guard_prefix
+
self
.
api_name
(
env
))
code
.
putln
(
"#define %s"
%
Naming
.
api_guard_prefix
+
self
.
api_name
(
env
))
self
.
generate_includes
(
env
,
cimported_modules
,
code
)
self
.
generate_includes
(
env
,
cimported_modules
,
code
)
if
env
.
directives
[
'c99_complex'
]:
if
env
.
directives
[
'ccomplex'
]:
code
.
putln
(
"#ifndef _Complex_I"
)
code
.
putln
(
""
)
code
.
putln
(
"#include <complex.h>"
)
code
.
putln
(
"#if !defined(CYTHON_CCOMPLEX)"
)
code
.
putln
(
"#define CYTHON_CCOMPLEX 1"
)
code
.
putln
(
"#endif"
)
code
.
putln
(
"#endif"
)
code
.
putln
(
"#define __PYX_USE_C99_COMPLEX defined(_Complex_I)"
)
code
.
putln
(
""
)
code
.
putln
(
''
)
code
.
put
(
Nodes
.
utility_function_predeclarations
)
code
.
put
(
Nodes
.
utility_function_predeclarations
)
code
.
put
(
PyrexTypes
.
type_conversion_predeclarations
)
code
.
put
(
PyrexTypes
.
type_conversion_predeclarations
)
code
.
put
(
Nodes
.
branch_prediction_macros
)
code
.
put
(
Nodes
.
branch_prediction_macros
)
...
...
Cython/Compiler/Nodes.py
View file @
dd37f81e
...
@@ -3134,7 +3134,7 @@ class InPlaceAssignmentNode(AssignmentNode):
...
@@ -3134,7 +3134,7 @@ class InPlaceAssignmentNode(AssignmentNode):
c_op
=
"/"
c_op
=
"/"
elif
c_op
==
"**"
:
elif
c_op
==
"**"
:
error
(
self
.
pos
,
"No C inplace power operator"
)
error
(
self
.
pos
,
"No C inplace power operator"
)
elif
self
.
lhs
.
type
.
is_complex
and
not
code
.
globalstate
.
directives
[
'c99_complex'
]
:
elif
self
.
lhs
.
type
.
is_complex
:
error
(
self
.
pos
,
"Inplace operators not implemented for complex types."
)
error
(
self
.
pos
,
"Inplace operators not implemented for complex types."
)
# have to do assignment directly to avoid side-effects
# have to do assignment directly to avoid side-effects
...
...
Cython/Compiler/Options.py
View file @
dd37f81e
...
@@ -65,7 +65,7 @@ option_defaults = {
...
@@ -65,7 +65,7 @@ option_defaults = {
'cdivision_warnings'
:
False
,
'cdivision_warnings'
:
False
,
'always_allow_keywords'
:
False
,
'always_allow_keywords'
:
False
,
'wraparound'
:
True
,
'wraparound'
:
True
,
'c
99_complex'
:
False
,
# Don't use macro wrappers for complex arith, not sure what to name this...
'c
complex'
:
False
,
# use C99/C++ for complex types and arith
'callspec'
:
""
,
'callspec'
:
""
,
'profile'
:
False
,
'profile'
:
False
,
'infer_types'
:
False
,
'infer_types'
:
False
,
...
...
Cython/Compiler/PyrexTypes.py
View file @
dd37f81e
...
@@ -823,7 +823,7 @@ class CFloatType(CNumericType):
...
@@ -823,7 +823,7 @@ class CFloatType(CNumericType):
class
CComplexType
(
CNumericType
):
class
CComplexType
(
CNumericType
):
is_complex
=
1
is_complex
=
1
to_py_function
=
"__pyx_Py
Object_from_c
omplex"
to_py_function
=
"__pyx_Py
Complex_FromC
omplex"
has_attributes
=
1
has_attributes
=
1
scope
=
None
scope
=
None
...
@@ -859,7 +859,9 @@ class CComplexType(CNumericType):
...
@@ -859,7 +859,9 @@ class CComplexType(CNumericType):
return
self
.
base_declaration_code
(
base
,
entity_code
)
return
self
.
base_declaration_code
(
base
,
entity_code
)
def
sign_and_name
(
self
):
def
sign_and_name
(
self
):
return
Naming
.
type_prefix
+
self
.
real_type
.
specalization_name
()
+
"_complex"
real_type_name
=
self
.
real_type
.
specalization_name
()
real_type_name
=
real_type_name
.
replace
(
'long__double'
,
'long_double'
)
return
Naming
.
type_prefix
+
real_type_name
+
"_complex"
def
assignable_from_resolved_type
(
self
,
src_type
):
def
assignable_from_resolved_type
(
self
,
src_type
):
return
(
src_type
.
is_complex
and
self
.
real_type
.
assignable_from_resolved_type
(
src_type
.
real_type
)
return
(
src_type
.
is_complex
and
self
.
real_type
.
assignable_from_resolved_type
(
src_type
.
real_type
)
...
@@ -877,21 +879,34 @@ class CComplexType(CNumericType):
...
@@ -877,21 +879,34 @@ class CComplexType(CNumericType):
def
create_declaration_utility_code
(
self
,
env
):
def
create_declaration_utility_code
(
self
,
env
):
# This must always be run, because a single CComplexType instance can be shared
# This must always be run, because a single CComplexType instance can be shared
# across multiple compilations (the one created in the module scope)
# across multiple compilations (the one created in the module scope)
env
.
use_utility_code
(
complex_generic_utility_code
)
env
.
use_utility_code
(
complex_header_utility_code
)
env
.
use_utility_code
(
env
.
use_utility_code
(
complex_real_imag_utility_code
)
complex_arithmatic_utility_code
.
specialize
(
self
,
for
utility_code
in
(
complex_type_utility_code
,
math_h_modifier
=
self
.
real_type
.
math_h_modifier
,
complex_from_parts_utility_code
,
real_type
=
self
.
real_type
.
declaration_code
(
''
)))
complex_arithmatic_utility_code
):
env
.
use_utility_code
(
utility_code
.
specialize
(
self
,
real_type
=
self
.
real_type
.
declaration_code
(
''
),
m
=
self
.
real_type
.
math_h_modifier
))
return
True
def
create_to_py_utility_code
(
self
,
env
):
env
.
use_utility_code
(
complex_real_imag_utility_code
)
env
.
use_utility_code
(
complex_to_py_utility_code
)
return
True
return
True
def
create_from_py_utility_code
(
self
,
env
):
def
create_from_py_utility_code
(
self
,
env
):
self
.
real_type
.
create_from_py_utility_code
(
env
)
self
.
real_type
.
create_from_py_utility_code
(
env
)
env
.
use_utility_code
(
complex_conversion_utility_code
.
specialize
(
self
,
for
utility_code
in
(
complex_from_parts_utility_code
,
math_h_modifier
=
self
.
real_type
.
math_h_modifier
,
complex_from_py_utility_code
):
real_type
=
self
.
real_type
.
declaration_code
(
''
),
env
.
use_utility_code
(
type_convert
=
self
.
real_type
.
from_py_function
))
utility_code
.
specialize
(
self
.
from_py_function
=
"__pyx_PyObject_As_"
+
self
.
specalization_name
()
self
,
real_type
=
self
.
real_type
.
declaration_code
(
''
),
m
=
self
.
real_type
.
math_h_modifier
))
self
.
from_py_function
=
"__Pyx_PyComplex_As_"
+
self
.
specalization_name
()
return
True
return
True
def
lookup_op
(
self
,
nargs
,
op
):
def
lookup_op
(
self
,
nargs
,
op
):
...
@@ -901,7 +916,8 @@ class CComplexType(CNumericType):
...
@@ -901,7 +916,8 @@ class CComplexType(CNumericType):
pass
pass
try
:
try
:
op_name
=
complex_ops
[
nargs
,
op
]
op_name
=
complex_ops
[
nargs
,
op
]
self
.
binops
[
nargs
,
op
]
=
func_name
=
"%s_%s"
%
(
self
.
specalization_name
(),
op_name
)
modifier
=
self
.
real_type
.
math_h_modifier
self
.
binops
[
nargs
,
op
]
=
func_name
=
"__Pyx_c_%s%s"
%
(
op_name
,
modifier
)
return
func_name
return
func_name
except
KeyError
:
except
KeyError
:
return
None
return
None
...
@@ -915,114 +931,210 @@ class CComplexType(CNumericType):
...
@@ -915,114 +931,210 @@ class CComplexType(CNumericType):
complex_ops
=
{
complex_ops
=
{
(
1
,
'-'
):
'neg'
,
(
1
,
'-'
):
'neg'
,
(
1
,
'zero'
):
'is_zero'
,
(
1
,
'zero'
):
'is_zero'
,
(
2
,
'+'
):
'
add
'
,
(
2
,
'+'
):
'
sum
'
,
(
2
,
'-'
)
:
'sub
'
,
(
2
,
'-'
)
:
'diff
'
,
(
2
,
'*'
):
'
mul
'
,
(
2
,
'*'
):
'
prod
'
,
(
2
,
'/'
):
'
div
'
,
(
2
,
'/'
):
'
quot
'
,
(
2
,
'=='
):
'eq'
,
(
2
,
'=='
):
'eq'
,
}
}
complex_generic_utility_code
=
UtilityCode
(
complex_header_utility_code
=
UtilityCode
(
proto_block
=
'utility_code_proto_before_types'
,
proto
=
"""
proto
=
"""
#if __PYX_USE_C99_COMPLEX
#if !defined(CYTHON_CCOMPLEX)
#define __Pyx_REAL_PART(z) __real__(z)
#if defined(__cplusplus)
#define __Pyx_IMAG_PART(z) __imag__(z)
#define CYTHON_CCOMPLEX 1
#else
#elif defined(_Complex_I)
#define __Pyx_REAL_PART(z) ((z).real)
#define CYTHON_CCOMPLEX 1
#define __Pyx_IMAG_PART(z) ((z).imag)
#else
#define CYTHON_CCOMPLEX 0
#endif
#endif
#endif
#define __pyx_PyObject_from_complex(z) PyComplex_FromDoubles((double)__Pyx_REAL_PART(z), (double)__Pyx_IMAG_PART(z))
#if CYTHON_CCOMPLEX
#ifdef __cplusplus
#include <complex>
#else
#include <complex.h>
#endif
#endif
"""
)
"""
)
complex_
conversion
_utility_code
=
UtilityCode
(
complex_
real_imag
_utility_code
=
UtilityCode
(
proto
=
"""
proto
=
"""
static %(type)s __pyx_PyObject_As_%(type_name)s(PyObject* o); /* proto */
#if CYTHON_CCOMPLEX
"""
,
#ifdef __cplusplus
impl
=
"""
#define __Pyx_CREAL(z) ((z).real())
static %(type)s __pyx_PyObject_As_%(type_name)s(PyObject* o) {
#define __Pyx_CIMAG(z) ((z).imag())
if (PyComplex_CheckExact(o)) {
#else
return %(type_name)s_from_parts(
#define __Pyx_CREAL(z) (__real__(z))
(%(real_type)s)((PyComplexObject *)o)->cval.real,
#define __Pyx_CIMAG(z) (__imag__(z))
(%(real_type)s)((PyComplexObject *)o)->cval.imag);
#endif
}
#else
else {
#define __Pyx_CREAL(z) ((z).real)
Py_complex cval = PyComplex_AsCComplex(o);
#define __Pyx_CIMAG(z) ((z).imag)
return %(type_name)s_from_parts((%(real_type)s)cval.real, (%(real_type)s)cval.imag);
#endif
}
}
"""
)
"""
)
complex_arithmatic_utility_code
=
UtilityCode
(
complex_type_utility_code
=
UtilityCode
(
proto_block
=
'utility_code_proto_before_types'
,
proto
=
"""
proto
=
"""
#if __PYX_USE_C99_COMPLEX
#if CYTHON_CCOMPLEX
#ifdef __cplusplus
typedef ::std::complex< %(real_type)s > %(type_name)s;
#else
typedef %(real_type)s _Complex %(type_name)s;
typedef %(real_type)s _Complex %(type_name)s;
#endif
#else
typedef struct { %(real_type)s real, imag; } %(type_name)s;
#endif
"""
)
complex_from_parts_utility_code
=
UtilityCode
(
proto_block
=
'utility_code_proto_before_types'
,
proto
=
"""
#if CYTHON_CCOMPLEX
#ifdef __cplusplus
static INLINE %(type)s %(type_name)s_from_parts(%(real_type)s, %(real_type)s);
#else
static INLINE %(type)s %(type_name)s_from_parts(%(real_type)s, %(real_type)s);
#endif
#else
static INLINE %(type)s %(type_name)s_from_parts(%(real_type)s, %(real_type)s);
#endif
"""
,
impl
=
"""
#if CYTHON_CCOMPLEX
#ifdef __cplusplus
static INLINE %(type)s %(type_name)s_from_parts(%(real_type)s x, %(real_type)s y) {
return ::std::complex< %(real_type)s >(x, y);
}
#else
static INLINE %(type)s %(type_name)s_from_parts(%(real_type)s x, %(real_type)s y) {
static INLINE %(type)s %(type_name)s_from_parts(%(real_type)s x, %(real_type)s y) {
return x + y*(%(type)s)_Complex_I;
return x + y*(%(type)s)_Complex_I;
}
}
#endif
#define %(type_name)s_is_zero(a) ((a) == 0)
#define %(type_name)s_eq(a, b) ((a) == (b))
#define %(type_name)s_add(a, b) ((a)+(b))
#define %(type_name)s_sub(a, b) ((a)-(b))
#define %(type_name)s_mul(a, b) ((a)*(b))
#define %(type_name)s_div(a, b) ((a)/(b))
#define %(type_name)s_neg(a) (-(a))
#else
#else
typedef struct { %(real_type)s real, imag; } %(type_name)s;
static INLINE %(type)s %(type_name)s_from_parts(%(real_type)s x, %(real_type)s y) {
static INLINE %(type)s %(type_name)s_from_parts(%(real_type)s x, %(real_type)s y) {
%(type)s c; c.real = x; c.imag = y; return c;
%(type)s z;
}
z.real = x;
z.imag = y;
static INLINE int %(type_name)s_is_zero(%(type)s a) {
return z;
return (a.real == 0) & (a.imag == 0);
}
}
#endif
"""
)
static INLINE int %(type_name)s_eq(%(type)s a, %(type)s b) {
complex_to_py_utility_code
=
UtilityCode
(
return (a.real == b.real) & (a.imag == b.imag);
proto
=
"""
}
#define __pyx_PyComplex_FromComplex(z)
\
\
PyComplex_FromDoubles((double)__Pyx_CREAL(z),
\
\
(double)__Pyx_CIMAG(z))
"""
)
complex_from_py_utility_code
=
UtilityCode
(
proto
=
"""
static %(type)s __Pyx_PyComplex_As_%(type_name)s(PyObject*);
"""
,
impl
=
"""
static %(type)s __Pyx_PyComplex_As_%(type_name)s(PyObject* o) {
Py_complex cval;
if (PyComplex_CheckExact(o))
cval = ((PyComplexObject *)o)->cval;
else
cval = PyComplex_AsCComplex(o);
return %(type_name)s_from_parts(
(%(real_type)s)cval.real,
(%(real_type)s)cval.imag);
}
"""
)
static INLINE %(type)s %(type_name)s_add(%(type)s a, %(type)s b) {
complex_arithmatic_utility_code
=
UtilityCode
(
proto
=
"""
#if CYTHON_CCOMPLEX
#define __Pyx_c_eq%(m)s(a, b) ((a)==(b))
#define __Pyx_c_sum%(m)s(a, b) ((a)+(b))
#define __Pyx_c_diff%(m)s(a, b) ((a)-(b))
#define __Pyx_c_prod%(m)s(a, b) ((a)*(b))
#define __Pyx_c_quot%(m)s(a, b) ((a)/(b))
#define __Pyx_c_neg%(m)s(a) (-(a))
#ifdef __cplusplus
#define __Pyx_c_is_zero%(m)s(z) ((z)==0.0)
#define __Pyx_c_conj%(m)s(z) (::std::conj(z))
/*#define __Pyx_c_abs%(m)s(z) (::std::abs(z))*/
#else
#define __Pyx_c_is_zero%(m)s(z) ((z)==0)
#define __Pyx_c_conj%(m)s(z) (conj%(m)s(z))
/*#define __Pyx_c_abs%(m)s(z) (cabs%(m)s(z))*/
#endif
#else
static INLINE int __Pyx_c_eq%(m)s(%(type)s, %(type)s);
static INLINE %(type)s __Pyx_c_sum%(m)s(%(type)s, %(type)s);
static INLINE %(type)s __Pyx_c_diff%(m)s(%(type)s, %(type)s);
static INLINE %(type)s __Pyx_c_prod%(m)s(%(type)s, %(type)s);
static INLINE %(type)s __Pyx_c_quot%(m)s(%(type)s, %(type)s);
static INLINE %(type)s __Pyx_c_neg%(m)s(%(type)s);
static INLINE int __Pyx_c_is_zero%(m)s(%(type)s);
static INLINE %(type)s __Pyx_c_conj%(m)s(%(type)s);
/*static INLINE %(real_type)s __Pyx_c_abs%(m)s(%(type)s);*/
#endif
"""
,
impl
=
"""
#if CYTHON_CCOMPLEX
#else
static INLINE int __Pyx_c_eq%(m)s(%(type)s a, %(type)s b) {
return (a.real == b.real) && (a.imag == b.imag);
}
static INLINE %(type)s __Pyx_c_sum%(m)s(%(type)s a, %(type)s b) {
%(type)s z;
%(type)s 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 INLINE %(type)s __Pyx_c_diff%(m)s(%(type)s a, %(type)s b) {
static INLINE %(type)s %(type_name)s_sub(%(type)s a, %(type)s b) {
%(type)s z;
%(type)s 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 INLINE %(type)s __Pyx_c_prod%(m)s(%(type)s a, %(type)s b) {
static INLINE %(type)s %(type_name)s_mul(%(type)s a, %(type)s b) {
%(type)s z;
%(type)s 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;
return z;
return z;
}
}
static INLINE %(type)s __Pyx_c_quot%(m)s(%(type)s a, %(type)s b) {
static INLINE %(type)s %(type_name)s_div(%(type)s a, %(type)s b) {
%(type)s z;
%(type)s z;
%(real_type)s denom = b.real
*b.real + b.imag*
b.imag;
%(real_type)s denom = b.real
* b.real + b.imag *
b.imag;
z.real = (a.real * b.real + a.imag * b.imag) / denom;
z.real = (a.real * b.real + a.imag * b.imag) / denom;
z.imag = (a.imag * b.real - a.real * b.imag) / denom;
z.imag = (a.imag * b.real - a.real * b.imag) / denom;
return z;
return z;
}
}
static INLINE %(type)s __Pyx_c_neg%(m)s(%(type)s a) {
static INLINE %(type)s %(type_name)s_neg(%(type)s a) {
%(type)s z;
%(type)s z;
z.real = -a.real;
z.real = -a.real;
z.imag = -a.imag;
z.imag = -a.imag;
return z;
return z;
}
}
static INLINE int __Pyx_c_is_zero%(m)s(%(type)s a) {
return (a.real == 0) && (a.imag == 0);
}
static INLINE %(type)s __Pyx_c_conj%(m)s(%(type)s a) {
%(type)s z;
z.real = a.real;
z.imag = -a.imag;
return z;
}
/*
static INLINE %(real_type)s __Pyx_c_abs%(m)s(%(type)s z) {
#if HAVE_HYPOT
return hypot%(m)s(z.real, z.imag);
#else
return sqrt%(m)s(z.real*z.real + z.imag*z.imag);
#endif
}
*/
#endif
#endif
"""
,
proto_block
=
'complex_numbers_utility_code'
)
"""
)
class
CArrayType
(
CType
):
class
CArrayType
(
CType
):
...
...
Cython/Compiler/Symtab.py
View file @
dd37f81e
...
@@ -1157,7 +1157,7 @@ class StructOrUnionScope(Scope):
...
@@ -1157,7 +1157,7 @@ class StructOrUnionScope(Scope):
def declare_cfunction(self, name, type, pos,
def declare_cfunction(self, name, type, pos,
cname = None, visibility = '
private
', defining = 0,
cname = None, visibility = '
private
', defining = 0,
api = 0, in_pxd = 0, modifiers = ()):
api = 0, in_pxd = 0, modifiers = ()):
self.declare_var(name, type, pos, cname, visibility)
return
self.declare_var(name, type, pos, cname, visibility)
class ClassScope(Scope):
class ClassScope(Scope):
# Abstract base class for namespace of
# Abstract base class for namespace of
...
...
tests/run/complex_numbers_T305.pyx
View file @
dd37f81e
__doc__
=
u"""
__doc__
=
u"""
>>> test_object_conversion(2)
>>> test_object_conversion(2)
((2+0j), (2+0j))
((2+0j), (2+0j)
, (2+0j)
)
>>> test_object_conversion(2j - 0.5)
>>> test_object_conversion(2j - 0.5)
((-0.5+2j), (-0.5+2j))
((-0.5+2j), (-0.5+2j)
, (-0.5+2j)
)
>>> test_arithmetic(2j, 4j)
>>> test_arithmetic(2j, 4j)
(-2j, 6j, -2j, (-8+0j), (0.5+0j))
(
2j,
-2j, 6j, -2j, (-8+0j), (0.5+0j))
>>> test_arithmetic(6+12j, 3j)
>>> test_arithmetic(6+12j, 3j)
((-6-12j), (6+15j), (6+9j), (-36+18j), (4-2j))
((
6+12j), (
-6-12j), (6+15j), (6+9j), (-36+18j), (4-2j))
>>> test_arithmetic(5-10j, 3+4j)
>>> test_arithmetic(5-10j, 3+4j)
((-5+10j), (8-6j), (2-14j), (55-10j), (-1-2j))
((
5-10j), (
-5+10j), (8-6j), (2-14j), (55-10j), (-1-2j))
>>> test_div_by_zero(4j)
## XXX this is not working
-0.25j
## >>> test_div_by_zero(4j)
>>> test_div_by_zero(0)
## -0.25j
Traceback (most recent call last):
## >>> test_div_by_zero(0)
...
## Traceback (most recent call last):
ZeroDivisionError: float division
## ...
## ZeroDivisionError: float division
>>> test_coercion(1, 1.5, 2.5, 4+1j, 10j)
>>> test_coercion(1, 1.5, 2.5, 4+1j, 10j)
(1+0j)
(1+0j)
...
@@ -56,6 +57,10 @@ __doc__ = u"""
...
@@ -56,6 +57,10 @@ __doc__ = u"""
(1+2j)
(1+2j)
>>> test_real_imag_assignment(1.5, -3.5)
>>> test_real_imag_assignment(1.5, -3.5)
(1.5-3.5j)
(1.5-3.5j)
## XXX not implemented yet!
## >>> test_conjugate(1+2j)
## (1-2j)
"""
"""
#cdef extern from "complex.h":
#cdef extern from "complex.h":
...
@@ -65,15 +70,17 @@ cimport cython
...
@@ -65,15 +70,17 @@ cimport cython
def
test_object_conversion
(
o
):
def
test_object_conversion
(
o
):
cdef
float
complex
a
=
o
cdef
float
complex
a
=
o
cdef
double
complex
z
=
o
cdef
double
complex
b
=
o
return
(
a
,
z
)
cdef
long
double
complex
c
=
o
return
(
a
,
b
,
c
)
def
test_arithmetic
(
double
complex
z
,
double
complex
w
):
def
test_arithmetic
(
double
complex
z
,
double
complex
w
):
return
-
z
,
z
+
w
,
z
-
w
,
z
*
w
,
z
/
w
return
+
z
,
-
z
,
z
+
w
,
z
-
w
,
z
*
w
,
z
/
w
@
cython
.
cdivision
(
False
)
## XXX this is not working
def
test_div_by_zero
(
double
complex
z
):
## @cython.cdivision(False)
return
1
/
z
## def test_div_by_zero(double complex z):
## return 1/z
def
test_coercion
(
int
a
,
float
b
,
double
c
,
float
complex
d
,
double
complex
e
):
def
test_coercion
(
int
a
,
float
b
,
double
c
,
float
complex
d
,
double
complex
e
):
cdef
double
complex
z
cdef
double
complex
z
...
@@ -102,3 +109,6 @@ def test_real_imag_assignment(object a, double b):
...
@@ -102,3 +109,6 @@ def test_real_imag_assignment(object a, double b):
z
.
imag
=
b
z
.
imag
=
b
return
z
return
z
## XXX not implemented yet!
## def test_conjugate(float complex z):
## return z.conjugate()
tests/run/complex_numbers_c89_T398.h
0 → 100644
View file @
dd37f81e
#define CYTHON_CCOMPLEX 0
tests/run/complex_numbers_c89_T398.pyx
0 → 100644
View file @
dd37f81e
cdef
extern
from
"complex_numbers_c89_T398.h"
:
pass
include
"complex_numbers_T305.pyx"
tests/run/complex_numbers_c99_T398.h
0 → 100644
View file @
dd37f81e
#if !defined(__cplusplus)
#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) \
|| defined(__GNUC__) \
|| defined(__INTEL_COMPILER) \
|| defined(__IBMC__) \
#include <complex.h>
#if !defined(_Complex_I)
#error The "complex.h" header does not define the '_Complex_I' macro.
#error Please report this to Cython developers <cython-dev@codespeak.net>
#endif
#endif
#endif
tests/run/complex_numbers_c99_T398.pyx
0 → 100644
View file @
dd37f81e
cdef
extern
from
"complex_numbers_c99_T398.h"
:
pass
include
"complex_numbers_T305.pyx"
tests/run/complex_numbers_cxx_T398.h
0 → 100644
View file @
dd37f81e
#if defined(__cplusplus)
#define CYTHON_CCOMPLEX 1
#else
#define CYTHON_CCOMPLEX 0
#endif
tests/run/complex_numbers_cxx_T398.pyx
0 → 100644
View file @
dd37f81e
cdef
extern
from
"complex_numbers_cxx_T398.h"
:
pass
include
"complex_numbers_T305.pyx"
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment