bnmf-algs
collapsed_gibbs.hpp
Go to the documentation of this file.
1 #pragma once
2 
4 #include "defs.hpp"
5 #include "util/sampling.hpp"
6 #include "util_details.hpp"
7 
8 namespace bnmf_algs {
9 namespace details {
20 template <typename T, typename Scalar> class CollapsedGibbsComputer {
21  public:
36  const matrix_t<T>& X, size_t z,
37  const alloc_model::Params<Scalar>& model_params, size_t max_iter,
38  double eps)
39  : model_params(model_params),
40  one_sampler_repl(util::sample_ones_replace(X, max_iter)),
41  one_sampler_no_repl(util::sample_ones_noreplace(X)),
42  U_ipk(matrix_t<T>::Zero(X.rows(), z)), U_ppk(vector_t<T>::Zero(z)),
43  U_pjk(matrix_t<T>::Zero(X.cols(), z)),
44  sum_alpha(std::accumulate(model_params.alpha.begin(),
45  model_params.alpha.end(), Scalar())),
46  eps(eps), rnd_gen(util::gsl_rng_wrapper(gsl_rng_alloc(gsl_rng_taus),
47  gsl_rng_free)) {}
48 
65  void operator()(size_t curr_step, tensor_t<T, 3>& S_prev) {
66  size_t i, j;
67  if (curr_step == 0) {
68  for (const auto& pair : one_sampler_no_repl) {
69  std::tie(i, j) = pair;
70  increment_sampling(i, j, S_prev);
71  }
72  } else {
73  std::tie(i, j) = *one_sampler_repl.begin();
74  ++one_sampler_repl.begin();
75  decrement_sampling(i, j, S_prev);
76  increment_sampling(i, j, S_prev);
77  }
78  }
79 
80  private:
94  void increment_sampling(size_t i, size_t j, tensor_t<T, 3>& S_prev) {
95  vector_t<T> prob(U_ppk.cols());
96  Eigen::Map<vector_t<T>> beta(model_params.beta.data(), 1,
97  model_params.beta.size());
98  std::vector<unsigned int> multinomial_sample(
99  static_cast<unsigned long>(U_ppk.cols()));
100 
101  vector_t<T> alpha_row = U_ipk.row(i).array() + model_params.alpha[i];
102  vector_t<T> beta_row = (U_pjk.row(j) + beta).array();
103  vector_t<T> sum_alpha_row = U_ppk.array() + sum_alpha;
104  prob = alpha_row.array() * beta_row.array() /
105  (sum_alpha_row.array() + eps);
106 
107  gsl_ran_multinomial(rnd_gen.get(), static_cast<size_t>(prob.cols()), 1,
108  prob.data(), multinomial_sample.data());
109  auto k = std::distance(multinomial_sample.begin(),
110  std::max_element(multinomial_sample.begin(),
111  multinomial_sample.end()));
112 
113  ++S_prev(i, j, k);
114  ++U_ipk(i, k);
115  ++U_ppk(k);
116  ++U_pjk(j, k);
117  }
118 
133  void decrement_sampling(size_t i, size_t j, tensor_t<T, 3>& S_prev) {
134  vector_t<T> prob(U_ppk.cols());
135  Eigen::Map<vector_t<T>> beta(model_params.beta.data(), 1,
136  model_params.beta.size());
137  std::vector<unsigned int> multinomial_sample(
138  static_cast<unsigned long>(U_ppk.cols()));
139 
140  // todo: can we take a fiber from S with contiguous memory?
141  for (long k = 0; k < S_prev.dimension(2); ++k) {
142  prob(k) = S_prev(i, j, k);
143  }
144 
145  gsl_ran_multinomial(rnd_gen.get(), static_cast<size_t>(prob.cols()), 1,
146  prob.data(), multinomial_sample.data());
147  auto k = std::distance(multinomial_sample.begin(),
148  std::max_element(multinomial_sample.begin(),
149  multinomial_sample.end()));
150 
151  --S_prev(i, j, k);
152  --U_ipk(i, k);
153  --U_ppk(k);
154  --U_pjk(j, k);
155  }
156 
157  private:
158  alloc_model::Params<Scalar> model_params;
159  // computation variables
160  private:
162  one_sampler_repl;
165  one_sampler_no_repl;
166  matrix_t<T> U_ipk;
167  vector_t<T> U_ppk;
168  matrix_t<T> U_pjk;
169  T sum_alpha;
170  double eps;
171  util::gsl_rng_wrapper rnd_gen;
172 };
173 } // namespace details
174 
175 namespace bld {
216 template <typename T, typename Scalar>
218 collapsed_gibbs(const matrix_t<T>& X, size_t z,
219  const alloc_model::Params<Scalar>& model_params,
220  size_t max_iter = 1000, double eps = 1e-50) {
221  details::check_bld_params(X, z, model_params);
222 
223  tensor_t<T, 3> init_val(X.rows(), X.cols(), z);
224  init_val.setZero();
225 
227  gen(init_val, max_iter + 2,
229  max_iter, eps));
230 
231  ++gen.begin();
232 
233  return gen;
234 }
235 } // namespace bld
236 } // namespace bnmf_algs
Structure to hold the parameters for the Allocation Model .
Definition: alloc_model_params.hpp:25
T distance(T...args)
A template generator that generates values from an initial value by applying a computation to the pre...
Definition: generator.hpp:279
T tie(T...args)
util::Generator< std::pair< int, int >, details::SampleOnesNoReplaceComputer< T > > sample_ones_noreplace(const matrix_t< T > &X)
Return a bnmf_algs::util::Generator that will generate a sequence of samples from the given matrix wi...
Definition: sampling.hpp:526
Eigen::Tensor< Scalar, N, Eigen::RowMajor > tensor_t
Tensor type used in the computations.
Definition: defs.hpp:52
Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > matrix_t
Matrix type used in the computations.
Definition: defs.hpp:41
T max_element(T...args)
util::Generator< std::pair< int, int >, details::SampleOnesReplaceComputer< T > > sample_ones_replace(const matrix_t< T > &X, size_t num_samples)
Return a bnmf_algs::util::Generator that will generate a sequence of samples from the given matrix wi...
Definition: sampling.hpp:567
iter_type begin()
Return the iterator pointing to the previously computed value.
Definition: generator.hpp:421
Computer type that will compute the next collapsed gibbs sample when its operator() is invoked...
Definition: collapsed_gibbs.hpp:20
void operator()(size_t curr_step, tensor_t< T, 3 > &S_prev)
Function call operator that will compute the next tensor sample from the previous sample...
Definition: collapsed_gibbs.hpp:65
T get(T...args)
std::unique_ptr< gsl_rng, decltype(&gsl_rng_free)> gsl_rng_wrapper
RAII wrapper around gsl_rng types.
Definition: defs.hpp:73
void check_bld_params(const matrix_t< T > &X, size_t z, const alloc_model::Params< Scalar > &model_params)
Do parameter checks on BLD computing function parameters and throw an assertion error if the paramete...
Definition: util_details.hpp:20
util::Generator< tensor_t< T, 3 >, details::CollapsedGibbsComputer< T, Scalar > > collapsed_gibbs(const matrix_t< T > &X, size_t z, const alloc_model::Params< Scalar > &model_params, size_t max_iter=1000, double eps=1e-50)
Compute a sequence of tensors using Collapsed Gibbs Sampler method.
Definition: collapsed_gibbs.hpp:218
CollapsedGibbsComputer(const matrix_t< T > &X, size_t z, const alloc_model::Params< Scalar > &model_params, size_t max_iter, double eps)
Construct a new CollapsedGibbsComputer.
Definition: collapsed_gibbs.hpp:35
Computer type that will compute the next sample from a given matrix with replacement when its operato...
Definition: sampling.hpp:426
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
Computer type that will compute the next sample from a given matrix without replacement when its oper...
Definition: sampling.hpp:279