yat
0.8.3pre
|
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