/* * ParameterIntegerParser.java * * Copyright (c) 2002-2015 Alexei Drummond, Andrew Rambaut and Marc Suchard * * This file is part of BEAST. * See the NOTICE file distributed with this work for additional * information regarding copyright ownership and licensing. * * BEAST is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * BEAST is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with BEAST; if not, write to the * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301 USA */ package dr.inference.model; import dr.xml.AttributeRule; import dr.xml.XMLObject; import dr.xml.XMLParseException; import dr.xml.XMLSyntaxRule; /** * Parses a multi-dimensional continuous parameter. * * @author Alexei Drummond * @author Andrew Rambaut * @author Walter Xie * * @version $Id: ParameterParser.java,v 1.12 2005/05/24 20:26:00 rambaut Exp $ */ public class ParameterIntegerParser extends dr.xml.AbstractXMLObjectParser { // public static final String UPPER = "upper"; // public static final String LOWER = "lower"; public static final String DIMENSION = "dimension"; public static final String VALUE = "value"; public static final String PARAMETER = "integerParameter"; // public static final String RANDOMIZE = "randomize"; public String getParserName() { return PARAMETER; } public Object parseXMLObject(XMLObject xo) throws XMLParseException { int[] values = null; // double[] uppers; // double[] lowers; // if( xo.hasAttribute(DIMENSION) ) { // values = new int[xo.getIntegerAttribute(DIMENSION)]; // } if( xo.hasAttribute(VALUE) ) { if( values == null ) { values = xo.getIntegerArrayAttribute(VALUE); } else { int[] v = xo.getIntegerArrayAttribute(VALUE); if( v.length == values.length ) { System.arraycopy(v, 0, values, 0, v.length); } else if( v.length == 1 ) { for(int i = 0; i < values.length; i++) { values[i] = v[0]; } } else { throw new XMLParseException("value string must have 1 value or dimension values"); } } } else { if( xo.hasAttribute(DIMENSION) ) { values = new int[xo.getIntegerAttribute(DIMENSION)]; } else { // parameter dimension will get set correctly by TreeModel presumably. // if (!xo.hasChildNamed(RANDOMIZE)) { // return new Parameter.Default(1); // } values = new int[1]; values[0] = 0; } } // uppers = new double[values.length]; // for(int i = 0; i < values.length; i++) { // uppers[i] = Double.POSITIVE_INFINITY; // } // // lowers = new double[values.length]; // for(int i = 0; i < values.length; i++) { // lowers[i] = Double.NEGATIVE_INFINITY; // } // if( xo.hasAttribute(UPPER) ) { // double[] v = xo.getDoubleArrayAttribute(UPPER); // if( v.length == uppers.length ) { // System.arraycopy(v, 0, uppers, 0, v.length); // } else if( v.length == 1 ) { // for(int i = 0; i < uppers.length; i++) { // uppers[i] = v[0]; // } // } else { // throw new XMLParseException("uppers string must have 1 value or dimension values"); // } // } // // if( xo.hasAttribute(LOWER) ) { // double[] v = xo.getDoubleArrayAttribute(LOWER); // if( v.length == lowers.length ) { // System.arraycopy(v, 0, lowers, 0, v.length); // } else if( v.length == 1 ) { // for(int i = 0; i < lowers.length; i++) { // lowers[i] = v[0]; // } // } else { // throw new XMLParseException("lowers string must have 1 value or dimension values"); // } // } // assert uppers != null && lowers != null; // if( (uppers.length != values.length) ) { // throw new XMLParseException("value and upper limit strings have different dimension, in parameter"); // } // // if( (lowers.length != values.length) ) { // throw new XMLParseException("value and lower limit strings have different dimension, in parameter"); // } // // // check if uppers and lowers are consistent // for(int i = 0; i < values.length; i++) { // if( uppers[i] < lowers[i] ) { // throw new XMLParseException("upper is lower than lower, in parameter"); // } // } // // if (xo.hasChildNamed(RANDOMIZE)) { // // Distribution distribution = (Distribution) xo.getChild(RANDOMIZE).getChild(Distribution.class); // for (int i = 0; i < values.length; i++) { // do { // // Not an efficient way to draw random variables, but this is currently the only general interface // values[i] = distribution.quantile(MathUtils.nextDouble()); // } while (values[i] < lowers[i] || values[i] > uppers[i]); // } // // } else { // // // make values consistent with bounds // for(int i = 0; i < values.length; i++) { // if( uppers[i] < values[i] ) values[i] = uppers[i]; // } // // for(int i = 0; i < values.length; i++) { // if (lowers[i] > values[i]) values[i] = lowers[i]; // } // } Variable<Integer> param = new Variable.I(values); param.addBounds(new Bounds.Staircase(param)); return param; } public XMLSyntaxRule[] getSyntaxRules() { return rules; } private final XMLSyntaxRule[] rules = { AttributeRule.newIntegerArrayRule(VALUE, true), AttributeRule.newIntegerRule(DIMENSION, true), // AttributeRule.newDoubleArrayRule(UPPER, true), // AttributeRule.newDoubleArrayRule(LOWER, true), // new ElementRule(RANDOMIZE, new XMLSyntaxRule[] { // new ElementRule(Distribution.class), // },true), }; public String getParserDescription() { return "An integer-valued parameter only for staircase bound."; } public Class getReturnType() { return Variable.class; } // static public void replaceParameter(XMLObject xo, Parameter newParam) throws XMLParseException { // // for (int i = 0; i < xo.getChildCount(); i++) { // // if (xo.getChild(i) instanceof Parameter) { // // XMLObject rxo; // Object obj = xo.getRawChild(i); // // if (obj instanceof Reference ) { // rxo = ((Reference) obj).getReferenceObject(); // } else if (obj instanceof XMLObject) { // rxo = (XMLObject) obj; // } else { // throw new XMLParseException("object reference not available"); // } // // if (rxo.getChildCount() > 0) { // throw new XMLParseException("No child elements allowed in parameter element."); // } // // if (rxo.hasAttribute(XMLParser.IDREF)) { // throw new XMLParseException("References to " + xo.getName() + " parameters are not allowed in treeModel."); // } // // if (rxo.hasAttribute(VALUE)) { // throw new XMLParseException("Parameters in " + xo.getName() + " have values set automatically."); // } // //// if (rxo.hasAttribute(UPPER)) { //// throw new XMLParseException("Parameters in " + xo.getName() + " have bounds set automatically."); //// } //// //// if (rxo.hasAttribute(LOWER)) { //// throw new XMLParseException("Parameters in " + xo.getName() + " have bounds set automatically."); //// } // // if (rxo.hasAttribute(XMLParser.ID)) { // newParam.setId(rxo.getStringAttribute(XMLParser.ID)); // } // // rxo.setNativeObject(newParam); // // return; // } // } // } // static public Parameter getParameter(XMLObject xo) throws XMLParseException { // // int paramCount = 0; // Parameter param = null; // for (int i = 0; i < xo.getChildCount(); i++) { // if (xo.getChild(i) instanceof Parameter) { // param = (Parameter) xo.getChild(i); // paramCount += 1; // } // } // // if (paramCount == 0) { // throw new XMLParseException("no parameter element in treeModel " + xo.getName() + " element"); // } else if (paramCount > 1) { // throw new XMLParseException("More than one parameter element in treeModel " + xo.getName() + " element"); // } // // return param; // } }