Пример #1
0
        /** Get the full simplex of the current thread. This may be useful if the target function
         *  wants to modify the simplex */
        /* public List<double[]> getSimplex() {
         * return simpTable.get(Thread.currentThread());
         * } */

        /** One minimization run (including reinitializations of the simplex until the result is stable) */
        private void minimizeOnce(double[] initialParams, double[] initialParamVariations, int seed)
        {
            Random random = new Random(seed);
            var    simp   = makeSimplex(initialParams, initialParamVariations, random);

            if (simp == null)
            {
                status = wasInitialized ? REINITIALIZATION_FAILURE : INITIALIZATION_FAILURE;
                return;
            }
            wasInitialized = true;
            if (startTime == 0)
            {
                startTime = Java.SystemCurrentTimeMillis();
            }
            //if (io.binroot.regression.IJ.debugMode) showSimplex(simp, seed+" Initialized:");
            int    bestVertexNumber = minimize(simp);       // first minimization
            double bestValueSoFar   = value(simp[bestVertexNumber]);
            //reinitialize until converged or error/aborted (don't care about reinitialization failure in other thread)
            bool reinitialisationFailure = false;

            while (status == SUCCESS || status == REINITIALIZATION_FAILURE)
            {
                double[] paramVariations =
                    makeNewParamVariations(simp, bestVertexNumber, initialParams, initialParamVariations);
                if (!reInitializeSimplex(simp, bestVertexNumber, paramVariations, random))
                {
                    reinitialisationFailure = true;
                    break;
                }
                //if (io.binroot.regression.IJ.debugMode) showSimplex(simp, seed+" Reinitialized:");
                bestVertexNumber = minimize(simp);          // minimize with reinitialized simplex
                if (belowErrorLimit(value(simp[bestVertexNumber]), bestValueSoFar, 2.0))
                {
                    break;
                }
                bestValueSoFar = value(simp[bestVertexNumber]);
            }
            if (reinitialisationFailure)
            {
                status = REINITIALIZATION_FAILURE;
            }
            else if (status == SUCCESS || status == REINITIALIZATION_FAILURE) //i.e. not aborted, not max iterations exceeded
            {
                numCompletedMinimizations++;                                  // it was a complete minimization
            }
            //if (io.binroot.regression.IJ.debugMode) showSimplex(simp, seed+" Final:");
            if (resultsVector != null)
            {
                lock (resultsVector) {
                    resultsVector.Add(simp[bestVertexNumber]);
                }
            }
            else
            {
                result = simp[bestVertexNumber];
            }
        }
Пример #2
0
        /** Minimizes the target function by variation of the simplex.
         *  Note that one call to this function never does more than 0.4*maxIter iterations.
         *  @return index of the best value in simp
         */
        private int minimize(List <double[]> simp)
        {
            int[]    worstNextBestArray = new int[3];                                        // used to pass these indices from 'order' function
            double[] center             = new double[numParams + 1 + numExtraArrayElements]; // center of all vertices except worst
            double[] reflected          = new double[numParams + 1 + numExtraArrayElements]; // the 1st new vertex to try
            double[] secondTry          = new double[numParams + 1 + numExtraArrayElements]; // expanded or contracted vertex

            order(simp, worstNextBestArray);
            int worst     = worstNextBestArray[WORST];
            int nextWorst = worstNextBestArray[NEXT_WORST];
            int best      = worstNextBestArray[BEST];
            //showSimplex(simp, "before minimization, value="+value(simp[best]));

            //String operation="ini";
            int thisNumIter = 0;

            while (true)
            {
                totalNumIter++;                                 // global count over all threads
                thisNumIter++;                                  // local count for this minimize call
                                                                // THE MINIMIZAION ALGORITHM IS HERE
                {
                    getCenter(simp, worst, center);             // centroid of vertices except worst
                                                                // Reflect worst vertex through centriod of not-worst
                    getVertexAndEvaluate(center, simp[worst], -C_REFLECTION, reflected);
                    if (value(reflected) <= value(simp[best]))  // if it's better than the best...
                                                                // try expanding it
                    {
                        getVertexAndEvaluate(center, simp[worst], -C_EXPANSION, secondTry);
                        if (value(secondTry) <= value(reflected))
                        {
                            copyVertex(secondTry, simp[worst]);  // if expanded is better than reflected, keep it
                                                                 //operation="expa";
                            goto iteration;
                        }
                    }
                    if (value(reflected) < value(simp[nextWorst]))
                    {
                        copyVertex(reflected, simp[worst]);     // keep reflected if better than 2nd worst
                                                                //operation="refl";
                        goto iteration;
                    }
                    else if (value(reflected) < value(simp[worst]))
                    {
                        // try outer contraction
                        getVertexAndEvaluate(center, simp[worst], -C_CONTRACTION, secondTry);
                        if (value(secondTry) <= value(reflected))
                        {
                            copyVertex(secondTry, simp[worst]); // keep outer contraction
                                                                //operation="outC";
                            goto iteration;
                        }
                    }
                    else if (value(reflected) > value(simp[worst]) || double.IsNaN(value(reflected)))
                    {
                        // else inner contraction
                        getVertexAndEvaluate(center, simp[worst], C_CONTRACTION, secondTry);
                        if (value(secondTry) < value(simp[worst]))
                        {
                            copyVertex(secondTry, simp[worst]);     // keep contracted if better than 2nd worst
                                                                    //operation="innC";
                            goto iteration;
                        }
                    }
                    // if everything else has failed, contract simplex in on best
                    shrinkSimplexAndEvaluate(simp, best);
                    //operation="shri";
                    goto iteration;
                } // iteration:
iteration:

                bool checkParamResolution =    // if new 'worst' is not close to 'best', don't check any further
                                            paramResolutions != null && belowResolutionLimit(simp[worst], simp[best]);
                order(simp, worstNextBestArray);
                worst     = worstNextBestArray[WORST];
                nextWorst = worstNextBestArray[NEXT_WORST];
                best      = worstNextBestArray[BEST];

                if (checkParamResolution)
                {
                    if (belowResolutionLimit(simp, best))       // check whether all parameters are within the resolution limit
                    {
                        break;
                    }
                }
                if (belowErrorLimit(value(simp[best]), value(simp[worst]), 4.0)) // make sure we are at the minimum:
                {
                    getCenter(simp, -1, secondTry);                              // check center of the simplex
                    evaluate(secondTry);
                    if (value(secondTry) < value(simp[best]))
                    {
                        copyVertex(secondTry, simp[best]);      // better than best: keep
                    }
                }
                if (belowErrorLimit(value(simp[best]), value(simp[worst]), 4.0)) // no large spread of values
                {
                    break;                                                       // looks like we are at the minimum
                }
                if (totalNumIter > maxIter || thisNumIter > 4 * (maxIter / 10))
                {
                    status = MAX_ITERATIONS_EXCEEDED;
                }
                if (status != SUCCESS)
                {
                    break;
                }
                if ((ijStatusString != null || checkEscape) && totalNumIter > nextIterationForStatus)
                {
                    long time = Java.SystemCurrentTimeMillis();
                    nextIterationForStatus = totalNumIter + (int)(totalNumIter * 500L / (time - startTime + 1)); //next display 0.5 sec later
                }
            }
            //showSimplex(simp, "after "+totalNumIter+" iterations: value="+value(simp[best]));
            return(best);
        }