package dr.inference.operators; import dr.xml.*; import dr.inference.model.Parameter; import dr.math.MathUtils; /** * @author Marc Suchard */ public class RateBitExchangeOperator extends SimpleMCMCOperator { public static final String OPERATOR_NAME = "rateBitExchangeOperator"; public static final String BITS = "bits"; public static final String RATES = "rates"; RateBitExchangeOperator(Parameter rateParameter, Parameter bitParameter, double weight) { this.rateParameter = rateParameter; this.bitParameter = bitParameter; setWeight(weight); } public double doOperation() throws OperatorFailedException { int dim = rateParameter.getDimension() / 2; // Find a pair-set in which at least one bit is non-zero int index = -1; do { index = MathUtils.nextInt(dim); } while( bitParameter.getParameterValue(index) + bitParameter.getParameterValue(index+dim) < 1 ); // Swap (bit,rate) values double tmpBit = bitParameter.getParameterValue(index); double tmpRate = rateParameter.getParameterValue(index); bitParameter.setParameterValue(index, bitParameter.getParameterValue(index+dim)); rateParameter.setParameterValue(index, rateParameter.getParameterValue(index+dim)); bitParameter.setParameterValue(index+dim,tmpBit); rateParameter.setParameterValue(index+dim,tmpRate); return 0; } // Interface MCMCOperator public final String getOperatorName() { return OPERATOR_NAME + "(" + bitParameter.getParameterName() +"," + rateParameter.getParameterName() + ")"; } public final String getPerformanceSuggestion() { return "No performance suggestion"; } public String toString() { return getOperatorName(); } public static XMLObjectParser PARSER = new AbstractXMLObjectParser() { public String getParserName() { return OPERATOR_NAME; } public Object parseXMLObject(XMLObject xo) throws XMLParseException { double weight = xo.getDoubleAttribute(WEIGHT); Parameter ratesParameter = (Parameter) ((XMLObject)xo.getChild(RATES)).getChild(Parameter.class); Parameter bitsParameter = (Parameter) ((XMLObject)xo.getChild(BITS)).getChild(Parameter.class); return new RateBitExchangeOperator(ratesParameter,bitsParameter, weight); } //************************************************************************ // AbstractXMLObjectParser implementation //************************************************************************ public String getParserDescription() { return "This element returns a bit-flip operator on a given parameter."; } public Class getReturnType() { return MCMCOperator.class; } public XMLSyntaxRule[] getSyntaxRules() { return rules; } private final XMLSyntaxRule[] rules = { AttributeRule.newDoubleRule(WEIGHT), new ElementRule(BITS, new XMLSyntaxRule[] { new ElementRule(Parameter.class) }), new ElementRule(RATES, new XMLSyntaxRule[] { new ElementRule(Parameter.class) }), }; }; // Private instance variables private Parameter bitParameter = null; private Parameter rateParameter = null; }