Xmipp  v3.23.11-Nereus
code_book.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 // CodeBook.cc
28 //-----------------------------------------------------------------------------
29 
30 
31 #include "code_book.h"
32 #include <core/xmipp_funcs.h>
33 
59 CodeBook::CodeBook(unsigned _n, unsigned _size, bool _cal)
62 {
63  // Fill vectors with zeros
64  theItems.resize(_n);
65  //if (calibrated())
66  theTargets.resize(_n, "");
67  for (unsigned i = 0 ; i < _n ; i++)
68  {
69  FeatureVector v;
70  v.resize(_size, 0);
71  theItems[i] = v;
72  }
73 }
74 
75 
76 
87 CodeBook::CodeBook(unsigned _n, unsigned _size, floatFeature _lower,
88  floatFeature _upper, bool _cal)
91 {
92  theItems.resize(_n);
93  //if (calibrated())
94  theTargets.resize(_n, "");
95  // Assign random vectors
96  for (unsigned i = 0 ; i < _n ; i++)
97  {
98  std::vector<floatFeature> v;
99  v = randomVector(_size, _lower, _upper);
100  theItems[i] = v;
101  }
102 }
103 
114 /* Part of this code were developed by Lorenzo Zampighi and Nelson Tang
115  of the department of Physiology of the David Geffen School of Medistd::cine,
116  University of California, Los Angeles
117 */
118 
119 CodeBook::CodeBook(unsigned _n, const ClassicTrainingVectors& _ts, const bool _use_rand_cvs)
122 {
123  // Take random samples
124  // RandomUniformGenerator<unsigned> chosen( 0, _ts.size() -1 );
126 
127  theItems.resize(_n);
128  //if (_ts.calibrated())
129  theTargets.resize(_n, "");
130  // Assign random vectors
131  std::vector<floatFeature> v;
132  for (unsigned i = 0 ; i < _n ; i++)
133  {
134  auto index = (int) rnd_unif(0, _ts.size() - 1);
135  v = _ts.theItems[index];
136  if (_use_rand_cvs)
137  {
138  // NT: Scan this vector for the range of pixel values
139  floatFeature minval;
140  floatFeature maxval;
141  std::vector<floatFeature>::const_iterator viter = v.begin();
142  minval = maxval = *viter;
143  for (viter++; viter != v.end(); viter++)
144  {
145  if (*viter < minval)
146  minval = *viter;
147  else if (*viter > maxval)
148  maxval = *viter;
149  }
150  v = randomVector(_ts.theItems[0].size(), minval, maxval);
151  }
152  theItems[i] = v;
153  }
154 
155 }
156 
164 {
165  readSelf(_is);
166 }
167 
173 {
174  // eval the first one to init best & bestDist
175  std::vector<FeatureVector>::const_iterator i = itemsBegin();
176  std::vector<FeatureVector>::const_iterator best = i;
177  double bestDist = euclideanDistance(*i, _in);
178 
179  // eval the rest
180  for (i++ ; i < itemsEnd() ; i++)
181  {
182  double dist = euclideanDistance(*i, _in);
183  if (dist < bestDist)
184  {
185  bestDist = dist;
186  best = i;
187  }
188  }
189 
190  return (FeatureVector&)*best;
191 }
192 
197 unsigned CodeBook::testIndex(const FeatureVector& _in) const
198 {
199  // eval the first one to init best & bestDist
200  std::vector<FeatureVector>::const_iterator i = itemsBegin();
201  std::vector<FeatureVector>::const_iterator best = i;
202  double bestDist = euclideanDistance(*i, _in);
203 
204  // eval the rest
205  unsigned bestIndex = 0;
206  unsigned index = 1;
207  for (i++ ; i < itemsEnd() ; i++)
208  {
209  double dist = euclideanDistance(*i, _in);
210  if (dist < bestDist)
211  {
212  bestDist = dist;
213  best = i;
214  bestIndex = index;
215  }
216  index++;
217  }
218 
219  return bestIndex;
220 }
221 #ifdef UNUSED // detected as unused 29.6.2018
222 
228 unsigned CodeBook::winner(const ClassicTrainingVectors& _ts, unsigned _in) const
229 {
230  return testIndex(_ts.theItems[_in]);
231 }
232 #endif
233 
239 {
240  classifVectors.clear(); // clear previous classification.
241  classifVectors.resize(size());
242  aveDistances.clear(); // clear previous classification.
243  aveDistances.resize(size());
244  for (unsigned j = 0 ; j < _ts->size() ; j++)
245  classifVectors[testIndex(_ts->theItems[j])].push_back(j);
246 
247  for (unsigned i = 0 ; i < size() ; i++)
248  {
249  double aveDist = 0;
250  for (unsigned j = 0 ; j < classifVectors[i].size() ; j++)
251  aveDist += euclideanDistance(theItems[i], _ts->theItems[classifVectors[i][j]]);
252  if (classifVectors[i].size() != 0)
253  aveDist /= (double) classifVectors[i].size();
254  aveDistances[i] = (double) aveDist;
255  }
256 
257 }
258 
259 
264 void CodeBook::printHistogram(std::ostream& _os) const
265 {
266  _os << "1 " << size() << std::endl;
267  for (size_t j = 0; j < size(); j++)
268  _os << j << " " << classifSizeAt(j) << std::endl;
269 }
270 
271 
276 void CodeBook::printQuantError(std::ostream& _os) const
277 {
278  _os << "1 " << size() << std::endl;
279  for (size_t j = 0; j < size(); j++)
280  _os << j << " " << aveDistances[j] << std::endl;
281 }
282 
286 const std::vector< unsigned>& CodeBook::classifAt(const unsigned& _index) const
287 {
288  if (_index < 0 || _index > classifVectors.size())
289  {
290  std::ostringstream msg;
291  msg << "index out of range";
292  throw std::runtime_error(msg.str());
293  }
294  return classifVectors[_index];
295 }
296 
300 unsigned CodeBook::classifSizeAt(const unsigned& _index) const
301 {
302  if (_index < 0 || _index > classifVectors.size())
303  {
304  std::ostringstream msg;
305  msg << "index out of range";
306  throw std::runtime_error(msg.str());
307  }
308  return classifVectors[_index].size();
309 }
310 
311 
317 {
318  return theTargets[testIndex(_in)];
319 }
320 
321 
329  Label _def)
330 {
331  // set the default label
332  for (std::vector<FeatureVector>::const_iterator i = itemsBegin() ;
333  i < itemsEnd() ; i++)
334  theTargets[i - itemsBegin()] = _def;
335  if (_ts.calibrated())
336  {
337  for (unsigned j = 0 ; j < _ts.size() ; j++)
338  theTargets[testIndex(_ts.theItems[j])] = _ts.theTargets[j];
339  calibrated(true);
340  }
341  else
342  calibrated(false);
343 }
344 
350 unsigned CodeBook::output(const FeatureVector& _in)
351 const
352 {
353  return testIndex(_in);
354 }
355 
356 
361 void CodeBook::printSelf(std::ostream& _os) const
362 {
364 }
365 
370 void CodeBook::readSelf(std::istream& _is, long _dim, long _size)
371 {
372 
373 #ifndef _NO_EXCEPTION
374  try
375  {
376 #endif
377  clear();
378  std::string line;
379 
380  // Determines the number of rows and columns in the training set
381 
382  long dim;
383  long size;
384  if (_dim == -1)
385  {
386  _is >> dim;
387  }
388  else
389  dim = _dim;
390  if (_size == -1)
391  {
392  _is >> line;
393  if (!sscanf(line.c_str(), "%ld", &size))
394  {
395  int x;
396  int y;
397  _is >> x;
398  _is >> y;
399  size = x * y;
400  }
401  }
402  else
403  size = _size;
404  getline(_is, line);
405  theItems.resize(size);
406  theTargets.resize(size);
407 
408  for (int i = 0; i < size; i++)
409  {
410  std::vector<floatFeature> v;
411  v.resize(dim);
412  for (int j = 0; j < dim; j++)
413  {
414  floatFeature var;
415  _is >> var;
416  v[j] = var;
417  }
418  getline(_is, line);
419  theItems[i] = v;
420  theTargets[i] = line;
421  }
422 #ifndef _NO_EXCEPTION
423 
424  }
425  catch (std::exception& e)
426  {
427  std::ostringstream msg;
428  msg << e.what() << std::endl << "Error reading the code book";
429  throw std::runtime_error(msg.str());
430  }
431 #endif
432 }
433 
434 
440 {
441  int dim;
442  _is >> dim;
443  classifVectors.resize(dim);
444  for (size_t i = 0; i < classifVectors.size(); i++)
445  _is >> classifVectors[i];
446 }
447 
448 
453 void CodeBook::writeClassifVectors(std::ostream& _os) const
454 {
455  _os << classifVectors.size() << std::endl;
456  for (size_t i = 0; i < classifVectors.size(); i++)
457  _os << classifVectors[i] << std::endl;
458 }
459 
460 
466 void CodeBook::saveObject(std::ostream& _os) const
467 {
468  writeClassifVectors(_os);
470 }
471 
472 
479 {
480  clear();
481  readClassifVectors(_is);
483 }
484 
485 
491 void CodeBook::unNormalize(const std::vector<ClassicTrainingVectors::statsStruct>& _varStats)
492 {
493  using namespace std;
494  if (_varStats.size() != theItems[0].size())
495  {
496  std::ostringstream msg;
497  msg << "Normalization information does not coincide with codebook structure";
498  throw std::runtime_error(msg.str());
499  }
500  for (unsigned it = 0; it < size(); it++)
501  {
502  for (unsigned i = 0; i < theItems[0].size(); i++)
503  {
504  if (!isnan(theItems[it][i]))
505  theItems[it][i] = theItems[it][i] * _varStats[i].sd + _varStats[i].mean;
506  }
507  }
508 }
509 
510 
516 void CodeBook::Normalize(const std::vector<ClassicTrainingVectors::statsStruct>& _varStats)
517 {
518  using namespace std;
519  if (_varStats.size() != theItems[0].size())
520  {
521  std::ostringstream msg;
522  msg << "Normalization information does not coincide with codebook structure";
523  throw std::runtime_error(msg.str());
524  }
525  for (unsigned it = 0; it < size(); it++)
526  {
527  for (unsigned i = 0; i < theItems[0].size(); i++)
528  {
529  if (!isnan(theItems[it][i]))
530  {
531  if (_varStats[i].sd != 0)
532  theItems[it][i] = (theItems[it][i] - _varStats[i].mean) / _varStats[i].sd;
533  }
534  }
535  }
536 }
537 
538 
539 //-----------------------------------------------------------------------------
virtual unsigned output(const FeatureVector &_in) const
Definition: code_book.cpp:350
std::vector< FeatureVector >::const_iterator itemsBegin() const
Definition: training_set.h:624
virtual void Normalize(const std::vector< ClassicTrainingVectors::statsStruct > &_varStats)
Definition: code_book.cpp:516
double euclideanDistance(const std::vector< T > &_v1, const std::vector< T > &_v2)
Definition: vector_ops.h:377
std::string Label
Definition: data_types.h:79
virtual void classify(const ClassicTrainingVectors *_ts)
Definition: code_book.cpp:238
static double * y
void writeClassifVectors(std::ostream &_os) const
Definition: code_book.cpp:453
virtual unsigned testIndex(const FeatureVector &_in) const
Definition: code_book.cpp:197
float floatFeature
Definition: data_types.h:72
virtual void unNormalize(const std::vector< ClassicTrainingVectors::statsStruct > &_varStats)
Definition: code_book.cpp:491
CodeBook(const bool &_calib=false)
Definition: code_book.h:69
virtual FeatureVector & test(const FeatureVector &_in) const
Definition: code_book.cpp:172
doublereal * x
#define i
virtual void printSelf(std::ostream &_os) const
Definition: training_set.h:330
double rnd_unif()
viol index
virtual const std::vector< unsigned > & classifAt(const unsigned &_index) const
Definition: code_book.cpp:286
std::vector< double > aveDistances
Definition: code_book.h:62
virtual void printHistogram(std::ostream &_os) const
Definition: code_book.cpp:264
virtual void saveObject(std::ostream &_os) const
Definition: training_set.h:349
basic_istream< char, std::char_traits< char > > istream
Definition: utilities.cpp:815
#define j
std::vector< FeatureVector >::const_iterator itemsEnd() const
Definition: training_set.h:633
virtual unsigned classifSizeAt(const unsigned &_index) const
Definition: code_book.cpp:300
virtual void printQuantError(std::ostream &_os) const
Definition: code_book.cpp:276
std::vector< std::vector< unsigned > > classifVectors
Definition: code_book.h:61
void readClassifVectors(std::istream &_is)
Definition: code_book.cpp:439
unsigned int randomize_random_generator()
virtual void printSelf(std::ostream &_os) const
Definition: code_book.cpp:361
virtual void loadObject(std::istream &_is)
Definition: training_set.h:360
std::vector< floatFeature > FeatureVector
Definition: data_types.h:86
virtual void loadObject(std::istream &_is)
Definition: code_book.cpp:478
virtual void calibrate(ClassicTrainingVectors &_ts, Label _def="")
Definition: code_book.cpp:328
std::vector< T > randomVector(const unsigned &_size, const T &_lower, const T &_upper)
Definition: vector_ops.h:175
virtual Label apply(const FeatureVector &_in) const
Definition: code_book.cpp:316
virtual void readSelf(std::istream &_is, long _dim=-1, long _size=-1)
Definition: code_book.cpp:370
virtual void saveObject(std::ostream &_os) const
Definition: code_book.cpp:466