Xmipp  v3.23.11-Nereus
Functions | Variables
Collaboration diagram for kSVD:

Functions

double orthogonalMatchingPursuit (const Matrix1D< double > &x, const Matrix2D< double > &D, int S, Matrix1D< double > &alpha)
 
double lasso (const Matrix1D< double > &x, const Matrix2D< double > &D, const Matrix2D< double > &DtD, const Matrix2D< double > &DtDlambdaInv, double lambda, Matrix1D< double > &alpha, const int maxIter=20, const double tol=0.005)
 

Variables

constexpr int OMP_PROJECTION = 1
 
constexpr int LASSO_PROJECTION = 2
 

Detailed Description

Function Documentation

◆ lasso()

double lasso ( const Matrix1D< double > &  x,
const Matrix2D< double > &  D,
const Matrix2D< double > &  DtD,
const Matrix2D< double > &  DtDlambdaInv,
double  lambda,
Matrix1D< double > &  alpha,
const int  maxIter = 20,
const double  tol = 0.005 
)

Lasso projection

This function looks for the best approximation with as few components as possible (regularized through a L1 norm) of a given dictionary D. The representation is alpha, i.e., x=D*alpha.

DtD is D^t*D and must be precomputed before calling the dictionary

The approximation error is returned.

This implementation is based on Mark Schmidt http://www.cs.ubc.ca/~schmidtm/Software/lasso.html

Definition at line 149 of file kSVD.cpp.

155 {
156  // Compute the ridge least squares solution
157  // Compute D^t*x
158  Matrix1D<double> Dtx;
159  matrixOperation_Atx(D,x,Dtx); // Dtx=D^t*x
160  matrixOperation_Ax(DtDlambdaInv,Dtx,alpha); // alpha=DtDlambdaInv*Dtx
161 
162  // Iterate over alpha
163  Matrix1D<double> alphaOld;
164  int iter=0;
165  bool finished=false;
166  while (!finished)
167  {
168  // Keep the current alpha
169  alphaOld=alpha;
170 
171  // Update alpha
173  {
174  double S=-Dtx(i);
175  for (size_t j=0; j<alpha.size(); j++)
176  if (i!=j) S+=DtD(i,j)*alpha(j);
177  if (fabs(S)<lambda)
178  alpha(i)=0;
179  else if (S>lambda)
180  alpha(i)=(lambda-S)/DtD(i,i);
181  else
182  alpha(i)=(-lambda-S)/DtD(i,i);
183  }
184 
185  // Prepare for next iteration
186  iter++;
187  double normDiff=0;
188  double normAlpha=0;
190  {
191  double diff=alpha(i)-alphaOld(i);
192  normDiff+=diff*diff;
193  normAlpha+=alpha(i)*alpha(i);
194  }
195  finished=(iter>=maxIter) || normDiff/normAlpha<tol;
196  }
197 
198  // Compute the approximation error
199  Matrix1D<double> xp(x.size());
200  for (size_t j=0; j<D.Xdim(); j++)
201  if (alpha(j)!=0)
202  for (size_t i=0; i<D.Ydim(); i++)
203  xp(i)+=D(i,j)*alpha(j);
204  double approximationError=0;
206  {
207  double diff=xp(i)-x(i);
208  approximationError+=diff*diff;
209  }
210 
211  return sqrt(ABS(approximationError));
212 }
size_t Xdim() const
Definition: matrix2d.h:575
double alpha
Smoothness parameter.
Definition: blobs.h:121
size_t size() const
Definition: matrix1d.h:508
void sqrt(Image< double > &op)
glob_prnt iter
doublereal * x
#define i
#define FOR_ALL_ELEMENTS_IN_MATRIX1D(v)
Definition: matrix1d.h:72
double * lambda
#define ABS(x)
Definition: xmipp_macros.h:142
size_t Ydim() const
Definition: matrix2d.h:584
void matrixOperation_Ax(const Matrix2D< double > &A, const Matrix1D< double > &x, Matrix1D< double > &y)
Definition: matrix2d.cpp:424
void matrixOperation_Atx(const Matrix2D< double > &A, const Matrix1D< double > &x, Matrix1D< double > &y)
Definition: matrix2d.cpp:488
#define j

◆ orthogonalMatchingPursuit()

double orthogonalMatchingPursuit ( const Matrix1D< double > &  x,
const Matrix2D< double > &  D,
int  S,
Matrix1D< double > &  alpha 
)

Orthogonal matching pursuit (OMP)

This function looks for the best approximation with only S components of a given dictionary D. The representation is alpha, i.e., x=D*alpha.

The approximation error is returned.

This implementation is based on Karl Skretting http://www.ux.uis.no/~karlsk/proj02/index.html

