Xmipp  v3.23.11-Nereus
nca.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: Carlos Oscar coss@cnb.csic.es (2013)
4  *
5  * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20  * 02111-1307 USA
21  *
22  * All comments concerning this program package may be sent to the
23  * e-mail address 'xmipp@cnb.csic.es'
24  ***************************************************************************/
25 
26 #include "nca.h"
27 #include <data/numerical_tools.h>
28 
30 {
31  this->labels=labels;
32 }
33 
35 {
36  this->lambda=lambda;
37  this->K=K;
38 }
39 
41 {
42  // Project X onto the subspace given by A, Y=X*A
44 
45  // Compute the distance between the nearest neighbours of each observation
46  // in this new subspace
49  {
50  double aux=0.;
51  int actualj=MAT_ELEM(idx,i,j);
52  for (int l=0; l<MAT_XSIZE(Y); ++l)
53  {
54  double diff=MAT_ELEM(Y,i,l)-MAT_ELEM(Y,actualj,l);
55  aux+=diff*diff;
56  }
57  MAT_ELEM(D2Y,i,j)=exp(-aux);
58  }
60 
61  // Compute F
62  double F=0.;
63  for (int i=0; i<MAT_YSIZE(Y); ++i)
64  {
65  double sumClassi=0.;
66  int labeli=VEC_ELEM(labels,i);
67  for (int j=0; j<K; ++j)
68  {
69  int actualj=MAT_ELEM(idx,i,j);
70  if (VEC_ELEM(labels,actualj)==labeli)
71  sumClassi+=MAT_ELEM(D2Y,i,j);
72  }
73  if (fabs(VEC_ELEM(D2YRowSum,i))>1e-16)
74  F+=sumClassi/VEC_ELEM(D2YRowSum,i);
75  }
76 
77  // Compute regularization
78  double sumA2=0.0;
80  sumA2+=MAT_ELEM(A,i,j)*MAT_ELEM(A,i,j);
81  sumA2/=MAT_XSIZE(A)*MAT_YSIZE(A);
82 
83  return -(F-lambda*sumA2);
84 }
85 
86 double ncaObjectiveFuntion(double *p, void *prm)
87 {
88  auto *nca=(NeighbourhoodCA *)prm;
89  Matrix2D<double> &A=nca->A;
90  memcpy(&MAT_ELEM(A,0,0),&(p[1]),MAT_XSIZE(A)*MAT_YSIZE(A)*sizeof(double));
91  double c=nca->objectiveFunction();
92  return c;
93 }
94 
96 {
99  kNearestNeighbours(*X, K, idx, D2, distance, false);
100 
101  size_t d=MAT_XSIZE(*X);
102  A.initGaussian(d,outputDim,0,0.01);
103 
104  // Optimize A
106  steps.initConstant(1);
107  memcpy(&VEC_ELEM(pA,0),&MAT_ELEM(A,0,0),VEC_XSIZE(pA)*sizeof(double));
108  double goal;
109  int iter;
110  powellOptimizer(pA,1,VEC_XSIZE(pA),&ncaObjectiveFuntion,this,0.001,goal,iter,steps,false);
111  memcpy(&MAT_ELEM(A,0,0),&VEC_ELEM(pA,0),VEC_XSIZE(pA)*sizeof(double));
112 
113  // Reduction
115 }
#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
void rowSum(Matrix1D< T > &sum) const
Definition: matrix2d.cpp:779
void subtractColumnMeans(Matrix2D< double > &A)
Definition: matrix2d.cpp:230
Matrix2D< double > Y
Output data.
Definition: dimred_tools.h:147
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
doublereal * c
void matrixOperation_AB(const Matrix2D< double > &A, const Matrix2D< double > &B, Matrix2D< double > &C)
Definition: matrix2d.cpp:411
Matrix2D< double > * X
Pointer to input data.
Definition: dimred_tools.h:141
void setSpecificParameters(double lambda=0., int K=12)
Set specific parameters.
Definition: nca.cpp:34
Matrix1D< unsigned char > labels
Labels.
Definition: nca.h:27
void setLabels(const Matrix1D< unsigned char > &labels)
Set labels.
Definition: nca.cpp:29
void powellOptimizer(Matrix1D< double > &p, int i0, int n, double(*f)(double *x, void *), void *prm, double ftol, double &fret, int &iter, const Matrix1D< double > &steps, bool show)
glob_prnt iter
#define i
doublereal * d
void resizeNoCopy(int Ydim, int Xdim)
Definition: matrix2d.h:534
size_t outputDim
Output dim.
Definition: dimred_tools.h:144
#define MAT_ELEM(m, i, j)
Definition: matrix2d.h:116
Matrix2D< int > idx
Definition: nca.h:37
double lambda
Weight factor for regularization.
Definition: nca.h:24
double ncaObjectiveFuntion(double *p, void *prm)
Definition: nca.cpp:86
Matrix1D< double > D2YRowSum
Definition: nca.h:34
Matrix2D< double > D2Y
Definition: nca.h:33
#define j
double steps
DimRedDistance2 distance
Distance function.
Definition: dimred_tools.h:150
#define MAT_XSIZE(m)
Definition: matrix2d.h:120
Matrix2D< double > A
Definition: nca.h:33
double objectiveFunction()
Definition: nca.cpp:40
void reduceDimensionality()
Reduce dimensionality.
Definition: nca.cpp:95
ProgClassifyCL2D * prm
void initGaussian(int Ydim, int Xdim, double op1=0., double op2=1.)
Definition: matrix2d.cpp:1118
int K
Number of neighbours.
Definition: nca.h:30
void initConstant(T val)
Definition: matrix1d.cpp:83