@Override public LeastSquareResultsWithTransform getFitResult( final EuropeanVanillaOption[] options, final BlackFunctionData[] data, final double[] errors, final double[] initialFitParameters, final BitSet fixed) { testData(options, data, errors, initialFitParameters, fixed, N_PARAMETERS); final int n = options.length; final double forward = data[0].getForward(); 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])); }