import java.util.*; // T J Finney, 2001 // Not to be sold without my permission. class Scribe { // static methods // copy MS // acc = prob. of making an accurate copy (per unit) // If not accurate, scribe will insert existing reading or novel reading. // Prob. of adding novel reading is 1 / s^n, where s is number of states // and n is a suitable exponent. E.g., for n = 2, // s 1 2 3 4 5 // p 1.00 0.25 0.11 0.07 0.04 // Thanks to J R Adair for this idea. public static MS copy (MS source, double acc) { MS target = new MS (source.getAncestry()); int num = MS.getSize(); for (int i = 0; i < num; i++) { if (Stats.trial(acc)) { // accurate: transfer source reading target.setUnit(i, source.getUnit(i)); } else { // inaccurate: insert different reading // calculate probability of novel reading double nov = Math.pow((double) MS.howManyStates(i), -1.5); if (Stats.trial(nov)) { // create novel reading target.setUnit(i, MS.addState(i)); } else { // create novel reading if no others if (MS.howManyStates(i) == 1) { MS.addState(i); } // select existing reading besides current one int current = source.getUnit(i); int existing = current; while (current == existing) { existing = MS.getState(i); } target.setUnit(i, existing); } } } return target; } // correct MS public static void correct (MS ms, MS source) { // get prob. of correcting difference double corr = Stats.getRand(); int num = MS.getSize(); for (int i = 0; i < num; i++) { if (Stats.trial(corr)) { ms.setUnit(i, source.getUnit(i)); } } } // main: test public static void main (String [] args) { MS.initStates(); MS ms1 = MS.makeArchetype(); MS[] ms = new MS[10]; System.out.println("copy() ten times"); ms[0] = ms1; ms[0].print(); for (int i = 1; i < 10; i++) { ms[i] = Scribe.copy(ms[i - 1], 0.5); ms[i].print(); } System.out.println("correct()"); for (int i = 0; i < 10; i++) { Scribe.correct(ms[i], ms1); ms[i].print(); } } }