4
from __future__ import print_function
9
def pow_double_double(double a, double b, delta):
11
>>> pow_double_double(2, 2, 1e-15)
12
soft double complex float
13
>>> pow_double_double(4, 0.5, 1e-15)
14
soft double complex float
15
>>> pow_double_double(-4, 0.5, 1e-15)
16
soft double complex complex
19
# print out the Cython type, and the coerced type
20
print(cython.typeof(c), type(c).__name__)
21
object_c = (<object>a)**(<object>b)
22
assert abs((c/object_c) - 1) < delta
25
def pow_double_double_cpow(double a, double b, delta=None):
27
>>> pow_double_double_cpow(2, 2, 1e-15)
29
>>> pow_double_double_cpow(4, 0.5, 1e-15)
31
>>> x = pow_double_double_cpow(-4, 0.5)
37
# print out the Cython type, and the coerced type
38
print(cython.typeof(c), type(c).__name__)
40
object_c = (<object>a)**(<object>b)
41
assert abs((c/object_c) - 1) < delta
45
cdef cfunc_taking_double(double x):
48
def pow_double_double_coerced_directly(double a, double b):
50
>>> pow_double_double_coerced_directly(2, 2)
52
>>> x = pow_double_double_coerced_directly(-2, 0.5)
56
# Because we're assigning directly to a double assume 'cpow'
59
return cfunc_taking_double(a**b) + c
61
def pow_double_int(double a, int b):
63
# a few variations of 'double**int'. In all cases
64
# Cython should realise that the result can't be complex
65
# and avoid going through the soft complex type
66
>>> pow_double_int(5, 2)
78
print(cython.typeof(c1))
79
print(cython.typeof(c2))
80
print(cython.typeof(c3))
81
print(cython.typeof(c4))
82
print(cython.typeof(c5))
84
def soft_complex_coerced_to_double(double a, double b):
86
>>> soft_complex_coerced_to_double(2, 2)
88
>>> soft_complex_coerced_to_double(-2, 0.25)
89
Traceback (most recent call last):
91
TypeError: Cannot convert 'complex' with non-zero imaginary component to 'double' (this most likely comes from the '**' operator; use 'cython.cpow(True)' to return 'nan' instead of a complex number).
94
assert cython.typeof(c) == "soft double complex"
95
cdef double d = c # will raise if complex
98
def soft_complex_coerced_to_complex(double a, double b):
100
>>> soft_complex_coerced_to_complex(2, 2)
102
>>> x = soft_complex_coerced_to_complex(-1, 0.5)
103
>>> abs(x.real) < 1e-15
105
>>> abs(x.imag - 1) < 1e-15
108
# This is always fine, but just check it works
110
assert cython.typeof(c) == "soft double complex"
111
cdef double complex d = c
114
def soft_complex_type_inference_1(double a, double b, pick):
116
>>> soft_complex_type_inference_1(2, 1, False)
117
soft double complex 2.0
118
>>> soft_complex_type_inference_1(2, 3, True)
119
soft double complex 4.0
121
# double and soft complex should infer to soft-complex
126
print(cython.typeof(c), c)
128
def soft_complex_type_inference_2(double a, double b, expected):
130
>>> soft_complex_type_inference_2(2, 1, 1.0)
132
>>> soft_complex_type_inference_2(2, 3, 7.0)
135
# double and soft complex should infer to soft-complex
138
print(cython.typeof(c))
139
delta = abs(c/expected - 1)
140
assert delta < 1e-15, delta
142
def pow_int_int(int a, int b):
144
>>> pow_int_int(2, 2)
146
>>> pow_int_int(2, -2)
150
print(cython.typeof(c), c)
153
def pow_int_int_cpow(int a, int b):
155
>>> pow_int_int_cpow(2, 2)
157
>>> pow_int_int_cpow(2, -2)
161
print(cython.typeof(c), c)
163
cdef cfunc_taking_int(int x):
166
def pow_int_int_coerced_directly(int a, int b):
168
Generates two warnings about using cpow.
169
The actual behaviour isn't too easy to distinguish
170
without inspecting the c code though.
171
>>> pow_int_int_coerced_directly(2, 2)
175
return cfunc_taking_int(a**b) + c
177
def pow_int_int_non_negative(int a, unsigned int b):
179
A couple of combinations of non-negative values for the
180
exponent, which lets us fall back to int as a return type
181
>>> pow_int_int_non_negative(5, 3)
187
print(cython.typeof(c1))
188
print(cython.typeof(c2))
193
def pythagoras_with_typedef(double a, double b):
194
# see https://github.com/cython/cython/issues/5203
196
>>> rc = pythagoras_with_typedef(2.0, 2.0)
197
>>> pyresult = 1.0 / (2 * 2.0 ** 2) ** 0.5
198
>>> pyresult - 0.001 < rc < pyresult + 0.001 or (rc, pyresult)
201
cdef f64 result = a * a + b * b
202
result = 1.0 / result ** 0.5
207
def power_coercion_in_nogil_1(double a, double b):
209
>>> power_coercion_in_nogil_1(2., 2.)
211
>>> power_coercion_in_nogil_1(-1., 0.5)
212
Traceback (most recent call last):
214
TypeError: Cannot convert 'complex' with non-zero imaginary component to 'double' (this most likely comes from the '**' operator; use 'cython.cpow(True)' to return 'nan' instead of a complex number).
222
cdef double nogil_fun(double x) nogil:
225
def power_coercion_in_nogil_2(double a, double b):
227
>>> power_coercion_in_nogil_2(2., 2.)
229
>>> power_coercion_in_nogil_2(-1., 0.5)
230
Traceback (most recent call last):
232
TypeError: Cannot convert 'complex' with non-zero imaginary component to 'double' (this most likely comes from the '**' operator; use 'cython.cpow(True)' to return 'nan' instead of a complex number).
240
def power_coercion_in_nogil_3(double a, double b, double c):
242
>>> power_coercion_in_nogil_3(2., 2., 1.0)
244
>>> power_coercion_in_nogil_3(-1., 0.5, 1.0)
245
Traceback (most recent call last):
247
TypeError: Cannot convert 'complex' with non-zero imaginary component to 'double' (this most likely comes from the '**' operator; use 'cython.cpow(True)' to return 'nan' instead of a complex number).
255
58:21: Treating '**' as if 'cython.cpow(True)' since it is directly assigned to a a non-complex C numeric type. This is likely to be fragile and we recommend setting 'cython.cpow' explicitly.
256
59:32: Treating '**' as if 'cython.cpow(True)' since it is directly assigned to a a non-complex C numeric type. This is likely to be fragile and we recommend setting 'cython.cpow' explicitly.
257
174:18: Treating '**' as if 'cython.cpow(True)' since it is directly assigned to a an integer C numeric type. This is likely to be fragile and we recommend setting 'cython.cpow' explicitly.
258
175:29: Treating '**' as if 'cython.cpow(True)' since it is directly assigned to a an integer C numeric type. This is likely to be fragile and we recommend setting 'cython.cpow' explicitly.