1 #ifndef STAN__AGRAD__REV__MATRIX__LOG_SOFTMAX_HPP
2 #define STAN__AGRAD__REV__MATRIX__LOG_SOFTMAX_HPP
18 class log_softmax_elt_vari :
public vari {
25 log_softmax_elt_vari(
double val,
27 const double* softmax_alpha,
37 for (
int m = 0; m <
size_; ++m) {
59 inline Eigen::Matrix<var,Eigen::Dynamic,1>
60 log_softmax(
const Eigen::Matrix<var,Eigen::Dynamic,1>& alpha) {
66 if (alpha.size() == 0)
67 throw std::domain_error(
"arg vector to log_softmax() must have size > 0");
68 if (alpha.size() == 0)
69 throw std::domain_error(
"arg vector to log_softmax() must have size > 0");
71 if (alpha.size() == 0)
72 throw std::domain_error(
"arg vector to log_softmax() must have size > 0");
75 = (
vari**) agrad::chainable::operator
new(
sizeof(
vari*) * alpha.size());
76 for (
int i = 0; i < alpha.size(); ++i)
77 alpha_vi_array[i] = alpha(i).vi_;
80 Matrix<double,Dynamic,1> alpha_d(alpha.size());
81 for (
int i = 0; i < alpha_d.size(); ++i)
82 alpha_d(i) = alpha(i).val();
86 Matrix<double,Dynamic,1> softmax_alpha_d(alpha_d.size());
87 Matrix<double,Dynamic,1> log_softmax_alpha_d(alpha_d.size());
89 double max_v = alpha_d.maxCoeff();
92 for (
int i = 0; i < alpha_d.size(); ++i) {
93 softmax_alpha_d(i) =
std::exp(alpha_d(i) - max_v);
94 sum += softmax_alpha_d(i);
97 for (
int i = 0; i < alpha_d.size(); ++i)
98 softmax_alpha_d(i) /=
sum;
101 for (
int i = 0; i < alpha_d.size(); ++i)
102 log_softmax_alpha_d(i) = (alpha_d(i) - max_v) - log_sum;
106 double* softmax_alpha_d_array
107 = (
double*) agrad::chainable::operator
new(
sizeof(
double) * alpha_d.size());
109 for (
int i = 0; i < alpha_d.size(); ++i)
110 softmax_alpha_d_array[i] = softmax_alpha_d(i);
112 Matrix<var,Dynamic,1> log_softmax_alpha(alpha.size());
113 for (
int k = 0; k < log_softmax_alpha.size(); ++k)
114 log_softmax_alpha(k) =
var(
new log_softmax_elt_vari(log_softmax_alpha_d[k],
116 softmax_alpha_d_array,
119 return log_softmax_alpha;
Eigen::Matrix< fvar< T >, Eigen::Dynamic, 1 > log_softmax(const Eigen::Matrix< fvar< T >, Eigen::Dynamic, 1 > &alpha)
fvar< T > sum(const Eigen::Matrix< fvar< T >, R, C > &m)
The variable implementation base class.
Independent (input) and dependent (output) variables for gradients.
int size(const std::vector< T > &x)
const double * softmax_alpha_
fvar< T > log(const fvar< T > &x)
fvar< T > exp(const fvar< T > &x)
bool check_nonzero_size(const char *function, const T_y &y, const char *name, T_result *result)
Return true if the specified matrix/vector is of non-zero size.