3 #ifndef NTF_NTFNES_HPP_ 4 #define NTF_NTFNES_HPP_ 27 inline double get_lambda(
double L,
double mu) {
41 inline double get_alpha(
double alpha,
double q) {
47 b = alpha * alpha - q;
49 D = b * b - 4 * a * c;
50 x = (-b + sqrt(D)) / 2;
54 bool stop_iter(
const int mode) {
58 absmax = (arma::abs(m_grad_t.
factor(mode) % m_acc_t.
factor(mode))).max();
59 amin = (m_grad_t.
factor(mode)).min();
61 if (absmax <= delta1 && amin >= -delta2) stop =
true;
68 if (iter > acc_start) {
69 int num_modes = m_prox_t.
modes();
72 double acc_step = std::pow(iter + 1, (1.0 / acc_exp));
76 int lowrank = m_prox_t.
rank();
77 MAT scalecur = arma::eye<MAT>(lowrank, lowrank);
78 MAT scaleprev = arma::eye<MAT>(lowrank, lowrank);
79 for (
int mode = 0; mode < num_modes; mode++) {
81 if (mode == num_modes - 1) {
82 scalecur = arma::diagmat(this->m_ncp_factors.lambda());
83 scaleprev = arma::diagmat(m_prev_t.
lambda());
87 acc_mat = (scalecur * this->m_ncp_factors.factor(mode).t()) -
88 (scaleprev * m_prev_t.
factor(mode));
90 acc_mat += (scalecur * this->m_ncp_factors.factor(mode).t());
91 m_acc_t.
set(mode, acc_mat);
98 if (acc_err < cur_err) {
100 for (
int mode = 0; mode < num_modes; mode++) {
101 m_prox_t.
set(mode, m_acc_t.
factor(mode));
104 INFO <<
"Acceleration Successful::relative_error::" << acc_err
108 this->
reset(m_prox_t,
true);
110 if (acc_fails > fail_limit) {
114 INFO <<
"Acceleration Failed::relative_error::" << acc_err << std::endl;
119 MAT update(
const int mode) {
120 double L, mu, lambda, q, alpha, alpha_prev, beta;
124 m_prev_t.
set(mode, m_prox_t.
factor(mode));
127 m_acc_t.
set(mode, Ht);
128 modified_gram = this->gram_without_one;
130 VEC eigval = arma::eig_sym(modified_gram);
133 lambda = get_lambda(L, mu);
134 modified_gram.diag() += lambda;
136 q = (mu + lambda) / (L + lambda);
138 MAT modified_local_mttkrp_t =
139 (-1 * lambda) * m_acc_t.
factor(mode) - this->ncp_mttkrp_t[mode];
146 m_grad_t.
set(mode, modified_local_mttkrp_t +
147 (modified_gram * m_acc_t.
factor(mode)));
148 if (stop_iter(mode))
break;
151 Ht = m_acc_t.
factor(mode) - ((1 / (L + lambda)) * m_grad_t.
factor(mode));
153 Ht.for_each([](MAT::elem_type &val) { val = val > 0.0 ? val : 0.0; });
155 alpha = get_alpha(alpha_prev, q);
157 (alpha_prev * (1 - alpha_prev)) / (alpha + alpha_prev * alpha_prev);
158 m_acc_t.
set(mode, Ht + beta * (Ht - Htprev));
161 m_prox_t.
set(mode, Ht);
169 :
AUNTF(i_tensor, i_k, i_algo),
170 m_prox_t(i_tensor.dimensions(), i_k, true),
171 m_acc_t(i_tensor.dimensions(), i_k, true),
172 m_grad_t(i_tensor.dimensions(), i_k, true),
173 m_prev_t(i_tensor.dimensions(), i_k, true) {
178 modified_gram.zeros(i_k, i_k);
191 #endif // NTF_NTFNES_HPP_ double current_error() const
Data is stored such that the unfolding is column major.
void accelerated(const bool &set_acceleration)
#define EPSILON_1EMINUS16
double computeObjectiveError()
void normalize_rows(unsigned int mode)
Row normalizes the factor matrix of the given mode and replaces the existing lambda.
NTFNES(const Tensor &i_tensor, const int i_k, algotype i_algo)
VEC lambda() const
returns the lambda vector
void set(const int i_n, const MAT &i_factor)
Set the mode i_n with the given factor matrix.
void set_lambda(const VEC &new_lambda)
sets the lambda vector
int rank() const
returns low rank
int modes() const
returns number of modes
void zeros()
this is for reinitializing zeros across different processors.
void reset(const NCPFactors &new_factors, bool trans=false)
ncp_factors contains the factors of the ncp every ith factor is of size n_i * k number of factors is ...
MAT & factor(const int i_n) const
factor matrix of a mode i_n