3 #ifndef COMMON_NCPFACTORS_HPP_ 4 #define COMMON_NCPFACTORS_HPP_ 30 bool freed_ncp_factors;
42 this->m_dimensions = i_dimensions;
43 this->m_modes = i_dimensions.n_rows;
44 ncp_factors =
new MAT[this->m_modes];
46 arma::arma_rng::set_seed(103);
47 for (
unsigned int i = 0; i < this->m_modes; i++) {
49 int rsize = (i_dimensions[i] > 0) ? i_dimensions[i] : 1;
51 ncp_factors[i] = arma::randu<MAT>(this->m_k, rsize);
55 ncp_factors[i] = arma::randu<MAT>(rsize, this->m_k);
58 m_lambda = arma::ones<VEC>(this->m_k);
59 freed_ncp_factors =
false;
88 if (!freed_ncp_factors) {
90 freed_ncp_factors =
true;
96 int rank()
const {
return m_k; }
100 MAT &
factor(
const int i_n)
const {
return ncp_factors[i_n]; }
102 int modes()
const {
return m_modes; }
112 void set(
const int i_n,
const MAT &i_factor) {
113 assert(i_factor.size() == this->ncp_factors[i_n].size());
114 this->ncp_factors[i_n] = i_factor;
124 MAT currentGram(this->m_k, this->m_k);
125 for (
unsigned int i = 0; i < this->m_modes; i++) {
126 currentGram = ncp_factors[i].t() * ncp_factors[i];
127 (*o_UtU) = (*o_UtU) % currentGram;
140 MAT currentGram(this->m_k, this->m_k);
141 (*o_UtU) = arma::ones<MAT>(this->m_k, this->m_k);
142 for (
unsigned int i = 0; i < this->m_modes; i++) {
144 currentGram = ncp_factors[i].t() * ncp_factors[i];
145 (*o_UtU) = (*o_UtU) % currentGram;
155 UWORD krpsize = arma::prod(this->m_dimensions);
156 krpsize /= this->m_dimensions[i_n];
157 MAT krp(krpsize, this->m_k);
175 UVEC matorder = arma::zeros<UVEC>(this->m_modes - 1);
177 for (
int i = this->m_modes - 1; i >= 0; i--) {
183 INFO <<
"::" << __PRETTY_FUNCTION__ <<
"::" << __LINE__
184 <<
"::matorder::" << matorder << std::endl;
223 for (
unsigned int n = 0; n < this->m_k; n++) {
224 MAT ab = ncp_factors[matorder[0]].col(n);
225 for (
unsigned int i = 1; i < this->m_modes - 1; i++) {
226 VEC oldabvec = arma::vectorise(ab);
227 VEC currentvec = ncp_factors[matorder[i]].col(n);
229 ab = currentvec * oldabvec.t();
231 (*o_krp).col(n) = arma::vectorise(ab);
243 UVEC matorder = arma::zeros<UVEC>(i_modes.n_rows - 1);
245 for (
int i = i_modes.n_rows - 1; i >= 0; i--) {
246 matorder(j++) = i_modes[i];
249 INFO <<
"::" << __PRETTY_FUNCTION__ <<
"::" << __LINE__
250 <<
"::matorder::" << matorder << std::endl;
253 for (
unsigned int n = 0; n < this->m_k; n++) {
254 MAT ab = ncp_factors[matorder[0]].col(n);
255 for (
unsigned int i = 1; i < i_modes.n_rows - 1; i++) {
256 VEC oldabvec = arma::vectorise(ab);
257 VEC currentvec = ncp_factors[matorder[i]].col(n);
259 ab = currentvec * oldabvec.t();
261 (*o_krp).col(n) = arma::vectorise(ab);
283 UWORD krpsize = arma::prod(this->m_dimensions);
284 krpsize /= this->m_dimensions[0];
285 MAT krpleavingzero = arma::zeros<MAT>(krpsize, this->m_k);
287 MAT lowranktensor(this->m_dimensions[0], krpsize);
288 lowranktensor = this->ncp_factors[0] * krpleavingzero.t();
289 Tensor rc(this->m_dimensions, lowranktensor.memptr());
297 INFO <<
"modes::" << this->m_modes <<
"::k::" << this->m_k << std::endl;
298 INFO <<
"lambda::" << this->m_lambda << std::endl;
299 INFO <<
"::dims::" << std::endl << this->m_dimensions << std::endl;
304 for (
unsigned int i = 0; i < this->m_modes; i++) {
305 std::cout << i <<
"th factor" << std::endl
306 <<
"=============" << std::endl;
307 std::cout << this->ncp_factors[i];
314 void print(
const unsigned int i_n) {
315 std::cout << i_n <<
"th factor" << std::endl
316 <<
"=============" << std::endl;
317 std::cout << this->ncp_factors[i_n];
324 for (
unsigned int i = 0; i < this->m_modes; i++) {
325 factor_t.
set(i, this->ncp_factors[i].t());
330 double colNorm = 0.0;
332 for (
unsigned int i = 0; i < this->m_modes; i++) {
333 for (
unsigned int j = 0; j < this->m_k; j++) {
334 colNorm = arma::norm(this->ncp_factors[i].col(j));
335 if (colNorm > 0) this->ncp_factors[i].col(j) /= colNorm;
336 m_lambda(j) *= colNorm;
347 for (
unsigned int i = 0; i < this->m_k; i++) {
348 m_lambda(i) = arma::norm(this->ncp_factors[mode].col(i));
349 if (m_lambda(i) > 0) this->ncp_factors[mode].col(i) /= m_lambda(i);
359 for (
unsigned int i = 0; i < this->m_k; i++) {
360 m_lambda(i) = arma::norm(this->ncp_factors[mode].row(i));
361 if (m_lambda(i) > 0) this->ncp_factors[mode].row(i) /= m_lambda(i);
372 arma::arma_rng::set_seed(i_seed);
373 for (
unsigned int i = 0; i < this->m_modes; i++) {
374 if (m_dimensions[i] > 0) {
375 ncp_factors[i].randu();
377 ncp_factors[i].zeros();
383 for (
unsigned int i = 0; i < this->m_modes; i++) {
384 ncp_factors[i].zeros();
394 void distributed_normalize() {
395 double local_colnorm;
396 double global_colnorm;
397 for (
unsigned int i = 0; i < this->m_modes; i++) {
398 for (
unsigned int j = 0; j < this->m_k; j++) {
399 local_colnorm = arma::norm(this->ncp_factors[i].col(j));
400 local_colnorm *= local_colnorm;
401 MPI_Allreduce(&local_colnorm, &global_colnorm, 1, MPI_DOUBLE, MPI_SUM,
403 global_colnorm = std::sqrt(global_colnorm);
404 if (global_colnorm > 0) this->ncp_factors[i].col(j) /= global_colnorm;
405 m_lambda(j) *= global_colnorm;
414 void distributed_normalize(
unsigned int mode) {
415 double local_colnorm;
416 double global_colnorm;
417 for (
unsigned int j = 0; j < this->m_k; j++) {
418 local_colnorm = arma::norm(this->ncp_factors[mode].col(j));
419 local_colnorm *= local_colnorm;
420 MPI_Allreduce(&local_colnorm, &global_colnorm, 1, MPI_DOUBLE, MPI_SUM,
422 global_colnorm = std::sqrt(global_colnorm);
423 if (global_colnorm > 0) this->ncp_factors[mode].col(j) /= global_colnorm;
424 m_lambda(j) = global_colnorm;
432 void distributed_normalize_rows(
unsigned int mode) {
433 double local_rownorm;
434 double global_rownorm;
435 for (
unsigned int j = 0; j < this->m_k; j++) {
436 local_rownorm = arma::norm(this->ncp_factors[mode].row(j));
437 local_rownorm *= local_rownorm;
438 MPI_Allreduce(&local_rownorm, &global_rownorm, 1, MPI_DOUBLE, MPI_SUM,
440 global_rownorm = std::sqrt(global_rownorm);
441 if (global_rownorm > 0) this->ncp_factors[mode].row(j) /= global_rownorm;
442 m_lambda(j) = global_rownorm;
449 #endif // COMMON_NCPFACTORS_HPP_
void normalize(int mode)
Column normalizes the factor matrix of the given mode and replaces the existing lambda.
void randu(const int i_seed)
initializes the local tensor with the given seed.
UVEC dimensions() const
dimensions of every mode
Data is stored such that the unfolding is column major.
NCPFactors(const UVEC &i_dimensions, const int &i_k, bool trans)
constructor that takes the dimensions of every mode, low rank k All the factors will be initialized w...
void print()
prints the entire NCPFactors including the factor matrices
void krp_leave_out_one(const unsigned int i_n, MAT *o_krp)
khatrirao leaving out one.
void gram_leave_out_one(const unsigned int i_n, MAT *o_UtU)
Returns the hadamard of the factor grams except i_n.
void printinfo()
prints just the information about the factors.
void rankk_tensor(Tensor &out)
Construct the rank k tensor out of the factor matrices Determine the KRP of the n-1 modes leaving out...
void normalize()
only during initialization. Reset's all lambda.
void trans(NCPFactors &factor_t)
Transposes the entire factor matrix.
void gram(MAT *o_UtU)
Return the hadamard of the factor grams.
void normalize_rows(unsigned int mode)
Row normalizes the factor matrix of the given mode and replaces the existing lambda.
MAT krp_leave_out_one(const unsigned int i_n)
KRP leaving out the mode i_n.
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 print(const unsigned int i_n)
print the ith factor matrix alone
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 krp(const UVEC i_modes, MAT *o_krp)
KRP of the given vector of modes.
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