/// <summary> /// Nonlinear Least Squares Solver. Fx = F(x). minimizes Norm_2(F(x)) /// </summary> /// <param name="F">objective function</param> /// <param name="x">input values, initial guess to start, solution on exit</param> /// <param name="Fx">function values, just zero to start, solution on exit</param> /// <param name="eps">precisions for stop-criteria, defaults to all 1e-9</param> /// <param name="iter1">maximum number of iterations, defaults of 1000</param> /// <param name="iter2">maximum number of iterations of calculation of trial-step, default of 100</param> /// <param name="rs">initial step bound (0.1 - 100.0 recommended), default of 0.0 which MKL defaults as 100.0</param> /// <param name="jeps">precision of the Jacobian matrix calculation</param> /// <returns>stop criterion</returns> public static SolveResult NonLinearLeastSquares(Action <double[], double[]> F, double[] x, double[] Fx, double[] eps, int iter1 = 100, int iter2 = 10, double rs = 0.0, double jeps = 1e-7) { int n = x.Length; int m = Fx.Length; var jac = new double[n * m]; var f1 = new double[m]; var f2 = new double[m]; fixed(double *xp = &x[0], epsp = &eps[0], Fxp = &Fx[0], jacp = &jac[0], f1p = &f1[0], f2p = &f2[0]) { IntPtr handle; int request; int status = dtrnlsp_init(&handle, &n, &m, xp, epsp, &iter1, &iter2, &rs); while (status == SUCCESS && (status = dtrnlsp_solve(&handle, Fxp, jacp, &request)) == SUCCESS) { if (request == CALCULATE_FUNCTION) { if (MKL.IsNaN(x)) { return(SolveResult.NAN_PARAMETER); } F(x, Fx); } else if (request == CALCULATE_JACOBIAN) { IntPtr jacHandle; int jacRequest; status = djacobi_init(&jacHandle, &n, &m, xp, jacp, &jeps); if (status == SUCCESS) { while ((status = djacobi_solve(&jacHandle, f1p, f2p, &jacRequest)) == SUCCESS && jacRequest != 0) { if (MKL.IsNaN(x)) { return(SolveResult.NAN_PARAMETER); } F(x, jacRequest == 1 ? f1 : f2); } } djacobi_delete(&jacHandle); } else if (request != ONE_ITERATION) { status = request; break; } } dtrnlsp_delete(&handle); return((SolveResult)status); } }
/// <summary> /// Nonlinear Least Squares Solver. Fx = F(x). minimizes Norm_2(F(x)) /// </summary> /// <param name="F">objective function</param> /// <param name="J">Jacobian function, J_ij = df_i / dx_j as a column major array</param> /// <param name="x">input values, initial guess to start, solution on exit</param> /// <param name="Fx">function values, just zero to start, solution on exit</param> /// <param name="eps">precisions for stop-criteria, defaults to all 1e-9</param> /// <param name="iter1">maximum number of iterations, defaults of 1000</param> /// <param name="iter2">maximum number of iterations of calculation of trial-step, default of 100</param> /// <param name="rs">initial step bound (0.1 - 100.0 recommended), default of 0.0 which MKL defaults as 100.0</param> /// <returns>stop criterion</returns> public static SolveResult NonLinearLeastSquares(SolveFn F, Action <double[], double[]> J, double[] x, double[] Fx, double[] eps, int iter1 = 100, int iter2 = 10, double rs = 0.0) { int n = x.Length; int m = Fx.Length; var jac = new double[n * m]; fixed(double *xp = &x[0], epsp = &eps[0], Fxp = &Fx[0], jacp = &jac[0]) { IntPtr handle; int request; var status = dtrnlsp_init(&handle, &n, &m, xp, epsp, &iter1, &iter2, &rs); if (status == SUCCESS) { while ((status = dtrnlsp_solve(&handle, Fxp, jacp, &request)) == SUCCESS) { if (request == CALCULATE_FUNCTION) { if (MKL.IsNaN(x)) { return(SolveResult.NAN_PARAMETER); } F(&m, &n, xp, Fxp); } else if (request == CALCULATE_JACOBIAN) { if (MKL.IsNaN(x)) { return(SolveResult.NAN_PARAMETER); } J(x, jac); } else if (request != ONE_ITERATION) { status = request; break; } } } dtrnlsp_delete(&handle); return((SolveResult)status); } }
/// <summary> /// Nonlinear Least Squares Solver. Fx = F(x). minimizes Norm_2(F(x)) /// </summary> /// <param name="F">objective function, not called in parallel</param> /// <param name="x">input values, initial guess to start, solution on exit</param> /// <param name="lower">x lower bound</param> /// <param name="upper">x upper bound</param> /// <param name="Fx">function values, just zero to start, solution on exit</param> /// <param name="eps">precisions for stop-criteria, defaults to all 1e-9</param> /// <param name="iter1">maximum number of iterations, defaults of 1000</param> /// <param name="iter2">maximum number of iterations of calculation of trial-step, default of 100</param> /// <param name="rs">initial step bound (0.1 - 100.0 recommended), default of 0.0 which MKL defaults as 100.0</param> /// <param name="jeps">precision of the Jacobian matrix calculation</param> /// <returns>stop criterion</returns> public static SolveResult NonLinearLeastSquaresBounded(Action <double[], double[]> F, double[] x, double[] lower, double[] upper, double[] Fx, double[] eps, int iter1 = 100, int iter2 = 10, double rs = 0.1, double jeps = 1e-7) { //1. dtrnlsp_init(ref handle, ref n, ref m, x, eps, ref iter1, ref iter2, ref rs) //2.dtrnlsp_check(ref handle, ref n, ref m, fjac, fvec, eps, info) //3.LOOP dtrnlsp_solve(ref handle, fvec, fjac, ref RCI_Request) //4.dtrnlsp_get(ref handle, ref iter, ref st_cr, ref r1, ref r2) //5.dtrnlsp_delete(ref handle) int n = x.Length; int m = Fx.Length; var jac = new double[n * m]; var f1 = new double[m]; var f2 = new double[m]; fixed(double *xp = &x[0], lowerp = &lower[0], upperp = &upper[0], epsp = &eps[0], Fxp = &Fx[0], jacp = &jac[0], f1p = &f1[0], f2p = &f2[0]) { IntPtr handle; int RCI_request; int status = dtrnlspbc_init(&handle, &n, &m, xp, lowerp, upperp, epsp, &iter1, &iter2, &rs); while (status == SUCCESS && (status = dtrnlspbc_solve(&handle, Fxp, jacp, &RCI_request)) == SUCCESS) { if (RCI_request == CALCULATE_FUNCTION) { if (MKL.IsNaN(x)) { return(SolveResult.NAN_PARAMETER); } F(x, Fx); } else if (RCI_request == CALCULATE_JACOBIAN) { IntPtr jacHandle; int jacRequest; status = djacobi_init(&jacHandle, &n, &m, xp, jacp, &jeps); if (status == SUCCESS) { while ((status = djacobi_solve(&jacHandle, f1p, f2p, &jacRequest)) == SUCCESS && jacRequest != 0) { if (MKL.IsNaN(x)) { return(SolveResult.NAN_PARAMETER); } F(x, jacRequest == 1 ? f1 : f2); } } djacobi_delete(&jacHandle); } else if (RCI_request != ONE_ITERATION) { status = RCI_request; break; } } dtrnlspbc_delete(&handle); return((SolveResult)status); } }