yat  0.8.3pre
merge.h
00001 #ifndef _theplu_yat_utility_merge_
00002 #define _theplu_yat_utility_merge_ 
00003 
00004 // $Id: merge.h 2372 2010-12-12 07:18:51Z peter $
00005 
00006 /*
00007   Copyright (C) 2009, 2010 Peter Johansson
00008 
00009   This file is part of the yat library, http://dev.thep.lu.se/yat
00010 
00011   The yat library is free software; you can redistribute it and/or
00012   modify it under the terms of the GNU General Public License as
00013   published by the Free Software Foundation; either version 3 of the
00014   License, or (at your option) any later version.
00015 
00016   The yat library is distributed in the hope that it will be useful,
00017   but WITHOUT ANY WARRANTY; without even the implied warranty of
00018   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00019   General Public License for more details.
00020 
00021   You should have received a copy of the GNU General Public License
00022   along with yat. If not, see <http://www.gnu.org/licenses/>.
00023 */
00024 
00025 #include "concept_check.h"
00026 #include "Matrix.h"
00027 #include "MatrixWeighted.h"
00028 #include "stl_utility.h"
00029 
00030 #include "yat/statistics/Average.h"
00031 
00032 #include <boost/concept_check.hpp>
00033 #include <boost/iterator/permutation_iterator.hpp>
00034 
00035 #include <algorithm>
00036 #include <map>
00037 #include <string>
00038 #include <vector>
00039 
00040 namespace theplu {
00041 namespace yat {
00042 namespace utility {
00043 
00065   template<class Container2D>
00066   void merge(const Container2D& x, std::vector<std::string>& labels, Matrix& y); 
00067 
00068 
00082   template<class Container2D, class Functor>
00083   void merge(const Container2D& x, std::vector<std::string>& labels, Matrix& y,
00084              Functor func); 
00085 
00113   template<class Container2D, class Functor1, class Functor2>
00114   void merge(const Container2D& x, std::vector<std::string>& labels, 
00115              MatrixWeighted& y, Functor1 data_func, Functor2 weight_func); 
00116 
00117   namespace detail {
00118     
00125     template<typename Iterator, class Functor1, class Functor2>
00126     void assign(double& x, Iterator first, Iterator last, Functor1 func1,
00127                 Functor2 func2);
00128 
00134     template<typename Iterator, class Functor1, class Functor2>
00135     void assign(DataWeight& x, Iterator first, Iterator last, Functor1 func1,
00136                 Functor2 func2);
00137 
00138     void merge_labels(std::vector<std::string>&, 
00139                       std::map<std::string, std::vector<size_t> >&);
00140 
00141 
00142     template<class Container2D, class MutableContainer2D, 
00143              class Functor1, class Functor2>
00144     void merge(const Container2D& x, 
00145                std::map<std::string, std::vector<size_t> >& label2index, 
00146                MutableContainer2D& result, Functor1 func1, Functor2 func2);
00147 
00148   } // end of private namespace detail
00149 
00150 
00151   // template implementations //
00152 
00153   template<class Container2D>
00154   void merge(const Container2D& x, std::vector<std::string>& labels, Matrix& y)
00155   {
00156     BOOST_CONCEPT_ASSERT((utility::Container2D<Container2D>));
00157     merge(x, labels, y, statistics::Average());
00158   }
00159 
00160   template<class Container2D, class Functor>
00161   void merge(const Container2D& x, std::vector<std::string>& labels, 
00162              Matrix& result, Functor func)
00163   {
00164     BOOST_CONCEPT_ASSERT((utility::Container2D<Container2D>));
00165     std::map<std::string, std::vector<size_t> > label2index;
00166     detail::merge_labels(labels, label2index);
00167     detail::merge(x, label2index, result, func, func);
00168   }
00169 
00170 
00171   template<class Container2D, class Functor1, class Functor2>
00172   void merge(const Container2D& x, std::vector<std::string>& labels, 
00173              MatrixWeighted& result, Functor1 func1, Functor2 func2)
00174   {
00175     BOOST_CONCEPT_ASSERT((utility::Container2D<Container2D>));
00176     std::map<std::string, std::vector<size_t> > label2index;
00177     detail::merge_labels(labels, label2index);
00178     detail::merge(x, label2index, result, func1, func2);
00179   } 
00180 
00181   // implemantions of private functions
00182 
00183   namespace detail {
00184     template<typename Iterator, class Functor1, class Functor2>
00185     void assign(double& x, Iterator first, Iterator last, Functor1 func1,
00186                 Functor2 func)
00187     {
00188       x = func1(first, last);
00189     }
00190 
00191 
00192     template<typename Iterator, class Functor1, class Functor2>
00193     void assign(DataWeight& x, Iterator first, Iterator last, Functor1 func1,
00194                 Functor2 func2)
00195     {
00196       x.data() = func1(first, last);
00197       x.weight() = func2(first, last);
00198     }
00199 
00200 
00201     void merge_labels(std::vector<std::string>& labels, 
00202                       std::map<std::string, std::vector<size_t> >& label2index)
00203     {
00204       inverse(labels.begin(), labels.end(), label2index);
00205       labels.resize(label2index.size());
00206       std::copy(pair_first_iterator(label2index.begin()),
00207                 pair_first_iterator(label2index.end()),
00208                 labels.begin());
00209     }
00210 
00211 
00212     template<class Container2D, class MutableContainer2D, 
00213              class Functor1, class Functor2>
00214     void merge(const Container2D& x, 
00215                std::map<std::string, std::vector<size_t> >& label2index, 
00216                MutableContainer2D& result, Functor1 func1, Functor2 func2)
00217     {
00218       BOOST_CONCEPT_ASSERT((utility::Mutable_Container2D<MutableContainer2D>));
00219       BOOST_CONCEPT_ASSERT((utility::Container2D<Container2D>));
00220       result.resize(label2index.size(), x.columns());
00221       typedef std::map<std::string, std::vector<size_t> > Map;
00222       Map::const_iterator iter=label2index.begin(); 
00223 
00224       for (size_t row=0; row<result.rows(); ++row) {
00225         const std::vector<size_t>& index = iter->second;
00226         for (size_t col=0; col<result.columns(); ++col) {
00227           assign(result(row,col), 
00228                  boost::make_permutation_iterator(x.begin_column(col), 
00229                                                   index.begin()),
00230                  boost::make_permutation_iterator(x.end_column(col), 
00231                                                   index.end()),
00232                  func1, func2);
00233         }
00234         ++iter;
00235       }
00236     } 
00237 
00238   } // end of namespace detail
00239 
00240 }}} // of namespace utility, yat, and theplu
00241 
00242 #endif

Generated on Thu Dec 20 2012 03:12:58 for yat by  doxygen 1.8.0-20120409