// 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.
//
// -----------------------------------------------------------------------------
// File: distributions.h
// -----------------------------------------------------------------------------
//
// This header defines functions representing distributions, which you use in
// combination with an Abseil random bit generator to produce random values
// according to the rules of that distribution.
//
// The Abseil random library defines the following distributions within this
// file:
//
//   * `absl::Uniform` for uniform (constant) distributions having constant
//     probability
//   * `absl::Bernoulli` for discrete distributions having exactly two outcomes
//   * `absl::Beta` for continuous distributions parameterized through two
//     free parameters
//   * `absl::Exponential` for discrete distributions of events occurring
//     continuously and independently at a constant average rate
//   * `absl::Gaussian` (also known as "normal distributions") for continuous
//     distributions using an associated quadratic function
//   * `absl::LogUniform` for discrete distributions where the log to the given
//     base of all values is uniform
//   * `absl::Poisson` for discrete probability distributions that express the
//     probability of a given number of events occurring within a fixed interval
//   * `absl::Zipf` for discrete probability distributions commonly used for
//     modelling of rare events
//
// Prefer use of these distribution function classes over manual construction of
// your own distribution classes, as it allows library maintainers greater
// flexibility to change the underlying implementation in the future.

#ifndef ABSL_RANDOM_DISTRIBUTIONS_H_
#define ABSL_RANDOM_DISTRIBUTIONS_H_

#include <algorithm>
#include <cmath>
#include <limits>
#include <random>
#include <type_traits>

#include "absl/base/internal/inline_variable.h"
#include "absl/random/bernoulli_distribution.h"
#include "absl/random/beta_distribution.h"
#include "absl/random/exponential_distribution.h"
#include "absl/random/gaussian_distribution.h"
#include "absl/random/internal/distribution_caller.h"  // IWYU pragma: export
#include "absl/random/internal/uniform_helper.h"  // IWYU pragma: export
#include "absl/random/log_uniform_int_distribution.h"
#include "absl/random/poisson_distribution.h"
#include "absl/random/uniform_int_distribution.h"
#include "absl/random/uniform_real_distribution.h"
#include "absl/random/zipf_distribution.h"

