From 294eab8c10d448016ed91b705f28b0ec2bcac607 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Fri, 18 Mar 2011 11:48:29 +0000 Subject: [PATCH] testsuite_random.h: New. 2011-03-18 Paolo Carlini * testsuite/util/testsuite_random.h: New. * testsuite/lib/libstdc++.exp (check_v3_target_c99_math, dg-require-c99_math): Add. * testsuite/26_numerics/random/bernoulli_distribution/ operators/values.cc: New. * testsuite/26_numerics/random/binomial_distribution/ operators/values.cc: Likewise. * testsuite/26_numerics/random/geometric_distribution/ operators/values.cc: Likewise. From-SVN: r171133 --- libstdc++-v3/ChangeLog | 12 ++ .../operators/values.cc | 50 +++++++ .../binomial_distribution/operators/values.cc | 52 ++++++++ .../operators/values.cc | 51 +++++++ libstdc++-v3/testsuite/lib/dg-options.exp | 11 +- libstdc++-v3/testsuite/lib/libstdc++.exp | 65 ++++++++- .../testsuite/util/testsuite_random.h | 124 ++++++++++++++++++ 7 files changed, 361 insertions(+), 4 deletions(-) create mode 100644 libstdc++-v3/testsuite/26_numerics/random/bernoulli_distribution/operators/values.cc create mode 100644 libstdc++-v3/testsuite/26_numerics/random/binomial_distribution/operators/values.cc create mode 100644 libstdc++-v3/testsuite/26_numerics/random/geometric_distribution/operators/values.cc create mode 100644 libstdc++-v3/testsuite/util/testsuite_random.h diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index c63cf2f9157..e476058c1a5 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,15 @@ +2011-03-18 Paolo Carlini + + * testsuite/util/testsuite_random.h: New. + * testsuite/lib/libstdc++.exp (check_v3_target_c99_math, + dg-require-c99_math): Add. + * testsuite/26_numerics/random/bernoulli_distribution/ + operators/values.cc: New. + * testsuite/26_numerics/random/binomial_distribution/ + operators/values.cc: Likewise. + * testsuite/26_numerics/random/geometric_distribution/ + operators/values.cc: Likewise. + 2011-03-16 Benjamin Kosnik * config/abi/pre/gnu.ver: Add base destructors for stdexcept classes. diff --git a/libstdc++-v3/testsuite/26_numerics/random/bernoulli_distribution/operators/values.cc b/libstdc++-v3/testsuite/26_numerics/random/bernoulli_distribution/operators/values.cc new file mode 100644 index 00000000000..513b5a6bdef --- /dev/null +++ b/libstdc++-v3/testsuite/26_numerics/random/bernoulli_distribution/operators/values.cc @@ -0,0 +1,50 @@ +// { dg-options "-std=gnu++0x" } +// { dg-require-cstdint "" } +// +// Copyright (C) 2011 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// 26.5.8.2.1 Class template bernoulli_distribution [rand.dist.bern.bernoulli] + +#include +#include +#include + +void test01() +{ + using namespace __gnu_test; + + std::mt19937 eng; + + std::bernoulli_distribution bd1(0.25); + auto bbd1 = std::bind(bd1, eng); + testDiscreteDist(bbd1, [](int n) { return bernoulli_pdf(n, 0.25); } ); + + std::bernoulli_distribution bd2(0.5); + auto bbd2 = std::bind(bd2, eng); + testDiscreteDist(bbd2, [](int n) { return bernoulli_pdf(n, 0.5); } ); + + std::bernoulli_distribution bd3(0.75); + auto bbd3 = std::bind(bd3, eng); + testDiscreteDist(bbd3, [](int n) { return bernoulli_pdf(n, 0.75); } ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/26_numerics/random/binomial_distribution/operators/values.cc b/libstdc++-v3/testsuite/26_numerics/random/binomial_distribution/operators/values.cc new file mode 100644 index 00000000000..f1f956575a9 --- /dev/null +++ b/libstdc++-v3/testsuite/26_numerics/random/binomial_distribution/operators/values.cc @@ -0,0 +1,52 @@ +// { dg-options "-std=gnu++0x" } +// { dg-require-cstdint "" } +// { dg-require-c99_math "" } +// +// Copyright (C) 2011 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// 26.5.8.2.2 Class template binomial_distribution [rand.dist.bern.bin] + +#include +#include +#include + +void test01() +{ + using namespace __gnu_test; + + std::mt19937 eng; + + std::binomial_distribution<> bd1(5, 0.3); + auto bbd1 = std::bind(bd1, eng); + testDiscreteDist(bbd1, [](int n) { return binomial_pdf(n, 0.3, 5); } ); + + std::binomial_distribution<> bd2(55, 0.3); + auto bbd2 = std::bind(bd2, eng); + testDiscreteDist(bbd2, [](int n) { return binomial_pdf(n, 0.3, 55); } ); + + // libstdc++/48114 + std::binomial_distribution<> bd3(10, 0.75); + auto bbd3 = std::bind(bd3, eng); + testDiscreteDist(bbd3, [](int n) { return binomial_pdf(n, 0.75, 10); } ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/26_numerics/random/geometric_distribution/operators/values.cc b/libstdc++-v3/testsuite/26_numerics/random/geometric_distribution/operators/values.cc new file mode 100644 index 00000000000..f6eaaf6bd19 --- /dev/null +++ b/libstdc++-v3/testsuite/26_numerics/random/geometric_distribution/operators/values.cc @@ -0,0 +1,51 @@ +// { dg-options "-std=gnu++0x" } +// { dg-require-cstdint "" } +// +// Copyright (C) 2011 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// 26.5.8.2.3 Class template geometric_distribution [rand.dist.bern.geom] + +#include +#include +#include + +void test01() +{ + using namespace __gnu_test; + + std::mt19937 eng; + + std::geometric_distribution<> gd1(0.5); + auto bgd1 = std::bind(gd1, eng); + testDiscreteDist(bgd1, [](int n) { return geometric_pdf(n, 0.5); } ); + + std::geometric_distribution<> gd2(0.75); + auto bgd2 = std::bind(gd2, eng); + testDiscreteDist(bgd2, [](int n) { return geometric_pdf(n, 0.75); } ); + + // libstdc++/48114 + std::geometric_distribution<> gd3(0.25); + auto bgd3 = std::bind(gd3, eng); + testDiscreteDist(bgd3, [](int n) { return geometric_pdf(n, 0.25); } ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/lib/dg-options.exp b/libstdc++-v3/testsuite/lib/dg-options.exp index b75f516c41f..34f81e85978 100644 --- a/libstdc++-v3/testsuite/lib/dg-options.exp +++ b/libstdc++-v3/testsuite/lib/dg-options.exp @@ -1,6 +1,6 @@ # Handlers for additional dg-xxx keywords in tests. -# Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 +# Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 # Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify @@ -107,6 +107,15 @@ proc dg-require-cstdint { args } { return } +proc dg-require-c99_math { args } { + if { ![ check_v3_target_c99_math ] } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + return + } + return +} + proc dg-require-atomic-builtins { args } { if { ![ check_v3_target_atomic_builtins ] } { upvar dg-do-what dg-do-what diff --git a/libstdc++-v3/testsuite/lib/libstdc++.exp b/libstdc++-v3/testsuite/lib/libstdc++.exp index 2b96e29048d..ac67ebbb51f 100644 --- a/libstdc++-v3/testsuite/lib/libstdc++.exp +++ b/libstdc++-v3/testsuite/lib/libstdc++.exp @@ -1,6 +1,7 @@ # libstdc++ "tool init file" for DejaGNU -# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 +# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +# 2009, 2010, 2011 # Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify @@ -1145,12 +1146,70 @@ proc check_v3_target_cstdint { } { return $et_cstdint } +proc check_v3_target_c99_math { } { + global cxxflags + global DEFAULT_CXXFLAGS + global et_c99_math + + global tool + + if { ![info exists et_c99_math_target_name] } { + set et_c99_math_target_name "" + } + + # If the target has changed since we set the cached value, clear it. + set current_target [current_target_name] + if { $current_target != $et_c99_math_target_name } { + verbose "check_v3_target_c99_math: `$et_c99_math_target_name'" 2 + set et_c99_math_target_name $current_target + if [info exists et_c99_math] { + verbose "check_v3_target_c99_math: removing cached result" 2 + unset et_c99_math + } + } + + if [info exists et_c99_math] { + verbose "check_v3_target_c99_math: using cached result" 2 + } else { + set et_c99_math 0 + + # Set up and compile a C++0x test program that depends + # on the C99 math facilities to be available. + set src c99_math[pid].cc + set exe c99_math[pid].exe + + set f [open $src "w"] + puts $f "#include " + puts $f "int main()" + puts $f "#ifdef _GLIBCXX_USE_C99_MATH_TR1" + puts $f "{ return 0; }" + puts $f "#endif" + close $f + + set cxxflags_saved $cxxflags + set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -Werror" + + set lines [v3_target_compile $src $exe executable ""] + set cxxflags $cxxflags_saved + file delete $src + + if [string match "" $lines] { + # No error message, compilation succeeded. + set et_c99_math 1 + } else { + verbose "check_v3_target_c99_math: compilation failed" 2 + } + } + verbose "check_v3_target_c99_math: $et_c99_math" 2 + return $et_c99_math +} + proc check_v3_target_atomic_builtins { } { global cxxflags global DEFAULT_CXXFLAGS - global et_cstdint + global et_atomic_builtins - global tool + global tool if { ![info exists et_atomic_builtins_target_name] } { set et_atomic_builtins_target_name "" diff --git a/libstdc++-v3/testsuite/util/testsuite_random.h b/libstdc++-v3/testsuite/util/testsuite_random.h new file mode 100644 index 00000000000..417a95a8c6c --- /dev/null +++ b/libstdc++-v3/testsuite/util/testsuite_random.h @@ -0,0 +1,124 @@ +// -*- C++ -*- + +// Copyright (C) 2011 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 3, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +/** + * @file testsuite_random.h + */ + +#ifndef _GLIBCXX_TESTSUITE_RANDOM_H +#define _GLIBCXX_TESTSUITE_RANDOM_H + +#include +#include + +namespace __gnu_test +{ + // Adapted for libstdc++ from GNU gsl-1.14/randist/test.c + // Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007, 2010 + // James Theiler, Brian Gough + template + void + testDiscreteDist(Distribution& f, Pdf pdf) + { + bool test __attribute__((unused)) = true; + double count[BINS], p[BINS]; + + for (unsigned long i = 0; i < BINS; i++) + count[i] = 0; + + for (unsigned long i = 0; i < N; i++) + { + auto r = f(); + if (r >= 0 && r < BINS) + count[r]++; + } + + for (unsigned long i = 0; i < BINS; i++) + p[i] = pdf(i); + + for (unsigned long i = 0; i < BINS; i++) + { + bool status_i; + double d = std::abs(count[i] - N * p[i]); + + if (p[i] != 0) + { + double s = d / std::sqrt(N * p[i]); + status_i = (s > 5) && (d > 1); + } + else + status_i = (count[i] != 0); + + VERIFY( !status_i ); + } + } + + inline double + bernoulli_pdf(int k, double p) + { + if (k == 0) + return 1 - p; + else if (k == 1) + return p; + else + return 0; + } + +#ifdef _GLIBCXX_USE_C99_MATH_TR1 + inline double + binomial_pdf(int k, double p, int n) + { + if (k < 0 || k > n) + return 0; + else + { + double q; + + if (p == 0) + q = (k == 0) ? 1 : 0; + else if (p == 1) + q = (k == n) ? 1 : 0; + else + { + double ln_Cnk = (std::lgamma(n + 1) - std::lgamma(k + 1) + - std::lgamma(n - k + 1)); + q = ln_Cnk + k * std::log(p) + (n - k) * std::log1p(-p); + q = std::exp(q); + } + + return q; + } + } +#endif + + inline double + geometric_pdf(int k, double p) + { + if (k < 0) + return 0; + else if (k == 0) + return p; + else + return p * std::pow(1 - p, k); + } +} // namespace __gnu_test + +#endif // #ifndef _GLIBCXX_TESTSUITE_RANDOM_H -- 2.30.2