Esempio n. 1
0
        static void Main(string[] args)
        {
            Results = new StringBuilder();

            TestBigNumberMultinomial(0, ErrorMeasure.Absolute);

            Console.WriteLine();

            int iterationCount = 20000;

            Multinomial.ClearCache();
            Console.WriteLine("With prefetch");
            PerformanceTest(iterationCount, true);
            Console.WriteLine();
            Results.AppendLine();

            Multinomial.ClearCache();
            PerformanceTest2(iterationCount, true);
            Console.WriteLine();
            Results.AppendLine();

            Multinomial.ClearCache();
            Console.WriteLine("Without prefetch");
            PerformanceTest(iterationCount, false);
            Console.WriteLine();
            Results.AppendLine();

            Multinomial.ClearCache();
            PerformanceTest2(iterationCount, false);
            Console.WriteLine();
            Results.AppendLine();

            File.WriteAllText("result.txt", Results.ToString());
            Console.ReadLine();
        }
        public static Summand[] GenerateSummands(uint n, uint k)
        {
            var combs = Generate(n, k);

            // TODO: compute multinomial coeffs here (length of array = k)
            var multinomialCoefs = new List <Tuple <uint[], ulong> >();

            Summand[] result = new Summand[combs.Length];

            uint[] array = new uint[n];
            for (int i = 0; i < result.Length; i++)
            {
                result[i] = new Summand {
                    Factors = (uint[])combs[i].Clone()
                };

                for (int j = 0; j < n; j++)
                {
                    array[j] = 0;
                }
                for (int j = 0; j < k; j++)
                {
                    array[combs[i][j]]++;
                }
                Array.Sort(array);

                bool finded = false;
                foreach (var coef in multinomialCoefs)
                {
                    if (Enumerable.SequenceEqual(array, coef.Item1))
                    {
                        result[i].Coefficient = coef.Item2;
                        finded = true;
                        break;
                    }
                }
                if (!finded)
                {
                    result[i].Coefficient = Multinomial.PrimeNumbers(array);
                    multinomialCoefs.Add(new Tuple <uint[], ulong>((uint[])array.Clone(), result[i].Coefficient));
                }
            }

            return(result);
        }
Esempio n. 3
0
        static void TestBigNumberMultinomial(uint maxError, ErrorMeasure errorMeasure)
        {
            Dictionary <string, MultinomialResult> tempResults = new Dictionary <string, MultinomialResult>();

            Results.AppendLine("Number of arguments	Naive	Binom	Log	LogGamma	My	BigNumber	Table");

            const uint maxNumber = 1000;

            uint iteration = 2;

            ulong result;
            int   prevPermutNumber;
            ulong prevResult;

            uint[] prevPermut;
            int    count = 0;

            do
            {
                Results.Append(iteration + "\t");
                tempResults.Clear();

                prevPermut       = null;
                prevResult       = 0;
                prevPermutNumber = -1;
                bool bigIsCorrect          = true;
                bool naiveIsCorrect        = true;
                bool binomIsCorrect        = true;
                bool logIsCorrect          = true;
                bool optIsCorrect          = true;
                bool lnGammaIsCorrect      = true;
                bool primeNumbersIsCorrect = true;

                Console.WriteLine("Arg count: " + iteration);
                uint[] combination;
                while ((combination = CombinationWithRepetition.Next(maxNumber, iteration)) != null)
                {
                    var currentCombintaion = combination.Select(a => a + 1).ToArray();
                    count++;

                    result = 0;
                    try
                    {
                        result = Multinomial.Big(currentCombintaion);
                    }
                    catch
                    {
                        bigIsCorrect = false;
                    }

                    if (bigIsCorrect)
                    {
                        MultinomCoefMethodTest(currentCombintaion, prevPermut, prevPermutNumber, Multinomial.Naive, ref naiveIsCorrect, result, maxError, errorMeasure, tempResults);
                        MultinomCoefMethodTest(currentCombintaion, prevPermut, prevPermutNumber, Multinomial.Binom, ref binomIsCorrect, result, maxError, errorMeasure, tempResults);
                        MultinomCoefMethodTest(currentCombintaion, prevPermut, prevPermutNumber, Multinomial.Log, ref logIsCorrect, result, maxError, errorMeasure, tempResults);
                        MultinomCoefMethodTest(currentCombintaion, prevPermut, prevPermutNumber, Multinomial.LogGamma, ref lnGammaIsCorrect, result, maxError, errorMeasure, tempResults);
                        MultinomCoefMethodTest(currentCombintaion, prevPermut, prevPermutNumber, Multinomial.My, ref optIsCorrect, result, maxError, errorMeasure, tempResults);
                        MultinomCoefMethodTest(currentCombintaion, prevPermut, prevPermutNumber, Multinomial.PrimeNumbers, ref primeNumbersIsCorrect, result, maxError, errorMeasure, tempResults);

                        prevPermut = (uint[])currentCombintaion.Clone();
                        prevResult = result;
                        prevPermutNumber++;
                    }
                    else
                    {
                        if (prevPermut != null)
                        {
                            PrintIfCorrect(Multinomial.Naive, prevPermut, prevPermutNumber, prevResult, naiveIsCorrect, tempResults);
                            PrintIfCorrect(Multinomial.Binom, prevPermut, prevPermutNumber, prevResult, binomIsCorrect, tempResults);
                            PrintIfCorrect(Multinomial.Log, prevPermut, prevPermutNumber, prevResult, logIsCorrect, tempResults);
                            PrintIfCorrect(Multinomial.LogGamma, prevPermut, prevPermutNumber, prevResult, lnGammaIsCorrect, tempResults);
                            PrintIfCorrect(Multinomial.My, prevPermut, prevPermutNumber, prevResult, optIsCorrect, tempResults);
                            PrintIfCorrect(Multinomial.PrimeNumbers, prevPermut, prevPermutNumber, prevResult, primeNumbersIsCorrect, tempResults);
                            PrintIfCorrect(Multinomial.Big, prevPermut, prevPermutNumber, prevResult, true, tempResults);

                            PrintTempResult("Naive", tempResults);
                            PrintTempResult("Binom", tempResults);
                            PrintTempResult("Log", tempResults);
                            PrintTempResult("LogGamma", tempResults);
                            PrintTempResult("My", tempResults);
                            PrintTempResult("PrimeNumbers", tempResults);
                            PrintTempResult("Big", tempResults);
                            Results.Remove(Results.Length - 1, 1);
                        }

                        Console.WriteLine();
                        break;
                    }
                }
                iteration++;

                Results.AppendLine();
            }while (prevPermut != null);
            Console.WriteLine("Count: {0}", count);
        }
