public IEnumerable <double> SolveOptimizationProblem(double precision = 1.0e-8d) { #region check parameters if (mEventsSpaceVector == null) { throw new NotSetRequiredParametersException("x space values vector is null"); return(null); } if (mFittingValuesVector == null) { throw new NotSetRequiredParametersException("fitting values vector is null"); return(null); } if (nParametersSpacePoint == null) { throw new NotSetRequiredParametersException("initial guess X vector is null"); return(null); } if (fittingFunction == null) { throw new NotSetRequiredParametersException("fitting function has not been set"); return(null); } if (lowerBoundConstraints == null) { throw new NotSetRequiredParametersException("lower bound constraints has not been set"); return(null); } if (upperBoundConstraints == null) { throw new NotSetRequiredParametersException("upper bound constraints has not been set"); return(null); } #endregion check parameters int m = mFittingValuesVector.Count(); mEventsSetLength = mEventsSpaceVector.Count(); //nParametersLength = nParametersSpacePoint.Count(); nParametersLength = nParametersSpacePoint.Count(); double[] eps = new double[6] { precision, precision, precision, precision, precision, precision }; int iter1 = 100000; int iter2 = 10000; int RCI_Request = 0; double rs = 0.0d; bool successful = false; double r1 = 0.0d; double r2 = 0.0d; int[] check_info = new int[6] { 0, 0, 0, 0, 0, 0 }; double[] theta = nParametersSpacePoint.ToArray(); double[] fVec = ObjectiveFunctional(theta).ToArray(); double[,] fJacobi = new double[m, nParametersLength]; double[] lwBC = lowerBoundConstraints.ToArray(); double[] upBC = upperBoundConstraints.ToArray(); for (int i = 0; i < m; i++) { for (int j = 0; j < nParametersLength; j++) { fJacobi[i, j] = 0.0d; } } unsafe { fixed(double *xPtr = &theta[0], fVecPtr = &fVec[0], fJacPtr = &fJacobi[0, 0], lwBCptr = &lwBC[0], upBCptr = &upBC[0], epsPtr = &eps[0]) { int init_res = NonLinLeastSqProbWithBCNative.dtrnlspbc_init(ref solverHandle, ref nParametersLength, ref m, (IntPtr)xPtr, (IntPtr)lwBCptr, (IntPtr)upBCptr, (IntPtr)epsPtr, ref iter1, ref iter2, ref rs); if (init_res != MKLwrapper.DEFINE.TR_SUCCESS) { DeleteAndFreeBuffers(); return(theta); } int check_res = NonLinLeastSqProbWithBCNative.dtrnlspbc_check(ref solverHandle, ref nParametersLength, ref m, (IntPtr)fJacPtr, (IntPtr)fVecPtr, (IntPtr)lwBCptr, (IntPtr)upBCptr, (IntPtr)epsPtr, check_info); if (check_res != MKLwrapper.DEFINE.TR_SUCCESS) { DeleteAndFreeBuffers(); return(theta); } else { if (check_info.Sum() > 0) { resultStatus = "input parameters aren`t valid."; DeleteAndFreeBuffers(); return(nParametersSpacePoint); } } while (!successful) { int solve_res = NonLinLeastSqProbWithBCNative.dtrnlspbc_solve(ref solverHandle, (IntPtr)fVecPtr, (IntPtr)fJacPtr, ref RCI_Request); if (solve_res != MKLwrapper.DEFINE.TR_SUCCESS) { resultStatus = "error in dtrnlsp_solve"; DeleteAndFreeBuffers(); return(nParametersSpacePoint); } if (RCI_Request == -1 || RCI_Request == -2 || RCI_Request == -3 || RCI_Request == -4 || RCI_Request == -5 || RCI_Request == -6) { successful = true; } if (RCI_Request == 1) { double[] newFVecValues = ObjectiveFunctional(theta).ToArray(); for (int i = 0; i < m; i++) { fVec[i] = newFVecValues[i]; } resultStatus = ""; } if (RCI_Request == 2) { JacobianMatrixCalc jCalculator = new JacobianMatrixCalc(); //jCalculator.mSpaceVector = (new List<double>(mSpaceVector)).ToArray(); //jCalculator.mFittingValuesVector = (new List<double>(mFittingValuesVector)).ToArray(); jCalculator.mEventsPointsSetLength = mFittingValuesVector.Count(); jCalculator.nParametersSpacePoint = (new List <double>(theta)).ToArray(); jCalculator.objectiveFunction = t => ObjectiveFunctional(t).ToArray(); if (fittingFunctionPartDeriv != null) { double[,] tmpNewJacobiAnalytic = ObjectiveFunctionalJacobianMatrix(theta); #region // debugging test //DenseMatrix dmJacDev = DenseMatrix.OfArray(tmpNewJacobi) - // DenseMatrix.OfArray(tmpNewJacobiAnalytic); //dmJacDev.MapInplace(dVal => Math.Abs(dVal)); //double debugSum = (dmJacDev.ColumnAbsoluteSums()).Sum(); //debugSum = Math.Sqrt(debugSum); #endregion // debugging test System.Array.Copy(tmpNewJacobiAnalytic, fJacobi, tmpNewJacobiAnalytic.Length); } else { double[,] tmpNewJacobi = jCalculator.SolveJacobianMatrix(precision); System.Array.Copy(tmpNewJacobi, fJacobi, tmpNewJacobi.Length); } //for (int i = 0; i < m; i++) //{ // for (int j = 0; j < n; j++) // { // fJacobi[i, j] = tmpNewJacobi[i, j]; // } //} resultStatus = ""; } } } } int iterationsMade = 0; int stopCriterion = 0; if (NonLinLeastSqProbWithBCNative.dtrnlspbc_get(ref solverHandle, ref iterationsMade, ref stopCriterion, ref r1, ref r2) != MKLwrapper.DEFINE.TR_SUCCESS) { resultStatus = "error in dtrnlsp_get"; DeleteAndFreeBuffers(); return(theta); } DeleteAndFreeBuffers(); // stopCriterion // 1 The algorithm has exceeded the maximum number of iterations // 2 Δ < eps(1) // 3 ||F(x)||_2 < eps(2) // 4 The Jacobian matrix is singular. // ||J(x)(1:m,j)||_2 < eps(3), j = 1, ..., n // 5 ||s||_2 < eps(4) // 6 ||F(x)||_2 - ||F(x) - J(x)s||_2 < eps(5) resultStatus = "stopping criterion reached: "; switch (stopCriterion) { case 1: resultStatus += "The algorithm has exceeded the maximum number of iterations"; break; case 2: resultStatus += "Δ < precision(1)"; break; case 3: resultStatus += "||F(x)||_2 < precision(2)"; break; case 4: resultStatus += "The Jacobian matrix is singular"; break; case 5: resultStatus += "||s||_2 < precision(4)"; break; case 6: resultStatus += "||F(x)||_2 - ||F(x) - J(x)s||_2 < precision(5)"; break; default: break; } if (r2 < precision) { resultStatus += Environment.NewLine + "optimization passed successfully" + Environment.NewLine + "precision reached: " + r2 + Environment.NewLine + "precision needed : " + precision; return(theta); } else { resultStatus += Environment.NewLine + "optimization failed" + Environment.NewLine + "precision reached: " + r2 + Environment.NewLine + "precision needed : " + precision; return(theta); } }
public IEnumerable <double> SolveOptimizationProblem(double precision = 1.0e-8d) { if (mSpaceVector == null) { throw new NotSetRequiredParametersException("x space values vector is null"); return(null); } if (mFittingValuesVector == null) { throw new NotSetRequiredParametersException("fitting values vector is null"); return(null); } if (nXspacePoint == null) { throw new NotSetRequiredParametersException("initial guess X vector is null"); return(null); } if (fittingFunction == null) { throw new NotSetRequiredParametersException("fitting function has not been set"); return(null); } int m = mFittingValuesVector.Count(); int n = nXspacePoint.Count(); double[] eps = new double[6] { precision, precision, precision, precision, precision, precision }; int iter1 = 100000; int iter2 = 10000; int RCI_Request = 0; double rs = 0.0d; bool successful = false; double r1 = 0.0d; double r2 = 0.0d; int[] check_info = new int[6] { 0, 0, 0, 0, 0, 0 }; double[] x = nXspacePoint.ToArray(); double[] fVec = ObjectiveFunctional(x).ToArray(); double[,] fJacobi = new double[m, n]; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { fJacobi[i, j] = 0.0d; } } unsafe { fixed(double *xPtr = &x[0], fVecPtr = &fVec[0], fJacPtr = &fJacobi[0, 0]) { int init_res = NonLinLeastSqProbWoConstraintsNative.dtrnlsp_init(ref solverHandle, ref n, ref m, (IntPtr)xPtr, eps, ref iter1, ref iter2, ref rs); if (init_res != MKLwrapper.DEFINE.TR_SUCCESS) { DeleteAndFreeBuffers(); return(x); } int check_res = NonLinLeastSqProbWoConstraintsNative.dtrnlsp_check(ref solverHandle, ref n, ref m, (IntPtr)fJacPtr, (IntPtr)fVecPtr, eps, check_info); if (check_res != MKLwrapper.DEFINE.TR_SUCCESS) { DeleteAndFreeBuffers(); return(x); } else { if (check_info.Sum() > 0) { resultStatus = "input parameters aren`t valid."; DeleteAndFreeBuffers(); return(nXspacePoint); } } while (!successful) { int solve_res = NonLinLeastSqProbWoConstraintsNative.dtrnlsp_solve(ref solverHandle, (IntPtr)fVecPtr, (IntPtr)fJacPtr, ref RCI_Request); if (solve_res != MKLwrapper.DEFINE.TR_SUCCESS) { resultStatus = "error in dtrnlsp_solve"; DeleteAndFreeBuffers(); return(nXspacePoint); } if (RCI_Request == -1 || RCI_Request == -2 || RCI_Request == -3 || RCI_Request == -4 || RCI_Request == -5 || RCI_Request == -6) { successful = true; } if (RCI_Request == 1) { double[] newFVecValues = ObjectiveFunctional(x).ToArray(); for (int i = 0; i < m; i++) { fVec[i] = newFVecValues[i]; } resultStatus = ""; } if (RCI_Request == 2) { JacobianMatrixCalc jCalculator = new JacobianMatrixCalc(); //jCalculator.mSpaceVector = (new List<double>(mSpaceVector)).ToArray(); //jCalculator.mFittingValuesVector = (new List<double>(mFittingValuesVector)).ToArray(); jCalculator.mEventsPointsSetLength = mFittingValuesVector.Count(); jCalculator.nParametersSpacePoint = (new List <double>(x)).ToArray(); jCalculator.objectiveFunction = xPoint => ObjectiveFunctional(xPoint).ToArray(); double[,] tmpNewJacobi = jCalculator.SolveJacobianMatrix(precision); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { fJacobi[i, j] = tmpNewJacobi[i, j]; } } resultStatus = ""; } } } } int iterationsMade = 0; int stopCriterion = 0; if (NonLinLeastSqProbWoConstraintsNative.dtrnlsp_get(ref solverHandle, ref iterationsMade, ref stopCriterion, ref r1, ref r2) != MKLwrapper.DEFINE.TR_SUCCESS) { resultStatus = "error in dtrnlsp_get"; DeleteAndFreeBuffers(); return(x); } if (NonLinLeastSqProbWoConstraintsNative.dtrnlsp_delete(ref solverHandle) != MKLwrapper.DEFINE.TR_SUCCESS) { resultStatus = "error in dtrnlsp_delete"; return(x); } if (r2 < precision) { resultStatus = "optimization passed successfully"; return(x); } else { resultStatus = "optimization failed"; return(x); } }