/* We're overriding all internal data, to my knowledge, so this should be okay */ public Object clone() { try { MersenneTwisterFast f = (MersenneTwisterFast) (super.clone()); f.mt = (int[]) (mt.clone()); f.mag01 = (int[]) (mag01.clone()); return f; } catch (CloneNotSupportedException e) { throw new InternalError(); } // should never happen }
int[] findEmptySiteCancer(int x, int y) { LinkedList vacantSitesCancer = new LinkedList(); int[] tp1 = new int[2]; int[] tp2 = new int[2]; int[] tp3 = new int[2]; int[] tp4 = new int[2]; int[] tp5 = new int[2]; int[] tp6 = new int[2]; int[] tp7 = new int[2]; int[] tp8 = new int[2]; tp1 = convertCoordinatesNoFlux(x + 1, y - 1); if ((Cells[tp1[0]][tp1[1]] == 0) || (Cells[tp1[0]][tp1[1]] == 4)) vacantSitesCancer.add(tp1); tp2 = convertCoordinatesNoFlux(x + 1, y); if ((Cells[tp2[0]][tp2[1]] == 0) || (Cells[tp2[0]][tp2[1]] == 4)) vacantSitesCancer.add(tp2); tp3 = convertCoordinatesNoFlux(x + 1, y + 1); if ((Cells[tp3[0]][tp3[1]] == 0) || (Cells[tp3[0]][tp3[1]] == 4)) vacantSitesCancer.add(tp3); tp4 = convertCoordinatesNoFlux(x, y - 1); if ((Cells[tp4[0]][tp4[1]] == 0) || (Cells[tp4[0]][tp4[1]] == 4)) vacantSitesCancer.add(tp4); tp5 = convertCoordinatesNoFlux(x, y + 1); if ((Cells[tp5[0]][tp5[1]] == 0) || (Cells[tp5[0]][tp5[1]] == 4)) vacantSitesCancer.add(tp5); tp6 = convertCoordinatesNoFlux(x - 1, y - 1); if ((Cells[tp6[0]][tp6[1]] == 0) || (Cells[tp6[0]][tp6[1]] == 4)) vacantSitesCancer.add(tp6); tp7 = convertCoordinatesNoFlux(x - 1, y); if ((Cells[tp7[0]][tp7[1]] == 0) || (Cells[tp7[0]][tp7[1]] == 4)) vacantSitesCancer.add(tp7); tp8 = convertCoordinatesNoFlux(x - 1, y + 1); if ((Cells[tp8[0]][tp8[1]] == 0) || (Cells[tp8[0]][tp8[1]] == 4)) vacantSitesCancer.add(tp8); // Now let's see where. if (vacantSitesCancer.size() > 0) { // Now choose a vacant one, otherwise return the original location // pick a vacant site and return it int vacantElemIndexCancer = random.nextInt(vacantSitesCancer.size()); int[] p = (int[]) vacantSitesCancer.get(vacantElemIndexCancer); return (int[]) p; } else { int[] p = new int[2]; p[0] = x; p[1] = y; // Just return the original System.out.println("wrong!:" + vacantSitesCancer(x, y) + " - " + vacantSitesCancer.size()); return p; } }
/** Tests the code. */ public static void main(String args[]) { int j; MersenneTwisterFast r; // CORRECTNESS TEST // COMPARE WITH http://www.math.keio.ac.jp/matumoto/CODES/MT2002/mt19937ar.out r = new MersenneTwisterFast(new int[] {0x123, 0x234, 0x345, 0x456}); System.out.println("Output of MersenneTwisterFast with new (2002/1/26) seeding mechanism"); for (j = 0; j < 1000; j++) { // first, convert the int from signed to "unsigned" long l = (long) r.nextInt(); if (l < 0) l += 4294967296L; // max int value String s = String.valueOf(l); while (s.length() < 10) s = " " + s; // buffer System.out.print(s + " "); if (j % 5 == 4) System.out.println(); } // SPEED TEST final long SEED = 4357; int xx; long ms; System.out.println("\nTime to test grabbing 100000000 ints"); Random rr = new Random(SEED); xx = 0; ms = System.currentTimeMillis(); for (j = 0; j < 100000000; j++) xx += rr.nextInt(); System.out.println( "java.util.Random: " + (System.currentTimeMillis() - ms) + " Ignore this: " + xx); r = new MersenneTwisterFast(SEED); ms = System.currentTimeMillis(); xx = 0; for (j = 0; j < 100000000; j++) xx += r.nextInt(); System.out.println( "Mersenne Twister Fast: " + (System.currentTimeMillis() - ms) + " Ignore this: " + xx); // TEST TO COMPARE TYPE CONVERSION BETWEEN // MersenneTwisterFast.java AND MersenneTwister.java System.out.println("\nGrab the first 1000 booleans"); r = new MersenneTwisterFast(SEED); for (j = 0; j < 1000; j++) { System.out.print(r.nextBoolean() + " "); if (j % 8 == 7) System.out.println(); } if (!(j % 8 == 7)) System.out.println(); System.out.println("\nGrab 1000 booleans of increasing probability using nextBoolean(double)"); r = new MersenneTwisterFast(SEED); for (j = 0; j < 1000; j++) { System.out.print(r.nextBoolean((double) (j / 999.0)) + " "); if (j % 8 == 7) System.out.println(); } if (!(j % 8 == 7)) System.out.println(); System.out.println("\nGrab 1000 booleans of increasing probability using nextBoolean(float)"); r = new MersenneTwisterFast(SEED); for (j = 0; j < 1000; j++) { System.out.print(r.nextBoolean((float) (j / 999.0f)) + " "); if (j % 8 == 7) System.out.println(); } if (!(j % 8 == 7)) System.out.println(); byte[] bytes = new byte[1000]; System.out.println("\nGrab the first 1000 bytes using nextBytes"); r = new MersenneTwisterFast(SEED); r.nextBytes(bytes); for (j = 0; j < 1000; j++) { System.out.print(bytes[j] + " "); if (j % 16 == 15) System.out.println(); } if (!(j % 16 == 15)) System.out.println(); byte b; System.out.println("\nGrab the first 1000 bytes -- must be same as nextBytes"); r = new MersenneTwisterFast(SEED); for (j = 0; j < 1000; j++) { System.out.print((b = r.nextByte()) + " "); if (b != bytes[j]) System.out.print("BAD "); if (j % 16 == 15) System.out.println(); } if (!(j % 16 == 15)) System.out.println(); System.out.println("\nGrab the first 1000 shorts"); r = new MersenneTwisterFast(SEED); for (j = 0; j < 1000; j++) { System.out.print(r.nextShort() + " "); if (j % 8 == 7) System.out.println(); } if (!(j % 8 == 7)) System.out.println(); System.out.println("\nGrab the first 1000 ints"); r = new MersenneTwisterFast(SEED); for (j = 0; j < 1000; j++) { System.out.print(r.nextInt() + " "); if (j % 4 == 3) System.out.println(); } if (!(j % 4 == 3)) System.out.println(); System.out.println("\nGrab the first 1000 ints of different sizes"); r = new MersenneTwisterFast(SEED); int max = 1; for (j = 0; j < 1000; j++) { System.out.print(r.nextInt(max) + " "); max *= 2; if (max <= 0) max = 1; if (j % 4 == 3) System.out.println(); } if (!(j % 4 == 3)) System.out.println(); System.out.println("\nGrab the first 1000 longs"); r = new MersenneTwisterFast(SEED); for (j = 0; j < 1000; j++) { System.out.print(r.nextLong() + " "); if (j % 3 == 2) System.out.println(); } if (!(j % 3 == 2)) System.out.println(); System.out.println("\nGrab the first 1000 longs of different sizes"); r = new MersenneTwisterFast(SEED); long max2 = 1; for (j = 0; j < 1000; j++) { System.out.print(r.nextLong(max2) + " "); max2 *= 2; if (max2 <= 0) max2 = 1; if (j % 4 == 3) System.out.println(); } if (!(j % 4 == 3)) System.out.println(); System.out.println("\nGrab the first 1000 floats"); r = new MersenneTwisterFast(SEED); for (j = 0; j < 1000; j++) { System.out.print(r.nextFloat() + " "); if (j % 4 == 3) System.out.println(); } if (!(j % 4 == 3)) System.out.println(); System.out.println("\nGrab the first 1000 doubles"); r = new MersenneTwisterFast(SEED); for (j = 0; j < 1000; j++) { System.out.print(r.nextDouble() + " "); if (j % 3 == 2) System.out.println(); } if (!(j % 3 == 2)) System.out.println(); System.out.println("\nGrab the first 1000 gaussian doubles"); r = new MersenneTwisterFast(SEED); for (j = 0; j < 1000; j++) { System.out.print(r.nextGaussian() + " "); if (j % 3 == 2) System.out.println(); } if (!(j % 3 == 2)) System.out.println(); }
// main CELL CA loop************ public boolean iterateCells() { /* // modify consumption matrix for (int i=0;i<size;i++) for (int j=0;j<size;j++) consumption[i][j] = consumptionBasal[Cells[i][j]]; */ // if (cellList == null) cellList = new Bag(size * size); for (int i = 0; i < size; i++) for (int j = 0; j < size; j++) { if (Cells[i][j] < 4) { // All tumour cell types have Cell > 0, now 0 corresponds to 'healthy cells' that // consume at basal rate only int[] p = new int[2]; p[0] = i; p[1] = j; cellList.add(p); if (Cells[i][j] == 1) { stem_cells_this_TS++; } else if (Cells[i][j] == 2 || Cells[i][j] == 3) { non_stem_cells_this_TS++; } } } while (cellList.size() != 0) { // Select the next lattice element at random int randomElemIndex = 0; if (cellList.size() > 1) randomElemIndex = random.nextInt(cellList.size() - 1); int[] point = (int[]) cellList.get(randomElemIndex); int rI = point[0]; int rJ = point[1]; cellList.remove(randomElemIndex); // Remove it from the cell list int cell = Cells[rI][rJ]; // Cell death // if ((Oxygen[rI][rJ]<hypoxia)) { if ((random.nextFloat() < deathprob) && Cells[rI][rJ] > 0) { // x% chances of dying Age[rI][rJ] = 0; if (Cells[rI][rJ] == 1) stemDeathCounter[rI][rJ]++; if (Cells[rI][rJ] < 4) { // TACDeathCounter[rI][rJ]++; Cells[rI][rJ] = 4; // was 0, now making necrotic area (truly empty) deaths++; stemBirthCounter[rI][rJ] = 0; carriedmutation[rI][rJ] = 0; // empty space now has no mutations carriedGenome[rI][rJ] = initGenome; // empty space now has no mutations } } else if ((cell == 3) && (Age[rI][rJ] > 100 * maxMatureCellAge)) { // added * to allow for an update each celltimestep/x // ************************** Age[rI][rJ] = 0; Cells[rI][rJ] = 4; // was 0, now making necrotic area (truly empty) // TACDeathCounter[rI][rJ]++; deaths++; } else if ((radiotherapy) && (cell == 2) && (random.nextFloat() > Oxygen[rI][rJ])) { // Radiotherapy Age[rI][rJ] = 0; if (Cells[rI][rJ] == 1) stemDeathCounter[rI][rJ]++; if ((Cells[rI][rJ] == 2) || (Cells[rI][rJ] == 3)) // TACDeathCounter[rI][rJ]++; Cells[rI][rJ] = 4; // make necrotic stemBirthCounter[rI][rJ] = 0; deaths++; } // healthy division else if ((cell == 0) && (vacantSites(rI, rJ) > 0)) { if (proliferation[cell] >= random.nextFloat()) { // If tossing the coin we are to proliferate... // if (Oxygen[rI][rJ]>prolifThreshold) { // AND the oxygen concentration is enough for // division.. // consumption[rI][rJ]=consumptionDivision[Cells[rI][rJ]]; int[] daughter = findEmptySite(rI, rJ); births++; Cells[daughter[0]][daughter[1]] = 0; carriedmutation[daughter[0]][daughter[1]] = 0; carriedGenome[daughter[0]][daughter[1]] = initGenome; // resetting space to healthy cell with no mutations } } // } // cancer division else if ((vacantSitesCancer(rI, rJ) > 0) && (cell > 0)) if (proliferation[cell] >= random.nextFloat()) { // If tossing the coin we are to proliferate... if ((cell == 1) || ((cell == 2) && (Age[rI][rJ] < maxProDivisions))) { // AND the cell is stem or TAC ... // if (Oxygen[rI][rJ]>prolifThreshold) { // AND the oxygen concentration is enough for // division.. // consumption[rI][rJ]=consumptionDivision[Cells[rI][rJ]]; int[] daughter = findEmptySiteCancer(rI, rJ); // and there is space (for cancer) // if ((daughter[0]==0) || (daughter[0]==size) || // (daughter[1]==0)||(daughter[1]==size)) {simulationFinished=true;} // stop sim if a // cell hits the edge births++; if (cell == 1) { // stem cell stemBirthsTotal[rI][rJ]++; stemBirthCounter[rI][rJ]++; if (asymmetricRatio > random.nextFloat()) { Cells[daughter[0]][daughter[1]] = 1; // placing the stem daughter stemBirthCounter[daughter[0]][daughter[1]] = stemBirthCounter[rI][rJ]; // update stem birth counter carriedmutation[daughter[0]][daughter[1]] = carriedmutation[rI][rJ]; // inherit mutational status of parent carriedGenome[daughter[0]][daughter[1]] = carriedGenome[rI][rJ]; // inherit mutational status of parent if (mutfreq > random.nextFloat()) { // small chance of mutation mutationNum++; // advance mutation number System.out.println( +carriedmutation[rI][rJ] + ", " + mutationNum + ", " + stem_cells_this_TS + ", " + non_stem_cells_this_TS + ", " + timestep); // print (parent,child) pair // tree.put(carriedmutation[rI][rJ], mutationNum); // timeTree.put(mutationNum, timestep); // hash table stuff if (0.5 > random.nextFloat()) { carriedmutation[daughter[0]][daughter[1]] = mutationNum; genomeToMod = new StringBuilder(carriedGenome[daughter[0]][daughter[1]]); genomeToMod.setCharAt( mutationNum - 1, '1'); // daughter carries new carriedGenome carriedGenome[daughter[0]][daughter[1]] = genomeToMod; // System.out.println (carriedGenome[rI][rJ]); // System.out.println (carriedGenome[daughter[0]][daughter[1]]); } // 50:50 mutate new position daughter else { carriedmutation[rI][rJ] = mutationNum; // else mutate original position daughter genomeToMod = new StringBuilder(carriedGenome[rI][rJ]); // genomeToMod = carriedGenome[rI][rJ]; carriedGenome[rI][rJ] = genomeToMod; genomeToMod.setCharAt( mutationNum - 1, '1'); // original carries new carriedGenome // System.out.println (carriedGenome[rI][rJ]); // System.out.println (carriedGenome[daughter[0]][daughter[1]]); } } } else { Cells[daughter[0]][daughter[1]] = 2; // asymmetric division, daughter is TAC stemBirthCounter[daughter[0]][daughter[1]] = 0; // reset stem counter carriedmutation[daughter[0]][daughter[1]] = carriedmutation[rI][rJ]; // TAC carries parental mutation flag carriedGenome[daughter[0]][daughter[1]] = carriedGenome[rI][rJ]; } // TAC carries parental genome // } // redundant from above // else { // Only if there's hypoxia induced change of symmetric division ratio // float newASR=asymmetricRatio+0*(hypoxia-Oxygen[rI][rJ]); // currently OFF by way of 0 the ^^ multiplier. // if (newASR>random.nextFloat()) // {Cells[daughter[0]][daughter[1]]=1;stemBirthCounter[daughter[0]][daughter[1]]=stemBirthCounter[rI][rJ];} // else // {Cells[daughter[0]][daughter[1]]=2;stemBirthCounter[daughter[0]][daughter[1]]=0;} // // Otherwise differentiate // } } else if (cell == 2) { // non-stem division // TACBirthCounter[rI][rJ]++; if (Age[rI][rJ] < maxProDivisions - 1) { Cells[daughter[0]][daughter[1]] = 2; Age[rI][rJ]++; Age[daughter[0]][daughter[1]] = Age[rI][rJ]; carriedmutation[daughter[0]][daughter[1]] = carriedmutation[rI][rJ]; // TAC carries parental mutation flag carriedGenome[daughter[0]][daughter[1]] = carriedGenome[rI][rJ]; // TAC carries parental genome } else { Cells[daughter[0]][daughter[1]] = 3; Cells[rI][rJ] = 3; Age[rI][rJ] = 0; Age[daughter[0]][daughter[1]] = Age[rI][rJ]; carriedmutation[daughter[0]][daughter[1]] = carriedmutation[rI][rJ]; // TAC carries parental mutation flag carriedGenome[daughter[0]][daughter[1]] = carriedGenome[rI][rJ]; // TAC carries parental genome } } } } else if (pMotility > random.nextFloat()) { // Migration = not in use int[] daughter = findEmptySite(rI, rJ); Cells[daughter[0]][daughter[1]] = cell; Cells[rI][rJ] = 0; Age[daughter[0]][daughter[1]] = Age[rI][rJ]; Age[rI][rJ] = 0; System.err.println("moving " + rI + ", " + rJ); } // Aging for mature cells if (cell == 3) Age[rI][rJ]++; } return true; }