#!/usr/bin/env python #cython: language_level=3 """ This file shows how the distributions that are accessed through distributions.pxd can be used Cython code. """ import numpy as np cimport numpy as np cimport cython from cpython.pycapsule cimport PyCapsule_IsValid, PyCapsule_GetPointer from numpy.random.common cimport * from numpy.random.distributions cimport random_gauss_zig from numpy.random import Xoshiro256 @cython.boundscheck(False) @cython.wraparound(False) def normals_zig(Py_ssize_t n): cdef Py_ssize_t i cdef bitgen_t *rng cdef const char *capsule_name = "BitGenerator" cdef double[::1] random_values x = Xoshiro256() capsule = x.capsule if not PyCapsule_IsValid(capsule, capsule_name): raise ValueError("Invalid pointer to anon_func_state") rng = PyCapsule_GetPointer(capsule, capsule_name) random_values = np.empty(n) # Best practice is to release GIL and acquire the lock with x.lock, nogil: for i in range(n): random_values[i] = random_gauss_zig(rng) randoms = np.asarray(random_values) return randoms @cython.boundscheck(False) @cython.wraparound(False) def uniforms(Py_ssize_t n): cdef Py_ssize_t i cdef bitgen_t *rng cdef const char *capsule_name = "BitGenerator" cdef double[::1] random_values x = Xoshiro256() capsule = x.capsule # Optional check that the capsule if from a BitGenerator if not PyCapsule_IsValid(capsule, capsule_name): raise ValueError("Invalid pointer to anon_func_state") # Cast the pointer rng = PyCapsule_GetPointer(capsule, capsule_name) random_values = np.empty(n) with x.lock, nogil: for i in range(n): # Call the function random_values[i] = rng.next_double(rng.state) randoms = np.asarray(random_values) return randoms