Skip to content

Commit ebb47ad

Browse files
committed
ENH: Use low level access in complex normal
Switch to low level interface to improve performance of generated complex normal
1 parent 63ae94e commit ebb47ad

File tree

2 files changed

+23
-18
lines changed

2 files changed

+23
-18
lines changed

randomstate/randomstate.pyx

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1782,9 +1782,12 @@ cdef class RandomState:
17821782
17831783
>>> s = np.random.complex_normal(size=1000)
17841784
"""
1785-
cdef np.ndarray ogamma, orelation, oloc
1785+
# TODO: What about loc??
1786+
cdef np.ndarray ogamma, orelation, oloc, randoms
1787+
cdef double *randoms_data
17861788
cdef double fgamma_r, fgamma_i, frelation_r, frelation_i, frho, f_v_real , f_v_imag, \
1787-
floc_r, floc_i, f_real, f_imag
1789+
floc_r, floc_i, f_real, f_imag, i_r_scale, r_scale, i_scale
1790+
cdef np.npy_intp i, j, n,
17881791

17891792
oloc = <np.ndarray>np.PyArray_FROM_OTF(loc, np.NPY_COMPLEX128, np.NPY_ALIGNED)
17901793
ogamma = <np.ndarray>np.PyArray_FROM_OTF(gamma, np.NPY_COMPLEX128, np.NPY_ALIGNED)
@@ -1813,30 +1816,32 @@ cdef class RandomState:
18131816
raise ValueError('Im(relation) ** 2 > Re(gamma ** 2 - relation** 2)')
18141817

18151818
if size is None:
1816-
f_real, f_imag = self.standard_normal(size=2, method=method)
1817-
1819+
random_gauss_zig_double_fill(&self.rng_state, 1, &f_real)
1820+
random_gauss_zig_double_fill(&self.rng_state, 1, &f_imag)
18181821
f_imag *= sqrt(1 - f_rho * f_rho)
18191822
f_imag += f_rho * f_real
18201823
f_real *= sqrt(0.5 * f_v_real)
18211824
f_imag *= sqrt(0.5 * f_v_imag)
18221825

18231826
return PyComplex_FromDoubles(f_real, f_imag)
18241827

1825-
if np.PyArray_IsAnyScalar(size):
1826-
size = (size,)
1827-
else:
1828-
size = tuple(size)
1829-
1830-
norms = self.standard_normal(size=size + (2,), method=method)
1831-
real = norms[...,0]
1832-
imag = norms[...,1]
1828+
randoms = <np.ndarray>np.empty(size, np.complex128)
1829+
randoms_data = <double *>np.PyArray_DATA(randoms)
1830+
n = np.PyArray_SIZE(randoms)
18331831

1834-
imag *= sqrt(1 - f_rho * f_rho)
1835-
imag += f_rho * real
1836-
real *= sqrt(0.5 * f_v_real)
1837-
imag *= sqrt(0.5 * f_v_imag)
1832+
i_r_scale = sqrt(1 - f_rho * f_rho)
1833+
r_scale = sqrt(0.5 * f_v_real)
1834+
i_scale = sqrt(0.5 * f_v_imag)
1835+
j = 0
1836+
with self.lock, nogil:
1837+
for i in range(n):
1838+
random_gauss_zig_double_fill(&self.rng_state, 1, &f_real)
1839+
random_gauss_zig_double_fill(&self.rng_state, 1, &f_imag)
1840+
randoms_data[j+1] = i_scale * (f_rho * f_real + i_r_scale * f_imag)
1841+
randoms_data[j] = r_scale * f_real
1842+
j += 2
18381843

1839-
return floc_r + real + (floc_i + imag) * (0+1.0j)
1844+
return randoms
18401845

18411846
gpc = ogamma + orelation
18421847
gmc = ogamma - orelation

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ def cythonize(e, *args, **kwargs):
240240
with open(output_file_name, 'w') as output_file:
241241
output_file.write(template.substitute())
242242

243-
ext_modules = cythonize(extensions, force=not DEVELOP)
243+
ext_modules = cythonize(extensions, force=not DEVELOP, annotate=True)
244244

245245
classifiers = ['Development Status :: 5 - Production/Stable',
246246
'Environment :: Console',

0 commit comments

Comments
 (0)