<jupyter_start><jupyter_text>ASTR 119 Final Project Option 2: Logistic Maps<jupyter_code>import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline<jupyter_output><empty_output><jupyter_text>How population depends on previous population    $P_{n+1}=P_n (a-bP_n)$ Substitute $P_n = \frac{a}{b}x_n$ and $r = \frac{a}{4}$ to get: $x_{n+1}=4rx_n(1-x_n)$<jupyter_code>def compute_logistic_map(r,x0,N):
    # r,x0 = initial values, N = Number of steps
    # 0 <= r,x0 <= 1
    N = 100                             # n goes from 0 to N
    x = np.zeros(N)
    x[0] = x0
    for n in range(N-1):
        x[n+1] = 4*r*x[n]*(1-x[n])
    return x
# initial conditions to test
r=0.7
x0 = 0.65
N = 100
x = compute_logistic_map(r,x0,N)

# graph n vs x_n
plt.plot(np.arange(N),x,'.')
plt.xlabel('n')
plt.ylabel(r'$x_n$')
plt.show()<jupyter_output><empty_output><jupyter_text>Define the Lyapunov exponent as: $\lambda = \frac{1}{n}\sum_{i=0}^{n-1} ln\mid 4r(1-2x_i) \mid$ where if $\lambda<0$ : convergence and if $\lambda>0$ : divergence (chaos)<jupyter_code>def find_lyapunov_exp(r,x):
    # r = constant, x = array N long of x values according to recursion relation
    lyapunov_exp = 0.0   # initialize lambda
    for xi in x:
        lyapunov_exp += np.log(np.fabs(4*r*(1-2*xi)))
    lyapunov_exp *= 1/N
    return lyapunov_exp
    
# initial conditions to test
r=0.7
x0 = 0.65
N = 100
x = compute_logistic_map(r,x0,N)

print('Lyapunov exponent =',find_lyapunov_exp(r,x))<jupyter_output><empty_output><jupyter_text>Define wrapper to find logistic map of range of r values<jupyter_code>def range_logistic_map(r_range,x0,N):
    x = np.zeros((len(r_range),N))
    lyapunov_exp = np.zeros(len(r_range))
    for i in range(len(r_range)):
        x[i] = compute_logistic_map(r_range[i],x0,N)
        lyapunov_exp[i] = find_lyapunov_exp(r_range[i],x[i])
    return x,lyapunov_exp
r_range = np.arange(0.7,1.0,0.01)
x0 = 0.65
N = 100

x,lyapunov_exp = range_logistic_map(r_range,x0,N)
for i in range(len(r_range)):
    a = 75
    plt.plot(np.full(len(x[i]),r_range[i])[a:] , x[i][a:],'r.')
plt.xlabel('r')
plt.ylabel(r'$x_n$')
plt.show()
# plt.figure(figsize=(20,10))
plt.plot(r_range,lyapunov_exp,'b')
plt.axhline(0,c='k')
plt.xlabel('r')
plt.ylabel(r'$\lambda$')
plt.xlim((r_range[0],r_range[-1]))
plt.show()
print('{:>10}{:>10}'.format('r','lambda'))
for i in range(len(r_range)):
    print('{:10.2f}{:10.2f}'.format(r_range[i],lyapunov_exp[i]))<jupyter_output><empty_output><jupyter_text>$\lambda \approx 0$ at r = 0.75, 0.86, 0.89, 0.96 recreate the above plots with dashed lines at each of the above r values<jupyter_code>plt.figure(figsize=(10,7))
for i in range(len(r_range)):
    a = 40
    plt.plot(np.full(len(x[i]),r_range[i])[a:] , x[i][a:],'r.')
plt.xlabel('r')
plt.ylabel(r'$x_n$')
plt.axvline(0.75,c='k',ls='dashed')
plt.axvline(0.86,c='k',ls='dashed')
plt.axvline(0.89,c='k',ls='dashed')
plt.axvline(0.96,c='k',ls='dashed')
plt.plot(r_range,lyapunov_exp,'b')
plt.plot(r_range,lyapunov_exp,'k.')
plt.axhline(0,c='k')
plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.19092689295039164, 'fraction_numerical': 0.040796344647519585, 'mean_word_length': 4.826996197718631, 'pattern_counts': {'":': 0, '<': 24, '<?xml version=': 0, '>': 24, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '129814', 'license': 'MIT', 'n_tokens_mistral': 1481, 'n_tokens_neox': 1369, 'n_words': 240, 'path': 'Final_Project_2_Gerome_Algodon.ipynb', 'repo_name': 'galgodon/astr-119-final-project', 'size': '3064'}