iRoCS Toolbox  1.1.0
SparseFV.hh
Go to the documentation of this file.
1 /**************************************************************************
2  *
3  * Copyright (C) 2004-2015 Olaf Ronneberger, Florian Pigorsch, Jörg Mechnich,
4  * Thorsten Falk
5  *
6  * Image Analysis Lab, University of Freiburg, Germany
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 3 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 Foundation,
20  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  *
22  **************************************************************************/
23 
24 /**************************************************************************
25 ** Title: SparseFV.hh
26 ** $RCSfile$
27 ** $Revision: 907 $$Name$
28 ** $Date: 2006-10-06 15:50:05 +0200 (Fri, 06 Oct 2006) $
29 ** Copyright: LGPL $Author: fehr $
30 ** Description: Implementation of a sparse feature vector
31 **
32 **
33 **
34 **-------------------------------------------------------------------------
35 **
36 ** $Log$
37 ** Revision 1.3 2006/10/06 13:50:05 fehr
38 ** linear model optimizer added
39 **
40 ** Revision 1.2 2004/09/13 10:04:04 ronneber
41 ** - documentation update
42 **
43 ** Revision 1.1 2004/08/26 08:36:59 ronneber
44 ** initital import
45 **
46 ** Revision 1.5 2002/09/04 10:29:57 pigorsch
47 ** - initial revision, copied from libpollenpp and modified
48 **
49 ** Revision 1.4 2002/06/27 10:59:17 pigorsch
50 ** - added function cleanup
51 **
52 ** Revision 1.3 2002/05/23 11:54:44 ronneber
53 ** - inlined operator<< and operator>>
54 **
55 ** Revision 1.2 2002/05/14 10:15:54 ronneber
56 ** - made interface more similar to BasicFV to make them more easily exchangeable
57 **
58 ** Revision 1.1 2002/03/26 12:44:02 ronneber
59 ** restructured for autoconf
60 **
61 ** Revision 1.2 2002/01/28 13:42:15 pigorsch
62 ** * added functions Read-/WriteWithoutLabel
63 **
64 ** Revision 1.1 2002/01/14 13:54:04 pigorsch
65 ** * initial revision
66 **
67 **
68 **
69 **************************************************************************/
70 
71 #ifndef SPARSEFV_HH
72 #define SPARSEFV_HH
73 
74 #ifdef HAVE_CONFIG_H
75 #include <config.hh>
76 #endif
77 
78 #include <iostream>
79 #include <list>
80 #include <cctype>
81 
82 #include "svm_defines.hh"
83 #include "SVMError.hh"
84 
85 using std::isspace;
86 
87 
88 namespace svt
89 {
90  /*======================================================================*/
96  /*======================================================================*/
97  class SparseItem
98  {
99  public:
101  unsigned int index,
102  double value)
103  :pIndex(index),
104  pValue(value)
105  {};
106 
107  unsigned int index() const
108  {
109  return pIndex;
110  };
111 
112  const double& value() const
113  {
114  return pValue;
115  };
116 
117  double& value()
118  {
119  return pValue;
120  };
121 
122 
123  protected:
124  unsigned int pIndex;
125  double pValue;
126  };
127 
128  /*======================================================================*/
136  /*======================================================================*/
137  class SparseFV
138  {
139  public:
140  typedef std::list<svt::SparseItem>::iterator iterator;
141  typedef std::list<svt::SparseItem>::const_iterator const_iterator;
142  typedef double& reference;
143  typedef const double& const_reference;
144  typedef unsigned int size_type;
145 
146  /*====================================================================*/
150  /*====================================================================*/
152  : pLabel(0),
153  _uniqueID( MAX_BELIEVABLE_UNIQUE_ID+1),
154  pSquareValid(true),
155  pSquare(0.),
156  _size( 0)
157  {};
158 
159  /*====================================================================*/
163  /*====================================================================*/
165  {};
166 
167  /*====================================================================*/
173  /*====================================================================*/
174  double getLabel() const
175  {
176  return pLabel;
177  };
178 
179  /*====================================================================*/
186  /*====================================================================*/
187  void setLabel(double value)
188  {
189  pLabel=value;
190  };
191 
192  void setUniqueID( unsigned int uid)
193  {
194  _uniqueID = uid;
195  }
196 
197 
198  unsigned int uniqueID() const
199  {
200  return _uniqueID;
201  }
202 
203  /*====================================================================*/
208  /*====================================================================*/
209  void clear()
210  {
211  pFeatures.clear();
212  pSquareValid=false;
213  };
214 
215  const_iterator begin() const
216  {
217  return pFeatures.begin();
218  };
219 
220  iterator begin()
221  {
222  pSquareValid=false;
223  return pFeatures.begin();
224  };
225 
226  const_iterator end() const
227  {
228  return pFeatures.end();
229  };
230 
231  iterator end()
232  {
233  pSquareValid=false;
234  return pFeatures.end();
235  };
236 
237  /*====================================================================*/
245  /*====================================================================*/
246  double operator[](size_type index) const
247  {
248  const_iterator p = begin();
249  while( p != end() && p->index() < index)
250  {
251  ++p;
252  }
253  if (p->index() == index)
254  {
255  return p->value();
256  }
257  return 0.;
258  };
259 
260  /*====================================================================*/
268  /*====================================================================*/
269  reference operator[]( size_type index)
270  {
271  pSquareValid=false;
272 
273  // search insertion position
274  iterator p = begin();
275  while( p != end() && p->index() < index)
276  {
277  ++p;
278  }
279  if (p != end() && p->index() == index)
280  {
281  return p->value();
282  }
283 
284  // there is no entry, create one
285  iterator newItem = pFeatures.insert(p, svt::SparseItem(index, 0));
286  return newItem->value();
287 
288  };
289 
290  /*======================================================================*/
302  /*======================================================================*/
303  void resize( size_type s)
304  {
305  _size = s;
306  }
307 
308 
309 
310  /*======================================================================*/
320  /*======================================================================*/
321  size_type size() const
322  {
323  return _size;
324  }
325 
326 
327  /*======================================================================*/
338  /*======================================================================*/
339  void cleanup()
340  {
341  bool foundZero=true;
342  while (foundZero)
343  {
344  foundZero=false;
345  for (iterator p=begin();
346  p!=end();
347  ++p)
348  {
349  if (p->value()==0)
350  {
351  pFeatures.erase(p);
352  foundZero=true;
353  break;
354  }
355  }
356  }
357  }
358 
359 
360  /*====================================================================*/
366  /*====================================================================*/
367  double square() const
368  {
369  if (!pSquareValid)
370  {
371  pSquare=0.;
372  for (const_iterator p=begin();
373  p!=end();
374  )
375  {
376  pSquare+=p->value() * p->value();
377  ++p;
378  }
379 
380  pSquareValid=true;
381  }
382 
383  return pSquare;
384  };
385 
386  /*====================================================================*/
394  /*====================================================================*/
395  double dotProduct(
396  const svt::SparseFV& fv) const
397  {
398  double sum=0.;
399 
400  const_iterator i=begin();
401  const_iterator j=fv.begin();
402  for (;
403  i!=end() && j!=fv.end();
404  )
405  {
406  if (i->index()==j->index())
407  {
408  sum+=i->value() * j->value();
409  ++i;
410  ++j;
411  }
412  else if (i->index()>j->index())
413  {
414  ++j;
415  }
416  else
417  {
418  ++i;
419  }
420  }
421 
422  return sum;
423  };
424 
425  /*======================================================================*/
433  /*======================================================================*/
434  bool operator==( const svt::SparseFV& fv) const
435  {
436  if( pFeatures.size() != fv.pFeatures.size()) return false;
437  const_iterator p1 = pFeatures.begin();
438  const_iterator p2= fv.pFeatures.begin();
439  for( ; p1 != pFeatures.end(); ++p1, ++p2)
440  {
441  if( p1->index() != p2->index()
442  || p1->value() != p2->value())
443  {
444  return false;
445  }
446  }
447  return true;
448  }
449 
450  void operator+=( const svt::SparseFV& fv)
451  {
452  svt::SparseError err;
453  if( pFeatures.size() == fv.pFeatures.size())
454  {
455  SparseFV::iterator p1 = pFeatures.begin();
457  for( ; p1 != pFeatures.end(); ++p1, ++p2)
458  {
459  if( p1->index() == p2->index())
460  {
461  p1->value() += p2->value();
462  }
463  else
464  {
465  err << "can not calculate with sparse vectors of different shape !\n";
466  throw err;
467  }
468  }
469 
470  }
471  else
472  {
473  err<<"can not calculate with sparse vectors of differnt size !/n";
474  throw err;
475  }
476  }
477 
478  void operator*=( double factor)
479  {
480  SparseFV::iterator p1 = pFeatures.begin();
481  for( ; p1 != pFeatures.end(); ++p1)
482  {
483  p1->value() *= factor;
484  }
485  }
486 
487  void setZero()
488  {
489  SparseFV::iterator p1 = pFeatures.begin();
490  for( ; p1 != pFeatures.end(); ++p1)
491  {
492  p1->value() = 0;
493  }
494  }
495  /*====================================================================*/
502  /*====================================================================*/
504  std::istream& is)
505  {
506  clear();
507 
508  while (is.good())
509  {
510  //skip whitespace, stop if non-number character or newline occurs
511  char c;
512  do
513  {
514  if( is.rdbuf()->sgetc() == EOF) return;
515  is.get(c);
516  if( !is) return;
517  } while( isspace(c) && c != '\n');
518 
519  is.putback(c);
520  if( !isdigit(c) ) return;
521  // read index
522  unsigned int index;
523  is >> index;
524  // read ":"
525  is >> c;
526  // read value
527  double value;
528  is >> value;
529 
530  // add it to fv
531  operator[](index) = value;
532  }
533  };
534 
535  /*====================================================================*/
542  /*====================================================================*/
544  std::ostream& os) const
545  {
546  for (const_iterator p=begin(); p!=end(); ++p )
547  {
548  if( p != begin()) os << " ";
549  os << p->index() << ":" << p->value();
550  }
551  };
552 
553  static const char* helpPipeFormat()
554  {
555  return "<label><ws><index>:<feature><ws><index>:<feature>...\n"
556  "where <ws> is any number of white spaces except for newline\n"
557  "First <index> is 1.\n"
558  "example:\n"
559  "4 1:0.123 13:2.432 235:42.0";
560  }
561 
562 
563  friend std::ostream& operator<<(std::ostream& os, const svt::SparseFV& fv);
564  friend std::istream& operator>>(std::istream& is, svt::SparseFV& fv);
565 
566  protected:
567  std::list<svt::SparseItem> pFeatures;
568  double pLabel;
569  unsigned int _uniqueID;
570 
571  mutable bool pSquareValid;
572  mutable double pSquare;
573  size_type _size;
574  };
575 
576 
577  inline
578  std::ostream& operator<<(std::ostream& os, const svt::SparseFV& fv)
579  {
580  os << fv.pLabel << " ";
581  fv.writeWithoutLabel( os);
582  return os;
583  }
584 
585  inline
586  std::istream& operator>>(std::istream& is, svt::SparseFV& fv)
587  {
588  // read label
589  double label;
590  is >> label;
591  fv.setLabel(label);
592  fv.readWithoutLabel( is);
593  return is;
594  }
595 
596 }
597 
598 #endif
void pSquare(blitz::Array< Typea, Dim > &a)
size_type _size
Definition: SparseFV.hh:573
void operator*=(double factor)
Definition: SparseFV.hh:478
const double & const_reference
Definition: SparseFV.hh:143
SparseFV()
Constructor.
Definition: SparseFV.hh:151
~SparseFV()
Destructor.
Definition: SparseFV.hh:164
void cleanup()
cleanup function to delete items with value 0 (maybe someone needs this)
Definition: SparseFV.hh:339
const double & value() const
Definition: SparseFV.hh:112
void setZero()
Definition: SparseFV.hh:487
unsigned int size_type
Definition: SparseFV.hh:144
void setUniqueID(unsigned int uid)
Definition: SparseFV.hh:192
void readWithoutLabel(std::istream &is)
Read FV from input stream without label.
Definition: SparseFV.hh:503
double getLabel() const
Returns label of FV.
Definition: SparseFV.hh:174
const_iterator end() const
Definition: SparseFV.hh:226
const unsigned int MAX_BELIEVABLE_UNIQUE_ID
Definition: svm_defines.hh:63
std::ostream & operator<<(std::ostream &os, const svt::BasicFV &fv)
Definition: BasicFV.hh:464
iterator end()
Definition: SparseFV.hh:231
std::istream & operator>>(std::istream &is, svt::BasicFV &fv)
Definition: BasicFV.hh:473
unsigned int _uniqueID
Definition: SparseFV.hh:569
double pSquare
Definition: SparseFV.hh:572
unsigned int index() const
Definition: SparseFV.hh:107
std::list< svt::SparseItem >::iterator iterator
Definition: SparseFV.hh:140
void writeWithoutLabel(std::ostream &os) const
Write FV to output stream without label.
Definition: SparseFV.hh:543
iterator begin()
Definition: SparseFV.hh:220
double & reference
Definition: SparseFV.hh:142
SparseItem(unsigned int index, double value)
Definition: SparseFV.hh:100
void clear()
Clear FV&#39;s data.
Definition: SparseFV.hh:209
unsigned int uniqueID() const
Definition: SparseFV.hh:198
double pLabel
Definition: SparseFV.hh:568
The SparseFV class specifies a vector with sparse storage.
Definition: SparseFV.hh:137
double dotProduct(const svt::SparseFV &fv) const
Calculate and return dot product of *this and specified FV.
Definition: SparseFV.hh:395
void operator+=(const svt::SparseFV &fv)
Definition: SparseFV.hh:450
const_iterator begin() const
Definition: SparseFV.hh:215
double square() const
Calculate and return square of FV.
Definition: SparseFV.hh:367
bool operator==(const svt::SparseFV &fv) const
comparison
Definition: SparseFV.hh:434
reference operator[](size_type index)
Return reference to value data item with specified index.
Definition: SparseFV.hh:269
size_type size() const
size of sparse vector is just the value of the last resize()
Definition: SparseFV.hh:321
std::list< svt::SparseItem > pFeatures
Definition: SparseFV.hh:567
void setLabel(double value)
Set FV&#39;s label.
Definition: SparseFV.hh:187
std::list< svt::SparseItem >::const_iterator const_iterator
Definition: SparseFV.hh:141
void resize(size_type s)
resizing sparse vector has no effect on the vector.
Definition: SparseFV.hh:303
double & value()
Definition: SparseFV.hh:117
double operator[](size_type index) const
Return const reference to value data item with specified index.
Definition: SparseFV.hh:246
The SparseItem class specifies one element in a SpareFV.
Definition: SparseFV.hh:97
unsigned int pIndex
Definition: SparseFV.hh:120
bool pSquareValid
Definition: SparseFV.hh:571
static const char * helpPipeFormat()
Definition: SparseFV.hh:553