Definition at line 31 of file kSVD.cpp.

33 {
34  // Compute approximation error
35  double approximationError=0;
37  approximationError+=x(i)*x(i);
38  double errorLimit=approximationError*1e-10;
39 
40  // Initialize the number of available atoms
41  int N=D.Ydim(); // Dimension of each atom
42  if (0 == N) REPORT_ERROR(ERR_PARAM_INCORRECT, "Ydim of each atom must not be zero (0)");
43  int K=D.Xdim(); // Number of atoms in the dictionary
44  Matrix1D<int> availableAtoms;
45  availableAtoms.initZeros(K);
46  availableAtoms.initConstant(1);
47 
48  // Compute the projection of x onto each of the atoms and look for the
49  // maximum
54  c.initZeros(K);
55  e.initZeros(K); e.initConstant(1);
56  u.initZeros(K); u.initConstant(1);
57 
58  // Compute dot product between x and di
59  int km=0;
60  double ckm=-1;
61  for (int k=0; k<K; k++)
62  {
63  for (int j=0; j<N; j++)
64  c(k)+=D(j,k)*x(j);
65 
66  // Check if this is the maximum
67  if (ABS(c(k))>ckm)
68  {
69  km=k;
70  ckm=ABS(c(k));
71  }
72  }
73 
74  // Delete Js from the available indexes and update the approximation error
75  availableAtoms(km)=0;
76  approximationError-=ckm*ckm;
77 
78  // Annotate Jk
79  std::vector<int> J;
80  int s=0;
81  J.push_back(km);
82 
83  // Build the R matrix
84  Matrix2D<double> R(S,K);
85  R(0,km)=u(km);
86 
87  while (s<S-1 && approximationError>errorLimit)
88  {
89  // Update all the rest of R except Js
90  ckm=0;
91  int nextKm=-1;
92  for (int k=0; k<K; k++)
93  {
94  // If already used, skip it
95  if (!availableAtoms(k)) continue;
96 
97  // Compute the product between the atoms km and k
98  double aux=0;
99  for (int j=0; j<N; j++)
100  aux+=D(j,km)*D(j,k);
101  R(s,k)=aux;
102 
103  // Readjust R
104  for (int n=0; n<s; n++)
105  R(s,k)-=R(n,km)*R(n,k);
106  if (u(km)>XMIPP_EQUAL_ACCURACY)
107  R(s,k)/=u(km);
108 
109  // Update the rest of variables
110  c(k)=c(k)*u(k)-c(km)*R(s,k);
111  e(k)-=R(s,k)*R(s,k);
112  u(k)=sqrt(ABS(e(k)));
113  if (u(k)!=0) c(k)/=u(k);
114 
115  // Check if this is the best c(k)
116  if (ABS(c(k))>ckm)
117  {
118  nextKm=k;
119  ckm=ABS(c(k));
120  }
121  }
122 
123  // Delete km from the available indexes and update the approximation error
124  km=nextKm;
125  J.push_back(km);
126  availableAtoms(km)=0;
127  s++;
128  R(s,km)=u(km);
129  approximationError-=ckm*ckm;
130  }
131 
132  // Perform backsubstitution
133  alpha.initZeros(K);
134  for (int k=s; k>=0; k--)
135  {
136  int Jk=J[k];
137  for (int n=s; n>=k+1; n--)
138  c(Jk)-=R(k,J[n])*c(J[n]);
139  if (R(k,Jk)!=0) c(Jk)/=R(k,Jk);
140  alpha(Jk)=c(Jk);
141  }
142 
143  return sqrt(ABS(approximationError));
144 }
size_t Xdim() const
Definition: matrix2d.h:575
Parameter incorrect.
Definition: xmipp_error.h:181
double alpha
Smoothness parameter.
Definition: blobs.h:121
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
doublereal * c
void sqrt(Image< double > &op)
doublereal * w
doublereal * x
#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
#define FOR_ALL_ELEMENTS_IN_MATRIX1D(v)
Definition: matrix1d.h:72
#define XMIPP_EQUAL_ACCURACY
Definition: xmipp_macros.h:119
#define ABS(x)
Definition: xmipp_macros.h:142
size_t Ydim() const
Definition: matrix2d.h:584
void initZeros()
Definition: matrix1d.h:592
#define j
doublereal * u
constexpr int K
void initConstant(T val)
Definition: matrix1d.cpp:83
int * n

Variable Documentation

◆ LASSO_PROJECTION

constexpr int LASSO_PROJECTION = 2

Definition at line 72 of file kSVD.h.

◆ OMP_PROJECTION

constexpr int OMP_PROJECTION = 1

Definition at line 71 of file kSVD.h.