source: trunk/yat/normalizer/Zscore.h @ 3550

Last change on this file since 3550 was 3550, checked in by Peter, 5 years ago

Update copyright years. Happy New Year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svndigest:ignore set to 1518
File size: 4.3 KB
Line 
1#ifndef _theplu_yat_normalizer_z_score_
2#define _theplu_yat_normalizer_z_score_
3
4// $Id: Zscore.h 3550 2017-01-03 05:41:02Z peter $
5
6/*
7  Copyright (C) 2008 Jari Häkkinen, Peter Johansson
8  Copyright (C) 2009, 2010, 2016 Peter Johansson
9
10  This file is part of the yat library, http://dev.thep.lu.se/yat
11
12  The yat library is free software; you can redistribute it and/or
13  modify it under the terms of the GNU General Public License as
14  published by the Free Software Foundation; either version 3 of the
15  License, or (at your option) any later version.
16
17  The yat library is distributed in the hope that it will be useful,
18  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20  General Public License for more details.
21
22  You should have received a copy of the GNU General Public License
23  along with yat. If not, see <http://www.gnu.org/licenses/>.
24*/
25
26#include "utility.h"
27
28#include "yat/statistics/Averager.h"
29#include "yat/statistics/AveragerWeighted.h"
30
31#include "yat/utility/concept_check.h"
32#include "yat/utility/iterator_traits.h"
33
34#include <boost/concept_check.hpp>
35
36namespace theplu {
37namespace yat {
38namespace normalizer {
39
40  /**
41     \brief Zero mean and unity variance
42
43     Shift and scale the values in a range as: \f$ y_i =
44     \frac{x_i-m}{s} \f$ where \a m is the mean and \a s is the
45     standard deviation. After normalization, the range will have zero
46     mean and unity variance.
47
48       Type Requirements:
49       - \c InputIterator is \ref concept_data_iterator
50       - \c InputIterator is \forward_traversal_iterator
51       - \c OutputIterator is \writable_iterator
52       - \c OutputIterator is \forward_traversal_iterator
53
54     \since New in yat 0.5
55   */
56  class Zscore
57  {
58  public:
59    /**
60       The element in range [result, result + (last-first)) is
61       calculated as result[i] = (first[i] - m) / s where m and std
62       are the mean and standard deviation, respectively, of the range
63       [first, last).
64
65       It is possible to centralize a range "in place"; it is
66       permissible for the iterators \a first and \a result to be the
67       same. \see std::transform
68     */
69    template<class InputIterator, class OutputIterator>
70    void operator()(InputIterator first, InputIterator last,
71                    OutputIterator result) const
72    {
73      BOOST_CONCEPT_ASSERT((utility::DataIteratorConcept<InputIterator>));
74      BOOST_CONCEPT_ASSERT((utility::DataIteratorConcept<OutputIterator>));
75
76      // needed for weighted_if_any2
77      typename utility::weighted_if_any2<InputIterator, OutputIterator>::type tag;
78      normalize(first, last, result, tag);
79    }
80
81  private:
82    template<class ForwardIterator, class OutputIterator>
83    void normalize(ForwardIterator first, ForwardIterator last,
84                   OutputIterator result,
85                   utility::unweighted_iterator_tag tag) const
86    {
87      // we need to traverse the input range once in calculating m
88      // (and std) and a second time when assigning new values, so
89      // single pass iterator will not suffice.
90      BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversal<ForwardIterator>));
91
92      BOOST_CONCEPT_ASSERT((boost_concepts::WritableIterator<OutputIterator>));
93
94      statistics::Averager a;
95      add(a, first, last);
96      double m = a.mean();
97      double std = a.std();
98      while (first!=last) {
99        *result = (*first - m) / std;
100        ++first;
101        ++result;
102      }
103    }
104
105    template<class ForwardIterator, class OutputIterator>
106    void normalize(ForwardIterator first, ForwardIterator last,
107                   OutputIterator result,
108                   utility::weighted_iterator_tag tag) const
109    {
110      // we need to traverse the input range once in calculating m
111      // (and std) and a second time when assigning new values, so
112      // single pass iterator will not suffice.
113      BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversal<ForwardIterator>));
114
115      BOOST_CONCEPT_ASSERT((boost_concepts::WritableIterator<OutputIterator>));
116      // we traverse output range twice
117      BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversal<OutputIterator>));
118      detail::copy_weight_if_weighted(first, last, result);
119      statistics::AveragerWeighted a;
120      add(a, first, last);
121      double m = a.mean();
122      double std = a.std();
123      utility::iterator_traits<ForwardIterator> in_trait;
124      utility::iterator_traits<OutputIterator> out_trait;
125      while (first!=last) {
126        out_trait.data(result) = (in_trait.data(first) - m) / std;
127        ++first;
128        ++result;
129      }
130    }
131  };
132
133}}} // end of namespace normalizer, yat and thep
134#endif
Note: See TracBrowser for help on using the repository browser.