yat  0.13.2pre
merge.h
1 #ifndef _theplu_yat_utility_merge_
2 #define _theplu_yat_utility_merge_
3 
4 // $Id: merge.h 3225 2014-05-12 05:21:36Z peter $
5 
6 /*
7  Copyright (C) 2009, 2010, 2014 Peter Johansson
8 
9  This file is part of the yat library, http://dev.thep.lu.se/yat
10 
11  The yat library is free software; you can redistribute it and/or
12  modify it under the terms of the GNU General Public License as
13  published by the Free Software Foundation; either version 3 of the
14  License, or (at your option) any later version.
15 
16  The yat library is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  General Public License for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with yat. If not, see <http://www.gnu.org/licenses/>.
23 */
24 
25 #include "concept_check.h"
26 #include "Matrix.h"
27 #include "MatrixWeighted.h"
28 #include "stl_utility.h"
29 
30 #include "yat/statistics/Average.h"
31 
32 #include <boost/concept_check.hpp>
33 #include <boost/iterator/permutation_iterator.hpp>
34 
35 #include <algorithm>
36 #include <map>
37 #include <string>
38 #include <vector>
39 
40 namespace theplu {
41 namespace yat {
42 namespace utility {
43 
65  template<class Container2D>
66  void merge(const Container2D& x, std::vector<std::string>& labels, Matrix& y);
67 
68 
102  template<class Container2D, class Functor>
103  void merge(const Container2D& x, std::vector<std::string>& labels, Matrix& y,
104  Functor func);
105 
152  template<class Container2D, class Functor1, class Functor2>
153  void merge(const Container2D& x, std::vector<std::string>& labels,
154  MatrixWeighted& y, Functor1 data_func, Functor2 weight_func);
155 
156  namespace detail {
157 
164  template<typename Iterator, class Functor1, class Functor2>
165  void assign(double& x, Iterator first, Iterator last, Functor1 func1,
166  Functor2 func2);
167 
173  template<typename Iterator, class Functor1, class Functor2>
174  void assign(DataWeight& x, Iterator first, Iterator last, Functor1 func1,
175  Functor2 func2);
176 
177  void merge_labels(std::vector<std::string>&,
178  std::map<std::string, std::vector<size_t> >&);
179 
180 
181  template<class Container2D, class MutableContainer2D,
182  class Functor1, class Functor2>
183  void merge(const Container2D& x,
184  std::map<std::string, std::vector<size_t> >& label2index,
185  MutableContainer2D& result, Functor1 func1, Functor2 func2);
186 
187  } // end of private namespace detail
188 
189 
190  // template implementations //
191 
192  template<class Container2D>
193  void merge(const Container2D& x, std::vector<std::string>& labels, Matrix& y)
194  {
195  BOOST_CONCEPT_ASSERT((utility::Container2D<Container2D>));
196  merge(x, labels, y, statistics::Average());
197  }
198 
199  template<class Container2D, class Functor>
200  void merge(const Container2D& x, std::vector<std::string>& labels,
201  Matrix& result, Functor func)
202  {
203  BOOST_CONCEPT_ASSERT((utility::Container2D<Container2D>));
204  std::map<std::string, std::vector<size_t> > label2index;
205  detail::merge_labels(labels, label2index);
206  detail::merge(x, label2index, result, func, func);
207  }
208 
209 
210  template<class Container2D, class Functor1, class Functor2>
211  void merge(const Container2D& x, std::vector<std::string>& labels,
212  MatrixWeighted& result, Functor1 func1, Functor2 func2)
213  {
214  BOOST_CONCEPT_ASSERT((utility::Container2D<Container2D>));
215  std::map<std::string, std::vector<size_t> > label2index;
216  detail::merge_labels(labels, label2index);
217  detail::merge(x, label2index, result, func1, func2);
218  }
219 
220  // implemantions of private functions
221 
222  namespace detail {
223  template<typename Iterator, class Functor1, class Functor2>
224  void assign(double& x, Iterator first, Iterator last, Functor1 func1,
225  Functor2 func)
226  {
227  x = func1(first, last);
228  }
229 
230 
231  template<typename Iterator, class Functor1, class Functor2>
232  void assign(DataWeight& x, Iterator first, Iterator last, Functor1 func1,
233  Functor2 func2)
234  {
235  x.data() = func1(first, last);
236  x.weight() = func2(first, last);
237  }
238 
239 
240  void merge_labels(std::vector<std::string>& labels,
241  std::map<std::string, std::vector<size_t> >& label2index)
242  {
243  inverse(labels.begin(), labels.end(), label2index);
244  labels.resize(label2index.size());
245  std::copy(pair_first_iterator(label2index.begin()),
246  pair_first_iterator(label2index.end()),
247  labels.begin());
248  }
249 
250 
251  template<class Container2D, class MutableContainer2D,
252  class Functor1, class Functor2>
253  void merge(const Container2D& x,
254  std::map<std::string, std::vector<size_t> >& label2index,
255  MutableContainer2D& result, Functor1 func1, Functor2 func2)
256  {
257  BOOST_CONCEPT_ASSERT((utility::Mutable_Container2D<MutableContainer2D>));
258  BOOST_CONCEPT_ASSERT((utility::Container2D<Container2D>));
259  result.resize(label2index.size(), x.columns());
260  typedef std::map<std::string, std::vector<size_t> > Map;
261  Map::const_iterator iter=label2index.begin();
262 
263  for (size_t row=0; row<result.rows(); ++row) {
264  const std::vector<size_t>& index = iter->second;
265  for (size_t col=0; col<result.columns(); ++col) {
266  using boost::make_permutation_iterator;
267  assign(result(row,col),
268  make_permutation_iterator(x.begin_column(col), index.begin()),
269  make_permutation_iterator(x.end_column(col), index.end()),
270  func1, func2);
271  }
272  ++iter;
273  }
274  }
275 
276  } // end of namespace detail
277 
278 }}} // of namespace utility, yat, and theplu
279 
280 #endif
void inverse(InputIterator first, InputIterator last, std::map< Key, std::vector< size_t >, Comp > &m)
Definition: stl_utility.h:538
void merge(const Container2D &x, std::vector< std::string > &labels, Matrix &y)
merge rows in a Container2D
Definition: merge.h:193
Functor to take average of a range.
Definition: Average.h:36
Concept check for Container2D.
Definition: concept_check.h:57
boost::transform_iterator< PairFirst< typename boost::remove_reference< typename std::iterator_traits< Iter >::reference >::type >, Iter > pair_first_iterator(Iter i)
Definition: stl_utility.h:830
Interface to GSL matrix.
Definition: Matrix.h:63
Weighted Matrix.
Definition: MatrixWeighted.h:44

Generated on Wed Jan 4 2017 02:23:07 for yat by  doxygen 1.8.5