package affectors; import main.Node; import main.Globals; /** Adds white noise to the concentration of a node. The noise is chosen from a flat distribution that goes from + to - the noiseLevelParam

Formula
dnodex/dt = noise_level * [random white noise generation between -1 and 1]

Parameters
Noise level [NoiseLevel] The amount of white noise. Should be less than 1

Usage
&nodex

&WhiteNoiseAff noise_nodex
&endnodex */ public class WhiteNoiseAff extends Affector { /** The affector picks a new random number from a flat distribution between -noiseLevel and +noiseLevel for each timestep of the model */ final static int NUM_STORED = 100; int noiseLevelParam; float lastNoiseLevel; float [] noise = new float[NUM_STORED]; int curTime; static final String desc = "Adds noise from a flat distribution."; static final String [] paramDescriptions = {"Amount of noise"}; public WhiteNoiseAff() { } protected void setLabelsAndTypes() { setDescriptions(this.desc, null, paramDescriptions); this.Type[GUI_CAPABLE] = 1; this.Type[CERTIFICATION] = Affector.RETURNS_DERIV; this.Type[MATHTYPE] = Affector.TT; this.Type[TERMTYPE] = Affector.CONVERSION; // Doesn't really fit any of them } public void setParameterNumbers(int [] param_nums) { noiseLevelParam = param_nums[0]; } public float getValue(Node which_node) { if(params[noiseLevelParam] == 0) return 0.0f; // Don't waste time when turned off int t = (int)(Globals.time) % NUM_STORED; int t2 = t + 1; if(t2 >= NUM_STORED) t2 -= NUM_STORED; float val = (noise[t2] - noise[t]) * (Globals.time - (float)Math.floor(Globals.time)) + noise[t]; // A bunch of code to keep putting new random numbers into the array as models run and reset if(curTime > (int)Globals.time) curTime = (int)Globals.time; if(lastNoiseLevel != params[noiseLevelParam]) { // noise level changed so need to add noise for(curTime = 0; curTime < NUM_STORED; curTime++) noise[curTime] = ((float)Math.random() * 2f - 1.0f) * params[noiseLevelParam]; curTime = (int)Globals.time; } // Update the stored numbers if((int)Globals.time > curTime) { t = curTime % NUM_STORED; while(curTime < (int)Globals.time) { noise[t] = ((float)Math.random() * 2 - 1.0f) * params[noiseLevelParam]; curTime++; t++; if(t == NUM_STORED) t = 0; } } return val; } }