/* * DiscretizedLociRates.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.oldevomodel.sitemodel; import dr.inference.model.*; import dr.inference.distribution.ParametricDistributionModel; /** * @author Chieh-Hsi Wu * * This class models the relative loci rates using the given discritized parametric distribution. */ public class DiscretizedLociRates extends AbstractModel { private CompoundParameter lociRates; private Parameter rateCategoryParameter; private ParametricDistributionModel distrModel; private double normalizeRateTo; private double[] rates; private boolean normalize; private int categoryCount; private double scaleFactor; private boolean completeSetup; public DiscretizedLociRates( CompoundParameter lociRates, Parameter rateCategoryParameter, ParametricDistributionModel model, boolean normalize, double normalizeLociRateTo, int categoryCount) { super("DiscretizedLociRatesModel"); this.lociRates = lociRates; this.rateCategoryParameter = rateCategoryParameter; //Force the boundaries of rateCategoryParameter to match the category count Parameter.DefaultBounds bound = new Parameter.DefaultBounds(categoryCount - 1, 0, rateCategoryParameter.getDimension()); this.rateCategoryParameter.addBounds(bound); this.distrModel = model; this.normalizeRateTo = normalizeLociRateTo; this.normalize = normalize; this.categoryCount = categoryCount; rates = new double[categoryCount]; completeSetup = true; setupRates(); addModel(distrModel); addVariable(this.rateCategoryParameter); } private void setupRates(){ if(completeSetup){ double categoryIntervalSize = 1.0/categoryCount; for(int i = 0; i < categoryCount; i++){ rates[i]= distrModel.quantile((i+0.5)*categoryIntervalSize); } } if(normalize){ computeFactor(); } completeSetup = false; int lociCount = rateCategoryParameter.getDimension(); for(int i = 0; i < lociCount; i ++){ lociRates.setParameterValue(i,rates[(int)rateCategoryParameter.getParameterValue(i)]*scaleFactor); } } public void handleModelChangedEvent(Model model, Object object, int index) { if (model == distrModel) { completeSetup = true; setupRates(); //System.out.println("speed investigation 1"); fireModelChanged(); }else if (model == rateCategoryParameter) { //System.out.println("speed investigation 2"); setupRates(); fireModelChanged(null, index); } } protected final void handleVariableChangedEvent(Variable variable, int index, Parameter.ChangeType type) { //System.out.println("speed investigation 3"); setupRates(); fireModelChanged(null, index); } protected void storeState() { } protected void acceptState() { } protected void restoreState() { //setupRates(); } private void computeFactor(){ double sumRates = 0.0; int lociCount = rateCategoryParameter.getDimension(); for(int i = 0; i < lociCount; i++){ sumRates += rates[(int)rateCategoryParameter.getParameterValue(i)]; } scaleFactor = normalizeRateTo/(sumRates/lociCount); } }