home *** CD-ROM | disk | FTP | other *** search
- //===================================================================
- // Ranking.hpp
- //
- // Version 1.1
- //
- // Written by:
- // Brent Worden
- // WordenWare
- // email: Brent@Worden.org
- //
- // Copyright (c) 1998-1999 WordenWare
- //
- // Created: August 28, 1998
- // Revised: April 10, 1999
- //===================================================================
-
- #ifndef _RANKING_HPP_
- #define _RANKING_HPP_
-
- #include "algorthm.hpp"
- #include "descript.hpp"
- #include "funcobj.hpp"
- #include "numerror.h"
- #include "sort.hpp"
- #include "utility.hpp"
-
- NUM_BEGIN
-
- template<class Iter, class IndexIter>
- void index(Iter first, Iter last, IndexIter indx)
- //-------------------------------------------------------------------
- // Indexes the elements in [first, last) and places the index values
- // in [indx, indx + (last - first)). The input elements of [first,
- // last) are destoryed.
- //-------------------------------------------------------------------
- {
- int n = length(first, last);
- std::generate(indx, indx + n, IncGen<int>(0));
- qsort2(first, last, indx);
- };
-
- enum {RANK_MEAN, RANK_LOW, RANK_HIGH};
-
- template<class Iter, class RankIter>
- void rank(Iter first, Iter last, RankIter irank, int ties = RANK_MEAN)
- //-------------------------------------------------------------------
- // Ranks the elements in [first, last) by returning the table of
- // ranks in [irank, irank + (last - first)). The input elements of
- // [first, last) are not changed. The parameter ties determines the
- // method used to assign ranks to tied values. RANK_MEAN uses the
- // mean of the corresponding ranks. RANK_HIGH uses the largest of
- // the corresponding ranks. RANK_LOW uses the smallest of the
- // corresponding ranks.
- //-------------------------------------------------------------------
- {
- int n = length(first, last);
- int* indx = new int[n];
- int i, j, start, end;
- double rnk;
-
- index(first, last, indx);
-
- j = 0;
- while(j < n){
- start = end = j;
- while(end < n - 1 && *(first + *(indx + j)) == *(first + *(indx + end + 1))){
- ++end;
- }
- if(ties == RANK_MEAN){
- rnk = average(start, end);
- } else if(ties == RANK_LOW){
- rnk = start;
- } else if(ties == RANK_HIGH){
- rnk = end;
- } else {
- throw Exception("rank", "Invalid ties parameter.");
- rnk = start;
- }
- for(i = start; i <= end; ++i){
- *(irank + *(indx + i)) = rnk + 1;
- }
- j = end + 1;
- }
- delete [] indx;
- }
-
- template<class T, class Iter>
- void arank(T* first, T* last, Iter irank, int type = RANK_MEAN)
- //-------------------------------------------------------------------
- // Ranks the absolute values of the elements in [first, last) by
- // returning the table of ranks in [irank, irank + (last - first)).
- // The input elements of [first, last) are not changed. The
- // parameter ties determines the method used to assign ranks to tied
- // values as described above.
- //-------------------------------------------------------------------
- {
- int n = length(first, last);
- T* vec = new T[n];
-
- std::transform(first, last, vec, absoluteValue<T>);
- rank(vec, vec + n, irank, type);
- delete [] vec;
- }
-
- template<class T, class Iter>
- void abrank(T* first, T* last, Iter irank, int type = RANK_MEAN)
- //-------------------------------------------------------------------
- // Ranks the values of the elements in [first, last) using the
- // scoring method used in the Ansari-Bradley test returning the table
- // of ranks in [irank, irank + (last - first)). The input elements
- // of [first, last) are not changed. The parameter ties determines
- // the method used to assign ranks to tied values as described above.
- //-------------------------------------------------------------------
- {
- int n = length(first, last);
- double m = (n + 1.0) / 2.0;
- int i;
-
- rank(first, last, irank, type);
- for(i = 0; i < n; ++i){
- if(*irank > m){
- *irank = n - *irank + 1.0;
- }
- ++irank;
- }
- }
-
- template<class Iter, class S>
- int countGreater(Iter first, Iter last, S value)
- //-------------------------------------------------------------------
- // Returns the number of elements in [first, last) that are greater
- // than value.
- //-------------------------------------------------------------------
- {
- return std::count_if(first, last, BiggerThan<S>(value));
- };
-
- NUM_END
-
- #endif
-
- //===================================================================
- // Revision History
- //
- // Version 1.0 - 08/28/1998 - New.
- // Version 1.1 - 04/10/1999 - Added Numerics namespace.
- // Added use of exception class.
- // 04/17/1999 - Made arank() use std::transform()
- // Renamed count to countGreater.
- //===================================================================
-