From cc6bdfb045b10cba9d8085953f90839825200281 Mon Sep 17 00:00:00 2001 From: Andrey Kamaev Date: Thu, 28 Mar 2013 16:12:13 +0400 Subject: [PATCH] Remove inline sorting algorithms from core headers --- apps/haartraining/_cvcommon.h | 9 - apps/haartraining/cvboost.cpp | 54 ++-- apps/haartraining/cvcommon.cpp | 5 - apps/haartraining/cvhaartraining.cpp | 4 +- apps/traincascade/boost.cpp | 26 +- modules/calib3d/src/ptsetreg.cpp | 17 +- modules/contrib/src/spinimages.cpp | 6 +- .../core/include/opencv2/core/internal.hpp | 229 ----------------- .../core/include/opencv2/core/operations.hpp | 231 ------------------ modules/core/src/matrix.cpp | 11 +- modules/features2d/src/mser.cpp | 11 +- modules/imgproc/src/featureselect.cpp | 2 +- modules/imgproc/src/generalized_hough.cpp | 11 +- modules/imgproc/src/hough.cpp | 7 +- modules/legacy/src/planardetect.cpp | 4 +- modules/ml/src/boost.cpp | 18 +- modules/ml/src/ertrees.cpp | 21 +- modules/ml/src/gbt.cpp | 11 +- modules/ml/src/tree.cpp | 39 +-- 19 files changed, 139 insertions(+), 577 deletions(-) diff --git a/apps/haartraining/_cvcommon.h b/apps/haartraining/_cvcommon.h index 5b363f1fce..2155117feb 100644 --- a/apps/haartraining/_cvcommon.h +++ b/apps/haartraining/_cvcommon.h @@ -53,15 +53,6 @@ #define __END__ __CV_END__ #define EXIT __CV_EXIT__ -#define CV_DECLARE_QSORT( func_name, T, less_than ) \ -void func_name( T* array, size_t length, int aux ); - -#define less_than( a, b ) ((a) < (b)) - -CV_DECLARE_QSORT( icvSort_32f, float, less_than ) - -CV_DECLARE_QSORT( icvSort_32s, int, less_than ) - #ifndef PATH_MAX #define PATH_MAX 512 #endif /* PATH_MAX */ diff --git a/apps/haartraining/cvboost.cpp b/apps/haartraining/cvboost.cpp index 8dfd3dd316..dcde26c13b 100644 --- a/apps/haartraining/cvboost.cpp +++ b/apps/haartraining/cvboost.cpp @@ -76,15 +76,18 @@ typedef struct CvValArray size_t step; } CvValArray; -#define CMP_VALUES( idx1, idx2 ) \ - ( *( (float*) (aux->data + ((int) (idx1)) * aux->step ) ) < \ - *( (float*) (aux->data + ((int) (idx2)) * aux->step ) ) ) - -static CV_IMPLEMENT_QSORT_EX( icvSortIndexedValArray_16s, short, CMP_VALUES, CvValArray* ) - -static CV_IMPLEMENT_QSORT_EX( icvSortIndexedValArray_32s, int, CMP_VALUES, CvValArray* ) - -static CV_IMPLEMENT_QSORT_EX( icvSortIndexedValArray_32f, float, CMP_VALUES, CvValArray* ) +template +class LessThanValArray +{ +public: + LessThanValArray( const T* _aux ) : aux(_aux) {} + bool operator()(Idx a, Idx b) const + { + return *( (float*) (aux->data + ((int) (a)) * aux->step ) ) < + *( (float*) (aux->data + ((int) (b)) * aux->step ) ); + } + const T* aux; +}; CV_BOOST_IMPL void cvGetSortedIndices( CvMat* val, CvMat* idx, int sortcols ) @@ -130,8 +133,9 @@ void cvGetSortedIndices( CvMat* val, CvMat* idx, int sortcols ) { CV_MAT_ELEM( *idx, short, i, j ) = (short) j; } - icvSortIndexedValArray_16s( (short*) (idx->data.ptr + (size_t)i * idx->step), - idx->cols, &va ); + std::sort((short*) (idx->data.ptr + (size_t)i * idx->step), + (short*) (idx->data.ptr + (size_t)i * idx->step) + idx->cols, + LessThanValArray(&va)); va.data += istep; } break; @@ -143,8 +147,9 @@ void cvGetSortedIndices( CvMat* val, CvMat* idx, int sortcols ) { CV_MAT_ELEM( *idx, int, i, j ) = j; } - icvSortIndexedValArray_32s( (int*) (idx->data.ptr + (size_t)i * idx->step), - idx->cols, &va ); + std::sort((int*) (idx->data.ptr + (size_t)i * idx->step), + (int*) (idx->data.ptr + (size_t)i * idx->step) + idx->cols, + LessThanValArray(&va)); va.data += istep; } break; @@ -156,8 +161,9 @@ void cvGetSortedIndices( CvMat* val, CvMat* idx, int sortcols ) { CV_MAT_ELEM( *idx, float, i, j ) = (float) j; } - icvSortIndexedValArray_32f( (float*) (idx->data.ptr + (size_t)i * idx->step), - idx->cols, &va ); + std::sort((float*) (idx->data.ptr + (size_t)i * idx->step), + (float*) (idx->data.ptr + (size_t)i * idx->step) + idx->cols, + LessThanValArray(&va)); va.data += istep; } break; @@ -545,7 +551,7 @@ CvClassifier* cvCreateStumpClassifier( CvMat* trainData, va.data = data + i * ((size_t) cstep); va.step = sstep; - icvSortIndexedValArray_32s( idx, l, &va ); + std::sort(idx, idx + l, LessThanValArray(&va)); if( findStumpThreshold_32s[(int) ((CvStumpTrainParams*) trainParams)->error] ( data + i * ((size_t) cstep), sstep, wdata, wstep, ydata, ystep, (uchar*) idx, sizeof( int ), l, @@ -1028,7 +1034,7 @@ CvClassifier* cvCreateMTStumpClassifier( CvMat* trainData, { va.data = t_data + ti * t_cstep; va.step = t_sstep; - icvSortIndexedValArray_32s( t_idx, l, &va ); + std::sort(t_idx, t_idx + l, LessThanValArray(&va)); if( findStumpThreshold_32s[stumperror]( t_data + ti * t_cstep, t_sstep, wdata, wstep, ydata, ystep, @@ -2096,7 +2102,7 @@ static void icvZeroApproxMed( float* approx, CvBtTrainer* trainer ) trainer->f[i] = *((float*) (trainer->ydata + idx * trainer->ystep)); } - icvSort_32f( trainer->f, trainer->numsamples, 0 ); + std::sort(trainer->f, trainer->f + trainer->numsamples); approx[0] = trainer->f[trainer->numsamples / 2]; } @@ -2341,7 +2347,7 @@ static void icvBtNext_LADREG( CvCARTClassifier** trees, CvBtTrainer* trainer ) } if( respnum > 0 ) { - icvSort_32f( resp, respnum, 0 ); + std::sort(resp, resp + respnum); val = resp[respnum / 2]; } else @@ -2394,7 +2400,7 @@ static void icvBtNext_MREG( CvCARTClassifier** trees, CvBtTrainer* trainer ) } /* delta = quantile_alpha{abs(resid_i)} */ - icvSort_32f( resp, trainer->numsamples, 0 ); + std::sort(resp, resp + trainer->numsamples); delta = resp[(int)(trainer->param[1] * (trainer->numsamples - 1))]; /* yhat_i */ @@ -2434,7 +2440,7 @@ static void icvBtNext_MREG( CvCARTClassifier** trees, CvBtTrainer* trainer ) if( respnum > 0 ) { /* rhat = median(y_i - F_(m-1)(x_i)) */ - icvSort_32f( resp, respnum, 0 ); + std::sort(resp, resp + respnum); rhat = resp[respnum / 2]; /* val = sum{sign(r_i - rhat_i) * min(delta, abs(r_i - rhat_i)} @@ -2531,7 +2537,7 @@ static void icvBtNext_L2CLASS( CvCARTClassifier** trees, CvBtTrainer* trainer ) float threshold; int count; - icvSort_32f( sorted_weights, trainer->numsamples, 0 ); + std::sort(sorted_weights, sorted_weights + trainer->numsamples); sum_weights *= (1.0F - trainer->param[1]); @@ -2693,7 +2699,7 @@ static void icvBtNext_LKCLASS( CvCARTClassifier** trees, CvBtTrainer* trainer ) float threshold; int count; - icvSort_32f( sorted_weights, trainer->numsamples, 0 ); + std::sort(sorted_weights, sorted_weights + trainer->numsamples); sum_weights *= (1.0F - trainer->param[1]); @@ -3504,7 +3510,7 @@ CvMat* cvTrimWeights( CvMat* weights, CvMat* idx, float factor ) sum_weights += sorted_weights[i]; } - icvSort_32f( sorted_weights, num, 0 ); + std::sort(sorted_weights, sorted_weights + num); sum_weights *= (1.0F - factor); diff --git a/apps/haartraining/cvcommon.cpp b/apps/haartraining/cvcommon.cpp index 013256b6d8..e23fab263b 100644 --- a/apps/haartraining/cvcommon.cpp +++ b/apps/haartraining/cvcommon.cpp @@ -50,11 +50,6 @@ #include #endif /* _WIN32 */ - -CV_IMPLEMENT_QSORT( icvSort_32f, float, less_than ) - -CV_IMPLEMENT_QSORT( icvSort_32s, int, less_than ) - int icvMkDir( const char* filename ) { char path[PATH_MAX]; diff --git a/apps/haartraining/cvhaartraining.cpp b/apps/haartraining/cvhaartraining.cpp index 661bc959be..569169fc5d 100644 --- a/apps/haartraining/cvhaartraining.cpp +++ b/apps/haartraining/cvhaartraining.cpp @@ -1088,7 +1088,7 @@ CvIntHaarClassifier* icvCreateCARTStageClassifier( CvHaarTrainingData* data, numpos++; } } - icvSort_32f( eval.data.fl, numpos, 0 ); + std::sort(eval.data.fl, eval.data.fl + numpos); threshold = eval.data.fl[(int) ((1.0F - minhitrate) * numpos)]; numneg = 0; @@ -2291,7 +2291,7 @@ static CvMat* icvGetUsedValues( CvHaarTrainingData* training_data, feature_idx->data.i[total++] = cart->compidx[j]; } } - icvSort_32s( feature_idx->data.i, total, 0 ); + std::sort(feature_idx->data.i, feature_idx->data.i + total); last = 0; for( i = 1; i < total; i++ ) diff --git a/apps/traincascade/boost.cpp b/apps/traincascade/boost.cpp index 1b0f390a5b..0486bda4f5 100644 --- a/apps/traincascade/boost.cpp +++ b/apps/traincascade/boost.cpp @@ -18,12 +18,14 @@ logRatio( double val ) return log( val/(1. - val) ); } -#define CV_CMP_FLT(i,j) (i < j) -static CV_IMPLEMENT_QSORT_EX( icvSortFlt, float, CV_CMP_FLT, const float* ) - -#define CV_CMP_NUM_IDX(i,j) (aux[i] < aux[j]) -static CV_IMPLEMENT_QSORT_EX( icvSortIntAux, int, CV_CMP_NUM_IDX, const float* ) -static CV_IMPLEMENT_QSORT_EX( icvSortUShAux, unsigned short, CV_CMP_NUM_IDX, const float* ) +template +class LessThanIdx +{ +public: + LessThanIdx( const T* _arr ) : arr(_arr) {} + bool operator()(Idx a, Idx b) const { return arr[a] < arr[b]; } + const T* arr; +}; #define CV_THRESHOLD_EPS (0.00001F) @@ -722,7 +724,7 @@ void CvCascadeBoostTrainData::get_ord_var_data( CvDTreeNode* n, int vi, float* o sampleValues[i] = (*featureEvaluator)( vi, sampleIndices[i]); } } - icvSortIntAux( sortedIndicesBuf, nodeSampleCount, &sampleValues[0] ); + std::sort(sortedIndicesBuf, sortedIndicesBuf + nodeSampleCount, LessThanIdx(&sampleValues[0]) ); for( int i = 0; i < nodeSampleCount; i++ ) ordValuesBuf[i] = (&sampleValues[0])[sortedIndicesBuf[i]]; *sortedIndices = sortedIndicesBuf; @@ -791,9 +793,9 @@ struct FeatureIdxOnlyPrecalc *(idst + fi*sample_count + si) = si; } if ( is_buf_16u ) - icvSortUShAux( udst + fi*sample_count, sample_count, valCachePtr ); + std::sort(udst + fi*sample_count, udst + (fi + 1)*sample_count, LessThanIdx(valCachePtr) ); else - icvSortIntAux( idst + fi*sample_count, sample_count, valCachePtr ); + std::sort(idst + fi*sample_count, idst + (fi + 1)*sample_count, LessThanIdx(valCachePtr) ); } } const CvFeatureEvaluator* featureEvaluator; @@ -827,9 +829,9 @@ struct FeatureValAndIdxPrecalc *(idst + fi*sample_count + si) = si; } if ( is_buf_16u ) - icvSortUShAux( udst + fi*sample_count, sample_count, valCache->ptr(fi) ); + std::sort(idst + fi*sample_count, idst + (fi + 1)*sample_count, LessThanIdx(valCache->ptr(fi)) ); else - icvSortIntAux( idst + fi*sample_count, sample_count, valCache->ptr(fi) ); + std::sort(idst + fi*sample_count, idst + (fi + 1)*sample_count, LessThanIdx(valCache->ptr(fi)) ); } } const CvFeatureEvaluator* featureEvaluator; @@ -1602,7 +1604,7 @@ bool CvCascadeBoost::isErrDesired() if( ((CvCascadeBoostTrainData*)data)->featureEvaluator->getCls( i ) == 1.0F ) eval[numPos++] = predict( i, true ); - icvSortFlt( &eval[0], numPos, 0 ); + std::sort(&eval[0], &eval[0] + numPos); int thresholdIdx = (int)((1.0F - minHitRate) * numPos); diff --git a/modules/calib3d/src/ptsetreg.cpp b/modules/calib3d/src/ptsetreg.cpp index 58cad5cf38..6c5f20f7ca 100644 --- a/modules/calib3d/src/ptsetreg.cpp +++ b/modules/calib3d/src/ptsetreg.cpp @@ -154,7 +154,7 @@ public: continue; break; } - + return i == modelPoints && iters < maxAttempts; } @@ -235,7 +235,7 @@ public: } } } - + if( maxGoodCount > 0 ) { if( bestMask.data != bestMask0.data ) @@ -250,7 +250,7 @@ public: } else _model.release(); - + return result; } @@ -267,9 +267,6 @@ public: int maxIters; }; - -static CV_IMPLEMENT_QSORT( sortDistances, int, CV_LT ) - class LMeDSPointSetRegistrator : public RANSACPointSetRegistrator { public: @@ -347,7 +344,7 @@ public: else errf = err; CV_Assert( errf.isContinuous() && errf.type() == CV_32F && (int)errf.total() == count ); - sortDistances( (int*)errf.data, count, 0 ); + std::sort((int*)errf.data, (int*)errf.data + count); double median = count % 2 != 0 ? errf.at(count/2) : (errf.at(count/2-1) + errf.at(count/2))*0.5; @@ -359,7 +356,7 @@ public: } } } - + if( minMedian < DBL_MAX ) { sigma = 2.5*1.4826*(1 + 5./(count - modelPoints))*std::sqrt(minMedian); @@ -378,7 +375,7 @@ public: } else _model.release(); - + return result; } @@ -534,7 +531,7 @@ int cv::estimateAffine3D(InputArray _from, InputArray _to, const double epsilon = DBL_EPSILON; param1 = param1 <= 0 ? 3 : param1; param2 = (param2 < epsilon) ? 0.99 : (param2 > 1 - epsilon) ? 0.99 : param2; - + return createRANSACPointSetRegistrator(new Affine3DEstimatorCallback, 4, param1, param2)->run(dFrom, dTo, _out, _inliers); } diff --git a/modules/contrib/src/spinimages.cpp b/modules/contrib/src/spinimages.cpp index fd580b566a..291c66f8a0 100644 --- a/modules/contrib/src/spinimages.cpp +++ b/modules/contrib/src/spinimages.cpp @@ -809,7 +809,7 @@ void cv::SpinImageModel::selectRandomSubset(float ratio) left[pos] = left.back(); left.resize(left.size() - 1); } - sort(subset, std::less()); + std::sort(subset.begin(), subset.end()); } } @@ -928,7 +928,7 @@ void cv::SpinImageModel::matchSpinToModel(const Mat& spin, std::vector& ind if(total < 5) return; - sort(cleanCorrs, std::less()); + std::sort(cleanCorrs.begin(), cleanCorrs.end()); float lower_fourth = cleanCorrs[(1 * total) / 4 - 1]; float upper_fourth = cleanCorrs[(3 * total) / 4 - 0]; @@ -1016,7 +1016,7 @@ private: std::vector nonzero(model.spinImages.rows); for(int i = 0; i < model.spinImages.rows; ++i) nonzero[i] = countNonZero(model.spinImages.row(i)); - sort(nonzero, std::less()); + std::sort(nonzero.begin(), nonzero.end()); model.lambda = static_cast( nonzero[ nonzero.size()/2 ] ) / 2; } diff --git a/modules/core/include/opencv2/core/internal.hpp b/modules/core/include/opencv2/core/internal.hpp index d8a623fbb5..bb2eed2eae 100644 --- a/modules/core/include/opencv2/core/internal.hpp +++ b/modules/core/include/opencv2/core/internal.hpp @@ -455,235 +455,6 @@ CV_INLINE CvSize cvGetMatSize( const CvMat* mat ) #define CV_DESCALE(x,n) (((x) + (1 << ((n)-1))) >> (n)) #define CV_FLT_TO_FIX(x,n) cvRound((x)*(1<<(n))) -/****************************************************************************************\ - - Generic implementation of QuickSort algorithm. - ---------------------------------------------- - Using this macro user can declare customized sort function that can be much faster - than built-in qsort function because of lower overhead on elements - comparison and exchange. The macro takes less_than (or LT) argument - a macro or function - that takes 2 arguments returns non-zero if the first argument should be before the second - one in the sorted sequence and zero otherwise. - - Example: - - Suppose that the task is to sort points by ascending of y coordinates and if - y's are equal x's should ascend. - - The code is: - ------------------------------------------------------------------------------ - #define cmp_pts( pt1, pt2 ) \ - ((pt1).y < (pt2).y || ((pt1).y < (pt2).y && (pt1).x < (pt2).x)) - - [static] CV_IMPLEMENT_QSORT( icvSortPoints, CvPoint, cmp_pts ) - ------------------------------------------------------------------------------ - - After that the function "void icvSortPoints( CvPoint* array, size_t total, int aux );" - is available to user. - - aux is an additional parameter, which can be used when comparing elements. - The current implementation was derived from *BSD system qsort(): - - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - -\****************************************************************************************/ - -#define CV_IMPLEMENT_QSORT_EX( func_name, T, LT, user_data_type ) \ -void func_name( T *array, size_t total, user_data_type aux ) \ -{ \ - int isort_thresh = 7; \ - T t; \ - int sp = 0; \ - \ - struct \ - { \ - T *lb; \ - T *ub; \ - } \ - stack[48]; \ - \ - aux = aux; \ - \ - if( total <= 1 ) \ - return; \ - \ - stack[0].lb = array; \ - stack[0].ub = array + (total - 1); \ - \ - while( sp >= 0 ) \ - { \ - T* left = stack[sp].lb; \ - T* right = stack[sp--].ub; \ - \ - for(;;) \ - { \ - int i, n = (int)(right - left) + 1, m; \ - T* ptr; \ - T* ptr2; \ - \ - if( n <= isort_thresh ) \ - { \ - insert_sort: \ - for( ptr = left + 1; ptr <= right; ptr++ ) \ - { \ - for( ptr2 = ptr; ptr2 > left && LT(ptr2[0],ptr2[-1]); ptr2--) \ - CV_SWAP( ptr2[0], ptr2[-1], t ); \ - } \ - break; \ - } \ - else \ - { \ - T* left0; \ - T* left1; \ - T* right0; \ - T* right1; \ - T* pivot; \ - T* a; \ - T* b; \ - T* c; \ - int swap_cnt = 0; \ - \ - left0 = left; \ - right0 = right; \ - pivot = left + (n/2); \ - \ - if( n > 40 ) \ - { \ - int d = n / 8; \ - a = left, b = left + d, c = left + 2*d; \ - left = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a)) \ - : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c)); \ - \ - a = pivot - d, b = pivot, c = pivot + d; \ - pivot = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a)) \ - : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c)); \ - \ - a = right - 2*d, b = right - d, c = right; \ - right = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a)) \ - : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c)); \ - } \ - \ - a = left, b = pivot, c = right; \ - pivot = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a)) \ - : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c)); \ - if( pivot != left0 ) \ - { \ - CV_SWAP( *pivot, *left0, t ); \ - pivot = left0; \ - } \ - left = left1 = left0 + 1; \ - right = right1 = right0; \ - \ - for(;;) \ - { \ - while( left <= right && !LT(*pivot, *left) ) \ - { \ - if( !LT(*left, *pivot) ) \ - { \ - if( left > left1 ) \ - CV_SWAP( *left1, *left, t ); \ - swap_cnt = 1; \ - left1++; \ - } \ - left++; \ - } \ - \ - while( left <= right && !LT(*right, *pivot) ) \ - { \ - if( !LT(*pivot, *right) ) \ - { \ - if( right < right1 ) \ - CV_SWAP( *right1, *right, t ); \ - swap_cnt = 1; \ - right1--; \ - } \ - right--; \ - } \ - \ - if( left > right ) \ - break; \ - CV_SWAP( *left, *right, t ); \ - swap_cnt = 1; \ - left++; \ - right--; \ - } \ - \ - if( swap_cnt == 0 ) \ - { \ - left = left0, right = right0; \ - goto insert_sort; \ - } \ - \ - n = MIN( (int)(left1 - left0), (int)(left - left1) ); \ - for( i = 0; i < n; i++ ) \ - CV_SWAP( left0[i], left[i-n], t ); \ - \ - n = MIN( (int)(right0 - right1), (int)(right1 - right) ); \ - for( i = 0; i < n; i++ ) \ - CV_SWAP( left[i], right0[i-n+1], t ); \ - n = (int)(left - left1); \ - m = (int)(right1 - right); \ - if( n > 1 ) \ - { \ - if( m > 1 ) \ - { \ - if( n > m ) \ - { \ - stack[++sp].lb = left0; \ - stack[sp].ub = left0 + n - 1; \ - left = right0 - m + 1, right = right0; \ - } \ - else \ - { \ - stack[++sp].lb = right0 - m + 1; \ - stack[sp].ub = right0; \ - left = left0, right = left0 + n - 1; \ - } \ - } \ - else \ - left = left0, right = left0 + n - 1; \ - } \ - else if( m > 1 ) \ - left = right0 - m + 1, right = right0; \ - else \ - break; \ - } \ - } \ - } \ -} - -#define CV_IMPLEMENT_QSORT( func_name, T, cmp ) \ - CV_IMPLEMENT_QSORT_EX( func_name, T, cmp, int ) - /****************************************************************************************\ * Structures and macros for integration with IPP * \****************************************************************************************/ diff --git a/modules/core/include/opencv2/core/operations.hpp b/modules/core/include/opencv2/core/operations.hpp index 26f91461a5..4a4714a0bc 100644 --- a/modules/core/include/opencv2/core/operations.hpp +++ b/modules/core/include/opencv2/core/operations.hpp @@ -3108,237 +3108,6 @@ template static inline _Tp gcd(_Tp a, _Tp b) return a; } -/****************************************************************************************\ - - Generic implementation of QuickSort algorithm - Use it as: vector<_Tp> a; ... sort(a,); - - The current implementation was derived from *BSD system qsort(): - - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - -\****************************************************************************************/ - -template void sort( std::vector<_Tp>& vec, _LT LT=_LT() ) -{ - int isort_thresh = 7; - int sp = 0; - - struct - { - _Tp *lb; - _Tp *ub; - } stack[48]; - - size_t total = vec.size(); - - if( total <= 1 ) - return; - - _Tp* arr = &vec[0]; - stack[0].lb = arr; - stack[0].ub = arr + (total - 1); - - while( sp >= 0 ) - { - _Tp* left = stack[sp].lb; - _Tp* right = stack[sp--].ub; - - for(;;) - { - int i, n = (int)(right - left) + 1, m; - _Tp* ptr; - _Tp* ptr2; - - if( n <= isort_thresh ) - { - insert_sort: - for( ptr = left + 1; ptr <= right; ptr++ ) - { - for( ptr2 = ptr; ptr2 > left && LT(ptr2[0],ptr2[-1]); ptr2--) - std::swap( ptr2[0], ptr2[-1] ); - } - break; - } - else - { - _Tp* left0; - _Tp* left1; - _Tp* right0; - _Tp* right1; - _Tp* pivot; - _Tp* a; - _Tp* b; - _Tp* c; - int swap_cnt = 0; - - left0 = left; - right0 = right; - pivot = left + (n/2); - - if( n > 40 ) - { - int d = n / 8; - a = left, b = left + d, c = left + 2*d; - left = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a)) - : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c)); - - a = pivot - d, b = pivot, c = pivot + d; - pivot = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a)) - : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c)); - - a = right - 2*d, b = right - d, c = right; - right = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a)) - : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c)); - } - - a = left, b = pivot, c = right; - pivot = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a)) - : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c)); - if( pivot != left0 ) - { - std::swap( *pivot, *left0 ); - pivot = left0; - } - left = left1 = left0 + 1; - right = right1 = right0; - - for(;;) - { - while( left <= right && !LT(*pivot, *left) ) - { - if( !LT(*left, *pivot) ) - { - if( left > left1 ) - std::swap( *left1, *left ); - swap_cnt = 1; - left1++; - } - left++; - } - - while( left <= right && !LT(*right, *pivot) ) - { - if( !LT(*pivot, *right) ) - { - if( right < right1 ) - std::swap( *right1, *right ); - swap_cnt = 1; - right1--; - } - right--; - } - - if( left > right ) - break; - std::swap( *left, *right ); - swap_cnt = 1; - left++; - right--; - } - - if( swap_cnt == 0 ) - { - left = left0, right = right0; - goto insert_sort; - } - - n = std::min( (int)(left1 - left0), (int)(left - left1) ); - for( i = 0; i < n; i++ ) - std::swap( left0[i], left[i-n] ); - - n = std::min( (int)(right0 - right1), (int)(right1 - right) ); - for( i = 0; i < n; i++ ) - std::swap( left[i], right0[i-n+1] ); - n = (int)(left - left1); - m = (int)(right1 - right); - if( n > 1 ) - { - if( m > 1 ) - { - if( n > m ) - { - stack[++sp].lb = left0; - stack[sp].ub = left0 + n - 1; - left = right0 - m + 1, right = right0; - } - else - { - stack[++sp].lb = right0 - m + 1; - stack[sp].ub = right0; - left = left0, right = left0 + n - 1; - } - } - else - left = left0, right = left0 + n - 1; - } - else if( m > 1 ) - left = right0 - m + 1, right = right0; - else - break; - } - } - } -} - -template class CV_EXPORTS LessThan -{ -public: - bool operator()(const _Tp& a, const _Tp& b) const { return a < b; } -}; - -template class CV_EXPORTS GreaterEq -{ -public: - bool operator()(const _Tp& a, const _Tp& b) const { return a >= b; } -}; - -template class CV_EXPORTS LessThanIdx -{ -public: - LessThanIdx( const _Tp* _arr ) : arr(_arr) {} - bool operator()(int a, int b) const { return arr[a] < arr[b]; } - const _Tp* arr; -}; - -template class CV_EXPORTS GreaterEqIdx -{ -public: - GreaterEqIdx( const _Tp* _arr ) : arr(_arr) {} - bool operator()(int a, int b) const { return arr[a] >= arr[b]; } - const _Tp* arr; -}; - - // This function splits the input sequence or set into one or more equivalence classes and // returns the vector of labels - 0-based class indexes for each element. // predicate(a,b) returns true if the two sequence elements certainly belong to the same class. diff --git a/modules/core/src/matrix.cpp b/modules/core/src/matrix.cpp index 8336a28683..07a5d30a48 100644 --- a/modules/core/src/matrix.cpp +++ b/modules/core/src/matrix.cpp @@ -2393,7 +2393,7 @@ template static void sort_( const Mat& src, Mat& dst, int flags ) for( j = 0; j < len; j++ ) ptr[j] = ((const T*)(src.data + src.step*j))[i]; } - std::sort( ptr, ptr + len, LessThan() ); + std::sort( ptr, ptr + len ); if( sortDescending ) for( j = 0; j < len/2; j++ ) std::swap(ptr[j], ptr[len-1-j]); @@ -2403,6 +2403,15 @@ template static void sort_( const Mat& src, Mat& dst, int flags ) } } +template class LessThanIdx +{ +public: + LessThanIdx( const _Tp* _arr ) : arr(_arr) {} + bool operator()(int a, int b) const { return arr[a] < arr[b]; } + const _Tp* arr; +}; + + template static void sortIdx_( const Mat& src, Mat& dst, int flags ) { diff --git a/modules/features2d/src/mser.cpp b/modules/features2d/src/mser.cpp index 6581612dfc..ebd1f571c4 100644 --- a/modules/features2d/src/mser.cpp +++ b/modules/features2d/src/mser.cpp @@ -1054,10 +1054,11 @@ static int preprocessMSER_8UC3( MSCRNode* node, return Ne; } -#define cmp_mscr_edge(edge1, edge2) \ - ((edge1).chi < (edge2).chi) - -static CV_IMPLEMENT_QSORT( QuickSortMSCREdge, MSCREdge, cmp_mscr_edge ) +class LessThanEdge +{ +public: + bool operator()(const MSCREdge& a, const MSCREdge& b) const { return a.chi < b.chi; } +}; // to find the root of one region static MSCRNode* findMSCR( MSCRNode* x ) @@ -1112,7 +1113,7 @@ extractMSER_8UC3( CvMat* src, CvMat* dy = cvCreateMat( src->rows-1, src->cols, CV_64FC1 ); Ne = preprocessMSER_8UC3( map, edge, &emean, src, mask, dx, dy, Ne, params.edgeBlurSize ); emean = emean / (double)Ne; - QuickSortMSCREdge( edge, Ne, 0 ); + std::sort(edge, edge + Ne, LessThanEdge()); MSCREdge* edge_ub = edge+Ne; MSCREdge* edgeptr = edge; TempMSCR* mscrptr = mscr; diff --git a/modules/imgproc/src/featureselect.cpp b/modules/imgproc/src/featureselect.cpp index bcb9bd7091..8c740382f2 100644 --- a/modules/imgproc/src/featureselect.cpp +++ b/modules/imgproc/src/featureselect.cpp @@ -92,7 +92,7 @@ void cv::goodFeaturesToTrack( InputArray _image, OutputArray _corners, } } - sort( tmpCorners, greaterThanPtr() ); + std::sort( tmpCorners.begin(), tmpCorners.end(), greaterThanPtr() ); std::vector corners; size_t i, j, total = tmpCorners.size(), ncorners = 0; diff --git a/modules/imgproc/src/generalized_hough.cpp b/modules/imgproc/src/generalized_hough.cpp index ab0890ef83..41a4e72b2e 100644 --- a/modules/imgproc/src/generalized_hough.cpp +++ b/modules/imgproc/src/generalized_hough.cpp @@ -157,8 +157,13 @@ namespace releaseVector(voteOutBuf); } - #define votes_cmp_gt(l1, l2) (aux[l1][0] > aux[l2][0]) - static CV_IMPLEMENT_QSORT_EX( sortIndexies, size_t, votes_cmp_gt, const Vec3i* ) + class Vec3iGreaterThanIdx + { + public: + Vec3iGreaterThanIdx( const Vec3i* _arr ) : arr(_arr) {} + bool operator()(size_t a, size_t b) const { return arr[a][0] > arr[b][0]; } + const Vec3i* arr; + }; void GHT_Pos::filterMinDist() { @@ -173,7 +178,7 @@ namespace std::vector indexies(oldSize); for (size_t i = 0; i < oldSize; ++i) indexies[i] = i; - sortIndexies(&indexies[0], oldSize, &oldVoteBuf[0]); + std::sort(indexies.begin(), indexies.end(), Vec3iGreaterThanIdx(&oldVoteBuf[0])); posOutBuf.clear(); voteOutBuf.clear(); diff --git a/modules/imgproc/src/hough.cpp b/modules/imgproc/src/hough.cpp index 42901c2434..f33c6d2033 100644 --- a/modules/imgproc/src/hough.cpp +++ b/modules/imgproc/src/hough.cpp @@ -56,7 +56,10 @@ struct LinePolar struct hough_cmp_gt { hough_cmp_gt(const int* _aux) : aux(_aux) {} - bool operator()(int l1, int l2) const { return aux[l1] > aux[l2]; } + bool operator()(int l1, int l2) const + { + return aux[l1] > aux[l2] || (aux[l1] == aux[l2] && l1 < l2); + } const int* aux; }; @@ -128,7 +131,7 @@ HoughLinesStandard( const Mat& img, float rho, float theta, } // stage 3. sort the detected lines by accumulator value - cv::sort(_sort_buf, hough_cmp_gt(accum)); + std::sort(_sort_buf.begin(), _sort_buf.end(), hough_cmp_gt(accum)); // stage 4. store the first min(total,linesMax) lines to the output buffer linesMax = std::min(linesMax, (int)_sort_buf.size()); diff --git a/modules/legacy/src/planardetect.cpp b/modules/legacy/src/planardetect.cpp index ce0572013f..8faf9e79a2 100644 --- a/modules/legacy/src/planardetect.cpp +++ b/modules/legacy/src/planardetect.cpp @@ -389,7 +389,7 @@ void LDetector::getMostStable2D(const Mat& image, std::vector& keypoin if( (int)keypoints.size() > maxPoints ) { - sort(keypoints, CmpKeypointScores()); + std::sort(keypoints.begin(), keypoints.end(), CmpKeypointScores()); keypoints.resize(maxPoints); } } @@ -602,7 +602,7 @@ void LDetector::operator()(const std::vector& pyr, std::vector& k if( maxCount > 0 && keypoints.size() > (size_t)maxCount ) { - sort(keypoints, CmpKeypointScores()); + std::sort(keypoints.begin(), keypoints.end(), CmpKeypointScores()); keypoints.resize(maxCount); } } diff --git a/modules/ml/src/boost.cpp b/modules/ml/src/boost.cpp index 3d58ac0398..6af9c134b4 100644 --- a/modules/ml/src/boost.cpp +++ b/modules/ml/src/boost.cpp @@ -351,9 +351,12 @@ CvBoostTree::find_split_ord_class( CvDTreeNode* node, int vi, float init_quality return split; } - -#define CV_CMP_NUM_PTR(a,b) (*(a) < *(b)) -static CV_IMPLEMENT_QSORT_EX( icvSortDblPtr, double*, CV_CMP_NUM_PTR, int ) +template +class LessThanPtr +{ +public: + bool operator()(T* a, T* b) const { return *a < *b; } +}; CvDTreeSplit* CvBoostTree::find_split_cat_class( CvDTreeNode* node, int vi, float init_quality, CvDTreeSplit* _split, uchar* _ext_buf ) @@ -412,7 +415,7 @@ CvBoostTree::find_split_cat_class( CvDTreeNode* node, int vi, float init_quality // sort rows of c_jk by increasing c_j,1 // (i.e. by the weight of samples in j-th category that belong to class 1) - icvSortDblPtr( dbl_ptr, mi, 0 ); + std::sort(dbl_ptr, dbl_ptr + mi, LessThanPtr()); for( subset_i = 0; subset_i < mi-1; subset_i++ ) { @@ -594,7 +597,7 @@ CvBoostTree::find_split_cat_reg( CvDTreeNode* node, int vi, float init_quality, sum_ptr[i] = sum + i; } - icvSortDblPtr( sum_ptr, mi, 0 ); + std::sort(sum_ptr, sum_ptr + mi, LessThanPtr()); // revert back to unnormalized sums // (there should be a very little loss in accuracy) @@ -1421,9 +1424,6 @@ CvBoost::update_weights( CvBoostTree* tree ) } -static CV_IMPLEMENT_QSORT_EX( icvSort_64f, double, CV_LT, int ) - - void CvBoost::trim_weights() { @@ -1440,7 +1440,7 @@ CvBoost::trim_weights() // use weak_eval as temporary buffer for sorted weights cvCopy( weights, weak_eval ); - icvSort_64f( weak_eval->data.db, count, 0 ); + std::sort(weak_eval->data.db, weak_eval->data.db + count); // as weight trimming occurs immediately after updating the weights, // where they are renormalized, we assume that the weight sum = 1. diff --git a/modules/ml/src/ertrees.cpp b/modules/ml/src/ertrees.cpp index 8b7091c333..e379ed4b11 100644 --- a/modules/ml/src/ertrees.cpp +++ b/modules/ml/src/ertrees.cpp @@ -44,13 +44,18 @@ static const float ord_nan = FLT_MAX*0.5f; static const int min_block_size = 1 << 16; static const int block_size_delta = 1 << 10; -#define CV_CMP_NUM_PTR(a,b) (*(a) < *(b)) -static CV_IMPLEMENT_QSORT_EX( icvSortIntPtr, int*, CV_CMP_NUM_PTR, int ) +template +class LessThanPtr +{ +public: + bool operator()(T* a, T* b) const { return *a < *b; } +}; -#define CV_CMP_PAIRS(a,b) (*((a).i) < *((b).i)) -static CV_IMPLEMENT_QSORT_EX( icvSortPairs, CvPair16u32s, CV_CMP_PAIRS, int ) - -/// +class LessThanPairs +{ +public: + bool operator()(const CvPair16u32s& a, const CvPair16u32s& b) const { return *a.i < *b.i; } +}; void CvERTreeTrainData::set_data( const CvMat* _train_data, int _tflag, const CvMat* _responses, const CvMat* _var_idx, const CvMat* _sample_idx, @@ -353,7 +358,7 @@ void CvERTreeTrainData::set_data( const CvMat* _train_data, int _tflag, if (is_buf_16u) { - icvSortPairs( pair16u32s_ptr, sample_count, 0 ); + std::sort(pair16u32s_ptr, pair16u32s_ptr + sample_count, LessThanPairs()); // count the categories for( i = 1; i < num_valid; i++ ) if (*pair16u32s_ptr[i].i != *pair16u32s_ptr[i-1].i) @@ -361,7 +366,7 @@ void CvERTreeTrainData::set_data( const CvMat* _train_data, int _tflag, } else { - icvSortIntPtr( int_ptr, sample_count, 0 ); + std::sort(int_ptr, int_ptr + sample_count, LessThanPtr()); // count the categories for( i = 1; i < num_valid; i++ ) c_count += *int_ptr[i] != *int_ptr[i-1]; diff --git a/modules/ml/src/gbt.cpp b/modules/ml/src/gbt.cpp index 04e7a0fe31..f2e54524a8 100644 --- a/modules/ml/src/gbt.cpp +++ b/modules/ml/src/gbt.cpp @@ -5,9 +5,6 @@ #define pCvSeq CvSeq* #define pCvDTreeNode CvDTreeNode* -#define CV_CMP_FLOAT(a,b) ((a) < (b)) -static CV_IMPLEMENT_QSORT_EX( icvSortFloat, float, CV_CMP_FLOAT, float) - //=========================================================================== //----------------------------- CvGBTreesParams ----------------------------- //=========================================================================== @@ -285,7 +282,7 @@ CvGBTrees::train( const CvMat* _train_data, int _tflag, } break; default: CV_Error(CV_StsUnmatchedFormats, "_sample_idx should be a 32sC1, 8sC1 or 8uC1 vector."); } - icvSortFloat(sample_idx->data.fl, sample_idx_len, 0); + std::sort(sample_idx->data.fl, sample_idx->data.fl + sample_idx_len); } else { @@ -470,7 +467,7 @@ void CvGBTrees::find_gradient(const int k) int idx = *(sample_data + subsample_data[i]*s_step); residuals[i] = fabs(resp_data[idx] - current_data[idx]); } - icvSortFloat(residuals, n, 0.0f); + std::sort(residuals, residuals + n); delta = residuals[int(ceil(n*alpha))]; @@ -693,7 +690,7 @@ float CvGBTrees::find_optimal_value( const CvMat* _Idx ) float* residuals = new float[n]; for (int i=0; i> 1; float r_median = (n == n_half<<1) ? diff --git a/modules/ml/src/tree.cpp b/modules/ml/src/tree.cpp index 6f128ebdd1..b1aa123b99 100644 --- a/modules/ml/src/tree.cpp +++ b/modules/ml/src/tree.cpp @@ -120,16 +120,27 @@ bool CvDTreeTrainData::set_params( const CvDTreeParams& _params ) return ok; } -#define CV_CMP_NUM_PTR(a,b) (*(a) < *(b)) -static CV_IMPLEMENT_QSORT_EX( icvSortIntPtr, int*, CV_CMP_NUM_PTR, int ) -static CV_IMPLEMENT_QSORT_EX( icvSortDblPtr, double*, CV_CMP_NUM_PTR, int ) +template +class LessThanPtr +{ +public: + bool operator()(T* a, T* b) const { return *a < *b; } +}; -#define CV_CMP_NUM_IDX(i,j) (aux[i] < aux[j]) -static CV_IMPLEMENT_QSORT_EX( icvSortIntAux, int, CV_CMP_NUM_IDX, const float* ) -static CV_IMPLEMENT_QSORT_EX( icvSortUShAux, unsigned short, CV_CMP_NUM_IDX, const float* ) +template +class LessThanIdx +{ +public: + LessThanIdx( const T* _arr ) : arr(_arr) {} + bool operator()(Idx a, Idx b) const { return arr[a] < arr[b]; } + const T* arr; +}; -#define CV_CMP_PAIRS(a,b) (*((a).i) < *((b).i)) -static CV_IMPLEMENT_QSORT_EX( icvSortPairs, CvPair16u32s, CV_CMP_PAIRS, int ) +class LessThanPairs +{ +public: + bool operator()(const CvPair16u32s& a, const CvPair16u32s& b) const { return *a.i < *b.i; } +}; void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, const CvMat* _responses, const CvMat* _var_idx, const CvMat* _sample_idx, @@ -461,7 +472,7 @@ void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, c_count = num_valid > 0; if (is_buf_16u) { - icvSortPairs( pair16u32s_ptr, sample_count, 0 ); + std::sort(pair16u32s_ptr, pair16u32s_ptr + sample_count, LessThanPairs()); // count the categories for( i = 1; i < num_valid; i++ ) if (*pair16u32s_ptr[i].i != *pair16u32s_ptr[i-1].i) @@ -469,7 +480,7 @@ void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, } else { - icvSortIntPtr( int_ptr, sample_count, 0 ); + std::sort(int_ptr, int_ptr + sample_count, LessThanPtr()); // count the categories for( i = 1; i < num_valid; i++ ) c_count += *int_ptr[i] != *int_ptr[i-1]; @@ -561,9 +572,9 @@ void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, } if (is_buf_16u) - icvSortUShAux( udst, sample_count, _fdst); + std::sort(udst, udst + sample_count, LessThanIdx(_fdst)); else - icvSortIntAux( idst, sample_count, _fdst ); + std::sort(idst, idst + sample_count, LessThanIdx(_fdst)); } if( vi < var_count ) @@ -2239,7 +2250,7 @@ CvDTreeSplit* CvDTree::find_split_cat_class( CvDTreeNode* node, int vi, float in int_ptr = (int**)(c_weights + _mi); for( j = 0; j < mi; j++ ) int_ptr[j] = cjk + j*2 + 1; - icvSortIntPtr( int_ptr, mi, 0 ); + std::sort(int_ptr, int_ptr + mi, LessThanPtr()); subset_i = 0; subset_n = mi; } @@ -2466,7 +2477,7 @@ CvDTreeSplit* CvDTree::find_split_cat_reg( CvDTreeNode* node, int vi, float init sum_ptr[i] = sum + i; } - icvSortDblPtr( sum_ptr, mi, 0 ); + std::sort(sum_ptr, sum_ptr + mi, LessThanPtr()); // revert back to unnormalized sums // (there should be a very little loss of accuracy)