From 72e911e5ddc3b9000dbeb6b2a0dec674c4347852 Mon Sep 17 00:00:00 2001 From: Keith O'Hara Date: Sun, 23 Apr 2023 13:10:20 -0400 Subject: [PATCH] version 3.4.0 - add Rademacher distribution - minor fix to rlogis header --- README.md | 1 + docs/Doxyfile | 4 + docs/source/api/dist_index.rst | 15 ++ docs/source/api/rademacher.rst | 205 ++++++++++++++++++ include/stats_incl/dens/dens.hpp | 1 + include/stats_incl/dens/dradem.hpp | 170 +++++++++++++++ include/stats_incl/dens/dradem.ipp | 133 ++++++++++++ .../stats_incl/misc/sanity_checks/radem.hpp | 49 +++++ .../misc/sanity_checks/sanity_checks.hpp | 1 + include/stats_incl/misc/statslib_options.hpp | 4 +- include/stats_incl/prob/pradem.hpp | 170 +++++++++++++++ include/stats_incl/prob/pradem.ipp | 133 ++++++++++++ include/stats_incl/prob/prob.hpp | 1 + include/stats_incl/quant/qbern.hpp | 2 +- include/stats_incl/quant/qbern.ipp | 2 +- include/stats_incl/quant/qradem.hpp | 164 ++++++++++++++ include/stats_incl/quant/qradem.ipp | 133 ++++++++++++ include/stats_incl/quant/quant.hpp | 1 + include/stats_incl/rand/rand.hpp | 1 + include/stats_incl/rand/rlogis.hpp | 2 +- include/stats_incl/rand/rradem.hpp | 143 ++++++++++++ include/stats_incl/rand/rradem.ipp | 104 +++++++++ tests/dens/dradem.cpp | 89 ++++++++ tests/prob/pradem.cpp | 90 ++++++++ tests/quant/qradem.cpp | 90 ++++++++ tests/rand/rradem.cpp | 84 +++++++ 26 files changed, 1787 insertions(+), 5 deletions(-) create mode 100644 docs/source/api/rademacher.rst create mode 100644 include/stats_incl/dens/dradem.hpp create mode 100644 include/stats_incl/dens/dradem.ipp create mode 100644 include/stats_incl/misc/sanity_checks/radem.hpp create mode 100644 include/stats_incl/prob/pradem.hpp create mode 100644 include/stats_incl/prob/pradem.ipp create mode 100644 include/stats_incl/quant/qradem.hpp create mode 100644 include/stats_incl/quant/qradem.ipp create mode 100644 include/stats_incl/rand/rradem.hpp create mode 100644 include/stats_incl/rand/rradem.ipp create mode 100644 tests/dens/dradem.cpp create mode 100644 tests/prob/pradem.cpp create mode 100644 tests/quant/qradem.cpp create mode 100644 tests/rand/rradem.cpp diff --git a/README.md b/README.md index 571963c..e11eb52 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ Functions to compute the cdf, pdf, quantile, as well as random sampling methods, * Log-Normal * Normal (Gaussian) * Poisson +* Rademacher * Student's t * Uniform * Weibull diff --git a/docs/Doxyfile b/docs/Doxyfile index b028fc4..9227642 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -17,6 +17,7 @@ INPUT = ../include/stats_incl/dens/dbern.hpp \ ../include/stats_incl/dens/dmvnorm.hpp \ ../include/stats_incl/dens/dnorm.hpp \ ../include/stats_incl/dens/dpois.hpp \ + ../include/stats_incl/dens/dradem.hpp \ ../include/stats_incl/dens/dt.hpp \ ../include/stats_incl/dens/dunif.hpp \ ../include/stats_incl/dens/dweibull.hpp \ @@ -36,6 +37,7 @@ INPUT = ../include/stats_incl/dens/dbern.hpp \ ../include/stats_incl/prob/plogis.hpp \ ../include/stats_incl/prob/pnorm.hpp \ ../include/stats_incl/prob/ppois.hpp \ + ../include/stats_incl/prob/pradem.hpp \ ../include/stats_incl/prob/pt.hpp \ ../include/stats_incl/prob/punif.hpp \ ../include/stats_incl/prob/pweibull.hpp \ @@ -54,6 +56,7 @@ INPUT = ../include/stats_incl/dens/dbern.hpp \ ../include/stats_incl/quant/qlogis.hpp \ ../include/stats_incl/quant/qnorm.hpp \ ../include/stats_incl/quant/qpois.hpp \ + ../include/stats_incl/quant/qradem.hpp \ ../include/stats_incl/quant/qt.hpp \ ../include/stats_incl/quant/qunif.hpp \ ../include/stats_incl/quant/qweibull.hpp \ @@ -74,6 +77,7 @@ INPUT = ../include/stats_incl/dens/dbern.hpp \ ../include/stats_incl/rand/rmvnorm.hpp \ ../include/stats_incl/rand/rnorm.hpp \ ../include/stats_incl/rand/rpois.hpp \ + ../include/stats_incl/rand/rradem.hpp \ ../include/stats_incl/rand/rt.hpp \ ../include/stats_incl/rand/runif.hpp \ ../include/stats_incl/rand/rweibull.hpp \ diff --git a/docs/source/api/dist_index.rst b/docs/source/api/dist_index.rst index 81a0a84..5569e22 100644 --- a/docs/source/api/dist_index.rst +++ b/docs/source/api/dist_index.rst @@ -276,6 +276,21 @@ Distributions | :ref:`rpois ` | random sampling function of the Poisson distribution | +----------------------------------------+--------------------------------------------------------------+ +.. toctree:: + :maxdepth: 2 + + rademacher + ++----------------------------------------+--------------------------------------------------------------+ +| :ref:`dradem ` | density function of the Rademacher distribution | ++----------------------------------------+--------------------------------------------------------------+ +| :ref:`pradem ` | distribution function of the Rademacher distribution | ++----------------------------------------+--------------------------------------------------------------+ +| :ref:`qradem ` | quantile function of the Rademacher distribution | ++----------------------------------------+--------------------------------------------------------------+ +| :ref:`rradem ` | random sampling function of the Rademacher distribution | ++----------------------------------------+--------------------------------------------------------------+ + .. toctree:: :maxdepth: 2 diff --git a/docs/source/api/rademacher.rst b/docs/source/api/rademacher.rst new file mode 100644 index 0000000..65419a8 --- /dev/null +++ b/docs/source/api/rademacher.rst @@ -0,0 +1,205 @@ +.. Copyright (c) 2011-2023 Keith O'Hara + + Distributed under the terms of the Apache License, Version 2.0. + + The full license is in the file LICENSE, distributed with this software. + +Rademacher Distribution +======================= + +**Table of contents** + +.. contents:: :local: + +---- + +Density Function +---------------- + +The density function of the Rademacher distribution: + +.. math:: + + f(x; p) = p \times \mathbf{1}[x = 1] + (1-p) \times \mathbf{1}[x = -1] + +Note that this is a somewhat more general definition of the Rademacher distribution than is standard in the statistics literature, +which assumes :math:`p = 0.5`. + +Methods for scalar input, as well as for vector/matrix input, are listed below. + +Scalar Input +~~~~~~~~~~~~ + +.. _dradem-func-ref1: +.. doxygenfunction:: dradem(const llint_t x, const T prob_par, const bool log_form) + :project: statslib + +Vector/Matrix Input +~~~~~~~~~~~~~~~~~~~ + +STL Containers +______________ + +.. _dradem-func-ref2: +.. doxygenfunction:: dradem(const std::vector& x, const T1 prob_par, const bool log_form) + :project: statslib + +Armadillo +_________ + +.. _dradem-func-ref3: +.. doxygenfunction:: dradem(const ArmaGen& X, const T1 prob_par, const bool log_form) + :project: statslib + +Blaze +_____ + +.. _dradem-func-ref4: +.. doxygenfunction:: dradem(const BlazeMat& X, const T1 prob_par, const bool log_form) + :project: statslib + +Eigen +_____ + +.. _dradem-func-ref5: +.. doxygenfunction:: dradem(const EigenMat& X, const T1 prob_par, const bool log_form) + :project: statslib + +---- + +Cumulative Distribution Function +-------------------------------- + +The cumulative distribution function of the Rademacher distribution: + +.. math:: + + F(x; p) = \sum_{z \leq x} f(z; p) = \begin{cases} 0 & \text{ if } x < -1 \\ 1-p & \text{ if } x < 1 \\ 1 & \text{ if } x \geq 1 \end{cases} + +Methods for scalar input, as well as for vector/matrix input, are listed below. + +Scalar Input +~~~~~~~~~~~~ + +.. _pradem-func-ref1: +.. doxygenfunction:: pradem(const llint_t, const T, const bool) + :project: statslib + +Vector/Matrix Input +~~~~~~~~~~~~~~~~~~~ + +STL Containers +______________ + +.. _pradem-func-ref2: +.. doxygenfunction:: pradem(const std::vector&, const T1, const bool) + :project: statslib + +Armadillo +_________ + +.. _pradem-func-ref3: +.. doxygenfunction:: pradem(const ArmaMat&, const T1, const bool) + :project: statslib + +Blaze +_____ + +.. _pradem-func-ref4: +.. doxygenfunction:: pradem(const BlazeMat&, const T1, const bool) + :project: statslib + +Eigen +_____ + +.. _pradem-func-ref5: +.. doxygenfunction:: pradem(const EigenMat&, const T1, const bool) + :project: statslib + +---- + +Quantile Function +----------------- + +The quantile function of the Rademacher distribution: + +.. math:: + + q(r; p) = \begin{cases} -1 & \text{ if } r \leq 1 - p \\ 1 & \text{ else } \end{cases} + +Methods for scalar input, as well as for vector/matrix input, are listed below. + +Scalar Input +~~~~~~~~~~~~ + +.. _qradem-func-ref1: +.. doxygenfunction:: qradem(const T1, const T2) + :project: statslib + +Vector/Matrix Input +~~~~~~~~~~~~~~~~~~~ + +STL Containers +______________ + +.. _qradem-func-ref2: +.. doxygenfunction:: qradem(const std::vector&, const T1) + :project: statslib + +Armadillo +_________ + +.. _qradem-func-ref3: +.. doxygenfunction:: qradem(const ArmaMat&, const T1) + :project: statslib + +Blaze +_____ + +.. _qradem-func-ref4: +.. doxygenfunction:: qradem(const BlazeMat&, const T1) + :project: statslib + +Eigen +_____ + +.. _qradem-func-ref5: +.. doxygenfunction:: qradem(const EigenMat&, const T1) + :project: statslib + +---- + +Random Sampling +--------------- + +Random sampling for the Rademacher distribution is achieved via the inverse probability integral transform. + +Scalar Output +~~~~~~~~~~~~~ + +1. Random number engines + +.. _rradem-func-ref1: +.. doxygenfunction:: rradem(const T, rand_engine_t&) + :project: statslib + +2. Seed values + +.. _rradem-func-ref2: +.. doxygenfunction:: rradem(const T, const ullint_t) + :project: statslib + +Vector/Matrix Output +~~~~~~~~~~~~~~~~~~~~ + +1. Random number engines + +.. _rradem-func-ref3: +.. doxygenfunction:: rradem(const ullint_t, const ullint_t, const T1, rand_engine_t&) + :project: statslib + +2. Seed values + +.. _rradem-func-ref4: +.. doxygenfunction:: rradem(const ullint_t, const ullint_t, const T1, const ullint_t) + :project: statslib diff --git a/include/stats_incl/dens/dens.hpp b/include/stats_incl/dens/dens.hpp index becf841..2d271eb 100644 --- a/include/stats_incl/dens/dens.hpp +++ b/include/stats_incl/dens/dens.hpp @@ -35,6 +35,7 @@ #include "dmvnorm.hpp" #include "dnorm.hpp" #include "dpois.hpp" +#include "dradem.hpp" #include "dt.hpp" #include "dunif.hpp" #include "dweibull.hpp" diff --git a/include/stats_incl/dens/dradem.hpp b/include/stats_incl/dens/dradem.hpp new file mode 100644 index 0000000..4b0b00d --- /dev/null +++ b/include/stats_incl/dens/dradem.hpp @@ -0,0 +1,170 @@ +/*################################################################################ + ## + ## Copyright (C) 2011-2023 Keith O'Hara + ## + ## This file is part of the StatsLib C++ library. + ## + ## 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 + ## + ## http://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. + ## + ################################################################################*/ + +/* + * pdf of the Rademacher distribution + */ + +#ifndef _statslib_dradem_HPP +#define _statslib_dradem_HPP + +// +// scalar input + +/** + * @brief Density function of the Rademacher distribution + * + * @param x an integral-valued input, equal to -1 or 1. + * @param prob_par the probability parameter, a real-valued input. + * @param log_form return the log-density or the true form. + * + * @return the density function evaluated at \c x. + * + * Example: + * \code{.cpp} stats::dradem(1,0.6,false); \endcode + */ + +template +statslib_constexpr +return_t +dradem(const llint_t x, const T prob_par, const bool log_form = false) noexcept; + +// +// vector/matrix input + +/** + * @brief Density function of the Rademacher distribution + * + * @param x a standard vector. + * @param prob_par the probability parameter, a real-valued input. + * @param log_form return the log-density or the true form. + * + * @return a vector of density function values corresponding to the elements of \c x. + * + * Example: + * \code{.cpp} + * std::vector x = {-1, 1, 0}; + * stats::dradem(x,0.5,false); + * \endcode + */ + +#ifdef STATS_ENABLE_STDVEC_WRAPPERS +template> +statslib_inline +std::vector +dradem(const std::vector& x, const T1 prob_par, const bool log_form = false); +#endif + +/** + * @brief Density function of the Rademacher distribution + * + * @param X a matrix of input values. + * @param prob_par the probability parameter, a real-valued input. + * @param log_form return the log-density or the true form. + * + * @return a matrix of density function values corresponding to the elements of \c X. + * + * Example: + * \code{.cpp} + * arma::mat X = { {-1, 0, 1}, + * {-1, 1, -1} }; + * stats::dradem(X,0.5,false); + * \endcode + */ + +#ifdef STATS_ENABLE_ARMA_WRAPPERS +template> +statslib_inline +ArmaMat +dradem(const ArmaMat& X, const T1 prob_par, const bool log_form = false); + +/** + * @brief Density function of the Rademacher distribution + * + * @param X a matrix of input values. + * @param prob_par the probability parameter, a real-valued input. + * @param log_form return the log-density or the true form. + * + * @return a matrix of density function values corresponding to the elements of \c X. + * + * Example: + * \code{.cpp} + * arma::mat X = { {-1, 0, 1}, + * {-1, 1, -1} }; + * stats::dradem(X,0.5,false); + * \endcode + */ + +template +statslib_inline +mT +dradem(const ArmaGen& X, const T1 prob_par, const bool log_form = false); +#endif + +/** + * @brief Density function of the Rademacher distribution + * + * @param X a matrix of input values. + * @param prob_par the probability parameter, a real-valued input. + * @param log_form return the log-density or the true form. + * + * @return a matrix of density function values corresponding to the elements of \c X. + * + * Example: + * \code{.cpp} + * stats::dradem(X,0.5,false); + * \endcode + */ + +#ifdef STATS_ENABLE_BLAZE_WRAPPERS +template, bool To = blaze::columnMajor> +statslib_inline +BlazeMat +dradem(const BlazeMat& X, const T1 prob_par, const bool log_form = false); +#endif + +/** + * @brief Density function of the Rademacher distribution + * + * @param X a matrix of input values. + * @param prob_par the probability parameter, a real-valued input. + * @param log_form return the log-density or the true form. + * + * @return a matrix of density function values corresponding to the elements of \c X. + * + * Example: + * \code{.cpp} + * stats::dradem(X,0.5,false); + * \endcode + */ + +#ifdef STATS_ENABLE_EIGEN_WRAPPERS +template, int iTr = Eigen::Dynamic, int iTc = Eigen::Dynamic> +statslib_inline +EigenMat +dradem(const EigenMat& X, const T1 prob_par, const bool log_form = false); +#endif + +// +// include implementation files + +#include "dradem.ipp" + +#endif diff --git a/include/stats_incl/dens/dradem.ipp b/include/stats_incl/dens/dradem.ipp new file mode 100644 index 0000000..8029d31 --- /dev/null +++ b/include/stats_incl/dens/dradem.ipp @@ -0,0 +1,133 @@ +/*################################################################################ + ## + ## Copyright (C) 2011-2023 Keith O'Hara + ## + ## This file is part of the StatsLib C++ library. + ## + ## 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 + ## + ## http://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. + ## + ################################################################################*/ + +/* + * pdf of the Rademacher distribution + */ + +// +// scalar input + +namespace internal +{ + +template +statslib_constexpr +T +dradem_compute(const llint_t x, const T prob_par) +noexcept +{ + return( x == llint_t(1) ? \ + prob_par : + x == llint_t(-1) ? \ + T(1) - prob_par : + // + T(0) ); +} + +template +statslib_constexpr +T +dradem_vals_check(const llint_t x, const T prob_par, const bool log_form) +noexcept +{ + return( !radem_sanity_check(prob_par) ? \ + STLIM::quiet_NaN() : + // + log_if(dradem_compute(x,prob_par), log_form) ); +} + +} + +template +statslib_constexpr +return_t +dradem(const llint_t x, const T prob_par, const bool log_form) +noexcept +{ + return internal::dradem_vals_check(x,static_cast>(prob_par),log_form); +} + +// +// vector/matrix input + +namespace internal +{ + +#ifdef STATS_ENABLE_INTERNAL_VEC_FEATURES +template +statslib_inline +void +dradem_vec(const eT* __stats_pointer_settings__ vals_in, const T1 prob_par, const bool log_form, + rT* __stats_pointer_settings__ vals_out, const ullint_t num_elem) +{ + EVAL_DIST_FN_VEC(dradem,vals_in,vals_out,num_elem,prob_par,log_form); +} +#endif + +} + +#ifdef STATS_ENABLE_STDVEC_WRAPPERS +template +statslib_inline +std::vector +dradem(const std::vector& x, const T1 prob_par, const bool log_form) +{ + STDVEC_DIST_FN(dradem_vec,prob_par,log_form); +} +#endif + +#ifdef STATS_ENABLE_ARMA_WRAPPERS +template +statslib_inline +ArmaMat +dradem(const ArmaMat& X, const T1 prob_par, const bool log_form) +{ + ARMA_DIST_FN(dradem_vec,prob_par,log_form); +} + +template +statslib_inline +mT +dradem(const ArmaGen& X, const T1 prob_par, const bool log_form) +{ + return dradem(X.eval(),prob_par,log_form); +} +#endif + +#ifdef STATS_ENABLE_BLAZE_WRAPPERS +template +statslib_inline +BlazeMat +dradem(const BlazeMat& X, const T1 prob_par, const bool log_form) +{ + BLAZE_DIST_FN(dradem,prob_par,log_form); +} +#endif + +#ifdef STATS_ENABLE_EIGEN_WRAPPERS +template +statslib_inline +EigenMat +dradem(const EigenMat& X, const T1 prob_par, const bool log_form) +{ + EIGEN_DIST_FN(dradem_vec,prob_par,log_form); +} +#endif diff --git a/include/stats_incl/misc/sanity_checks/radem.hpp b/include/stats_incl/misc/sanity_checks/radem.hpp new file mode 100644 index 0000000..7bffa75 --- /dev/null +++ b/include/stats_incl/misc/sanity_checks/radem.hpp @@ -0,0 +1,49 @@ +/*################################################################################ + ## + ## Copyright (C) 2011-2023 Keith O'Hara + ## + ## This file is part of the StatsLib C++ library. + ## + ## 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 + ## + ## http://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. + ## + ################################################################################*/ + +/* + * Sanity checks for the Rademacher distribution + */ + +namespace internal +{ + +template +statslib_constexpr +bool +radem_sanity_check(const T prob_par) +noexcept +{ + return( GCINT::is_nan(prob_par) ? \ + false : + // + GCINT::is_inf(prob_par) ? \ + false : + // + prob_par < T(0) ? \ + false : + // + prob_par > T(1) ? \ + false : + // + true ); +} + +} diff --git a/include/stats_incl/misc/sanity_checks/sanity_checks.hpp b/include/stats_incl/misc/sanity_checks/sanity_checks.hpp index 2d434f7..614888e 100644 --- a/include/stats_incl/misc/sanity_checks/sanity_checks.hpp +++ b/include/stats_incl/misc/sanity_checks/sanity_checks.hpp @@ -40,6 +40,7 @@ // #include "mvnorm.hpp" #include "norm.hpp" #include "pois.hpp" +#include "radem.hpp" #include "t.hpp" #include "unif.hpp" #include "weibull.hpp" diff --git a/include/stats_incl/misc/statslib_options.hpp b/include/stats_incl/misc/statslib_options.hpp index f165de5..22ddb24 100644 --- a/include/stats_incl/misc/statslib_options.hpp +++ b/include/stats_incl/misc/statslib_options.hpp @@ -31,11 +31,11 @@ #endif #ifndef STATS_VERSION_MINOR - #define STATS_VERSION_MINOR 3 + #define STATS_VERSION_MINOR 4 #endif #ifndef STATS_VERSION_PATCH - #define STATS_VERSION_PATCH 1 + #define STATS_VERSION_PATCH 0 #endif // switch between inline mode and constexpr mode diff --git a/include/stats_incl/prob/pradem.hpp b/include/stats_incl/prob/pradem.hpp new file mode 100644 index 0000000..028e710 --- /dev/null +++ b/include/stats_incl/prob/pradem.hpp @@ -0,0 +1,170 @@ +/*################################################################################ + ## + ## Copyright (C) 2011-2023 Keith O'Hara + ## + ## This file is part of the StatsLib C++ library. + ## + ## 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 + ## + ## http://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. + ## + ################################################################################*/ + +/* + * cdf of the Rademacher distribution + */ + +#ifndef _statslib_pradem_HPP +#define _statslib_pradem_HPP + +// +// scalar input + +/** + * @brief Distribution function of the Rademacher distribution + * + * @param x a value equal to 0 or 1. + * @param prob_par the probability parameter, a real-valued input. + * @param log_form return the log-probability or the true form. + * + * @return the cumulative distribution function evaluated at \c x. + * + * Example: + * \code{.cpp} stats::pradem(1,0.6,false); \endcode + */ + +template +statslib_constexpr +return_t +pradem(const llint_t x, const T prob_par, const bool log_form = false) noexcept; + +// +// vector/matrix input + +/** + * @brief Density function of the Rademacher distribution + * + * @param x a standard vector. + * @param prob_par the probability parameter, a real-valued input. + * @param log_form return the log-probability or the true form. + * + * @return a vector of CDF values corresponding to the elements of \c x. + * + * Example: + * \code{.cpp} + * std::vector x = {0, 1, 0}; + * stats::pradem(x,0.5,false); + * \endcode + */ + +#ifdef STATS_ENABLE_STDVEC_WRAPPERS +template> +statslib_inline +std::vector +pradem(const std::vector& x, const T1 prob_par, const bool log_form = false); +#endif + +/** + * @brief Density function of the Rademacher distribution + * + * @param X a matrix of input values. + * @param prob_par the probability parameter, a real-valued input. + * @param log_form return the log-probability or the true form. + * + * @return a matrix of CDF values corresponding to the elements of \c X. + * + * Example: + * \code{.cpp} + * arma::mat X = { {1, 0, 1}, + * {0, 1, 0} }; + * stats::pradem(X,0.5,false); + * \endcode + */ + +#ifdef STATS_ENABLE_ARMA_WRAPPERS +template> +statslib_inline +ArmaMat +pradem(const ArmaMat& X, const T1 prob_par, const bool log_form = false); + +/** + * @brief Density function of the Rademacher distribution + * + * @param X a matrix of input values. + * @param prob_par the probability parameter, a real-valued input. + * @param log_form return the log-probability or the true form. + * + * @return a matrix of CDF values corresponding to the elements of \c X. + * + * Example: + * \code{.cpp} + * arma::mat X = { {1, 0, 1}, + * {0, 1, 0} }; + * stats::pradem(X,0.5,false); + * \endcode + */ + +template +statslib_inline +mT +pradem(const ArmaGen& X, const T1 prob_par, const bool log_form = false); +#endif + +/** + * @brief Density function of the Rademacher distribution + * + * @param X a matrix of input values. + * @param prob_par the probability parameter, a real-valued input. + * @param log_form return the log-probability or the true form. + * + * @return a matrix of CDF values corresponding to the elements of \c X. + * + * Example: + * \code{.cpp} + * stats::pradem(X,0.5,false); + * \endcode + */ + +#ifdef STATS_ENABLE_BLAZE_WRAPPERS +template, bool To = blaze::columnMajor> +statslib_inline +BlazeMat +pradem(const BlazeMat& X, const T1 prob_par, const bool log_form = false); +#endif + +/** + * @brief Density function of the Rademacher distribution + * + * @param X a matrix of input values. + * @param prob_par the probability parameter, a real-valued input. + * @param log_form return the log-probability or the true form. + * + * @return a matrix of CDF values corresponding to the elements of \c X. + * + * Example: + * \code{.cpp} + * stats::pradem(X,0.5,false); + * \endcode + */ + +#ifdef STATS_ENABLE_EIGEN_WRAPPERS +template, int iTr = Eigen::Dynamic, int iTc = Eigen::Dynamic> +statslib_inline +EigenMat +pradem(const EigenMat& X, const T1 prob_par, const bool log_form = false); +#endif + +// +// include implementation files + +#include "pradem.ipp" + +#endif diff --git a/include/stats_incl/prob/pradem.ipp b/include/stats_incl/prob/pradem.ipp new file mode 100644 index 0000000..0b075c7 --- /dev/null +++ b/include/stats_incl/prob/pradem.ipp @@ -0,0 +1,133 @@ +/*################################################################################ + ## + ## Copyright (C) 2011-2023 Keith O'Hara + ## + ## This file is part of the StatsLib C++ library. + ## + ## 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 + ## + ## http://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. + ## + ################################################################################*/ + +/* + * cdf of the Rademacher distribution + */ + +// +// scalar input + +namespace internal +{ + +template +statslib_constexpr +T +pradem_compute(const llint_t x, const T prob_par) +noexcept +{ + return( x < llint_t(-1) ? \ + T(0) : + // + x >= llint_t(1) ? \ + T(1) : + T(1) - prob_par ); +} + +template +statslib_constexpr +T +pradem_vals_check(const llint_t x, const T prob_par, const bool log_form) +noexcept +{ + return( !radem_sanity_check(prob_par) ? \ + STLIM::quiet_NaN() : + // + log_if(pradem_compute(x,prob_par), log_form) ); +} + +} + +template +statslib_constexpr +return_t +pradem(const llint_t x, const T prob_par, const bool log_form) +noexcept +{ + return internal::pradem_vals_check(x,static_cast>(prob_par),log_form); +} + +// +// vector/matrix input + +namespace internal +{ + +#ifdef STATS_ENABLE_INTERNAL_VEC_FEATURES +template +statslib_inline +void +pradem_vec(const eT* __stats_pointer_settings__ vals_in, const T1 prob_par, const bool log_form, + rT* __stats_pointer_settings__ vals_out, const ullint_t num_elem) +{ + EVAL_DIST_FN_VEC(pradem,vals_in,vals_out,num_elem,prob_par,log_form); +} +#endif + +} + +#ifdef STATS_ENABLE_STDVEC_WRAPPERS +template +statslib_inline +std::vector +pradem(const std::vector& x, const T1 prob_par, const bool log_form) +{ + STDVEC_DIST_FN(pradem_vec,prob_par,log_form); +} +#endif + +#ifdef STATS_ENABLE_ARMA_WRAPPERS +template +statslib_inline +ArmaMat +pradem(const ArmaMat& X, const T1 prob_par, const bool log_form) +{ + ARMA_DIST_FN(pradem_vec,prob_par,log_form); +} + +template +statslib_inline +mT +pradem(const ArmaGen& X, const T1 prob_par, const bool log_form) +{ + return pradem(X.eval(),prob_par,log_form); +} +#endif + +#ifdef STATS_ENABLE_BLAZE_WRAPPERS +template +statslib_inline +BlazeMat +pradem(const BlazeMat& X, const T1 prob_par, const bool log_form) +{ + BLAZE_DIST_FN(pradem_vec,prob_par,log_form); +} +#endif + +#ifdef STATS_ENABLE_EIGEN_WRAPPERS +template +statslib_inline +EigenMat +pradem(const EigenMat& X, const T1 prob_par, const bool log_form) +{ + EIGEN_DIST_FN(pradem_vec,prob_par,log_form); +} +#endif diff --git a/include/stats_incl/prob/prob.hpp b/include/stats_incl/prob/prob.hpp index 7fc50f0..80df537 100644 --- a/include/stats_incl/prob/prob.hpp +++ b/include/stats_incl/prob/prob.hpp @@ -34,6 +34,7 @@ #include "plogis.hpp" #include "pnorm.hpp" #include "ppois.hpp" +#include "pradem.hpp" #include "pt.hpp" #include "punif.hpp" #include "pweibull.hpp" diff --git a/include/stats_incl/quant/qbern.hpp b/include/stats_incl/quant/qbern.hpp index 80ff158..3aa5f6a 100644 --- a/include/stats_incl/quant/qbern.hpp +++ b/include/stats_incl/quant/qbern.hpp @@ -19,7 +19,7 @@ ################################################################################*/ /* - * quantile function of the univariate Bernoulli distribution + * quantile function of the Bernoulli distribution */ #ifndef _statslib_qbern_HPP diff --git a/include/stats_incl/quant/qbern.ipp b/include/stats_incl/quant/qbern.ipp index 478295a..cdc4117 100644 --- a/include/stats_incl/quant/qbern.ipp +++ b/include/stats_incl/quant/qbern.ipp @@ -19,7 +19,7 @@ ################################################################################*/ /* - * quantile function of the univariate Bernoulli distribution + * quantile function of the Bernoulli distribution */ // diff --git a/include/stats_incl/quant/qradem.hpp b/include/stats_incl/quant/qradem.hpp new file mode 100644 index 0000000..4236b5e --- /dev/null +++ b/include/stats_incl/quant/qradem.hpp @@ -0,0 +1,164 @@ +/*################################################################################ + ## + ## Copyright (C) 2011-2023 Keith O'Hara + ## + ## This file is part of the StatsLib C++ library. + ## + ## 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 + ## + ## http://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. + ## + ################################################################################*/ + +/* + * quantile function of the Rademacher distribution + */ + +#ifndef _statslib_qradem_HPP +#define _statslib_qradem_HPP + +// +// scalar input + +/** + * @brief Quantile function of the Rademacher distribution + * + * @param p a real-valued input. + * @param prob_par the probability parameter, a real-valued input. + * + * @return the quantile function evaluated at \c p. + * + * Example: + * \code{.cpp} stats::qradem(0.5,0.4); \endcode + */ + +template +statslib_constexpr +common_return_t +qradem(const T1 p, const T2 prob_par) noexcept; + +// +// vector/matrix input + +/** + * @brief Quantile function of the Rademacher distribution + * + * @param x a standard vector. + * @param prob_par the probability parameter, a real-valued input. + * + * @return a vector of quantile values corresponding to the elements of \c x. + * + * Example: + * \code{.cpp} + * std::vector x = {0.4, 0.5, 0.9}; + * stats::qradem(x,0.5); + * \endcode + */ + +#ifdef STATS_ENABLE_STDVEC_WRAPPERS +template> +statslib_inline +std::vector +qradem(const std::vector& x, const T1 prob_par); +#endif + +/** + * @brief Quantile function of the Rademacher distribution + * + * @param X a matrix of input values. + * @param prob_par the probability parameter, a real-valued input. + * + * @return a matrix of quantile values corresponding to the elements of \c X. + * + * Example: + * \code{.cpp} + * arma::mat X = { {0.4, 0.5, 0.9}, + * {0.3, 0.6, 0.7} }; + * stats::qradem(X,0.5); + * \endcode + */ + +#ifdef STATS_ENABLE_ARMA_WRAPPERS +template> +statslib_inline +ArmaMat +qradem(const ArmaMat& X, const T1 prob_par); + +/** + * @brief Quantile function of the Rademacher distribution + * + * @param X a matrix of input values. + * @param prob_par the probability parameter, a real-valued input. + * + * @return a matrix of quantile values corresponding to the elements of \c X. + * + * Example: + * \code{.cpp} + * arma::mat X = { {0.4, 0.5, 0.9}, + * {0.3, 0.6, 0.7} }; + * stats::qradem(X,0.5); + * \endcode + */ + +template +statslib_inline +mT +qradem(const ArmaGen& X, const T1 prob_par); +#endif + +/** + * @brief Quantile function of the Rademacher distribution + * + * @param X a matrix of input values. + * @param prob_par the probability parameter, a real-valued input. + * + * @return a matrix of quantile values corresponding to the elements of \c X. + * + * Example: + * \code{.cpp} + * stats::qradem(X,0.5); + * \endcode + */ + +#ifdef STATS_ENABLE_BLAZE_WRAPPERS +template, bool To = blaze::columnMajor> +statslib_inline +BlazeMat +qradem(const BlazeMat& X, const T1 prob_par); +#endif + +/** + * @brief Quantile function of the Rademacher distribution + * + * @param X a matrix of input values. + * @param prob_par the probability parameter, a real-valued input. + * + * @return a matrix of quantile values corresponding to the elements of \c X. + * + * Example: + * \code{.cpp} + * stats::qradem(X,0.5); + * \endcode + */ + +#ifdef STATS_ENABLE_EIGEN_WRAPPERS +template, int iTr = Eigen::Dynamic, int iTc = Eigen::Dynamic> +statslib_inline +EigenMat +qradem(const EigenMat& X, const T1 prob_par); +#endif + +// +// include implementation files + +#include "qradem.ipp" + +#endif diff --git a/include/stats_incl/quant/qradem.ipp b/include/stats_incl/quant/qradem.ipp new file mode 100644 index 0000000..dfe0914 --- /dev/null +++ b/include/stats_incl/quant/qradem.ipp @@ -0,0 +1,133 @@ +/*################################################################################ + ## + ## Copyright (C) 2011-2023 Keith O'Hara + ## + ## This file is part of the StatsLib C++ library. + ## + ## 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 + ## + ## http://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. + ## + ################################################################################*/ + +/* + * quantile function of the Rademacher distribution + */ + +// +// scalar input + +namespace internal +{ + +template +statslib_constexpr +T +qradem_compute(const T p, const T prob_par) +noexcept +{ + return( !radem_sanity_check(prob_par) ? \ + STLIM::quiet_NaN() : + // + !prob_val_check(p) ? \ + STLIM::quiet_NaN() : + // + p > (T(1) - prob_par) ? \ + llint_t(1) : + llint_t(-1) ); +} + +template> +statslib_constexpr +TC +qradem_type_check(const T1 p, const T2 prob_par) +noexcept +{ + return qradem_compute(static_cast(p),static_cast(prob_par)); +} + +} + +template +statslib_constexpr +common_return_t // not llint_t so we can return NaN +qradem(const T1 p, const T2 prob_par) +noexcept +{ + return internal::qradem_type_check(p,prob_par); +} + +// +// vector/matrix input + +namespace internal +{ + +#ifdef STATS_ENABLE_INTERNAL_VEC_FEATURES +template +statslib_inline +void +qradem_vec(const eT* __stats_pointer_settings__ vals_in, const T1 prob_par, + rT* __stats_pointer_settings__ vals_out, const ullint_t num_elem) +{ + EVAL_DIST_FN_VEC(qradem,vals_in,vals_out,num_elem,prob_par); +} +#endif + +} + +#ifdef STATS_ENABLE_STDVEC_WRAPPERS +template +statslib_inline +std::vector +qradem(const std::vector& x, const T1 prob_par) +{ + STDVEC_DIST_FN(qradem_vec,prob_par); +} +#endif + +#ifdef STATS_ENABLE_ARMA_WRAPPERS +template +statslib_inline +ArmaMat +qradem(const ArmaMat& X, const T1 prob_par) +{ + ARMA_DIST_FN(qradem_vec,prob_par); +} + +template +statslib_inline +mT +qradem(const ArmaGen& X, const T1 prob_par) +{ + return qradem(X.eval(),prob_par); +} +#endif + +#ifdef STATS_ENABLE_BLAZE_WRAPPERS +template +statslib_inline +BlazeMat +qradem(const BlazeMat& X, const T1 prob_par) +{ + BLAZE_DIST_FN(qradem_vec,prob_par); +} +#endif + +#ifdef STATS_ENABLE_EIGEN_WRAPPERS +template +statslib_inline +EigenMat +qradem(const EigenMat& X, const T1 prob_par) +{ + EIGEN_DIST_FN(qradem_vec,prob_par); +} +#endif diff --git a/include/stats_incl/quant/quant.hpp b/include/stats_incl/quant/quant.hpp index f4987e8..daf446d 100644 --- a/include/stats_incl/quant/quant.hpp +++ b/include/stats_incl/quant/quant.hpp @@ -35,6 +35,7 @@ #include "qlogis.hpp" #include "qnorm.hpp" #include "qpois.hpp" +#include "qradem.hpp" #include "qt.hpp" #include "qunif.hpp" #include "qweibull.hpp" diff --git a/include/stats_incl/rand/rand.hpp b/include/stats_incl/rand/rand.hpp index 07ea6ad..c69d605 100644 --- a/include/stats_incl/rand/rand.hpp +++ b/include/stats_incl/rand/rand.hpp @@ -42,6 +42,7 @@ #include "rmultinom.hpp" #include "rmvnorm.hpp" #include "rpois.hpp" +#include "rradem.hpp" #include "rt.hpp" #include "rweibull.hpp" #include "rwish.hpp" diff --git a/include/stats_incl/rand/rlogis.hpp b/include/stats_incl/rand/rlogis.hpp index aab2841..397f0e5 100644 --- a/include/stats_incl/rand/rlogis.hpp +++ b/include/stats_incl/rand/rlogis.hpp @@ -72,7 +72,7 @@ rlogis(const T1 mu_par, const T2 sigma_par, const ullint_t seed_val = std::rando // // vector/matrix output -#ifdef STATS_ENABLE_MATRIX_FEATURES +#ifdef STATS_ENABLE_INTERNAL_VEC_FEATURES /** * @brief Random matrix sampling function for the Logistic distribution diff --git a/include/stats_incl/rand/rradem.hpp b/include/stats_incl/rand/rradem.hpp new file mode 100644 index 0000000..d763854 --- /dev/null +++ b/include/stats_incl/rand/rradem.hpp @@ -0,0 +1,143 @@ +/*################################################################################ + ## + ## Copyright (C) 2011-2023 Keith O'Hara + ## + ## This file is part of the StatsLib C++ library. + ## + ## 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 + ## + ## http://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. + ## + ################################################################################*/ + +/* + * Sample from a Rademacher distribution + */ + +#ifndef _statslib_rradem_HPP +#define _statslib_rradem_HPP + +// +// scalar output + +/** + * @brief Random sampling function for the Rademacher distribution + * + * @param prob_par the probability parameter, a real-valued input. + * @param engine a random engine, passed by reference. + * + * @return a pseudo-random draw from the Rademacher distribution. + * + * Example: + * \code{.cpp} + * stats::rand_engine_t engine(1776); + * stats::rradem(0.7,engine); + * \endcode + */ + +template +statslib_inline +return_t +rradem(const T prob_par, rand_engine_t& engine); + +/** + * @brief Random sampling function for the Rademacher distribution + * + * @param prob_par the probability parameter, a real-valued input. + * @param seed_val initialize the random engine with a non-negative integral-valued seed. + * + * @return a pseudo-random draw from the Rademacher distribution. + * + * Example: + * \code{.cpp} + * stats::rradem(0.7,1776); + * \endcode + */ + +template +statslib_inline +return_t +rradem(const T prob_par, const ullint_t seed_val = std::random_device{}()); + +// +// vector/matrix output + +#ifdef STATS_ENABLE_INTERNAL_VEC_FEATURES + +/** + * @brief Random matrix sampling function for the Rademacher distribution + * + * @param n the number of output rows + * @param k the number of output columns + * @param prob_par the probability parameter, a real-valued input. + * @param engine a random engine, passed by reference. + * + * @return a matrix of pseudo-random draws from the Rademacher distribution. + * + * Example: + * \code{.cpp} + * stats::rand_engine_t engine(1776); + * // std::vector + * stats::rradem>(5,4,0.7,engine); + * // Armadillo matrix + * stats::rradem(5,4,0.7,engine); + * // Blaze dynamic matrix + * stats::rradem>(5,4,0.7,engine); + * // Eigen dynamic matrix + * stats::rradem(5,4,0.7,engine); + * \endcode + * + * @note This function requires template instantiation; acceptable output types include: std::vector, with element type \c float, \c double, etc., as well as Armadillo, Blaze, and Eigen dense matrices. + */ + +template +statslib_inline +mT +rradem(const ullint_t n, const ullint_t k, const T1 prob_par, rand_engine_t& engine); + +/** + * @brief Random matrix sampling function for the Rademacher distribution + * + * @param n the number of output rows + * @param k the number of output columns + * @param prob_par the probability parameter, a real-valued input. + * @param seed_val initialize the random engine with a non-negative integral-valued seed. + * + * @return a matrix of pseudo-random draws from the Rademacher distribution. + * + * Example: + * \code{.cpp} + * // std::vector + * stats::rradem>(5,4,0.7); + * // Armadillo matrix + * stats::rradem(5,4,0.7); + * // Blaze dynamic matrix + * stats::rradem>(5,4,0.7); + * // Eigen dynamic matrix + * stats::rradem(5,4,0.7); + * \endcode + * + * @note This function requires template instantiation; acceptable output types include: std::vector, with element type \c float, \c double, etc., as well as Armadillo, Blaze, and Eigen dense matrices. + */ + +template +statslib_inline +mT +rradem(const ullint_t n, const ullint_t k, const T1 prob_par, const ullint_t seed_val = std::random_device{}()); + +#endif + +// +// include implementation files + +#include "rradem.ipp" + +#endif diff --git a/include/stats_incl/rand/rradem.ipp b/include/stats_incl/rand/rradem.ipp new file mode 100644 index 0000000..1a8ead8 --- /dev/null +++ b/include/stats_incl/rand/rradem.ipp @@ -0,0 +1,104 @@ +/*################################################################################ + ## + ## Copyright (C) 2011-2023 Keith O'Hara + ## + ## This file is part of the StatsLib C++ library. + ## + ## 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 + ## + ## http://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. + ## + ################################################################################*/ + +/* + * Sample from a Rademacher distribution + */ + +// +// scalar output + +template +statslib_inline +return_t +rradem(const T prob_par, rand_engine_t& engine) +{ + return( !internal::radem_sanity_check(prob_par) ? \ + STLIM::quiet_NaN() : + // + 2 * (runif(T(0),T(1),engine) <= prob_par) - 1 ); +} + +template +statslib_inline +return_t +rradem(const T prob_par, const ullint_t seed_val) +{ + rand_engine_t engine(seed_val); + return rradem(prob_par,engine); +} + +// +// vector/matrix output + +namespace internal +{ + +#ifdef STATS_ENABLE_INTERNAL_VEC_FEATURES +template +statslib_inline +void +rradem_vec(const T1 prob_par, rand_engine_t& engine_0, + rT* __stats_pointer_settings__ vals_out, const ullint_t num_elem) +{ + RAND_DIST_FN_VEC(rradem,vals_out,num_elem,engine_0,prob_par); +} +#endif + +#ifdef STATS_ENABLE_STDVEC_WRAPPERS +template +statslib_inline +void +rradem_mat_check(std::vector& X, const T1 prob_par, rand_engine_t& engine_0) +{ + STDVEC_RAND_DIST_FN(rradem,prob_par,engine_0); +} +#endif + +#ifdef STATS_ENABLE_MATRIX_FEATURES +template +statslib_inline +void +rradem_mat_check(mT& X, const T1 prob_par, rand_engine_t& engine_0) +{ + MAIN_MAT_RAND_DIST_FN(rradem,prob_par,engine_0); +} +#endif + +} + +#ifdef STATS_ENABLE_INTERNAL_VEC_FEATURES +template +statslib_inline +mT +rradem(const ullint_t n, const ullint_t k, const T1 prob_par, rand_engine_t& engine) +{ + GEN_MAT_RAND_FN(rradem_mat_check,prob_par,engine); +} + +template +statslib_inline +mT +rradem(const ullint_t n, const ullint_t k, const T1 prob_par, const ullint_t seed_val) +{ + rand_engine_t engine(seed_val); + GEN_MAT_RAND_FN(rradem_mat_check,prob_par,engine); +} +#endif diff --git a/tests/dens/dradem.cpp b/tests/dens/dradem.cpp new file mode 100644 index 0000000..48680a5 --- /dev/null +++ b/tests/dens/dradem.cpp @@ -0,0 +1,89 @@ +/*################################################################################ + ## + ## Copyright (C) 2011-2023 Keith O'Hara + ## + ## This file is part of the StatsLib C++ library. + ## + ## 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 + ## + ## http://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. + ## + ################################################################################*/ + +#define TEST_PRINT_PRECISION_1 2 +#define TEST_PRINT_PRECISION_2 5 + +#include "../stats_tests.hpp" + +int main() +{ + print_begin("dradem"); + + // parameters + + double prob_par = 0.4; + + // + + std::vector inp_vals = { 1, -1, 1 }; + std::vector exp_vals = { prob_par, 1-prob_par, prob_par }; + + // + // scalar tests + + STATS_TEST_EXPECTED_VAL(dradem,inp_vals[0],exp_vals[0],false,prob_par); + STATS_TEST_EXPECTED_VAL(dradem,inp_vals[1],exp_vals[1],false,prob_par); + STATS_TEST_EXPECTED_VAL(dradem,inp_vals[2],exp_vals[2],true,prob_par); + + // STATS_TEST_EXPECTED_VAL(dradem,TEST_NAN,TEST_NAN,false,0.5); // NaN inputs + STATS_TEST_EXPECTED_VAL(dradem,1,TEST_NAN,false,TEST_NAN); + + STATS_TEST_EXPECTED_VAL(dradem,1,TEST_NAN,false,-0.1); // bad parameter values + STATS_TEST_EXPECTED_VAL(dradem,1,TEST_NAN,false,1.1); + + STATS_TEST_EXPECTED_VAL(dradem,-2,0.0,false,prob_par); // x < -1 or > 1 + STATS_TEST_EXPECTED_VAL(dradem,2,0.0,false,prob_par); + + // + // vector/matrix tests + +#ifdef STATS_TEST_STDVEC_FEATURES + STATS_TEST_EXPECTED_MAT(dradem,inp_vals,exp_vals,std::vector,false,prob_par); + STATS_TEST_EXPECTED_MAT(dradem,inp_vals,exp_vals,std::vector,true,prob_par); +#endif + +#ifdef STATS_TEST_MATRIX_FEATURES + mat_obj inp_mat(2,3); + inp_mat(0,0) = inp_vals[0]; + inp_mat(1,0) = inp_vals[2]; + inp_mat(0,1) = inp_vals[1]; + inp_mat(1,1) = inp_vals[0]; + inp_mat(0,2) = inp_vals[2]; + inp_mat(1,2) = inp_vals[1]; + + mat_obj exp_mat(2,3); + exp_mat(0,0) = exp_vals[0]; + exp_mat(1,0) = exp_vals[2]; + exp_mat(0,1) = exp_vals[1]; + exp_mat(1,1) = exp_vals[0]; + exp_mat(0,2) = exp_vals[2]; + exp_mat(1,2) = exp_vals[1]; + + STATS_TEST_EXPECTED_MAT(dradem,inp_mat,exp_mat,mat_obj,false,prob_par); + STATS_TEST_EXPECTED_MAT(dradem,inp_mat,exp_mat,mat_obj,true,prob_par); +#endif + + // + + print_final("dradem"); + + return 0; +} diff --git a/tests/prob/pradem.cpp b/tests/prob/pradem.cpp new file mode 100644 index 0000000..b51df5e --- /dev/null +++ b/tests/prob/pradem.cpp @@ -0,0 +1,90 @@ +/*################################################################################ + ## + ## Copyright (C) 2011-2023 Keith O'Hara + ## + ## This file is part of the StatsLib C++ library. + ## + ## 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 + ## + ## http://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. + ## + ################################################################################*/ + +#define TEST_PRINT_PRECISION_1 2 +#define TEST_PRINT_PRECISION_2 5 + +#include "../stats_tests.hpp" + +int main() +{ + print_begin("pradem"); + + // parameters + + double prob_par = 0.4; + + // + + std::vector inp_vals = { 1, 2, -1, 0}; + std::vector exp_vals = { 1, 1, 1 - prob_par, 1 - prob_par }; + + // + // scalar tests + + STATS_TEST_EXPECTED_VAL(pradem,inp_vals[0],exp_vals[0],false,prob_par); + STATS_TEST_EXPECTED_VAL(pradem,inp_vals[1],exp_vals[1],false,prob_par); + STATS_TEST_EXPECTED_VAL(pradem,inp_vals[2],exp_vals[2],true,prob_par); + STATS_TEST_EXPECTED_VAL(pradem,inp_vals[3],exp_vals[3],true,prob_par); + + // STATS_TEST_EXPECTED_VAL(pradem,TEST_NAN,TEST_NAN,false,0.5); // NaN inputs + STATS_TEST_EXPECTED_VAL(pradem,1,TEST_NAN,false,TEST_NAN); + + STATS_TEST_EXPECTED_VAL(pradem,1,TEST_NAN,false,-0.1); // bad parameter values + STATS_TEST_EXPECTED_VAL(pradem,1,TEST_NAN,false,1.1); + + STATS_TEST_EXPECTED_VAL(pradem,-2,0.0,false,prob_par); // x < -1 or > 1 + STATS_TEST_EXPECTED_VAL(pradem,5,1.0,false,prob_par); + + // + // vector/matrix tests + +#ifdef STATS_TEST_STDVEC_FEATURES + STATS_TEST_EXPECTED_MAT(pradem,inp_vals,exp_vals,std::vector,false,prob_par); + STATS_TEST_EXPECTED_MAT(pradem,inp_vals,exp_vals,std::vector,true,prob_par); +#endif + +#ifdef STATS_TEST_MATRIX_FEATURES + mat_obj inp_mat(2,3); + inp_mat(0,0) = inp_vals[0]; + inp_mat(1,0) = inp_vals[2]; + inp_mat(0,1) = inp_vals[1]; + inp_mat(1,1) = inp_vals[0]; + inp_mat(0,2) = inp_vals[2]; + inp_mat(1,2) = inp_vals[1]; + + mat_obj exp_mat(2,3); + exp_mat(0,0) = exp_vals[0]; + exp_mat(1,0) = exp_vals[2]; + exp_mat(0,1) = exp_vals[1]; + exp_mat(1,1) = exp_vals[0]; + exp_mat(0,2) = exp_vals[2]; + exp_mat(1,2) = exp_vals[1]; + + STATS_TEST_EXPECTED_MAT(pradem,inp_mat,exp_mat,mat_obj,false,prob_par); + STATS_TEST_EXPECTED_MAT(pradem,inp_mat,exp_mat,mat_obj,true,prob_par); +#endif + + // + + print_final("pradem"); + + return 0; +} diff --git a/tests/quant/qradem.cpp b/tests/quant/qradem.cpp new file mode 100644 index 0000000..874f4a4 --- /dev/null +++ b/tests/quant/qradem.cpp @@ -0,0 +1,90 @@ +/*################################################################################ + ## + ## Copyright (C) 2011-2023 Keith O'Hara + ## + ## This file is part of the StatsLib C++ library. + ## + ## 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 + ## + ## http://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. + ## + ################################################################################*/ + +#define STATS_TEST_INPUT_TYPE 1 + +#define TEST_PRINT_PRECISION_1 2 +#define TEST_PRINT_PRECISION_2 5 + +#include "../stats_tests.hpp" + +int main() +{ + print_begin("qradem"); + + // parameters + + double prob_par = 0.4; + + // + + std::vector inp_vals = { 0.2, prob_par, 0.9 }; + std::vector exp_vals = { -1, -1, 1}; + + // + // scalar tests + + STATS_TEST_EXPECTED_QUANT_VAL(qradem,inp_vals[0],exp_vals[0],prob_par); + STATS_TEST_EXPECTED_QUANT_VAL(qradem,inp_vals[1],exp_vals[1],prob_par); + STATS_TEST_EXPECTED_QUANT_VAL(qradem,inp_vals[2],exp_vals[2],prob_par); + + STATS_TEST_EXPECTED_QUANT_VAL(qradem,TEST_NAN,TEST_NAN,0.5); // NaN inputs + STATS_TEST_EXPECTED_QUANT_VAL(qradem,0.5,TEST_NAN,TEST_NAN); + STATS_TEST_EXPECTED_QUANT_VAL(qradem,TEST_NAN,TEST_NAN,TEST_NAN); + + STATS_TEST_EXPECTED_QUANT_VAL(qradem,1,TEST_NAN,-0.1); // bad parameter values + STATS_TEST_EXPECTED_QUANT_VAL(qradem,1,TEST_NAN,1.1); + + STATS_TEST_EXPECTED_QUANT_VAL(qradem,-1,TEST_NAN,prob_par); // p < 0 or > 1 + STATS_TEST_EXPECTED_QUANT_VAL(qradem, 5,TEST_NAN,prob_par); + + // + // vector/matrix tests + +#ifdef STATS_TEST_STDVEC_FEATURES + STATS_TEST_EXPECTED_QUANT_MAT(qradem,inp_vals,exp_vals,std::vector,prob_par); +#endif + +#ifdef STATS_TEST_MATRIX_FEATURES + mat_obj inp_mat(2,3); + inp_mat(0,0) = inp_vals[0]; + inp_mat(1,0) = inp_vals[2]; + inp_mat(0,1) = inp_vals[1]; + inp_mat(1,1) = inp_vals[0]; + inp_mat(0,2) = inp_vals[2]; + inp_mat(1,2) = inp_vals[1]; + + mat_obj exp_mat(2,3); + exp_mat(0,0) = exp_vals[0]; + exp_mat(1,0) = exp_vals[2]; + exp_mat(0,1) = exp_vals[1]; + exp_mat(1,1) = exp_vals[0]; + exp_mat(0,2) = exp_vals[2]; + exp_mat(1,2) = exp_vals[1]; + + STATS_TEST_EXPECTED_QUANT_MAT(qradem,inp_mat,exp_mat,mat_obj,prob_par); +#endif + + // + + print_final("qradem"); + + return 0; +} diff --git a/tests/rand/rradem.cpp b/tests/rand/rradem.cpp new file mode 100644 index 0000000..b1aafaf --- /dev/null +++ b/tests/rand/rradem.cpp @@ -0,0 +1,84 @@ +/*################################################################################ + ## + ## Copyright (C) 2011-2023 Keith O'Hara + ## + ## This file is part of the StatsLib C++ library. + ## + ## 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 + ## + ## http://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 "../stats_tests.hpp" + +int main() +{ + print_begin("rradem"); + + // + + double prob_par = 0.75; + + double radem_mean = 2 * prob_par - 1; // p * (1) + (1 - p) * (-1) + double radem_var = 1 - radem_mean * radem_mean; // E[X^2] - (E[X])^2 + + int n_sample = 10000; + + // + + int radem_rand = stats::rradem(prob_par); + std::cout << "radem rv draw: " << radem_rand << std::endl; + + // + +#ifdef STATS_TEST_STDVEC_FEATURES + std::cout << "\n"; + std::vector radem_stdvec = stats::rradem>(n_sample,1,prob_par); + + std::cout << "stdvec: radem rv mean: " << stats::mat_ops::mean(radem_stdvec) << ". Should be close to: " << radem_mean << "\n"; + std::cout << "stdvec: radem rv variance: " << stats::mat_ops::var(radem_stdvec) << ". Should be close to: " << radem_var << std::endl; + + // + + stats::rand_engine_t engine_s(1); + + radem_stdvec = stats::rradem>(n_sample,1,prob_par,engine_s); + + std::cout << "stdvec (with random engine): radem rv mean: " << stats::mat_ops::mean(radem_stdvec) << ". Should be close to: " << radem_mean << std::endl; + std::cout << "stdvec (with random engine): radem rv variance: " << stats::mat_ops::var(radem_stdvec) << ". Should be close to: " << radem_var << std::endl; +#endif + + // + +#ifdef STATS_TEST_MATRIX_FEATURES + std::cout << "\n"; + mat_obj radem_vec = stats::rradem(n_sample,1,prob_par); + + std::cout << "Matrix: radem rv mean: " << stats::mat_ops::mean(radem_vec) << ". Should be close to: " << radem_mean << "\n"; + std::cout << "Matrix: radem rv variance: " << stats::mat_ops::var(radem_vec) << ". Should be close to: " << radem_var << std::endl; + + // + + stats::rand_engine_t engine_m(1); + + radem_vec = stats::rradem(n_sample,1,prob_par,engine_m); + + std::cout << "Matrix (with random engine): radem rv mean: " << stats::mat_ops::mean(radem_vec) << ". Should be close to: " << radem_mean << std::endl; + std::cout << "Matrix (with random engine): radem rv variance: " << stats::mat_ops::var(radem_vec) << ". Should be close to: " << radem_var << std::endl; +#endif + + // + + std::cout << "\n*** rradem: end tests. ***\n" << std::endl; + + return 0; +}