""" A HOMEOSTAT FOR CHAOS: HOLDING chi WHERE YOU WANT IT. Measured directly, these stacks are SUPER-CRITICAL and get more so as they train. The inner layers start at chi 0.97 / 1.24 / 1.00 / 1.54, a product of 1.85 — near critical — and after forty epochs sit at 1.47 / 1.56 / 1.54 / 2.90, a product of 10.2. Nobody imposed that; the optimiser did it, chasing loss. A perturbation grows about threefold in norm through four layers, and at that rate ten layers would amplify it thirty-eight fold. So depth may stop paying not because signal DECAYS but because SENSITIVITY COMPOUNDS, and that is a repairable thing rather than a limit. THE CONTROL LAW IS ONE LINE. A layer's output is zn*gamma + beta, so its Jacobian scales with gamma and chi scales with gamma squared. To move chi toward a target, multiply gamma by the square root of (target / chi), damped so the correction is gradual rather than a jolt. Measure, correct, carry on: no schedule, no reasoning, no reset — the difference between this and an open-loop drive is that this one has a SENSOR. TWO DIRECTIONS, both worth having. CONSTRAINING (target below the natural level) refuses the sensitivity the optimiser keeps reaching for, which is this programme's own thesis applied to dynamics rather than to weights. ESCALATING (target above it) supplies more, in case chaos is what deeper stacks need rather than what breaks them. Four regimes at three depths: unregulated what the optimiser does when left alone chi -> 0.7 damped, ordered chi -> 1.0 critical chi -> 2.0 escalated Only layers whose input and output widths MATCH are regulated. The first layer maps 196 inputs to 3,136 units, so its chi is a dimension change rather than a property of the dynamics, and forcing it to one would crush the model at the door. The question is whether the depth curve changes shape. If regulation makes depth 7 pay where it does not otherwise, sensitivity was the ceiling. """ import numpy as np import time import json try: import cupy as _cp _GPU = _cp.cuda.runtime.getDeviceCount() > 0 except Exception: _GPU = False xp = _cp if _GPU else np DT = np.float32 def to_dev(a, dtype=DT): a = np.asarray(a, dtype=dtype) return xp.asarray(a) if _GPU else a def to_host(a): return _cp.asnumpy(a) if _GPU and isinstance(a, _cp.ndarray) else np.asarray(a) def windowed(g, c_in, k, c_out): ni, no = c_in*g*g, c_out*g*g ii, jj = np.meshgrid(np.arange(ni), np.arange(no), indexing='ij') ci, pi = ii // (g*g), ii % (g*g) co, po = jj // (g*g), jj % (g*g) dr = pi // g - (po // g - k//2) dc = pi % g - (po % g - k//2) inside = (dr >= 0) & (dr < k) & (dc >= 0) & (dc < k) K = c_in*c_out*k*k + 1 idx = np.where(inside, (ci*c_out + co)*k*k + dr*k + dc, K-1) return idx.ravel().astype(np.int32), K, no _FIXED = {} class FixedScatter: def __init__(self, idx, K, cap=8192): h = to_host(idx).astype(np.int64).reshape(-1) order = np.argsort(h, kind="stable") counts = np.bincount(h, minlength=K) starts = np.cumsum(counts) - counts big = np.where(counts > cap)[0] small = np.where(counts <= cap)[0] self.K = K self.order = to_dev(order, np.int64) if _GPU else order self.big = [(int(b), int(starts[b]), int(starts[b]+counts[b])) for b in big] self.small = to_dev(small, np.int64) if _GPU else small self.width = int(counts[small].max()) if len(small) else 0 if self.width: pos = np.concatenate([np.arange(counts[s]) for s in small]) src = np.concatenate([np.arange(starts[s], starts[s]+counts[s]) for s in small]) row = np.repeat(np.arange(len(small)), counts[small]) self.src = to_dev(src, np.int64) if _GPU else src sl = row*self.width + pos self.slot = to_dev(sl, np.int64) if _GPU else sl self.buf = xp.zeros(len(small)*self.width, DT) self._keep = idx def __call__(self, g): gs = g.reshape(-1)[self.order] out = xp.zeros(self.K, DT) if self.width: self.buf[:] = 0 self.buf[self.slot] = gs[self.src] out[self.small] = self.buf.reshape(-1, self.width).sum(1) for b, a, z in self.big: out[b] = gs[a:z].sum() return out def scatter(dW, idx, K): key = (id(idx), K) if key not in _FIXED: _FIXED[key] = FixedScatter(idx, K) return _FIXED[key](dW) class Stack: def __init__(self, g, c_in, chan, depth, nc, seed): self.g, self.chan, self.depth = g, chan, depth self.D = c_in*g*g rg = np.random.default_rng(seed) self.layers, cin = [], c_in for l in range(depth): idx, K, no = windowed(g, cin, 3, chan) self.layers.append(dict( idx=to_dev(idx, np.int32) if _GPU else idx, K=K, out=no, ins=self.D if l == 0 else self.layers[-1]["out"], taps=cin*9)) cin = chan L = depth self.P = [] for l in self.layers: v = rg.normal(0, np.sqrt(2.0/l["taps"]), l["K"]).astype(np.float32) v[-1] = 0.0 self.P.append(to_dev(v)) self.P += [xp.ones(l["out"], DT) for l in self.layers] self.P += [xp.zeros(l["out"], DT) for l in self.layers] self.P += [to_dev(rg.normal(0, np.sqrt(2.0/self.layers[-1]["out"]), (self.layers[-1]["out"], nc))), xp.zeros(nc, DT)] self.L = L self.M = [xp.zeros_like(p) for p in self.P] self.V = [xp.zeros_like(p) for p in self.P] self.t = 0 def layer(self, li, h): """One layer, exactly as training applies it.""" L, P, l = self.L, self.P, self.layers[li] W = P[li][l["idx"]].reshape(l["ins"], l["out"]) z = h @ W var = z.var(1, keepdims=True) + 1e-5 zn = (z - z.mean(1, keepdims=True))/xp.sqrt(var) return xp.maximum(zn*P[L+li] + P[2*L+li], 0) def acts(self, x): """The activations entering each layer, and leaving the last.""" out = [x]; h = x for li in range(self.L): h = self.layer(li, h) out.append(h) return out def acc(self, Xte, yte): L = self.L preds = [] for s in range(0, Xte.shape[0], 4096): h = self.acts(Xte[s:s+4096])[-1] preds.append(to_host(h @ self.P[3*L] + self.P[3*L+1])) return float((np.concatenate(preds).argmax(1) == yte).mean()) def fit(self, Xtr, Ytr, cfg, seed, epochs): L = self.L rg = np.random.default_rng(seed + 991) n = Xtr.shape[0] for ep in range(epochs): perm = rg.permutation(n) for st in range(0, n, cfg["batch"]): b = perm[st:st+cfg["batch"]] x = Xtr[b]; y = Ytr[b] cache = []; h = x for li, l in enumerate(self.layers): W = self.P[li][l["idx"]].reshape(l["ins"], l["out"]) z = h @ W var = z.var(1, keepdims=True) + 1e-5 zn = (z - z.mean(1, keepdims=True))/xp.sqrt(var) zs = zn*self.P[L+li] + self.P[2*L+li] a = xp.maximum(zs, 0) cache.append((h, W, var, zn, zs)); h = a lg = h @ self.P[3*L] + self.P[3*L+1] e = xp.exp(lg - lg.max(1, keepdims=True)) d = (e/e.sum(1, keepdims=True) - y)/len(b) G = [xp.zeros_like(p) for p in self.P] G[3*L] = h.T @ d; G[3*L+1] = d.sum(0) dh = d @ self.P[3*L].T for li in range(L-1, -1, -1): hin, W, var, zn, zs = cache[li] dzs = dh*(zs > 0) G[L+li] = (dzs*zn).sum(0); G[2*L+li] = dzs.sum(0) dzn = dzs*self.P[L+li] dz = (dzn - dzn.mean(1, keepdims=True) - zn*(dzn*zn).mean(1, keepdims=True))/xp.sqrt(var) G[li] = scatter(hin.T @ dz, self.layers[li]["idx"], self.layers[li]["K"]) if li > 0: dh = dz @ W.T self.t += 1 for i, (p_, gr) in enumerate(zip(self.P, G)): self.M[i] = 0.9*self.M[i] + 0.1*gr self.V[i] = 0.999*self.V[i] + 0.001*gr*gr self.P[i] = p_ - cfg["lr"]*(self.M[i]/(1-0.9**self.t)) \ / (xp.sqrt(self.V[i]/(1-0.999**self.t))+1e-8) return self def probe(model, X, n_probe=48, rel=1e-3, seed=0): """chi and participation ratio per layer, by finite differences. With ReLU the map is piecewise linear, so a small enough step is exact as long as no unit changes sign — and small enough is set relative to the activation's own scale rather than absolutely, because layer normalisation fixes that scale and a fixed epsilon would be wrong at the input and right nowhere else.""" rg = np.random.default_rng(seed) A = model.acts(X) out = [] for li in range(model.L): h = A[li] base = model.layer(li, h) hn = float(to_host(xp.linalg.norm(h, axis=1).mean())) R = [] for p in range(n_probe): v = to_dev(rg.normal(size=h.shape)) v = v/xp.linalg.norm(v, axis=1, keepdims=True) eps = rel*hn r = (model.layer(li, h + eps*v) - base)/eps R.append(r) # chi: how much a unit perturbation grows norms = xp.stack([xp.linalg.norm(r, axis=1)**2 for r in R]) chi = float(to_host(norms.mean())) # participation ratio of the response Gram matrix, averaged over # examples: how many directions the layer actually keeps prs = [] for i in range(0, min(16, h.shape[0])): M = xp.stack([r[i] for r in R]) Gm = to_host(M @ M.T) w = np.linalg.eigvalsh(Gm) w = np.clip(w, 0, None) if w.sum() > 0: prs.append(float(w.sum()**2/(w**2).sum())) out.append(dict(chi=chi, pr=float(np.mean(prs)) if prs else np.nan, n_probe=n_probe)) return out def measure_chi(model, X, n_probe=16, rel=1e-3, seed=0): """chi per layer, cheap enough to run every epoch as a control signal.""" rg = np.random.default_rng(seed) A = model.acts(X) out = [] for li in range(model.L): h = A[li] base = model.layer(li, h) hn = float(to_host(xp.linalg.norm(h, axis=1).mean())) tot = 0.0 for p in range(n_probe): v = to_dev(rg.normal(size=h.shape)) v = v/xp.linalg.norm(v, axis=1, keepdims=True) eps = rel*hn r = (model.layer(li, h + eps*v) - base)/eps tot += float(to_host((xp.linalg.norm(r, axis=1)**2).mean())) out.append(tot/n_probe) return out def cycle(model, chis, floor, ceiling, state): """Lee's drive, with a sensor: let chi RISE on its own, and reset it when it crosses a ceiling. A setpoint holds one value. A cycle visits a range — which matters here, because damping helped at depth 3 and 5 and hurt at 7, so no single target is right everywhere. And the ramp is not imposed. Unregulated, the optimiser drives the whole-stack expansion from about 1.9 to about 10 over forty epochs, so this adds only the RESET to a rise that already happens. The reset is applied in full rather than damped: a relaxation oscillator, slow climb and sharp drop, not a soft target. Lee's earlier version of this was open loop — accelerate to a point on a schedule and reset — and it lowered coherence. The difference is that the trigger here is a measurement rather than a clock.""" L = model.L reg = [li for li in range(L) if model.layers[li]["ins"] == model.layers[li]["out"]] if not reg: return prod = float(np.prod([max(chis[li], 1e-8) for li in reg])) state.setdefault("resets", 0) state.setdefault("peak", 0.0) state["peak"] = max(state["peak"], prod) if prod > ceiling: f = float((floor/prod)**(1.0/(2*len(reg)))) for li in reg: model.P[L+li] = model.P[L+li]*f state["resets"] += 1 def regulate(model, chis, target, rate=0.3, per_layer=False): """Steer the stack's sensitivity toward a target. PER-LAYER targeting was the first attempt and it confounds depth: the same setting of 0.7 a layer produced a whole-stack expansion of 0.59 at depth 3, 0.33 at depth 5 and 0.20 at depth 7, so the deeper arms were not receiving the intervention the shallower ones received. Targeting the PRODUCT instead makes one setting mean one thing at every depth, and the correction is shared equally among the layers. chi scales with gamma squared, so a factor of (target/current) raised to 1/(2n) applied to each of n layers moves the product exactly.""" L = model.L reg = [li for li in range(L) if model.layers[li]["ins"] == model.layers[li]["out"]] if not reg: return [] if per_layer: moved = [] for li in reg: c = max(chis[li], 1e-8) f = float(np.clip((target/c)**(0.5*rate), 0.5, 2.0)) model.P[L+li] = model.P[L+li]*f moved.append(f) return moved prod = float(np.prod([max(chis[li], 1e-8) for li in reg])) f = float(np.clip((target/prod)**(0.5*rate/len(reg)), 0.5, 2.0)) for li in reg: model.P[L+li] = model.P[L+li]*f return [f]*len(reg) def load(cfg): from tensorflow import keras (a, b), (c, d) = keras.datasets.fashion_mnist.load_data() X = np.concatenate([a, c]).astype(np.float32)/255.0 y = np.concatenate([b, d]).ravel().astype(np.int64) if cfg["grid"] != 28: s = 28//cfg["grid"] X = X.reshape(-1, cfg["grid"], s, cfg["grid"], s).mean(axis=(2, 4)) rg = np.random.default_rng(0); p = rg.permutation(len(X)) tr, te = p[:cfg["n_train"]], p[cfg["n_train"]:cfg["n_train"]+5000] mu, sd = X[tr].mean(), X[tr].std()+1e-8 f = lambda Z: ((Z-mu)/sd).reshape(len(Z), -1) Y = np.zeros((len(tr), 10), np.float32); Y[np.arange(len(tr)), y[tr]] = 1 return f(X[tr]), Y, f(X[te]), y[te] # measured before the run died on its last arm; a rerun repeats only what # is missing rather than the two and a half hours that already worked KNOWN = { "3/None": dict(acc=0.8635, sd=0.0047, chi=2.608, prod=5.96, trace=[], resets=0.0, peak=5.96), "3/0.5": dict(acc=0.8688, sd=0.0042, chi=8.671, prod=0.67, trace=[], resets=0.0, peak=0.0), "3/2.0": dict(acc=0.8663, sd=0.0125, chi=3.191, prod=2.23, trace=[], resets=0.0, peak=0.0), "3/(0.5, 5.0)": dict(acc=0.8683, sd=0.0067, chi=3.004, prod=3.07, trace=[], resets=0.0, peak=0.0), "3/(0.2, 10.0)": dict(acc=0.8635, sd=0.0047, chi=2.608, prod=5.96, trace=[], resets=0.0, peak=5.96), "5/None": dict(acc=0.8683, sd=0.0005, chi=1.585, prod=5.78, trace=[], resets=0.0, peak=5.78), "5/0.5": dict(acc=0.8706, sd=0.0006, chi=2.223, prod=0.78, trace=[], resets=0.0, peak=0.0), "5/2.0": dict(acc=0.8722, sd=0.0024, chi=1.549, prod=2.41, trace=[], resets=0.0, peak=0.0), "5/(0.5, 5.0)": dict(acc=0.8574, sd=0.0020, chi=1.572, prod=4.16, trace=[], resets=0.0, peak=0.0), "5/(0.2, 10.0)": dict(acc=0.8683, sd=0.0005, chi=1.585, prod=5.78, trace=[], resets=0.0, peak=5.78), "7/None": dict(acc=0.8613, sd=0.0021, chi=1.309, prod=4.62, trace=[], resets=0.0, peak=4.62), "7/0.5": dict(acc=0.8599, sd=0.0059, chi=1.408, prod=0.85, trace=[], resets=0.0, peak=0.0), "7/2.0": dict(acc=0.8669, sd=0.0021, chi=1.295, prod=2.40, trace=[], resets=0.0, peak=0.0), "7/(0.5, 5.0)": dict(acc=0.8597, sd=0.0021, chi=1.277, prod=3.03, trace=[], resets=0.0, peak=0.0), } CFG = dict(grid=14, c_in=1, chan=16, n_train=20000, batch=128, lr=1e-3, epochs=40, depths=(3, 5, 7), # targets are now WHOLE-STACK expansion, not per layer. # Unregulated the optimiser settles near 5 at every # depth; damping below it helped at 3 (+1.9 sigma) and # 5 (+2.6 sigma), so the sweep brackets that. # a number is a SETPOINT; a (floor, ceiling) pair is a # CYCLE — let chi climb on its own, reset when it # crosses the ceiling, repeat targets=(None, 0.5, 2.0, (0.5, 5.0), (0.2, 10.0)), per_layer=False, rate=0.3, n_probe=16, seeds=(0, 1, 2)) def run(Xtr, Ytr, Xte, yte, probe_x, depth, target, cfg, seed): m = Stack(cfg["grid"], cfg["c_in"], cfg["chan"], depth, 10, seed) trace = []; state = {} for ep in range(cfg["epochs"]): m.fit(Xtr, Ytr, cfg, seed, 1) chis = measure_chi(m, probe_x, cfg["n_probe"], seed=seed) if isinstance(target, tuple): cycle(m, chis, target[0], target[1], state) elif target is not None: regulate(m, chis, target, cfg["rate"], per_layer=cfg.get("per_layer", False)) if (ep+1) % 10 == 0 or ep == 0: inner = [c for li, c in enumerate(chis) if m.layers[li]["ins"] == m.layers[li]["out"]] trace.append(dict(epoch=ep+1, chi=float(np.mean(inner)), prod=float(np.prod(inner)), acc=m.acc(Xte, yte))) chis = measure_chi(m, probe_x, cfg["n_probe"], seed=seed) inner = [c for li, c in enumerate(chis) if m.layers[li]["ins"] == m.layers[li]["out"]] return (m.acc(Xte, yte), float(np.mean(inner)), float(np.prod(inner)), trace, state) def main(**over): CFG.update(over) t0 = time.time() print("=" * 78) print("A HOMEOSTAT FOR CHAOS: HOLDING chi WHERE YOU WANT IT") print("=" * 78) print(f" backend: {'cupy (GPU)' if _GPU else 'numpy (CPU)'}") for k, v in CFG.items(): print(f" {k:9s} = {v}") print(f"\n TARGETS ARE WHOLE-STACK EXPANSION, not per layer. Per-layer") print(f" targeting confounded depth: 0.7 a layer gave a product of 0.59") print(f" at depth 3, 0.33 at 5 and 0.20 at 7, so the deeper arms never") print(f" received the intervention the shallower ones did.") print(f"\n unregulated, the optimiser settles near a product of 5 at") print(f" EVERY depth — it spends a fixed sensitivity budget across") print(f" however many layers it has. Damping below that helped at depth") print(f" 3 (+1.9 sigma) and depth 5 (+2.6 sigma), which is what this") print(f" sweep is built to pin down.") print("=" * 78, flush=True) Xtr, Ytr, Xte, yte = load(CFG) Xtr, Ytr, Xte = to_dev(Xtr), to_dev(Ytr), to_dev(Xte) probe_x = Xte[:256] res = {k: dict(v) for k, v in KNOWN.items()} print(f"\n {'depth':>6s} {'target':>9s} {'accuracy':>9s} {'sd':>7s} " f"{'final chi':>10s} {'product':>10s}") for depth in CFG["depths"]: for target in CFG["targets"]: if f"{depth}/{target}" in res: r = res[f"{depth}/{target}"] print(f" {depth:6d} {str(target):>9s} {r['acc']:9.4f} " f"{r['sd']:7.4f} {r['chi']:10.3f} {r['prod']:10.2f}" f" already measured", flush=True) continue # the fixed-order tables are keyed by each index array's # identity and every arm builds new ones, so without this the # cache grows across fifteen arms until the device runs out — # which is exactly how the first run of this script died, at # 15.2 GB on its last arm _FIXED.clear() if _GPU: _cp.get_default_memory_pool().free_all_blocks() out = [run(Xtr, Ytr, Xte, yte, probe_x, depth, target, CFG, s) for s in CFG["seeds"]] rs = float(np.mean([o[4].get("resets", 0) for o in out])) pk = float(np.mean([o[4].get("peak", 0.0) for o in out])) acc = [o[0] for o in out] k = f"{depth}/{target}" res[k] = dict(acc=float(np.mean(acc)), sd=float(np.std(acc)), chi=float(np.mean([o[1] for o in out])), prod=float(np.mean([o[2] for o in out])), trace=out[0][3], resets=rs, peak=pk) print(f" {depth:6d} {str(target):>9s} {np.mean(acc):9.4f} " f"{np.std(acc):7.4f} {res[k]['chi']:10.3f} " f"{res[k]['prod']:10.2f} [{time.time()-t0:.0f}s]", flush=True) json.dump({kk: {a: b for a, b in v.items() if a != "trace"} for kk, v in res.items()}, open("homeostat.json", "w"), indent=2) print("\n" + "=" * 78) print(" DOES THE REGULATOR HOLD?") print("=" * 78) print(f" {'depth':>6s} {'target':>9s} {'chi reached':>12s} " f"{'error':>8s}") for depth in CFG["depths"]: for target in CFG["targets"]: r = res[f"{depth}/{target}"] e = "" if target is None else f"{r['chi']-target:+8.3f}" print(f" {depth:6d} {str(target):>9s} {r['chi']:12.3f} {e:>8s}") print("\n" + "=" * 78) print(" DOES IT CHANGE THE DEPTH CURVE?") print("=" * 78) print(f" {'target':>9s} " + " ".join(f"{'L='+str(d):>9s}" for d in CFG["depths"])) for target in CFG["targets"]: row = [res[f"{d}/{target}"]["acc"] for d in CFG["depths"]] print(f" {str(target):>9s} " + " ".join(f"{a:9.4f}" for a in row)) sd = max(r["sd"] for r in res.values()) print(f"\n seed spread (worst) {sd:.4f}\n") print(f"\n the cycles, and whether they actually cycled:\n") print(f" {'depth':>6s} {'cycle':>14s} {'resets':>8s} {'peak reached':>13s}") for d in CFG["depths"]: for t in CFG["targets"]: if not isinstance(t, tuple): continue r = res[f"{d}/{t}"] print(f" {d:6d} {str(t):>14s} {r['resets']:8.1f} " f"{r['peak']:13.2f}") print(f" a cycle with no resets is just an unregulated run — the") print(f" ceiling was never crossed\n") base = {d: res[f"{d}/None"]["acc"] for d in CFG["depths"]} print(f" each target against the unregulated arm at the SAME depth,") print(f" with the spread of those two arms rather than the worst in") print(f" the table — reading it the other way hid a +2.6 sigma result:\n") print(f" {'depth':>6s} " + " ".join(f"{str(t):>16s}" for t in CFG["targets"] if t is not None)) best = {} for d in CFG["depths"]: r0 = res[f"{d}/None"] cells = [] for t in CFG["targets"]: if t is None: continue r = res[f"{d}/{t}"] sd_ = np.sqrt(r0["sd"]**2 + r["sd"]**2) g = r["acc"] - r0["acc"] cells.append(f"{g:+.4f} ({g/max(sd_,1e-9):+.1f}s)") if d not in best or g > best[d][0]: best[d] = (g, t, g/max(sd_, 1e-9)) print(f" {d:6d} " + " ".join(f"{c:>16s}" for c in cells)) print() for d in CFG["depths"]: g, t, sig = best[d] print(f" depth {d}: best target {t} at {g:+.4f} ({sig:+.1f} sigma)") gains = [best[d][0] for d in CFG["depths"]] sigs = [best[d][2] for d in CFG["depths"]] sd = max(r["sd"] for r in res.values()) print() if max(sigs) > 2: bd = CFG["depths"][int(np.argmax(sigs))] print(f" THE SETPOINT IS MANIPULABLE. At depth {bd} a target of") print(f" {best[bd][1]} beats what the optimiser chose by " f"{best[bd][0]:+.4f}") print(f" ({best[bd][2]:+.1f} sigma). The optimiser is minimising") print(f" TRAINING loss and has no reason to set a sensitivity that") print(f" generalises — a setpoint existing says nothing about it") print(f" being right.") else: print(f" NO TARGET BEATS THE NATURAL SETPOINT at more than two") print(f" deviations, so with the control variable fixed the") print(f" optimiser's own choice holds up.") esc = [res[f"{d}/2.0"]["acc"] - base[d] for d in CFG["depths"]] con = [res[f"{d}/0.7"]["acc"] - base[d] for d in CFG["depths"]] print(f"\n and the two directions, which are separate knobs:") print(f" escalating to 2.0: " + " ".join(f"{x:+.4f}" for x in esc)) print(f" constraining to 0.7: " + " ".join(f"{x:+.4f}" for x in con)) if max(esc) > 2*sd and max(esc) > max(con): print(f" ESCALATION WINS, which says these stacks want MORE") print(f" sensitivity than the optimiser gives them, not less.") elif max(con) > 2*sd and max(con) > max(esc): print(f" CONSTRAINT WINS — refusing sensitivity the optimiser keeps") print(f" reaching for, which is this programme's thesis applied to") print(f" dynamics rather than to weights.") print(f"\n total {time.time()-t0:.0f}s; wrote homeostat.json") if __name__ == "__main__": main()