Download brain_lab/static/brain-activity-models.js from Chungulus/brain-lab: direct link, hf CLI and curl.
- Browser
- Download file 2.45 kB
-
https://huggingface.co/spaces/Chungulus/brain-lab/resolve/main/brain_lab/static/brain-activity-models.js
- Command line
-
hf download hf://spaces/Chungulus/brain-lab/brain_lab/static/brain-activity-models.js
-
curl -L -o brain-activity-models.js https://huggingface.co/spaces/Chungulus/brain-lab/resolve/main/brain_lab/static/brain-activity-models.js
2.45 kB
| /** Small, deterministic teaching models. No recorded neural or participant data. */ | |
| export class NeuronModel { | |
| constructor(){this.reset()} | |
| reset(){this.t=0;this.v=-65;this.refractory=0;this.spikes=[];this.count=0;this.trace=[{t:0,v:-65,spike:false}];} | |
| pulse(amount=8,{threshold=-50,refractory=4}={}){ | |
| if(this.refractory>0)return false; | |
| this.v+=amount;if(this.v>=threshold){this.count++;this.spikes.push(this.t);this.v=-65;this.refractory=refractory;this.trace.push({t:this.t,v:20,spike:true});} | |
| return true; | |
| } | |
| step(duration,{excitation=18,inhibition=0,threshold=-50,tau=20,refractory=4,pattern='steady'}={}){ | |
| if(!Number.isFinite(duration)||duration<0||duration>10000)throw Error('Choose a simulation interval between 0 and 10,000 ms.'); | |
| if(!(tau>0)||refractory<0||threshold<=-65)throw Error('Invalid neuron settings.'); | |
| const end=this.t+duration; | |
| while(this.t<end-1e-8){const dt=Math.min(.5,end-this.t);let spike=false; | |
| if(this.refractory>0){this.refractory=Math.max(0,this.refractory-dt);this.v=-65;} | |
| else {const input=(pattern==='steady'||this.t%100<40?excitation:0)-inhibition,target=-65+input; | |
| this.v=target+(this.v-target)*Math.exp(-dt/tau); | |
| if(this.v>=threshold){spike=true;this.count++;this.spikes.push(this.t+dt);this.v=-65;this.refractory=refractory;} | |
| } | |
| this.t+=dt;this.trace.push({t:this.t,v:spike?20:this.v,spike}); | |
| } | |
| this.trace=this.trace.filter(row=>row.t>=this.t-1000);this.spikes=this.spikes.filter(t=>t>=this.t-1000); | |
| return this; | |
| } | |
| rate(){const window=Math.min(500,this.t);return window>0?this.spikes.filter(t=>t>this.t-window).length*1000/window:0;} | |
| } | |
| export class AssociationModel { | |
| constructor(){this.reset()} | |
| reset(){this.weights={A:0,B:0};this.history=[];} | |
| trial(cues=['A'],outcome=1,rate=.2){ | |
| if(!Array.isArray(cues)||!cues.length||new Set(cues).size!==cues.length||cues.some(c=>!['A','B'].includes(c)))throw Error('Choose cue A, B, or A + B.'); | |
| if(![0,1].includes(outcome)||!(rate>0&&rate<=.5))throw Error('Invalid learning settings.'); | |
| if(this.history.length>=5000)throw Error('This run has reached 5,000 trials. Reset learning to start another.'); | |
| const prediction=cues.reduce((sum,cue)=>sum+this.weights[cue],0),error=outcome-prediction; | |
| for(const cue of cues)this.weights[cue]+=rate*error; | |
| const row={trial:this.history.length+1,cues:cues.join('+'),outcome,prediction,error,A:this.weights.A,B:this.weights.B,rate};this.history.push(row);return row; | |
| } | |
| } | |