<commit_before>#ifndef STAN_MATH_REV_FUNCTOR_integrate_1d_HPP
#define STAN_MATH_REV_FUNCTOR_integrate_1d_HPP

#include <stan/math/rev/meta.hpp>
#include <stan/math/rev/fun/is_nan.hpp>
#include <stan/math/rev/fun/value_of.hpp>
#include <stan/math/rev/core/precomputed_gradients.hpp>
#include <stan/math/prim/meta.hpp>
#include <stan/math/prim/err.hpp>
#include <stan/math/prim/fun/constants.hpp>
#include <stan/math/prim/functor/integrate_1d.hpp>
#include <cmath>
#include <functional>
#include <ostream>
#include <string>
#include <type_traits>
#include <vector>

namespace stan {
namespace math {

/**
 * Calculate first derivative of f(x, param, std::ostream&)
 * with respect to the nth parameter. Uses nested reverse mode autodiff
 *
 * Gradients that evaluate to NaN are set to zero if the function itself
 * evaluates to zero. If the function is not zero and the gradient evaluates to
 * NaN, a std::domain_error is thrown
 *
 * @tparam F type of f
 * @tparam Args types of arguments to f
 * @param f function to compute gradients of
 * @param x location at which to evaluate gradients
 * @param xc complement of location (if bounded domain of integration)
 * @param n compute gradient with respect to nth parameter
 * @param msgs stream for messages
 * @param args other arguments to pass to f
 */
template <typename F, typename... Args>
inline double gradient_of_f(const F &f, const double &x, const double &xc,
                            size_t n, std::ostream *msgs,
                            const Args &... args) {
  double gradient = 0.0;

  // Run nested autodiff in this scope
  nested_rev_autodiff nested;

  auto args_tuple_local_copy = std::make_tuple(deep_copy_vars(args)...);

  Eigen::VectorXd adjoints = Eigen::VectorXd::Zero(count_vars(args...));

  var fx = apply(
      [&f, &x, &xc, msgs](auto &&... args) { return f(x, xc, msgs, args...); },
      args_tuple_local_copy);

  fx.grad();

  apply(
      [&](auto &&... args) {
        accumulate_adjoints(adjoints.data(),
                            std::forward<decltype(args)>(args)...);
      },
      std::move(args_tuple_local_copy));

  gradient = adjoints.coeff(n);
  if (is_nan(gradient)) {
    if (fx.val() == 0) {
      gradient = 0;
    } else {
      throw_domain_error("gradient_of_f", "The gradient of f", n,
                         "is nan for parameter ", "");
    }
  }

  return gradient;
}

/**
 * Return the integral of f from a to b to the given relative tolerance
 *
 * @tparam T_a type of first limit
 * @tparam T_b type of second limit
 * @tparam T_theta type of parameters
 * @tparam T Type of f
 *
 * @param f the functor to integrate
 * @param a lower limit of integration
 * @param b upper limit of integration
 * @param relative_tolerance relative tolerance passed to Boost quadrature
 * @param[in, out] msgs the print stream for warning messages
 * @param args additional arguments to pass to f
 * @return numeric integral of function f
 */
template <typename F, typename T_a, typename T_b, typename... Args,
          require_any_st_var<T_a, T_b, Args...> * = nullptr>
inline return_type_t<T_a, T_b, Args...> integrate_1d_impl(
    const F &f, const T_a &a, const T_b &b, double relative_tolerance,
    std::ostream *msgs, const Args &... args) {
  static const char *function = "integrate_1d";
  check_less_or_equal(function, "lower limit", a, b);<commit_msg>Updated docs<commit_after>#ifndef STAN_MATH_REV_FUNCTOR_integrate_1d_HPP
#define STAN_MATH_REV_FUNCTOR_integrate_1d_HPP

#include <stan/math/rev/meta.hpp>
#include <stan/math/rev/fun/is_nan.hpp>
#include <stan/math/rev/fun/value_of.hpp>
#include <stan/math/rev/core/precomputed_gradients.hpp>
#include <stan/math/prim/meta.hpp>
#include <stan/math/prim/err.hpp>
#include <stan/math/prim/fun/constants.hpp>
#include <stan/math/prim/functor/integrate_1d.hpp>
#include <cmath>
#include <functional>
#include <ostream>
#include <string>
#include <type_traits>
#include <vector>

namespace stan {
namespace math {

/**
 * Calculate first derivative of f(x, xc, msgs, args...)
 * with respect to the nth parameter in args. Uses nested reverse mode autodiff
 *
 * Gradients that evaluate to NaN are set to zero if the function itself
 * evaluates to zero. If the function is not zero and the gradient evaluates to
 * NaN, a std::domain_error is thrown
 *
 * @tparam F type of f
 * @tparam Args types of arguments to f
 * @param f function to compute gradients of
 * @param x location at which to evaluate gradients
 * @param xc complement of location (if bounded domain of integration)
 * @param n compute gradient with respect to nth parameter
 * @param msgs stream for messages
 * @param args other arguments to pass to f
 */
template <typename F, typename... Args>
inline double gradient_of_f(const F &f, const double &x, const double &xc,
                            size_t n, std::ostream *msgs,
                            const Args &... args) {
  double gradient = 0.0;

  // Run nested autodiff in this scope
  nested_rev_autodiff nested;

  auto args_tuple_local_copy = std::make_tuple(deep_copy_vars(args)...);

  Eigen::VectorXd adjoints = Eigen::VectorXd::Zero(count_vars(args...));

  var fx = apply(
      [&f, &x, &xc, msgs](auto &&... args) { return f(x, xc, msgs, args...); },
      args_tuple_local_copy);

  fx.grad();

  apply(
      [&](auto &&... args) {
        accumulate_adjoints(adjoints.data(),
                            std::forward<decltype(args)>(args)...);
      },
      std::move(args_tuple_local_copy));

  gradient = adjoints.coeff(n);
  if (is_nan(gradient)) {
    if (fx.val() == 0) {
      gradient = 0;
    } else {
      throw_domain_error("gradient_of_f", "The gradient of f", n,
                         "is nan for parameter ", "");
    }
  }

  return gradient;
}

/**
 * Return the integral of f from a to b to the given relative tolerance
 *
 * @tparam F Type of f
 * @tparam T_a type of first limit
 * @tparam T_b type of second limit
 * @tparam Args types of parameter pack arguments
 *
 * @param f the functor to integrate
 * @param a lower limit of integration
 * @param b upper limit of integration
 * @param relative_tolerance relative tolerance passed to Boost quadrature
 * @param[in, out] msgs the print stream for warning messages
 * @param args additional arguments to pass to f
 * @return numeric integral of function f
 */
template <typename F, typename T_a, typename T_b, typename... Args,
          require_any_st_var<T_a, T_b, Args...> * = nullptr>
inline return_type_t<T_a, T_b, Args...> integrate_1d_impl(
    const F &f, const T_a &a, const T_b &b, double relative_tolerance,
    std::ostream *msgs, const Args &... args) {
  static const char *function = "integrate_1d";
  check_less_or_equal(function, "lower limit", a, b);
{'fraction_non_alphanumeric': 0.11471284783895797, 'fraction_numerical': 0.0026642984014209592, 'mean_word_length': 3.3762953367875648, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2124117', 'n_tokens_mistral': 2220, 'n_tokens_neox': 2155, 'n_words': 719}