planc
Parallel Lowrank Approximation with Non-negativity Constraints
ntfaoadmm.hpp
Go to the documentation of this file.
1 /* Copyright Ramakrishnan Kannan 2018 */
2 
3 #ifndef NTF_NTFAOADMM_HPP_
4 #define NTF_NTFAOADMM_HPP_
5 
6 #include "ntf/auntf.hpp"
7 
8 namespace planc {
9 
10 class NTFAOADMM : public AUNTF {
11  private:
12  // ADMM auxiliary variables
13  NCPFactors m_ncp_aux;
14  NCPFactors m_ncp_aux_t;
15  NCPFactors m_temp_ncp_aux_t;
16  MAT L;
17  MAT Lt;
18  MAT tempgram;
19  int admm_iter;
20  double tolerance;
21 
22  protected:
23  MAT update(const int mode) {
24  // return variable
25  MAT updated_fac(this->m_ncp_factors.factor(mode));
26  MAT prev_fac = updated_fac;
27 
28  // Set up ADMM iteration
29  double alpha =
30  arma::trace(this->gram_without_one) / this->m_ncp_factors.rank();
31  alpha = (alpha > 0) ? alpha : 0.01;
32  tempgram = this->gram_without_one;
33  tempgram.diag() += alpha;
34  L = arma::chol(tempgram, "lower");
35  Lt = L.t();
36  bool stop_iter = false;
37 
38  // Start ADMM loop from here
39  for (int i = 0; i < admm_iter && !stop_iter; i++) {
40  prev_fac = updated_fac;
41  m_ncp_aux_t.set(mode, m_ncp_aux.factor(mode).t());
42 
43  m_temp_ncp_aux_t.set(
44  mode, arma::solve(arma::trimatl(L),
45  this->ncp_mttkrp_t[mode] +
46  (alpha * (updated_fac.t() +
47  m_ncp_aux_t.factor(mode)))));
48  m_ncp_aux_t.set(
49  mode, arma::solve(arma::trimatu(Lt), m_temp_ncp_aux_t.factor(mode)));
50 
51  // Update factor matrix
52  updated_fac = m_ncp_aux_t.factor(mode).t();
53  fixNumericalError<MAT>(&(updated_fac), EPSILON_1EMINUS16);
54  updated_fac = updated_fac - m_ncp_aux.factor(mode);
55  updated_fac.for_each(
56  [](MAT::elem_type &val) { val = val > 0.0 ? val : 0.0; });
57 
58  // Update dual variable
59  m_ncp_aux.set(mode, m_ncp_aux.factor(mode) + updated_fac -
60  m_ncp_aux_t.factor(mode).t());
61 
62  // factor norm
63  double facnorm = arma::norm(updated_fac, "fro");
64 
65  // dual norm
66  double dualnorm = arma::norm(m_ncp_aux.factor(mode), "fro");
67 
68  // Check stopping criteria
69  double r = norm(updated_fac.t() - m_ncp_aux_t.factor(mode), "fro");
70  double s = norm(updated_fac - prev_fac, "fro");
71  if (r < (tolerance * facnorm) && s < (tolerance * dualnorm))
72  stop_iter = true;
73  }
74  m_ncp_aux.normalize(mode);
75  return updated_fac.t();
76  }
77 
78  public:
79  NTFAOADMM(const Tensor &i_tensor, const int i_k, algotype i_algo)
80  : AUNTF(i_tensor, i_k, i_algo),
81  m_ncp_aux(i_tensor.dimensions(), i_k, false),
82  m_ncp_aux_t(i_tensor.dimensions(), i_k, true),
83  m_temp_ncp_aux_t(i_tensor.dimensions(), i_k, true) {
84  m_ncp_aux.zeros();
85  m_ncp_aux_t.zeros();
86  m_temp_ncp_aux_t.zeros();
87  L.zeros(i_k, i_k);
88  Lt.zeros(i_k, i_k);
89  tempgram.zeros(i_k, i_k);
90  admm_iter = 5;
91  tolerance = 0.01;
92  }
93 }; // class NTFAOADMM
94 
95 } // namespace planc
96 
97 #endif // NTF_NTFAOADMM_HPP_
NTFAOADMM(const Tensor &i_tensor, const int i_k, algotype i_algo)
Definition: ntfaoadmm.hpp:79
Data is stored such that the unfolding is column major.
Definition: tensor.hpp:32
#define EPSILON_1EMINUS16
Definition: utils.h:43
void normalize()
only during initialization. Reset&#39;s all lambda.
Definition: ncpfactors.hpp:329
algotype
Definition: utils.h:10
void set(const int i_n, const MAT &i_factor)
Set the mode i_n with the given factor matrix.
Definition: ncpfactors.hpp:112
#define MAT
Definition: utils.h:52
void zeros()
this is for reinitializing zeros across different processors.
Definition: ncpfactors.hpp:382
ncp_factors contains the factors of the ncp every ith factor is of size n_i * k number of factors is ...
Definition: ncpfactors.hpp:20
MAT & factor(const int i_n) const
factor matrix of a mode i_n
Definition: ncpfactors.hpp:100