@@ -51,6 +51,10 @@ return_type_t<T_y, T_dof, T_loc, T_scale> multi_student_t_cholesky_lpdf(
51
51
using Eigen::Matrix;
52
52
using std::log ;
53
53
using std::vector;
54
+ using T_y_ref = ref_type_t <T_y>;
55
+ using T_mu_ref = ref_type_t <T_loc>;
56
+ using T_L_ref = ref_type_t <T_scale>;
57
+
54
58
static const char * function = " multi_student_t_cholesky" ;
55
59
check_not_nan (function, " Degrees of freedom parameter" , nu);
56
60
check_positive (function, " Degrees of freedom parameter" , nu);
@@ -61,20 +65,25 @@ return_type_t<T_y, T_dof, T_loc, T_scale> multi_student_t_cholesky_lpdf(
61
65
62
66
check_consistent_sizes_mvt (function, " y" , y, " mu" , mu);
63
67
64
- vector_seq_view<T_y> y_vec (y);
65
- vector_seq_view<T_loc> mu_vec (mu);
66
- size_t size_vec = max_size_mvt (y, mu);
68
+ T_y_ref y_ref = y;
69
+ T_mu_ref mu_ref = mu;
70
+ T_L_ref L_ref = L;
71
+
72
+ vector_seq_view<T_y_ref> y_vec (y_ref);
73
+ vector_seq_view<T_mu_ref> mu_vec (mu_ref);
74
+ size_t size_vec = max_size_mvt (y_ref, mu_ref);
75
+
67
76
if (size_vec == 0 ) {
68
- return 0 ;
77
+ return lp_type ( 0 ) ;
69
78
}
70
79
71
- for (size_t i = 1 , size_mvt_y = size_mvt (y) ; i < size_mvt_y; i++) {
80
+ for (size_t i = 1 , size_mvt_y = num_y ; i < size_mvt_y; i++) {
72
81
check_size_match (
73
82
function, " Size of one of the vectors of the random variable" ,
74
83
y_vec[i].size (), " Size of another vector of the random variable" ,
75
84
y_vec[i - 1 ].size ());
76
85
}
77
- for (size_t i = 1 , size_mvt_mu = size_mvt (mu) ; i < size_mvt_mu; i++) {
86
+ for (size_t i = 1 , size_mvt_mu = num_mu ; i < size_mvt_mu; i++) {
78
87
check_size_match (function,
79
88
" Size of one of the vectors "
80
89
" of the location variable" ,
@@ -95,31 +104,31 @@ return_type_t<T_y, T_dof, T_loc, T_scale> multi_student_t_cholesky_lpdf(
95
104
check_size_match (function, " Size of random variable" , num_dims,
96
105
" columns of scale parameter" , L.cols ());
97
106
98
- if (num_dims == 0 ) {
99
- return 0 ;
107
+ if (unlikely ( num_dims == 0 ) ) {
108
+ return lp_type ( 0 ) ;
100
109
}
101
110
102
111
for (size_t i = 0 ; i < size_vec; i++) {
103
112
check_finite (function, " Location parameter" , mu_vec[i]);
104
113
check_not_nan (function, " Random variable" , y_vec[i]);
105
114
}
106
115
107
- check_cholesky_factor (function, " scale parameter" , L );
116
+ check_cholesky_factor (function, " scale parameter" , L_ref );
108
117
109
118
lp_type lp (0 );
110
119
111
120
if (include_summand<propto, T_dof>::value) {
112
121
lp += lgamma (0.5 * (nu + num_dims)) * size_vec;
113
- lp -= lgamma (0.5 * nu) * size_vec;
114
- lp -= (0.5 * num_dims) * log (nu) * size_vec;
122
+ lp += - lgamma (0.5 * nu) * size_vec;
123
+ lp += - (0.5 * num_dims) * log (nu) * size_vec;
115
124
}
116
125
117
126
if (include_summand<propto>::value) {
118
- lp -= (0.5 * num_dims) * LOG_PI * size_vec;
127
+ lp += - (0.5 * num_dims) * LOG_PI * size_vec;
119
128
}
120
129
121
130
if (include_summand<propto, T_scale_elem>::value) {
122
- lp -= sum (stan::math::log (L .diagonal ())) * size_vec;
131
+ lp += - sum (stan::math::log (L_ref .diagonal ())) * size_vec;
123
132
}
124
133
125
134
if (include_summand<propto, T_y, T_dof, T_loc, T_scale_elem>::value) {
@@ -129,10 +138,9 @@ return_type_t<T_y, T_dof, T_loc, T_scale> multi_student_t_cholesky_lpdf(
129
138
const auto & y_col = as_column_vector_or_scalar (y_vec[i]);
130
139
const auto & mu_col = as_column_vector_or_scalar (mu_vec[i]);
131
140
sum_lp_vec += log1p (
132
- dot_self (mdivide_left_tri<Eigen::Lower>(L , y_col - mu_col)) / nu);
141
+ dot_self (mdivide_left_tri<Eigen::Lower>(L_ref , y_col - mu_col)) / nu);
133
142
}
134
-
135
- lp -= 0.5 * (nu + num_dims) * sum_lp_vec;
143
+ lp += -0.5 * (nu + num_dims) * sum_lp_vec;
136
144
}
137
145
return lp;
138
146
}
0 commit comments