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
12#include <tuple>
13#include <vector>
14
15namespace stan {
16namespace math {
17
26template <typename Mat, require_rev_matrix_t<Mat>* = nullptr>
27inline auto softmax(const Mat& alpha) {
28 using mat_plain = plain_type_t<Mat>;
29 using ret_type = return_var_matrix_t<Mat>;
30 if (alpha.size() == 0) {
31 return ret_type(alpha);
32 }
33 arena_t<mat_plain> alpha_arena = alpha;
34 arena_t<Eigen::VectorXd> res_val = softmax(value_of(alpha_arena));
35 arena_t<ret_type> res = res_val;
36
37 reverse_pass_callback([res_val, res, alpha_arena]() mutable {
38 const auto& res_adj = to_ref(res.adj());
39 alpha_arena.adj()
40 += -res_val * res_adj.dot(res_val) + res_val.cwiseProduct(res_adj);
41 });
42
43 return ret_type(res);
44}
45
46} // namespace math
47} // namespace stan
48#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:15
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 ...