Ignore:
Timestamp:
Jan 7, 2009, 11:53:05 PM (12 years ago)
Author:
Peter
Message:

class KolmogorovSmirnov?:
add (sorted) range (fixes #462)
allow copy and assignment
add a shuffle function
p_value calculation now scales linearly with number of data points and
not N*logN as before

configure.ac: added a test to see if std::multiset::iterator is mutable

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/yat/statistics/KolmogorovSmirnov.cc

    r1687 r1701  
    22
    33/*
    4   Copyright (C) 2008 Peter Johansson
     4  Copyright (C) 2008, 2009 Peter Johansson
    55
    66  This file is part of the yat library, http://dev.thep.lu.se/yat
     
    1919  along with yat. If not, see <http://www.gnu.org/licenses/>.
    2020*/
     21
     22#include <config.h>
    2123
    2224#include "KolmogorovSmirnov.h"
     
    4749      return;
    4850
    49     data_.insert(std::make_pair(std::make_pair(x,w),target));
     51    data_.insert(Element(x,target,w));
    5052    if (target){
    5153      sum_w1_+=w;
     
    8082  {
    8183    size_t count=0;
    82     std::deque<bool> targets;
    83     typedef data_w::const_iterator const_iter;
    84     for (const_iter i(data_.begin()); i!=data_.end(); ++i)
    85       targets.push_back(i->second);
    86 
    8784    double score_threshold = score()-10*std::numeric_limits<double>().epsilon();
     85    KolmogorovSmirnov ks(*this);
    8886
    8987    for (size_t i=0; i<perm; ++i){
    90       random::random_shuffle(targets.begin(), targets.end());
    91       KolmogorovSmirnov ks;
    92       std::deque<bool>::const_iterator target_i(targets.begin());
    93       const_iter end(data_.end());
    94       for (const_iter iter(data_.begin()); iter!=end; ++iter, ++target_i)
    95         ks.add(iter->first.first, *target_i, iter->first.second);
    96      
     88      ks.shuffle();
    9789      if (ks.score()>=score_threshold)
    9890        ++count;
     
    117109
    118110
     111  void KolmogorovSmirnov::scores(std::vector<double>& res) const
     112  {
     113    res.clear();
     114    res.reserve(data_.size());
     115    data_w::const_iterator iter(data_.begin());
     116    double f1=0;
     117    double f2=0;
     118    while(iter!=data_.end()){
     119      size_t count=0;
     120      double value = iter->value;
     121      while (iter!=data_.end() && iter->value==value) {
     122        if (iter->label) {
     123          f1 += iter->weight;
     124        }
     125        else {
     126          f2 += iter->weight;
     127        }
     128        ++count;
     129        ++iter;
     130      }
     131      res.resize(res.size()+count, f1/sum_w1_-f2/sum_w2_);
     132    }
     133  }
     134
     135
     136  void KolmogorovSmirnov::shuffle(void)
     137  {
     138    std::deque<bool> labels;
     139    for (data_w::const_iterator iter=data_.begin();
     140         iter!=data_.end(); ++iter) {
     141      labels.push_back(iter->label);
     142    }
     143    random::random_shuffle(labels.begin(), labels.end());
     144    std::deque<bool>::const_iterator label = labels.begin();
     145    for (data_w::iterator iter=data_.begin();
     146         iter!=data_.end(); ++iter, ++label) {
     147      // label does not affect sorting of set, so modifying label is safe
     148#ifdef MULTISET_ITERATOR_IS_MUTABLE
     149      (*iter).label = *label;
     150#else
     151      // standard requires that multiset::iterator is modifiable, but
     152      // some implementations do not fulfill the requirement
     153      const_cast<Element&>(*iter).label = *label;
     154#endif
     155    }
     156    sum_w1_ = 0;
     157    sum_w2_ = 0;
     158    add_sum_w(data_.begin(), data_.end());
     159    cached_ = false;
     160  }
     161
     162
    119163  double KolmogorovSmirnov::signed_score(void) const
    120164  {
     
    136180
    137181
    138   void KolmogorovSmirnov::scores(std::vector<double>& res) const
    139   {
    140     res.clear();
    141     res.reserve(data_.size());
    142     data_w::const_iterator iter(data_.begin());
    143     double f1=0;
    144     double f2=0;
    145     while(iter!=data_.end()){
    146       size_t count=0;
    147       double value = iter->first.first;
    148       while (iter!=data_.end() && iter->first.first==value) {
    149         if (iter->second) {
    150           f1 += iter->first.second;
    151         }
    152         else {
    153           f2 += iter->first.second;
    154         }
    155         ++count;
    156         ++iter;
    157       }
    158       res.resize(res.size()+count, f1/sum_w1_-f2/sum_w2_);
    159     }
    160   }
    161 
    162 
    163182  std::ostream& operator<<(std::ostream& os, const KolmogorovSmirnov& ks)
    164183  {
     
    171190
    172191
     192  bool KolmogorovSmirnov::Element::operator<
     193  (const KolmogorovSmirnov::Element rhs) const
     194  {
     195    return value<rhs.value;
     196  }
     197
    173198}}} // of namespace theplu yat statistics
Note: See TracChangeset for help on using the changeset viewer.