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); }
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); }
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); }