tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

distribution_test_util_test.cc (6065B)


      1 // Copyright 2017 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 
     15 #include "absl/random/internal/distribution_test_util.h"
     16 
     17 #include "gtest/gtest.h"
     18 
     19 namespace {
     20 
     21 TEST(TestUtil, InverseErf) {
     22  const struct {
     23    const double z;
     24    const double value;
     25  } kErfInvTable[] = {
     26      {0.0000001, 8.86227e-8},
     27      {0.00001, 8.86227e-6},
     28      {0.5, 0.4769362762044},
     29      {0.6, 0.5951160814499},
     30      {0.99999, 3.1234132743},
     31      {0.9999999, 3.7665625816},
     32      {0.999999944, 3.8403850690566985},  // = log((1-x) * (1+x)) =~ 16.004
     33      {0.999999999, 4.3200053849134452},
     34  };
     35 
     36  for (const auto& data : kErfInvTable) {
     37    auto value = absl::random_internal::erfinv(data.z);
     38 
     39    // Log using the Wolfram-alpha function name & parameters.
     40    EXPECT_NEAR(value, data.value, 1e-8)
     41        << " InverseErf[" << data.z << "]  (expected=" << data.value << ")  -> "
     42        << value;
     43  }
     44 }
     45 
     46 const struct {
     47  const double p;
     48  const double q;
     49  const double x;
     50  const double alpha;
     51 } kBetaTable[] = {
     52    {0.5, 0.5, 0.01, 0.06376856085851985},
     53    {0.5, 0.5, 0.1, 0.2048327646991335},
     54    {0.5, 0.5, 1, 1},
     55    {1, 0.5, 0, 0},
     56    {1, 0.5, 0.01, 0.005012562893380045},
     57    {1, 0.5, 0.1, 0.0513167019494862},
     58    {1, 0.5, 0.5, 0.2928932188134525},
     59    {1, 1, 0.5, 0.5},
     60    {2, 2, 0.1, 0.028},
     61    {2, 2, 0.2, 0.104},
     62    {2, 2, 0.3, 0.216},
     63    {2, 2, 0.4, 0.352},
     64    {2, 2, 0.5, 0.5},
     65    {2, 2, 0.6, 0.648},
     66    {2, 2, 0.7, 0.784},
     67    {2, 2, 0.8, 0.896},
     68    {2, 2, 0.9, 0.972},
     69    {5.5, 5, 0.5, 0.4361908850559777},
     70    {10, 0.5, 0.9, 0.1516409096346979},
     71    {10, 5, 0.5, 0.08978271484375},
     72    {10, 5, 1, 1},
     73    {10, 10, 0.5, 0.5},
     74    {20, 5, 0.8, 0.4598773297575791},
     75    {20, 10, 0.6, 0.2146816102371739},
     76    {20, 10, 0.8, 0.9507364826957875},
     77    {20, 20, 0.5, 0.5},
     78    {20, 20, 0.6, 0.8979413687105918},
     79    {30, 10, 0.7, 0.2241297491808366},
     80    {30, 10, 0.8, 0.7586405487192086},
     81    {40, 20, 0.7, 0.7001783247477069},
     82    {1, 0.5, 0.1, 0.0513167019494862},
     83    {1, 0.5, 0.2, 0.1055728090000841},
     84    {1, 0.5, 0.3, 0.1633399734659245},
     85    {1, 0.5, 0.4, 0.2254033307585166},
     86    {1, 2, 0.2, 0.36},
     87    {1, 3, 0.2, 0.488},
     88    {1, 4, 0.2, 0.5904},
     89    {1, 5, 0.2, 0.67232},
     90    {2, 2, 0.3, 0.216},
     91    {3, 2, 0.3, 0.0837},
     92    {4, 2, 0.3, 0.03078},
     93    {5, 2, 0.3, 0.010935},
     94 
     95    // These values test small & large points along the range of the Beta
     96    // function.
     97    //
     98    // When selecting test points, remember that if BetaIncomplete(x, p, q)
     99    // returns the same value to within the limits of precision over a large
    100    // domain of the input, x, then BetaIncompleteInv(alpha, p, q) may return an
    101    // essentially arbitrary value where BetaIncomplete(x, p, q) =~ alpha.
    102 
    103    // BetaRegularized[x, 0.00001, 0.00001],
    104    // For x in {~0.001 ... ~0.999}, => ~0.5
    105    {1e-5, 1e-5, 1e-5, 0.4999424388184638311},
    106    {1e-5, 1e-5, (1.0 - 1e-8), 0.5000920948389232964},
    107 
    108    // BetaRegularized[x, 0.00001, 10000].
    109    // For x in {~epsilon ... 1.0}, => ~1
    110    {1e-5, 1e5, 1e-6, 0.9999817708130066936},
    111    {1e-5, 1e5, (1.0 - 1e-7), 1.0},
    112 
    113    // BetaRegularized[x, 10000, 0.00001].
    114    // For x in {0 .. 1-epsilon}, => ~0
    115    {1e5, 1e-5, 1e-6, 0},
    116    {1e5, 1e-5, (1.0 - 1e-6), 1.8229186993306369e-5},
    117 };
    118 
    119 TEST(BetaTest, BetaIncomplete) {
    120  for (const auto& data : kBetaTable) {
    121    auto value = absl::random_internal::BetaIncomplete(data.x, data.p, data.q);
    122 
    123    // Log using the Wolfram-alpha function name & parameters.
    124    EXPECT_NEAR(value, data.alpha, 1e-12)
    125        << " BetaRegularized[" << data.x << ", " << data.p << ", " << data.q
    126        << "]  (expected=" << data.alpha << ")  -> " << value;
    127  }
    128 }
    129 
    130 TEST(BetaTest, BetaIncompleteInv) {
    131  for (const auto& data : kBetaTable) {
    132    auto value =
    133        absl::random_internal::BetaIncompleteInv(data.p, data.q, data.alpha);
    134 
    135    // Log using the Wolfram-alpha function name & parameters.
    136    EXPECT_NEAR(value, data.x, 1e-6)
    137        << " InverseBetaRegularized[" << data.alpha << ", " << data.p << ", "
    138        << data.q << "]  (expected=" << data.x << ")  -> " << value;
    139  }
    140 }
    141 
    142 TEST(MaxErrorTolerance, MaxErrorTolerance) {
    143  std::vector<std::pair<double, double>> cases = {
    144      {0.0000001, 8.86227e-8 * 1.41421356237},
    145      {0.00001, 8.86227e-6 * 1.41421356237},
    146      {0.5, 0.4769362762044 * 1.41421356237},
    147      {0.6, 0.5951160814499 * 1.41421356237},
    148      {0.99999, 3.1234132743 * 1.41421356237},
    149      {0.9999999, 3.7665625816 * 1.41421356237},
    150      {0.999999944, 3.8403850690566985 * 1.41421356237},
    151      {0.999999999, 4.3200053849134452 * 1.41421356237}};
    152  for (auto entry : cases) {
    153    EXPECT_NEAR(absl::random_internal::MaxErrorTolerance(entry.first),
    154                entry.second, 1e-8);
    155  }
    156 }
    157 
    158 TEST(ZScore, WithSameMean) {
    159  absl::random_internal::DistributionMoments m;
    160  m.n = 100;
    161  m.mean = 5;
    162  m.variance = 1;
    163  EXPECT_NEAR(absl::random_internal::ZScore(5, m), 0, 1e-12);
    164 
    165  m.n = 1;
    166  m.mean = 0;
    167  m.variance = 1;
    168  EXPECT_NEAR(absl::random_internal::ZScore(0, m), 0, 1e-12);
    169 
    170  m.n = 10000;
    171  m.mean = -5;
    172  m.variance = 100;
    173  EXPECT_NEAR(absl::random_internal::ZScore(-5, m), 0, 1e-12);
    174 }
    175 
    176 TEST(ZScore, DifferentMean) {
    177  absl::random_internal::DistributionMoments m;
    178  m.n = 100;
    179  m.mean = 5;
    180  m.variance = 1;
    181  EXPECT_NEAR(absl::random_internal::ZScore(4, m), 10, 1e-12);
    182 
    183  m.n = 1;
    184  m.mean = 0;
    185  m.variance = 1;
    186  EXPECT_NEAR(absl::random_internal::ZScore(-1, m), 1, 1e-12);
    187 
    188  m.n = 10000;
    189  m.mean = -5;
    190  m.variance = 100;
    191  EXPECT_NEAR(absl::random_internal::ZScore(-4, m), -10, 1e-12);
    192 }
    193 }  // namespace