// 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 <cmath>

#include "absl/random/internal/distribution_test_util.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace random_internal {
namespace {

#if defined(__EMSCRIPTEN__)
// Workaround __EMSCRIPTEN__ error: llvm_fma_f64 not found.
inline double fma(double x, double y, double z) {
  return (x * y) + z;
}
#endif

// Use Horner's method to evaluate a polynomial.
template <typename T, unsigned N>
inline T EvaluatePolynomial(T x, const T (&poly)[N]) {
#if !defined(__EMSCRIPTEN__)
  using std::fma;
#endif
  T p = poly[N - 1];
  for (unsigned i = 2; i <= N; i++) {
    p = fma(p, x, poly[N - i]);
  }
  return p;
}

static constexpr int kLargeDOF = 150;

// Returns the probability of a normal z-value.
//
// Adapted from the POZ function in:
//     Ibbetson D, Algorithm 209
//     Collected Algorithms of the CACM 1963 p. 616
//
double POZ(double z) {
  static constexpr double kP1[] = {
      0.797884560593,  -0.531923007300, 0.319152932694,
      -0.151968751364, 0.059054035642,  -0.019198292004,
      0.005198775019,  -0.001075204047, 0.000124818987,
  };
  static constexpr double kP2[] = {
      0.999936657524,  0.000535310849,  -0.002141268741, 0.005353579108,
      -0.009279453341, 0.011630447319,  -0.010557625006, 0.006549791214,
      -0.002034254874, -0.000794620820, 0.001390604284,  -0.000676904986,
      -0.000019538132, 0.000152529290,  -0.000045255659,
  };

  const double kZMax = 6.0;  // Maximum meaningful z-value.
  if (z == 0.0) {
    return 0.5;
  }
  double x;
  double y = 0.5 * std::fabs(z);
  if (y >= (kZMax * 0.5)) {
    x = 1.0;
  } else if (y < 1.0) {
    double w = y * y;
    x = EvaluatePolynomial(w, kP1) * y * 2.0;
  } else {
    y -= 2.0;
    x = EvaluatePolynomial(y, kP2);
  }
  return z > 0.0 ? ((x + 1.0) * 0.5) : ((1.0 - x) * 0.5);
}

// Approximates the survival function of the normal distribution.
//
// Algorithm 26.2.18, from:
// [Abramowitz and Stegun, Handbook of Mathematical Functions,p.932]
// http://people.math.sfu.ca/~cbm/aands/abramowitz_and_stegun.pdf
//
double normal_survival(double z) {
  // Maybe replace with the alternate formulation.
  // 0.5 * erfc((x - mean)/(sqrt(2) * sigma))
  static constexpr double kR[] = {
      1.0, 0.196854, 0.115194, 0.000344, 0.019527,
  };
  double r = EvaluatePolynomial(z, kR);
  r *= r;
  return 0.5 / (r * r);
}

}  // namespace

// Calculates the critical chi-square value given degrees-of-freedom and a
// p-value, usually using bisection. Also known by the name CRITCHI.
double ChiSquareValue(int dof, double p) {
  static constexpr double kChiEpsilon =
      0.000001;  // Accuracy of the approximation.
  static constexpr double kChiMax =
      99999.0;  // Maximum chi-squared value.

  const double p_value = 1.0 - p;
  if (dof < 1 || p_value > 1.0) {
    return 0.0;
  }

  if (dof > kLargeDOF) {
    // For large degrees of freedom, use the normal approximation by
    //     Wilson, E. B. and Hilferty, M. M. (1931)
    //                     chi^2 - mean
    //                Z = --------------
    //                        stddev
    const double z = InverseNormalSurvival(p_value);
    const double mean = 1 - 2.0 / (9 * dof);
    const double variance = 2.0 / (9 * dof);
    // Cannot use this method if the variance is 0.
    if (variance != 0) {
      return std::pow(z * std::sqrt(variance) + mean, 3.0) * dof;
    }
  }

  if (p_value <= 0.0) return kChiMax;

  // Otherwise search for the p value by bisection
  double min_chisq = 0.0;
  double max_chisq = kChiMax;
  double current = dof / std::sqrt(p_value);
  while ((max_chisq - min_chisq) > kChiEpsilon) {
    if (ChiSquarePValue(current, dof) < p_value) {
      max_chisq = current;
    } else {
      min_chisq = current;
    }
    current = (max_chisq + min_chisq) * 0.5;
  }
  return current;
}

// Calculates the p-value (probability) of a given chi-square value
// and degrees of freedom.
//
// Adapted from the POCHISQ function from:
//     Hill, I. D. and Pike, M. C.  Algorithm 299
//     Collected Algorithms of the CACM 1963 p. 243
//
double ChiSquarePValue(double chi_square, int dof) {
  static constexpr double kLogSqrtPi =
      0.5723649429247000870717135;  // Log[Sqrt[Pi]]
  static constexpr double kInverseSqrtPi =
      0.5641895835477562869480795;  // 1/(Sqrt[Pi])

  // For large degrees of freedom, use the normal approximation by
  //     Wilson, E. B. and Hilferty, M. M. (1931)
  // Via Wikipedia:
  //   By the Central Limit Theorem, because the chi-square distribution is the
  //   sum of k independent random variables with finite mean and variance, it
  //   converges to a normal distribution for large k.
  if (dof > kLargeDOF) {
    // Re-scale everything.
    const double chi_square_scaled = std::pow(chi_square / dof, 1.0 / 3);
    const double mean = 1 - 2.0 / (9 * dof);
    const double variance = 2.0 / (9 * dof);
    // If variance is 0, this method cannot be used.
    if (variance != 0) {
      const double z = (chi_square_scaled - mean) / std::sqrt(variance);
      if (z > 0) {
        return normal_survival(z);
      } else if (z < 0) {
        return 1.0 - normal_survival(-z);
      } else {
        return 0.5;
      }
    }
  }

  // The chi square function is >= 0 for any degrees of freedom.
  // In other words, probability that the chi square function >= 0 is 1.
  if (chi_square <= 0.0) return 1.0;

  // If the degrees of freedom is zero, the chi square function is always 0 by
  // definition. In other words, the probability that the chi square function
  // is > 0 is zero (chi square values <= 0 have been filtered above).
  if (dof < 1) return 0;

  auto capped_exp = [](double x) { return x < -20 ? 0.0 : std::exp(x); };
  static constexpr double kBigX = 20;

  double a = 0.5 * chi_square;
  const bool even = !(dof & 1);  // True if dof is an even number.
  const double y = capped_exp(-a);
  double s = even ? y : (2.0 * POZ(-std::sqrt(chi_square)));

  if (dof <= 2) {
    return s;
  }

  chi_square = 0.5 * (dof - 1.0);
  double z = (even ? 1.0 : 0.5);
  if (a > kBigX) {
    double e = (even ? 0.0 : kLogSqrtPi);
    double c = std::log(a);
    while (z <= chi_square) {
      e = std::log(z) + e;
      s += capped_exp(c * z - a - e);
      z += 1.0;
    }
    return s;
  }

  double e = (even ? 1.0 : (kInverseSqrtPi / std::sqrt(a)));
  double c = 0.0;
  while (z <= chi_square) {
    e = e * (a / z);
    c = c + e;
    z += 1.0;
  }
  return c * y + s;
}

}  // namespace random_internal
ABSL_NAMESPACE_END
}  // namespace absl