namespace absl {
ABSL_NAMESPACE_BEGIN

ABSL_INTERNAL_INLINE_CONSTEXPR(IntervalClosedClosedTag, IntervalClosedClosed,
                               {});
ABSL_INTERNAL_INLINE_CONSTEXPR(IntervalClosedClosedTag, IntervalClosed, {});
ABSL_INTERNAL_INLINE_CONSTEXPR(IntervalClosedOpenTag, IntervalClosedOpen, {});
ABSL_INTERNAL_INLINE_CONSTEXPR(IntervalOpenOpenTag, IntervalOpenOpen, {});
ABSL_INTERNAL_INLINE_CONSTEXPR(IntervalOpenOpenTag, IntervalOpen, {});
ABSL_INTERNAL_INLINE_CONSTEXPR(IntervalOpenClosedTag, IntervalOpenClosed, {});

// -----------------------------------------------------------------------------
// absl::Uniform<T>(tag, bitgen, lo, hi)
// -----------------------------------------------------------------------------
//
// `absl::Uniform()` produces random values of type `T` uniformly distributed in
// a defined interval {lo, hi}. The interval `tag` defines the type of interval
// which should be one of the following possible values:
//
//   * `absl::IntervalOpenOpen`
//   * `absl::IntervalOpenClosed`
//   * `absl::IntervalClosedOpen`
//   * `absl::IntervalClosedClosed`
//
// where "open" refers to an exclusive value (excluded) from the output, while
// "closed" refers to an inclusive value (included) from the output.
//
// In the absence of an explicit return type `T`, `absl::Uniform()` will deduce
// the return type based on the provided endpoint arguments {A lo, B hi}.
// Given these endpoints, one of {A, B} will be chosen as the return type, if
// a type can be implicitly converted into the other in a lossless way. The
// lack of any such implicit conversion between {A, B} will produce a
// compile-time error
//
// See https://en.wikipedia.org/wiki/Uniform_distribution_(continuous)
//
// Example:
//
//   absl::BitGen bitgen;
//
//   // Produce a random float value between 0.0 and 1.0, inclusive
//   auto x = absl::Uniform(absl::IntervalClosedClosed, bitgen, 0.0f, 1.0f);
//
//   // The most common interval of `absl::IntervalClosedOpen` is available by
//   // default:
//
//   auto x = absl::Uniform(bitgen, 0.0f, 1.0f);
//
//   // Return-types are typically inferred from the arguments, however callers
//   // can optionally provide an explicit return-type to the template.
//
//   auto x = absl::Uniform<float>(bitgen, 0, 1);
//
template <typename R = void, typename TagType, typename URBG>
typename absl::enable_if_t<!std::is_same<R, void>::value, R>  //
Uniform(TagType tag,
        URBG&& urbg,  // NOLINT(runtime/references)
        R lo, R hi) {
  using gen_t = absl::decay_t<URBG>;
  using distribution_t = random_internal::UniformDistributionWrapper<R>;

  auto a = random_internal::uniform_lower_bound(tag, lo, hi);
  auto b = random_internal::uniform_upper_bound(tag, lo, hi);
  if (!random_internal::is_uniform_range_valid(a, b)) return lo;

  return random_internal::DistributionCaller<gen_t>::template Call<
      distribution_t>(&urbg, tag, lo, hi);
}

// absl::Uniform<T>(bitgen, lo, hi)
//
// Overload of `Uniform()` using the default closed-open interval of [lo, hi),
// and returning values of type `T`
template <typename R = void, typename URBG>
typename absl::enable_if_t<!std::is_same<R, void>::value, R>  //
Uniform(URBG&& urbg,  // NOLINT(runtime/references)
        R lo, R hi) {
  using gen_t = absl::decay_t<URBG>;
  using distribution_t = random_internal::UniformDistributionWrapper<R>;
  constexpr auto tag = absl::IntervalClosedOpen;

  auto a = random_internal::uniform_lower_bound(tag, lo, hi);
  auto b = random_internal::uniform_upper_bound(tag, lo, hi);
  if (!random_internal::is_uniform_range_valid(a, b)) return lo;

  return random_internal::DistributionCaller<gen_t>::template Call<
      distribution_t>(&urbg, lo, hi);
}

// absl::Uniform(tag, bitgen, lo, hi)
//
// Overload of `Uniform()` using different (but compatible) lo, hi types. Note
// that a compile-error will result if the return type cannot be deduced
// correctly from the passed types.
template <typename R = void, typename TagType, typename URBG, typename A,
          typename B>
typename absl::enable_if_t<std::is_same<R, void>::value,
                           random_internal::uniform_inferred_return_t<A, B>>
Uniform(TagType tag,
        URBG&& urbg,  // NOLINT(runtime/references)
        A lo, B hi) {
  using gen_t = absl::decay_t<URBG>;
  using return_t = typename random_internal::uniform_inferred_return_t<A, B>;
  using distribution_t = random_internal::UniformDistributionWrapper<return_t>;

  auto a = random_internal::uniform_lower_bound<return_t>(tag, lo, hi);
  auto b = random_internal::uniform_upper_bound<return_t>(tag, lo, hi);
  if (!random_internal::is_uniform_range_valid(a, b)) return lo;

  return random_internal::DistributionCaller<gen_t>::template Call<
      distribution_t>(&urbg, tag, static_cast<return_t>(lo),
                                static_cast<return_t>(hi));
}

// absl::Uniform(bitgen, lo, hi)
//
// Overload of `Uniform()` using different (but compatible) lo, hi types and the
// default closed-open interval of [lo, hi). Note that a compile-error will
// result if the return type cannot be deduced correctly from the passed types.
template <typename R = void, typename URBG, typename A, typename B>
typename absl::enable_if_t<std::is_same<R, void>::value,
                           random_internal::uniform_inferred_return_t<A, B>>
Uniform(URBG&& urbg,  // NOLINT(runtime/references)
        A lo, B hi) {
  using gen_t = absl::decay_t<URBG>;
  using return_t = typename random_internal::uniform_inferred_return_t<A, B>;
  using distribution_t = random_internal::UniformDistributionWrapper<return_t>;

  constexpr auto tag = absl::IntervalClosedOpen;
  auto a = random_internal::uniform_lower_bound<return_t>(tag, lo, hi);
  auto b = random_internal::uniform_upper_bound<return_t>(tag, lo, hi);
  if (!random_internal::is_uniform_range_valid(a, b)) return lo;

  return random_internal::DistributionCaller<gen_t>::template Call<
      distribution_t>(&urbg, static_cast<return_t>(lo),
                                static_cast<return_t>(hi));
}

// absl::Uniform<unsigned T>(bitgen)
//
// Overload of Uniform() using the minimum and maximum values of a given type
// `T` (which must be unsigned), returning a value of type `unsigned T`
template <typename R, typename URBG>
typename absl::enable_if_t<!std::is_signed<R>::value, R>  //
Uniform(URBG&& urbg) {  // NOLINT(runtime/references)
  using gen_t = absl::decay_t<URBG>;
  using distribution_t = random_internal::UniformDistributionWrapper<R>;

  return random_internal::DistributionCaller<gen_t>::template Call<
      distribution_t>(&urbg);
}

// -----------------------------------------------------------------------------
// absl::Bernoulli(bitgen, p)
// -----------------------------------------------------------------------------
//
// `absl::Bernoulli` produces a random boolean value, with probability `p`
// (where 0.0 <= p <= 1.0) equaling `true`.
//
// Prefer `absl::Bernoulli` to produce boolean values over other alternatives
// such as comparing an `absl::Uniform()` value to a specific output.
//
// See https://en.wikipedia.org/wiki/Bernoulli_distribution
//
// Example:
//
//   absl::BitGen bitgen;
//   ...
//   if (absl::Bernoulli(bitgen, 1.0/3721.0)) {
//     std::cout << "Asteroid field navigation successful.";
//   }
//
template <typename URBG>
bool Bernoulli(URBG&& urbg,  // NOLINT(runtime/references)
               double p) {
  using gen_t = absl::decay_t<URBG>;
  using distribution_t = absl::bernoulli_distribution;

  return random_internal::DistributionCaller<gen_t>::template Call<
      distribution_t>(&urbg, p);
}

// -----------------------------------------------------------------------------
// absl::Beta<T>(bitgen, alpha, beta)
// -----------------------------------------------------------------------------
//
// `absl::Beta` produces a floating point number distributed in the closed
// interval [0,1] and parameterized by two values `alpha` and `beta` as per a
// Beta distribution. `T` must be a floating point type, but may be inferred
// from the types of `alpha` and `beta`.
//
// See https://en.wikipedia.org/wiki/Beta_distribution.
//
// Example:
//
//   absl::BitGen bitgen;
//   ...
//   double sample = absl::Beta(bitgen, 3.0, 2.0);
//
template <typename RealType, typename URBG>
RealType Beta(URBG&& urbg,  // NOLINT(runtime/references)
              RealType alpha, RealType beta) {
  static_assert(
      std::is_floating_point<RealType>::value,
      "Template-argument 'RealType' must be a floating-point type, in "
      "absl::Beta<RealType, URBG>(...)");

  using gen_t = absl::decay_t<URBG>;
  using distribution_t = typename absl::beta_distribution<RealType>;

  return random_internal::DistributionCaller<gen_t>::template Call<
      distribution_t>(&urbg, alpha, beta);
}

// -----------------------------------------------------------------------------
// absl::Exponential<T>(bitgen, lambda = 1)
// -----------------------------------------------------------------------------
//
// `absl::Exponential` produces a floating point number representing the
// distance (time) between two consecutive events in a point process of events
// occurring continuously and independently at a constant average rate. `T` must
// be a floating point type, but may be inferred from the type of `lambda`.
//
// See https://en.wikipedia.org/wiki/Exponential_distribution.
//
// Example:
//
//   absl::BitGen bitgen;
//   ...
//   double call_length = absl::Exponential(bitgen, 7.0);
//
template <typename RealType, typename URBG>
RealType Exponential(URBG&& urbg,  // NOLINT(runtime/references)
                     RealType lambda = 1) {
  static_assert(
      std::is_floating_point<RealType>::value,
      "Template-argument 'RealType' must be a floating-point type, in "
      "absl::Exponential<RealType, URBG>(...)");

  using gen_t = absl::decay_t<URBG>;
  using distribution_t = typename absl::exponential_distribution<RealType>;

  return random_internal::DistributionCaller<gen_t>::template Call<
      distribution_t>(&urbg, lambda);
}

// -----------------------------------------------------------------------------
// absl::Gaussian<T>(bitgen, mean = 0, stddev = 1)
// -----------------------------------------------------------------------------
//
// `absl::Gaussian` produces a floating point number selected from the Gaussian
// (ie. "Normal") distribution. `T` must be a floating point type, but may be
// inferred from the types of `mean` and `stddev`.
//
// See https://en.wikipedia.org/wiki/Normal_distribution
//
// Example:
//
//   absl::BitGen bitgen;
//   ...
//   double giraffe_height = absl::Gaussian(bitgen, 16.3, 3.3);
//
template <typename RealType, typename URBG>
RealType Gaussian(URBG&& urbg,  // NOLINT(runtime/references)
                  RealType mean = 0, RealType stddev = 1) {
  static_assert(
      std::is_floating_point<RealType>::value,
      "Template-argument 'RealType' must be a floating-point type, in "
      "absl::Gaussian<RealType, URBG>(...)");

  using gen_t = absl::decay_t<URBG>;
  using distribution_t = typename absl::gaussian_distribution<RealType>;

  return random_internal::DistributionCaller<gen_t>::template Call<
      distribution_t>(&urbg, mean, stddev);
}

// -----------------------------------------------------------------------------
// absl::LogUniform<T>(bitgen, lo, hi, base = 2)
// -----------------------------------------------------------------------------
//
// `absl::LogUniform` produces random values distributed where the log to a
// given base of all values is uniform in a closed interval [lo, hi]. `T` must
// be an integral type, but may be inferred from the types of `lo` and `hi`.
//
// I.e., `LogUniform(0, n, b)` is uniformly distributed across buckets
// [0], [1, b-1], [b, b^2-1] .. [b^(k-1), (b^k)-1] .. [b^floor(log(n, b)), n]
// and is uniformly distributed within each bucket.
//
// The resulting probability density is inversely related to bucket size, though
// values in the final bucket may be more likely than previous values. (In the
// extreme case where n = b^i the final value will be tied with zero as the most
// probable result.
//
// If `lo` is nonzero then this distribution is shifted to the desired interval,
// so LogUniform(lo, hi, b) is equivalent to LogUniform(0, hi-lo, b)+lo.
//
// See https://en.wikipedia.org/wiki/Reciprocal_distribution
//
// Example:
//
//   absl::BitGen bitgen;
//   ...
//   int v = absl::LogUniform(bitgen, 0, 1000);
//
template <typename IntType, typename URBG>
IntType LogUniform(URBG&& urbg,  // NOLINT(runtime/references)
                   IntType lo, IntType hi, IntType base = 2) {
  static_assert(random_internal::IsIntegral<IntType>::value,
                "Template-argument 'IntType' must be an integral type, in "
                "absl::LogUniform<IntType, URBG>(...)");

  using gen_t = absl::decay_t<URBG>;
  using distribution_t = typename absl::log_uniform_int_distribution<IntType>;

  return random_internal::DistributionCaller<gen_t>::template Call<
      distribution_t>(&urbg, lo, hi, base);
}

// -----------------------------------------------------------------------------
// absl::Poisson<T>(bitgen, mean = 1)
// -----------------------------------------------------------------------------
//
// `absl::Poisson` produces discrete probabilities for a given number of events
// occurring within a fixed interval within the closed interval [0, max]. `T`
// must be an integral type.
//
// See https://en.wikipedia.org/wiki/Poisson_distribution
//
// Example:
//
//   absl::BitGen bitgen;
//   ...
//   int requests_per_minute = absl::Poisson<int>(bitgen, 3.2);
//
template <typename IntType, typename URBG>
IntType Poisson(URBG&& urbg,  // NOLINT(runtime/references)
                double mean = 1.0) {
  static_assert(random_internal::IsIntegral<IntType>::value,
                "Template-argument 'IntType' must be an integral type, in "
                "absl::Poisson<IntType, URBG>(...)");

  using gen_t = absl::decay_t<URBG>;
  using distribution_t = typename absl::poisson_distribution<IntType>;

  return random_internal::DistributionCaller<gen_t>::template Call<
      distribution_t>(&urbg, mean);
}

// -----------------------------------------------------------------------------
// absl::Zipf<T>(bitgen, hi = max, q = 2, v = 1)
// -----------------------------------------------------------------------------
//
// `absl::Zipf` produces discrete probabilities commonly used for modelling of
// rare events over the closed interval [0, hi]. The parameters `v` and `q`
// determine the skew of the distribution. `T`  must be an integral type, but
// may be inferred from the type of `hi`.
//
// See http://mathworld.wolfram.com/ZipfDistribution.html
//
// Example:
//
//   absl::BitGen bitgen;
//   ...
//   int term_rank = absl::Zipf<int>(bitgen);
//
template <typename IntType, typename URBG>
IntType Zipf(URBG&& urbg,  // NOLINT(runtime/references)
             IntType hi = (std::numeric_limits<IntType>::max)(), double q = 2.0,
             double v = 1.0) {
  static_assert(random_internal::IsIntegral<IntType>::value,
                "Template-argument 'IntType' must be an integral type, in "
                "absl::Zipf<IntType, URBG>(...)");

  using gen_t = absl::decay_t<URBG>;
  using distribution_t = typename absl::zipf_distribution<IntType>;

  return random_internal::DistributionCaller<gen_t>::template Call<
      distribution_t>(&urbg, hi, q, v);
}

ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_RANDOM_DISTRIBUTIONS_H_
