00001 #ifndef _theplu_yat_utility_merge_
00002 #define _theplu_yat_utility_merge_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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 }
00149
00150
00151
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
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 }
00239
00240 }}}
00241
00242 #endif