Orfeo Toolbox  3.16
itkVariableDimensionHistogram.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Insight Segmentation & Registration Toolkit
4  Module: $RCSfile: itkVariableDimensionHistogram.txx,v $
5  Language: C++
6  Date: $Date: 2009-03-04 20:26:56 $
7  Version: $Revision: 1.8 $
8 
9  Copyright (c) Insight Software Consortium. All rights reserved.
10  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
11 
12  This software is distributed WITHOUT ANY WARRANTY; without even
13  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14  PURPOSE. See the above copyright notices for more information.
15 
16 =========================================================================*/
17 #ifndef __itkVariableDimensionHistogram_txx
18 #define __itkVariableDimensionHistogram_txx
19 
21 #include "itkNumericTraits.h"
22 
23 namespace itk {
24 namespace Statistics {
25 
26 template< class TMeasurement,
27  class TFrequencyContainer>
30 {
31  m_ClipBinsAtEnds = true;
32  m_FrequencyContainer = FrequencyContainerType::New();
33 }
34 
35 template< class TMeasurement,
36  class TFrequencyContainer>
39 {
40  if( s == this->GetMeasurementVectorSize() )
41  {
42  return;
43  }
44 
45  if( (m_OffsetTable.Size() != 0) ||
46  (m_Size.Size() != 0) ||
47  (m_TempIndex.Size() != 0) ||
48  (m_TempMeasurementVector.Size() != 0))
49  {
50  itkWarningMacro( << "Destructively resizing paramters of the histogram" );
51  }
52  Superclass::SetMeasurementVectorSize( s );
53  m_OffsetTable.SetSize( s + 1 );
54  m_OffsetTable.Fill( 0 );
55  m_Size.SetSize( s );
56  m_TempIndex.SetSize( s );
57  m_TempMeasurementVector.SetSize( s );
58  this->Modified();
59 }
60 
61 
62 template< class TMeasurement,
63  class TFrequencyContainer>
64 unsigned int
66 ::Size() const
67 {
68  if( this->GetMeasurementVectorSize() == 0 )
69  {
70  return 0;
71  }
72 
73  unsigned int size = 1;
74  for (unsigned int i = 0; i < this->GetMeasurementVectorSize(); i++)
75  {
76  size *= m_Size[i];
77  }
78  return size;
79 }
80 
81 template< class TMeasurement,
82  class TFrequencyContainer>
83 void
85 ::Initialize(const SizeType &size)
86 {
88  MeasurementVectorTraits::Assert( size, this->GetMeasurementVectorSize(),
89  "Size mismatch in VariableDimensionHistogram::Initialize(const SizeType &size)");
90  if( s )
91  {
92  this->SetMeasurementVectorSize( size.Size() );
93  }
94 
95  m_Size = size;
96 
97  // creates offset table which will be used for generation of
98  // instance identifiers.
99  InstanceIdentifier num = 1;
100 
101  m_OffsetTable[0] = num;
102  for (unsigned int i = 0; i < this->GetMeasurementVectorSize(); i++)
103  {
104  num *= m_Size[i];
105  m_OffsetTable[i + 1] = num;
106  }
107 
108  m_NumberOfInstances = num;
109 
110  // adjust the sizes of min max value containers
111  unsigned int dim;
112  m_Min.resize(this->GetMeasurementVectorSize());
113  for ( dim = 0; dim < this->GetMeasurementVectorSize(); dim++)
114  {
115  m_Min[dim].resize(m_Size[dim]);
116  }
117 
118  m_Max.resize(this->GetMeasurementVectorSize());
119  for ( dim = 0; dim < this->GetMeasurementVectorSize(); dim++)
120  {
121  m_Max[dim].resize(m_Size[dim]);
122  }
123 
124  // initialize the frequency container
125  m_FrequencyContainer->Initialize(m_OffsetTable[ this->GetMeasurementVectorSize() ]);
126  this->SetToZero();
127 }
128 
129 template< class TMeasurement,
130  class TFrequencyContainer>
131 void
134 {
135  m_FrequencyContainer->SetToZero();
136 }
137 
138 template< class TMeasurement,
139  class TFrequencyContainer>
140 void
142 ::Initialize(const SizeType &size, MeasurementVectorType& lowerBound,
143  MeasurementVectorType& upperBound)
144 {
145  this->Initialize(size);
146 
147  // Sanity check to see if size, lowerBound and upperBound are of the
148  // same length.
149  const MeasurementVectorSizeType measurementVectorSize =
150  this->GetMeasurementVectorSize();
151  MeasurementVectorTraits::Assert( lowerBound, measurementVectorSize,
152  "Length mismatch: VariableDimensionHistogram::Initialize( , )");
153  MeasurementVectorTraits::Assert( upperBound, measurementVectorSize,
154  "Length mismatch: VariableDimensionHistogram::Initialize( , )");
155 
156  float interval;
157  for ( unsigned int i = 0; i < measurementVectorSize; i++)
158  {
159  interval = (float) (upperBound[i] - lowerBound[i])
160  / static_cast< MeasurementType >(size[i]);
161 
162  // Set the min vector and max vector
163  for (unsigned int j = 0; j < static_cast< unsigned int >(size[i] - 1); j++)
164  {
165  this->SetBinMin(i, j, (MeasurementType)(lowerBound[i] +
166  ((float)j * interval)));
167  this->SetBinMax(i, j, (MeasurementType)(lowerBound[i] +
168  (((float)j + 1) * interval)));
169  }
170  this->SetBinMin(i, size[i] - 1,
171  (MeasurementType)(lowerBound[i] +
172  (((float) size[i] - 1) * interval)));
173  this->SetBinMax(i, size[i] - 1,
174  (MeasurementType)(upperBound[i]));
175  }
176 }
177 
178 
180 template< class TMeasurement,
181  class TFrequencyContainer>
183 ::GetIndex(const MeasurementVectorType & measurement,IndexType & index ) const
184 {
185  // Sanity check.. see if index is of the same length as MeasurementVectorSize;
186  const MeasurementVectorSizeType measurementVectorSize =
187  this->GetMeasurementVectorSize();
188  MeasurementVectorTraits::Assert( index, measurementVectorSize,
189  "Length mismatch: VariableDimensionHistogram::GetIndex(MeasurementVectorType, IndexType)");
190  MeasurementVectorTraits::Assert( measurement, measurementVectorSize,
191  "Length mismatch: VariableDimensionHistogram::GetIndex(MeasurementVectorType, IndexType)");
192 
193 
194  // now using something similar to binary search to find
195  // index.
196  unsigned int dim;
197 
198  int begin, mid, end;
199  MeasurementType median;
200  MeasurementType tempMeasurement;
201 
202  for (dim = 0; dim < measurementVectorSize; dim++)
203  {
204  tempMeasurement = measurement[dim];
205  begin = 0;
206  if (tempMeasurement < m_Min[dim][begin])
207  {
208  // one of measurement is below the minimum
209  index[dim] = (long) m_Size[dim];
210  return false;
211  }
212 
213  end = m_Min[dim].size() - 1;
214  if (tempMeasurement >= m_Max[dim][end])
215  {
216  // one of measurement is above the maximum
217  index[dim] = (long) m_Size[dim];
218  return false;
219  }
220 
221  mid = (end + 1) / 2;
222  median = m_Min[dim][mid];
223 
224  while(true)
225  {
226  if (tempMeasurement < median )
227  {
228  end = mid - 1;
229  }
230  else if (tempMeasurement > median)
231  {
232  if (tempMeasurement < m_Max[dim][mid])
233  {
234  index[dim] = mid;
235  break;
236  }
237 
238  begin = mid + 1;
239  }
240  else
241  {
242  // measurement[dim] = m_Min[dim][med]
243  index[dim] = mid;
244  break;
245  }
246  mid = begin + (end - begin) / 2;
247  median = m_Min[dim][mid];
248  } // end of while
249  } // end of for()
250  return true;
251 }
252 
253 template< class TMeasurement,
254  class TFrequencyContainer>
257 ::GetIndex(const InstanceIdentifier &ident) const
258 {
259  InstanceIdentifier ident2 = ident;
260 
261  for (int i = this->GetMeasurementVectorSize() - 1; i > 0; i--)
262  {
263  m_TempIndex[i] = static_cast<IndexValueType>(ident2 / m_OffsetTable[i]);
264  ident2 -= (m_TempIndex[i] * m_OffsetTable[i]);
265  }
266  m_TempIndex[0] = static_cast<IndexValueType>(ident2);
267 
268  return m_TempIndex;
269 }
270 
271 
272 template< class TMeasurement,
273  class TFrequencyContainer >
274 inline bool
276 ::IsIndexOutOfBounds(const IndexType &index) const
277 {
278  // Sanity check.. see if index is of the same length as MeasurementVectorSize;
279  MeasurementVectorTraits::Assert( index, this->GetMeasurementVectorSize(),
280  "Length mismatch: VariableDimensionHistogram::GetIndex(MeasurementVectorType, IndexType)");
281 
282  for (unsigned int dim = 0; dim < this->GetMeasurementVectorSize(); dim++)
283  {
284  if (index[dim] < 0 || index[dim] >= static_cast<IndexValueType>(m_Size[dim]))
285  {
286  return true;
287  }
288  }
289  return false;
290 }
291 
292 template< class TMeasurement,
293  class TFrequencyContainer >
294 inline typename VariableDimensionHistogram<TMeasurement,
295  TFrequencyContainer>::InstanceIdentifier
298 {
299  // Sanity check.. see if index is of the same length as MeasurementVectorSize;
300  MeasurementVectorTraits::Assert( index, this->GetMeasurementVectorSize(),
301  "Length mismatch: VariableDimensionHistogram::GetIndex(MeasurementVectorType, IndexType)");
302 
303  InstanceIdentifier ident = 0;
304  for (int i= this->GetMeasurementVectorSize() - 1; i > 0; i-- )
305  {
306  ident += index[i] * m_OffsetTable[i];
307  }
308 
309  ident += index[0];
310 
311  return ident;
312 }
313 
314 
315 template< class TMeasurement,
316  class TFrequencyContainer >
317 inline const typename VariableDimensionHistogram<TMeasurement,
318  TFrequencyContainer>::MeasurementType&
320 ::GetBinMinFromValue(const unsigned int dimension, const float value ) const
321 {
322  // If the value is lower than any of min value in the VariableDimensionHistogram,
323  // it returns the lowest min value
324  if ( value <= this->m_Min[dimension][0] )
325  {
326  return this->m_Min[dimension][0];
327  }
328 
329  // If the value is higher than any of min value in the VariableDimensionHistogram,
330  // it returns the highest min value
331  if ( value >= m_Min[dimension][m_Size[dimension]-1] )
332  {
333  return m_Min[dimension][this->m_Size[dimension]-1];
334  }
335 
336  for ( int i=0; i < this->m_Size[dimension]; i++ )
337  {
338  if ( (value >= this->m_Min[dimension][i])
339  && (value < this->m_Max[dimension][i]) )
340  {
341  return this->m_Min[dimension][i];
342  }
343  }
344 }
345 
346 template< class TMeasurement,
347  class TFrequencyContainer >
348 inline const typename VariableDimensionHistogram< TMeasurement,
349  TFrequencyContainer >::MeasurementType&
351 ::GetBinMaxFromValue(const unsigned int dimension, const float value ) const
352 {
353  // If the value is lower than any of max value in the VariableDimensionHistogram,
354  // it returns the lowest max value
355  if ( value <= this->m_Max[dimension][0] )
356  {
357  return this->m_Max[dimension][0];
358  }
359 
360  // If the value is higher than any of max value in the VariableDimensionHistogram,
361  // it returns the highest max value
362  if ( value >= m_Max[dimension][m_Size[dimension]-1] )
363  {
364  return m_Max[dimension][this->m_Size[dimension]-1];
365  }
366 
367  for ( int i = 0; i < this->m_Size[dimension]; i++ )
368  {
369  if ( (value >= this->m_Min[dimension][i])
370  && (value < this->m_Max[dimension][i]) )
371  {
372  return this->m_Max[dimension][i];
373  }
374  }
375 }
376 
377 template< class TMeasurement,
378  class TFrequencyContainer >
379 inline typename VariableDimensionHistogram< TMeasurement,
380  TFrequencyContainer >::MeasurementVectorType&
383 {
384  // Sanity check.. see if index is of the same length as MeasurementVectorSize;
385  const MeasurementVectorSizeType measurementVectorSize =
386  this->GetMeasurementVectorSize();
387  MeasurementVectorTraits::Assert( measurement, measurementVectorSize,
388  "Length mismatch: VariableDimensionHistogram::GetIndex(MeasurementVectorType, IndexType)");
389 
390  for ( int i = 0; i < measurementVectorSize; i++ )
391  {
392  m_TempMeasurementVector[i] = this->GetDimensionMinByValue(i,measurement[i]);
393  }
394  return m_TempMeasurementVector;
395 }
396 
397 template< class TMeasurement,
398  class TFrequencyContainer >
399 inline typename VariableDimensionHistogram< TMeasurement,
400  TFrequencyContainer >::MeasurementVectorType&
403 {
404  // Sanity check.. see if index is of the same length as MeasurementVectorSize;
405  const MeasurementVectorSizeType measurementVectorSize =
406  this->GetMeasurementVectorSize();
407  MeasurementVectorTraits::Assert( measurement, measurementVectorSize,
408  "Length mismatch: VariableDimensionHistogram::GetIndex(MeasurementVectorType, IndexType)");
409 
410  for ( int i=0; i < measurementVectorSize; i++ )
411  {
412  m_TempMeasurementVector[i] = this->GetDimensionMaxByValue(i,measurement[i]);
413  }
414  return m_TempMeasurementVector;
415 
416 }
417 
418 template< class TMeasurement,
419  class TFrequencyContainer >
420 inline typename VariableDimensionHistogram< TMeasurement,
421  TFrequencyContainer >::MeasurementVectorType&
424 {
425  // Sanity check.. see if index is of the same length as MeasurementVectorSize;
426  MeasurementVectorTraits::Assert( index, this->GetMeasurementVectorSize(),
427  "Length mismatch: VariableDimensionHistogram::GetIndex(MeasurementVectorType, IndexType)");
428 
429  for ( int i=0; i < this->GetMeasurementVectorSize(); i++ )
430  {
431  m_TempMeasurementVector[i] = this->GetBinMin(i, index[i]);
432  }
433  return m_TempMeasurementVector;
434 }
435 
436 template< class TMeasurement,
437  class TFrequencyContainer >
438 inline typename VariableDimensionHistogram< TMeasurement,
439  TFrequencyContainer >::MeasurementVectorType&
442 {
443  // Sanity check.. see if index is of the same length as MeasurementVectorSize;
444  MeasurementVectorTraits::Assert( index, this->GetMeasurementVectorSize(),
445  "Length mismatch: VariableDimensionHistogram::GetIndex(MeasurementVectorType, IndexType)");
446 
447  for ( int i=0; i < this->GetMeasurementVectorSize(); i++ )
448  {
449  m_TempMeasurementVector[i] = this->GetBinMax(i, index[i]);
450  }
451  return m_TempMeasurementVector;
452 }
453 
454 template< class TMeasurement,
455  class TFrequencyContainer >
456 inline const typename VariableDimensionHistogram< TMeasurement,
457  TFrequencyContainer >::MeasurementVectorType &
460 {
461  // Sanity check.. see if index is of the same length as MeasurementVectorSize;
462  MeasurementVectorTraits::Assert( index, this->GetMeasurementVectorSize(),
463  "Length mismatch: VariableDimensionHistogram::GetIndex(MeasurementVectorType, IndexType)");
464 
465  for ( unsigned int i = 0; i < this->GetMeasurementVectorSize(); i++)
466  {
467  MeasurementType value = (m_Min[i][index[i]] + m_Max[i][index[i]]);
468  m_TempMeasurementVector[i] = static_cast< MeasurementType >( value / 2.0 );
469  }
470  return m_TempMeasurementVector;
471 }
472 
473 template< class TMeasurement,
474  class TFrequencyContainer >
475 inline const typename VariableDimensionHistogram< TMeasurement,
476  TFrequencyContainer >::MeasurementVectorType &
479 {
480  return this->GetMeasurementVector( this->GetIndex(ident) );
481 }
482 
483 template< class TMeasurement,
484  class TFrequencyContainer >
485 inline void
488 {
489  typename Self::Iterator iter = this->Begin();
490  typename Self::Iterator end = this->End();
491 
492  while ( iter != end )
493  {
494  iter.SetFrequency(value);
495  ++iter;
496  }
497 }
498 
499 template< class TMeasurement,
500  class TFrequencyContainer >
501 inline bool
503 ::SetFrequency(const IndexType &index, const FrequencyType value)
504 {
505  // Sanity check.. see if index is of the same length as MeasurementVectorSize;
506  MeasurementVectorTraits::Assert( index, this->GetMeasurementVectorSize(),
507  "Length mismatch: VariableDimensionHistogram::GetIndex(MeasurementVectorType, IndexType)");
508 
509  return this->SetFrequency( this->GetInstanceIdentifier(index), value);
510 }
511 
512 template< class TMeasurement,
513  class TFrequencyContainer >
514 inline bool
516 ::SetFrequency(const MeasurementVectorType &measurement, const FrequencyType value)
517 {
518  // Sanity check.. see if index is of the same length as MeasurementVectorSize;
519  const MeasurementVectorSizeType measurementVectorSize =
520  this->GetMeasurementVectorSize();
521  MeasurementVectorTraits::Assert( measurement, this->GetMeasurementVectorSize(),
522  "Length mismatch: VariableDimensionHistogram::SetFrequency");
523 
524  return this->SetFrequency( this->GetInstanceIdentifier(GetIndex(measurement)), value);
525 }
526 
527 template< class TMeasurement,
528  class TFrequencyContainer >
529 inline bool
531 ::IncreaseFrequency(const IndexType &index, const FrequencyType value)
532 {
533  // Sanity check.. see if index is of the same length as MeasurementVectorSize;
534  MeasurementVectorTraits::Assert( index, this->GetMeasurementVectorSize(),
535  "Length mismatch: VariableDimensionHistogram::GetIndex(MeasurementVectorType, IndexType)");
536 
537  const bool result =
538  this->IncreaseFrequency( this->GetInstanceIdentifier(index), value);
539  return result;
540 }
541 
542 template< class TMeasurement,
543  class TFrequencyContainer >
544 inline bool
546 ::IncreaseFrequency(const MeasurementVectorType &measurement, const FrequencyType value)
547 {
548  // Sanity check.. see if index is of the same length as MeasurementVectorSize;
549  const MeasurementVectorSizeType measurementVectorSize =
550  this->GetMeasurementVectorSize();
551  MeasurementVectorTraits::Assert( measurement, this->GetMeasurementVectorSize(),
552  "Length mismatch: VariableDimensionHistogram::IncreaseFrequency");
553 
554  IndexType index( measurementVectorSize );
555  this->GetIndex( measurement, index );
556  return this->IncreaseFrequency( this->GetInstanceIdentifier( index ), value );
557 }
558 
559 template< class TMeasurement,
560  class TFrequencyContainer >
561 inline typename VariableDimensionHistogram< TMeasurement,
562  TFrequencyContainer >::FrequencyType
564 ::GetFrequency(const IndexType &index) const
565 {
566  MeasurementVectorTraits::Assert( index, this->GetMeasurementVectorSize(),
567  "Length mismatch: VariableDimensionHistogram::GetFrequency");
568 
569  return ( this->GetFrequency( this->GetInstanceIdentifier(index)) );
570 }
571 
572 template< class TMeasurement,
573  class TFrequencyContainer>
574 inline typename VariableDimensionHistogram< TMeasurement,
575  TFrequencyContainer >::MeasurementType
577 ::GetMeasurement(const unsigned long n, const unsigned int dimension) const
578 {
579  return static_cast< MeasurementType >((m_Min[dimension][n] +
580  m_Max[dimension][n]) / 2);
581 }
582 
583 template< class TMeasurement,
584  class TFrequencyContainer >
585 inline typename VariableDimensionHistogram< TMeasurement,
586  TFrequencyContainer >::FrequencyType
588 ::GetFrequency(const unsigned long n, const unsigned int dimension) const
589 {
590  InstanceIdentifier nextOffset = m_OffsetTable[dimension + 1];
591  InstanceIdentifier current = m_OffsetTable[dimension] * n;
592  InstanceIdentifier includeLength = m_OffsetTable[dimension];
593  InstanceIdentifier include;
594  InstanceIdentifier includeEnd;
595  InstanceIdentifier last = m_OffsetTable[this->GetMeasurementVectorSize()];
596 
597  FrequencyType frequency = 0;
598  while (current < last)
599  {
600  include = current;
601  includeEnd = include + includeLength;
602  while(include < includeEnd)
603  {
604  frequency += GetFrequency(include);
605  include++;
606  }
607  current += nextOffset;
608  }
609  return frequency;
610 }
611 
612 template< class TMeasurement,
613  class TFrequencyContainer >
614 inline typename VariableDimensionHistogram< TMeasurement,
615  TFrequencyContainer >::TotalFrequencyType
618 {
619  return m_FrequencyContainer->GetTotalFrequency();
620 }
621 
622 template< class TMeasurement,
623  class TFrequencyContainer >
624 double
626 ::Quantile(const unsigned int dimension, const double &p) const
627 {
629  const unsigned int size = this->GetSize(dimension);
630  double p_n_prev;
631  double p_n;
632  double f_n;
633  double cumulated = 0;
634  double totalFrequency = double( this->GetTotalFrequency() );
635  double binProportion;
636  double min, max, interval;
637 
638  if ( p < 0.5 )
639  {
640  n = 0;
641  p_n = NumericTraits< double >::Zero;
642  do
643  {
644  f_n = this->GetFrequency(n, dimension);
645  cumulated += f_n;
646  p_n_prev = p_n;
647  p_n = cumulated / totalFrequency;
648  n++;
649  }
650  while( n < size && p_n < p);
651 
652  binProportion = f_n / totalFrequency;
653 
654  min = double( this->GetBinMin(dimension, n - 1) );
655  max = double( this->GetBinMax(dimension, n - 1) );
656  interval = max - min;
657  return min + ((p - p_n_prev) / binProportion) * interval;
658  }
659  else
660  {
661  n = size - 1;
662  InstanceIdentifier m = NumericTraits< InstanceIdentifier >::Zero;
663  p_n = NumericTraits< double >::One;
664  do
665  {
666  f_n = this->GetFrequency(n, dimension);
667  cumulated += f_n;
668  p_n_prev = p_n;
669  p_n = NumericTraits< double >::One - cumulated / totalFrequency;
670  n--;
671  m++;
672  }
673  while( m < size && p_n > p);
674 
675  binProportion = f_n / totalFrequency;
676  min = double( this->GetBinMin(dimension, n + 1) );
677  max = double( this->GetBinMax(dimension, n + 1) );
678  interval = max - min;
679  return max - ((p_n_prev - p) / binProportion) * interval;
680  }
681 }
682 
683 template< class TMeasurement,
684  class TFrequencyContainer >
685 void
687 ::PrintSelf(std::ostream& os, Indent indent) const
688 {
689  Superclass::PrintSelf(os,indent);
690 
691  //os << indent << "OffsetTable: " << *m_OffsetTable << std::endl;
692  if(m_ClipBinsAtEnds)
693  {
694  os << indent << "ClipBinsAtEnds: True" << std::endl;
695  }
696  else
697  {
698  os << indent << "ClipBinsAtEnds: False" << std::endl;
699  }
700  os << indent << "FrequencyContainerPointer: " << m_FrequencyContainer
701  << std::endl;
702 }
703 } // end of namespace Statistics
704 } // end of namespace itk
705 
706 #endif

Generated at Sun Feb 3 2013 00:11:22 for Orfeo Toolbox with doxygen 1.8.1.1