final double maturity = options[0].getTimeToExpiry();
for (int i = 1; i < n; i++) {
Validate.isTrue(CompareUtils.closeEquals(options[i].getTimeToExpiry(), maturity),
"All options must have the same maturity " + maturity + "; have one with maturity " + options[i].getTimeToExpiry());
}
final UncoupledParameterTransforms transforms = new UncoupledParameterTransforms(new DoubleMatrix1D(initialFitParameters), TRANSFORMS, fixed);
final Function1D<DoubleMatrix1D, Double> function = new Function1D<DoubleMatrix1D, Double>() {
@SuppressWarnings("synthetic-access")
@Override
public Double evaluate(final DoubleMatrix1D fp) {
final DoubleMatrix1D mp = transforms.inverseTransform(fp);
final double alpha = mp.getEntry(0);
final double beta = mp.getEntry(1);
final double nu = mp.getEntry(2);
final double rho = mp.getEntry(3);
double chiSqr = 0;
final SABRFormulaData sabrFormulaData = new SABRFormulaData(alpha, beta, rho, nu);
for (int i = 0; i < n; i++) {
chiSqr += FunctionUtils.square((data[i].getBlackVolatility() - _formula.getVolatilityFunction(options[i], forward).evaluate(sabrFormulaData)) / errors[i]);
}
return chiSqr;
}
};
final ScalarMinimizer lineMinimizer = new BrentMinimizer1D();
final ConjugateDirectionVectorMinimizer minimzer = new ConjugateDirectionVectorMinimizer(lineMinimizer, 1e-6, 10000);
final DoubleMatrix1D fp = transforms.transform(new DoubleMatrix1D(initialFitParameters));
final DoubleMatrix1D minPos = minimzer.minimize(function, fp);
final double chiSquare = function.evaluate(minPos);
final DoubleMatrix1D res = transforms.inverseTransform(minPos);
return new LeastSquareResultsWithTransform(new LeastSquareResults(chiSquare, res, new DoubleMatrix2D(new double[N_PARAMETERS][N_PARAMETERS])), transforms);
// return new LeastSquareResults(chiSquare, res, new DoubleMatrix2D(new double[N_PARAMETERS][N_PARAMETERS]));
}