package iterators; import java.io.*; import main.BetterTokenizer; import java.lang.*; import java.util.Vector; import main.Model; import main.Node; import main.Cell; import main.ModelRunner; import affectors.Affector; import parameters.ParameterSet; import main.GeneralInput; import mygraphs.PhaseGraph; import mygraphs.PlotPath; import main.Globals; public class PhasePortraitIterator extends ModelIterator implements Runnable { int cellX = 0, cellY = 0, numPoints = 10; Vector xNodeNames = new Vector(), yNodeNames = new Vector(), paths = new Vector(); String xResultNodeName, yResultNodeName; Node [] xNodes, yNodes; Node xResultNode, yResultNode; float xStart = 0, yStart = 0, xEnd = 1, yEnd = 1; float pathSegmentLength = 0.1f; int numPtsPerPath = 2; // lineScale = 1; // float [] results; // int numResults = 0; final static int LINEAR = 1, LOGARITHMIC = 2; int scaleType = LINEAR; public PhasePortraitIterator() {} // Have a no argument initializer so we can do new_by_name public ModelIterator copy() throws Exception { PhasePortraitIterator newIter = new PhasePortraitIterator(); newIter.init(this.network, this.model); newIter.nParsTV = this.nParsTV; newIter.parsTV = this.parsTV.copy(); newIter.theFunction = this.theFunction.copy(); // Here copy any other variables specific to this subclass. return newIter; } // Put any Iterator parameters specific to this Iterator class in here, as if clauses. protected void loadParameter(String info, BetterTokenizer tokenizer) throws Exception { // A couple examples of parameters that might be loaded here and how to do it. // Replace these with your own parameters if(info.equals("CellX")) { GeneralInput.nextToken(tokenizer); cellX = (int)tokenizer.nval; } else if(info.equals("CellY")) { GeneralInput.nextToken(tokenizer); cellY = (int)tokenizer.nval; } else if(info.equals("XNode")) { GeneralInput.nextToken(tokenizer); xNodeNames.addElement(tokenizer.sval); } else if(info.equals("YNode")) { GeneralInput.nextToken(tokenizer); yNodeNames.addElement(tokenizer.sval); } else if(info.equals("XResultNode")) { GeneralInput.nextToken(tokenizer); xResultNodeName = tokenizer.sval; } else if(info.equals("YResultNode")) { GeneralInput.nextToken(tokenizer); yResultNodeName = tokenizer.sval; } else if(info.equals("NumPoints")) { GeneralInput.nextToken(tokenizer); numPoints = (int)tokenizer.nval; } else if(info.equals("XStart")) { GeneralInput.nextToken(tokenizer); xStart = (float)tokenizer.nval; } else if(info.equals("YStart")) { GeneralInput.nextToken(tokenizer); yStart = (float)tokenizer.nval; } else if(info.equals("XEnd")) { GeneralInput.nextToken(tokenizer); xEnd = (float)tokenizer.nval; } else if(info.equals("YEnd")) { GeneralInput.nextToken(tokenizer); yEnd = (float)tokenizer.nval; } else if(info.equals("PathSegmentLength")) { GeneralInput.nextToken(tokenizer); pathSegmentLength = (float)tokenizer.nval; } else if(info.equals("NumPointsPerPath")) { GeneralInput.nextToken(tokenizer); numPtsPerPath = (int)tokenizer.nval; } /* else if(info.equals("LineScale")) { GeneralInput.nextToken(tokenizer); lineScale = (float)tokenizer.nval; } */ else if(info.equals("ScaleType")) { GeneralInput.nextToken(tokenizer); if(tokenizer.sval.toUpperCase().equals("LOGARITHMIC")) scaleType = LOGARITHMIC; else scaleType = LINEAR; } else if(info.equals("PlotPath")) { GeneralInput.nextToken(tokenizer); paths.addElement(new Float((float)tokenizer.nval)); GeneralInput.nextToken(tokenizer); paths.addElement(new Float((float)tokenizer.nval)); GeneralInput.nextToken(tokenizer); paths.addElement(new Integer((int)tokenizer.nval)); } // Always call super.loadParameter() if it didn't match any of this classes parameters else super.loadParameter(info, tokenizer); } public void doRun() { int i; PhaseGraph pg = null; // Always call reset() before doing anything else. reset(); // results = new float[(numPoints+1)*(numPoints+1)*4]; // numResults = 0; if(Globals.getUsingGUI()) { pg = new PhaseGraph(); pg.setGraphAxes(xStart, yStart, xEnd - xStart, yEnd - yStart); if(scaleType == LINEAR) pg.setScaleType("Linear"); else pg.setScaleType("Logarithmic"); } float start1, start2, end1, end2; Cell cell = model.cells[cellY * model.arrayWidth + cellX]; try { xNodes = new Node[xNodeNames.size()]; for(i = 0; i < xNodeNames.size(); i++) xNodes[i] = cell.getNode((String)xNodeNames.elementAt(i)); yNodes = new Node[yNodeNames.size()]; for(i = 0; i < yNodeNames.size(); i++) yNodes[i] = cell.getNode((String)yNodeNames.elementAt(i)); xResultNode = cell.getNode(xResultNodeName); yResultNode = cell.getNode(yResultNodeName); // Node.setStepNum(0); // Set scales up correctly if logarithmic if(scaleType == LINEAR) start1 = xStart; else start1 = (float)Math.log(xStart); if(scaleType == LINEAR) end1 = xEnd; else end1 = (float)Math.log(xEnd); if(scaleType == LINEAR) start2 = yStart; else start2 = (float)Math.log(yStart); if(scaleType == LINEAR) end2 = yEnd; else end2 = (float)Math.log(yEnd); float incrx = (end1 - start1) / (float)numPoints; float valy = start2; float incry = (end2 - start2) / (float)numPoints; while(valy <= end2) { float valx = start1; while(valx <= end1) { float x, y; if(scaleType == LINEAR) { x = valx; y = valy; } else { x = (float)Math.exp(valx); y = (float)Math.exp(valy); } //PlotPath path = findPath(x, y, pathSegmentLength, numPtsPerPath); PlotPath path = findPath(x, y, pathSegmentLength); if(pg != null) pg.addPath(path); valx += incrx; } valy += incry; } /* this was for my first try with little vectors if(scaleType == LINEAR) { for(i = 0; i < xnodes.length; i++) xnodes[i].setValue(val1); results[numResults*4+0] = val1; results[numResults*4+1] = val2; } else { for(i = 0; i < xnodes.length; i++) xnodes[i].setValue((float)Math.exp(val1)); results[numResults*4+0] = (float)Math.exp(val1); results[numResults*4+1] = (float)Math.exp(val2); } int side; results[numResults*4+2] = 0; for(side = 0; side < x_result_node.numSides; side++) results[numResults*4+2] += x_result_node.getAffectorsValue(side); results[numResults*4+2] *= lineScale; results[numResults*4+3] = 0; for(side = 0; side < y_result_node.numSides; side++) results[numResults*4+3] += y_result_node.getAffectorsValue(side); results[numResults*4+3] *= lineScale; numResults++; } // would have been outside of loop, but now just here for reminder of old ways pg.setPoints(results, numResults); */ if(pg != null) { // Add in extra paths if(paths.size() > 0) { for(int p = 0; p < paths.size() / 3; p++) { float xstart = ((Float)paths.elementAt(p*3+0)).floatValue(); float ystart = ((Float)paths.elementAt(p*3+1)).floatValue(); int num_points = ((Integer)paths.elementAt(p*3+2)).intValue(); pg.addPath(findPath(xstart, ystart, pathSegmentLength, num_points)); } } pg.repaint(); } } catch(Exception e) { System.out.println("PhasePortrait had an error: " + e.toString()); } // After doing your thing, set finalScore equal to the score you want to return. finalScore = 0; // At the end, call stopRun(). super.stopRun(); } private PlotPath findPath(float x, float y, float step_len, float num_steps) { int i, side; PlotPath path = new PlotPath(); path.addPoint(x, y); for(int pt = 0; pt < num_steps; pt++) { for(i = 0; i < xNodes.length; i++) xNodes[i].setValue(x); for(i = 0; i < yNodes.length; i++) yNodes[i].setValue(y); // Move along derivative for(side = 0; side < xResultNode.numSides; side++) x += step_len * xResultNode.getAffectorsValue(side); for(side = 0; side < yResultNode.numSides; side++) y += step_len * yResultNode.getAffectorsValue(side); path.addPoint(x,y); } return path; } /* This version does a psuedo-integration for a given length of time, where it tries to adjust the step sizes to not go too far in any one step. */ private PlotPath findPath(float x, float y, float timelen) { int i, side; PlotPath path = new PlotPath(); float tot_time = 0, timestep; float x_move, y_move; path.addPoint(x, y); while(tot_time < timelen) { for(i = 0; i < xNodes.length; i++) xNodes[i].setValue(x); for(i = 0; i < yNodes.length; i++) yNodes[i].setValue(y); // Move along derivative x_move = 0; y_move = 0; for(side = 0; side < xResultNode.numSides; side++) x_move += xResultNode.getAffectorsValue(side); for(side = 0; side < yResultNode.numSides; side++) y_move += yResultNode.getAffectorsValue(side); float dist = x_move * x_move + y_move * y_move; if(dist == 0) timestep = timelen; else { if(xEnd - xStart < yEnd - yStart) timestep = ((xEnd - xStart) / 1000f) / dist; else timestep = ((yEnd - yStart) / 1000f) / dist; if(tot_time + timestep > timelen) timestep = timelen - tot_time; } x += x_move * timestep; y += y_move *timestep; path.addPoint(x,y); tot_time += timestep; } return path; } /* Old version which ran the model to find the path private float [] findPath(float xstart, float ystart, float runtime) { ModelRunner runner = theFunction.runner; runner.doReset(); for(i = 0; i < xnodes.length; i++) xnodes[i].setValue(xstart); for(i = 0; i < ynodes.length; i++) ynodes[i].setValue(ystart); float [] path = new float[10000]; path[0] = xstart; path[1] = ystart; int path_pos = 1; while(Globals.time < runtime) { runner.doStep(); path[path_pos*2] = xnodes[0].getSum(); path[path_pos*2+1] = ynodes[0].getSum(); // Protect against number that go outside of graph, which can look quite strange // and will especially screw up if plotting logarithmically if(path[path_pos*2] < xStart) path[path_pos*2] = xStart; if(path[path_pos*2+1] < yStart) path[path_pos*2+1] = yStart; path_pos++; } float [] cropped_path = new float[path_pos*2]; System.arraycopy(path, cropped_path, path_pos*2); return cropped_path; } */ }