Beispiel #1
0
        private int DeleteAndFreeBuffers()
        {
            int res = NonLinLeastSqProbWithBCNative.dtrnlspbc_delete(ref solverHandle);

            NonLinLeastSqProbWithBCNative.mkl_free_buffers();
            return(res);
        }
Beispiel #2
0
        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);
            }
        }