00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00028 #ifndef SCYTHE_STAT_H
00029 #define SCYTHE_STAT_H
00030
00031 #ifdef SCYTHE_COMPILE_DIRECT
00032 #include "matrix.h"
00033 #include "algorithm.h"
00034 #include "error.h"
00035 #else
00036 #include "scythestat/matrix.h"
00037 #include "scythestat/algorithm.h"
00038 #include "scythestat/error.h"
00039 #endif
00040
00041 #include <numeric>
00042 #include <set>
00043
00044
00045 namespace scythe {
00046
00047 namespace {
00048 typedef unsigned int uint;
00049 }
00050
00051
00052
00053
00054
00055
00056
00057 #define SCYTHE_STATMETH_COL(NAME) \
00058 template <matrix_order RO, matrix_style RS, typename T, \
00059 matrix_order PO, matrix_style PS> \
00060 Matrix<T,RO,RS> \
00061 NAME ## c (const Matrix<T,PO,PS>& A) \
00062 { \
00063 Matrix<T,RO,RS> res (1, A.cols(), false); \
00064 \
00065 for (uint j = 0; j < A.cols(); ++j) \
00066 res[j] = NAME(A(_, j)); \
00067 \
00068 return res; \
00069 } \
00070 \
00071 template <typename T, matrix_order O, matrix_style S> \
00072 Matrix<T,O,Concrete> \
00073 NAME ## c (const Matrix<T,O,S>& A) \
00074 { \
00075 return NAME ## c<O,Concrete>(A); \
00076 }
00077
00078
00079
00080
00095 template <typename T, matrix_order PO, matrix_style PS>
00096 T
00097 sum (const Matrix<T,PO,PS> &A)
00098 {
00099 return (std::accumulate(A.begin_f(), A.end_f(), (T) 0));
00100 }
00101
00102
00103
00118 SCYTHE_STATMETH_COL(sum);
00119
00120
00121
00135 template <typename T, matrix_order PO, matrix_style PS>
00136 T
00137 prod (const Matrix<T,PO,PS> &A)
00138 {
00139 return std::accumulate(A.begin_f(), A.end_f(), (T) 1,
00140 std::multiplies<T> ());
00141 }
00142
00143
00144
00159 SCYTHE_STATMETH_COL(prod);
00160
00161
00162
00178 template <typename T, matrix_order PO, matrix_style PS>
00179 T
00180 mean (const Matrix<T,PO,PS> &A)
00181 {
00182 return (std::accumulate(A.begin_f(), A.end_f(), (T) 0) / A.size());
00183 }
00184
00185
00186
00203 SCYTHE_STATMETH_COL(mean);
00204
00205
00206
00207
00208
00209
00223 template <typename T, matrix_order PO, matrix_style PS>
00224 T
00225 median (const Matrix<T,PO,PS> &A)
00226 {
00227 Matrix<T, PO, PS> temp(A);
00228 uint n = temp.size();
00229
00230 sort(temp.begin(), temp.end());
00231 if (n % 2 == 0)
00232 return ((temp[n / 2] + temp[n / 2 - 1]) / 2);
00233 else
00234 return temp[(uint) ::floor(n / 2)];
00235 }
00236
00237
00238
00253 SCYTHE_STATMETH_COL(median);
00254
00255
00256
00270 template <typename T, matrix_order PO, matrix_style PS>
00271 T
00272 mode (const Matrix<T,PO,PS> &A)
00273 {
00274 Matrix<T, PO, PS> temp(A);
00275
00276 sort(temp.begin(), temp.end());
00277
00278 T last = temp[0];
00279 uint cnt = 1;
00280 T cur_max = temp[0];
00281 uint max_cnt = 1;
00282
00283 for (uint i = 1; i < temp.size(); ++i) {
00284 if (last == temp[i]) {
00285 ++cnt;
00286 } else {
00287 last = temp[i];
00288 cnt = 1;
00289 }
00290 if (cnt > max_cnt) {
00291 max_cnt = cnt;
00292 cur_max = temp[i];
00293 }
00294 }
00295
00296 return cur_max;
00297 }
00298
00313 SCYTHE_STATMETH_COL(mode);
00314
00315
00316
00317
00318
00319 namespace {
00320 template <typename T, typename T2>
00321 struct var_step : std::binary_function<T, T, T>
00322 {
00323 T constant_;
00324 T2 divisor_;
00325 T exponent_;
00326 var_step (T c, T2 d, T e) : constant_ (c), divisor_ (d),
00327 exponent_ (e) {}
00328 T operator() (T last, T x) const
00329 {
00330 return (last + std::pow(constant_ - x, exponent_) / divisor_);
00331 }
00332 };
00333 }
00334
00347 template <typename T, matrix_order PO, matrix_style PS>
00348 T
00349 var (const Matrix<T,PO,PS> &A)
00350 {
00351 return var(A, mean(A));
00352 }
00353
00354
00355
00369 SCYTHE_STATMETH_COL(var);
00370
00385 template <typename T, matrix_order PO, matrix_style PS>
00386 T
00387 var (const Matrix<T,PO,PS> &A, T mu)
00388 {
00389 return std::accumulate(A.begin_f(), A.end_f(), (T) 0,
00390 var_step<T, uint> (mu, A.size() - 1, 2));
00391 }
00392
00393
00394
00408 template <typename T, matrix_order PO, matrix_style PS>
00409 T
00410 sd (const Matrix<T,PO,PS> &A)
00411 {
00412 return std::sqrt(var(A));
00413 }
00414
00415
00428 SCYTHE_STATMETH_COL(sd);
00429
00444 template <typename T, matrix_order PO, matrix_style PS>
00445 T
00446 sd (const Matrix<T,PO,PS> &A, T mu)
00447 {
00448 return std::sqrt(var(A, mu));
00449 }
00450
00451
00452
00464 template <typename T, matrix_order PO, matrix_style PS>
00465 T
00466 skew (const Matrix<T,PO,PS> &A)
00467 {
00468 T mu = mean(A);
00469 T sde = sd(A, mu);
00470 return std::accumulate(A.begin_f(), A.end_f(), (T) 0,
00471 var_step<T, T> (mu, A.size() * std::pow(sde, 3), 3));
00472 }
00473
00474
00475
00487 SCYTHE_STATMETH_COL(skew);
00488
00489
00490
00501 template <typename T, matrix_order PO, matrix_style PS>
00502 T
00503 kurtosis (const Matrix<T,PO,PS> &A)
00504 {
00505 T mu = mean(A);
00506 T sde = sd(A, mu);
00507 return (std::accumulate(A.begin_f(), A.end_f(), (T) 0,
00508 var_step<T, T> (mu, A.size() * std::pow(sde, 4), 4))
00509 - 3);
00510 }
00511
00512
00513
00525 SCYTHE_STATMETH_COL(kurtosis);
00526
00527
00540 template <typename T, matrix_order PO, matrix_style PS>
00541 T
00542 max (const Matrix<T,PO,PS> &A)
00543 {
00544 return *(max_element(A.begin_f(), A.end_f()));
00545 }
00546
00558 SCYTHE_STATMETH_COL(max);
00559
00560
00561
00572 template <typename T, matrix_order PO, matrix_style PS>
00573 T
00574 min (const Matrix<T,PO,PS> &A)
00575 {
00576 return *(min_element(A.begin_f(), A.end_f()));
00577 }
00578
00590 SCYTHE_STATMETH_COL(min);
00591
00592
00605 template <typename T, matrix_order PO, matrix_style PS>
00606 unsigned int
00607 maxind (const Matrix<T,PO,PS> &A)
00608 {
00609 return (max_element(A.begin_f(), A.end_f())).get_index();
00610 }
00611
00623 SCYTHE_STATMETH_COL(maxind);
00624
00625
00626
00638 template <typename T, matrix_order PO, matrix_style PS>
00639 unsigned int
00640 minind (const Matrix<T,PO,PS> &A)
00641 {
00642 return (min_element(A.begin_f(), A.end_f())).get_index();
00643 }
00644
00655 SCYTHE_STATMETH_COL(minind);
00656
00657 }
00658
00659
00660 #endif