home *** CD-ROM | disk | FTP | other *** search
- //===================================================================
- // descript.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 _DESCRIPT_HPP_
- #define _DESCRIPT_HPP_
-
- #include <cmath>
-
- #include <algorithm>
- #include <numeric>
-
- #include "algorthm.hpp"
- #include "residual.hpp"
- #include "vector.hpp"
-
- NUM_BEGIN
-
- template<class Iter>
- double centmom(Iter first, Iter last, double n)
- //-------------------------------------------------------------------
- // Returns the n-th central moment of the elements in [first, last).
- //-------------------------------------------------------------------
- {
- Vector<double> r(length(first, last));
- std::copy(first, last, r.begin());
-
- nresid(r.begin(), r.end(), mean(first, last), n);
- return mean(r.begin(), r.end());
- };
-
- template<class Iter>
- inline double coeffvar(Iter first, Iter last)
- //-------------------------------------------------------------------
- // Returns the coefficient of variation of the elements in
- // [first, last).
- //-------------------------------------------------------------------
- {
- return stddev(first, last) / mean(first, last) * 100.0;
- };
-
- template<class Iter>
- double geomean(Iter first, Iter last)
- //-------------------------------------------------------------------
- // Returns the geometric mean of the elements in [first, last).
- //-------------------------------------------------------------------
- {
- double p = 1.0 / length(first, last);
- double m = 1.0;
-
- while(first != last){
- m *= pow(*first, p);
- ++first;
- };
-
- return m;
- };
-
- template<class Iter>
- double harmean(Iter first, Iter last)
- //-------------------------------------------------------------------
- // Returns the harmonic mean of the elements in [first, last).
- //-------------------------------------------------------------------
- {
- double n = length(first, last);
- double m = 0.0;
-
- while(first != last){
- if(*first){
- m += 1.0 / *first;
- }
- ++first;
- }
-
- return m;
- };
-
- template<class Iter>
- inline double iqr(Iter first, Iter last)
- //-------------------------------------------------------------------
- // Returns the interquartile range of the elements in [first, last).
- //-------------------------------------------------------------------
- {
- return quartile3(first, last) - quartile1(first, last);
- };
-
- template<class Iter>
- inline double kurtosis(Iter first, Iter last)
- //-------------------------------------------------------------------
- // Returns the kurtosis of the elements in [first, last).
- //-------------------------------------------------------------------
- {
- return centmom(first, last, 4) / pow(variance(first, last), 2);
- };
-
- template<class Iter>
- int length(Iter first, Iter last)
- //-------------------------------------------------------------------
- // Returns the number of elements in [first, last).
- //-------------------------------------------------------------------
- {
- int len = 0;
- while(first != last){
- ++first;
- ++len;
- }
- return len;
- };
-
- template<class Iter>
- double mean(Iter first, Iter last)
- //-------------------------------------------------------------------
- // Returns the mean of the elements in [first, last).
- //-------------------------------------------------------------------
- {
- double m = 0.0;
- double n = 0.0;
- while(first != last){
- n += 1.0;
- m += (*first - m) / n;
- ++first;
- }
- return m;
- };
-
- template<class Iter>
- double meandev(Iter first, Iter last)
- //-------------------------------------------------------------------
- // Returns the mean deviation of the elements in [first, last).
- //-------------------------------------------------------------------
- {
- Vector<double> r(length(first, last));
- std::copy(first, last, r.begin());
- aresid(r.begin(), r.end(), mean(first, last));
- return mean(r.begin(), r.end());
- };
-
- template<class Iter>
- double meddev(Iter first, Iter last)
- //-------------------------------------------------------------------
- // Returns the median deviation of the elements in [first, last).
- //-------------------------------------------------------------------
- {
- Vector<double> r(length(first, last));
- std::copy(first, last, r.begin());
- aresid(r.begin(), r.end(), median(first, last));
- return median(r.begin(), r.end());
- };
-
- template<class Iter>
- double median(Iter first, Iter last)
- //-------------------------------------------------------------------
- // Returns the median of the elements in [first, last).
- //-------------------------------------------------------------------
- {
- int n = length(first, last);
- Vector<double> v(n);
- std::copy(first, last, v.begin());
- Vector<double>::iterator nth = v.begin() + n / 2;
- std::nth_element(v.begin(), nth, v.end());
-
- if(n % 2 == 0){ // even n
- double b = *nth;
- nth = v.begin() + n / 2 - 1;
- std::nth_element(v.begin(), nth, v.end());
- return average(*nth, b);
- } else {
- return *nth;
- }
- };
-
- template<class Iter>
- double quantile(Iter first, Iter last, double q)
- //-------------------------------------------------------------------
- // Returns the q*100 percentile of the elements in [first, last).
- //-------------------------------------------------------------------
- {
- int n = length(first, last);
- Vector<double> vec(n);
- std::copy(first, last, vec.begin());
- double u, f, v, ans;
- int i;
-
- if(q < 0.0){
- q = 0.0;
- }
- if(q > 1.0){
- q = 1.0;
- }
-
- std::sort(vec.begin(), vec.end());
- if(q < (v = 1.0 / (2.0 * n))){
- ans = *(vec.begin());
- } else if(q > 1.0 - v){
- ans = *(vec.end() - 1);
- } else {
- u = n * q + .5;
- i = int(u);
- f = u - i;
- ans = (1.0 - f) * *(vec.begin() + i - 1) + f * *(vec.begin() + i);
- }
-
- return ans;
- };
-
- template<class Iter>
- inline double quartile1(Iter first, Iter last)
- //-------------------------------------------------------------------
- // Returns the first quartile of the elements in [first, last).
- //-------------------------------------------------------------------
- {
- return quantile(first, last, .25);
- };
-
- template<class Iter>
- inline double quartile3(Iter first, Iter last)
- //-------------------------------------------------------------------
- // Returns the third quartile of the elements in [first, last).
- //-------------------------------------------------------------------
- {
- return quantile(first, last, .75);
- };
-
- template<class Iter>
- inline double range(Iter first, Iter last)
- //-------------------------------------------------------------------
- // Returns the range of the elements in [first, last).
- //-------------------------------------------------------------------
- {
- return *std::max_element(first, last) - *std::min_element(first, last);
- };
-
- template<class Iter>
- inline double rms(Iter first, Iter last)
- //-------------------------------------------------------------------
- // Returns the root mean square of the elements in [first, last).
- //-------------------------------------------------------------------
- {
- return sqrt(sum2(first, last) / length(first, last));
- };
-
- template<class Iter>
- inline double skewness(Iter first, Iter last)
- //-------------------------------------------------------------------
- // Returns the skewness of the elements in
- // [first, last).
- //-------------------------------------------------------------------
- {
- return centmom(first, last, 3) / pow(stddev(first, last), 3);
- };
-
- template<class Iter>
- inline double stddev(Iter first, Iter last)
- //-------------------------------------------------------------------
- // Returns the sample standard deviation of the elements in
- // [first, last).
- //-------------------------------------------------------------------
- {
- return sqrt(variance(first, last));
- };
-
- template<class Iter>
- inline double stderrmean(Iter first, Iter last)
- //-------------------------------------------------------------------
- // Returns the standard error of the mean of the elements in
- // [first, last).
- //-------------------------------------------------------------------
- {
- return sqrt(variance(first, last) / (double)length(first, last));
- };
-
- template<class Iter>
- inline double sum(Iter first, Iter last)
- //-------------------------------------------------------------------
- // Returns the sum of the elements in [first, last).
- //-------------------------------------------------------------------
- {
- return std::accumulate(first, last, 0.0);
- };
-
- template<class Iter>
- inline double sum2(Iter first, Iter last)
- //-------------------------------------------------------------------
- // Returns the sum of the squares of the elements in [first, last).
- //-------------------------------------------------------------------
- {
- return std::inner_product(first, last, first, (double)0.0);
- };
-
- template<class Iter1, class Iter2>
- inline double sump(Iter1 first1, Iter1 last1, Iter2 first2)
- //-------------------------------------------------------------------
- // Returns the sum of the products of the corresponding elements in
- // [first1, last1) and [first2, first2 + (last1 - first1) ).
- //-------------------------------------------------------------------
- {
- return std::inner_product(first1, last1, first2, (double)0.0);
- };
-
- template<class Iter1, class Iter2>
- double sumproduct(Iter1 first1, Iter1 last1, Iter2 first2)
- //-------------------------------------------------------------------
- // Returns the sums of products of the elements in [first, last).
- //-------------------------------------------------------------------
- {
- int n = length(first1, last1);
- Vector<double> r1(n);
- std::copy(first1, last1, r1.begin());
- Vector<double> r2(n);
- std::copy(first2, first2 + n, r2.begin());
-
- resid(r1.begin(), r1.end(), mean(r1.begin(), r1.end()));
- resid(r2.begin(), r2.end(), mean(r2.begin(), r2.end()));
-
- return std::inner_product(r1.begin(), r1.end(), r2.begin(), 0.0);
- };
-
- template<class Iter>
- double sumsquare(Iter first, Iter last)
- //-------------------------------------------------------------------
- // Returns the sums of squares of the elements in [first, last).
- //-------------------------------------------------------------------
- {
- Vector<double> r(length(first, last));
- std::copy(first, last, r.begin());
-
- resid(r.begin(), r.end(), mean(first, last));
-
- double ep = std::accumulate(r.begin(), r.end(), 0.0);
- double s2 = sum2(r.begin(), r.end());
-
- return s2 - ep * ep / (double)r.size();
- };
-
- template<class Iter>
- inline double trimmean(Iter first, Iter last, double f)
- //-------------------------------------------------------------------
- // Returns the mean of the elements in [first, last) with f*100
- // percent of the lowest and highest terms removed.
- //-------------------------------------------------------------------
- {
- return trimmean(first, last, f, f);
- };
-
- template<class Iter>
- double trimmean(Iter first, Iter last, double f1, double f2)
- //-------------------------------------------------------------------
- // Returns the mean of the elements in [first, last) with f1*100
- // percent of the lowest terms and f2*100 percent of the highest
- // terms removed.
- //-------------------------------------------------------------------
- {
- int n = length(first, last);
- Vector<double> v(n);
- std::copy(first, last, v.begin());
- int n1 = floor(f1 * n), n2 = floor(f2 * n);
-
- std::sort(v.begin(), v.end());
-
- return mean(v.begin() + n1, v.end() - n2);
- };
-
- template<class Iter>
- inline double variance(Iter first, Iter last)
- //-------------------------------------------------------------------
- // Returns the sample variance of the elements in [first, last).
- //-------------------------------------------------------------------
- {
- return sumsquare(first, last) / (double)(length(first, last) - 1);
- };
-
- NUM_END
-
- #endif
-
- //===================================================================
- // Revision History
- //
- // Version 1.0 - 08/28/1998 - New.
- // Version 1.1 - 04/10/1999 - Added std scope resolution.
- // - 04/10/1999 - Added Numerics namespace.
- // - 04/10/1999 - Made length more robust.
- // - 04/10/1999 - Change implementation of mean
- //===================================================================
-