Automatic Differentiation
 
Loading...
Searching...
No Matches
softmax.hpp
Go to the documentation of this file.
1#ifndef STAN_MATH_FWD_FUN_SOFTMAX_HPP
2#define STAN_MATH_FWD_FUN_SOFTMAX_HPP
3
11
12namespace stan {
13namespace math {
14
22template <typename T, require_std_vector_st<is_fvar, T>* = nullptr>
23inline auto softmax(T&& x) {
24 return apply_vector_unary<T>::apply(std::forward<T>(x), [](auto&& v) {
25 return softmax(std::forward<decltype(v)>(v));
26 });
27}
28
36template <typename Vec, require_eigen_vector_vt<is_fvar, Vec>* = nullptr>
37inline auto softmax(Vec&& x) {
38 using vec = std::decay_t<Vec>;
39 constexpr int Rows = vec::RowsAtCompileTime;
40 constexpr int Cols = vec::ColsAtCompileTime;
41 using T = typename value_type_t<vec>::Scalar;
42 decltype(auto) x_ref = to_ref(std::forward<Vec>(x));
43 if (x_ref.size() == 0) {
44 return Eigen::Matrix<fvar<T>, Rows, Cols>{};
45 }
46 const auto s = softmax(value_of(x_ref));
47 const auto d_in = x_ref.d();
48 const auto dot_sd = s.dot(d_in);
49 Eigen::Matrix<fvar<T>, Rows, Cols> result(x_ref.size());
50 result.val() = s;
51 result.d() = (s.array() * (d_in.array() - dot_sd)).matrix();
52 return result;
53}
54
55} // namespace math
56} // namespace stan
57#endif
typename value_type< T >::type value_type_t
Helper function for accessing underlying type.
T value_of(const fvar< T > &v)
Return the value of the specified variable.
Definition value_of.hpp:18
auto softmax(T &&x)
Return the softmax of each vector in a container of fvar values.
Definition softmax.hpp:23
ref_type_t< T && > to_ref(T &&a)
This evaluates expensive Eigen expressions.
Definition to_ref.hpp:18
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...