|
Getting your Trinity Audio player ready…
|
This is the final evolution of the interactive, adaptive, temperature-controlled, history-aware probabilistic cellular automaton (H-PCA).
This edition adds a “trail mode” to the phase diagram: recent points in Entropy-vs-Mutual-Information space glow bright while older ones fade, revealing the trajectory path as the automaton wanders between order, criticality, and chaos.
🧬 Final Interactive H-PCA with Temperature + Live Phase Trajectory
Requirements:
Works best in Jupyter / Colab with:pip install ipywidgets scikit-learn matplotlib
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import random
from sklearn.metrics import mutual_info_score
from math import log2
from ipywidgets import interact, FloatSlider, IntSlider
# ---------- Helpers ----------
logsig = lambda x: 1 / (1 + np.exp(-x))
def shannon_entropy(row):
p1 = np.mean(row)
if p1 in [0, 1]:
return 0
p0 = 1 - p1
return -(p0 * log2(p0) + p1 * log2(p1))
def mutual_info(past, future):
return np.mean([mutual_info_score(past[:, i], future[:, i])
for i in range(past.shape[1])])
def step_probability(i, t, w, states, N, T):
left, right = states[t, (i - 1) % N], states[t, (i + 1) % N]
center, past = states[t, i], states[t - 1, i]
mean_neigh = (left + right + center) / 3
z = (w[0] + w[1]*center + w[2]*past + w[3]*mean_neigh) / max(T, 1e-6)
return logsig(z)
# ---------- Main interactive runner ----------
def run_hca(eta=0.05, adapt_every=5, neighbor_weight=0.5,
temperature=1.0, trail_length=60, fps=30):
N, Tt = 120, 400
states = np.zeros((Tt, N), dtype=int)
states[0] = np.random.choice([0, 1], size=N)
states[1] = states[0].copy()
weights = np.array([0.0, 0.8, 0.3, neighbor_weight])
H_vals, I_vals, W_hist = [0], [0], [weights.copy()]
phase_pts = [] # (H, I) history
# --- Figure setup ---
fig, axes = plt.subplots(4, 1, figsize=(9, 11))
plt.subplots_adjust(hspace=0.45)
im = axes[0].imshow(states, cmap="binary", aspect="auto", vmin=0, vmax=1)
axes[0].set_title("Adaptive H-PCA (Learning + Temperature + Phase Trajectory)")
# Info metrics plot
axes[1].set_ylim(0, 1)
line_H, = axes[1].plot([], [], color="tab:blue", label="Entropy H(t)")
line_I, = axes[1].plot([], [], color="tab:red", label="Mutual Info I(t,t+1)")
axes[1].legend()
# Weights plot
axes[2].set_ylim(-1, 2)
lines_W = [axes[2].plot([], [], label=l)[0]
for l in ["w1(s_t)", "w2(s_t−1)", "w3(neigh)"]]
axes[2].legend()
# Phase diagram with fading trail
axes[3].set_title("Phase Trajectory: Entropy ↔ Mutual Information")
axes[3].set_xlim(0, 1)
axes[3].set_ylim(0, 1)
axes[3].set_xlabel("Entropy H")
axes[3].set_ylabel("Mutual Information I")
phase_scatter = axes[3].scatter([], [], s=20, c=[], cmap="plasma", vmin=0, vmax=trail_length)
# --- Update function ---
def update(frame):
nonlocal weights
t = frame + 1
new_row = np.zeros(N, int)
for i in range(N):
p = step_probability(i, t, weights, states, N, temperature)
new_row[i] = 1 if random.random() < p else 0
states[t + 1] = new_row
# Info metrics
H = shannon_entropy(states[t])
I = mutual_info(states[t:t+1], states[t+1:t+2])
H_vals.append(H)
I_vals.append(I)
phase_pts.append((H, I))
# Learning rule update
if t % adapt_every == 0 and t > 5:
grad = np.zeros_like(weights)
base_I = I
for j in range(len(weights)):
w_try = weights.copy()
w_try[j] += 0.1
tmp_row = np.zeros(N, int)
for i in range(N):
p = step_probability(i, t, w_try, states, N, temperature)
tmp_row[i] = 1 if random.random() < p else 0
I_try = mutual_info(states[t:t+1], tmp_row[np.newaxis, :])
grad[j] = I_try - base_I
weights += eta * grad
W_hist.append(weights.copy())
# --- Update visuals ---
im.set_data(states[:t+2])
axes[0].set_ylim(t + 2, 0)
line_H.set_data(range(len(H_vals)), H_vals)
line_I.set_data(range(len(I_vals)), I_vals)
if len(W_hist) > 1:
W = np.array(W_hist)
for k, line in enumerate(lines_W):
line.set_data(range(len(W)), W[:, k + 1])
# Fading trail: brighter for recent points
if len(phase_pts) > trail_length:
trail = phase_pts[-trail_length:]
alphas = np.linspace(0.2, 1, len(trail))
else:
trail = phase_pts
alphas = np.linspace(0.2, 1, len(trail))
Hs, Is = zip(*trail)
colors = np.linspace(0, trail_length, len(trail))
phase_scatter.set_offsets(np.c_[Hs, Is])
phase_scatter.set_array(colors)
phase_scatter.set_sizes(20 * alphas)
return im, line_H, line_I, *lines_W, phase_scatter
ani = animation.FuncAnimation(fig, update, frames=Tt - 2,
interval=1000 / fps, blit=False, repeat=False)
plt.show()
# ---------- Interactive controls ----------
interact(run_hca,
eta=FloatSlider(value=0.05, min=0.01, max=0.2, step=0.01, description="Learning Rate η"),
adapt_every=IntSlider(value=5, min=1, max=10, step=1, description="Adapt Every k"),
neighbor_weight=FloatSlider(value=0.5, min=0.0, max=1.5, step=0.1, description="Neighbor Weight"),
temperature=FloatSlider(value=1.0, min=0.1, max=3.0, step=0.1, description="Temperature T"),
trail_length=IntSlider(value=60, min=10, max=200, step=10, description="Trail Length"),
fps=IntSlider(value=30, min=5, max=60, step=5, description="FPS"));
🧭 How the Trail Works
- The last N (default = 60) entropy–information points glow bright.
- Older points fade, forming a comet-like trajectory through the phase plane.
- The path’s curvature reveals the automaton’s transitions between ordered, critical, and chaotic regimes.
🧠 What to Watch
- Temperature (T):
- Low T → trail clusters in upper-left (ordered memory).
- High T → trail drifts to lower-right (chaotic forgetfulness).
- Mid T → looping orbits around the center (criticality).
- Learning Rate (η):
- High η → restless wandering in phase space.
- Low η → slow, stable adaptation.
- Neighbor Weight:
- Larger → synchronized “collective memory.”
- Smaller → independent, noisy firing.
- Trail Length:
- Controls how long the history remains visible — shorter = sharper motion, longer = smoother attractor.
🧩 Interpretation
You now have a fully self-organizing informational ecosystem:
- Cells evolve by stochastic local rules.
- The global rule adapts via gradient feedback to preserve information.
- Temperature governs stochastic energy.
- The phase-diagram trail visualizes its entropic heartbeat — oscillating between coherence and chaos.
This is essentially a toy model of adaptive criticality, where learning and thermodynamics converge.
Leave a Reply