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 "Matrix.h"
00026 #include "MatrixWeighted.h"
00027 #include "stl_utility.h"
00028
00029 #include "yat/statistics/Average.h"
00030
00031 #include <boost/iterator/permutation_iterator.hpp>
00032
00033 #include <algorithm>
00034 #include <map>
00035 #include <string>
00036 #include <vector>
00037
00038 namespace theplu {
00039 namespace yat {
00040 namespace utility {
00041
00063 template<class Container2D>
00064 void merge(const Container2D& x, std::vector<std::string>& labels, Matrix& y);
00065
00066
00080 template<class Container2D, class Functor>
00081 void merge(const Container2D& x, std::vector<std::string>& labels, Matrix& y,
00082 Functor func);
00083
00111 template<class Container2D, class Functor1, class Functor2>
00112 void merge(const Container2D& x, std::vector<std::string>& labels,
00113 MatrixWeighted& y, Functor1 data_func, Functor2 weight_func);
00114
00115 namespace detail {
00116
00123 template<typename Iterator, class Functor1, class Functor2>
00124 void assign(double& x, Iterator first, Iterator last, Functor1 func1,
00125 Functor2 func2);
00126
00132 template<typename Iterator, class Functor1, class Functor2>
00133 void assign(DataWeight& x, Iterator first, Iterator last, Functor1 func1,
00134 Functor2 func2);
00135
00136 void merge_labels(std::vector<std::string>&,
00137 std::map<std::string, std::vector<size_t> >&);
00138
00139
00140 template<class Container2D, class MutableContainer2D,
00141 class Functor1, class Functor2>
00142 void merge(const Container2D& x,
00143 std::map<std::string, std::vector<size_t> >& label2index,
00144 MutableContainer2D& result, Functor1 func1, Functor2 func2);
00145
00146 }
00147
00148
00149
00150
00151 template<class Container2D>
00152 void merge(const Container2D& x, std::vector<std::string>& labels, Matrix& y)
00153 {
00154 merge(x, labels, y, statistics::Average());
00155 }
00156
00157 template<class Container2D, class Functor>
00158 void merge(const Container2D& x, std::vector<std::string>& labels,
00159 Matrix& result, Functor func)
00160 {
00161 std::map<std::string, std::vector<size_t> > label2index;
00162 detail::merge_labels(labels, label2index);
00163 detail::merge(x, label2index, result, func, func);
00164 }
00165
00166
00167 template<class Container2D, class Functor1, class Functor2>
00168 void merge(const Container2D& x, std::vector<std::string>& labels,
00169 MatrixWeighted& result, Functor1 func1, Functor2 func2)
00170 {
00171 std::map<std::string, std::vector<size_t> > label2index;
00172 detail::merge_labels(labels, label2index);
00173 detail::merge(x, label2index, result, func1, func2);
00174 }
00175
00176
00177
00178 namespace detail {
00179 template<typename Iterator, class Functor1, class Functor2>
00180 void assign(double& x, Iterator first, Iterator last, Functor1 func1,
00181 Functor2 func)
00182 {
00183 x = func1(first, last);
00184 }
00185
00186
00187 template<typename Iterator, class Functor1, class Functor2>
00188 void assign(DataWeight& x, Iterator first, Iterator last, Functor1 func1,
00189 Functor2 func2)
00190 {
00191 x.data() = func1(first, last);
00192 x.weight() = func2(first, last);
00193 }
00194
00195
00196 void merge_labels(std::vector<std::string>& labels,
00197 std::map<std::string, std::vector<size_t> >& label2index)
00198 {
00199 inverse(labels.begin(), labels.end(), label2index);
00200 labels.resize(label2index.size());
00201 std::copy(pair_first_iterator(label2index.begin()),
00202 pair_first_iterator(label2index.end()),
00203 labels.begin());
00204 }
00205
00206
00207 template<class Container2D, class MutableContainer2D,
00208 class Functor1, class Functor2>
00209 void merge(const Container2D& x,
00210 std::map<std::string, std::vector<size_t> >& label2index,
00211 MutableContainer2D& result, Functor1 func1, Functor2 func2)
00212 {
00213 result.resize(label2index.size(), x.columns());
00214 typedef std::map<std::string, std::vector<size_t> > Map;
00215 Map::const_iterator iter=label2index.begin();
00216
00217 for (size_t row=0; row<result.rows(); ++row) {
00218 const std::vector<size_t>& index = iter->second;
00219 for (size_t col=0; col<result.columns(); ++col) {
00220 assign(result(row,col),
00221 boost::make_permutation_iterator(x.begin_column(col),
00222 index.begin()),
00223 boost::make_permutation_iterator(x.end_column(col),
00224 index.end()),
00225 func1, func2);
00226 }
00227 ++iter;
00228 }
00229 }
00230
00231 }
00232
00233 }}}
00234
00235 #endif