/** * Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.analytics.math.statistics.leastsquare; import org.apache.commons.lang.Validate; import com.opengamma.analytics.math.matrix.DoubleMatrix1D; import com.opengamma.analytics.math.matrix.DoubleMatrix2D; import com.opengamma.analytics.math.matrix.MatrixAlgebra; import com.opengamma.analytics.math.matrix.OGMatrixAlgebra; import com.opengamma.analytics.math.minimization.NonLinearParameterTransforms; /** * Container for the results of a least square (minimum chi-square) fit, where some model (with a set of parameters), is calibrated * to a data set, but the model parameters are first transformed to some fitting parameters (usually to impose some constants). */ public class LeastSquareResultsWithTransform extends LeastSquareResults { private static final MatrixAlgebra MA = new OGMatrixAlgebra(); private final NonLinearParameterTransforms _transform; private final DoubleMatrix1D _modelParameters; private DoubleMatrix2D _inverseJacobianModelPararms; public LeastSquareResultsWithTransform(final LeastSquareResults transformedFitResult) { super(transformedFitResult); _transform = null; _modelParameters = transformedFitResult.getFitParameters(); _inverseJacobianModelPararms = getFittingParameterSensitivityToData(); } public LeastSquareResultsWithTransform(final LeastSquareResults transformedFitResult, final NonLinearParameterTransforms transform) { super(transformedFitResult); Validate.notNull(transform, "null transform"); _transform = transform; _modelParameters = transform.inverseTransform(getFitParameters()); } public DoubleMatrix1D getModelParameters() { return _modelParameters; } /** * This a matrix where the i,jth element is the (infinitesimal) sensitivity of the ith fitting parameter to the jth data * point (NOT the model point), when the fitting parameter are such that the chi-squared is minimised. So it is a type of (inverse) * Jacobian, but should not be confused with the model jacobian (sensitivity of model data points, to parameters) or its inverse. * @return a matrix */ public DoubleMatrix2D getModelParameterSensitivityToData() { if (_inverseJacobianModelPararms == null) { setModelParameterSensitivityToData(); } return _inverseJacobianModelPararms; } private void setModelParameterSensitivityToData() { DoubleMatrix2D invJac = _transform.inverseJacobian(getFitParameters()); _inverseJacobianModelPararms = (DoubleMatrix2D) MA.multiply(invJac, getFittingParameterSensitivityToData()); } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((_inverseJacobianModelPararms == null) ? 0 : _inverseJacobianModelPararms.hashCode()); result = prime * result + ((_modelParameters == null) ? 0 : _modelParameters.hashCode()); result = prime * result + ((_transform == null) ? 0 : _transform.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!super.equals(obj)) { return false; } if (getClass() != obj.getClass()) { return false; } LeastSquareResultsWithTransform other = (LeastSquareResultsWithTransform) obj; if (_inverseJacobianModelPararms == null) { if (other._inverseJacobianModelPararms != null) { return false; } } else if (!_inverseJacobianModelPararms.equals(other._inverseJacobianModelPararms)) { return false; } if (_modelParameters == null) { if (other._modelParameters != null) { return false; } } else if (!_modelParameters.equals(other._modelParameters)) { return false; } if (_transform == null) { if (other._transform != null) { return false; } } else if (!_transform.equals(other._transform)) { return false; } return true; } @Override public String toString() { return "LeastSquareResults [chiSq=" + getChiSq() + ", fit parameters=" + getFitParameters().toString() + ", model parameters= " + getModelParameters().toString() + ", covariance=" + getCovariance().toString() + "]"; } }