Xmipp  v3.23.11-Nereus
npe.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: Carlos Oscar coss@cnb.csic.es (2013)
4  * Javier Gamas
5  *
6  * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21  * 02111-1307 USA
22  *
23  * All comments concerning this program package may be sent to the
24  * e-mail address 'xmipp@cnb.csic.es'
25  ***************************************************************************/
26 
27 #include "npe.h"
28 #include <core/matrix2d.h>
29 #include <core/matrix1d.h>
31 
33  this->k=k;
34 }
35 
36 /*
37  * Reduce dimensionality method based on NPE algorithm
38  */
40 {
41  if (MAT_YSIZE(*X) <= MAT_XSIZE(*X))
42  REPORT_ERROR(ERR_MATRIX_DIM, "Number of samples should be higher than number of dimensions.");
43 
44  int n = MAT_YSIZE(*X);
45 
46  //Find nearest neighbours
48  Matrix2D<int> idx;
49  kNearestNeighbours(*X,k,idx,D,distance,false);
50 
51  Matrix2D<double> W(k,n), Xi, C, M;
53 
55  h.b.resizeNoCopy(k);
56  h.b.initConstant(1);
57 
58  double tol=1e-5;
59  for (int ip=0; ip<n; ++ip)
60  {
61  extractNearestNeighbours(*X, idx, ip, Xi);
62 
63  // Move the origin to observation ip
65  MAT_ELEM(Xi,i,j)-=MAT_ELEM(*X,ip,j);
66 
67  matrixOperation_AAt(Xi,C);
68 
69  double K=C.trace()*tol;
70  for (int ii=0; ii<MAT_XSIZE(C); ++ii)
71  MAT_ELEM(C,ii,ii)+=K;
72 
73  h.A=C;
74 
75  solveLinearSystem(h,wi);
76  wi/=wi.sum();
77 
78  W.setCol(ip,wi);
79  }
80 
81  //Find the sparse cost matrix
82  M.initIdentity(n);
83  Matrix1D<int> neighboursi;
84 
85  for(int i=0;i<n; ++i)
86  {
87  // Get wi for this observation
88  W.getCol(i,wi);
89 
90  // Get the neighbours of this observation
91  idx.getRow(i,neighboursi);
92 
93  for(size_t p1=0;p1<VEC_XSIZE(neighboursi); p1++)
94  {
95  int j1=VEC_ELEM(neighboursi,p1); // j is the index of the neighbour
96  double w1=VEC_ELEM(wi,p1);
97  MAT_ELEM(M,i,j1)-=w1;
98  MAT_ELEM(M,j1,i)-=w1;
99  for (size_t p2=0; p2<VEC_XSIZE(neighboursi); p2++)
100  {
101  int j2=VEC_ELEM(neighboursi,p2);
102  MAT_ELEM(M,j1,j2)+=w1*VEC_ELEM(wi,p2);
103  }
104 
105  }
106  }
107 
108  //Check symmetry
109  Matrix2D<double> DP, WP;
110 
111  X->transpose();
113  matrixOperation_AtA(*X, DP);
114 
115  //Solve eigenvector problem
116  Matrix2D<double> Peigvec, eigvector;
117  Matrix1D<double> Deigval;
118  generalizedEigs(WP,DP,Deigval,Peigvec);
119 
120  //Sort eigenvalues
121  Matrix1D<int> idx2;
122  Deigval.indexSort(idx2);
123 
124  eigvector.resizeNoCopy(MAT_YSIZE(Peigvec),outputDim);
125  for(size_t j =0;j<outputDim;++j){
126  int idxj=VEC_ELEM(idx2,j)-1;
127  for(size_t i=0;i<MAT_YSIZE(Peigvec);++i)
128  MAT_ELEM(eigvector, i, j)=MAT_ELEM(Peigvec,i,idxj);
129  }
130 
131  //Compute results
132  Y=*X*eigvector;
133  if (fnMapping!="")
134  eigvector.write(fnMapping);
135 }
#define FOR_ALL_ELEMENTS_IN_MATRIX2D(m)
Definition: matrix2d.h:104
#define MAT_YSIZE(m)
Definition: matrix2d.h:124
#define VEC_ELEM(v, i)
Definition: matrix1d.h:245
Matrix2D< double > Y
Output data.
Definition: dimred_tools.h:147
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
void kNearestNeighbours(const Matrix2D< double > &X, int K, Matrix2D< int > &idx, Matrix2D< double > &distance, DimRedDistance2 f, bool computeSqrt)
#define VEC_XSIZE(m)
Definition: matrix1d.h:77
void indexSort(Matrix1D< int > &indx) const
Definition: matrix1d.cpp:861
void reduceDimensionality()
Reduce dimensionality.
Definition: npe.cpp:39
Matrix2D< double > * X
Pointer to input data.
Definition: dimred_tools.h:141
T trace() const
Definition: matrix2d.cpp:1304
void extractNearestNeighbours(const Matrix2D< double > &X, Matrix2D< int > &idx, int i, Matrix2D< double > &Xi)
Matrix2D< T > transpose() const
Definition: matrix2d.cpp:1314
void matrixOperation_AtA(const Matrix2D< double > &A, Matrix2D< double > &B)
Definition: matrix2d.cpp:436
#define i
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
void resizeNoCopy(int Ydim, int Xdim)
Definition: matrix2d.h:534
void setSpecificParameters(int k=12)
Set specific parameters.
Definition: npe.cpp:32
void matrixOperation_AAt(const Matrix2D< double > &A, Matrix2D< double > &C)
Definition: matrix2d.cpp:449
size_t outputDim
Output dim.
Definition: dimred_tools.h:144
#define MAT_ELEM(m, i, j)
Definition: matrix2d.h:116
Matrix1D< double > b
Problem with matrix dimensions.
Definition: xmipp_error.h:150
Matrix2D< double > A
int k
Definition: npe.h:37
void generalizedEigs(const Matrix2D< double > &A, const Matrix2D< double > &B, Matrix1D< double > &D, Matrix2D< double > &P)
Definition: matrix2d.cpp:267
double sum(bool average=false) const
Definition: matrix1d.cpp:652
void solveLinearSystem(PseudoInverseHelper &h, Matrix1D< double > &result)
#define j
DimRedDistance2 distance
Distance function.
Definition: dimred_tools.h:150
#define DP(x)
FileName fnMapping
Save mapping.
Definition: dimred_tools.h:153
#define MAT_XSIZE(m)
Definition: matrix2d.h:120
double tol
Definition: npe.h:38
void write(const FileName &fn) const
Definition: matrix2d.cpp:113
void resizeNoCopy(int Xdim)
Definition: matrix1d.h:458
constexpr int K
void getRow(size_t i, Matrix1D< T > &v) const
Definition: matrix2d.cpp:871
void matrixOperation_XtAX_symmetric(const Matrix2D< double > &X, const Matrix2D< double > &A, Matrix2D< double > &B)
Definition: matrix2d.cpp:513
void initConstant(T val)
Definition: matrix1d.cpp:83
int * n
void initIdentity()
Definition: matrix2d.h:673