예제 #1
0
        } //# end of higher.local.max

        //# new_0.11
        private double[] SplitStartingValuesLeftRight(GenObject o, double target, SGNFnAParam A, double[] range, double[] startValues)
        {
            double[] start = new double[2] {
                Tools.NA, Tools.NA
            };
            double[] lsStart = startValues.Where(number => (number < A.Mode) && (number > range[0])).ToArray();
            double[] rsStart = startValues.Where(number => (number > A.Mode) && (number < range[1])).ToArray();

            if (lsStart.Length == 1)
            {
                start[0] = lsStart[0];
            }
            else if (lsStart.Length > 1)
            {
                double[] f = new double[lsStart.Length];
                for (int i = 0; i < lsStart.Length; i++)
                {
                    f[i] = o.LogF(lsStart[i], A);
                }

                double[] d = f.Substract(target).Abs();
                int      w = d.WhichMin();
                start[0] = lsStart[w];
            }

            if (rsStart.Length == 1)
            {
                start[1] = rsStart[0];
            }
            else if (rsStart.Length > 1)
            {
                double[] f = new double[rsStart.Length];
                for (int i = 0; i < rsStart.Length; i++)
                {
                    f[i] = o.LogF(rsStart[i], A);
                }

                double[] d = f.Substract(target).Abs();
                int      w = d.WhichMin();
                start[1] = rsStart[w];
            }

            return(start);
        } //# end of split.starting.values.leftRight
예제 #2
0
        private double HigherLocalMax(GenObject o, SGNFnAParam A, double dipX, double[] range, double epsilon)
        {
            //# Find a starting point on each side of dip.x
            double[] start     = o.Start(A);
            double   tmp       = start.Substract(dipX).Abs().Max();
            double   startLeft = start.Min();

            if (startLeft > dipX)
            {
                startLeft = dipX - tmp;
            }

            double startRight = start.Max();

            if (startRight < dipX)
            {
                startRight = dipX + tmp;
            }

            //# Look for starting points with negative values for h''
            //# i) on left side
            bool cntn = o.LogFSecond(startLeft, A) > 0;

            while (cntn)
            {
                startLeft = startLeft - tmp;
                if (startLeft < range[0])
                {
                    startLeft = (range[0] + startLeft + tmp) / 2;
                }
                cntn = o.LogFSecond(startLeft, A) > 0;
            }

            //# ii) on right side
            cntn = o.LogFSecond(startRight, A) > 0;
            while (cntn)
            {
                startRight = startRight + tmp;
                cntn       = o.LogFSecond(startRight, A) > 0;
            }

            //# Run pure Newton-Raphson to find local max on each side
            //# i) left side
            double x = startLeft;

            cntn = true;
            double hp = o.LogFPrime(x, A);

            while (cntn)
            {
                double change = hp / o.LogFSecond(x, A);
                x    = x - change;
                hp   = o.LogFPrime(x, A);
                cntn = Math.Abs(hp) > epsilon;
            }

            double localModeLeft = x;

            //# ii) right-side
            x    = startRight;
            cntn = true;
            hp   = o.LogFPrime(x, A);
            while (cntn)
            {
                double change = hp / o.LogFSecond(x, A);
                x    = x - change;
                hp   = o.LogFPrime(x, A);
                cntn = Math.Abs(hp) > epsilon;
            }
            double localModeRight = x;
            double hLeft          = o.LogF(localModeLeft, A);
            double hRight         = o.LogF(localModeRight, A);

            x = hLeft > hRight ? localModeLeft : localModeRight;
            return(x);
        } //# end of higher.local.max
예제 #3
0
        } //# end of split.starting.values.leftRight

        //# new_0.11
        private MaxFastTrackObject MaxFastTrack(GenObject o, SGNFnAParam A, double lowerLimit, double rightsideX, double rightsideHp, double epsilon = 1e-4, double epsilonX = 1e-20)
        {
            double x  = rightsideX;
            double h  = o.LogF(x, A);
            double hp = rightsideHp;

            //b = list(x = c(NA, x), h = c(NA, h), hp = c(NA, hp))
            double[] bX = new double[2] {
                x, Tools.NA
            };
            double[] bH = new double[2] {
                h, Tools.NA
            };
            double[] bHp = new double[2] {
                hp, Tools.NA
            };

            x = (x + lowerLimit) / 2;
            bool cntn = true;

            //# Find a point with positive slope (that is, to the left of the mode)
            while (cntn)
            {
                hp = o.LogFPrime(x, A);
                if (hp > 0)
                {
                    cntn = double.IsInfinity(hp);

                    if (cntn)
                    {
                        double nextX = (3 * x - lowerLimit) / 2.0;
                        lowerLimit = x;
                        cntn       = Math.Abs(nextX - x) > epsilonX;
                        if (cntn)
                        {
                            x = nextX;
                        }
                    }
                }
                else
                {
                    x = (x + lowerLimit) / 2.0;
                }
            }

            hp = o.LogFPrime(x, A);
            bool converged = Tools.IsFinite(hp) & (hp > 0);

            cntn = converged;

            while (cntn)
            {
                int side = hp > 0 ? 0 : 1;
                bX[side]  = x;
                bH[side]  = o.LogF(x, A);
                bHp[side] = hp;

                double bDiff = bHp.Diff()[0];

                if (bDiff == 0)
                {
                    x = bX.Mean();
                }
                else
                {
                    x = (bHp.Multiply(bX).Diff()[0] - bH.Diff()[0]) / bDiff;
                    if ((x <= bX[0]) || (x >= bX[1]))
                    {
                        x = bX.Mean();
                    }

                    hp   = o.LogFPrime(x, A);
                    cntn = Math.Abs(hp) > epsilon;
                }
            }
            h = o.LogF(x, A);

            return(new MaxFastTrackObject(x, h, converged));
        } //# end of max.fastTrack