public void CacheHitRatioCase(int n, double cacheSizePercentage, double alpha, double expectedHitRate, int maxTrials) { var zipf = new ZipfDistribution(n, alpha, 10, 0.0001); var capacity = (int)(n * cacheSizePercentage / 100); var cache = new PseudoLRUCache <string>(capacity); var allItems = new PseudoLRUCache <string> .CacheItem[n + 1]; var rankHistogram = new int[n + 1]; for (var trial = 0; trial < maxTrials; trial++) { var rank = zipf.NextRandomRank(); if (allItems[rank] == null) { allItems[rank] = cache.Add(rank.ToString()); } else { allItems[rank].GetOrCreate(() => rank.ToString()); } rankHistogram[rank]++; } Console.WriteLine($"The Hit Ratio is {cache.HitRatio}; hoped for {expectedHitRate}"); var histogram = "Rank Histogram for first 100 items\n"; var cumePct = 0.0; for (var rank = 1; rank <= 100; rank++) { var pct = 100.0 * rankHistogram[rank] / (double)maxTrials; cumePct += pct; histogram += $"{rank} chosen {rankHistogram[rank]} times ({pct}%, {cumePct}% cume)\n"; } Console.WriteLine(histogram); Assert.GreaterOrEqual(cache.HitRatio, expectedHitRate, $"Cache Hit Ratio is lower than expected: {cache.HitRatio} < {expectedHitRate}"); }
public void ZipfInterpolatedInverseRanksMatch() { var n = 10000; var k = 100; var alpha = 1.0; var epsilon = 0.0002; // Uses Interpolation var zipf = new ZipfDistribution(n, alpha, k, epsilon); var lowestRankWithDifference = new int[1000]; var success = true; var detailedLog = ""; var countWithDifferenceMoreThanTwo = 0; var prevDifference = 0; for (var rank = 1; rank <= n; rank++) { var cdf = zipf.CDF(rank); var actualRank = zipf.Rank(cdf); var trueDifference = rank - actualRank; var difference = Abs(trueDifference); if (lowestRankWithDifference[difference] == 0) { lowestRankWithDifference[difference] = rank; } success = success && difference <= 2; if (difference > 0 && zipf.InterpolationCDFRanks.Contains(rank)) { Console.WriteLine($"Difference = {difference} for interpolation point at rank = {rank}"); } if (trueDifference != prevDifference) { detailedLog += $"{rank}. {trueDifference}\n"; } if (difference > 2) { countWithDifferenceMoreThanTwo++; } prevDifference = trueDifference; } Console.WriteLine(zipf.ToString()); Console.WriteLine($"Count with Difference > 2: {countWithDifferenceMoreThanTwo}"); for (var i = 1; i < lowestRankWithDifference.Length; i++) { if (lowestRankWithDifference[i] > 0) { Console.WriteLine($"Difference = {i}, Rank = {lowestRankWithDifference[i]}"); } } Console.WriteLine(detailedLog); Assert.IsTrue(success, $"Interpolation failed for rank {lowestRankWithDifference[3]}."); }
public void ZipfUninterpolatedInverseRanksMatchWhenAlphaIsOne() { var n = 1000; var alpha = 1.0; var epsilon = 0; // Uses No interpolation var zipf = new ZipfDistribution(n, alpha, 5, epsilon); for (var rank = 1; rank <= n; rank++) { var cdf = zipf.CDF(rank); var actualRank = zipf.Rank(cdf); Assert.IsTrue(Abs(rank - actualRank) <= 1, $"Interpolation failed for rank {rank}. CDF = {cdf}. Inverse Rank {actualRank}"); } }
public void ZipfPDFValuesDecrease() { var n = 1000; var alpha = .01; var zipf = new ZipfDistribution(n, alpha, 5, 0.01); var prevPdf = zipf.PDF(1); Assert.IsTrue(prevPdf < 1 && prevPdf > 0, $"PDF(1) is out of range: {prevPdf}"); for (var rank = 2; rank <= n; rank++) { var pdf = zipf.PDF(rank); Assert.Less(pdf, prevPdf, $"PDF({rank}) is not less than PDF({rank-1}): {pdf}"); prevPdf = pdf; } }
public void ZipfApproximateCDFIsCloseToCDF() { var n = 10000; var alpha = 0.95; var epsilon = 0.01; var zipf = new ZipfDistribution(n, alpha, 10, epsilon, ZipfDistribution.InterpolationMethod.Hyperbolic); Console.WriteLine(zipf.ToString()); for (var rank = 1; rank <= n; rank++) { var expectedCdf = zipf.CDF(rank); var actualCdf = zipf.ApproximateCDF(rank); Assert.IsFalse(RelativeErrorExceedsTolerance(expectedCdf, actualCdf, epsilon), $"Approximate CDF has unacceptable error for rank {rank} with {zipf.InterpolationSize} control points: Expected {expectedCdf} vs actual {actualCdf}"); } }
public void ZipfInterpolationSizeIncreasesWithAccuracy() { var n = 10000; var alpha = 0.95; var epsilons = new[] { 0.05, 0.04, 0.03, 0.02, 0.01, 0.005, 0.001, 0.0005, 0.0001, 0.00005 }; var previousCount = 1; foreach (var epsilon in epsilons) { var zipf = new ZipfDistribution(n, alpha, 10, epsilon, ZipfDistribution.InterpolationMethod.Hyperbolic); Console.WriteLine(zipf.ToString()); var currentCount = zipf.InterpolationSize; Assert.GreaterOrEqual(currentCount, previousCount, $"Number of interpolation points decreased unexpectedly for epsilon = {epsilon}"); previousCount = currentCount; } }
public void ZipfCDFValuesIncreaseToOne() { var n = 1000; var alpha = 0.9; var zipf = new ZipfDistribution(n, alpha, 5, 0.01); var prevCdf = zipf.CDF(1); Assert.IsTrue(prevCdf < 1 && prevCdf > 0, $"CDF(1) is out of range: {prevCdf}"); for (var rank = 2; rank <= n; rank++) { var cdf = zipf.CDF(rank); Assert.Greater(cdf, prevCdf, $"CDF({rank}) is not greater than CDF({rank - 1}): {cdf}"); prevCdf = cdf; } var actualCdf = zipf.CDF(n); Assert.AreEqual(1.0, actualCdf, $"CDF(N) should equal one, but is instead {actualCdf}"); }