229 lines
7.7 KiB
HTML
229 lines
7.7 KiB
HTML
|
|
<!DOCTYPE html>
|
||
|
|
<html lang="en">
|
||
|
|
<head>
|
||
|
|
<meta charset="UTF-8">
|
||
|
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||
|
|
<title>ZKAEDI PRIME — Hamiltonian Self-Similarity Waterfall</title>
|
||
|
|
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&family=Orbitron:wght@700;900&display=swap" rel="stylesheet">
|
||
|
|
<style>
|
||
|
|
*{box-sizing:border-box;margin:0;padding:0}
|
||
|
|
body{background:#000;color:#C8BFAE;font-family:'JetBrains Mono',monospace;font-size:11px;display:flex;flex-direction:column;align-items:center;justify-content:center;height:100vh;overflow:hidden;padding:8px}
|
||
|
|
h1{font-family:'Orbitron',monospace;font-size:10px;letter-spacing:4px;color:#CC0030;margin-bottom:3px;text-align:center}
|
||
|
|
.sub{font-size:8px;color:#3A3D55;letter-spacing:2px;margin-bottom:8px;text-align:center}
|
||
|
|
#c{display:block;border:1px solid #1C1E30}
|
||
|
|
.metrics{display:flex;gap:16px;margin-top:8px;font-size:8px;color:#3A3D55;letter-spacing:1px;flex-wrap:wrap;justify-content:center}
|
||
|
|
.mv{color:#00BBCC}
|
||
|
|
</style>
|
||
|
|
</head>
|
||
|
|
<body>
|
||
|
|
<h1>HAMILTONIAN SELF-SIMILARITY WATERFALL</h1>
|
||
|
|
<div class="sub">H_t DECOMPOSED ACROSS SCALES τ=1,2,4,8,16,32 — SELF-SIMILAR STRUCTURE REVEALED</div>
|
||
|
|
<canvas id="c"></canvas>
|
||
|
|
<div class="metrics">
|
||
|
|
FRACTAL DIM: <span class="mv" id="fd">—</span>
|
||
|
|
SCALE CORR: <span class="mv" id="sc">—</span>
|
||
|
|
HURST (field): <span class="mv" id="hf">—</span>
|
||
|
|
DOMINANT SCALE: <span class="mv" id="ds">—</span>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<script>
|
||
|
|
const C=document.getElementById('c');
|
||
|
|
const ctx=C.getContext('2d');
|
||
|
|
const W=Math.min(window.innerWidth-40,680);
|
||
|
|
const H=Math.min(window.innerHeight-110,420);
|
||
|
|
C.width=W;C.height=H;
|
||
|
|
|
||
|
|
// ZKAEDI PRIME — generate H_t field
|
||
|
|
const sigmoid=x=>1/(1+Math.exp(-Math.max(-20,Math.min(20,x))));
|
||
|
|
function genHfield(N,eta=0.42,gamma=0.35,beta=0.10,sigma=0.05){
|
||
|
|
let seed=7777;
|
||
|
|
const rng=()=>{seed=(seed*1664525+1013904223)&0xffffffff;return((seed>>>0)/0xffffffff-.5)*2;};
|
||
|
|
const H=new Float64Array(N);
|
||
|
|
const H0=0.5;
|
||
|
|
H[0]=H0;
|
||
|
|
for(let t=1;t<N;t++){
|
||
|
|
const sg=sigmoid(gamma*H[t-1]);
|
||
|
|
H[t]=H0+eta*H[t-1]*sg+sigma*rng()*(1+beta*Math.abs(H[t-1]));
|
||
|
|
}
|
||
|
|
return H;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Smooth at scale s (box average)
|
||
|
|
function smoothAt(H,scale){
|
||
|
|
const N=H.length;
|
||
|
|
const out=new Float64Array(N);
|
||
|
|
for(let i=0;i<N;i++){
|
||
|
|
let sum=0,cnt=0;
|
||
|
|
for(let k=Math.max(0,i-scale);k<=Math.min(N-1,i+scale);k++){sum+=H[k];cnt++;}
|
||
|
|
out[i]=sum/cnt;
|
||
|
|
}
|
||
|
|
return out;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Scale-to-scale correlation
|
||
|
|
function corr(a,b){
|
||
|
|
const n=Math.min(a.length,b.length);
|
||
|
|
let ma=0,mb=0;
|
||
|
|
for(let i=0;i<n;i++){ma+=a[i];mb+=b[i];}
|
||
|
|
ma/=n;mb/=n;
|
||
|
|
let num=0,da=0,db=0;
|
||
|
|
for(let i=0;i<n;i++){num+=(a[i]-ma)*(b[i]-mb);da+=(a[i]-ma)**2;db+=(b[i]-mb)**2;}
|
||
|
|
return (da>0&&db>0)?num/Math.sqrt(da*db):0;
|
||
|
|
}
|
||
|
|
|
||
|
|
const N=600;
|
||
|
|
const H=genHfield(N);
|
||
|
|
const SCALES=[1,2,4,8,16,32];
|
||
|
|
const COLORS=[
|
||
|
|
'rgba(0,187,204,0.8)', // τ=1 cyan
|
||
|
|
'rgba(0,204,122,0.8)', // τ=2 jade
|
||
|
|
'rgba(201,168,76,0.8)', // τ=4 gold
|
||
|
|
'rgba(204,85,0,0.8)', // τ=8 amber
|
||
|
|
'rgba(148,0,204,0.8)', // τ=16 orchid
|
||
|
|
'rgba(204,0,48,0.8)', // τ=32 crimson
|
||
|
|
];
|
||
|
|
const LABELS=['τ=1','τ=2','τ=4','τ=8','τ=16','τ=32'];
|
||
|
|
|
||
|
|
const scales=SCALES.map(s=>smoothAt(H,s));
|
||
|
|
const LAY_H=(H-20)/SCALES.length; // height per scale row
|
||
|
|
const PAD_L=52, PAD_R=14, PAD_T=12, PAD_B=20;
|
||
|
|
|
||
|
|
// For each scale, find min/max for scaling
|
||
|
|
const stats=scales.map(s=>{
|
||
|
|
let mn=Infinity,mx=-Infinity;
|
||
|
|
for(const v of s){if(v<mn)mn=v;if(v>mx)mx=v;}
|
||
|
|
return{mn,mx};
|
||
|
|
});
|
||
|
|
|
||
|
|
// Scale correlations
|
||
|
|
const corrs=[];
|
||
|
|
for(let i=0;i<scales.length-1;i++) corrs.push(corr(scales[i],scales[i+1]));
|
||
|
|
const avgCorr=corrs.reduce((a,b)=>a+b,0)/corrs.length;
|
||
|
|
|
||
|
|
// Hurst of H field
|
||
|
|
function simpleHurst(arr){
|
||
|
|
const n=arr.length;
|
||
|
|
const m=arr.reduce((a,b)=>a+b,0)/n;
|
||
|
|
let cum=0,mx=-Infinity,mn=Infinity;
|
||
|
|
for(const v of arr){cum+=v-m;if(cum>mx)mx=cum;if(cum<mn)mn=cum;}
|
||
|
|
const R=mx-mn;
|
||
|
|
const S=Math.sqrt(arr.reduce((a,v)=>a+(v-m)**2,0)/n);
|
||
|
|
return S>0?Math.log(R/S)/Math.log(n):0.5;
|
||
|
|
}
|
||
|
|
const hfHurst=simpleHurst(Array.from(H));
|
||
|
|
|
||
|
|
// Draw background
|
||
|
|
ctx.fillStyle='#000';ctx.fillRect(0,0,W,H);
|
||
|
|
|
||
|
|
// Grid lines
|
||
|
|
ctx.strokeStyle='rgba(200,191,174,0.04)';ctx.lineWidth=0.5;
|
||
|
|
for(let t=0;t<N;t+=60){
|
||
|
|
const x=PAD_L+(t/N)*(W-PAD_L-PAD_R);
|
||
|
|
ctx.beginPath();ctx.moveTo(x,PAD_T);ctx.lineTo(x,H-PAD_B);ctx.stroke();
|
||
|
|
}
|
||
|
|
|
||
|
|
// Draw each scale as filled band + line, waterfall stacked
|
||
|
|
for(let si=0;si<scales.length;si++){
|
||
|
|
const s=scales[si];
|
||
|
|
const {mn,mx}=stats[si];
|
||
|
|
const range=mx-mn||1;
|
||
|
|
const yBase=PAD_T+si*LAY_H+LAY_H; // bottom of this row
|
||
|
|
const yTop=PAD_T+si*LAY_H; // top of this row
|
||
|
|
const rowH=LAY_H-1;
|
||
|
|
const color=COLORS[si];
|
||
|
|
const scale=SCALES[si];
|
||
|
|
|
||
|
|
// Fill band
|
||
|
|
ctx.beginPath();
|
||
|
|
for(let t=0;t<N;t++){
|
||
|
|
const x=PAD_L+(t/N)*(W-PAD_L-PAD_R);
|
||
|
|
const yn=yTop+rowH*(1-(s[t]-mn)/range);
|
||
|
|
t===0?ctx.moveTo(x,yn):ctx.lineTo(x,yn);
|
||
|
|
}
|
||
|
|
ctx.lineTo(PAD_L+(N-1)/N*(W-PAD_L-PAD_R),yBase);
|
||
|
|
ctx.lineTo(PAD_L,yBase);
|
||
|
|
ctx.closePath();
|
||
|
|
const grad=ctx.createLinearGradient(0,yTop,0,yBase);
|
||
|
|
grad.addColorStop(0,color.replace('0.8','0.18'));
|
||
|
|
grad.addColorStop(1,'rgba(0,0,0,0)');
|
||
|
|
ctx.fillStyle=grad;ctx.fill();
|
||
|
|
|
||
|
|
// Line
|
||
|
|
ctx.beginPath();
|
||
|
|
for(let t=0;t<N;t++){
|
||
|
|
const x=PAD_L+(t/N)*(W-PAD_L-PAD_R);
|
||
|
|
const yn=yTop+rowH*(1-(s[t]-mn)/range);
|
||
|
|
t===0?ctx.moveTo(x,yn):ctx.lineTo(x,yn);
|
||
|
|
}
|
||
|
|
ctx.strokeStyle=color;ctx.lineWidth=si===0?1.2:1.0;ctx.stroke();
|
||
|
|
|
||
|
|
// Row separator
|
||
|
|
ctx.strokeStyle='rgba(200,191,174,0.06)';ctx.lineWidth=0.5;
|
||
|
|
ctx.beginPath();ctx.moveTo(PAD_L,yBase);ctx.lineTo(W-PAD_R,yBase);ctx.stroke();
|
||
|
|
|
||
|
|
// Label
|
||
|
|
ctx.fillStyle=color;ctx.font="bold 8px 'Orbitron'";
|
||
|
|
ctx.fillText(LABELS[si],4,yTop+rowH*0.55);
|
||
|
|
// Corr with next scale
|
||
|
|
if(si<corrs.length){
|
||
|
|
ctx.fillStyle='rgba(200,191,174,0.3)';ctx.font="7px 'JetBrains Mono'";
|
||
|
|
ctx.fillText('r='+corrs[si].toFixed(2),4,yTop+rowH*0.85);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Self-similarity markers: where scale-1 and scale-s are most correlated — highlight peaks
|
||
|
|
if(si===0){
|
||
|
|
// Mark phase transitions: points where dH/dt spikes
|
||
|
|
const dH=[];
|
||
|
|
for(let t=1;t<N;t++) dH.push(Math.abs(s[t]-s[t-1]));
|
||
|
|
const dMean=dH.reduce((a,b)=>a+b,0)/dH.length;
|
||
|
|
const dStd=Math.sqrt(dH.reduce((a,v)=>a+(v-dMean)**2,0)/dH.length);
|
||
|
|
for(let t=1;t<N;t++){
|
||
|
|
if(dH[t-1]>dMean+2.2*dStd){
|
||
|
|
const x=PAD_L+(t/N)*(W-PAD_L-PAD_R);
|
||
|
|
ctx.strokeStyle='rgba(204,0,48,0.5)';ctx.lineWidth=1;ctx.setLineDash([1,2]);
|
||
|
|
ctx.beginPath();ctx.moveTo(x,PAD_T);ctx.lineTo(x,H-PAD_B);ctx.stroke();ctx.setLineDash([]);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Time axis
|
||
|
|
ctx.fillStyle='rgba(200,191,174,0.25)';ctx.font="7px 'JetBrains Mono'";
|
||
|
|
for(let t=0;t<N;t+=100){
|
||
|
|
const x=PAD_L+(t/N)*(W-PAD_L-PAD_R);
|
||
|
|
ctx.fillText('t='+t,x-8,H-4);
|
||
|
|
}
|
||
|
|
ctx.fillText('t →',W-30,H-4);
|
||
|
|
|
||
|
|
// Spectral power analysis (RMS at each scale)
|
||
|
|
const powers=scales.map((s,i)=>{
|
||
|
|
const mn=stats[i].mn;
|
||
|
|
return Math.sqrt(s.reduce((a,v)=>a+(v-mn)**2,0)/N);
|
||
|
|
});
|
||
|
|
const maxP=Math.max(...powers);
|
||
|
|
|
||
|
|
// Mini power spectrum bar in top-right
|
||
|
|
const sbX=W-80,sbY=PAD_T,sbW=60,sbH=40;
|
||
|
|
ctx.strokeStyle='rgba(200,191,174,0.1)';ctx.lineWidth=0.5;
|
||
|
|
ctx.strokeRect(sbX,sbY,sbW,sbH);
|
||
|
|
ctx.fillStyle='rgba(200,191,174,0.15)';ctx.font="6px 'JetBrains Mono'";
|
||
|
|
ctx.fillText('POWER',sbX+16,sbY-2);
|
||
|
|
for(let si=0;si<SCALES.length;si++){
|
||
|
|
const bx=sbX+si*(sbW/SCALES.length)+1;
|
||
|
|
const bh=(powers[si]/maxP)*sbH*0.9;
|
||
|
|
ctx.fillStyle=COLORS[si].replace('0.8','0.7');
|
||
|
|
ctx.fillRect(bx,sbY+sbH-bh,sbW/SCALES.length-2,bh);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Fractal dimension estimate: D = 2 - H
|
||
|
|
const D=(2-hfHurst).toFixed(3);
|
||
|
|
document.getElementById('fd').textContent=D;
|
||
|
|
document.getElementById('sc').textContent=avgCorr.toFixed(3);
|
||
|
|
document.getElementById('hf').textContent=hfHurst.toFixed(3);
|
||
|
|
// Dominant scale: highest power
|
||
|
|
const domIdx=powers.indexOf(Math.max(...powers));
|
||
|
|
document.getElementById('ds').textContent=LABELS[domIdx];
|
||
|
|
</script>
|
||
|
|
</body>
|
||
|
|
</html>
|