/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.math.minimization;
import com.opengamma.analytics.math.MathException;
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.MatrixAlgebraFactory;
import com.opengamma.analytics.math.minimization.QuasiNewtonVectorMinimizer.DataBundle;
/**
*
*/
public class BroydenFletcherGoldfarbShannoInverseHessianUpdate implements QuasiNewtonInverseHessianUpdate {
private static final MatrixAlgebra MA = MatrixAlgebraFactory.getMatrixAlgebra("OG");
@Override
public void update(final DataBundle data) {
final DoubleMatrix1D hDeltaGrad = (DoubleMatrix1D) MA.multiply(data.getInverseHessianEsimate(), data.getDeltaGrad());
final double deltaXdeltaGrad = MA.getInnerProduct(data.getDeltaX(), data.getDeltaGrad());
final double deltaGradHdeltaGrad = MA.getInnerProduct(data.getDeltaGrad(), hDeltaGrad);
if (deltaXdeltaGrad == 0.0) {
throw new MathException("The dot product of the change in position and the change in gradient is zero");
}
if (deltaGradHdeltaGrad == 0.0) {
throw new MathException("Most likely the change in gradient is zero - should have exited");
}
final DoubleMatrix2D tempMat1 = MA.getOuterProduct(MA.scale(data.getDeltaX(), 1.0 / deltaXdeltaGrad), data.getDeltaX());
final DoubleMatrix2D tempMat2 = MA.getOuterProduct(MA.scale(hDeltaGrad, -1.0 / deltaGradHdeltaGrad), hDeltaGrad);
final DoubleMatrix1D u = (DoubleMatrix1D) MA.subtract(MA.scale(data.getDeltaX(), 1.0 / deltaXdeltaGrad), MA.scale(hDeltaGrad, deltaGradHdeltaGrad));
final DoubleMatrix2D tempMat3 = MA.getOuterProduct(MA.scale(u, deltaGradHdeltaGrad), u);
final DoubleMatrix2D res = (DoubleMatrix2D) MA.add(data.getInverseHessianEsimate(), MA.add(tempMat1, MA.add(tempMat2, tempMat3)));
data.setInverseHessianEsimate(res);
}
}