<jupyter_start><jupyter_text>quant-econ Solutions: Need for Speed Solutions for http://quant-econ.net/py/need_for_speed.html  Exercise 1 Let's start with some imports<jupyter_code>import matplotlib.pyplot as plt
import numpy as np
from numba import jit<jupyter_output><empty_output><jupyter_text>We let * 0 represent "low"* 1 represent "high"<jupyter_code>p, q = 0.1, 0.2  # Prob of leaving low and high state respectively<jupyter_output><empty_output><jupyter_text>Here's a pure Python version of the function<jupyter_code>def compute_series(n):
    x = np.empty(n, dtype=int)
    x[0] = 1  # Start in state 1
    U = np.random.uniform(0, 1, size=n)
    for t in range(1, n):
        current_x = x[t-1]
        if current_x == 0:
            x[t] = U[t] < p
        else:
            x[t] = U[t] > q
    return x<jupyter_output><empty_output><jupyter_text>Let's run this code and check that the fraction of time spent in the low state is about 0.666<jupyter_code>n = 100000
x = compute_series(n)
print(np.mean(x == 0))  # Fraction of time x is in state 0<jupyter_output>0.66837<jupyter_text>Now let's time it<jupyter_code>%timeit compute_series(n)<jupyter_output>10 loops, best of 3: 77 ms per loop<jupyter_text>Next let's implement a Numba version, which is easy<jupyter_code>compute_series_numba = jit(compute_series)<jupyter_output><empty_output><jupyter_text>Let's check we still get the right numbers<jupyter_code>x = compute_series_numba(n)
print(np.mean(x == 0))<jupyter_output>0.67165<jupyter_text>Let's see the time<jupyter_code>%timeit compute_series_numba(n)<jupyter_output>1000 loops, best of 3: 1.81 ms per loop<jupyter_text>This is a nice speed improvement for one line of codeNow let's implement a Cython version<jupyter_code>%load_ext Cython
%%cython
import numpy as np
from numpy cimport int_t, float_t

def compute_series_cy(int n):
    # == Create NumPy arrays first == #
    x_np = np.empty(n, dtype=int)
    U_np = np.random.uniform(0, 1, size=n)
    # == Now create memoryviews of the arrays == #
    cdef int_t [:] x = x_np
    cdef float_t [:] U = U_np
    # == Other variable declarations == #
    cdef float p = 0.1
    cdef float q = 0.2
    cdef int t
    # == Main loop == #
    x[0] = 1  
    for t in range(1, n):
        current_x = x[t-1]
        if current_x == 0:
            x[t] = U[t] < p
        else:
            x[t] = U[t] > q
    return np.asarray(x)
compute_series_cy(10)
x = compute_series_cy(n)
print(np.mean(x == 0))
%timeit compute_series_cy(n)<jupyter_output>100 loops, best of 3: 2.09 ms per loop
{'fraction_non_alphanumeric': 0.11189634864546526, 'fraction_numerical': 0.029053788771103258, 'mean_word_length': 3.844106463878327, 'pattern_counts': {'":': 0, '<': 34, '<?xml version=': 0, '>': 34, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '530257', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 1020, 'n_tokens_neox': 961, 'n_words': 264, 'path': 'need_for_speed/speed_solutions.ipynb', 'repo_name': 'indextrading/my', 'size': '2547'}