yat/normalizer/UnityScaler.h

Code
Comments
Other
Rev Date Author Line
3957 26 Jul 20 peter 1 #ifndef _theplu_yat_normalizer_unity_scaler_
3957 26 Jul 20 peter 2 #define _theplu_yat_normalizer_unity_scaler_
3957 26 Jul 20 peter 3
3957 26 Jul 20 peter 4 // $Id$
3957 26 Jul 20 peter 5
3957 26 Jul 20 peter 6 /*
4164 13 Mar 22 peter 7   Copyright (C) 2020, 2022 Peter Johansson
3957 26 Jul 20 peter 8
3957 26 Jul 20 peter 9   This file is part of the yat library, http://dev.thep.lu.se/yat
3957 26 Jul 20 peter 10
3957 26 Jul 20 peter 11   The yat library is free software; you can redistribute it and/or
3957 26 Jul 20 peter 12   modify it under the terms of the GNU General Public License as
3957 26 Jul 20 peter 13   published by the Free Software Foundation; either version 3 of the
3957 26 Jul 20 peter 14   License, or (at your option) any later version.
3957 26 Jul 20 peter 15
3957 26 Jul 20 peter 16   The yat library is distributed in the hope that it will be useful,
3957 26 Jul 20 peter 17   but WITHOUT ANY WARRANTY; without even the implied warranty of
3957 26 Jul 20 peter 18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3957 26 Jul 20 peter 19   General Public License for more details.
3957 26 Jul 20 peter 20
3957 26 Jul 20 peter 21   You should have received a copy of the GNU General Public License
3957 26 Jul 20 peter 22   along with yat. If not, see <http://www.gnu.org/licenses/>.
3957 26 Jul 20 peter 23 */
3957 26 Jul 20 peter 24
3957 26 Jul 20 peter 25 #include "RangeNormalizer.h"
3957 26 Jul 20 peter 26 #include "yat/statistics/AveragerWeighted.h"
3957 26 Jul 20 peter 27 #include "yat/utility/DataIterator.h"
3957 26 Jul 20 peter 28
3957 26 Jul 20 peter 29 #include <functional>
4164 13 Mar 22 peter 30 #include <numeric>
3957 26 Jul 20 peter 31
3957 26 Jul 20 peter 32 namespace theplu {
3957 26 Jul 20 peter 33 namespace yat {
3957 26 Jul 20 peter 34 namespace normalizer {
3957 26 Jul 20 peter 35
3957 26 Jul 20 peter 36   /// \cond IGNORE_DOXYGEN
3957 26 Jul 20 peter 37   namespace detail {
3957 26 Jul 20 peter 38     class UnityScalerFactor
3957 26 Jul 20 peter 39     {
3957 26 Jul 20 peter 40     public:
3957 26 Jul 20 peter 41       // return the inverse of the sum of range [first, last)
3957 26 Jul 20 peter 42       template<typename Iterator>
3957 26 Jul 20 peter 43       double operator()(Iterator first, Iterator last) const
3957 26 Jul 20 peter 44       {
3957 26 Jul 20 peter 45         using traits = typename utility::weighted_iterator_traits<Iterator>;
3957 26 Jul 20 peter 46         return calculate(first, last, typename traits::type());
3957 26 Jul 20 peter 47       }
3957 26 Jul 20 peter 48
3957 26 Jul 20 peter 49     private:
3957 26 Jul 20 peter 50
3957 26 Jul 20 peter 51       template<typename Iterator>
3957 26 Jul 20 peter 52       double calculate(Iterator first, Iterator last,
3957 26 Jul 20 peter 53                        utility::unweighted_iterator_tag tag) const
3957 26 Jul 20 peter 54       {
3957 26 Jul 20 peter 55         return 1.0 / std::accumulate(utility::data_iterator(first),
3957 26 Jul 20 peter 56                                      utility::data_iterator(last),
3957 26 Jul 20 peter 57                                      0.0);
3957 26 Jul 20 peter 58       }
3957 26 Jul 20 peter 59
3957 26 Jul 20 peter 60
3957 26 Jul 20 peter 61       template<typename Iterator>
3957 26 Jul 20 peter 62       double calculate(Iterator first, Iterator last,
3957 26 Jul 20 peter 63                        utility::weighted_iterator_tag tag) const
3957 26 Jul 20 peter 64       {
3957 26 Jul 20 peter 65         statistics::AveragerWeighted averager;
3957 26 Jul 20 peter 66         add(averager, first, last);
3957 26 Jul 20 peter 67         return 1.0 / averager.sum_wx();
3957 26 Jul 20 peter 68       }
3957 26 Jul 20 peter 69     };
3957 26 Jul 20 peter 70   }
3957 26 Jul 20 peter 71   /// \endcond
3957 26 Jul 20 peter 72
3957 26 Jul 20 peter 73
3957 26 Jul 20 peter 74   /**
3957 26 Jul 20 peter 75      \brief Scale a range to unity
3957 26 Jul 20 peter 76
3957 26 Jul 20 peter 77      The sum of input range is calculated. If the input range is
3957 26 Jul 20 peter 78      unweighted: \f$\sum x_i \f$; if the input range is weighted: \f$
3957 26 Jul 20 peter 79      \sum w_i x_i \f$ and the data value in the result range is
3957 26 Jul 20 peter 80      calculated as the <tt> result[i] = input[i] / sum
3957 26 Jul 20 peter 81      </tt>. Consequently, the sum of elements in the resulting range
3957 26 Jul 20 peter 82      is unity, except in the case when the input range is weighted and
3957 26 Jul 20 peter 83      the result range is unweighed the information about the weights
3957 26 Jul 20 peter 84      gets lost.
3957 26 Jul 20 peter 85
3957 26 Jul 20 peter 86      \since New in yat 0.18
3957 26 Jul 20 peter 87    */
3957 26 Jul 20 peter 88   using UnityScaler =
3957 26 Jul 20 peter 89     RangeNormalizer<detail::UnityScalerFactor, std::multiplies<double>>;
3957 26 Jul 20 peter 90
3957 26 Jul 20 peter 91 }}} // end of namespace normalizer, yat and thep
3957 26 Jul 20 peter 92 #endif