/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package jgrow; import java.util.Random; /** * * @author maryam */ public class Simulator { int [] state; int cycle=0; double time; double previousTime=-1; int population = 0, previousPopulation; InfoTiles tiles; InfoBonds bonds; PanelInformation info; double totalk, totalConc; double ConstantK = 1000000; double eGmc=1, Gse=1; int pickedIndex, xMask; double mark1, mark2; Random rand; boolean isStability = false; // SimCell lastCell; int boardSize, bufferSize; int boardDim; int numBonds, numTiles; SimNode baseNode; SimCell []simCellMatrix; double []bondMatrix; int [] sim_sn; int [] sim_se; int [] sim_ss; int [] sim_sw; int [] colors; double [] conc; int labelIndex = 0; PairList basePair, currentPair; GraphAdjacency []graphLabels; boolean []graphVisited; int seedX,seedY; public Simulator(int b, int[] s, InfoTiles ts, InfoBonds bs, PanelInformation inf) { boardSize = b; bufferSize = b*b; state = s; tiles = ts; bonds = bs; info = inf; updateVars(); switch(boardSize) { case 256: boardDim = 8; xMask = 0x000000FF; break; case 512: boardDim = 9; xMask = 0x000001FF; break; case 1024: boardDim = 10; xMask = 0x000003FF; break; default: System.out.println("not ready for such input"); } simCellMatrix = new SimCell[bufferSize]; for(int i=0; i<bufferSize; i++) { simCellMatrix[i] = new SimCell(); } baseNode = sim_generateNodes(null,boardDim, 0); rand = new Random(); } public void setStability(boolean st) { isStability = st; presentState(); } public String infoBoard(int x, int y) { String out = ""; int tileType; //out += "tile: "+simCellMatrix[y*boardSize+x].tile+"\n"; out += "Koff = "+ simCellMatrix[y*boardSize+x].node.koff; out += " / Kon = "+ simCellMatrix[y*boardSize+x].node.kon; if( (tileType = simCellMatrix[y*boardSize+x].tile) >= 0) { out += " (Tile type: "+tiles.names[tileType]+")"; } else { out+= " Empty"; } out += "["+x+","+y+"]"; printProbability(simCellMatrix[y*boardSize+x].node); return out; } /* private void colorSubTree(SimNode in, int c) { if(in.p0 == null) { state[in.index] = 255; } else { colorSubTree(in.p0,c); colorSubTree(in.p1,c); colorSubTree(in.p2,c); colorSubTree(in.p3,c); } } */ public void updateVars() { bondMatrix = bonds.bondMatrix; numBonds = bonds.size(); Gse = bonds.gse; numTiles = tiles.size(); sim_sn = tiles.north; sim_se = tiles.east; sim_ss = tiles.south; sim_sw = tiles.west; colors = tiles.colors; conc = tiles.concs; eGmc = Math.exp(-tiles.gmc); } public int pickTile() { double totalTilesConc = 0; double pickingATile; for(int i=0; i<numTiles; i++) { totalTilesConc += conc[i]; } pickingATile = totalTilesConc*rand.nextDouble(); totalTilesConc = 0; int j = -1; while(totalTilesConc < pickingATile) { totalTilesConc += conc[++j]; } return j; } public void onlyGrow() { double totalk = (baseNode.p0.kon + baseNode.p1.kon + baseNode.p2.kon + baseNode.p3.kon)*totalConc; time += 1-Math.exp(-(rand.nextDouble()/totalk)/ConstantK); /// pick a transition SimNode pickedNode; do { pickedNode = pickGrowActionNode(baseNode); //pickedNode = pickNode( baseNode, rand.nextDouble()*totalk,boardDim); //System.out.println("picking node"); } while(pickedNode == null); sim_put_tile(pickedNode.index &xMask,pickedNode.index >>boardDim,pickTile()); } public void nextRound() { //System.out.println("next round:"+population); if(numTiles == 0 || population == 0) return; if(cycle % 20000 == 0) { previousTime = time; previousPopulation = population; } for(int j=0; j<10000; j++) { totalConc = 0; for(int i=0; i<numTiles; i++) { totalConc += conc[i]; } totalConc *= eGmc; if(totalConc == 0) return; if(population == 1) { onlyGrow(); cycle++; } totalk = baseNode.p0.koff + baseNode.p1.koff + baseNode.p2.koff + baseNode.p3.koff + (baseNode.p0.kon + baseNode.p1.kon + baseNode.p2.kon + baseNode.p3.kon)*totalConc; /// calculate time advance per cycle // propagate time change //dt = -log(drand48())/sum; //before it was wrong: time += 1-Math.exp(-(rand.nextDouble()/totalk)/ConstantK); time += -Math.log(rand.nextDouble())/(ConstantK*totalk); /// pick a transition SimNode pickedNode; do { pickedNode = pickActionNode(baseNode); //pickedNode = pickNode( baseNode, rand.nextDouble()*totalk,boardDim); //System.out.println("picking node"); } while(pickedNode == null); pickedIndex = pickedNode.index; //int tTile; //if((tTile = simCellMatrix[pickedIndex].tile) >= 0) { if((simCellMatrix[pickedIndex].tile) >= 0) { // if transition is koff, remove //System.out.println("take pickedIndex = "+pickedIndex); //System.out.println("take "+(pickedIndex&xMask)+","+(pickedIndex>>boardDim)); //int px,py; // sim_take_tile(px = pickedIndex&xMask,py = pickedIndex>>boardDim); sim_take_tile(pickedIndex&xMask,pickedIndex>>boardDim); //System.out.println("after: "+infoBoard(pickedIndex&xMask,pickedIndex>>boardDim)); /* if( px>0 && simCellMatrix[pickedIndex-1].tile >= 0 && bondMatrix[sim_sw[tTile]*numBonds+sim_se[simCellMatrix[pickedIndex-1].tile]] > 0 ) { //////////////////////////////////////////////////// sim_prepareNodesForLabeling(baseNode, boardDim); labelIndex = 0; basePair = new PairList(0,0); currentPair = basePair; trimBoard(baseNode); graphLabels = new GraphAdjacency[labelIndex]; graphVisited = new boolean[labelIndex]; for(int i=0; i<labelIndex; i++) { graphLabels[i] = new GraphAdjacency(i); graphVisited[i] = false; } currentPair = basePair.next; while(currentPair != null) { graphLabels[currentPair.x].add(currentPair.y); graphLabels[currentPair.y].add(currentPair.x); currentPair = currentPair.next; } doEquivalentLabels(); labelIndex = graphLabels[simCellMatrix[seedY*boardSize+seedX].label].y; trimAllBoard(baseNode); //////////////////////////////////////////// } /// */ } else { // if transition is kon, pick a tile to place //System.out.println("put "+(pickedIndex&xMask)+","+(pickedIndex>>boardDim)); sim_put_tile(pickedIndex&xMask,pickedIndex>>boardDim,pickTile()); //System.out.println("after: "+infoBoard(pickedIndex&xMask,pickedIndex>>boardDim)); //System.out.println("lastCell.tile"+lastCell.tile); } cycle++; //if(cycle%600 == 0) correctKoff(baseNode); } presentState(); } /* public void nextCycle() { //System.out.println("next cycle"); //// do the transition totalConc = 0; for(int i=0; i<numTiles; i++) { totalConc += conc[i]; } if(totalConc == 0) return; totalk = baseNode.p0.koff + baseNode.p1.koff + baseNode.p2.koff + baseNode.p3.koff + (baseNode.p0.kon + baseNode.p1.kon + baseNode.p2.kon + baseNode.p3.kon)*totalConc; /// calculate time advance per cycle // propagate time change time += 1-Math.exp(-(rand.nextDouble()/totalk)/ConstantK); /// pick a transition SimNode pickedNode; do { pickedNode = pickActionNode(baseNode); //pickedNode = pickNode( baseNode, rand.nextDouble()*totalk,boardDim); } while(pickedNode == null); pickedIndex = pickedNode.index; if(simCellMatrix[pickedIndex].tile >= 0) { // if transition is koff, remove //System.out.println("take pickedIndex = "+pickedIndex); //System.out.println("take "+(pickedIndex&xMask)+","+(pickedIndex>>boardDim)); sim_take_tile(pickedIndex&xMask,pickedIndex>>boardDim); //System.out.println("after: "+infoBoard(pickedIndex&xMask,pickedIndex>>boardDim)); } else { // if transition is kon, pick a tile to place //System.out.println("put "+(pickedIndex&xMask)+","+(pickedIndex>>boardDim)); sim_put_tile(pickedIndex&xMask,pickedIndex>>boardDim,rand.nextInt(numTiles)); //System.out.println("after: "+infoBoard(pickedIndex&xMask,pickedIndex>>boardDim)); //System.out.println("lastCell.tile"+lastCell.tile); } cycle++; ///////////////////////////////////////////////////// sim_prepareNodesForLabeling(baseNode, boardDim); labelIndex = 0; basePair = new PairList(0,0); currentPair = basePair; trimBoard(baseNode); graphLabels = new GraphAdjacency[labelIndex]; graphVisited = new boolean[labelIndex]; for(int i=0; i<labelIndex; i++) { graphLabels[i] = new GraphAdjacency(i); graphVisited[i] = false; } currentPair = basePair.next; while(currentPair != null) { graphLabels[currentPair.x].add(currentPair.y); graphLabels[currentPair.y].add(currentPair.x); currentPair = currentPair.next; } doEquivalentLabels(); labelIndex = graphLabels[simCellMatrix[seedY*boardSize+seedX].label].y; trimAllBoard(baseNode); //////////////////////////////////////////////////// //if(cycle%30 == 0) correctKoff(baseNode); //colorSubTree(baseNode.p2,255); //colorSubTree(baseNode.p2.p0,255); //colorSubTree(baseNode.p2.p0.p1,255*256*256); } */ private void doEquivalentLabels() { for(int i=0; i<labelIndex; i++) { dfsVisit(i,graphLabels[i].y); } } private void dfsVisit(int vertex, int withLabel) { if(graphVisited[vertex]) return; //System.out.println("visiting "+vertex+", and label was "+graphLabels[vertex].y); graphLabels[vertex].y = withLabel; graphVisited[vertex] = true; GraphAdjacency temp = graphLabels[vertex]; while( (temp = temp.next) != null) { dfsVisit(temp.y, withLabel); } } /* private boolean isNonSeedLabeled(int yy) { GraphAdjacency current = currentIsSeedLabeled; do { if(current.y == yy) return false; if(current.next == null) { return true; } } while( (current = current.next) != null); return true; } */ private void trimAllBoard(SimNode in) { if(in.tilesCovered == 0) return; if(in.p0 != null) { trimAllBoard(in.p0); trimAllBoard(in.p1); trimAllBoard(in.p2); trimAllBoard(in.p3); } else { int indexNow = in.index; //System.out.println("index -> "+indexNow); if(labelIndex != graphLabels[simCellMatrix[indexNow].label].y) { //System.out.println(">> new guy: ["+simCellMatrix[indexNow].label+",but "+labelIndex+"] on cell "+(indexNow%boardSize)+","+(indexNow>>boardDim)); sim_take_tile(indexNow%boardSize,indexNow>>boardDim); } } } private void trimBoard(SimNode in) { if(in.tilesCovered == 0) return; if(in.p0 != null) { trimBoard(in.p0); trimBoard(in.p1); trimBoard(in.p2); trimBoard(in.p3); } else { int indexNow = in.index; int xNow = indexNow%boardSize, yNow = indexNow>>boardDim; SimCell temp = simCellMatrix[indexNow]; int currentLabel; if(temp.unlabeled) { temp.unlabeled = false; currentLabel = labelIndex; temp.label = labelIndex++; } else { currentLabel = temp.label; } //System.out.println("Checking man"+(xNow)+","+(yNow)); int tileType = temp.tile; //each neighbor if(xNow>0 && simCellMatrix[indexNow-1].tile >= 0 && bondMatrix[sim_sw[tileType]*numBonds+sim_se[simCellMatrix[indexNow-1].tile]] > 0) { //System.out.println("Checking "+(xNow-1)+","+(yNow)+"..............."+simCellMatrix[indexNow-1].unlabeled); if(simCellMatrix[indexNow-1].unlabeled) { simCellMatrix[indexNow-1].unlabeled = false; simCellMatrix[indexNow-1].label = currentLabel; } else { currentPair = currentPair.add(currentLabel,simCellMatrix[indexNow-1].label); } } if(xNow<boardSize-1 && simCellMatrix[indexNow+1].tile >= 0 && bondMatrix[sim_se[tileType]*numBonds+sim_sw[simCellMatrix[indexNow+1].tile]] > 0) { if(simCellMatrix[indexNow+1].unlabeled) { simCellMatrix[indexNow+1].unlabeled = false; simCellMatrix[indexNow+1].label = currentLabel; } else { currentPair = currentPair.add(currentLabel,simCellMatrix[indexNow+1].label); } } if(yNow>0 && simCellMatrix[indexNow-boardSize].tile >= 0 && bondMatrix[sim_sn[tileType]*numBonds+sim_ss[simCellMatrix[indexNow-boardSize].tile]] > 0) { if(simCellMatrix[indexNow-boardSize].unlabeled) { simCellMatrix[indexNow-boardSize].unlabeled = false; simCellMatrix[indexNow-boardSize].label = currentLabel; } else { currentPair = currentPair.add(currentLabel,simCellMatrix[indexNow-boardSize].label); } } if(yNow<boardSize-1 && simCellMatrix[indexNow+boardSize].tile >= 0 && bondMatrix[sim_ss[tileType]*numBonds+sim_sn[simCellMatrix[indexNow+boardSize].tile]] > 0) { if(simCellMatrix[indexNow+boardSize].unlabeled) { simCellMatrix[indexNow+boardSize].unlabeled = false; simCellMatrix[indexNow+boardSize].label = currentLabel; } else { currentPair = currentPair.add(currentLabel,simCellMatrix[indexNow+boardSize].label); } } } /* how much load is okay? int [] temp = new int[bufferSize]; for(int i=0; i<bufferSize; i++) { temp[i] = state[i]; temp[i] = i*temp[i]; temp[i] = state[i]; } for(int i=0; i<bufferSize; i++) { temp[i] = state[i]; temp[i] = i*temp[i]; temp[i] = state[i]; } */ } private void sim_prepareNodesForLabeling(SimNode p, int level) { if(p.tilesCovered == 0) return; if(level > 0) { sim_prepareNodesForLabeling(p.p0,level-1); sim_prepareNodesForLabeling(p.p1,level-1); sim_prepareNodesForLabeling(p.p2,level-1); sim_prepareNodesForLabeling(p.p3,level-1); return; } else if(level == 0) { simCellMatrix[p.index].unlabeled = true; return; } } private void printProbability(SimNode in) { totalConc = 0; for(int i=0; i<numTiles; i++) { totalConc += conc[i]; } totalConc *= eGmc; /////////////////////////////////////////////////// if(in != baseNode) { double tot = in.parent.koff + in.parent.kon*totalConc; double pot = in.tilesCovered > 0 ? in.koff : in.kon*totalConc; System.out.println(">"+pot+"/"+tot+" :"+in.tilesCovered); printProbability(in.parent); } } private SimNode pickActionNode(SimNode p) { if(p.p0 == null) return p; double totalk = p.koff + p.kon*totalConc; double dir = rand.nextDouble()*totalk; //System.out.println("totalk "+totalk); double mark = p.p0.koff + p.p0.kon*totalConc;//*eGmc; if(dir < mark) { //System.out.println("rand -> "+dir+" \nwith ["+mark+"]"); return pickActionNode(p.p0); } else if(dir < (mark += p.p1.koff + p.p1.kon*totalConc) ) { //*eGmc) ){ //System.out.println("rand -> "+dir+" \nwith ["+mark+"]"); return pickActionNode(p.p1); } else if(dir < (mark += p.p2.koff + p.p2.kon*totalConc) ) { //*eGmc) ){ //System.out.println("rand -> "+dir+" \nwith ["+mark+"]"); return pickActionNode(p.p2); } else if(dir < (mark += p.p3.koff + p.p3.kon*totalConc) ) { //*eGmc) ){ //System.out.println("rand -> "+dir+" \nwith ["+mark+"]"); return pickActionNode(p.p3); } else { //System.out.println("total p "+mark+"\n..koff.."+p.koff+"="+(p.p0.koff+p.p1.koff+p.p2.koff+p.p3.koff)+"\n..kon.."+p.kon+"="+(p.p0.kon+p.p1.kon+p.p2.kon+p.p3.kon+"\nx,y->"+p.p0.index+","+p.p1.index)); return null; } } private SimNode pickGrowActionNode(SimNode p) { if(p.p0 == null) return p; double totalk = p.kon*totalConc; double dir = rand.nextDouble()*totalk; //System.out.println("totalk "+totalk); double mark = p.p0.kon*totalConc;//*eGmc; if(dir < mark) { //System.out.println("rand -> "+dir+" \nwith ["+mark+"]"); return pickGrowActionNode(p.p0); } else if(dir < (mark += p.p1.kon*totalConc) ) { //*eGmc) ){ //System.out.println("rand -> "+dir+" \nwith ["+mark+"]"); return pickGrowActionNode(p.p1); } else if(dir < (mark += p.p2.kon*totalConc) ) { //*eGmc) ){ //System.out.println("rand -> "+dir+" \nwith ["+mark+"]"); return pickGrowActionNode(p.p2); } else if(dir < (mark += p.p3.kon*totalConc) ) { //*eGmc) ){ //System.out.println("rand -> "+dir+" \nwith ["+mark+"]"); return pickGrowActionNode(p.p3); } else { //System.out.println("total p "+mark+"\n..koff.."+p.koff+"="+(p.p0.koff+p.p1.koff+p.p2.koff+p.p3.koff)+"\n..kon.."+p.kon+"="+(p.p0.kon+p.p1.kon+p.p2.kon+p.p3.kon+"\nx,y->"+p.p0.index+","+p.p1.index)); return null; } } private double correctKoff(SimNode p) { if(p.tilesCovered == 0) { p.koff = 0; return 0; } //System.out.println(""+p.koff+">"+p.p0); if(p.p0 == null) return p.koff; //double oldval = p.koff; p.koff = correctKoff(p.p0) + correctKoff(p.p1) + correctKoff(p.p2) + correctKoff(p.p3); //if(oldval != p.koff) { // System.out.println("old p.koff = "+oldval+" and sum = "+p.koff); //} return p.koff; } // pick node based on random number private SimNode pickNode(SimNode p, double remaining, int level) { //System.out.println("Level: "+level+"\tremaining: "+remaining); mark1 = p.p0.kon*totalConc+p.p0.koff; //System.out.println("mark1: "+mark1+"\tp.p0.kon"+p.p0.kon+"\ttotalConc"+totalConc+"p.p0.koff"+p.p0.koff); if(remaining < mark1) { if(level == 1) return p.p0; if(remaining <= 0) return null; //pickNode(p.p0,(remaining+mark1)/2,--level); return pickNode(p.p0,remaining,--level); } else if(remaining < (mark2 = mark1 + p.p1.kon*totalConc+p.p1.koff)){ if(level == 1) return p.p1; if(remaining == mark1) return null; //pickNode(p.p1,(remaining+mark2)/2,--level); return pickNode(p.p1,remaining-mark1,--level); } else if(remaining < (mark1 = mark2 + p.p2.kon*totalConc+p.p2.koff)){ if(level == 1) return p.p2; if(remaining == mark2) return null; //pickNode(p.p2,(remaining+mark1)/2,--level); return pickNode(p.p2,remaining-mark2,--level); } else if(remaining < (mark2 = mark1 + p.p3.kon*totalConc+p.p3.koff)){ if(level == 1) return p.p3; if(remaining == mark1) return null; //pickNode(p.p3,(remaining+mark2)/2,--level); return pickNode(p.p3,remaining-mark1,--level); } else { if(level == 1) return p.p3; return null; //pickNode(p.p3,(mark2+mark1)/2,--level); } } //only presents the current status public void presentState() { /* if(isStability) { int tileType; for(int i=0; i<bufferSize; i++) { if( (tileType = simCellMatrix[i].tile) >= 0) { double tempKoff = simCellMatrix[i].node.koff; if(tempKoff < 0.002) { state[i] = 200+(int)(tempKoff*2500); } else if(tempKoff < 0.018) { state[i] = 120+(int)((tempKoff-0.002)*8125); } else { state[i] = (int)((tempKoff-0.018)*122.2); } } else { state[i] = 0; } } */ if(isStability) { //int tileType; for(int i=0; i<bufferSize; i++) { //if( (tileType = simCellMatrix[i].tile) >= 0) { if( (simCellMatrix[i].tile) >= 0) { double tempKoff = -Math.log( simCellMatrix[i].node.koff)/tiles.gmc; if(tempKoff > 2) { state[i] = 255; } else if(tempKoff > 1) { state[i] = 150 + (int)((tempKoff-1)*55); } else { state[i] = (int)(tempKoff*150); } } else { state[i] = 0; } } } else { int tileType; for(int i=0; i<bufferSize; i++) { if( (tileType = simCellMatrix[i].tile) >= 0) { state[i] = colors[tileType]; } else { state[i] = 0; } } } info.setStats(population, time, cycle, 1000*(((double)(population-previousPopulation))/(time-previousTime))); } public void placeSeedTile(int x, int y, int se) { if(simCellMatrix[y*boardSize+x].tile >= 0) { sim_take_tile(x,y); } if(population == 0) { seedX = x; seedY = y; } else if(seedX == x && seedY == y) { return; } sim_put_tile(x,y,se); presentState(); } public void removeSeedTile(int x, int y) { //System.out.println("els -> "+colors.length ); if(simCellMatrix[y*boardSize+x].tile >= 0) { sim_take_tile(x,y); presentState(); } } public boolean hasTile(int x,int y) { return simCellMatrix[y*boardSize+x].tile >= 0; } ///////////////////////////////////////////// // generate the seed tile structure deterministically private SimNode sim_generateNodes(SimNode p, int level, int index) { SimNode bnode; if(level > 0) { bnode = new SimNode(); bnode.p0 = sim_generateNodes(bnode,level-1, (int)(index+Math.pow(2,level-1))); bnode.p1 = sim_generateNodes(bnode,level-1, index); bnode.p2 = sim_generateNodes(bnode,level-1, (int)(index+Math.pow(2,level+boardDim-1))); bnode.p3 = sim_generateNodes(bnode,level-1, (int)(index+Math.pow(2,level+boardDim-1) +Math.pow(2,level-1))); bnode.parent = p; bnode.kon = 0; bnode.koff = 0; return bnode; } else if(level == 0) { bnode = new SimNode(); bnode.p0 = null; bnode.p1 = null; bnode.p2 = null; bnode.p3 = null; bnode.parent = p; bnode.kon = 0; bnode.koff = 0; bnode.index = index; simCellMatrix[index].node = bnode; simCellMatrix[index].tile = -1; return bnode; } else return null; //shouldn't even happen } // a new tile was added to one of its successors' without tile and not available before public void sim_goParentIncrementOn(SimNode in) { if(in == null) return; in.kon = in.kon + 1; sim_goParentIncrementOn(in.parent); return; } // a tile was removed from one of its successors' without neighbor tile and not available after public void sim_goParentDecrementOn(SimNode in) { if(in == null) return; in.kon = in.kon - 1; sim_goParentDecrementOn(in.parent); return; } // a new tile was added to one of its successors' with tile /* public void sim_goParentModifyOff(SimNode in, double ch) { if(in == null) return; in.koff = in.koff + ch; sim_goParentModifyOff(in.parent,ch); return; } */ // a new tile was added on the sucessor line public void sim_goParentNewborn(SimNode in) { if(in == null) return; in.kon = in.kon - 1; //in.koff = in.koff + ch; in.tilesCovered = in.tilesCovered + 1; sim_goParentNewborn(in.parent); return; } // a tile was removed on the sucessor line public void sim_comeParentNewborn(SimNode in) { if(in == null) return; in.kon = in.kon + 1; //in.koff = in.koff - ch; in.tilesCovered = in.tilesCovered - 1; sim_comeParentNewborn(in.parent); return; } // a new tile was added on the sucessor line, this time no need to reduce the kon, since the tile is a part of seed a. public void sim_goParentMoonborn(SimNode in, int tilesCov) { if(in == null) return; //in.koff = in.koff + ch; in.tilesCovered = in.tilesCovered + tilesCov; sim_goParentMoonborn(in.parent,tilesCov); return; } public void sim_recalculateKoff(SimNode in) { double tet = 0; int x,y, t; x = in.index & xMask; y = in.index>>boardDim; t = simCellMatrix[in.index].tile; if(y>0 && simCellMatrix[(y-1)*boardSize+x].tile >= 0) { tet += bondMatrix[sim_sn[t]*numBonds+sim_ss[simCellMatrix[(y-1)*boardSize+x].tile]]; } if(x < boardSize-1 && simCellMatrix[y*boardSize+x+1].tile >= 0) { tet += bondMatrix[sim_se[t]*numBonds+sim_sw[simCellMatrix[y*boardSize+x+1].tile]]; } if(y < boardSize-1 && simCellMatrix[(y+1)*boardSize+x].tile >= 0) { tet += bondMatrix[sim_ss[t]*numBonds+sim_sn[simCellMatrix[(y+1)*boardSize+x].tile]]; } if(x>0 && simCellMatrix[y*boardSize+x-1].tile >= 0) { tet += bondMatrix[sim_sw[t]*numBonds+sim_se[simCellMatrix[y*boardSize+x-1].tile]]; } //System.out.println("recalculating "+x+","+y+":"+tet); in.koff = Math.exp(-tet*Gse); sim_updateKoff(in.parent); } public void sim_updateKoff(SimNode in) { in.koff = in.p0.koff+in.p1.koff+in.p2.koff+in.p3.koff; if(in.parent != null) { sim_updateKoff(in.parent); } } // assemble a tile public void sim_put_tile(int x, int y, int t) { boolean neighbors=false; SimCell cell; if(x>=boardSize || y>=boardSize || x<0 || y<0) return; // maybe, notify ppl cell = simCellMatrix[y*boardSize+x]; lastCell = cell; cell.tile = t; //System.out.println("lastCell.tile"+lastCell.tile); //System.out.println("putting tile"+x+","+y+":"+t); if(y>0) { if(simCellMatrix[(y-1)*boardSize+x].tile >= 0) { sim_recalculateKoff(simCellMatrix[(y-1)*boardSize+x].node); neighbors = true; } else { if(simCellMatrix[(y-1)*boardSize+x].node.kon != 1) { //simCellMatrix[(y-1)*boardSize+x].node.kon = 1; // notify parents sim_goParentIncrementOn(simCellMatrix[(y-1)*boardSize+x].node); } } } if(x < boardSize-1) { if(simCellMatrix[y*boardSize+x+1].tile >= 0) { sim_recalculateKoff(simCellMatrix[y*boardSize+x+1].node); neighbors = true; } else { if(simCellMatrix[y*boardSize+x+1].node.kon != 1) { //simCellMatrix[y*boardSize+x+1].node.kon = 1; // notify parents sim_goParentIncrementOn(simCellMatrix[y*boardSize+x+1].node); } } } if(y < boardSize-1) { if(simCellMatrix[(y+1)*boardSize+x].tile >= 0) { sim_recalculateKoff(simCellMatrix[(y+1)*boardSize+x].node); neighbors = true; } else { if(simCellMatrix[(y+1)*boardSize+x].node.kon != 1) { //simCellMatrix[(y+1)*boardSize+x].node.kon = 1; // notify parents sim_goParentIncrementOn(simCellMatrix[(y+1)*boardSize+x].node); } } } if(x>0) { if(simCellMatrix[y*boardSize+x-1].tile >= 0) { sim_recalculateKoff(simCellMatrix[y*boardSize+x-1].node); neighbors = true; } else { if(simCellMatrix[y*boardSize+x-1].node.kon != 1) { //simCellMatrix[y*boardSize+x-1].node.kon = 1; // notify parents sim_goParentIncrementOn(simCellMatrix[y*boardSize+x-1].node); //.parent); } } } cell.node.kon = 0; sim_recalculateKoff(cell.node); cell.node.tilesCovered = 1; // run upwards and tell all neighbours to change their k's if(neighbors) { sim_goParentNewborn(cell.node.parent); } else { System.out.println("no neighs"); sim_goParentMoonborn(cell.node.parent,1 ); } population++; //System.out.println("finished putting tile"+x+","+y); //if(!willSurvive) sim_take_tile(x,y); return; } //disassemble a tile public void sim_take_tile(int x, int y) { if(seedX == x && seedY == y) { if(y>0 && simCellMatrix[(y-1)*boardSize+x].tile >= 0) { seedY--; } else if(x+1 < boardSize && simCellMatrix[y*boardSize+x+1].tile >= 0) { seedX++; } else if(y+1 < boardSize && simCellMatrix[(y+1)*boardSize+x].tile >= 0) { seedY++; } else if(x>0 && simCellMatrix[y*boardSize+x-1].tile >= 0) { seedX--; } else return; } boolean neighbors=false, bn=false, be=false, bs=false, bw=false; int nn=-1, ne=-1, ns=-1, nw=-1, t; SimCell cell; if(x>=boardSize || y>=boardSize || x<0 || y<0) return; // maybe, notify ppl cell = simCellMatrix[y*boardSize+x]; t = cell.tile; cell.tile = -1; //i0=0; if(y>0) { if((nn = simCellMatrix[(y-1)*boardSize+x].tile) >= 0) { sim_recalculateKoff(simCellMatrix[(y-1)*boardSize+x].node); bn = bondMatrix[sim_sn[t]*numBonds+sim_ss[nn]] > 0; neighbors = true; } else { if(!( (x>0 && simCellMatrix[(y-1)*boardSize+x-1].tile >= 0) || (y>1 && simCellMatrix[(y-2)*boardSize+x].tile >= 0) || (x< (boardSize-1) && simCellMatrix[(y-1)*boardSize+x+1].tile >= 0))) { simCellMatrix[(y-1)*boardSize+x].node.kon = 0; // notify parents sim_goParentDecrementOn(simCellMatrix[(y-1)*boardSize+x].node.parent); } } } if(x+1 < boardSize) { if( (ne = simCellMatrix[y*boardSize+x+1].tile) >= 0) { sim_recalculateKoff(simCellMatrix[y*boardSize+x+1].node); be = bondMatrix[sim_se[t]*numBonds+sim_sw[ne]]>0; neighbors = true; } else { if(!( (y>0 && simCellMatrix[(y-1)*boardSize+x+1].tile >= 0) || ((x< (boardSize-2)) && simCellMatrix[y*boardSize+x+2].tile >= 0) || ((y< (boardSize-1)) && simCellMatrix[(y+1)*boardSize+x+1].tile >= 0))) { simCellMatrix[y*boardSize+x+1].node.kon = 0; // notify parents sim_goParentDecrementOn(simCellMatrix[y*boardSize+x+1].node.parent); } } } if(y+1 < boardSize) { if( (ns = simCellMatrix[(y+1)*boardSize+x].tile) >= 0) { sim_recalculateKoff(simCellMatrix[(y+1)*boardSize+x].node); bs = bondMatrix[sim_ss[t]*numBonds+sim_sn[ns]]>0; neighbors = true; } else { if(!( (x>0 && simCellMatrix[(y+1)*boardSize+x-1].tile >= 0) || (y<(boardSize-2) && simCellMatrix[(y+2)*boardSize+x].tile >= 0) || (x< (boardSize-1) && simCellMatrix[(y+1)*boardSize+x+1].tile >= 0))) { simCellMatrix[(y+1)*boardSize+x].node.kon = 0; // notify parents sim_goParentDecrementOn(simCellMatrix[(y+1)*boardSize+x].node.parent); } } } if(x>0) { if( (nw = simCellMatrix[y*boardSize+x-1].tile) >= 0) { sim_recalculateKoff(simCellMatrix[y*boardSize+x-1].node); bw = bondMatrix[sim_sw[t]*numBonds+sim_se[nw]] > 0; neighbors = true; } else { if(!( (x>1 && simCellMatrix[y*boardSize+x-2].tile >= 0) || (y>0 && simCellMatrix[(y-1)*boardSize+x-1].tile >= 0) || (y< (boardSize-1) && simCellMatrix[(y+1)*boardSize+x-1].tile >= 0))) { simCellMatrix[y*boardSize+x-1].node.kon = 0; // notify parents sim_goParentDecrementOn(simCellMatrix[y*boardSize+x-1].node.parent); } } } // yourself and upwards: change k's if(neighbors) { cell.node.kon = 1; sim_comeParentNewborn(cell.node.parent); } else { cell.node.kon = 0; sim_goParentMoonborn(cell.node.parent,-1 ); } cell.node.koff = 0; cell.node.tilesCovered = 0; sim_updateKoff(cell.node.parent); population--; // handle "disconnectivity" int tTile; if( (!bn || !be || ( (tTile = simCellMatrix[y*boardSize+x+1-boardSize].tile) >= 0 && bondMatrix[sim_sw[nn]*numBonds+sim_se[tTile]] > 0 && bondMatrix[sim_sn[ne]*numBonds+sim_ss[tTile]] > 0) ) && (!bn || !bw || ( (tTile = simCellMatrix[y*boardSize+x-1-boardSize].tile) >= 0 && bondMatrix[sim_se[nn]*numBonds+sim_sw[tTile]] > 0 && bondMatrix[sim_sn[nw]*numBonds+sim_ss[tTile]] > 0) ) && (!bs || !be || ( (tTile = simCellMatrix[y*boardSize+x+1+boardSize].tile) >= 0 && bondMatrix[sim_sw[ns]*numBonds+sim_se[tTile]] > 0 && bondMatrix[sim_ss[ne]*numBonds+sim_sn[tTile]] > 0) ) && (!bs || !bw || ( (tTile = simCellMatrix[y*boardSize+x-1+boardSize].tile) >= 0 && bondMatrix[sim_se[ns]*numBonds+sim_sw[tTile]] > 0 && bondMatrix[sim_ss[nw]*numBonds+sim_sn[tTile]] > 0) ) && ( !bn || !bs || be || bw ) && ( !be || !bw || bn || bs ) ) { return; } else { sim_prepareNodesForLabeling(baseNode, boardDim); labelIndex = 0; basePair = new PairList(0,0); currentPair = basePair; trimBoard(baseNode); graphLabels = new GraphAdjacency[labelIndex]; graphVisited = new boolean[labelIndex]; for(int i=0; i<labelIndex; i++) { graphLabels[i] = new GraphAdjacency(i); graphVisited[i] = false; } currentPair = basePair.next; while(currentPair != null) { graphLabels[currentPair.x].add(currentPair.y); graphLabels[currentPair.y].add(currentPair.x); currentPair = currentPair.next; } doEquivalentLabels(); labelIndex = graphLabels[simCellMatrix[seedY*boardSize+seedX].label].y; trimAllBoard(baseNode); } /* if(nn) { if(ne) { if(ns) { if(nw) { } else { } } else { } } else { } } else { } */ // return; } } class SimNode { SimNode p0,p1,p2,p3,parent; double koff; int kon; int tilesCovered=0; int index; } class SimCell { SimNode node; int tile; int label; boolean unlabeled; } class PairList { int x,y; PairList next = null; public PairList(int xx, int yy) { x = xx; y = yy; } public PairList add(int xx, int yy) { //System.out.println(">>>>>>>"+xx+" = "+yy); return (next = new PairList(xx,yy)); } } class GraphAdjacency { int y; GraphAdjacency next = null; public GraphAdjacency(int yy) { y = yy; } public void add(int yy) { GraphAdjacency current = this; do { if(current.y == yy) return; if(current.next == null) { current = (current.next = new GraphAdjacency(yy)); return; } } while( (current = current.next) != null); } }