SHOGUN  4.2.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
UWedge.cpp
Go to the documentation of this file.
2 
3 
4 #include <shogun/base/init.h>
5 
8 
9 using namespace shogun;
10 using namespace Eigen;
11 
13  double eps, int itermax)
14 {
15  int d = C.dims[0];
16  int L = C.dims[2];
17 
19  if (V0.num_rows == d && V0.num_cols == d)
20  {
21  V = V0.clone();
22  }
23  else
24  {
25  Map<MatrixXd> C0(C.get_matrix(0),d,d);
26  EigenSolver<MatrixXd> eig;
27  eig.compute(C0);
28 
29  // sort eigenvectors
30  MatrixXd eigenvectors = eig.pseudoEigenvectors();
31  MatrixXd eigenvalues = eig.pseudoEigenvalueMatrix();
32 
33  bool swap = false;
34  do
35  {
36  swap = false;
37  for (int j = 1; j < d; j++)
38  {
39  if ( eigenvalues(j,j) > eigenvalues(j-1,j-1) )
40  {
41  std::swap(eigenvalues(j,j),eigenvalues(j-1,j-1));
42  eigenvectors.col(j).swap(eigenvectors.col(j-1));
43  swap = true;
44  }
45  }
46 
47  } while(swap);
48 
50  Map<MatrixXd> EV(V.matrix, d,d);
51  EV = eigenvalues.cwiseAbs().cwiseSqrt().inverse() * eigenvectors.transpose();
52  }
53  Map<MatrixXd> EV(V.matrix, d,d);
54 
55  index_t * Cs_dims = SG_MALLOC(index_t, 3);
56  Cs_dims[0] = d;
57  Cs_dims[1] = d;
58  Cs_dims[2] = L;
59  SGNDArray<float64_t> Cs(Cs_dims,3);
60  memcpy(Cs.array, C.array, Cs.dims[0]*Cs.dims[1]*Cs.dims[2]*sizeof(float64_t));
61 
62  MatrixXd Rs(d,L);
63  std::vector<float64_t> crit;
64  crit.push_back(0.0);
65  for (int l = 0; l < L; l++)
66  {
67  Map<MatrixXd> Ci(C.get_matrix(l),d,d);
68  Map<MatrixXd> Csi(Cs.get_matrix(l),d,d);
69  Ci = 0.5 * (Ci + Ci.transpose());
70  Csi = EV * Ci * EV.transpose();
71  Rs.col(l) = Csi.diagonal();
72  crit.back() += Csi.cwiseAbs2().sum() - Rs.col(l).cwiseAbs2().sum();
73  }
74 
75  float64_t iter = 0;
76  float64_t improve = 10;
77  while (improve > eps && iter < itermax)
78  {
79  MatrixXd B = Rs * Rs.transpose();
80 
81  MatrixXd C1 = MatrixXd::Zero(d,d);
82  for (int id = 0; id < d; id++)
83  {
84  // rowSums
85  for (int l = 0; l < L; l++)
86  {
87  Map<MatrixXd> Csi(Cs.get_matrix(l),d,d);
88  C1.row(id) += Csi.row(id) * Rs(id,l);
89  }
90  }
91 
92  MatrixXd D0 = B.cwiseProduct(B.transpose()) - B.diagonal() * B.diagonal().transpose();
93  MatrixXd A0 = MatrixXd::Identity(d,d) + (C1.cwiseProduct(B) - B.diagonal().asDiagonal() * C1.transpose()).cwiseQuotient(D0+MatrixXd::Identity(d,d));
94  EV = A0.inverse() * EV;
95 
96  Map<MatrixXd> C0(C.get_matrix(0),d,d);
97  MatrixXd Raux = EV * C0 * EV.transpose();
98  MatrixXd aux = Raux.diagonal().cwiseAbs().cwiseSqrt().asDiagonal().inverse();
99  EV = aux * EV;
100 
101  crit.push_back(0.0);
102  for (int l = 0; l < L; l++)
103  {
104  Map<MatrixXd> Ci(C.get_matrix(l),d,d);
105  Map<MatrixXd> Csi(Cs.get_matrix(l),d,d);
106  Csi = EV * Ci * EV.transpose();
107  Rs.col(l) = Csi.diagonal();
108  crit.back() += Csi.cwiseAbs2().sum() - Rs.col(l).cwiseAbs2().sum();
109  }
110 
111  improve = CMath::abs(crit.back() - crit[iter]);
112  iter++;
113  }
114 
115  if (iter == itermax)
116  SG_SERROR("Convergence not reached\n")
117 
118  return V;
119 
120 }
121 
int32_t index_t
Definition: common.h:62
Definition: SGMatrix.h:20
SGMatrix< T > clone()
Definition: SGMatrix.cpp:256
index_t num_cols
Definition: SGMatrix.h:376
index_t num_rows
Definition: SGMatrix.h:374
T * get_matrix(index_t matIdx) const
Definition: SGNDArray.h:72
double float64_t
Definition: common.h:50
static SGMatrix< float64_t > diagonalize(SGNDArray< float64_t > C, SGMatrix< float64_t > V0=SGMatrix< float64_t >(NULL, 0, 0, false), double eps=1e-12, int itermax=200)
Definition: UWedge.cpp:12
all of classes and functions are contained in the shogun namespace
Definition: class_list.h:18
index_t * dims
Definition: SGNDArray.h:177
#define SG_SERROR(...)
Definition: SGIO.h:179
static SGMatrix< T > create_identity_matrix(index_t size, T scale)
static T abs(T a)
Definition: Math.h:179

SHOGUN Machine Learning Toolbox - Documentation