1import{a as b,j as e,C as I}from"./index-DXbvyrii.js";import{P as B}from"./playground-CSYyeFEG.js";const $=[{name:"Arm A",probability:.72},{name:"Arm B",probability:.55},{name:"Arm C",probability:.38}];function S(){let t=0,n=0;for(;t===0;)t=Math.random();for(;n===0;)n=Math.random();return Math.sqrt(-2*Math.log(t))*Math.cos(2*Math.PI*n)}function F(t){if(t<1)return F(t+1)*Math.pow(Math.random(),1/t);const n=t-1/3,a=1/Math.sqrt(9*n);for(;;){const o=S();let s=1+a*o;if(s<=0)continue;s**=3;const i=Math.random();if(i<1-.0331*o**4||Math.log(i)<.5*o**2+n*(1-s+Math.log(s)))return n*s}}function T(t,n){const a=F(t),o=F(n);return a/(a+o)}function P({arms:t=$,maxTrials:n=300}={}){const a=t.map(()=>1),o=t.map(()=>1),s=t.map(()=>0),i=Math.max(...t.map(l=>l.probability));let c=0;const d=[{trial:0,alphas:[...a],betas:[...o],pulls:[...s],chosenArm:null,reward:null,cumulativeRegret:c}];for(let l=1;l<=n;l+=1){const m=t.map((N,p)=>T(a[p],o[p])),r=m.indexOf(Math.max(...m)),u=Math.random()<t[r].probability?1:0;s[r]+=1,a[r]+=u,o[r]+=1-u,c+=i-t[r].probability,d.push({trial:l,alphas:[...a],betas:[...o],pulls:[...s],chosenArm:r,reward:u,cumulativeRegret:c})}return d}function v(t){const n=[.9999999999998099,676.5203681218851,-1259.1392167224028,771.3234287776531,-176.6150291621406,12.5073432786869,-.1385710952657201,9984369578019572e-21,15056327351493116e-23];if(t<.5)return Math.log(Math.PI)-Math.log(Math.sin(Math.PI*t))-v(1-t);const a=t-1;let o=n[0];for(let i=1;i<n.length;i+=1)o+=n[i]/(a+i);const s=a+n.length-1.5;return .5*Math.log(2*Math.PI)+(a+.5)*Math.log(s)-s+Math.log(o)}function C(t,n,a=90){const o=v(t)+v(n)-v(t+n);return Array.from({length:a},(s,i)=>{const c=.005+i/(a-1)*.99,d=(t-1)*Math.log(c)+(n-1)*Math.log(1-c)-o;return{x:c,y:Math.exp(d)}})}const R=300,L=55;function E({arm:t,alpha:n,beta:a,pulls:o,selected:s,index:i}){const l={top:8,right:15,bottom:19,left:20},m=470-l.left-l.right,r=92-l.bottom,u=b.useMemo(()=>C(n,a),[n,a]),N=Math.max(...u.map(g=>g.y),1),p=u.map(g=>({x:l.left+g.x*m,y:r-g.y/N*(r-l.top)})),h=p.map((g,y)=>`${y===0?"M":"L"} ${g.x.toFixed(2)} ${g.y.toFixed(2)}`).join(" "),x=`${h} L ${p[p.length-1].x.toFixed(2)} ${r} L ${p[0].x.toFixed(2)} ${r} Z`,f=l.left+t.probability*m,j=n/(n+a),A=l.left+j*m,M=`belief-fill-${i}`;return e.jsxs("article",{className:`belief-row${s?" selected":""}`,children:[e.jsxs("div",{className:"belief-row-header",children:[e.jsxs("div",{children:[e.jsx("strong",{children:t.name}),e.jsxs("span",{children:["Beta(",n,", ",a,")"]})]}),e.jsxs("div",{className:"belief-meta",children:[e.jsxs("span",{children:[o," pulls"]}),e.jsxs("strong",{children:["true p = ",t.probability.toFixed(2)]})]})]}),e.jsxs("svg",{className:"belief-svg",viewBox:"0 0 470 92",role:"img","aria-label":`${t.name} posterior belief with true probability ${t.probability}`,children:[e.jsx("defs",{children:e.jsxs("linearGradient",{id:M,x1:"0",y1:"0",x2:"0",y2:"1",children:[e.jsx("stop",{offset:"0%",stopColor:"#66ccff",stopOpacity:"0.34"}),e.jsx("stop",{offset:"100%",stopColor:"#66ccff",stopOpacity:"0.02"})]})}),[0,.25,.5,.75,1].map(g=>{const y=l.left+g*m;return e.jsxs("g",{children:[e.jsx("line",{x1:y,x2:y,y1:l.top,y2:r,className:"belief-grid"}),e.jsx("text",{x:y,y:85,className:"belief-tick",children:g.toFixed(2).replace("0.",".")})]},g)}),e.jsx("line",{x1:l.left,x2:470-l.right,y1:r,y2:r,className:"belief-axis"}),e.jsx("path",{d:x,fill:`url(#${M})`}),e.jsx("path",{d:h,className:"belief-density"}),e.jsx("line",{x1:f,x2:f,y1:l.top,y2:r,className:"truth-line"}),e.jsx("circle",{cx:A,cy:r,r:"4.5",className:"posterior-mean"})]})]})}function _({history:t,fullHistory:n}){const s={top:28,right:22,bottom:54,left:62},i=640-s.left-s.right,c=430-s.top-s.bottom,d=n[n.length-1].cumulativeRegret,l=Math.max(4,Math.ceil(d/2)*2),m=h=>s.left+h/R*i,r=h=>s.top+c-h/l*c,u=t[t.length-1]??n[0],p=(t.length>0?t:[u]).map((h,x)=>`${x===0?"M":"L"} ${m(h.trial).toFixed(2)} ${r(h.cumulativeRegret).toFixed(2)}`).join(" ");return e.jsxs("svg",{className:"regret-svg",viewBox:"0 0 640 430",role:"img","aria-label":`Cumulative regret after ${u.trial} trials`,children:[[0,75,150,225,300].map(h=>{const x=m(h);return e.jsxs("g",{children:[e.jsx("line",{x1:x,x2:x,y1:s.top,y2:s.top+c,className:"regret-grid"}),e.jsx("text",{x,y:403,className:"regret-tick",children:h})]},h)}),[0,.25,.5,.75,1].map(h=>{const x=l*h,f=r(x);return e.jsxs("g",{children:[e.jsx("line",{x1:s.left,x2:s.left+i,y1:f,y2:f,className:"regret-grid"}),e.jsx("text",{x:s.left-12,y:f,className:"regret-tick regret-y-tick",children:x.toFixed(x<10?1:0)})]},h)}),e.jsx("line",{x1:s.left,x2:s.left+i,y1:s.top+c,y2:s.top+c,className:"regret-axis"}),e.jsx("line",{x1:s.left,x2:s.left,y1:s.top,y2:s.top+c,className:"regret-axis"}),e.jsx("path",{d:p,className:"regret-curve"}),e.jsx("circle",{cx:m(u.trial),cy:r(u.cumulativeRegret),r:"5",className:"regret-endpoint"}),e.jsx("text",{x:s.left+i/2,y:426,className:"regret-label",children:"trials"}),e.jsx("text",{x:"17",y:s.top+c/2,className:"regret-label",transform:`rotate(-90 17 ${s.top+c/2})`,children:"regret"})]})}function H(){const[t,n]=b.useState(()=>P({maxTrials:R})),[a,o]=b.useState(0),[s,i]=b.useState(!1),c=b.useRef(0),d=b.useRef(null),l=b.useRef(0),m=Math.min(Math.max(Number.isFinite(a)?a:0,0),t.length-1),r=t[m]??t[0],u=t.slice(0,m+1);b.useEffect(()=>{if(!s)return;const f=c.current,j=window.performance.now(),A=l.current,M=g=>{if(A!==l.current)return;const y=Math.max(0,Math.floor((g-j)/L)),w=Math.min(Math.max(f+y,0),t.length-1);if(w!==c.current&&(c.current=w,o(w)),w>=t.length-1){d.current=null,i(!1);return}d.current=window.requestAnimationFrame(M)};return d.current=window.requestAnimationFrame(M),()=>{d.current!==null&&(window.cancelAnimationFrame(d.current),d.current=null)}},[s,t.length]);const N=()=>
1{if(s){l.current+=1,d.current!==null&&(window.cancelAnimationFrame(d.current),d.current=null),i(!1);return}a>=t.length-1&&(c.current=0,o(0)),i(!0)},p=()=>{l.current+=1,d.current!==null&&(window.cancelAnimationFrame(d.current),d.current=null),i(!1),c.current=0,o(0),n(P({maxTrials:R}))},h=r.chosenArm===null?"â":$[r.chosenArm].name,x=r.reward===null?"â":r.reward===1?"success":"failure";return e.jsxs("main",{className:"playground-page bandit-page",children:[e.jsx(I,{alwaysHome:!0}),e.jsxs("header",{className:"playground-header",children:[e.jsx(B,{current:2}),e.jsx("h1",{children:"Thompson Sampling"}),e.jsx("h2",{className:"playground-subtitle",children:"Multi-armed bandit"})]}),e.jsxs("section",{className:"bandit-shell",children:[e.jsxs("div",{className:"bandit-status",children:[e.jsxs("div",{className:"bandit-live-metrics","aria-live":"polite",children:[e.jsxs("span",{children:["trial ",e.jsx("strong",{children:r.trial})," / ",R]}),e.jsxs("span",{children:["selected ",e.jsx("strong",{children:h})]}),e.jsxs("span",{children:["outcome ",e.jsx("strong",{children:x})]}),e.jsxs("span",{children:["regret ",e.jsx("strong",{children:r.cumulativeRegret.toFixed(2)})]})]}),e.jsxs("div",{className:"bandit-playback",children:[e.jsx("button",{type:"button",className:"playground-button primary",onClick:N,children:s?"Pause":"Start"}),e.jsx("button",{type:"button",className:"playground-button",onClick:p,children:"Reset"})]})]}),e.jsxs("div",{className:"bandit-panels",children:[e.jsxs("section",{className:"bandit-card beliefs-card",children:[e.jsxs("div",{className:"bandit-card-heading",children:[e.jsxs("div",{children:[e.jsx("p",{className:"panel-label",children:"Posterior beliefs"}),e.jsx("h2",{children:"Bernoulli arms"})]}),e.jsxs("div",{className:"belief-legend",children:[e.jsx("span",{className:"legend-belief",children:"belief"}),e.jsx("span",{className:"legend-truth",children:"ground truth"})]})]}),e.jsx("div",{className:"belief-list",children:$.map((f,j)=>e.jsx(E,{arm:f,alpha:r.alphas[j],beta:r.betas[j],pulls:r.pulls[j],selected:r.chosenArm===j,index:j},f.name))})]}),e.jsxs("section",{className:"bandit-card regret-card",children:[e.jsxs("div",{className:"bandit-card-heading",children:[e.jsxs("div",{children:[e.jsx("p",{className:"panel-label",children:"Performance"}),e.jsx("h2",{children:"Cumulative regret"})]}),e.jsx("span",{className:"regret-value",children:r.cumulativeRegret.toFixed(2)})]}),e.jsx("div",{className:"regret-chart-wrap",children:e.jsx(_,{history:u,fullHistory:t})})]})]})]})]})}export{H as default};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.