/// <summary>
        /// 
        /// </summary>
        ///
        public override sealed void Iteration()
        {
            if (!_samplesLoaded)
            {
                _network.Samples = new BasicMLDataSet(_training);
                _samplesLoaded = true;
            }

            var globalMinimum = new GlobalMinimumSearch();
            var dermin = new DeriveMinimum();

            int k;

            if (_network.OutputMode == PNNOutputMode.Classification)
            {
                k = _network.OutputCount;
            }
            else
            {
                k = _network.OutputCount + 1;
            }

            _dsqr = new double[_network.InputCount];
            _v = new double[_network.InputCount*k];
            _w = new double[_network.InputCount*k];

            var x = new double[_network.InputCount];
            var bs = new double[_network.InputCount];
            var direc = new double[_network.InputCount];
            var g = new double[_network.InputCount];
            var h = new double[_network.InputCount];
            var dwk2 = new double[_network.InputCount];

            if (_network.Trained)
            {
                for (int i = 0; i < _network.InputCount; i++)
                {
                    x[i] = _network.Sigma[i];
                }
                globalMinimum.Y2 = 1.0e30d;
            }
            else
            {
                globalMinimum.FindBestRange(_sigmaLow, _sigmaHigh,
                                            _numSigmas, true, _maxError, this);

                for (int i = 0; i < _network.InputCount; i++)
                {
                    x[i] = globalMinimum.X2;
                }
            }

            double d = dermin.Calculate(32767, _maxError, 1.0e-8d,
                                        _minImprovement, this, _network.InputCount, x,
                                        globalMinimum.Y2, bs, direc, g, h, dwk2);
            globalMinimum.Y2 = d;

            for (int i = 0; i < _network.InputCount; i++)
            {
                _network.Sigma[i] = x[i];
            }

            _network.Error = Math.Abs(globalMinimum.Y2);
            _network.Trained = true; // Tell other routines net is trained

            return;
        }
