yat/normalizer/RangeNormalizer.h

Code
Comments
Other
Rev Date Author Line
3953 22 Jul 20 peter 1 #ifndef _theplu_yat_normalizer_range_normalizer_
3953 22 Jul 20 peter 2 #define _theplu_yat_normalizer_range_normalizer_
1445 27 Aug 08 peter 3
1576 14 Oct 08 jari 4 // $Id$
1576 14 Oct 08 jari 5
1445 27 Aug 08 peter 6 /*
2119 12 Dec 09 peter 7   Copyright (C) 2008 Jari H√§kkinen, Peter Johansson
3953 22 Jul 20 peter 8   Copyright (C) 2009, 2010, 2011, 2014, 2016, 2020 Peter Johansson
1445 27 Aug 08 peter 9
1445 27 Aug 08 peter 10   This file is part of the yat library, http://dev.thep.lu.se/yat
1445 27 Aug 08 peter 11
1445 27 Aug 08 peter 12   The yat library is free software; you can redistribute it and/or
1445 27 Aug 08 peter 13   modify it under the terms of the GNU General Public License as
1486 09 Sep 08 jari 14   published by the Free Software Foundation; either version 3 of the
1445 27 Aug 08 peter 15   License, or (at your option) any later version.
1445 27 Aug 08 peter 16
1445 27 Aug 08 peter 17   The yat library is distributed in the hope that it will be useful,
1445 27 Aug 08 peter 18   but WITHOUT ANY WARRANTY; without even the implied warranty of
1445 27 Aug 08 peter 19   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1445 27 Aug 08 peter 20   General Public License for more details.
1445 27 Aug 08 peter 21
1445 27 Aug 08 peter 22   You should have received a copy of the GNU General Public License
1487 10 Sep 08 jari 23   along with yat. If not, see <http://www.gnu.org/licenses/>.
1445 27 Aug 08 peter 24 */
1445 27 Aug 08 peter 25
2283 26 Jun 10 peter 26 #include "utility.h"
2283 26 Jun 10 peter 27
3541 23 Dec 16 peter 28 #include "yat/utility/concept_check.h"
1523 23 Sep 08 peter 29 #include "yat/utility/DataIterator.h"
1523 23 Sep 08 peter 30 #include "yat/utility/iterator_traits.h"
1523 23 Sep 08 peter 31 #include "yat/utility/WeightIterator.h"
1445 27 Aug 08 peter 32
2146 15 Jan 10 peter 33 #include <boost/concept_check.hpp>
3281 08 Jul 14 peter 34 #include <boost/iterator/iterator_concepts.hpp>
2146 15 Jan 10 peter 35
1445 27 Aug 08 peter 36 #include <algorithm>
1445 27 Aug 08 peter 37 #include <functional>
1445 27 Aug 08 peter 38
1445 27 Aug 08 peter 39 namespace theplu {
1445 27 Aug 08 peter 40 namespace yat {
1497 12 Sep 08 peter 41 namespace normalizer {
1445 27 Aug 08 peter 42
1445 27 Aug 08 peter 43   /**
3953 22 Jul 20 peter 44      The class normalizes a range <tt> [first, last) </tt> in two
3953 22 Jul 20 peter 45      steps. First, a value is calculaterd using the functor \c
3953 22 Jul 20 peter 46      UnaryFunction. Second, the each element in the result range is
3953 22 Jul 20 peter 47      calculated by applying the operator on the input range and the
3953 22 Jul 20 peter 48      value. \c UnaryFunction must be a functor that has an operator:
1445 27 Aug 08 peter 49
3281 08 Jul 14 peter 50      \code
2415 22 Jan 11 peter 51      return_type operator()(InputIterator, InputIterator) const
3281 08 Jul 14 peter 52      \endcode
2283 26 Jun 10 peter 53
2415 22 Jan 11 peter 54      where \c return_type must be convertible to \c value_type of \c
3953 22 Jul 20 peter 55      InputIterator.
2415 22 Jan 11 peter 56
3953 22 Jul 20 peter 57      Operator must be a binary function object class with result type
3953 22 Jul 20 peter 58      and argument types such that <tt> result type </tt> is convertible to
3953 22 Jul 20 peter 59      \c double and \c double is convertible to the <tt> argument type</tt>s.
3953 22 Jul 20 peter 60
3953 22 Jul 20 peter 61      \since New in yat 0.18
1445 27 Aug 08 peter 62    */
3953 22 Jul 20 peter 63   template<class UnaryFunction, class Operator>
3953 22 Jul 20 peter 64   class RangeNormalizer
1445 27 Aug 08 peter 65   {
1445 27 Aug 08 peter 66   public:
1445 27 Aug 08 peter 67     /**
1445 27 Aug 08 peter 68        \brief default constructor
1445 27 Aug 08 peter 69
3953 22 Jul 20 peter 70        Internal UnaryFunction and Operator are created using default
3953 22 Jul 20 peter 71        constructors.
1445 27 Aug 08 peter 72      */
3953 22 Jul 20 peter 73     RangeNormalizer(void){}
1445 27 Aug 08 peter 74
1445 27 Aug 08 peter 75     /**
3953 22 Jul 20 peter 76        \param uf unary function defining the value
1445 27 Aug 08 peter 77      */
3953 22 Jul 20 peter 78     // This is superfluous but required to keep the Centralizer API
3953 22 Jul 20 peter 79     // with version 0.17
3953 22 Jul 20 peter 80     RangeNormalizer(const UnaryFunction& uf)
1445 27 Aug 08 peter 81       : func_(uf) {}
1445 27 Aug 08 peter 82
1445 27 Aug 08 peter 83     /**
3953 22 Jul 20 peter 84        \param uf unary function defining the value
3953 22 Jul 20 peter 85        \param op binary function defining the operation applied on the
3953 22 Jul 20 peter 86        input range
3953 22 Jul 20 peter 87      */
3953 22 Jul 20 peter 88     RangeNormalizer(const UnaryFunction& uf, const Operator& op)
3953 22 Jul 20 peter 89       : func_(uf), op_(op) {}
3953 22 Jul 20 peter 90
3953 22 Jul 20 peter 91     /**
3953 22 Jul 20 peter 92        Calculates the value \a x of the range [first, last) using
3953 22 Jul 20 peter 93        UnaryFunction. This value, \a x, is then applied from each
1445 27 Aug 08 peter 94        element in the range [first, last) and assigned to the
1445 27 Aug 08 peter 95        corresponding element in range [result, result + (last-first) ).
1445 27 Aug 08 peter 96
3953 22 Jul 20 peter 97        It is possible to normalize a range "in place"; it is
1445 27 Aug 08 peter 98        permissible for the iterators \a first and \a result to be the
3281 08 Jul 14 peter 99        same.
1445 27 Aug 08 peter 100
2415 22 Jan 11 peter 101        Type Requirements:
3281 08 Jul 14 peter 102        - \c InputIterator is \ref concept_data_iterator
3281 08 Jul 14 peter 103        - \c InputIterator is \readable_iterator
3281 08 Jul 14 peter 104        - \c InputIterator is \forward_traversal_iterator
3281 08 Jul 14 peter 105        - \c OutputIterator is \ref concept_data_iterator
3281 08 Jul 14 peter 106        - \c OutputIterator is \readable_iterator
3281 08 Jul 14 peter 107        - \c OutputIterator is \writable_iterator
3281 08 Jul 14 peter 108        - If \c OutputIterator is \ref concept_weighted_iterator, it
3281 08 Jul 14 peter 109        must be a \forward_traversal_iterator; if unweighted,
3281 08 Jul 14 peter 110        \single_pass_iterator suffice.
2415 22 Jan 11 peter 111
1717 13 Jan 09 peter 112        \see std::transform
1445 27 Aug 08 peter 113      */
3281 08 Jul 14 peter 114     template<class InputIterator, class OutputIterator>
1739 21 Jan 09 peter 115     void operator()(InputIterator first, InputIterator last,
3281 08 Jul 14 peter 116                     OutputIterator result) const
1445 27 Aug 08 peter 117     {
3541 23 Dec 16 peter 118       BOOST_CONCEPT_ASSERT((utility::DataIteratorConcept<InputIterator>));
3541 23 Dec 16 peter 119       BOOST_CONCEPT_ASSERT((utility::DataIteratorConcept<OutputIterator>));
3541 23 Dec 16 peter 120       BOOST_CONCEPT_ASSERT((boost_concepts::WritableIterator<OutputIterator>));
3541 23 Dec 16 peter 121
3281 08 Jul 14 peter 122       // we need to traverse the input range once in call to func_ and
3281 08 Jul 14 peter 123       // one in call to std::transform, so single pass iterator will
3281 08 Jul 14 peter 124       // not suffice.
3281 08 Jul 14 peter 125       BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversal<InputIterator>));
3281 08 Jul 14 peter 126       // requirments for OutputIterator is different depending on
3281 08 Jul 14 peter 127       // whether it's weighted or not
3281 08 Jul 14 peter 128       typename utility::weighted_iterator_traits<OutputIterator>::type tag;
3281 08 Jul 14 peter 129       check_requirements<OutputIterator>(tag);
3281 08 Jul 14 peter 130
2283 26 Jun 10 peter 131       // copy weight if result is weighted
3281 08 Jul 14 peter 132       detail::copy_weight_if_weighted(first, last, result);
3954 22 Jul 20 peter 133       double val = func_(first, last);
3281 08 Jul 14 peter 134       std::transform(utility::data_iterator(first),
3281 08 Jul 14 peter 135                      utility::data_iterator(last),
1523 23 Sep 08 peter 136                      utility::data_iterator(result),
3954 22 Jul 20 peter 137                      [this, val](double x) {return op_(x, val);});
1523 23 Sep 08 peter 138     }
1523 23 Sep 08 peter 139
2283 26 Jun 10 peter 140   private:
3281 08 Jul 14 peter 141
3281 08 Jul 14 peter 142     template<typename OutputIterator>
3281 08 Jul 14 peter 143     void check_requirements(utility::unweighted_iterator_tag) const
3281 08 Jul 14 peter 144     {
3281 08 Jul 14 peter 145       using boost_concepts::SinglePassIterator;
3281 08 Jul 14 peter 146       using boost_concepts::WritableIterator;
3281 08 Jul 14 peter 147       BOOST_CONCEPT_ASSERT((SinglePassIterator<OutputIterator>));
3281 08 Jul 14 peter 148       BOOST_CONCEPT_ASSERT((WritableIterator<OutputIterator, double>));
3281 08 Jul 14 peter 149
3281 08 Jul 14 peter 150     }
3281 08 Jul 14 peter 151
3281 08 Jul 14 peter 152     template<typename OutputIterator>
3281 08 Jul 14 peter 153     void check_requirements(utility::weighted_iterator_tag) const
3281 08 Jul 14 peter 154     {
3281 08 Jul 14 peter 155       using boost_concepts::ForwardTraversal;
3281 08 Jul 14 peter 156       using boost_concepts::WritableIterator;
3281 08 Jul 14 peter 157       BOOST_CONCEPT_ASSERT((ForwardTraversal<OutputIterator>));
3281 08 Jul 14 peter 158       BOOST_CONCEPT_ASSERT((WritableIterator<OutputIterator
3281 08 Jul 14 peter 159                             , utility::DataWeight>));
3281 08 Jul 14 peter 160     }
3281 08 Jul 14 peter 161
2283 26 Jun 10 peter 162     UnaryFunction func_;
3953 22 Jul 20 peter 163     Operator op_;
1445 27 Aug 08 peter 164   };
1445 27 Aug 08 peter 165
1497 12 Sep 08 peter 166 }}} // end of namespace normalizer, yat and thep
1445 27 Aug 08 peter 167 #endif