1 #ifndef STAN_MATH_REV_FUN_BESSEL_FIRST_KIND_HPP
2 #define STAN_MATH_REV_FUN_BESSEL_FIRST_KIND_HPP
3 
4 #include <stan/math/rev/meta.hpp>
5 #include <stan/math/rev/core.hpp>
6 #include <stan/math/prim/fun/bessel_first_kind.hpp>
7 
8 namespace stan {
9 namespace math {
10 
bessel_first_kind(int v,const var & a)11 inline var bessel_first_kind(int v, const var& a) {
12   auto ret_val = bessel_first_kind(v, a.val());
13   auto precomp_bessel
14       = v * ret_val / a.val() - bessel_first_kind(v + 1, a.val());
15   return make_callback_var(ret_val,
16                            [precomp_bessel, a](const auto& vi) mutable {
17                              a.adj() += vi.adj_ * precomp_bessel;
18                            });
19 }
20 
21 /**
22  * Overload with `var_value<Matrix>` for `int`, `std::vector<int>`, and
23  * `std::vector<std::vector<int>>`
24  */
25 template <typename T1, typename T2, require_st_integral<T1>* = nullptr,
26           require_eigen_t<T2>* = nullptr>
bessel_first_kind(const T1 & v,const var_value<T2> & a)27 inline auto bessel_first_kind(const T1& v, const var_value<T2>& a) {
28   auto ret_val = bessel_first_kind(v, a.val()).array().eval();
29   auto v_map = as_array_or_scalar(v);
30   auto precomp_bessel
31       = to_arena(v_map * ret_val / a.val().array()
32                  - bessel_first_kind(v_map + 1, a.val().array()));
33   return make_callback_var(
34       ret_val.matrix(), [precomp_bessel, a](const auto& vi) mutable {
35         a.adj().array() += vi.adj().array() * precomp_bessel;
36       });
37 }
38 
39 }  // namespace math
40 }  // namespace stan
41 #endif
42