<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Plain Python
Step1:  Still Python, but inside a Cython cell
There are still no types declared, but you get a surprising speedup.
Step2:  Cython
Step3:  Example of a while loop
Step6:  Application
Step7:  Quick demo
Step8:  Speed test - compare Cython and Numpy
Note
<ASSISTANT_TASK:>
Python Code:
def p(n, m):
    output = 0
    for i in range(n):
        output += i % m
    return output
%timeit p(1000000, 42)
Explanation: Plain Python: modulo (%) in a loop
End of explanation
%%cython
def f(n, m):
    output = 0
    for i in range(n):
        output += i % m
    return output
%timeit f(1000000, 42)
Explanation: Still Python, but inside a Cython cell
There are still no types declared, but you get a surprising speedup.
End of explanation
%%cython
def c(int n):
    cdef int i, output
    for i in range(n):
        output += i % 42
    return output
%timeit c(1000000)
Explanation: Cython: give types to all variables
End of explanation
%%cython
def w(int n):
    cdef int i = 0, output
    while i < n:
        output += i % 42
        i += 1
    return output
%timeit w(1000000)
Explanation: Example of a while loop
End of explanation
%%cython
cimport cython
# This code was translated to Cython from a 
# wikipedia article at:
#
# https://en.wikipedia.org/wiki/Xorshift
#
#         "Xorshift random number generators are a 
#         class of pseudorandom number generators that 
#         was discovered by George Marsaglia.[1] They 
#         generate the next number in their sequence 
#         by repeatedly taking the exclusive or of a 
#         number with a bit shifted version of itself. 
#         This makes them extremely fast on modern 
#         computer architectures"
#
#         "A naive C implementation of a xorshift+ generator 
#         that passes all tests from the BigCrush suite 
#         (with an order of magnitude fewer failures than 
#         Mersenne Twister or WELL) typically takes fewer 
#         than 10 clock cycles on x86 to generate a random 
#         number, thanks to instruction pipelining."
cdef unsigned long long s[2]  # Seed: initialize to nonzero
cdef inline unsigned long long xorshiftplus():
     Direct translation from Wikipedia page 
    cdef unsigned long long x = s[0]
    cdef unsigned long long y = s[1]
    s[0] = y
    x ^= x << 23  # a
    x ^= x >> 17  # b
    x ^= y^(y>>26) # c
    s[1] = x
    return x + y
@cython.boundscheck(False)
def random_array(unsigned long long[:] output):
     Array must be already be sized 
    s[0] = 1  # Set the seed
    s[1] = 2
    cdef int i, n = output.shape[0] 
    for i in range(n):
        output[i] = xorshiftplus()
Explanation: Application: custom random number generator
Numpy only generates 32-bit random integers.  Let's make a 64-bit random integer generator!
End of explanation
# Create storage for our 8-byte random numbers
import numpy
output = numpy.zeros(10, dtype=numpy.uint64)
random_array(output)
print(output)
Explanation: Quick demo
End of explanation
n = int(1e8)  # 100 million random numbers
output = numpy.zeros(n, dtype=numpy.uint64)
%timeit random_array(output)
%timeit y = numpy.random.randint(low=0, high=2**31 - 1, size=n)
Explanation: Speed test - compare Cython and Numpy
Note: Numpy generates only 32-bit integers, but uses the Mersenne Twister algorithm.  Our Cython function generates 64-bit integers, but uses the Xorshift+ algorithm.
End of explanation
<END_TASK>