-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjulia_core.pyx
104 lines (95 loc) · 3.02 KB
/
julia_core.pyx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
from cython.parallel import prange
import cython
import numpy as np
cimport numpy as np
def calculate_z(zs, c, maxiter):
"""
This is identical to the first example in julia.py. It is here to
demonstrate that it is possible to compile ordinary Python code.
"""
zdim = zs.shape[0]
mask = np.empty(zs.shape, dtype=np.int32)
for i in xrange(zs.size):
n = 0
z = zs[i]
while abs(z)<2 and n<maxiter:
z = z * z + c
n = n + 1
mask[i] = n
return mask
# def calculate_z(double complex [:] zs, double complex c, int maxiter):
# """
# This is fairly typical Cythonised version of the basic Python
# implementation. The major difference is the inclusion of types.
# """
#
# cdef int n, j
# cdef int zdim = zs.size
# cdef int [:] mask = np.empty(zdim, dtype=np.int32)
#
# for j in xrange(zdim):
# n = 0
# while abs(zs[j]) < 2 and n < maxiter:
# zs[j] = zs[j] * zs[j] + c
# n = n + 1
# mask[j] = n
#
# return mask
# def calculate_z(double complex [:] zs, double complex c, int maxiter):
# """
# The following is an improved version of the above code. By replacing the
# absolute value with some more explicit code which avoids taking the square
# root, we gain a substantial speed-up.
# """
#
# cdef int n, j
# cdef int zdim = zs.size
# cdef int [:] mask = np.empty(zdim, dtype=np.int32)
#
# for j in xrange(zdim):
# n = 0
# while (zs[j].real * zs[j].real + zs[j].imag * zs[j].imag) < 4 and n < maxiter:
# zs[j] = zs[j] * zs[j] + c
# n = n + 1
# mask[j] = n
#
# return mask
# def calculate_z(double complex [:] zs, double complex c, int maxiter):
# """
# This adds some multithreading. Note how simple it is to replace the
# xrange with prange and surrender the GIL. This makes parallelism quite
# easy.
# """
# cdef int n, j
# cdef int zdim = zs.size
# cdef int [:] mask = np.empty(zdim, dtype=np.int32)
#
# for j in prange(zdim, nogil=True, schedule="guided"):
# n = 0
# while (zs[j].real * zs[j].real + zs[j].imag * zs[j].imag) < 4 and n < maxiter:
# zs[j] = zs[j] * zs[j] + c
# n = n + 1
# mask[j] = n
#
# return mask
# @cython.wraparound(False)
# @cython.boundscheck(False)
# @cython.nonecheck(False)
# def calculate_z(double complex [:] zs, double complex c, int maxiter):
# """
# This final version includes some decorators which tell the compiler to
# ignore some standard checks. This can be dangerous, but well written code
# will often not require these checks and removing them does increase speed.
# """
# cdef int n, j
# cdef int zdim = zs.size
# cdef int [:] mask = np.empty(zdim, dtype=np.int32)
#
# for j in prange(zdim, nogil=True, schedule="guided"):
# n = 0
# while (zs[j].real * zs[j].real + zs[j].imag * zs[j].imag) < 4 and n < maxiter:
# zs[j] = zs[j] * zs[j] + c
# n = n + 1
# mask[j] = n
#
# return mask