8 #include <gsl/gsl_sf_gamma.h> 29 const auto x =
static_cast<size_t>(X.rows());
30 const auto y =
static_cast<size_t>(X.cols());
33 size_t nonnan_count = 0;
35 #pragma omp parallel for reduction(+:nonnan_sum,nonnan_count) 36 for (
size_t i = 0; i < x; ++i) {
37 for (
size_t j = 0; j < y; ++j) {
39 nonnan_sum += X(i, j);
45 if (nonnan_count != 0) {
46 const T nonnan_mean = nonnan_sum / nonnan_count;
48 #pragma omp parallel for schedule(static) 49 for (
size_t i = 0; i < x; ++i) {
50 for (
size_t j = 0; j < y; ++j) {
52 X(i, j) = nonnan_mean;
75 template <
typename Scalar>
79 const auto x =
static_cast<size_t>(param_vec[0].alpha.size());
80 const auto z =
static_cast<size_t>(param_vec.size());
85 #pragma omp parallel for schedule(static) 86 for (
size_t k = 0; k < z; ++k) {
87 for (
size_t i = 0; i < x; ++i) {
88 alpha(i, k) = param_vec[k].alpha[i];
91 for (
size_t j = 0; j < y; ++j) {
92 beta(k, j) = param_vec[k].beta[j];
118 template <
typename T>
122 const auto x =
static_cast<size_t>(X_full.rows());
123 const auto y =
static_cast<size_t>(X_full.cols());
145 for (
size_t t = 0; t < ii.
size(); ++t) {
146 size_t i = ii[t], j = jj[t];
148 gsl_ran_dirichlet(rnd_gen.
get(), z, dirichlet_params.data(),
149 fiber_double.data());
150 fiber = fiber_double.template cast<T>();
151 fiber = fiber.array() * X_full(i, j);
153 S_pjk_local.row(j) += fiber;
154 S_ipk_local.row(i) += fiber;
155 S_ppk_local += fiber;
161 S_pjk += S_pjk_local;
162 S_ipk += S_ipk_local;
163 S_ppk += S_ppk_local;
185 template <
typename T,
typename Scalar,
typename PsiFunction>
189 const auto x =
static_cast<size_t>(alpha.rows());
190 const auto z =
static_cast<size_t>(alpha.cols());
193 #pragma omp parallel for schedule(static) 194 for (
size_t k = 0; k < z; ++k) {
195 psi_of_sums(k) = psi_fn(alpha_pk(k) + S_ppk(k));
198 #pragma omp parallel for schedule(static) 199 for (
size_t i = 0; i < x; ++i) {
200 for (
size_t k = 0; k < z; ++k) {
201 logW(i, k) = psi_fn(alpha(i, k) + S_ipk(i, k)) - psi_of_sums(k);
220 template <
typename T,
typename Scalar,
typename PsiFunction>
222 const Scalar b,
const PsiFunction& psi_fn,
224 const auto z =
static_cast<size_t>(beta.rows());
225 const auto y =
static_cast<size_t>(beta.cols());
227 const Scalar logb =
std::log(b + 1);
229 #pragma omp parallel for schedule(static) 230 for (
size_t k = 0; k < z; ++k) {
231 for (
size_t j = 0; j < y; ++j) {
232 logH(k, j) = psi_fn(beta(k, j) + S_pjk(j, k)) - logb;
249 template <
typename T>
252 std::vector<size_t> ii, jj;
255 for (
long i = 0; i < X.rows(); ++i) {
256 for (
long j = 0; j < X.cols(); ++j) {
284 template <
typename T>
286 const std::vector<size_t>& jj,
290 const auto x =
static_cast<size_t>(res.
X_full.rows());
291 const auto y =
static_cast<size_t>(res.
X_full.cols());
292 const auto z =
static_cast<size_t>(S_ppk.cols());
306 double delta_log_PS_local = 0;
309 for (
size_t t = 0; t < xx.
size(); ++t) {
310 const size_t i = ii[t];
311 const size_t j = jj[t];
312 const T orig_x_ij = xx[t];
314 log_p = res.
logW.row(i) + res.
logH.col(j).transpose();
319 max_fiber = log_p_exp.array().floor();
320 res.
X_full(i, j) = max_fiber.sum();
325 S_pjk.row(j) += max_fiber;
326 S_ipk.row(i) += max_fiber;
327 S_ppk_local += max_fiber;
329 for (
size_t k = 0; k < z; ++k) {
330 gammaln_max_fiber(k) = gsl_sf_lngamma(max_fiber(k) + 1);
332 delta_log_PS_local -= gammaln_max_fiber.sum();
339 S_ppk += S_ppk_local;
340 delta_log_PS += delta_log_PS_local;
363 template <
typename T,
typename Scalar>
365 const matrix_t<T>& S_ipk,
const matrix_t<T>& S_pjk,
368 double delta = -(
std::log(b + 1) * S_ppk.sum());
370 #pragma omp parallel for schedule(static) reduction(+:delta) 371 for (
long k = 0; k < alpha.cols(); ++k) {
372 for (
long i = 0; i < alpha.rows(); ++i) {
373 delta += gsl_sf_lngamma(alpha(i, k) + S_ipk(i, k));
376 for (
long j = 0; j < beta.cols(); ++j) {
377 delta += gsl_sf_lngamma(beta(k, j) + S_pjk(j, k));
380 delta -= gsl_sf_lngamma(alpha_pk(k) + S_ppk(k));
Structure to hold the parameters for the Allocation Model .
Definition: alloc_model_params.hpp:25
void update_logH(const matrix_t< Scalar > &beta, const matrix_t< T > &S_pjk, const Scalar b, const PsiFunction &psi_fn, matrix_t< double > &logH)
Perform an update on logW matrix.
Definition: online_EM_funcs.hpp:221
EMResult< T > online_EM(const matrix_t< T > &X, const std::vector< alloc_model::Params< Scalar >> ¶m_vec, const size_t max_iter=1000, const bool use_psi_appr=false)
Complete a matrix containing unobserved values given as NaN using an EM procedure according to the al...
Definition: online_EM.hpp:50
double delta_log_PS(const matrix_t< Scalar > &alpha, const matrix_t< Scalar > &beta, const matrix_t< T > &S_ipk, const matrix_t< T > &S_pjk, const vector_t< Scalar > &alpha_pk, const vector_t< T > &S_ppk, Scalar b)
Compute the difference in log_PS value computed using the given model variables.
Definition: online_EM_funcs.hpp:364
Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > matrix_t
Matrix type used in the computations.
Definition: defs.hpp:41
Structure holding the results of EM procedures.
Definition: online_EM_defs.hpp:13
matrix_t< double > logH
Matrix whose entry contains .
Definition: online_EM_defs.hpp:41
std::tuple< std::vector< size_t >, std::vector< size_t >, std::vector< T > > find_nonzero(const matrix_t< T > &X)
Find nonzero entries and their indices in the given matrix and return indices and values as vectors...
Definition: online_EM_funcs.hpp:251
matrix_t< T > X_full
Completed version of the incomplete matrix given as input to an EM algorithm.
Definition: online_EM_defs.hpp:33
matrix_t< T > S_ipk
Sum of the hidden tensor along its second dimension, i.e. .
Definition: online_EM_defs.hpp:24
void multinomial_mode(Integer num_trials, const vector_t< Real > &prob, vector_t< Integer > &count, double eps=1e-50)
Find the mode of a multinomial distribution using Finucan's algorithm.
Definition: sampling.hpp:88
matrix_t< double > logW
Matrix whose entry contains .
Definition: online_EM_defs.hpp:37
matrix_t< T > S_pjk
Sum of the hidden tensor along its first dimension, i.e. .
Definition: online_EM_defs.hpp:19
size_t init_nan_values(matrix_t< T > &X)
Initialize all NaN values in the given matrix with the mean of the remaining values that are differen...
Definition: online_EM_funcs.hpp:28
std::tuple< matrix_t< T >, matrix_t< T >, vector_t< T > > init_S_xx(const matrix_t< T > &X_full, size_t z, const std::vector< size_t > &ii, const std::vector< size_t > &jj)
Initialize S_pjk, S_ipk matrices and S_ppk vector from a Dirichlet distribution with all parameters e...
Definition: online_EM_funcs.hpp:120
std::pair< matrix_t< Scalar >, matrix_t< Scalar > > init_alpha_beta(const std::vector< alloc_model::Params< Scalar >> ¶m_vec, size_t y)
Initialize each entry of alpha and beta matrices with the given model parameters. ...
Definition: online_EM_funcs.hpp:77
Eigen::Matrix< Scalar, 1, Eigen::Dynamic, Eigen::RowMajor > vector_t
Vector type used in the computations.
Definition: defs.hpp:27
Main namespace for bnmf-algs library.
Definition: alloc_model_funcs.hpp:12
double update_allocation(const std::vector< size_t > &ii, const std::vector< size_t > &jj, const std::vector< T > &xx, bld::EMResult< T > &res, vector_t< T > &S_ppk)
Update the current allocation by performing a maximization step for each nonzero entry of the origina...
Definition: online_EM_funcs.hpp:285
void update_logW(const matrix_t< Scalar > &alpha, const matrix_t< T > &S_ipk, const vector_t< Scalar > &alpha_pk, const vector_t< T > &S_ppk, const PsiFunction &psi_fn, matrix_t< double > &logW)
Perform an update on logW matrix.
Definition: online_EM_funcs.hpp:186