Automatic Differentiation
 
Loading...
Searching...
No Matches
softmax.hpp
Go to the documentation of this file.
1#ifndef STAN_MATH_REV_FUN_SOFTMAX_HPP
2#define STAN_MATH_REV_FUN_SOFTMAX_HPP
3
13#include <tuple>
14#include <vector>
15
16namespace stan {
17namespace math {
18
27template <typename Mat, require_rev_matrix_t<Mat>* = nullptr>
28inline auto softmax(const Mat& alpha) {
29 using mat_plain = plain_type_t<Mat>;
30 using ret_type = return_var_matrix_t<Mat>;
31 if (alpha.size() == 0) {
32 return ret_type(alpha);
33 }
34 arena_t<mat_plain> alpha_arena = alpha;
35 arena_t<Eigen::VectorXd> res_val = softmax(value_of(alpha_arena));
36 arena_t<ret_type> res = res_val;
37
38 reverse_pass_callback([res_val, res, alpha_arena]() mutable {
39 const auto& res_adj = to_ref(res.adj());
40 alpha_arena.adj()
41 += -res_val * res_adj.dot(res_val) + res_val.cwiseProduct(res_adj);
42 });
43
44 return ret_type(res);
45}
46
47} // namespace math
48} // namespace stan
49#endif
void reverse_pass_callback(F &&functor)
Puts a callback on the autodiff stack to be called in reverse pass.
auto softmax(const ColVec &alpha)
Definition softmax.hpp:16
T value_of(const fvar< T > &v)
Return the value of the specified variable.
Definition value_of.hpp:18
ref_type_t< T && > to_ref(T &&a)
This evaluates expensive Eigen expressions.
Definition to_ref.hpp:17
typename plain_type< T >::type plain_type_t
typename internal::arena_type_impl< std::decay_t< T > >::type arena_t
Determines a type that can be used in place of T that does any dynamic allocations on the AD stack.
std::conditional_t< is_any_var_matrix< ReturnType, Types... >::value, stan::math::var_value< stan::math::promote_scalar_t< double, plain_type_t< ReturnType > > >, stan::math::promote_scalar_t< stan::math::var_value< double >, plain_type_t< ReturnType > > > return_var_matrix_t
Given an Eigen type and several inputs, determine if a matrix should be var<Matrix> or Matrix<var>.
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...