package test.beast.core; import org.junit.Test; import beast.core.OperatorSchedule; import beast.core.parameter.RealParameter; import beast.evolution.operators.DeltaExchangeOperator; import beast.evolution.operators.ScaleOperator; import junit.framework.TestCase; public class OperatorScheduleTest extends TestCase { RealParameter parameter = new RealParameter(new Double[] {1., 1., 1., 1.}); OperatorSchedule setUpSchedule() { DeltaExchangeOperator operator1 = new DeltaExchangeOperator(); operator1.setID("deltaOperator"); operator1.initByName("parameter", parameter, "weight", 1.0); ScaleOperator operator2 = new ScaleOperator(); operator2.setID("scaleOperator"); operator2.initByName("parameter", parameter, "weight", 3.0); OperatorSchedule schedule = new OperatorSchedule(); schedule.initAndValidate(); schedule.addOperator(operator1); schedule.addOperator(operator2); return schedule; } /** test single schedule with 2 operators **/ @Test public void testOperatorSchedulePlain() { double [] probs; OperatorSchedule schedule = setUpSchedule(); // selectOperator() causes reweighting schedule.selectOperator(); // weights have not changed probs = schedule.getCummulativeProbs(); assertEquals(2, probs.length); assertEquals(2, schedule.operators.size()); assertEquals(1.0/4.0, probs[0], 1e-15); assertEquals(4.0/4.0, probs[1], 1e-15); } /** as testOperatorSchedulePlain() but with 1 nested schedule **/ @Test public void testOperatorScheduleNestedByPercentage() { double [] probs; OperatorSchedule schedule = setUpSchedule(); ScaleOperator operator3 = new ScaleOperator(); operator3.setID("scaleOperator.Species"); operator3.initByName("parameter", parameter, "weight", 20.0); OperatorSchedule subSchedule = new OperatorSchedule(); subSchedule.initByName("operator", operator3, "weight", 20.0, "weightIsPercentage", true, "operatorPattern", "^.*\\.Species$"); schedule.subschedulesInput.setValue(subSchedule, schedule); schedule.initAndValidate(); schedule.addOperator(operator3); // selectOperator() causes reweighting schedule.selectOperator(); probs = schedule.getCummulativeProbs(); assertEquals(3, probs.length); assertEquals(3, schedule.operators.size()); assertEquals(1.0/5.0, probs[0], 1e-15); assertEquals(4.0/5.0, probs[1], 1e-15); assertEquals(5.0/5.0, probs[2], 1e-15); } /** as testOperatorScheduleNestedByPercentage() but with 2 nested operators **/ @Test public void testOperatorScheduleNestedByPercentage2() { double [] probs; OperatorSchedule schedule = setUpSchedule(); ScaleOperator operator3 = new ScaleOperator(); operator3.setID("scaleOperator.Species"); operator3.initByName("parameter", parameter, "weight", 20.0); OperatorSchedule subSchedule = new OperatorSchedule(); subSchedule = new OperatorSchedule(); ScaleOperator operator4 = new ScaleOperator(); operator4.setID("scaleOperator2.Species"); operator4.initByName("parameter", parameter, "weight", 20.0); subSchedule.initByName("operator", operator3, "operator", operator4, "weight", 20.0, "weightIsPercentage", true, "operatorPattern", "^.*\\.Species$"); schedule.subschedulesInput.get().clear(); schedule.subschedulesInput.setValue(subSchedule, schedule); schedule.initAndValidate(); schedule.addOperator(operator3); schedule.addOperator(operator4); // selectOperator() causes reweighting schedule.selectOperator(); probs = schedule.getCummulativeProbs(); assertEquals(4, probs.length); assertEquals(4, schedule.operators.size()); assertEquals(1.0/5.0, probs[0], 1e-15); assertEquals(4.0/5.0, probs[1], 1e-15); assertEquals(4.5/5.0, probs[2], 1e-15); assertEquals(5.0/5.0, probs[3], 1e-15); } /** as testOperatorSchedulePlain() but with 1 nested schedule weighted by relative weight * Also, make sure the operatorPattern matching works **/ @Test public void testOperatorScheduleNestedByRelativeWeight() { double [] probs; OperatorSchedule schedule = setUpSchedule(); ScaleOperator operator3 = new ScaleOperator(); operator3.setID("scaleOperator.Species"); operator3.initByName("parameter", parameter, "weight", 20.0); OperatorSchedule subSchedule = new OperatorSchedule(); subSchedule.initByName(/*"operator", operator3,*/ "weight", 4.0, "operatorPattern", "^.*\\.Species$"); schedule.subschedulesInput.setValue(subSchedule, schedule); schedule.initAndValidate(); schedule.addOperator(operator3); // selectOperator() causes reweighting schedule.selectOperator(); probs = schedule.getCummulativeProbs(); assertEquals(3, probs.length); assertEquals(3, schedule.operators.size()); assertEquals(1.0/8.0, probs[0], 1e-15); assertEquals(4.0/8.0, probs[1], 1e-15); assertEquals(8.0/8.0, probs[2], 1e-15); } /** as testOperatorScheduleNestedByRelativeWeight() but with 2 nested operators **/ @Test public void testOperatorScheduleNestedByRelativeWeight2() { double [] probs; OperatorSchedule schedule = setUpSchedule(); ScaleOperator operator3 = new ScaleOperator(); operator3.setID("scaleOperator.Species"); operator3.initByName("parameter", parameter, "weight", 20.0); OperatorSchedule subSchedule = new OperatorSchedule(); subSchedule = new OperatorSchedule(); ScaleOperator operator4 = new ScaleOperator(); operator4.setID("scaleOperator2.Species"); operator4.initByName("parameter", parameter, "weight", 20.0); subSchedule.initByName("operator", operator3, "operator", operator4, "weight", 4.0, "operatorPattern", "^.*\\.Species$"); schedule.subschedulesInput.get().clear(); schedule.subschedulesInput.setValue(subSchedule, schedule); schedule.initAndValidate(); schedule.addOperator(operator3); schedule.addOperator(operator4); // selectOperator() causes reweighting schedule.selectOperator(); probs = schedule.getCummulativeProbs(); assertEquals(4, probs.length); assertEquals(4, schedule.operators.size()); assertEquals(1.0/8.0, probs[0], 1e-15); assertEquals(4.0/8.0, probs[1], 1e-15); assertEquals(6.0/8.0, probs[2], 1e-15); assertEquals(8.0/8.0, probs[3], 1e-15); } /** as testOperatorSchedulePlain() but with 2 nested schedules weighted by relative weight **/ @Test public void testOperatorScheduleMultiNestedByRelativeWeight() { double [] probs; OperatorSchedule schedule = setUpSchedule(); ScaleOperator operator3 = new ScaleOperator(); operator3.setID("scaleOperator.Species"); operator3.initByName("parameter", parameter, "weight", 20.0); OperatorSchedule subSchedule = new OperatorSchedule(); subSchedule.initByName("operator", operator3, "weight", 4.0, "operatorPattern", "^.*\\.Species$"); ScaleOperator operator4 = new ScaleOperator(); operator4.setID("scaleOperator.Species2"); operator4.initByName("parameter", parameter, "weight", 20.0); OperatorSchedule subSchedule2 = new OperatorSchedule(); subSchedule2.initByName("operator", operator4, "weight", 2.0, "operatorPattern", "^.*\\.Species2$"); schedule.subschedulesInput.setValue(subSchedule, schedule); schedule.subschedulesInput.setValue(subSchedule2, schedule); schedule.initAndValidate(); schedule.addOperator(operator3); schedule.addOperator(operator4); // selectOperator() causes reweighting schedule.selectOperator(); probs = schedule.getCummulativeProbs(); assertEquals(4, probs.length); assertEquals(4, schedule.operators.size()); assertEquals(1.0/10.0, probs[0], 1e-15); assertEquals(4.0/10.0, probs[1], 1e-15); assertEquals(8.0/10.0, probs[2], 1e-15); assertEquals(10.0/10.0, probs[3], 1e-15); } /** as testOperatorSchedulePlain() but with 2 nested schedules weighted by percentage * Also, reuse operator, so it is in 2 sub schedules **/ @Test public void testOperatorScheduleMultiNestedByPercentage() { double [] probs; OperatorSchedule schedule = setUpSchedule(); ScaleOperator operator3 = new ScaleOperator(); operator3.setID("scaleOperator.Species"); operator3.initByName("parameter", parameter, "weight", 20.0); OperatorSchedule subSchedule = new OperatorSchedule(); subSchedule.initByName("operator", operator3, "weight", 20.0, "weightIsPercentage", true, "operatorPattern", "^.*\\.Species$"); OperatorSchedule subSchedule2 = new OperatorSchedule(); subSchedule2.initByName("operator", operator3, "weight", 30.0, "weightIsPercentage", true, "operatorPattern", "^.*\\.Species2$"); schedule.subschedulesInput.setValue(subSchedule, schedule); schedule.subschedulesInput.setValue(subSchedule2, schedule); schedule.initAndValidate(); schedule.addOperator(operator3); // selectOperator() causes reweighting schedule.selectOperator(); probs = schedule.getCummulativeProbs(); assertEquals(4, probs.length); assertEquals(4, schedule.operators.size()); assertEquals(1.25/10.0, probs[0], 1e-15); assertEquals(5.0/10.0, probs[1], 1e-15); assertEquals(7.0/10.0, probs[2], 1e-15); assertEquals(10.0/10.0, probs[3], 1e-15); } /** as testOperatorSchedulePlain() but with 2 nested schedules, one weighted by percentage, one weighted by relative weight * Also, reuse operator, so it is in 2 sub schedules **/ @Test public void testOperatorScheduleMultiNestedByPercentageAndRelativeWeight() { double [] probs; OperatorSchedule schedule = setUpSchedule(); ScaleOperator operator3 = new ScaleOperator(); operator3.setID("scaleOperator.Species"); operator3.initByName("parameter", parameter, "weight", 20.0); OperatorSchedule subSchedule = new OperatorSchedule(); subSchedule.initByName("operator", operator3, "weight", 4.0, "weightIsPercentage", false, "operatorPattern", "^.*\\.Species$"); OperatorSchedule subSchedule2 = new OperatorSchedule(); subSchedule2.initByName(/*"operator", operator3, */"weight", 20.0, "weightIsPercentage", true, "operatorPattern", "^.*\\.Species$"); schedule.subschedulesInput.setValue(subSchedule, schedule); schedule.subschedulesInput.setValue(subSchedule2, schedule); schedule.initAndValidate(); //schedule.addOperator(operator3); // selectOperator() causes reweighting schedule.selectOperator(); probs = schedule.getCummulativeProbs(); assertEquals(4, probs.length); assertEquals(4, schedule.operators.size()); assertEquals(1.0/10.0, probs[0], 1e-15); assertEquals(4.0/10.0, probs[1], 1e-15); assertEquals(8.0/10.0, probs[2], 1e-15); assertEquals(10.0/10.0, probs[3], 1e-15); } }