Changeset 3289


Ignore:
Timestamp:
Jul 12, 2014, 6:25:36 PM (9 years ago)
Author:
Peter
Message:

refs #803. use boost concepts in Spearman.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/test/normalization.cc

    r3281 r3289  
    449449  // compile test should not be run
    450450  if (false) {
    451     spearman(boost::random_access_iterator_archetype<double>(),
    452              boost::random_access_iterator_archetype<double>(),
    453              boost::mutable_random_access_iterator_archetype<double>());
    454     using utility::DataWeight;
    455     spearman(boost::random_access_iterator_archetype<DataWeight>(),
    456              boost::random_access_iterator_archetype<DataWeight>(),
    457              boost::mutable_random_access_iterator_archetype<DataWeight>());
    458     spearman(boost::random_access_iterator_archetype<double>(),
    459              boost::random_access_iterator_archetype<double>(),
    460              boost::mutable_random_access_iterator_archetype<DataWeight>());
    461     spearman(boost::random_access_iterator_archetype<DataWeight>(),
    462              boost::random_access_iterator_archetype<DataWeight>(),
    463              boost::mutable_random_access_iterator_archetype<double>());
     451    using boost::iterator_archetype;
     452    iterator_archetype<double,
     453                       boost::iterator_archetypes::readable_iterator_t,
     454                       boost::random_access_traversal_tag>
     455      readable_iterator;
     456
     457    iterator_archetype<double,
     458                       boost::iterator_archetypes::readable_writable_iterator_t,
     459                       boost::random_access_traversal_tag>
     460      writable_iterator;
     461
     462    // We have to use lvalue here because otherwise proxy classes
     463    // provided by boost kick in and they do not provide the needed
     464    // data() and weight() functions that e.g. DataWeightProxy does.
     465    iterator_archetype<utility::DataWeight,
     466                       boost::iterator_archetypes::readable_lvalue_iterator_t,
     467                       boost::random_access_traversal_tag>
     468      weighted_readable_iterator;
     469
     470    iterator_archetype<utility::DataWeight,
     471                       boost::iterator_archetypes::writable_lvalue_iterator_t,
     472                       boost::random_access_traversal_tag>
     473      weighted_writable_iterator;
     474
     475    spearman(readable_iterator, readable_iterator, writable_iterator);
     476    spearman(readable_iterator, readable_iterator, weighted_writable_iterator);
     477    spearman(weighted_readable_iterator, weighted_readable_iterator,
     478             writable_iterator);
     479    spearman(weighted_readable_iterator, weighted_readable_iterator,
     480             weighted_writable_iterator);
    464481  }
    465482
  • trunk/yat/normalizer/Spearman.h

    r2161 r3289  
    2626#include "utility.h"
    2727
     28#include "yat/utility/concept_check.h"
    2829#include "yat/utility/DataIterator.h"
    2930#include "yat/utility/iterator_traits.h"
    3031#include "yat/utility/sort_index.h"
     32#include "yat/utility/stl_utility.h"
     33#include "yat/utility/utility.h"
    3134#include "yat/utility/WeightIterator.h"
    3235
     
    3538#include <algorithm>
    3639#include <functional>
     40#include <numeric>
    3741#include <vector>
    3842
     
    6468
    6569       Type Requirements:
    66        - RandomAccessIter1 must be a \random_access_iterator
    67        - RandomAccessIter2 must be a mutable \random_access_iterator
    68 
     70       - \c RandomAccessIter1 is \readable_iterator
     71       - \c RandomAccessIter1 is \random_access_traversal_iterator
     72       - \c RandomAccessIter1 is \ref concept_data_iterator
     73       - \c RandomAccessIter2 is \readable_iterator
     74       - \c RandomAccessIter2 is \writable_iterator
     75       - \c RandomAccessIter2 is \random_access_traversal_iterator
     76       - \c RandomAccessIter2 is \ref concept_data_iterator
    6977     */
    7078    template<typename RandomAccessIter1, typename RandomAccessIter2>
     
    7280                    RandomAccessIter2 result) const
    7381    {
    74       BOOST_CONCEPT_ASSERT((boost::RandomAccessIterator<RandomAccessIter1>));
    75       BOOST_CONCEPT_ASSERT((boost::Mutable_RandomAccessIterator<RandomAccessIter2>));
     82      using boost_concepts::ReadableIterator;
     83      BOOST_CONCEPT_ASSERT((ReadableIterator<RandomAccessIter1>));
     84      using boost_concepts::RandomAccessTraversal;
     85      BOOST_CONCEPT_ASSERT((RandomAccessTraversal<RandomAccessIter1>));
     86      using utility::DataIteratorConcept;
     87      BOOST_CONCEPT_ASSERT((DataIteratorConcept<RandomAccessIter1>));
     88
     89      BOOST_CONCEPT_ASSERT((ReadableIterator<RandomAccessIter2>));
     90      using boost_concepts::WritableIterator;
     91      BOOST_CONCEPT_ASSERT((WritableIterator<RandomAccessIter2>));
     92      BOOST_CONCEPT_ASSERT((RandomAccessTraversal<RandomAccessIter2>));
     93      BOOST_CONCEPT_ASSERT((DataIteratorConcept<RandomAccessIter2>));
     94
    7695      using utility::weighted_if_any2;
    7796      typename weighted_if_any2<RandomAccessIter1,RandomAccessIter2>::type tag;
     
    84103    template<typename RandomAccessIter1, typename RandomAccessIter2>
    85104    void normalize(RandomAccessIter1 first, RandomAccessIter1 last,
    86                    RandomAccessIter2 result, 
     105                   RandomAccessIter2 result,
    87106                   utility::unweighted_iterator_tag) const
    88107    {
     
    90109      utility::sort_index(first, last, perm);
    91110      double n = perm.size();
    92       size_t i=0; 
     111      size_t i=0;
    93112      while ( i<perm.size() ) {
    94113        size_t min_i = i;
    95114        while (i<perm.size() && first[perm[i]]<=first[perm[min_i]])
    96115          ++i;
    97         double res = static_cast<double>(i + min_i)/(2*n);
     116        double res = (i + min_i)/(2.0*n);
    98117        for ( ; min_i < i; ++min_i)
    99118          result[perm[min_i]] = res;
     
    105124    template<typename RandomAccessIter1, typename RandomAccessIter2>
    106125    void normalize(RandomAccessIter1 first, RandomAccessIter1 last,
    107                    RandomAccessIter2 result, 
     126                   RandomAccessIter2 result,
    108127                   utility::weighted_iterator_tag) const
    109128    {
    110129      detail::copy_weight_if_weighted(first, last, result);
    111       std::vector<double> input_vec;
    112       input_vec.reserve(last-first);
    113       // set values with w=0 to 0 to avoid problems with NaNs
     130      std::vector<size_t> perm;
     131      utility::sort_index(first, last, perm);
    114132      utility::iterator_traits<RandomAccessIter1> trait;
    115       for (RandomAccessIter1 i=first; i!=last; ++i) {
    116         if (trait.weight(i)==0)
    117           input_vec.push_back(0.0);
    118         else
    119           input_vec.push_back(trait.data(i));
    120       }
    121 
    122       std::vector<size_t> perm(input_vec.size());
    123       utility::sort_index(input_vec.begin(), input_vec.end(), perm);
    124133      utility::iterator_traits<RandomAccessIter2> rtrait;
    125134
     135      double total_w = utility::sum_weight(first, last);
    126136      double sum_w=0;
    127       size_t i=0; 
     137      size_t i=0;
    128138      while ( i<perm.size() ) {
    129139        double w=0;
    130140        size_t min_i = i;
    131141        while (i<perm.size() && (trait.weight(first+perm[i])==0 ||
    132                                  trait.data(first+perm[i]) <= 
     142                                 trait.data(first+perm[i]) <=
    133143                                 trait.data(first+perm[min_i])) ) {
    134144          w += trait.weight(first+perm[i]);
    135145          ++i;
    136146        }
    137         double res=sum_w + 0.5*w;
     147        double res = (sum_w + 0.5*w)/total_w;
    138148        for ( size_t j=min_i; j<i; ++j)
    139149          rtrait.data(result+perm[j]) = res;
    140150        sum_w += w;
    141       }       
    142 
    143       size_t n = std::distance(first, last);
    144       std::transform(utility::data_iterator(result),
    145                      utility::data_iterator(result+n),
    146                      utility::data_iterator(result),
    147                      std::bind2nd(std::divides<double>(), sum_w));
     151      }
    148152    }
    149 
    150153  };
    151154
Note: See TracChangeset for help on using the changeset viewer.