abseil-cpp/absl/profiling/internal/exponential_biased_test.cc
Go to the documentation of this file.
1 // Copyright 2019 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
16 
17 #include <stddef.h>
18 
19 #include <cmath>
20 #include <cstdint>
21 #include <vector>
22 
23 #include "gmock/gmock.h"
24 #include "gtest/gtest.h"
25 #include "absl/strings/str_cat.h"
26 
28 
29 namespace absl {
31 namespace profiling_internal {
32 namespace {
33 
34 MATCHER_P2(IsBetween, a, b,
35  absl::StrCat(std::string(negation ? "isn't" : "is"), " between ", a,
36  " and ", b)) {
37  return a <= arg && arg <= b;
38 }
39 
40 // Tests of the quality of the random numbers generated
41 // This uses the Anderson Darling test for uniformity.
42 // See "Evaluating the Anderson-Darling Distribution" by Marsaglia
43 // for details.
44 
45 // Short cut version of ADinf(z), z>0 (from Marsaglia)
46 // This returns the p-value for Anderson Darling statistic in
47 // the limit as n-> infinity. For finite n, apply the error fix below.
48 double AndersonDarlingInf(double z) {
49  if (z < 2) {
50  return exp(-1.2337141 / z) / sqrt(z) *
51  (2.00012 +
52  (0.247105 -
53  (0.0649821 - (0.0347962 - (0.011672 - 0.00168691 * z) * z) * z) *
54  z) *
55  z);
56  }
57  return exp(
58  -exp(1.0776 -
59  (2.30695 -
60  (0.43424 - (0.082433 - (0.008056 - 0.0003146 * z) * z) * z) * z) *
61  z));
62 }
63 
64 // Corrects the approximation error in AndersonDarlingInf for small values of n
65 // Add this to AndersonDarlingInf to get a better approximation
66 // (from Marsaglia)
67 double AndersonDarlingErrFix(int n, double x) {
68  if (x > 0.8) {
69  return (-130.2137 +
70  (745.2337 -
71  (1705.091 - (1950.646 - (1116.360 - 255.7844 * x) * x) * x) * x) *
72  x) /
73  n;
74  }
75  double cutoff = 0.01265 + 0.1757 / n;
76  if (x < cutoff) {
77  double t = x / cutoff;
78  t = sqrt(t) * (1 - t) * (49 * t - 102);
79  return t * (0.0037 / (n * n) + 0.00078 / n + 0.00006) / n;
80  } else {
81  double t = (x - cutoff) / (0.8 - cutoff);
82  t = -0.00022633 +
83  (6.54034 - (14.6538 - (14.458 - (8.259 - 1.91864 * t) * t) * t) * t) *
84  t;
85  return t * (0.04213 + 0.01365 / n) / n;
86  }
87 }
88 
89 // Returns the AndersonDarling p-value given n and the value of the statistic
90 double AndersonDarlingPValue(int n, double z) {
91  double ad = AndersonDarlingInf(z);
92  double errfix = AndersonDarlingErrFix(n, ad);
93  return ad + errfix;
94 }
95 
96 double AndersonDarlingStatistic(const std::vector<double>& random_sample) {
97  int n = random_sample.size();
98  double ad_sum = 0;
99  for (int i = 0; i < n; i++) {
100  ad_sum += (2 * i + 1) *
101  std::log(random_sample[i] * (1 - random_sample[n - 1 - i]));
102  }
103  double ad_statistic = -n - 1 / static_cast<double>(n) * ad_sum;
104  return ad_statistic;
105 }
106 
107 // Tests if the array of doubles is uniformly distributed.
108 // Returns the p-value of the Anderson Darling Statistic
109 // for the given set of sorted random doubles
110 // See "Evaluating the Anderson-Darling Distribution" by
111 // Marsaglia and Marsaglia for details.
112 double AndersonDarlingTest(const std::vector<double>& random_sample) {
113  double ad_statistic = AndersonDarlingStatistic(random_sample);
114  double p = AndersonDarlingPValue(random_sample.size(), ad_statistic);
115  return p;
116 }
117 
118 TEST(ExponentialBiasedTest, CoinTossDemoWithGetSkipCount) {
119  ExponentialBiased eb;
120  for (int runs = 0; runs < 10; ++runs) {
121  for (int flips = eb.GetSkipCount(1); flips > 0; --flips) {
122  printf("head...");
123  }
124  printf("tail\n");
125  }
126  int heads = 0;
127  for (int i = 0; i < 10000000; i += 1 + eb.GetSkipCount(1)) {
128  ++heads;
129  }
130  printf("Heads = %d (%f%%)\n", heads, 100.0 * heads / 10000000);
131 }
132 
133 TEST(ExponentialBiasedTest, SampleDemoWithStride) {
134  ExponentialBiased eb;
135  int stride = eb.GetStride(10);
136  int samples = 0;
137  for (int i = 0; i < 10000000; ++i) {
138  if (--stride == 0) {
139  ++samples;
140  stride = eb.GetStride(10);
141  }
142  }
143  printf("Samples = %d (%f%%)\n", samples, 100.0 * samples / 10000000);
144 }
145 
146 
147 // Testing that NextRandom generates uniform random numbers. Applies the
148 // Anderson-Darling test for uniformity
149 TEST(ExponentialBiasedTest, TestNextRandom) {
150  for (auto n : std::vector<int>({
151  10, // Check short-range correlation
152  100, 1000,
153  10000 // Make sure there's no systemic error
154  })) {
155  uint64_t x = 1;
156  // This assumes that the prng returns 48 bit numbers
157  uint64_t max_prng_value = static_cast<uint64_t>(1) << 48;
158  // Initialize.
159  for (int i = 1; i <= 20; i++) {
161  }
162  std::vector<uint64_t> int_random_sample(n);
163  // Collect samples
164  for (int i = 0; i < n; i++) {
165  int_random_sample[i] = x;
167  }
168  // First sort them...
169  std::sort(int_random_sample.begin(), int_random_sample.end());
170  std::vector<double> random_sample(n);
171  // Convert them to uniform randoms (in the range [0,1])
172  for (int i = 0; i < n; i++) {
173  random_sample[i] =
174  static_cast<double>(int_random_sample[i]) / max_prng_value;
175  }
176  // Now compute the Anderson-Darling statistic
177  double ad_pvalue = AndersonDarlingTest(random_sample);
178  EXPECT_GT(std::min(ad_pvalue, 1 - ad_pvalue), 0.0001)
179  << "prng is not uniform: n = " << n << " p = " << ad_pvalue;
180  }
181 }
182 
183 // The generator needs to be available as a thread_local and as a static
184 // variable.
185 TEST(ExponentialBiasedTest, InitializationModes) {
186  ABSL_CONST_INIT static ExponentialBiased eb_static;
187  EXPECT_THAT(eb_static.GetSkipCount(2), Ge(0));
188 
189 #ifdef ABSL_HAVE_THREAD_LOCAL
190  thread_local ExponentialBiased eb_thread;
191  EXPECT_THAT(eb_thread.GetSkipCount(2), Ge(0));
192 #endif
193 
194  ExponentialBiased eb_stack;
195  EXPECT_THAT(eb_stack.GetSkipCount(2), Ge(0));
196 }
197 
198 } // namespace
199 } // namespace profiling_internal
201 } // namespace absl
ABSL_CONST_INIT
#define ABSL_CONST_INIT
Definition: abseil-cpp/absl/base/attributes.h:716
absl::StrCat
std::string StrCat(const AlphaNum &a, const AlphaNum &b)
Definition: abseil-cpp/absl/strings/str_cat.cc:98
EXPECT_THAT
#define EXPECT_THAT(value, matcher)
printf
_Use_decl_annotations_ int __cdecl printf(const char *_Format,...)
Definition: cs_driver.c:91
EXPECT_GT
#define EXPECT_GT(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2036
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
absl::TEST
TEST(NotificationTest, SanityTest)
Definition: abseil-cpp/absl/synchronization/notification_test.cc:126
a
int a
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:88
testing::Ge
internal::GeMatcher< Rhs > Ge(Rhs x)
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:8585
xds_manager.p
p
Definition: xds_manager.py:60
z
Uncopyable z
Definition: bloaty/third_party/googletest/googlemock/test/gmock-matchers_test.cc:3612
ABSL_NAMESPACE_END
#define ABSL_NAMESPACE_END
Definition: third_party/abseil-cpp/absl/base/config.h:171
ABSL_NAMESPACE_BEGIN
#define ABSL_NAMESPACE_BEGIN
Definition: third_party/abseil-cpp/absl/base/config.h:170
uint64_t
unsigned __int64 uint64_t
Definition: stdint-msvc2008.h:90
arg
Definition: cmdline.cc:40
x
int x
Definition: bloaty/third_party/googletest/googlemock/test/gmock-matchers_test.cc:3610
min
#define min(a, b)
Definition: qsort.h:83
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
absl::base_internal::AndersonDarlingPValue
double AndersonDarlingPValue(int n, double z)
Definition: bloaty/third_party/abseil-cpp/absl/base/internal/exponential_biased_test.cc:89
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
absl::base_internal::AndersonDarlingTest
double AndersonDarlingTest(const std::vector< double > &random_sample)
Definition: bloaty/third_party/abseil-cpp/absl/base/internal/exponential_biased_test.cc:111
absl::base_internal::AndersonDarlingErrFix
double AndersonDarlingErrFix(int n, double x)
Definition: bloaty/third_party/abseil-cpp/absl/base/internal/exponential_biased_test.cc:66
absl::base_internal::AndersonDarlingInf
double AndersonDarlingInf(double z)
Definition: bloaty/third_party/abseil-cpp/absl/base/internal/exponential_biased_test.cc:47
absl::profiling_internal::ExponentialBiased::NextRandom
static uint64_t NextRandom(uint64_t rnd)
Definition: abseil-cpp/absl/profiling/internal/exponential_biased.h:117
absl::str_format_internal::LengthMod::t
@ t
log
bool log
Definition: abseil-cpp/absl/synchronization/mutex.cc:310
absl::base_internal::AndersonDarlingStatistic
double AndersonDarlingStatistic(const std::vector< double > &random_sample)
Definition: bloaty/third_party/abseil-cpp/absl/base/internal/exponential_biased_test.cc:95
absl
Definition: abseil-cpp/absl/algorithm/algorithm.h:31
absl::MATCHER_P2
MATCHER_P2(CordzMethodCountEq, method, n, absl::StrCat("CordzInfo method count equals ", n))
Definition: abseil-cpp/absl/strings/cordz_test_helpers.h:82
exponential_biased.h
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230


grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:20