Xmipp  v3.23.11-Nereus
som.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: Alberto Pascual Montano (pascual@cnb.csic.es)
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 //-----------------------------------------------------------------------------
27 // SOM.cc
28 // Implements Kohonen Self-Organizing Feature Maps
29 //-----------------------------------------------------------------------------
30 
31 #include "som.h"
32 
38 {
39  readSelf(_is);
40 }
41 
42 
47 void SOM::alpha(Descent _alpha)
48 {
49  somAlpha = _alpha;
50 }
51 
56 void SOM::radius(Descent _radius)
57 {
58  somRadius = _radius;
59 }
60 
65 void SOM::nSteps(const unsigned long& _nSteps)
66 {
67  somNSteps = _nSteps;
68 }
69 
70 
77 {
78  unsigned long t = 0;
79 
80  int verbosity = listener->getVerbosity();
81  if (verbosity)
82  listener->OnReportOperation((std::string) "Training Kohonen SOM....\n");
83  if (verbosity == 1 || verbosity == 3)
85 
86 
87  while (t < somNSteps)
88  {
89  for (std::vector<SomIn>::iterator i = _ts.theItems.begin();
90  t < somNSteps && i < _ts.theItems.end() ; i++, t++)
91  {
92  // get the best matching.
93  SomIn& theBest = _som.test(*i)
94  ;
95  if (somNeigh == BUBBLE)
96  { // Bubble
97  // update the neighborhood around the best one
98  std::vector<unsigned> neig = _som.neighborhood(_som.codVecPos(theBest),
99  ceil(somRadius(t, somNSteps)));
100  for (std::vector<unsigned>::iterator it = neig.begin();it < neig.end();it++)
101  {
102  SomIn& v = _som.theItems[*it]
103  ;
104  for (unsigned j = 0; j < v.size(); j++)
105  v[j] += ((*i)[j] - v[j]) * somAlpha(t, somNSteps);
106  }
107  }
108  else
109  { // Gaussian
110  // update all neighborhood convoluted by a gaussian
111  double radius = somRadius(t, somNSteps);
112  double alpha = somAlpha(t, somNSteps);
113  for (unsigned it = 0 ; it < _som.size(); it++)
114  {
115  double dist = _som.neighDist(_som.codVecPos(theBest), _som.indexToPos(it));
116  double alp = alpha * (double) exp((double)(-dist * dist / (2.0 * radius * radius)));
117  SomIn& v = _som.theItems[it];
118  for (unsigned j = 0; j < v.size(); j++)
119  v[j] += ((*i)[j] - v[j]) * alp;
120  }
121  } // else
122 
123  } // for examples
124 
125  if (verbosity == 1 || verbosity == 3)
126  listener->OnProgress(t);
127  if (verbosity >= 2)
128  {
129  char s[100]
130  ;
131  sprintf(s, "Iteration %d of %d.\n", (int)t, (int)somNSteps);
132  listener->OnReportOperation((std::string) s);
133  }
134  } // while t < somSteps
135 
136 
137  if (verbosity == 1 || verbosity == 3)
139 
140 }
141 
142 
148 double SOM::test(const ClassificationMap& _som, const TS& _examples) const
149 {
150 
151  // Defines verbosity level
152  int verbosity = listener->getVerbosity();
153  if (verbosity)
154  {
155  listener->OnReportOperation((std::string) "Estimating quantization error....\n");
156  listener->OnInitOperation(_examples.size());
157  }
158 
159 
160  /* Scan all data entries */
161  double qerror = 0.0;
162  for (size_t i = 0; i < _examples.size(); i++)
163  {
164  SomIn& theBest = _som.test(_examples.theItems[i]); // get the best
165  qerror += euclideanDistance(theBest, _examples.theItems[i]);
166  if (verbosity)
167  {
168  auto tmp = (int)((_examples.size() * 5) / 100);
169  if ((tmp == 0) && (i != 0))
170  tmp = i;
171  else
172  tmp = 1;
173  if ((i % tmp) == 0)
175  }
176  }
177  if (verbosity)
178  listener->OnProgress(_examples.size());
179  return (qerror / (double) _examples.size());
180 }
181 
187 {
188  somNeigh = GAUSSIAN;
189  somNSteps = 0;
190  listener = NULL; // it can not be deleted here
191 }
192 
197 void SOM::printSelf(std::ostream& _os) const
198 {
199  _os << (int) somNeigh << std::endl;
200  _os << somNSteps << std::endl;
201  somAlpha.printSelf(_os);
202  somRadius.printSelf(_os);
203 }
204 
210 {
211  clear();
212  try
213  {
214  if (_is)
215  _is >> (int&) somNeigh;
216  if (_is)
217  _is >> somNSteps;
218  somAlpha.readSelf(_is);
219  somRadius.readSelf(_is);
220 
221  }
222  catch (std::exception& e)
223  {
224  std::stringstream msg;
225  msg << e.what() << std::endl << "Error reading the SOM algorithm";
226  throw std::runtime_error(msg.str());
227  }
228 
229 }
230 
231 
237 void SOM::saveObject(std::ostream& _os) const
238 {
239  printSelf(_os);
240 }
241 
242 
249 {
250  readSelf(_is);
251 }
252 
253 
254 
255 
256 //---------------------------------------------------------------------------
257 // Class Descent
258 //---------------------------------------------------------------------------
266 double Descent::operator()(const unsigned _step, const unsigned _nSteps) const
267 {
268  if (_nSteps == 0 || initial == final || _step >= _nSteps)
269  return final;
270  else
271  return final + ((initial - final) *
272  ((double)(_nSteps - _step) / (double)_nSteps));
273 }
274 
275 
280 void Descent::printSelf(std::ostream& _os) const
281 {
282  _os << initial << std::endl;
283  _os << final << std::endl;
284 }
285 
291 {
292  try
293  {
294  if (_is)
295  _is >> initial;
296  if (_is)
297  _is >> final;
298  }
299  catch (std::exception& e)
300  {
301  std::stringstream msg;
302  msg << e.what() << std::endl << "Error reading Descent class";
303  throw std::runtime_error(msg.str());
304  }
305 
306 }
307 
308 
314 void Descent::saveObject(std::ostream& _os) const
315 {
316  printSelf(_os);
317 }
318 
319 
326 {
327  readSelf(_is);
328 }
329 
virtual void printSelf(std::ostream &_os) const
Definition: som.cpp:280
SomPos indexToPos(const unsigned &_i) const
Definition: map.cpp:306
double euclideanDistance(const std::vector< T > &_v1, const std::vector< T > &_v2)
Definition: vector_ops.h:377
virtual void OnReportOperation(const std::string &_rsOp)=0
SOM(Descent &_alpha, Descent &_radius, neighType _neighType, unsigned long _nSteps)
Definition: som.h:150
virtual void readSelf(std::istream &_is)
Definition: som.cpp:290
virtual void OnInitOperation(unsigned long _est_it)=0
virtual const unsigned & getVerbosity() const
Definition: xmipp_funcs.h:1065
virtual void clear()
Definition: som.cpp:186
unsigned long somNSteps
Neighborhood type for training (Bubble or Gaussian)
Definition: som.h:278
void radius(Descent _radius)
Definition: som.cpp:56
std::vector< unsigned > neighborhood(const SomPos &_center, double _radius) const
Definition: map.cpp:167
virtual FeatureVector & test(const FeatureVector &_in) const
Definition: code_book.cpp:172
FeatureVector SomIn
Definition: map.h:44
virtual void printSelf(std::ostream &_os) const
Definition: som.cpp:197
#define i
virtual void train(ClassificationMap &_som, ClassicTrainingVectors &_ts) const
Definition: som.cpp:76
neighType somNeigh
radius(t)
Definition: som.h:277
Definition: som.h:48
virtual void loadObject(std::istream &_is)
Definition: som.cpp:325
std::vector< Item > theItems
Definition: training_set.h:84
virtual double test(const ClassificationMap &_som, const TS &_examples) const
Definition: som.cpp:148
virtual void readSelf(std::istream &_is)
Definition: som.cpp:209
virtual void OnProgress(unsigned long _it)=0
virtual double operator()(const unsigned _step, const unsigned _nSteps) const
Definition: som.cpp:266
basic_istream< char, std::char_traits< char > > istream
Definition: utilities.cpp:815
Descent somAlpha
Definition: som.h:275
SomPos codVecPos(SomIn &_v)
Definition: map.cpp:341
#define j
virtual void loadObject(std::istream &_is)
Definition: som.cpp:248
virtual void saveObject(std::ostream &_os) const
Definition: som.cpp:237
virtual void saveObject(std::ostream &_os) const
Definition: som.cpp:314
void alpha(Descent _alpha)
Definition: som.cpp:47
void nSteps(const unsigned long &_nSteps)
Definition: som.cpp:65
Descent somRadius
alpha(t)
Definition: som.h:276
double neighDist(const SomPos &_center, const SomPos &_v) const
Definition: map.cpp:177