package stoppers; import java.lang.*; import java.io.*; import main.BetterTokenizer; import main.Cell; import main.GeneralInput; import main.Model; public class TwoCellDifferenceStop 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; final static private int THRESHOLDS = 0, ABSOLUTE_DIFFERENCE = 1, MULTIPLICATIVE_DIFFERENCE = 2; int mode = THRESHOLDS; float interval; int xPosLow, yPosLow, xPosHigh, yPosHigh; float lastScoreTime = 0; float fadeAvg = 0; float averagingTime = 10; float lastHighVal, lastLowVal; float punishSlope = 10; // No arg constructor for instantiating by name public TwoCellDifferenceStop() { this(1); } public TwoCellDifferenceStop(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 < lastTime + interval) return false; if(time > stopTime) return true; float timestep_score = 0; float low_val = model.cells[yPosLow * model.arrayWidth + xPosLow].getValue(nodeNum); float high_val = model.cells[yPosHigh * model.arrayWidth + xPosHigh].getValue(nodeNum); float temp = (time - lastTime) / averagingTime; if(temp > 1) temp = 1; fadeAvg -= fadeAvg * temp; // Add in pattern scoring and stability scoring // In this stability scoring attempt, I am only punishing movement away from a good solution, not // movement towards a good solution if(mode == THRESHOLDS) { if(high_val < highThreshold) fadeAvg += (highThreshold - high_val) * punishSlope * temp; if(low_val > lowThreshold) fadeAvg += (low_val - lowThreshold) * punishSlope * temp; // Stability scoring if(high_val < lastHighVal) fadeAvg += (lastHighVal - high_val) * punishSlope * temp; if(low_val > lastLowVal) fadeAvg += (low_val - lastLowVal) * punishSlope * temp; } else if(mode == ABSOLUTE_DIFFERENCE) { } else if(mode == MULTIPLICATIVE_DIFFERENCE) { } lastHighVal = high_val; lastLowVal = low_val; 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; float low_val = model.cells[yPosLow * model.arrayWidth + xPosLow].getValue(nodeNum); float high_val = model.cells[yPosHigh * model.arrayWidth + xPosHigh].getValue(nodeNum); if(mode == THRESHOLDS) { if(low_val > lowThreshold || high_val < highThreshold) return false; } else if(mode == ABSOLUTE_DIFFERENCE) { if(high_val - low_val < lowThreshold) return false; } else if(mode == MULTIPLICATIVE_DIFFERENCE) { if(low_val > 0 && high_val / low_val < lowThreshold) return false; else if(high_val <= 0) return false; } return true; } public void reset() { score = 0; lastScoreTime = 0; fadeAvg = 0; super.reset(); } 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("LowCellXPos")) { GeneralInput.nextToken(tokenizer); xPosLow = ((int)tokenizer.nval); } else if(info.equals("LowCellYPos")) { GeneralInput.nextToken(tokenizer); yPosLow = ((int)tokenizer.nval); } else if(info.equals("HighCellXPos")) { GeneralInput.nextToken(tokenizer); xPosHigh = ((int)tokenizer.nval); } else if(info.equals("HighCellYPos")) { GeneralInput.nextToken(tokenizer); yPosHigh = ((int)tokenizer.nval); } else if(info.equals("LowThreshold")) { GeneralInput.nextToken(tokenizer); lowThreshold = ((float)tokenizer.nval); } else if(info.equals("Threshold")) { 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 if(info.equals("Mode")) { GeneralInput.nextToken(tokenizer); if(tokenizer.sval.equals("Thresholds")) mode = THRESHOLDS; else if(tokenizer.sval.equals("Absolute")) mode = ABSOLUTE_DIFFERENCE; else if(tokenizer.sval.equals("Multiplicative")) mode = MULTIPLICATIVE_DIFFERENCE; else System.out.println("Unrecognized mode <" + tokenizer.sval +"> in TwoCellDifferenceStop"); } else super.loadParameter(info,tokenizer); } }