📄 itkstatisticsalgorithm.txx
字号:
typedef typename TSubsample::MeasurementType MeasurementType ;
int begin = beginIndex ;
int end = endIndex - 1 ;
int kthIndex = kth + beginIndex;
MeasurementType tempMedian;
//
// Select a pivot value
//
if (medianGuess != NumericTraits< MeasurementType >::NonpositiveMin())
{
tempMedian = medianGuess ;
}
else
{
const int length = end - begin ;
const int middle = begin + length / 2;
const MeasurementType v1 = sample->GetMeasurementVectorByIndex(begin)[activeDimension];
const MeasurementType v2 = sample->GetMeasurementVectorByIndex(end)[activeDimension];
const MeasurementType v3 = sample->GetMeasurementVectorByIndex(middle)[activeDimension];
tempMedian = MedianOfThree< MeasurementType >( v1, v2, v3 );
}
while( true )
{
// Partition expects the end argument to be one past-the-end of the array.
// The index pivotNewIndex returned by Partition is in the range [begin,end].
int pivotNewIndex =
Partition< TSubsample >(sample, activeDimension, begin, end+1, tempMedian) ;
if( kthIndex == pivotNewIndex )
{
break;
}
if( kthIndex < pivotNewIndex )
{
end = pivotNewIndex - 1;
}
else
{
begin = pivotNewIndex + 1;
}
if( begin > end )
{
break;
}
const int length = end - begin ;
const MeasurementType v1 = sample->GetMeasurementVectorByIndex(begin)[activeDimension];
const MeasurementType v2 = sample->GetMeasurementVectorByIndex(end)[activeDimension];
// current partition has only 1 or 2 elements
if( length < 2 )
{
if( v2 < v1 )
{
sample->Swap(begin, end) ;
}
break;
}
const int middle = begin + length / 2;
const MeasurementType v3 = sample->GetMeasurementVectorByIndex(middle)[activeDimension];
tempMedian = MedianOfThree< MeasurementType >( v1, v2, v3 );
}
return sample->GetMeasurementVectorByIndex(kthIndex)[activeDimension];
}
template< class TSubsample >
inline typename TSubsample::MeasurementType
QuickSelect(TSubsample* sample,
unsigned int activeDimension,
int beginIndex,
int endIndex,
int kth)
{
typedef typename TSubsample::MeasurementType MeasurementType;
MeasurementType medianGuess = NumericTraits< MeasurementType >::NonpositiveMin();
return QuickSelect< TSubsample >(sample, activeDimension,
beginIndex, endIndex, kth, medianGuess);
}
template< class TSubsample >
inline typename TSubsample::MeasurementType
NthElement(TSubsample* sample,
unsigned int activeDimension,
int beginIndex,
int endIndex,
int nth)
{
typedef typename TSubsample::MeasurementType MeasurementType;
const int nthIndex = beginIndex + nth;
int beginElement = beginIndex;
int endElement = endIndex;
while( endElement - beginElement > 3)
{
const int begin = beginElement;
const int end = endElement-1;
const int length = endElement - beginElement ;
const int middle = beginElement + length / 2;
const MeasurementType v1 = sample->GetMeasurementVectorByIndex(begin)[activeDimension];
const MeasurementType v2 = sample->GetMeasurementVectorByIndex(end)[activeDimension];
const MeasurementType v3 = sample->GetMeasurementVectorByIndex(middle)[activeDimension];
const MeasurementType tempMedian = MedianOfThree< MeasurementType >( v1, v2, v3 );
int cut = UnguardedPartition( sample, activeDimension, beginElement, endElement, tempMedian );
if( cut <= nthIndex )
{
beginElement = cut;
}
else
{
endElement = cut;
}
}
InsertSort( sample, activeDimension, beginElement, endElement );
return sample->GetMeasurementVectorByIndex(nthIndex)[activeDimension];
}
template< class TSubsample >
inline int UnguardedPartition(TSubsample* sample,
unsigned int activeDimension,
int beginIndex,
int endIndex,
typename TSubsample::MeasurementType pivotValue )
{
typedef typename TSubsample::MeasurementType MeasurementType;
while( true )
{
MeasurementType beginValue =
sample->GetMeasurementVectorByIndex(beginIndex)[activeDimension];
while( beginValue < pivotValue )
{
++beginIndex;
beginValue = sample->GetMeasurementVectorByIndex(beginIndex)[activeDimension];
}
--endIndex;
MeasurementType endValue =
sample->GetMeasurementVectorByIndex(endIndex)[activeDimension];
while( pivotValue < endValue )
{
--endIndex;
endValue = sample->GetMeasurementVectorByIndex(endIndex)[activeDimension];
}
if( !(beginIndex < endIndex) )
{
return beginIndex;
}
sample->Swap( beginIndex, endIndex );
++beginIndex;
}
}
template< class TSubsample >
inline void InsertSort(TSubsample* sample,
unsigned int activeDimension,
int beginIndex,
int endIndex)
{
int backwardSearchBegin ;
int backwardIndex ;
for (backwardSearchBegin = beginIndex + 1 ;
backwardSearchBegin < endIndex ;
backwardSearchBegin++)
{
backwardIndex = backwardSearchBegin ;
while (backwardIndex > beginIndex)
{
if (sample->GetMeasurementVectorByIndex(backwardIndex)[activeDimension] <
sample->GetMeasurementVectorByIndex(backwardIndex - 1)[activeDimension])
{
sample->Swap(backwardIndex, backwardIndex - 1) ;
}
else
{
break ;
}
--backwardIndex ;
}
}
}
template< class TSubsample >
inline void DownHeap(TSubsample* sample,
unsigned int activeDimension,
int beginIndex, int endIndex, int node)
{
int currentNode = node;
int leftChild ;
int rightChild ;
int largerChild ;
typedef typename TSubsample::MeasurementType MeasurementType ;
MeasurementType currentNodeValue =
sample->GetMeasurementVectorByIndex(currentNode)[activeDimension] ;
MeasurementType leftChildValue ;
MeasurementType rightChildValue ;
MeasurementType largerChildValue ;
while (true)
{
// location of first child
largerChild = leftChild =
beginIndex + 2*(currentNode - beginIndex) + 1 ;
rightChild = leftChild + 1 ;
if (leftChild > endIndex - 1)
{
// leaf node
return ;
}
largerChildValue = rightChildValue = leftChildValue =
sample->GetMeasurementVectorByIndex(leftChild)[activeDimension] ;
if (rightChild < endIndex)
{
rightChildValue =
sample->GetMeasurementVectorByIndex(rightChild)[activeDimension] ;
}
if (leftChildValue < rightChildValue)
{
largerChild = rightChild ;
largerChildValue = rightChildValue ;
}
if (largerChildValue <= currentNodeValue)
{
// the node satisfies heap property
return ;
}
// move down current node value to the larger child
sample->Swap(currentNode, largerChild) ;
currentNode = largerChild ;
}
}
template< class TSubsample >
inline void HeapSort(TSubsample* sample,
unsigned int activeDimension,
int beginIndex,
int endIndex)
{
// construct a heap
int node ;
for (node = beginIndex + (endIndex - beginIndex) / 2 - 1 ;
node >= beginIndex ; node--)
{
DownHeap< TSubsample >(sample, activeDimension,
beginIndex, endIndex, node) ;
}
// sort
int newEndIndex ;
for (newEndIndex = endIndex - 1 ; newEndIndex >= beginIndex ;
--newEndIndex)
{
sample->Swap(beginIndex, newEndIndex);
DownHeap< TSubsample >(sample, activeDimension,
beginIndex, newEndIndex, beginIndex);
}
}
template< class TSubsample >
inline void IntrospectiveSortLoop(TSubsample* sample,
unsigned int activeDimension,
int beginIndex,
int endIndex,
int depthLimit,
int sizeThreshold)
{
typedef typename TSubsample::MeasurementType MeasurementType ;
int length = endIndex - beginIndex ;
int cut ;
while(length > sizeThreshold)
{
if (depthLimit == 0)
{
HeapSort< TSubsample >(sample, activeDimension,
beginIndex, endIndex) ;
return ;
}
--depthLimit ;
cut = Partition< TSubsample >(sample, activeDimension,
beginIndex, endIndex,
MedianOfThree< MeasurementType >
(sample->GetMeasurementVectorByIndex(beginIndex)[activeDimension],
sample->GetMeasurementVectorByIndex(beginIndex + length/2)[activeDimension],
sample->GetMeasurementVectorByIndex(endIndex - 1)[activeDimension])) ;
IntrospectiveSortLoop< TSubsample >(sample, activeDimension,
cut, endIndex,
depthLimit, sizeThreshold) ;
endIndex = cut ;
length = endIndex - beginIndex ;
}
}
template< class TSubsample >
inline void IntrospectiveSort(TSubsample* sample,
unsigned int activeDimension,
int beginIndex,
int endIndex,
int sizeThreshold)
{
typedef typename TSubsample::MeasurementType MeasurementType ;
IntrospectiveSortLoop< TSubsample >(sample, activeDimension, beginIndex, endIndex,
2 * FloorLog(endIndex - beginIndex), sizeThreshold) ;
InsertSort< TSubsample >(sample, activeDimension, beginIndex, endIndex) ;
}
} // end of namespace Statistics
} // end of namespace itk
#endif // #ifndef __itkStatisticsAlgorithm_txx
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -