17 #ifndef __itkStatisticsAlgorithm_txx
18 #define __itkStatisticsAlgorithm_txx
21 #include "itkNumericTraits.h"
24 namespace Statistics {
26 template<
class TSize >
31 for (k = 0; size != 1; size >>= 1)
44 template<
class TSubsample >
46 unsigned int activeDimension,
47 int beginIndex,
int endIndex,
48 const typename TSubsample::MeasurementType partitionValue)
50 typedef typename TSubsample::MeasurementType MeasurementType;
52 int moveToFrontIndex = beginIndex;
53 int moveToBackIndex = endIndex-1;
59 while( moveToFrontIndex < moveToBackIndex )
64 while( moveToBackIndex >= beginIndex )
66 if( sample->GetMeasurementVectorByIndex(moveToBackIndex)[activeDimension] != partitionValue )
76 while( moveToFrontIndex < endIndex )
78 if( sample->GetMeasurementVectorByIndex(moveToFrontIndex)[activeDimension] == partitionValue )
85 if( moveToFrontIndex < moveToBackIndex )
90 sample->Swap( moveToBackIndex, moveToFrontIndex );
99 moveToFrontIndex = beginIndex;
100 moveToBackIndex = endIndex-1;
101 while( moveToFrontIndex < moveToBackIndex )
106 while( moveToBackIndex >= beginIndex )
108 if( sample->GetMeasurementVectorByIndex(moveToBackIndex)[activeDimension] < partitionValue )
118 while( moveToFrontIndex < endIndex )
120 if( sample->GetMeasurementVectorByIndex(moveToFrontIndex)[activeDimension] > partitionValue )
128 if( moveToFrontIndex < moveToBackIndex )
133 sample->Swap( moveToBackIndex, moveToFrontIndex );
143 int beginOfSectionEqualToPartition = moveToFrontIndex;
144 moveToBackIndex = endIndex-1;
145 while( moveToFrontIndex < moveToBackIndex )
150 while( moveToBackIndex >= beginIndex )
152 if( sample->GetMeasurementVectorByIndex(moveToBackIndex)[activeDimension] == partitionValue )
163 while( moveToFrontIndex < endIndex )
165 if( sample->GetMeasurementVectorByIndex(moveToFrontIndex)[activeDimension] != partitionValue )
172 if( moveToFrontIndex < moveToBackIndex )
177 sample->Swap( moveToBackIndex, moveToFrontIndex );
180 int endOfSectionEqualToPartition = moveToFrontIndex-1;
182 int storeIndex = ( beginOfSectionEqualToPartition + endOfSectionEqualToPartition ) / 2;
184 const MeasurementType pivotValue = sample->GetMeasurementVectorByIndex( storeIndex )[activeDimension];
185 if( pivotValue != partitionValue )
191 for(
int kk=beginIndex; kk<storeIndex; kk++)
193 MeasurementType nodeValue = sample->GetMeasurementVectorByIndex( kk )[activeDimension];
194 MeasurementType boundaryValue = sample->GetMeasurementVectorByIndex( storeIndex )[activeDimension];
195 if( nodeValue > boundaryValue )
197 sample->Swap(kk, storeIndex);
207 template<
class TValue >
234 template<
class TSample >
236 typename TSample::ConstIterator begin,
237 typename TSample::ConstIterator end,
238 typename TSample::MeasurementVectorType &min,
239 typename TSample::MeasurementVectorType &max)
241 typedef typename TSample::MeasurementVectorSizeType MeasurementVectorSizeType;
243 const MeasurementVectorSizeType Dimension = sample->GetMeasurementVectorSize();
246 itkGenericExceptionMacro(
247 <<
"Length of a sample's measurement vector hasn't been set.");
251 "Length mismatch StatisticsAlgorithm::FindSampleBound");
253 "Length mismatch StatisticsAlgorithm::FindSampleBound");
255 unsigned int dimension;
256 typename TSample::MeasurementVectorType temp;
258 min = max = temp = begin.GetMeasurementVector();
261 for (dimension= 0; dimension < Dimension; dimension++)
263 if ( temp[dimension] < min[dimension])
265 min[dimension] = temp[dimension];
267 else if (temp[dimension] > max[dimension])
269 max[dimension] = temp[dimension];
277 temp = begin.GetMeasurementVector();
282 template<
class TSubsample >
287 typename TSubsample::MeasurementVectorType &min,
288 typename TSubsample::MeasurementVectorType &max,
289 typename TSubsample::MeasurementVectorType &mean)
291 typedef typename TSubsample::MeasurementType MeasurementType;
292 typedef typename TSubsample::MeasurementVectorType MeasurementVectorType;
294 typedef typename TSubsample::MeasurementVectorSizeType MeasurementVectorSizeType;
295 const MeasurementVectorSizeType Dimension = sample->GetMeasurementVectorSize();
298 itkGenericExceptionMacro(
299 <<
"Length of a sample's measurement vector hasn't been set.");
304 MeasurementVectorSizeType dimension;
305 MeasurementVectorType temp;
309 min = max = temp = sample->GetMeasurementVectorByIndex(beginIndex);
310 double frequencySum = sample->GetFrequencyByIndex(beginIndex);
315 for (dimension= 0; dimension < Dimension; dimension++)
317 if ( temp[dimension] < min[dimension])
319 min[dimension] = temp[dimension];
321 else if (temp[dimension] > max[dimension])
323 max[dimension] = temp[dimension];
325 sum[dimension] += temp[dimension];
328 if (beginIndex == endIndex)
332 temp = sample->GetMeasurementVectorByIndex(beginIndex);
333 frequencySum += sample->GetFrequencyByIndex(beginIndex);
336 for (
unsigned int i = 0; i < Dimension; i++)
338 mean[i] = (MeasurementType)(sum[i] / frequencySum);
347 template<
class TSubsample >
348 inline typename TSubsample::MeasurementType
350 unsigned int activeDimension,
354 typename TSubsample::MeasurementType medianGuess)
356 typedef typename TSubsample::MeasurementType MeasurementType;
358 int begin = beginIndex;
359 int end = endIndex - 1;
360 int kthIndex = kth + beginIndex;
362 MeasurementType tempMedian;
367 if (medianGuess != NumericTraits< MeasurementType >::NonpositiveMin())
369 tempMedian = medianGuess;
373 const int length = end - begin;
374 const int middle = begin + length / 2;
375 const MeasurementType v1 = sample->GetMeasurementVectorByIndex(begin)[activeDimension];
376 const MeasurementType v2 = sample->GetMeasurementVectorByIndex(end)[activeDimension];
377 const MeasurementType v3 = sample->GetMeasurementVectorByIndex(middle)[activeDimension];
378 tempMedian = MedianOfThree< MeasurementType >( v1, v2, v3 );
386 Partition< TSubsample >(sample, activeDimension, begin, end+1, tempMedian);
388 if( kthIndex == pivotNewIndex )
393 if( kthIndex < pivotNewIndex )
395 end = pivotNewIndex - 1;
399 begin = pivotNewIndex + 1;
407 const int length = end - begin;
408 const MeasurementType v1 = sample->GetMeasurementVectorByIndex(begin)[activeDimension];
409 const MeasurementType v2 = sample->GetMeasurementVectorByIndex(end)[activeDimension];
416 sample->Swap(begin, end);
421 const int middle = begin + length / 2;
422 const MeasurementType v3 = sample->GetMeasurementVectorByIndex(middle)[activeDimension];
423 tempMedian = MedianOfThree< MeasurementType >( v1, v2, v3 );
427 return sample->GetMeasurementVectorByIndex(kthIndex)[activeDimension];
431 template<
class TSubsample >
432 inline typename TSubsample::MeasurementType
434 unsigned int activeDimension,
439 typedef typename TSubsample::MeasurementType MeasurementType;
440 MeasurementType medianGuess = NumericTraits< MeasurementType >::NonpositiveMin();
441 return QuickSelect< TSubsample >(sample, activeDimension,
442 beginIndex, endIndex, kth, medianGuess);
446 template<
class TSubsample >
447 inline typename TSubsample::MeasurementType
449 unsigned int activeDimension,
454 typedef typename TSubsample::MeasurementType MeasurementType;
456 const int nthIndex = beginIndex + nth;
458 int beginElement = beginIndex;
459 int endElement = endIndex;
461 while( endElement - beginElement > 3)
463 const int begin = beginElement;
464 const int end = endElement-1;
465 const int length = endElement - beginElement;
466 const int middle = beginElement + length / 2;
468 const MeasurementType v1 = sample->GetMeasurementVectorByIndex(begin)[activeDimension];
469 const MeasurementType v2 = sample->GetMeasurementVectorByIndex(end)[activeDimension];
470 const MeasurementType v3 = sample->GetMeasurementVectorByIndex(middle)[activeDimension];
472 const MeasurementType tempMedian = MedianOfThree< MeasurementType >( v1, v2, v3 );
474 int cut =
UnguardedPartition( sample, activeDimension, beginElement, endElement, tempMedian );
476 if( cut <= nthIndex )
486 InsertSort( sample, activeDimension, beginElement, endElement );
488 return sample->GetMeasurementVectorByIndex(nthIndex)[activeDimension];
492 template<
class TSubsample >
494 unsigned int activeDimension,
497 typename TSubsample::MeasurementType pivotValue )
499 typedef typename TSubsample::MeasurementType MeasurementType;
502 MeasurementType beginValue =
503 sample->GetMeasurementVectorByIndex(beginIndex)[activeDimension];
505 while( beginValue < pivotValue )
509 beginValue = sample->GetMeasurementVectorByIndex(beginIndex)[activeDimension];
514 MeasurementType endValue =
515 sample->GetMeasurementVectorByIndex(endIndex)[activeDimension];
517 while( pivotValue < endValue )
520 endValue = sample->GetMeasurementVectorByIndex(endIndex)[activeDimension];
523 if( !(beginIndex < endIndex) )
528 sample->Swap( beginIndex, endIndex );
535 template<
class TSubsample >
537 unsigned int activeDimension,
541 int backwardSearchBegin;
544 for (backwardSearchBegin = beginIndex + 1;
545 backwardSearchBegin < endIndex;
546 backwardSearchBegin++)
548 backwardIndex = backwardSearchBegin;
549 while (backwardIndex > beginIndex)
551 typedef typename TSubsample::MeasurementType MeasurementType;
552 const MeasurementType value1 = sample->GetMeasurementVectorByIndex(backwardIndex)[activeDimension];
553 const MeasurementType value2 = sample->GetMeasurementVectorByIndex(backwardIndex - 1)[activeDimension];
555 if( value1 < value2 )
557 sample->Swap(backwardIndex, backwardIndex - 1);
568 template<
class TSubsample >
570 unsigned int activeDimension,
571 int beginIndex,
int endIndex,
int node)
573 int currentNode = node;
577 typedef typename TSubsample::MeasurementType MeasurementType;
578 MeasurementType currentNodeValue =
579 sample->GetMeasurementVectorByIndex(currentNode)[activeDimension];
580 MeasurementType leftChildValue;
581 MeasurementType rightChildValue;
582 MeasurementType largerChildValue;
587 largerChild = leftChild =
588 beginIndex + 2*(currentNode - beginIndex) + 1;
589 rightChild = leftChild + 1;
590 if (leftChild > endIndex - 1)
596 largerChildValue = rightChildValue = leftChildValue =
597 sample->GetMeasurementVectorByIndex(leftChild)[activeDimension];
599 if (rightChild < endIndex)
602 sample->GetMeasurementVectorByIndex(rightChild)[activeDimension];
605 if (leftChildValue < rightChildValue)
607 largerChild = rightChild;
608 largerChildValue = rightChildValue;
611 if (largerChildValue <= currentNodeValue)
617 sample->Swap(currentNode, largerChild);
618 currentNode = largerChild;
622 template<
class TSubsample >
624 unsigned int activeDimension,
631 for (node = beginIndex + (endIndex - beginIndex) / 2 - 1;
632 node >= beginIndex; node--)
634 DownHeap< TSubsample >(sample, activeDimension,
635 beginIndex, endIndex, node);
640 for (newEndIndex = endIndex - 1; newEndIndex >= beginIndex;
643 sample->Swap(beginIndex, newEndIndex);
644 DownHeap< TSubsample >(sample, activeDimension,
645 beginIndex, newEndIndex, beginIndex);
650 template<
class TSubsample >
652 unsigned int activeDimension,
658 typedef typename TSubsample::MeasurementType MeasurementType;
660 int length = endIndex - beginIndex;
662 while(length > sizeThreshold)
666 HeapSort< TSubsample >(sample, activeDimension,
667 beginIndex, endIndex);
672 cut = Partition< TSubsample >(sample, activeDimension,
673 beginIndex, endIndex,
674 MedianOfThree< MeasurementType >
675 (sample->GetMeasurementVectorByIndex(beginIndex)[activeDimension],
676 sample->GetMeasurementVectorByIndex(beginIndex + length/2)[activeDimension],
677 sample->GetMeasurementVectorByIndex(endIndex - 1)[activeDimension]));
678 IntrospectiveSortLoop< TSubsample >(sample, activeDimension,
680 depthLimit, sizeThreshold);
682 length = endIndex - beginIndex;
686 template<
class TSubsample >
688 unsigned int activeDimension,
693 typedef typename TSubsample::MeasurementType MeasurementType;
694 IntrospectiveSortLoop< TSubsample >(sample, activeDimension, beginIndex, endIndex,
695 2 *
FloorLog(endIndex - beginIndex), sizeThreshold);
696 InsertSort< TSubsample >(sample, activeDimension, beginIndex, endIndex);
702 #endif // #ifndef __itkStatisticsAlgorithm_txx