home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 41 / IOPROG_41.ISO / soft / c++ / NUMCPP11.ZIP / ranking.hpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-05-09  |  4.9 KB  |  151 lines

  1. //===================================================================
  2. // Ranking.hpp
  3. //
  4. // Version 1.1
  5. //
  6. // Written by:
  7. //   Brent Worden
  8. //   WordenWare
  9. //   email:  Brent@Worden.org
  10. //
  11. // Copyright (c) 1998-1999 WordenWare
  12. //
  13. // Created:  August 28, 1998
  14. // Revised:  April 10, 1999
  15. //===================================================================
  16.  
  17. #ifndef _RANKING_HPP_
  18. #define _RANKING_HPP_
  19.  
  20. #include "algorthm.hpp"
  21. #include "descript.hpp"
  22. #include "funcobj.hpp"
  23. #include "numerror.h"
  24. #include "sort.hpp"
  25. #include "utility.hpp"
  26.  
  27. NUM_BEGIN
  28.  
  29. template<class Iter, class IndexIter>
  30. void index(Iter first, Iter last, IndexIter indx)
  31. //-------------------------------------------------------------------
  32. // Indexes the elements in [first, last) and places the index values
  33. // in [indx, indx + (last - first)).  The input elements of [first,
  34. // last) are destoryed.
  35. //-------------------------------------------------------------------
  36. {
  37.     int n = length(first, last);
  38.     std::generate(indx, indx + n, IncGen<int>(0));
  39.     qsort2(first, last, indx);
  40. };
  41.  
  42. enum {RANK_MEAN, RANK_LOW, RANK_HIGH};
  43.  
  44. template<class Iter, class RankIter>
  45. void rank(Iter first, Iter last, RankIter irank, int ties = RANK_MEAN)
  46. //-------------------------------------------------------------------
  47. // Ranks the elements in [first, last) by returning the table of
  48. // ranks in [irank, irank + (last - first)).  The input elements of
  49. // [first, last) are not changed.  The parameter ties determines the
  50. // method used to assign ranks to tied values.  RANK_MEAN uses the
  51. // mean of the corresponding ranks.  RANK_HIGH uses the largest of
  52. // the corresponding ranks.  RANK_LOW uses the smallest of the
  53. // corresponding ranks.
  54. //-------------------------------------------------------------------
  55. {
  56.     int n = length(first, last);
  57.     int* indx = new int[n];
  58.     int i, j, start, end;
  59.     double rnk;
  60.     
  61.     index(first, last, indx);
  62.     
  63.     j = 0;
  64.     while(j < n){
  65.         start = end = j;
  66.         while(end < n - 1 && *(first + *(indx + j)) == *(first + *(indx + end + 1))){
  67.             ++end;
  68.         }
  69.         if(ties == RANK_MEAN){
  70.             rnk = average(start, end);
  71.         } else if(ties == RANK_LOW){
  72.             rnk = start;
  73.         } else if(ties == RANK_HIGH){
  74.             rnk = end;
  75.         } else {
  76.             throw Exception("rank", "Invalid ties parameter.");
  77.             rnk = start;
  78.         }
  79.         for(i = start; i <= end; ++i){
  80.             *(irank + *(indx + i)) = rnk + 1;
  81.         }
  82.         j = end + 1;
  83.     }
  84.     delete [] indx;
  85. }
  86.  
  87. template<class T, class Iter>
  88. void arank(T* first, T* last, Iter irank, int type = RANK_MEAN)
  89. //-------------------------------------------------------------------
  90. // Ranks the absolute values of the elements in [first, last) by
  91. // returning the table of ranks in [irank, irank + (last - first)).
  92. // The input elements of [first, last) are not changed.  The
  93. // parameter ties determines the method used to assign ranks to tied
  94. // values as described above.
  95. //-------------------------------------------------------------------
  96. {
  97.     int n = length(first, last);
  98.     T* vec = new T[n];
  99.     
  100.     std::transform(first, last, vec, absoluteValue<T>);
  101.     rank(vec, vec + n, irank, type);
  102.     delete [] vec;
  103. }
  104.  
  105. template<class T, class Iter>
  106. void abrank(T* first, T* last, Iter irank, int type = RANK_MEAN)
  107. //-------------------------------------------------------------------
  108. // Ranks the values of the elements in [first, last) using the
  109. // scoring method used in the Ansari-Bradley test returning the table
  110. // of ranks in [irank, irank + (last - first)).  The input elements
  111. // of [first, last) are not changed.  The parameter ties determines
  112. // the method used to assign ranks to tied values as described above.
  113. //-------------------------------------------------------------------
  114. {
  115.     int n = length(first, last);
  116.     double m = (n + 1.0) / 2.0;
  117.     int i;
  118.     
  119.     rank(first, last, irank, type);
  120.     for(i = 0; i < n; ++i){
  121.         if(*irank > m){
  122.             *irank = n - *irank + 1.0;
  123.         }
  124.         ++irank;
  125.     }
  126. }
  127.  
  128. template<class Iter, class S>
  129. int countGreater(Iter first, Iter last, S value)
  130. //-------------------------------------------------------------------
  131. // Returns the number of elements in [first, last) that are greater
  132. // than value.
  133. //-------------------------------------------------------------------
  134. {
  135.     return std::count_if(first, last, BiggerThan<S>(value));
  136. };
  137.  
  138. NUM_END
  139.  
  140. #endif
  141.  
  142. //===================================================================
  143. // Revision History
  144. //
  145. // Version 1.0 - 08/28/1998 - New.
  146. // Version 1.1 - 04/10/1999 - Added Numerics namespace.
  147. //                            Added use of exception class.
  148. //               04/17/1999 - Made arank() use std::transform()
  149. //                            Renamed count to countGreater.
  150. //===================================================================
  151.