summaryrefslogtreecommitdiff
path: root/absl/random/internal/chi_square_test.cc
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2019-08-08 10:56:58 -0700
committerGravatar CJ Johnson <johnsoncj@google.com>2019-08-08 14:19:45 -0400
commitaa844899c937bde5d2b24f276b59997e5b668bde (patch)
treecd18e64150abc74b85bbbf6abf990f66fa47cacd /absl/random/internal/chi_square_test.cc
parentfcb104594b0bb4b8ac306cb2f55ecdad40974683 (diff)
Creation of LTS branch "lts_2019_08_08"20190808
- 9ee91d3e430fb33a4590486573792eb0fa146c2d Export of internal Abseil changes by Abseil Team <absl-team@google.com> - 8efba58a3b656e9b41fb0471ae6453425a61c520 Export of internal Abseil changes by Abseil Team <absl-team@google.com> - b49b8d16b67ec6912899684b732e6367f258cfdb Export of internal Abseil changes by Abseil Team <absl-team@google.com> - 67222ffc4c83d918ce8395aa61769eeb77df4c4d Export of internal Abseil changes by Abseil Team <absl-team@google.com> - c5c4db4f5191fe5e76cbf68dcc71fb28702f7d2b Export of internal Abseil changes by Abseil Team <absl-team@google.com> - 14550beb3b7b97195e483fb74b5efb906395c31e Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 52e88ee56b72cf32bc66534d942c7398ce481331 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 36d37ab992038f52276ca66b9da80c1cf0f57dc2 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - ad1485c8986246b2ae9105e512738d0e97aec887 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - f3840bc5e33ce4932e35986cf3718450c6f02af2 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 278b26058c036833a4f7f3047d3f4d9296527f87 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - c6c3c1b498e4ee939b24be59cae29d59c3863be8 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 44efe96dfca674a17b45ca53fc77fb69f1e29bf4 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 3c98fcc0461bd2a4b9c149d4748a7373a225cf4b Merge pull request #340 from jtsylve/macos_cxx17_fix by Matt Calabrese <38107210+mattcalabrese-google@users.noreply.github.com> - 74d91756c11bc22f9b0108b94da9326f7f9e376f Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - e6b050212c859fbaf67abac76105da10ec348274 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - c964fcffac27bd4a9ff67fe393410dd1146ef8b8 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 72e09a54d993b192db32be14c65adf7e9bd08c31 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - d65e19dfcd8697076f68598c0131c6930cdcd74d Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 5162fc83d2f3b79a9753ed59594c43966afdd37a Merge pull request #336 from shields/patch-2 by Shaindel Schwartz <31392632+shaindelschwartz@users.noreply.github.com> - 0389f7bf58fa41f35b3ad60be61d32f31e4f8ed6 Merge pull request #335 from shields/patch-1 by Shaindel Schwartz <31392632+shaindelschwartz@users.noreply.github.com> - e9324d926a9189e222741fce6e676f0944661a72 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 43ef2148c0936ebf7cb4be6b19927a9d9d145b8f Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - a13d3df2b3ba68aeead92e2d078fba0510d55024 Merge pull request #323 from gosnik/master by Gennadiy Rozental <rogeeff@google.com> - 310a11865c97c5cdcc42a4ee2c2e3578423afe69 Merge pull request #324 from RasPat1/patch-1 by Gennadiy Rozental <rogeeff@google.com> - 8f11724067248acc330b4d1f12f0c76d03f2cfb1 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - b1dd425423380126f6441ce4fbb6f8f6c75b793a Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 361cb8a9db2f2130442389fd80593255be26d681 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 0238ab0a831f179518c1a814f9584e99da2d75a3 Merge pull request #321 from christoph-cullmann/c4245_fix... by Xiaoyi Zhang <zhangxy988@gmail.com> - 61c9bf3e3e1c28a4aa6d7f1be4b37fd473bb5529 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - bc9101f9982391019521161a36179b52555ed212 Merge pull request #320 from christoph-cullmann/master by Xiaoyi Zhang <zhangxy988@gmail.com> - 2f76a9bf50046e396138cc8eeb3cdc17b7a5ac24 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 4adaf5490921f13028b55018c9f550277de5aebb Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 27c30ec671cb7b5ba84c4e79feff7fd0b0ac6338 Avoid undefined behavior when nullptr is passed to memcpy... by Roman Gershman <romange@gmail.com> - ce65f5ac3cbf897bb5e3de1a51d80fd00866abaa Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - a18fc7461e7409c2ad64e28537261db1e02e76fa Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 8a394b19c149cab50534b04c5e21d42bc2217a7d Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - daf381e8535a1f1f1b8a75966a74e7cca63dee89 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - fa00c321073c7ea40a4fc3dfc8a06309eae3d025 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 436ba6c4a0ea3a06eca6e055f9c8d296bf3bae12 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 0cbdc774b97f7e80ab60dbe2ed4eaca3b2e33fc8 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 27c2f6e2f3b5929fbd322b0f0ca392eb02efd9f8 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - aa468ad75539619b47979911297efbb629c52e44 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - cd86d0d20ab167c33b23d3875db68d1d4bad3a3b Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 33841c5c963aa9c3f096ef8e6c1e71624b941940 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - ca3f87560a0eef716195cadf66dc6b938a579ec6 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - d902eb869bcfacc1bad14933ed9af4bed006d481 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - a02f62f456f2c4a7ecf2be3104fe0c6e16fbad9a Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 0b545b460141b882b244a1efcef7621d59278160 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - dbae8764fbd429bf7d7745e24bcf73962177a7c0 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 044da8a29c923506af0f0b46bc46f43c1e1300b5 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 6cc6ac44e065b9e8975fadfd6ccb99cbcf89aac4 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 666fc1266bccfd8e6eaaa084e7b42580bb8eb199 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 93dfcf74cb5fccae3da07897d8613ae6cab958a0 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 2c8421e1c6cef0da9e8a20b01c15256ec9ec116d Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 5b65c4af5107176555b23a638e5947686410ac1f Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - eab2078b53c9e3d9d240135c09d27e3393acb50a Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 253eb7416421661873afbaa33828a850db978541 [CMake] Set correct flags for clang-cl (#278) by Loo Rong Jie <loorongjie@gmail.com> - e75672f6afc7e8f23ee7b532e86d1b3b9be3984e Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - bf29470384a101b307873b26d358433138c857fc Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 6fd827124facd8336981e73218997f9e73029b4f Merge pull request #280 from chiumichael/master by Derek Mauro <761129+derekmauro@users.noreply.github.com> - 7c7754fb3ed9ffb57d35fe8658f3ba4d73a31e72 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 256be563447a315f2a7993ec669460ba475fa86a Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 88a152ae747c3c42dc9167d46c590929b048d436 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - c1cecb25a94c075725e9d2640f6b978a8f61957b Implement Span::first and Span::last from C++20 (#274) by Girts <girtsf@users.noreply.github.com> - 38b704384cd2f17590b3922b97744be0b43622c9 Changed HTTP URLs to HTTPS where possible (#270) by nik7273 <nik8470@gmail.com> - febc5ee6a92d0eb7dac1fceaa6c648cf6521b4dc Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 9fdf5e5b805412cb2a2e624d3e9a11588120465f Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 419f3184f8ebcdb23105295eadd2a569f3351eb9 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - b312c3cb53a0aad75a85ac2bf57c4a614fbd48d4 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 308ce31528a7edfa39f5f6d36142278a0ae1bf45 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 93d155bc4414f6c121bb1f19dba9fdb27c8943bc Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 426eaa4aa44e4580418bee46c1bd13911151bfb1 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 2901ec32a919311384d6ad4194e2d927c06831f7 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - d78310fe5a82f2e0e6e16509ef8079c8d7e4674e Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - a4cb1c8ba61531a63f9d309eea01ac1d43d8371d Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 540e2537b92cd4abfae6ceddfe24304345461f32 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 89ea0c5ff34aaa5855cfc7aa41f323b8a0ef0ede Merge pull request #255 from uilianries/hotfix/conan by ahedberg <ahedberg@google.com> - 5e0dcf72c64fae912184d2e0de87195fe8f0a425 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 0dffca4e36791c7beeda04da10460b534283948a Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 6b4201f9ef650637510a21b8d6cbcc3bee4a606f Fix GCC8 warnings by Boris Staletic <boris.staletic@gmail.com> - 0b1e6d417b414aad9282e32e8c49c719edeb63c1 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - efccc502606bed768e50a6cd5806d8eb13e4e935 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 5e6a78131f7bd5940218462c07d88cdefdd75dbe Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 5eea0f713c14ac17788b83e496f11903f8e2bbb0 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 66f9becbb98ecc083f4db349b4b1e0ca9de93b15 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 018b4db1d73ec8238e6dc4b17fd9e1fd7468d0ed Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 9449ae94397f2fd683851348e25ed8c93f75b3b9 Merge pull request #243 from ThomsonTan/FixIntrinsic by Alex Strelnikov <strel@google.com> - b16aeb6756bdab08cdf12d40baab5b51f7d15b16 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 7ffbe09f3d85504bd018783bbe1e2c12992fe47c Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 01b471d9f3ebef27f5aaca14b66509099fa8cd6c Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 7bd8f36c741c7cbe311611d7981bf38ba04c6fef Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 968a34ffdaadd7db062a9621dfbdf8b2d16e05af Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 3e2e9b5557e76d098de4b8a2a659125b98ca519b Merge pull request #231 from uilianries/feature/conan by Mark Barolak <mbxx@users.noreply.github.com> - 111ca7060a6ff50115ca85b59f6b5d8c8c5e9105 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 389ec3f906f018661a5308458d623d01f96d7b23 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 8fbcdb90952c57828c4a9c2f6d79fcd7cae9088f Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 455dc17ba1af9635f0b60155bc565bc572a1e722 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - f197d7c72a54064cfde5a2058f1513a4a0ee36fb Export of internal Abseil changes. by Abseil Team <absl-team@google.com> - 284378a71b32dfb3af4e3661f585e671d1b603a3 Export of internal Abseil changes. by Abseil Team <absl-team@google.com> GitOrigin-RevId: 9ee91d3e430fb33a4590486573792eb0fa146c2d Change-Id: Ia06e548bc106cc9d136f6c65714be6645317aced
Diffstat (limited to 'absl/random/internal/chi_square_test.cc')
-rw-r--r--absl/random/internal/chi_square_test.cc365
1 files changed, 365 insertions, 0 deletions
diff --git a/absl/random/internal/chi_square_test.cc b/absl/random/internal/chi_square_test.cc
new file mode 100644
index 00000000..5025defa
--- /dev/null
+++ b/absl/random/internal/chi_square_test.cc
@@ -0,0 +1,365 @@
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/random/internal/chi_square.h"
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <iterator>
+#include <numeric>
+#include <vector>
+
+#include "gtest/gtest.h"
+#include "absl/base/macros.h"
+
+using absl::random_internal::ChiSquare;
+using absl::random_internal::ChiSquarePValue;
+using absl::random_internal::ChiSquareValue;
+using absl::random_internal::ChiSquareWithExpected;
+
+namespace {
+
+TEST(ChiSquare, Value) {
+ struct {
+ int line;
+ double chi_square;
+ int df;
+ double confidence;
+ } const specs[] = {
+ // Testing lookup at 1% confidence
+ {__LINE__, 0, 0, 0.01},
+ {__LINE__, 0.00016, 1, 0.01},
+ {__LINE__, 1.64650, 8, 0.01},
+ {__LINE__, 5.81221, 16, 0.01},
+ {__LINE__, 156.4319, 200, 0.01},
+ {__LINE__, 1121.3784, 1234, 0.01},
+ {__LINE__, 53557.1629, 54321, 0.01},
+ {__LINE__, 651662.6647, 654321, 0.01},
+
+ // Testing lookup at 99% confidence
+ {__LINE__, 0, 0, 0.99},
+ {__LINE__, 6.635, 1, 0.99},
+ {__LINE__, 20.090, 8, 0.99},
+ {__LINE__, 32.000, 16, 0.99},
+ {__LINE__, 249.4456, 200, 0.99},
+ {__LINE__, 1131.1573, 1023, 0.99},
+ {__LINE__, 1352.5038, 1234, 0.99},
+ {__LINE__, 55090.7356, 54321, 0.99},
+ {__LINE__, 656985.1514, 654321, 0.99},
+
+ // Testing lookup at 99.9% confidence
+ {__LINE__, 16.2659, 3, 0.999},
+ {__LINE__, 22.4580, 6, 0.999},
+ {__LINE__, 267.5409, 200, 0.999},
+ {__LINE__, 1168.5033, 1023, 0.999},
+ {__LINE__, 55345.1741, 54321, 0.999},
+ {__LINE__, 657861.7284, 654321, 0.999},
+ {__LINE__, 51.1772, 24, 0.999},
+ {__LINE__, 59.7003, 30, 0.999},
+ {__LINE__, 37.6984, 15, 0.999},
+ {__LINE__, 29.5898, 10, 0.999},
+ {__LINE__, 27.8776, 9, 0.999},
+
+ // Testing lookup at random confidences
+ {__LINE__, 0.000157088, 1, 0.01},
+ {__LINE__, 5.31852, 2, 0.93},
+ {__LINE__, 1.92256, 4, 0.25},
+ {__LINE__, 10.7709, 13, 0.37},
+ {__LINE__, 26.2514, 17, 0.93},
+ {__LINE__, 36.4799, 29, 0.84},
+ {__LINE__, 25.818, 31, 0.27},
+ {__LINE__, 63.3346, 64, 0.50},
+ {__LINE__, 196.211, 128, 0.9999},
+ {__LINE__, 215.21, 243, 0.10},
+ {__LINE__, 285.393, 256, 0.90},
+ {__LINE__, 984.504, 1024, 0.1923},
+ {__LINE__, 2043.85, 2048, 0.4783},
+ {__LINE__, 48004.6, 48273, 0.194},
+ };
+ for (const auto& spec : specs) {
+ SCOPED_TRACE(spec.line);
+ // Verify all values are have at most a 1% relative error.
+ const double val = ChiSquareValue(spec.df, spec.confidence);
+ const double err = std::max(5e-6, spec.chi_square / 5e3); // 1 part in 5000
+ EXPECT_NEAR(spec.chi_square, val, err) << spec.line;
+ }
+
+ // Relaxed test for extreme values, from
+ // http://www.ciphersbyritter.com/JAVASCRP/NORMCHIK.HTM#ChiSquare
+ EXPECT_NEAR(49.2680, ChiSquareValue(100, 1e-6), 5); // 0.000'005 mark
+ EXPECT_NEAR(123.499, ChiSquareValue(200, 1e-6), 5); // 0.000'005 mark
+
+ EXPECT_NEAR(149.449, ChiSquareValue(100, 0.999), 0.01);
+ EXPECT_NEAR(161.318, ChiSquareValue(100, 0.9999), 0.01);
+ EXPECT_NEAR(172.098, ChiSquareValue(100, 0.99999), 0.01);
+
+ EXPECT_NEAR(381.426, ChiSquareValue(300, 0.999), 0.05);
+ EXPECT_NEAR(399.756, ChiSquareValue(300, 0.9999), 0.1);
+ EXPECT_NEAR(416.126, ChiSquareValue(300, 0.99999), 0.2);
+}
+
+TEST(ChiSquareTest, PValue) {
+ struct {
+ int line;
+ double pval;
+ double chi_square;
+ int df;
+ } static const specs[] = {
+ {__LINE__, 1, 0, 0},
+ {__LINE__, 0, 0.001, 0},
+ {__LINE__, 1.000, 0, 453},
+ {__LINE__, 0.134471, 7972.52, 7834},
+ {__LINE__, 0.203922, 28.32, 23},
+ {__LINE__, 0.737171, 48274, 48472},
+ {__LINE__, 0.444146, 583.1234, 579},
+ {__LINE__, 0.294814, 138.2, 130},
+ {__LINE__, 0.0816532, 12.63, 7},
+ {__LINE__, 0, 682.32, 67},
+ {__LINE__, 0.49405, 999, 999},
+ {__LINE__, 1.000, 0, 9999},
+ {__LINE__, 0.997477, 0.00001, 1},
+ {__LINE__, 0, 5823.21, 5040},
+ };
+ for (const auto& spec : specs) {
+ SCOPED_TRACE(spec.line);
+ const double pval = ChiSquarePValue(spec.chi_square, spec.df);
+ EXPECT_NEAR(spec.pval, pval, 1e-3);
+ }
+}
+
+TEST(ChiSquareTest, CalcChiSquare) {
+ struct {
+ int line;
+ std::vector<int> expected;
+ std::vector<int> actual;
+ } const specs[] = {
+ {__LINE__,
+ {56, 234, 76, 1, 546, 1, 87, 345, 1, 234},
+ {2, 132, 4, 43, 234, 8, 345, 8, 236, 56}},
+ {__LINE__,
+ {123, 36, 234, 367, 345, 2, 456, 567, 234, 567},
+ {123, 56, 2345, 8, 345, 8, 2345, 23, 48, 267}},
+ {__LINE__,
+ {123, 234, 345, 456, 567, 678, 789, 890, 98, 76},
+ {123, 234, 345, 456, 567, 678, 789, 890, 98, 76}},
+ {__LINE__, {3, 675, 23, 86, 2, 8, 2}, {456, 675, 23, 86, 23, 65, 2}},
+ {__LINE__, {1}, {23}},
+ };
+ for (const auto& spec : specs) {
+ SCOPED_TRACE(spec.line);
+ double chi_square = 0;
+ for (int i = 0; i < spec.expected.size(); ++i) {
+ const double diff = spec.actual[i] - spec.expected[i];
+ chi_square += (diff * diff) / spec.expected[i];
+ }
+ EXPECT_NEAR(chi_square,
+ ChiSquare(std::begin(spec.actual), std::end(spec.actual),
+ std::begin(spec.expected), std::end(spec.expected)),
+ 1e-5);
+ }
+}
+
+TEST(ChiSquareTest, CalcChiSquareInt64) {
+ const int64_t data[3] = {910293487, 910292491, 910216780};
+ // $ python -c "import scipy.stats
+ // > print scipy.stats.chisquare([910293487, 910292491, 910216780])[0]"
+ // 4.25410123524
+ double sum = std::accumulate(std::begin(data), std::end(data), double{0});
+ size_t n = std::distance(std::begin(data), std::end(data));
+ double a = ChiSquareWithExpected(std::begin(data), std::end(data), sum / n);
+ EXPECT_NEAR(4.254101, a, 1e-6);
+
+ // ... Or with known values.
+ double b =
+ ChiSquareWithExpected(std::begin(data), std::end(data), 910267586.0);
+ EXPECT_NEAR(4.254101, b, 1e-6);
+}
+
+TEST(ChiSquareTest, TableData) {
+ // Test data from
+ // http://www.itl.nist.gov/div898/handbook/eda/section3/eda3674.htm
+ // 0.90 0.95 0.975 0.99 0.999
+ const double data[100][5] = {
+ /* 1*/ {2.706, 3.841, 5.024, 6.635, 10.828},
+ /* 2*/ {4.605, 5.991, 7.378, 9.210, 13.816},
+ /* 3*/ {6.251, 7.815, 9.348, 11.345, 16.266},
+ /* 4*/ {7.779, 9.488, 11.143, 13.277, 18.467},
+ /* 5*/ {9.236, 11.070, 12.833, 15.086, 20.515},
+ /* 6*/ {10.645, 12.592, 14.449, 16.812, 22.458},
+ /* 7*/ {12.017, 14.067, 16.013, 18.475, 24.322},
+ /* 8*/ {13.362, 15.507, 17.535, 20.090, 26.125},
+ /* 9*/ {14.684, 16.919, 19.023, 21.666, 27.877},
+ /*10*/ {15.987, 18.307, 20.483, 23.209, 29.588},
+ /*11*/ {17.275, 19.675, 21.920, 24.725, 31.264},
+ /*12*/ {18.549, 21.026, 23.337, 26.217, 32.910},
+ /*13*/ {19.812, 22.362, 24.736, 27.688, 34.528},
+ /*14*/ {21.064, 23.685, 26.119, 29.141, 36.123},
+ /*15*/ {22.307, 24.996, 27.488, 30.578, 37.697},
+ /*16*/ {23.542, 26.296, 28.845, 32.000, 39.252},
+ /*17*/ {24.769, 27.587, 30.191, 33.409, 40.790},
+ /*18*/ {25.989, 28.869, 31.526, 34.805, 42.312},
+ /*19*/ {27.204, 30.144, 32.852, 36.191, 43.820},
+ /*20*/ {28.412, 31.410, 34.170, 37.566, 45.315},
+ /*21*/ {29.615, 32.671, 35.479, 38.932, 46.797},
+ /*22*/ {30.813, 33.924, 36.781, 40.289, 48.268},
+ /*23*/ {32.007, 35.172, 38.076, 41.638, 49.728},
+ /*24*/ {33.196, 36.415, 39.364, 42.980, 51.179},
+ /*25*/ {34.382, 37.652, 40.646, 44.314, 52.620},
+ /*26*/ {35.563, 38.885, 41.923, 45.642, 54.052},
+ /*27*/ {36.741, 40.113, 43.195, 46.963, 55.476},
+ /*28*/ {37.916, 41.337, 44.461, 48.278, 56.892},
+ /*29*/ {39.087, 42.557, 45.722, 49.588, 58.301},
+ /*30*/ {40.256, 43.773, 46.979, 50.892, 59.703},
+ /*31*/ {41.422, 44.985, 48.232, 52.191, 61.098},
+ /*32*/ {42.585, 46.194, 49.480, 53.486, 62.487},
+ /*33*/ {43.745, 47.400, 50.725, 54.776, 63.870},
+ /*34*/ {44.903, 48.602, 51.966, 56.061, 65.247},
+ /*35*/ {46.059, 49.802, 53.203, 57.342, 66.619},
+ /*36*/ {47.212, 50.998, 54.437, 58.619, 67.985},
+ /*37*/ {48.363, 52.192, 55.668, 59.893, 69.347},
+ /*38*/ {49.513, 53.384, 56.896, 61.162, 70.703},
+ /*39*/ {50.660, 54.572, 58.120, 62.428, 72.055},
+ /*40*/ {51.805, 55.758, 59.342, 63.691, 73.402},
+ /*41*/ {52.949, 56.942, 60.561, 64.950, 74.745},
+ /*42*/ {54.090, 58.124, 61.777, 66.206, 76.084},
+ /*43*/ {55.230, 59.304, 62.990, 67.459, 77.419},
+ /*44*/ {56.369, 60.481, 64.201, 68.710, 78.750},
+ /*45*/ {57.505, 61.656, 65.410, 69.957, 80.077},
+ /*46*/ {58.641, 62.830, 66.617, 71.201, 81.400},
+ /*47*/ {59.774, 64.001, 67.821, 72.443, 82.720},
+ /*48*/ {60.907, 65.171, 69.023, 73.683, 84.037},
+ /*49*/ {62.038, 66.339, 70.222, 74.919, 85.351},
+ /*50*/ {63.167, 67.505, 71.420, 76.154, 86.661},
+ /*51*/ {64.295, 68.669, 72.616, 77.386, 87.968},
+ /*52*/ {65.422, 69.832, 73.810, 78.616, 89.272},
+ /*53*/ {66.548, 70.993, 75.002, 79.843, 90.573},
+ /*54*/ {67.673, 72.153, 76.192, 81.069, 91.872},
+ /*55*/ {68.796, 73.311, 77.380, 82.292, 93.168},
+ /*56*/ {69.919, 74.468, 78.567, 83.513, 94.461},
+ /*57*/ {71.040, 75.624, 79.752, 84.733, 95.751},
+ /*58*/ {72.160, 76.778, 80.936, 85.950, 97.039},
+ /*59*/ {73.279, 77.931, 82.117, 87.166, 98.324},
+ /*60*/ {74.397, 79.082, 83.298, 88.379, 99.607},
+ /*61*/ {75.514, 80.232, 84.476, 89.591, 100.888},
+ /*62*/ {76.630, 81.381, 85.654, 90.802, 102.166},
+ /*63*/ {77.745, 82.529, 86.830, 92.010, 103.442},
+ /*64*/ {78.860, 83.675, 88.004, 93.217, 104.716},
+ /*65*/ {79.973, 84.821, 89.177, 94.422, 105.988},
+ /*66*/ {81.085, 85.965, 90.349, 95.626, 107.258},
+ /*67*/ {82.197, 87.108, 91.519, 96.828, 108.526},
+ /*68*/ {83.308, 88.250, 92.689, 98.028, 109.791},
+ /*69*/ {84.418, 89.391, 93.856, 99.228, 111.055},
+ /*70*/ {85.527, 90.531, 95.023, 100.425, 112.317},
+ /*71*/ {86.635, 91.670, 96.189, 101.621, 113.577},
+ /*72*/ {87.743, 92.808, 97.353, 102.816, 114.835},
+ /*73*/ {88.850, 93.945, 98.516, 104.010, 116.092},
+ /*74*/ {89.956, 95.081, 99.678, 105.202, 117.346},
+ /*75*/ {91.061, 96.217, 100.839, 106.393, 118.599},
+ /*76*/ {92.166, 97.351, 101.999, 107.583, 119.850},
+ /*77*/ {93.270, 98.484, 103.158, 108.771, 121.100},
+ /*78*/ {94.374, 99.617, 104.316, 109.958, 122.348},
+ /*79*/ {95.476, 100.749, 105.473, 111.144, 123.594},
+ /*80*/ {96.578, 101.879, 106.629, 112.329, 124.839},
+ /*81*/ {97.680, 103.010, 107.783, 113.512, 126.083},
+ /*82*/ {98.780, 104.139, 108.937, 114.695, 127.324},
+ /*83*/ {99.880, 105.267, 110.090, 115.876, 128.565},
+ /*84*/ {100.980, 106.395, 111.242, 117.057, 129.804},
+ /*85*/ {102.079, 107.522, 112.393, 118.236, 131.041},
+ /*86*/ {103.177, 108.648, 113.544, 119.414, 132.277},
+ /*87*/ {104.275, 109.773, 114.693, 120.591, 133.512},
+ /*88*/ {105.372, 110.898, 115.841, 121.767, 134.746},
+ /*89*/ {106.469, 112.022, 116.989, 122.942, 135.978},
+ /*90*/ {107.565, 113.145, 118.136, 124.116, 137.208},
+ /*91*/ {108.661, 114.268, 119.282, 125.289, 138.438},
+ /*92*/ {109.756, 115.390, 120.427, 126.462, 139.666},
+ /*93*/ {110.850, 116.511, 121.571, 127.633, 140.893},
+ /*94*/ {111.944, 117.632, 122.715, 128.803, 142.119},
+ /*95*/ {113.038, 118.752, 123.858, 129.973, 143.344},
+ /*96*/ {114.131, 119.871, 125.000, 131.141, 144.567},
+ /*97*/ {115.223, 120.990, 126.141, 132.309, 145.789},
+ /*98*/ {116.315, 122.108, 127.282, 133.476, 147.010},
+ /*99*/ {117.407, 123.225, 128.422, 134.642, 148.230},
+ /*100*/ {118.498, 124.342, 129.561, 135.807, 149.449}
+ /**/};
+
+ // 0.90 0.95 0.975 0.99 0.999
+ for (int i = 0; i < ABSL_ARRAYSIZE(data); i++) {
+ const double E = 0.0001;
+ EXPECT_NEAR(ChiSquarePValue(data[i][0], i + 1), 0.10, E)
+ << i << " " << data[i][0];
+ EXPECT_NEAR(ChiSquarePValue(data[i][1], i + 1), 0.05, E)
+ << i << " " << data[i][1];
+ EXPECT_NEAR(ChiSquarePValue(data[i][2], i + 1), 0.025, E)
+ << i << " " << data[i][2];
+ EXPECT_NEAR(ChiSquarePValue(data[i][3], i + 1), 0.01, E)
+ << i << " " << data[i][3];
+ EXPECT_NEAR(ChiSquarePValue(data[i][4], i + 1), 0.001, E)
+ << i << " " << data[i][4];
+
+ const double F = 0.1;
+ EXPECT_NEAR(ChiSquareValue(i + 1, 0.90), data[i][0], F) << i;
+ EXPECT_NEAR(ChiSquareValue(i + 1, 0.95), data[i][1], F) << i;
+ EXPECT_NEAR(ChiSquareValue(i + 1, 0.975), data[i][2], F) << i;
+ EXPECT_NEAR(ChiSquareValue(i + 1, 0.99), data[i][3], F) << i;
+ EXPECT_NEAR(ChiSquareValue(i + 1, 0.999), data[i][4], F) << i;
+ }
+}
+
+TEST(ChiSquareTest, ChiSquareTwoIterator) {
+ // Test data from http://www.stat.yale.edu/Courses/1997-98/101/chigf.htm
+ // Null-hypothesis: This data is normally distributed.
+ const int counts[10] = {6, 6, 18, 33, 38, 38, 28, 21, 9, 3};
+ const double expected[10] = {4.6, 8.8, 18.4, 30.0, 38.2,
+ 38.2, 30.0, 18.4, 8.8, 4.6};
+ double chi_square = ChiSquare(std::begin(counts), std::end(counts),
+ std::begin(expected), std::end(expected));
+ EXPECT_NEAR(chi_square, 2.69, 0.001);
+
+ // Degrees of freedom: 10 bins. two estimated parameters. = 10 - 2 - 1.
+ const int dof = 7;
+ // The critical value of 7, 95% => 14.067 (see above test)
+ double p_value_05 = ChiSquarePValue(14.067, dof);
+ EXPECT_NEAR(p_value_05, 0.05, 0.001); // 95%-ile p-value
+
+ double p_actual = ChiSquarePValue(chi_square, dof);
+ EXPECT_GT(p_actual, 0.05); // Accept the null hypothesis.
+}
+
+TEST(ChiSquareTest, DiceRolls) {
+ // Assume we are testing 102 fair dice rolls.
+ // Null-hypothesis: This data is fairly distributed.
+ //
+ // The dof value of 4, @95% = 9.488 (see above test)
+ // The dof value of 5, @95% = 11.070
+ const int rolls[6] = {22, 11, 17, 14, 20, 18};
+ double sum = std::accumulate(std::begin(rolls), std::end(rolls), double{0});
+ size_t n = std::distance(std::begin(rolls), std::end(rolls));
+
+ double a = ChiSquareWithExpected(std::begin(rolls), std::end(rolls), sum / n);
+ EXPECT_NEAR(a, 4.70588, 1e-5);
+ EXPECT_LT(a, ChiSquareValue(4, 0.95));
+
+ double p_a = ChiSquarePValue(a, 4);
+ EXPECT_NEAR(p_a, 0.318828, 1e-5); // Accept the null hypothesis.
+
+ double b = ChiSquareWithExpected(std::begin(rolls), std::end(rolls), 17.0);
+ EXPECT_NEAR(b, 4.70588, 1e-5);
+ EXPECT_LT(b, ChiSquareValue(5, 0.95));
+
+ double p_b = ChiSquarePValue(b, 5);
+ EXPECT_NEAR(p_b, 0.4528180, 1e-5); // Accept the null hypothesis.
+}
+
+} // namespace