Esempio n. 4
0
        static ulong MultinomCoefMethodTest(uint[] args, uint[] prevArgs, int prevPermutNumber, Func <uint[], ulong> method,
                                            ref bool methodIsCorrect, ulong correctResult, ulong maxError, ErrorMeasure errorMeasure,
                                            Dictionary <string, MultinomialResult> tempResults)
        {
            ulong result = 0;

            if (methodIsCorrect)
            {
                try
                {
                    result = method(args);
                }
                catch
                {
                    if (prevArgs != null)
                    {
                        result = method(prevArgs);
                        Console.WriteLine(string.Format("{0}({1}) = {2}; #{3}; overflow",
                                                        method.Method.Name, string.Join(",", prevArgs), result, prevPermutNumber));
                        tempResults[method.Method.Name] = new MultinomialResult
                        {
                            Number      = prevPermutNumber,
                            Permutation = prevArgs,
                            Result      = result,
                            ErrorType   = ErrorType.Overflow,
                            Error       = 0
                        };
                    }
                    else
                    {
                        Console.WriteLine(string.Format("{0}(x); #{1}; overflow", method.Method.Name, prevPermutNumber));
                        tempResults[method.Method.Name] = new MultinomialResult
                        {
                            Number      = -1,
                            Permutation = prevArgs,
                            Result      = 0,
                            ErrorType   = ErrorType.Overflow,
                            Error       = 0
                        };
                    }

                    methodIsCorrect = false;
                }

                var error = Multinomial.Diff(result, correctResult);
                if (methodIsCorrect && ((errorMeasure == ErrorMeasure.Absolute && error > maxError) ||
                                        (errorMeasure == ErrorMeasure.Relative && ((double)error * 10000000000000 / correctResult) > maxError)))
                {
                    if (prevArgs != null)
                    {
                        Console.WriteLine(string.Format("{0}({1}) = {2}; #{3}; rounding(error = {4}{5})",
                                                        method.Method.Name, string.Join(",", prevArgs), method(prevArgs),
                                                        prevPermutNumber, error,
                                                        errorMeasure == ErrorMeasure.Relative ? "%" : string.Empty));
                        tempResults[method.Method.Name] = new MultinomialResult
                        {
                            Number      = prevPermutNumber,
                            Permutation = prevArgs,
                            Result      = result,
                            ErrorType   = ErrorType.Rounding,
                            Error       = error
                        };
                    }
                    else
                    {
                        Console.WriteLine(string.Format("{0}(x); #{1}; rounding(error = {2}{3})",
                                                        method.Method.Name, prevPermutNumber, error,
                                                        errorMeasure == ErrorMeasure.Relative ? "%" : string.Empty));
                        tempResults[method.Method.Name] = new MultinomialResult
                        {
                            Number      = -1,
                            Permutation = prevArgs,
                            Result      = 0,
                            ErrorType   = ErrorType.Rounding,
                            Error       = error
                        };
                    }

                    methodIsCorrect = false;
                }
            }
            return(result);
        }