importnumpyasnpimportnumbaasnbfromnumpy.randomimportPCG64fromtimeitimporttimeitbit_gen=PCG64()next_d=bit_gen.cffi.next_doublestate_addr=bit_gen.cffi.state_addressdefnormals(n,state):out=np.empty(n)foriinrange((n+1)//2):x1=2.0*next_d(state)-1.0x2=2.0*next_d(state)-1.0r2=x1*x1+x2*x2whiler2>=1.0orr2==0.0:x1=2.0*next_d(state)-1.0x2=2.0*next_d(state)-1.0r2=x1*x1+x2*x2f=np.sqrt(-2.0*np.log(r2)/r2)out[2*i]=f*x1if2*i+1<n:out[2*i+1]=f*x2returnout# Compile using Numbanormalsj=nb.jit(normals,nopython=True)# Must use state address not state with numban=10000defnumbacall():returnnormalsj(n,state_addr)rg=np.random.Generator(PCG64())defnumpycall():returnrg.normal(size=n)# Check that the functions workr1=numbacall()r2=numpycall()assertr1.shape==(n,)assertr1.shape==r2.shapet1=timeit(numbacall,number=1000)print(f'{t1:.2f} secs for {n} PCG64 (Numba/PCG64) gaussian randoms')t2=timeit(numpycall,number=1000)print(f'{t2:.2f} secs for {n} PCG64 (NumPy/PCG64) gaussian randoms')# example 2next_u32=bit_gen.ctypes.next_uint32ctypes_state=bit_gen.ctypes.state@nb.jit(nopython=True)defbounded_uint(lb,ub,state):mask=delta=ub-lbmask|=mask>>1mask|=mask>>2mask|=mask>>4mask|=mask>>8mask|=mask>>16val=next_u32(state)&maskwhileval>delta:val=next_u32(state)&maskreturnlb+valprint(bounded_uint(323,2394691,ctypes_state.value))@nb.jit(nopython=True)defbounded_uints(lb,ub,n,state):out=np.empty(n,dtype=np.uint32)foriinrange(n):out[i]=bounded_uint(lb,ub,state)bounded_uints(323,2394691,10000000,ctypes_state.value)