final MixedLogNormalModelData[] modelParams = new MixedLogNormalModelData[n - 2];
double[] errors = new double[n];
Arrays.fill(errors, 0.0001); //1bps
final SmileModelFitter<MixedLogNormalModelData> globalFitter = new MixedLogNormalModelFitter(forward, strikes, expiry, impliedVols, errors, MODEL, 2, true);
final BitSet fixed = new BitSet();
if (n == 3 || !_globalBetaSearch) {
fixed.set(1); //fixed beta
}
//do a global fit first
final LeastSquareResultsWithTransform gRes = globalFitter.solve(start, fixed);
if (n == 3) {
if (gRes.getChiSq() / n > 1.0) {
s_logger.warn("chi^2 on SABR fit to ", +n + " points is " + gRes.getChiSq());
}
modelParams[0] = new MixedLogNormalModelData(gRes.getModelParameters().getData());
} else {
//impose a global beta on the remaining 3 point fits
//final double[] gFitParms = gRes.getModelParameters().getData();
//final double theta = gFitParms[2];
//start = new DoubleMatrix1D(gFitParms[0], gFitParms[1], gFitParms[3]);
start = gRes.getModelParameters();
fixed.set(2); //fixed weight
//final BroydenVectorRootFinder rootFinder = new BroydenVectorRootFinder(1e-8, 1e-8, 100, new SVDecompositionCommons());
double[] tStrikes = new double[4];
double[] tVols = new double[4];
for (int i = 0; i < n - 2; i++) {
tStrikes = Arrays.copyOfRange(strikes, i, i + 3);
tVols = Arrays.copyOfRange(impliedVols, i, i + 3);
errors = new double[3];
Arrays.fill(errors, 0.0001); //1bps
// Function1D<DoubleMatrix1D, DoubleMatrix1D> func = getVolDiffFunc(forward, tStrikes, expiry, tVols, theta);
// Function1D<DoubleMatrix1D, DoubleMatrix2D> jac = getVolJacFunc(forward, tStrikes, expiry, theta);
// NonLinearTransformFunction tf = new NonLinearTransformFunction(func, jac, TRANSFORM);
//
// DoubleMatrix1D res = rootFinder.getRoot(tf.getFittingFunction(),tf.getFittingJacobian(), start);
// double[] root = TRANSFORM.inverseTransform(res).getData();
final SmileModelFitter<MixedLogNormalModelData> fitter = new MixedLogNormalModelFitter(forward, tStrikes, expiry, tVols, errors, MODEL, 2, true);
final LeastSquareResultsWithTransform lRes = fitter.solve(start, fixed);
if (lRes.getChiSq() > 3.0) {
s_logger.warn("chi^2 on 3-point SABR fit #" + i + " is " + lRes.getChiSq());
}
modelParams[i] = new MixedLogNormalModelData(lRes.getModelParameters().getData());