Automatic Differentiation
 
Loading...
Searching...
No Matches
bessel_second_kind.hpp
Go to the documentation of this file.
1#ifndef STAN_MATH_REV_FUN_BESSEL_SECOND_KIND_HPP
2#define STAN_MATH_REV_FUN_BESSEL_SECOND_KIND_HPP
3
7
8namespace stan {
9namespace math {
10
11template <typename T1, typename T2, require_integral_t<T1>* = nullptr,
12 require_var_t<T2>* = nullptr, require_stan_scalar_t<T2>* = nullptr>
13inline var bessel_second_kind(T1&& v, T2&& a) {
14 double ret_val = bessel_second_kind(v, a.val());
15 auto precomp_bessel
16 = v * ret_val / a.val() - bessel_second_kind(v + 1, a.val());
17 return make_callback_var(ret_val, [precomp_bessel, a](auto& vi) mutable {
18 a.adj() += vi.adj() * precomp_bessel;
19 });
20}
21
26template <typename T1, typename T2, require_st_integral<T1>* = nullptr,
27 require_var_matrix_t<T2>* = nullptr>
28inline auto bessel_second_kind(T1&& v, T2&& a) {
29 auto ret_val = bessel_second_kind(v, a.val()).array().eval();
30 auto v_map = as_array_or_scalar(v);
31 auto precomp_bessel
32 = to_arena(v_map * ret_val / a.val().array()
33 - bessel_second_kind(v_map + 1, a.val().array()));
34 return make_callback_var(
35 ret_val.matrix(), [precomp_bessel, a](const auto& vi) mutable {
36 a.adj().array() += vi.adj().array() * precomp_bessel;
37 });
38}
39
40} // namespace math
41} // namespace stan
42#endif
T as_array_or_scalar(T &&v)
Returns specified input value.
var_value< plain_type_t< T > > make_callback_var(T &&value, F &&functor)
Creates a new var initialized with a callback_vari with a given value and reverse-pass callback funct...
arena_t< T > to_arena(const T &a)
Converts given argument into a type that either has any dynamic allocation on AD stack or schedules i...
Definition to_arena.hpp:25
fvar< T > bessel_second_kind(int v, const fvar< T > &z)
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...