amkkk's picture
download
raw
2.35 kB
"""Verbatim copies of the authors' G3 notebook functions, used only as an
independent reference to cross-check src/sequential_test.py on identical inputs.
Source: official_code/G3_ParametricFamily.ipynb cells 4, 10, 12.
Pasted exactly as written (no modifications) so any numerical discrepancy is
attributable to my re-implementation, not to a transcription difference.
"""
import numpy as np
from scipy.linalg import eig
from scipy.optimize import minimize_scalar
# --- Official cell 4: build_P_theta -----------------------------------------
def build_P_theta(theta, P0, f):
tilde = P0 * np.exp(theta * f[np.newaxis, :])
eigvals, eigvecs = eig(tilde.T)
idx = np.argmax(np.real(eigvals))
rho = np.real(eigvals[idx])
v = np.real(eigvecs[:, idx])
v = np.abs(v)
Ptheta = (tilde * v[np.newaxis, :]) / (rho * v[:, np.newaxis])
Ptheta = np.maximum(Ptheta, 0)
Ptheta = Ptheta / Ptheta.sum(axis=1, keepdims=True)
return Ptheta, rho, v
# --- Official cell 10: stationary_dist --------------------------------------
def stationary_dist(P):
m = P.shape[0]
A = np.vstack([P.T - np.eye(m), np.ones(m)])
b = np.zeros(m + 1)
b[-1] = 1.0
pi, *_ = np.linalg.lstsq(A, b, rcond=None)
pi = np.maximum(pi, 0)
return pi / pi.sum()
# --- Official cell 11: kl_row, f_P_from_QP, D_M -----------------------------
def kl_row(q, p, eps=1e-12):
q = np.clip(q, eps, 1)
p = np.clip(p, eps, 1)
return np.sum(q * np.log(q / p))
def f_P_from_QP(Q, P):
m = Q.shape[0]
f = np.zeros(m)
for i in range(m):
f[i] = kl_row(Q[i], P[i])
return f
def D_M_official(Q, P):
pi = stationary_dist(Q)
f = f_P_from_QP(Q, P)
return np.dot(pi, f)
# --- Official cell 12: compute_information_rate -----------------------------
def compute_information_rate(Q_TPM, Theta_P, P0, f, build_P_theta):
pi_Q = stationary_dist(Q_TPM)
def objective(theta):
P_theta, _, _ = build_P_theta(theta, P0, f)
eps = 1e-12
ratio = Q_TPM / np.maximum(P_theta, eps)
with np.errstate(divide="ignore", invalid="ignore"):
kl_matrix = Q_TPM * np.log(ratio)
kl_matrix[~np.isfinite(kl_matrix)] = 0.0
return np.sum(pi_Q[:, None] * kl_matrix)
res = minimize_scalar(objective, bounds=Theta_P, method="bounded")
return res.fun

Xet Storage Details

Size:
2.35 kB
·
Xet hash:
0ff60fcdb1fb8ce0480319e5b545993f7a83fa063682c49b7ab09d618d353c3f

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.