00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <numeric>
00036 #include <algorithm>
00037 #include <OpenMS/CONCEPT/Types.h>
00038 #include <boost/lambda/lambda.hpp>
00039 #include <boost/lambda/casts.hpp>
00040 #include <boost/function/function_base.hpp>
00041
00042 #ifndef OPENMS_MATH_STATISTICS_STATISTICFUNCTIONS_H
00043 #define OPENMS_MATH_STATISTICS_STATISTICFUNCTIONS_H
00044
00045 namespace OpenMS
00046 {
00047
00048 namespace Math
00049 {
00055 template <typename IteratorType>
00056 static DoubleReal sum(IteratorType begin, IteratorType end)
00057 {
00058 return std::accumulate(begin, end, 0.0);
00059 }
00060
00068 template <typename IteratorType>
00069 static DoubleReal mean(IteratorType begin, IteratorType end)
00070 {
00071 SignedSize size = std::distance(begin, end);
00072 if (size <= 0)
00073 {
00074 throw Exception::InvalidRange(__FILE__, __LINE__, __PRETTY_FUNCTION__);
00075 }
00076 return sum(begin, end) / size;
00077 }
00078
00090 template <typename IteratorType>
00091 static DoubleReal median(IteratorType begin, IteratorType end, bool sorted = FALSE)
00092 {
00093 Size size = std::distance(begin, end);
00094
00095 if (size == 0)
00096 {
00097 throw Exception::InvalidRange(__FILE__, __LINE__, __PRETTY_FUNCTION__);
00098 }
00099
00100 if (!sorted)
00101 {
00102 std::sort(begin, end);
00103 }
00104
00105 if (size % 2 == 0)
00106 {
00107 IteratorType it1 = begin;
00108 std::advance(it1, size / 2 - 1);
00109 IteratorType it2 = it1;
00110 std::advance(it2, 1);
00111 return (*it1 + *it2) / 2.0;
00112 }
00113 else
00114 {
00115 IteratorType it = begin;
00116 std::advance(it, (size - 1) / 2);
00117 return *it;
00118 }
00119 }
00120
00132 template <typename IteratorType>
00133 static DoubleReal quantile(IteratorType begin, IteratorType end, UInt quantile, bool sorted = FALSE)
00134 {
00135 Size size = std::distance(begin, end);
00136
00137 if (size == 0)
00138 {
00139 throw Exception::InvalidRange(__FILE__, __LINE__, __PRETTY_FUNCTION__);
00140 }
00141 if (quantile > 100 || quantile < 1)
00142 {
00143 throw Exception::InvalidRange(__FILE__, __LINE__, __PRETTY_FUNCTION__);
00144 }
00145
00146 int l = floor( (double(quantile) * (double(size) / 100)) + 0.5);
00147
00148 if (!sorted)
00149 {
00150 std::sort(begin, end);
00151 }
00152
00153 IteratorType it = begin;
00154 std::advance(it, l - 1);
00155 return *it;
00156
00157 }
00158
00168 template <typename IteratorType1, typename IteratorType2>
00169 static DoubleReal meanSquareError(IteratorType1 begin_a, IteratorType1 end_a, IteratorType2 begin_b, IteratorType2 end_b)
00170 {
00171
00172 SignedSize dist = std::distance(begin_a, end_a);
00173 if (dist == 0 || dist != std::distance(begin_b, end_b))
00174 {
00175 throw Exception::InvalidRange(__FILE__, __LINE__, __PRETTY_FUNCTION__);
00176 }
00177
00178 DoubleReal error = 0;
00179 while (begin_a != end_a)
00180 {
00181 DoubleReal tmp(*begin_a - *begin_b);
00182 error += tmp * tmp;
00183 ++begin_a;
00184 ++begin_b;
00185 }
00186
00187 return error / dist;
00188 }
00189
00199 template <typename IteratorType1, typename IteratorType2>
00200 static DoubleReal classificationRate(IteratorType1 begin_a, IteratorType1 end_a, IteratorType2 begin_b, IteratorType2 end_b)
00201 {
00202
00203 SignedSize dist = std::distance(begin_a, end_a);
00204 if (dist == 0 || dist != std::distance(begin_b, end_b))
00205 {
00206 throw Exception::InvalidRange(__FILE__, __LINE__, __PRETTY_FUNCTION__);
00207 }
00208
00209 DoubleReal correct = (DoubleReal) dist;
00210 while (begin_a != end_a)
00211 {
00212 if ((*begin_a < 0 && *begin_b >= 0) || (*begin_a >= 0 && *begin_b < 0))
00213 {
00214 --correct;
00215 }
00216 ++begin_a;
00217 ++begin_b;
00218 }
00219
00220 return correct / dist;
00221 }
00222
00232 template <typename IteratorType1, typename IteratorType2>
00233 static DoubleReal matthewsCorrelationCoefficient(IteratorType1 begin_a, IteratorType1 end_a, IteratorType2 begin_b, IteratorType2 end_b)
00234 {
00235
00236 Int dist = std::distance(begin_a, end_a);
00237 if (dist == 0 || dist != std::distance(begin_b, end_b))
00238 {
00239 throw Exception::InvalidRange(__FILE__, __LINE__, __PRETTY_FUNCTION__);
00240 }
00241
00242 DoubleReal tp = 0;
00243 DoubleReal fp = 0;
00244 DoubleReal tn = 0;
00245 DoubleReal fn = 0;
00246
00247 while (begin_a != end_a)
00248 {
00249 if (*begin_a < 0 && *begin_b >= 0)
00250 {
00251 ++fn;
00252 }
00253 else if (*begin_a < 0 && *begin_b < 0)
00254 {
00255 ++tn;
00256 }
00257 else if (*begin_a >= 0 && *begin_b >= 0)
00258 {
00259 ++tp;
00260 }
00261 else if (*begin_a >= 0 && *begin_b < 0)
00262 {
00263 ++fp;
00264 }
00265
00266 ++begin_a;
00267 ++begin_b;
00268 }
00269
00270 return (tp * tn - fp * fn) / sqrt((tp + fp) * (tp + fn) * (tn + fp) * (tn + fn));
00271 }
00272
00284 template <typename IteratorType1, typename IteratorType2>
00285 static DoubleReal pearsonCorrelationCoefficient(IteratorType1 begin_a, IteratorType1 end_a, IteratorType2 begin_b, IteratorType2 end_b)
00286 {
00287
00288 SignedSize dist = std::distance(begin_a, end_a);
00289 if (dist == 0 || dist != std::distance(begin_b, end_b))
00290 {
00291 throw Exception::InvalidRange(__FILE__, __LINE__, __PRETTY_FUNCTION__);
00292 }
00293
00294
00295 DoubleReal avg_a = std::accumulate(begin_a, end_a, 0.0) / dist;
00296 DoubleReal avg_b = std::accumulate(begin_b, end_b, 0.0) / dist;
00297
00298 DoubleReal numerator = 0;
00299 DoubleReal denominator_a = 0;
00300 DoubleReal denominator_b = 0;
00301 while (begin_a != end_a)
00302 {
00303 DoubleReal temp_a = *begin_a - avg_a;
00304 DoubleReal temp_b = *begin_b - avg_b;
00305 numerator += (temp_a * temp_b);
00306 denominator_a += (temp_a * temp_a);
00307 denominator_b += (temp_b * temp_b);
00308 ++begin_a;
00309 ++begin_b;
00310 }
00311
00312 return numerator / sqrt(denominator_a * denominator_b);
00313 }
00314
00316 template <typename Value>
00317 static void computeRank(std::vector<Value> & w)
00318 {
00319 using namespace boost::lambda;
00320 Size i = 0;
00321 Size z = 0;
00322 Value rank = 0;
00323 Size n = (w.size() - 1);
00324
00325 std::vector<std::pair<Size, Value> > w_idx;
00326 for (Size j = 0; j < w.size(); ++j)
00327 {
00328 w_idx.push_back(std::make_pair(j, w[j]));
00329 }
00330
00331 std::sort(w_idx.begin(), w_idx.end(),
00332 ret<bool>((&_1->*& std::pair<Size, Value>::second) < (&_2->*& std::pair<Size, Value>::second)));
00333
00334 while (i < n)
00335 {
00336
00337 if (fabs(w_idx[i + 1].second - w_idx[i].second) > 0.0000001 * fabs(w_idx[i + 1].second))
00338 {
00339 w_idx[i].second = Value(i + 1);
00340 ++i;
00341 }
00342 else
00343 {
00344
00345 for (z = i + 1; (z <= n) && fabs(w_idx[z].second - w_idx[i].second) <= 0.0000001 * fabs(w_idx[z].second); ++z)
00346 {
00347 }
00348
00349 rank = 0.5 * (i + z + 1);
00350
00351 for (Size v = i; v <= z - 1; ++v)
00352 {
00353 w_idx[v].second = rank;
00354 }
00355 i = z;
00356 }
00357 }
00358 if (i == n)
00359 w_idx[n].second = Value(n + 1);
00360
00361 for (Size j = 0; j < w.size(); ++j)
00362 {
00363 w[w_idx[j].first] = w_idx[j].second;
00364 }
00365 }
00366
00378 template <typename IteratorType1, typename IteratorType2>
00379 static DoubleReal rankCorrelationCoefficient(IteratorType1 begin_a, IteratorType1 end_a, IteratorType2 begin_b, IteratorType2 end_b)
00380 {
00381
00382 SignedSize dist = std::distance(begin_a, end_a);
00383 if (dist == 0 || dist != std::distance(begin_b, end_b))
00384 {
00385 throw Exception::InvalidRange(__FILE__, __LINE__, __PRETTY_FUNCTION__);
00386 }
00387
00388
00389 std::vector<DoubleReal> ranks_data;
00390 ranks_data.reserve(dist);
00391 std::vector<DoubleReal> ranks_model;
00392 ranks_model.reserve(dist);
00393
00394 while (begin_a != end_a)
00395 {
00396 ranks_model.push_back(*begin_a);
00397 ranks_data.push_back(*begin_b);
00398 ++begin_a;
00399 ++begin_b;
00400 }
00401
00402
00403 computeRank(ranks_data);
00404 computeRank(ranks_model);
00405
00406 DoubleReal mu = DoubleReal(ranks_data.size() + 1) / 2.;
00407
00408
00409
00410 DoubleReal sum_model_data = 0;
00411 DoubleReal sqsum_data = 0;
00412 DoubleReal sqsum_model = 0;
00413
00414 for (Int i = 0; i < dist; ++i)
00415 {
00416 sum_model_data += (ranks_data[i] - mu) * (ranks_model[i] - mu);
00417 sqsum_data += (ranks_data[i] - mu) * (ranks_data[i] - mu);
00418 sqsum_model += (ranks_model[i] - mu) * (ranks_model[i] - mu);
00419 }
00420
00421
00422 if (!sqsum_data || !sqsum_model)
00423 return 0;
00424
00425 return sum_model_data / (sqrt(sqsum_data) * sqrt(sqsum_model));
00426 }
00427
00428 }
00429 }
00430
00431 #endif // OPENMS_MATH_STATISTICS_STATISTICFUNCTIONS_H