Exemple #2
0
        /// <summary>
        /// Derive the minimum, using a conjugate gradient method.
        /// </summary>
        ///
        /// <param name="maxIterations">The max iterations.</param>
        /// <param name="maxError">Stop at this error rate.</param>
        /// <param name="eps">The machine's precision.</param>
        /// <param name="tol">The convergence tolerance.</param>
        /// <param name="network">The network to get the error from.</param>
        /// <param name="n">The number of variables.</param>
        /// <param name="x">The independent variable.</param>
        /// <param name="ystart">The start for y.</param>
        /// <param name="bs">Work vector, must have n elements.</param>
        /// <param name="direc">Work vector, must have n elements.</param>
        /// <param name="g">Work vector, must have n elements.</param>
        /// <param name="h">Work vector, must have n elements.</param>
        /// <param name="deriv2">Work vector, must have n elements.</param>
        /// <returns>The best error.</returns>
        public double Calculate(int maxIterations, double maxError,
                                double eps, double tol,
                                ICalculationCriteria network, int n, double[] x,
                                double ystart, double[] bs, double[] direc,
                                double[] g, double[] h, double[] deriv2)
        {
            var globalMinimum = new GlobalMinimumSearch();

            double fbest = network.CalcErrorWithMultipleSigma(x, direc, deriv2,
                                                              true);
            double prevBest = 1.0e30d;

            for (int i = 0; i < n; i++)
            {
                direc[i] = -direc[i];
            }

            EngineArray.ArrayCopy(direc, g);
            EngineArray.ArrayCopy(direc, h);

            int convergenceCounter = 0;
            int poorCj             = 0;

            // Main loop
            for (int iteration = 0; iteration < maxIterations; iteration++)
            {
                if (fbest < maxError)
                {
                    break;
                }

                EncogLogging.Log(EncogLogging.LevelInfo,
                                 "Beginning internal Iteration #" + iteration + ", currentError=" + fbest + ",target=" + maxError);

                // Check for convergence
                double toler;
                if (prevBest <= 1.0d)
                {
                    toler = tol;
                }
                else
                {
                    toler = tol * prevBest;
                }

                // Stop if there is little improvement
                if ((prevBest - fbest) <= toler)
                {
                    if (++convergenceCounter >= 3)
                    {
                        break;
                    }
                }
                else
                {
                    convergenceCounter = 0;
                }

                double dot2 = 0;
                double dlen = 0;
                double dot1 = dot2 = dlen = 0.0d;
                double high = 1.0e-4d;
                for (int i = 0; i < n; i++)
                {
                    bs[i] = x[i];
                    if (deriv2[i] > high)
                    {
                        high = deriv2[i];
                    }
                    dot1 += direc[i] * g[i];                 // Directional first derivative
                    dot2 += direc[i] * direc[i] * deriv2[i]; // and second
                    dlen += direc[i] * direc[i];             // Length of search vector
                }

                double scale;

                if (Math.Abs(dot2) < EncogFramework.DefaultDoubleEqual)
                {
                    scale = 0;
                }
                else
                {
                    scale = dot1 / dot2;
                }
                high = 1.5d / high;
                if (high < 1.0e-4d)
                {
                    high = 1.0e-4d;
                }

                if (scale < 0.0d)
                {
                    scale = high;
                }
                else if (scale < 0.1d * high)
                {
                    scale = 0.1d * high;
                }
                else if (scale > 10.0d * high)
                {
                    scale = 10.0d * high;
                }

                prevBest         = fbest;
                globalMinimum.Y2 = fbest;

                globalMinimum.FindBestRange(0.0d, 2.0d * scale, -3, false, maxError,
                                            network);

                if (globalMinimum.Y2 < maxError)
                {
                    if (globalMinimum.Y2 < fbest)
                    {
                        for (int i = 0; i < n; i++)
                        {
                            x[i] = bs[i] + globalMinimum.Y2 * direc[i];
                            if (x[i] < 1.0e-10d)
                            {
                                x[i] = 1.0e-10d;
                            }
                        }
                        fbest = globalMinimum.Y2;
                    }
                    else
                    {
                        for (int i = 0; i < n; i++)
                        {
                            x[i] = bs[i];
                        }
                    }
                    break;
                }

                if (convergenceCounter > 0)
                {
                    fbest = globalMinimum.Brentmin(20, maxError, eps, 1.0e-7d,
                                                   network, globalMinimum.Y2);
                }
                else
                {
                    fbest = globalMinimum.Brentmin(10, maxError, 1.0e-6d, 1.0e-5d,
                                                   network, globalMinimum.Y2);
                }

                for (int i = 0; i < n; i++)
                {
                    x[i] = bs[i] + globalMinimum.X2 * direc[i];
                    if (x[i] < 1.0e-10d)
                    {
                        x[i] = 1.0e-10d;
                    }
                }

                double improvement = (prevBest - fbest) / prevBest;

                if (fbest < maxError)
                {
                    break;
                }

                for (int i = 0; i < n; i++)
                {
                    direc[i] = -direc[i]; // negative gradient
                }

                double gam = Gamma(n, g, direc);

                if (gam < 0.0d)
                {
                    gam = 0.0d;
                }

                if (gam > 10.0d)
                {
                    gam = 10.0d;
                }

                if (improvement < 0.001d)
                {
                    ++poorCj;
                }
                else
                {
                    poorCj = 0;
                }

                if (poorCj >= 2)
                {
                    if (gam > 1.0d)
                    {
                        gam = 1.0d;
                    }
                }

                if (poorCj >= 6)
                {
                    poorCj = 0;
                    gam    = 0.0d;
                }

                FindNewDir(n, gam, g, h, direc);
            }

            return(fbest);
        }
        /// <summary>
        /// Derive the minimum, using a conjugate gradient method.
        /// </summary>
        ///
        /// <param name="maxIterations">The max iterations.</param>
        /// <param name="maxError">Stop at this error rate.</param>
        /// <param name="eps">The machine's precision.</param>
        /// <param name="tol">The convergence tolerance.</param>
        /// <param name="network">The network to get the error from.</param>
        /// <param name="n">The number of variables.</param>
        /// <param name="x">The independent variable.</param>
        /// <param name="ystart">The start for y.</param>
        /// <param name="bs">Work vector, must have n elements.</param>
        /// <param name="direc">Work vector, must have n elements.</param>
        /// <param name="g">Work vector, must have n elements.</param>
        /// <param name="h">Work vector, must have n elements.</param>
        /// <param name="deriv2">Work vector, must have n elements.</param>
        /// <returns>The best error.</returns>
        public double Calculate(int maxIterations, double maxError,
            double eps, double tol,
            ICalculationCriteria network, int n, double[] x,
            double ystart, double[] bs, double[] direc,
            double[] g, double[] h, double[] deriv2)
        {
            var globalMinimum = new GlobalMinimumSearch();

            double fbest = network.CalcErrorWithMultipleSigma(x, direc, deriv2,
                                                              true);
            double prevBest = 1.0e30d;
            for (int i = 0; i < n; i++)
            {
                direc[i] = -direc[i];
            }

            EngineArray.ArrayCopy(direc, g);
            EngineArray.ArrayCopy(direc, h);

            int convergenceCounter = 0;
            int poorCj = 0;

            // Main loop
            for (int iteration = 0; iteration < maxIterations; iteration++)
            {
                if (fbest < maxError)
                {
                    break;
                }

                EncogLogging.Log(EncogLogging.LevelInfo,
                    "Beginning internal Iteration #" + iteration + ", currentError=" + fbest + ",target=" + maxError);

                // Check for convergence
                double toler;
                if (prevBest <= 1.0d)
                {
                    toler = tol;
                }
                else
                {
                    toler = tol*prevBest;
                }

                // Stop if there is little improvement
                if ((prevBest - fbest) <= toler)
                {
                    if (++convergenceCounter >= 3)
                    {
                        break;
                    }
                }
                else
                {
                    convergenceCounter = 0;
                }

                double dot2 = 0;
                double dlen = 0;
                double dot1 = dot2 = dlen = 0.0d;
                double high = 1.0e-4d;
                for (int i= 0; i < n; i++)
                {
                    bs[i] = x[i];
                    if (deriv2[i] > high)
                    {
                        high = deriv2[i];
                    }
                    dot1 += direc[i]*g[i]; // Directional first derivative
                    dot2 += direc[i]*direc[i]*deriv2[i]; // and second
                    dlen += direc[i]*direc[i]; // Length of search vector
                }

                double scale;

                if (Math.Abs(dot2) < EncogFramework.DefaultDoubleEqual)
                {
                    scale = 0;
                }
                else
                {
                    scale = dot1/dot2;
                }
                high = 1.5d/high;
                if (high < 1.0e-4d)
                {
                    high = 1.0e-4d;
                }

                if (scale < 0.0d)
                {
                    scale = high;
                }
                else if (scale < 0.1d*high)
                {
                    scale = 0.1d*high;
                }
                else if (scale > 10.0d*high)
                {
                    scale = 10.0d*high;
                }

                prevBest = fbest;
                globalMinimum.Y2 = fbest;

                globalMinimum.FindBestRange(0.0d, 2.0d*scale, -3, false, maxError,
                                            network);

                if (globalMinimum.Y2 < maxError)
                {
                    if (globalMinimum.Y2 < fbest)
                    {
                        for (int i = 0; i < n; i++)
                        {
                            x[i] = bs[i] + globalMinimum.Y2*direc[i];
                            if (x[i] < 1.0e-10d)
                            {
                                x[i] = 1.0e-10d;
                            }
                        }
                        fbest = globalMinimum.Y2;
                    }
                    else
                    {
                        for (int i = 0; i < n; i++)
                        {
                            x[i] = bs[i];
                        }
                    }
                    break;
                }

                if (convergenceCounter > 0)
                {
                    fbest = globalMinimum.Brentmin(20, maxError, eps, 1.0e-7d,
                                                   network, globalMinimum.Y2);
                }
                else
                {
                    fbest = globalMinimum.Brentmin(10, maxError, 1.0e-6d, 1.0e-5d,
                                                   network, globalMinimum.Y2);
                }

                for (int i = 0; i < n; i++)
                {
                    x[i] = bs[i] + globalMinimum.X2*direc[i];
                    if (x[i] < 1.0e-10d)
                    {
                        x[i] = 1.0e-10d;
                    }
                }

                double improvement = (prevBest - fbest)/prevBest;

                if (fbest < maxError)
                {
                    break;
                }

                for (int i = 0; i < n; i++)
                {
                    direc[i] = -direc[i]; // negative gradient
                }

                double gam = Gamma(n, g, direc);

                if (gam < 0.0d)
                {
                    gam = 0.0d;
                }

                if (gam > 10.0d)
                {
                    gam = 10.0d;
                }

                if (improvement < 0.001d)
                {
                    ++poorCj;
                }
                else
                {
                    poorCj = 0;
                }

                if (poorCj >= 2)
                {
                    if (gam > 1.0d)
                    {
                        gam = 1.0d;
                    }
                }

                if (poorCj >= 6)
                {
                    poorCj = 0;
                    gam = 0.0d;
                }

                FindNewDir(n, gam, g, h, direc);
            }

            return fbest;
        }
