package stoppers; import java.lang.*; import java.io.*; import main.BetterTokenizer; import main.Cell; import main.GeneralInput; import main.Model; public class NeuroTest3Stop extends SimpleStop { int nodeNum; /** The threshold below which the concentration of a node is considered 0. This is used to say whether a cell has switched low. */ float lowThreshold; /** The threshold above which the concentration of a node is considered 1. This is used to say whether a cell has switched high. */ float highThreshold; float interval; int firstGoodRow, lastGoodRow, numSkippedRows, thresholdRow; float lastScoreTime = 0; float fadeAvg = 0; float averagingTime = 10; float lastHighVal1, lastHighVal2, lastLowVal1, lastLowVal2; float punishSlope = 10; // No arg constructor for instantiating by name public NeuroTest3Stop() { this(1); } public NeuroTest3Stop(float stop_time) { stopTime = stop_time; } public void init(Model model) { super.init(model); score = 0; } public boolean stop(float time) { // trivial reasons to return if(time > stopTime) return true; if(time < lastTime + interval) return false; // The following code assumes that each row of cells contains a low cell second // from the left and a high cell third from left, and then another low / high // pair at cells 5 and 6 in the row. firstGoodRow = lastGoodRow = -1; numSkippedRows = 0; thresholdRow = -1; float timestep_score = 0; int cell_num = model.arrayWidth; // Cells of interest are on second row float low_val1 = model.cells[cell_num + 1].getValue(nodeNum); float high_val1 = model.cells[cell_num + 2].getValue(nodeNum); float low_val2 = model.cells[cell_num + 4].getValue(nodeNum); float high_val2 = model.cells[cell_num + 5].getValue(nodeNum); float temp = (time - lastTime) / averagingTime; if(temp > 1) temp = 1; fadeAvg -= fadeAvg * temp; // Add in pattern scoring if(high_val1 < highThreshold) fadeAvg += (highThreshold - high_val1) * punishSlope * temp; if(high_val2 < highThreshold) fadeAvg += (highThreshold - high_val2) * punishSlope * temp; if(low_val1 > lowThreshold) fadeAvg += (low_val1 - lowThreshold) * punishSlope * temp; if(low_val2 > lowThreshold) fadeAvg += (low_val2 - lowThreshold) * punishSlope * temp; // Add in stability scoring // In this attempt, I am only punishing movement away from a good solution, not // movement towards a good solution if(high_val1 < lastHighVal1) fadeAvg += (lastHighVal1 - high_val1) * punishSlope * temp; if(high_val2 < lastHighVal2) fadeAvg += (lastHighVal2 - high_val2) * punishSlope * temp; if(low_val1 > lastLowVal1) fadeAvg += (low_val1 - lastLowVal1) * punishSlope * temp; if(low_val2 > lastLowVal2) fadeAvg += (low_val2 - lastLowVal2) * punishSlope * temp; /* pre-Apr 18 stability scoring fadeAvg += Math.abs(lastHighVal1 - high_val1) / averagingTime; fadeAvg += Math.abs(lastHighVal2 - high_val2) / averagingTime; */ lastHighVal1 = high_val1; lastHighVal2 = high_val2; lastLowVal1 = low_val1; lastLowVal2 = low_val2; /* timestep_score += (1 - (high_val1 - low_val1)) / (model.arrayHeight / 2); timestep_score += (1 - (high_val2 - low_val2)) / (model.arrayHeight / 2); score *= lastScoreTime; score += (time - lastScoreTime) * timestep_score; score /= time; if(score < 0) { score = score; } lastScoreTime = time; */ score = fadeAvg; lastTime = time; return false; // Only stop when run out of time } public boolean didPass(float s) { return didPass(); } public boolean didPass() { if(score < Cutoff) return true; int cell_num = model.arrayWidth; float low_val1 = model.cells[cell_num + 1].getValue(nodeNum); float high_val1 = model.cells[cell_num + 2].getValue(nodeNum); float low_val2 = model.cells[cell_num + 4].getValue(nodeNum); float high_val2 = model.cells[cell_num + 5].getValue(nodeNum); if(low_val1 > lowThreshold || high_val1 < highThreshold || low_val2 > lowThreshold || high_val2 < highThreshold) return false; return true; } public void reset() { score = 0; lastScoreTime = 0; fadeAvg = 0; super.reset(); } public void saveOutputTags(PrintWriter ps, String inset) { super.saveOutputTags(ps, inset); ps.println(inset + "&FirstGoodRow\tnumber"); ps.println(inset + "&LastGoodRow\tnumber"); ps.println(inset + "&NumSkippedRows\tnumber"); ps.println(inset + "&ThresholdRow\tnumber"); } public void saveOutput(PrintWriter ps, String inset) { super.saveOutput(ps, inset); ps.println(inset + "&FirstGoodRow\t" + firstGoodRow); ps.println(inset + "&LastGoodRow\t" + lastGoodRow); ps.println(inset + "&NumSkippedRows\t" + numSkippedRows); ps.println(inset + "&ThresholdRow\t" + thresholdRow); } protected void loadParameter(String info, BetterTokenizer tokenizer) throws Exception { if(info.equals("Node")) { GeneralInput.nextToken(tokenizer); nodeNum = model.cells[0].getNodeNum(tokenizer.sval); } else if(info.equals("LowThreshold")) { GeneralInput.nextToken(tokenizer); lowThreshold = ((float)tokenizer.nval); } else if(info.equals("HighThreshold")) { GeneralInput.nextToken(tokenizer); highThreshold = ((float)tokenizer.nval); } else if(info.equals("AveragingTime")) { GeneralInput.nextToken(tokenizer); averagingTime = ((float)tokenizer.nval); } else if(info.equals("PunishSlope")) { GeneralInput.nextToken(tokenizer); punishSlope = ((float)tokenizer.nval); } else if(info.equals("Interval")) { GeneralInput.nextToken(tokenizer); interval = ((float)tokenizer.nval); } else super.loadParameter(info,tokenizer); } }