import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# 1. Generate synthetic data
# First, an upward trend (60% probability of an upward move), then a sharp downward reversal (30% probability of an upward move)
np.random.seed(42)
data_up = np.random.choice([1, 0], size=100, p=[0.6, 0.4])
data_down = np.random.choice([1, 0], size=100, p=[0.3, 0.7])
data = np.concatenate([data_up, data_down])

# 2. Model parameters
gamma = 0.94  # Decay factor gamma (the smaller γ is, the faster the model forgets the past)
a_curr, b_curr = 1, 1 # Initial parameters: Beta(1,1) — uniform prior

history = []

# 3. Dynamic Bayesian updating loop with exponential decay
for y in data:
    #  Add 1 to always retain at least a minimal Beta(1,1) prior
    a_curr = (a_curr - 1) * gamma + 1
    b_curr = (b_curr - 1) * gamma + 1
    
    # Update with a new observation
    if y == 1:
        a_curr += 1
    else:
        b_curr += 1
        
    # Calculate the current posterior mean (expected probability of success)    
    mean = a_curr / (a_curr + b_curr)
    history.append(mean)

# 4. Visualization
plt.figure(figsize=(12, 5), dpi=100)
plt.plot(history, color='#3498db', lw=2, label=f'Adaptive Bayesian (gamma={gamma})')
plt.axhline(0.5, color='black', linestyle='--', alpha=0.3)
plt.axvline(100, color='red', linestyle=':', label='Change point')

# 5. Comparison with standard (non-adaptive) Bayesian updating (gamma=1)
a_std, b_std = 1, 1  # Also start with a uniform Beta(1,1) prior
std_history = []
for y in data:
    # Standard Bayesian updating—we simply add each new observation
    if y == 1: a_std += 1
    else: b_std += 1
    mean_std = a_std / (a_std + b_std) # Posterior mean
    std_history.append(mean_std)

plt.plot(std_history, color='gray', alpha=0.5, label='Standard Bayesian (gamma=1.0)')

plt.title('Adaptive Bayesian Update vs Standard', fontsize=12)
plt.legend()
plt.grid(alpha=0.2)
plt.show()