Exemple #4
0
        /// <summary>
        ///
        /// </summary>
        ///
        public override sealed void Iteration()
        {
            if (!_samplesLoaded)
            {
                _network.Samples = new BasicMLDataSet(_training);
                _samplesLoaded   = true;
            }

            var globalMinimum = new GlobalMinimumSearch();
            var dermin        = new DeriveMinimum();

            int k;

            if (_network.OutputMode == PNNOutputMode.Classification)
            {
                k = _network.OutputCount;
            }
            else
            {
                k = _network.OutputCount + 1;
            }

            _dsqr = new double[_network.InputCount];
            _v    = new double[_network.InputCount * k];
            _w    = new double[_network.InputCount * k];

            var x     = new double[_network.InputCount];
            var bs    = new double[_network.InputCount];
            var direc = new double[_network.InputCount];
            var g     = new double[_network.InputCount];
            var h     = new double[_network.InputCount];
            var dwk2  = new double[_network.InputCount];

            if (_network.Trained)
            {
                for (int i = 0; i < _network.InputCount; i++)
                {
                    x[i] = _network.Sigma[i];
                }
                globalMinimum.Y2 = 1.0e30d;
            }
            else
            {
                globalMinimum.FindBestRange(_sigmaLow, _sigmaHigh,
                                            _numSigmas, true, _maxError, this);

                for (int i = 0; i < _network.InputCount; i++)
                {
                    x[i] = globalMinimum.X2;
                }
            }

            double d = dermin.Calculate(32767, _maxError, 1.0e-8d,
                                        _minImprovement, this, _network.InputCount, x,
                                        globalMinimum.Y2, bs, direc, g, h, dwk2);

            globalMinimum.Y2 = d;

            for (int i = 0; i < _network.InputCount; i++)
            {
                _network.Sigma[i] = x[i];
            }

            _network.Error   = Math.Abs(globalMinimum.Y2);
            _network.Trained = true; // Tell other routines net is trained

            return;
        }
