public override EndCriteria.Type minimize(Problem P, EndCriteria endCriteria) {
EndCriteria.Type ecType = EndCriteria.Type.None;
P.reset();
Vector x_ = P.currentValue();
currentProblem_ = P;
initCostValues_ = P.costFunction().values(x_);
int m = initCostValues_.size();
int n = x_.size();
Vector xx = new Vector(x_);
Vector fvec = new Vector(m), diag = new Vector(n);
int mode = 1;
double factor = 1;
int nprint = 0;
int info = 0;
int nfev =0;
Matrix fjac = new Matrix(m, n);
int ldfjac = m;
List<int> ipvt = new InitializedList<int>(n);
Vector qtf = new Vector(n), wa1 = new Vector(n), wa2 = new Vector(n), wa3 = new Vector(n), wa4 = new Vector(m);
// call lmdif to minimize the sum of the squares of m functions
// in n variables by the Levenberg-Marquardt algorithm.
MINPACK.lmdif(m, n, xx, ref fvec,
endCriteria.functionEpsilon(),
xtol_,
gtol_,
endCriteria.maxIterations(),
epsfcn_,
diag, mode, factor,
nprint, ref info, ref nfev, ref fjac,
ldfjac, ref ipvt, ref qtf,
wa1, wa2, wa3, wa4,
fcn);
info_ = info;
// check requirements & endCriteria evaluation
if(info == 0) throw new ApplicationException("MINPACK: improper input parameters");
//if(info == 6) throw new ApplicationException("MINPACK: ftol is too small. no further " +
// "reduction in the sum of squares is possible.");
if (info != 6) ecType = EndCriteria.Type.StationaryFunctionValue;
//QL_REQUIRE(info != 5, "MINPACK: number of calls to fcn has reached or exceeded maxfev.");
endCriteria.checkMaxIterations(nfev, ref ecType);
if(info == 7) throw new ApplicationException("MINPACK: xtol is too small. no further " +
"improvement in the approximate " +
"solution x is possible.");
if(info == 8) throw new ApplicationException("MINPACK: gtol is too small. fvec is " +
"orthogonal to the columns of the " +
"jacobian to machine precision.");
// set problem
x_ = new Vector(xx.GetRange(0, n));
P.setCurrentValue(x_);
P.setFunctionValue(P.costFunction().value(x_));
return ecType;
}