예제 #1
0
        //steffensen's method
        public static double FindRoot(ProbabilityFunction func, double xGuess)
        {
            double[] xvals = new double[iterations];
            double   funcResult1;
            double   funcResult2;
            double   deltaSquare;

            xvals[0] = xGuess;

            for (int i = 0; i < iterations - 1; i++)
            {
                funcResult1 = func(xvals[i]);
                funcResult2 = func(funcResult1);
                deltaSquare = xvals[i] - (Math.Pow((funcResult2 - xvals[i]), 2) / (funcResult2 - (2 * funcResult1) + xvals[i])); //aitkens delta square method


                if (Math.Abs(deltaSquare - xvals[i]) < tolerance) //close enough
                {
                    return(deltaSquare);
                }
                xvals[i + 1] = deltaSquare;
                //xvals[i + 1] = xvals[i] - (funcResult / (((func(xvals[i] + funcResult) - funcResult) / (funcResult))));
            }
            return(xvals[iterations - 1]);
        }
예제 #2
0
        public Ziggurat(PDFType pdfType)
        {
            pdf = new PDF(0, 1);

            switch (pdfType)
            {
            case PDFType.Normal:
                pFunc      = pdf.NormalPDF;
                lowerBound = 0;
                upperBound = 0x100000000;
                guess      = 3.56;
                tailBound  = 10;
                break;

            case PDFType.Laplace:
                pFunc      = pdf.LaplacePDF;
                lowerBound = 0;
                upperBound = 5000;
                guess      = 9;
                tailBound  = 10;
                break;

            case PDFType.T:
                pFunc      = pdf.TPDF;
                lowerBound = 0;
                upperBound = Int16.MaxValue;
                guess      = 4;
                tailBound  = 10;
                break;
            }
            GenerateZigTable();
        }
예제 #3
0
        public static double Integrate(ProbabilityFunction f, double lower, double upper, double intervals)
        {
            double h   = (upper - lower) / intervals;
            double res = (f(lower) + f(upper)) / 2;

            for (int i = 1; i < intervals; i++)
            {
                res += f(lower + i * h);
            }
            return(h * res);
        }
예제 #4
0
        //my guess method
        public static double FindGuess(ProbabilityFunction func, double guess, double sanity)
        {
            double increment = .1;
            double current;
            double update;
            bool   changeInc = false;
            bool   increased = false;

            for (int i = 0; i < iterations; i++)
            {
                current = func(guess);
                if (changeInc)
                {
                    increment = increment / 10;
                    changeInc = false;
                }
                if (Math.Abs(current - sanity) < tolerance)
                {
                    return(guess);
                }
                if (current > sanity)
                {
                    guess    += increment;
                    increased = true;
                }
                else if (current < sanity)
                {
                    guess    -= increment;
                    increased = false;
                }
                update = func(guess);
                if ((Math.Abs(current - sanity) < Math.Abs(update - sanity)))
                {
                    if (increased)
                    {
                        guess    -= increment;
                        changeInc = true;
                    }
                    else
                    {
                        guess    += increment;
                        changeInc = true;
                    }
                }
            }
            return(guess);
        }
예제 #5
0
        private static void CheckPearsonCriteria(List <double> list, ProbabilityFunction function, int criteriaItemsAmount)
        {
            var    probabilityFunctionValues = GetProbabilityFunctionValues();
            var    valuesAmount = GetAmountByValues();
            double value        = 0;

            for (int i = 0; i < criteriaItemsAmount; i++)
            {
                if (probabilityFunctionValues[i] != 0)
                {
                    value += Math.Pow(valuesAmount[i] - N * probabilityFunctionValues[i], 2) / (N * probabilityFunctionValues[i]);
                }
            }
            Console.WriteLine($"Pearson criterion: {DisplayCriteriaResults(Pearson0_05Quantiles[criteriaItemsAmount - 1])}");

            List <double> GetProbabilityFunctionValues() //For Puasson: 0.220, 0.333, 0.252, 0.127, 0.048, 0.015, 0.005
            {
                return(GetIEnumerableProbabilityFunctionValues().ToList());

                IEnumerable <double> GetIEnumerableProbabilityFunctionValues()
                {
                    for (int i = 0; i < criteriaItemsAmount; i++)
                    {
                        yield return(function(i));
                    }
                }
            }

            List <int> GetAmountByValues()
            {
                return(GetIEnumerableAmountByValues().ToList());

                IEnumerable <int> GetIEnumerableAmountByValues()
                {
                    for (int i = 0; i < criteriaItemsAmount; i++)
                    {
                        yield return(list.Count(x => x == i));
                    }
                }
            }

            string DisplayCriteriaResults(double quantile) => value < quantile ?
            $"{value:F5} < {quantile:F3}, so it's passed" : $"{value:F5} > {quantile:F3}, so it isn't passed";
        }