Exemple #5
0
 public double Calculate(int maxIterations, double maxError, double eps, double tol, ICalculationCriteria network, int n, double[] x, double ystart, double[] bs, double[] direc, double[] g, double[] h, double[] deriv2)
 {
     double num;
     double num2;
     int num3;
     int num4;
     int num5;
     int num6;
     double num7;
     double num8;
     double num9;
     double num10;
     double num11;
     int num12;
     double num13;
     int num14;
     int num16;
     double num19;
     GlobalMinimumSearch search = new GlobalMinimumSearch();
     if ((((uint) ystart) | 8) != 0)
     {
         num = network.CalcErrorWithMultipleSigma(x, direc, deriv2, true);
         num2 = 1E+30;
         num3 = 0;
         goto Label_07E4;
     }
     goto Label_03E1;
     Label_003D:
     if (num6 >= maxIterations)
     {
         if ((((uint) num19) + ((uint) num11)) < 0)
         {
             if (((uint) num7) <= uint.MaxValue)
             {
                 goto Label_005E;
             }
             goto Label_003D;
         }
         if (((uint) maxError) < 0)
         {
             goto Label_0080;
         }
         if (((uint) num10) <= uint.MaxValue)
         {
             return num;
         }
         goto Label_039C;
     }
     Label_005E:
     if (num >= maxError)
     {
         goto Label_071B;
     }
     return num;
     Label_0080:
     if (num5 >= 6)
     {
         goto Label_0096;
     }
     Label_0085:
     xbfc8da7bffe4bca2(n, num19, g, h, direc);
     num6++;
     goto Label_003D;
     Label_0096:
     num5 = 0;
     num19 = 0.0;
     goto Label_0085;
     Label_009D:
     if (num5 < 2)
     {
         goto Label_0080;
     }
     Label_00A2:
     if (num19 <= 1.0)
     {
         goto Label_0080;
     }
     Label_00DF:
     num19 = 1.0;
     goto Label_0080;
     Label_0213:
     if (num16 < n)
     {
         x[num16] = bs[num16] + (search.X2 * direc[num16]);
         if (((((uint) num3) | 0xfffffffe) == 0) || (x[num16] < 1E-10))
         {
             x[num16] = 1E-10;
         }
         goto Label_0276;
     }
     double num17 = (num2 - num) / num2;
     if ((((uint) num10) - ((uint) ystart)) < 0)
     {
         goto Label_045B;
     }
     if ((((uint) num6) - ((uint) num14)) > uint.MaxValue)
     {
         goto Label_04C5;
     }
     if (num < maxError)
     {
         return num;
     }
     int index = 0;
     Label_019D:
     if (index < n)
     {
         direc[index] = -direc[index];
         if ((((uint) n) - ((uint) num13)) >= 0)
         {
             index++;
             goto Label_019D;
         }
     }
     else
     {
         num19 = xdf79f321ca5c3af5(n, g, direc);
     }
     if (4 != 0)
     {
         if (num19 < 0.0)
         {
             num19 = 0.0;
         }
         if (num19 > 10.0)
         {
             num19 = 10.0;
         }
         else if ((((uint) maxError) | 0xff) == 0)
         {
             goto Label_06FD;
         }
         if (num17 >= 0.001)
         {
             num5 = 0;
         }
         else
         {
             if ((((uint) num10) | 1) == 0)
             {
                 goto Label_0096;
             }
             num5++;
         }
         goto Label_009D;
     }
     if ((((uint) num12) & 0) == 0)
     {
         goto Label_029C;
     }
     Label_0276:
     num16++;
     if (0 == 0)
     {
         if (((uint) maxError) > uint.MaxValue)
         {
             goto Label_031E;
         }
         goto Label_0213;
     }
     Label_029C:
     num = search.Brentmin(10, maxError, 1E-06, 1E-05, network, search.Y2);
     Label_02C0:
     num16 = 0;
     if ((((uint) maxIterations) - ((uint) maxError)) > uint.MaxValue)
     {
         goto Label_07E9;
     }
     goto Label_0213;
     Label_031E:
     if (num4 > 0)
     {
         num = search.Brentmin(20, maxError, eps, 1E-07, network, search.Y2);
         goto Label_02C0;
     }
     if ((((uint) num16) + ((uint) num2)) <= uint.MaxValue)
     {
         goto Label_029C;
     }
     goto Label_0276;
     Label_0365:
     if (search.Y2 >= maxError)
     {
         goto Label_031E;
     }
     Label_039C:
     if (search.Y2 < num)
     {
         num14 = 0;
         goto Label_041C;
     }
     int num15 = 0;
     Label_0391:
     if (num15 < n)
     {
         x[num15] = bs[num15];
         num15++;
         if ((((uint) n) + ((uint) num15)) >= 0)
         {
             goto Label_0391;
         }
     }
     else
     {
         return num;
     }
     if ((((uint) num13) - ((uint) n)) >= 0)
     {
         goto Label_031E;
     }
     goto Label_0365;
     Label_03E1:
     x[num14] = bs[num14] + (search.Y2 * direc[num14]);
     if (x[num14] < 1E-10)
     {
         x[num14] = 1E-10;
     }
     num14++;
     Label_041C:
     if (num14 < n)
     {
         goto Label_03E1;
     }
     return search.Y2;
     Label_045B:
     num13 = 10.0 * num11;
     Label_0469:
     num2 = num;
     search.Y2 = num;
     search.FindBestRange(0.0, 2.0 * num13, -3, false, maxError, network);
     goto Label_0365;
     Label_04C5:
     num13 = num11;
     goto Label_0469;
     Label_04CB:
     if (num13 < 0.0)
     {
         goto Label_04C5;
     }
     if ((((uint) num17) + ((uint) maxIterations)) >= 0)
     {
         if (((uint) num9) >= 0)
         {
             if (num13 >= (0.1 * num11))
             {
                 if (num13 <= (10.0 * num11))
                 {
                     goto Label_0469;
                 }
             }
             else
             {
                 num13 = 0.1 * num11;
                 if ((((uint) num11) - ((uint) num16)) < 0)
                 {
                     goto Label_04CB;
                 }
                 goto Label_0469;
             }
         }
         goto Label_045B;
     }
     Label_04F0:
     num11 = 1.5 / num11;
     if (((((uint) tol) + ((uint) eps)) >= 0) && (num11 >= 0.0001))
     {
         goto Label_04CB;
     }
     Label_0516:
     num11 = 0.0001;
     goto Label_04CB;
     Label_05C6:
     if (num12 < n)
     {
         bs[num12] = x[num12];
         if (((uint) num8) > uint.MaxValue)
         {
             goto Label_009D;
         }
     }
     else
     {
         if (Math.Abs(num8) < 1E-07)
         {
             if ((((uint) num14) + ((uint) num4)) > uint.MaxValue)
             {
                 goto Label_07E4;
             }
             num13 = 0.0;
             if ((((uint) num19) - ((uint) ystart)) < 0)
             {
                 goto Label_0516;
             }
             goto Label_04F0;
         }
         num13 = num10 / num8;
         if ((((uint) num13) - ((uint) num15)) >= 0)
         {
             goto Label_04F0;
         }
         goto Label_05C6;
     }
     Label_0640:
     if (deriv2[num12] > num11)
     {
         num11 = deriv2[num12];
         if (((uint) num) < 0)
         {
             goto Label_00A2;
         }
     }
     num10 += direc[num12] * g[num12];
     if ((((uint) num8) + ((uint) num8)) > uint.MaxValue)
     {
         goto Label_071B;
     }
     num8 += (direc[num12] * direc[num12]) * deriv2[num12];
     num9 += direc[num12] * direc[num12];
     num12++;
     goto Label_05C6;
     Label_06B9:
     if (++num4 >= 3)
     {
         return num;
     }
     Label_06D9:
     num8 = 0.0;
     num9 = 0.0;
     num10 = num8 = num9 = 0.0;
     num11 = 0.0001;
     num12 = 0;
     goto Label_05C6;
     Label_06F7:
     num7 = tol * num2;
     Label_06FD:
     if ((num2 - num) > num7)
     {
         num4 = 0;
         if ((((uint) num14) & 0) != 0)
         {
             goto Label_06B9;
         }
         goto Label_06D9;
     }
     if (((uint) num9) <= uint.MaxValue)
     {
         goto Label_06B9;
     }
     return num;
     Label_071B:
     if (num2 > 1.0)
     {
         if ((((uint) num7) + ((uint) eps)) < 0)
         {
             goto Label_003D;
         }
         if ((((uint) num8) - ((uint) num14)) <= uint.MaxValue)
         {
             goto Label_06F7;
         }
     }
     else
     {
         num7 = tol;
         goto Label_06FD;
     }
     Label_0762:
     num5 = 0;
     num6 = 0;
     goto Label_003D;
     Label_07D7:
     direc[num3] = -direc[num3];
     num3++;
     Label_07E4:
     if (num3 < n)
     {
         goto Label_07D7;
     }
     Label_07E9:
     if (((uint) num15) > uint.MaxValue)
     {
         if ((((uint) num11) + ((uint) num13)) < 0)
         {
             goto Label_0640;
         }
         goto Label_00DF;
     }
     do
     {
         EngineArray.ArrayCopy(direc, g);
         EngineArray.ArrayCopy(direc, h);
         if ((((uint) num5) + ((uint) maxError)) < 0)
         {
             goto Label_06F7;
         }
         num4 = 0;
         if ((((uint) num5) - ((uint) num10)) <= uint.MaxValue)
         {
             goto Label_0762;
         }
     }
     while ((((uint) index) - ((uint) num17)) > uint.MaxValue);
     goto Label_07D7;
 }