/*
* LatentFactorModelParser.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.inferencexml.model;
import dr.inference.model.*;
import dr.xml.*;
/**
* @author Max Tolkoff
* @author Marc Suchard
*/
public class LatentFactorModelParser extends AbstractXMLObjectParser {
public final static String LATENT_FACTOR_MODEL = "latentFactorModel";
public final static String NUMBER_OF_FACTORS = "factorNumber";
public final static String FACTORS = "factors";
public final static String DATA = "data";
public final static String LOADINGS = "loadings";
public static final String ROW_PRECISION = "rowPrecision";
public static final String COLUMN_PRECISION = "columnPrecision";
public static final String SCALE_DATA="scaleData";
public static final String CONTINUOUS="continuous";
public static final String COMPUTE_RESIDUALS_FOR_DISCRETE="computeResidualsForDiscrete";
public static final String RECOMPUTE_RESIDUALS="recomputeResiduals";
public static final String RECOMPUTE_FACTORS="recomputeFactors";
public static final String RECOMPUTE_LOADINGS="recomputeLoadings";
public static final String MISSING_INDICATOR = "missingIndicator";
public String getParserName() {
return LATENT_FACTOR_MODEL;
}
public Object parseXMLObject(XMLObject xo) throws XMLParseException {
MatrixParameterInterface factors;
if (xo.getChild(FACTORS).getChild(FastMatrixParameter.class) == null)
{
CompoundParameter factorsTemp = (CompoundParameter) xo.getChild(FACTORS).getChild(CompoundParameter.class);
factors = MatrixParameter.recast(factorsTemp.getParameterName(), factorsTemp);
}
else {
factors = (MatrixParameterInterface) xo.getChild(FACTORS).getChild(MatrixParameterInterface.class);
}
MatrixParameterInterface dataParameter = (MatrixParameterInterface) xo.getChild(DATA).getChild(MatrixParameterInterface.class);
MatrixParameterInterface loadings = (MatrixParameterInterface) xo.getChild(LOADINGS).getChild(MatrixParameterInterface.class);
Parameter missingIndicator = null;
if(xo.hasChildNamed(MISSING_INDICATOR))
missingIndicator = (Parameter) xo.getChild(MISSING_INDICATOR).getChild(Parameter.class);
DiagonalMatrix rowPrecision = (DiagonalMatrix) xo.getChild(ROW_PRECISION).getChild(MatrixParameter.class);
DiagonalMatrix colPrecision = (DiagonalMatrix) xo.getChild(COLUMN_PRECISION).getChild(MatrixParameter.class);
boolean newModel= xo.getAttribute(COMPUTE_RESIDUALS_FOR_DISCRETE, true);
boolean computeResiduals= xo.getAttribute(RECOMPUTE_RESIDUALS, true);
boolean computeFactors=xo.getAttribute(RECOMPUTE_FACTORS, true);
boolean computeLoadings=xo.getAttribute(RECOMPUTE_LOADINGS, true);
Parameter continuous=null;
if(xo.getChild(CONTINUOUS)!=null)
continuous=(Parameter) xo.getChild(CONTINUOUS).getChild(Parameter.class);
else
continuous=new Parameter.Default(colPrecision.getRowDimension(), 1.0);
boolean scaleData=xo.getAttribute(SCALE_DATA, true);
// int numFactors = xo.getAttribute(NUMBER_OF_FACTORS, 4);
Parameter temp=null;
// for(int i=0; i<loadings.getColumnDimension(); i++)
// {
// if(loadings.getParameterValue(i,i)<0)
// {
// loadings.setParameterValue(i, i, temp.getParameterValue(i));
// }
// }
return new LatentFactorModel(dataParameter, factors, loadings, rowPrecision, colPrecision, missingIndicator, scaleData, continuous, newModel, computeResiduals, computeFactors, computeLoadings);
}
private static final XMLSyntaxRule[] rules = {
AttributeRule.newIntegerRule(NUMBER_OF_FACTORS),
AttributeRule.newBooleanRule(SCALE_DATA, true),
AttributeRule.newBooleanRule(COMPUTE_RESIDUALS_FOR_DISCRETE, true),
AttributeRule.newBooleanRule(RECOMPUTE_FACTORS, true),
AttributeRule.newBooleanRule(RECOMPUTE_RESIDUALS, true),
AttributeRule.newBooleanRule(RECOMPUTE_LOADINGS,true),
new ElementRule(DATA, new XMLSyntaxRule[]{
new ElementRule(MatrixParameterInterface.class),
}),
new ElementRule(FACTORS, new XMLSyntaxRule[]{
new ElementRule(CompoundParameter.class)
}),
new ElementRule(LOADINGS, new XMLSyntaxRule[]{
new ElementRule(MatrixParameterInterface.class)
}),
new ElementRule(ROW_PRECISION, new XMLSyntaxRule[]{
new ElementRule(DiagonalMatrix.class)
}),
new ElementRule(COLUMN_PRECISION, new XMLSyntaxRule[]{
new ElementRule(DiagonalMatrix.class)
}),
new ElementRule(CONTINUOUS, new XMLSyntaxRule[]{
new ElementRule(Parameter.class)
}, true),
new ElementRule(MISSING_INDICATOR, new XMLSyntaxRule[]{
new ElementRule(Parameter.class)
}, true),
};
// <latentFactorModel>
// <factors>
// <parameter idref="factors"/>
// </factors>
// </latentFactorModel>
public XMLSyntaxRule[] getSyntaxRules() {
return rules;
}
@Override
public String getParserDescription() {
return "Sets up a latent factor model, with starting guesses for the loadings and factor matrices as well as the data for the factor analysis";
}
@Override
public Class getReturnType() {
return LatentFactorModel.class;
}
}