예제 #6
0
        private static void DisplayResults(string parameters, int criteriaItemsAmount, List <double> results,
                                           ProbabilityFunction probabilityFunction, MathematicalExpectation mathematicalExpectation, Dispersion dispersion)
        {
            Console.WriteLine(Environment.NewLine +
                              $"-----{dispersion.Method.Name.Replace("Dispersion", "")} distribution ({parameters})-----");
            results.Take(30).ToList().ForEach(x => Console.Write($"{x:F0} "));
            Console.Write(Environment.NewLine + $"{N} items: ");
            for (int i = 0; i < Math.Min(7, criteriaItemsAmount); i++)
            {
                Console.Write($"{i}({results.Count(x => x == i)}) ");
            }
            Console.WriteLine();
            Console.WriteLine($"Practical  : Average={results.Average():F5}, Dispersion={CalculateDispersion(results.ToList()):F5}");
            Console.WriteLine($"Theoretical: Average={mathematicalExpectation():F5}, Dispersion={dispersion():F5}");
            CheckPearsonCriteria(GetSortedList(results), probabilityFunction, criteriaItemsAmount);

            double CalculateDispersion(List <double> list) => list.Sum(x => Math.Pow(x - list.Average(), 2)) / list.Count;
            List <double> GetSortedList(List <double> list) => list.OrderBy(x => x).ToList();
        }
예제 #7
0
        //brent's method
        public static double Root(ProbabilityFunction func, double lowerBound, double upperBound)
        {
            double a = lowerBound;
            double b = upperBound;
            double c;
            double fa = func(a);
            double fb = func(b);
            double fc;
            double fs   = 0;
            double s    = 0;
            double d    = 0;
            bool   flag = true;

            if ((fa * fb) >= 0)
            {
                return(0);
            }
            if (Math.Abs(fa) < Math.Abs(fb)) //swap if the magnitude of lower is less then upper
            {
                var temp = a;
                a    = b;
                b    = temp;
                temp = fa;
                fa   = fb;
                fb   = temp;
            }
            fc = fa;
            c  = a;

            for (int i = 0; i < iterations; i++)
            {
                if (Math.Abs(b - a) < tolerance)
                {
                    return(s);
                }

                if (fa != fc && fb != fc) //inverse quadratic interpolation
                {
                    s = (a * fb * fc / ((fa - fb) * (fa - fc))) + (b * fa * fc / ((fb - fa) * (fb - fc))) + (c * fa * fb / ((fc - fa) * (fc - fb)));
                }
                else //secant
                {
                    s = b - fb * (b - a) / (fb - fa);
                }
                //bijection
                if (((s < (3 * a + b) * 0.25) || (s > b)) ||
                    (flag && (Math.Abs(s - b) >= (Math.Abs(b - c) / 2))) ||
                    (flag == false && (Math.Abs(s - b) >= (Math.Abs(c - d) / 2))) ||
                    (flag && (Math.Abs(b - c) < tolerance)) ||
                    (flag == false && (Math.Abs(c - d) < tolerance)))
                {
                    s    = (a + b) / 2;
                    flag = true;
                }
                else
                {
                    flag = false;
                }

                fs = func(s);
                d  = c;
                c  = b;
                fc = fb;

                if (fa * fs < 0)
                {
                    b  = s;
                    fb = fs;
                }
                else
                {
                    a  = s;
                    fa = fs;
                }

                if (Math.Abs(fa) < Math.Abs(fb))
                {
                    var temp = a;
                    a    = b;
                    b    = temp;
                    temp = fa;
                    fa   = fb;
                    fb   = temp;
                }
            }

            return(0);
        }