00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef WIFI_FRAME_FILTER_SYNCHRONIZER_HXX_
00023 # define WIFI_FRAME_FILTER_SYNCHRONIZER_HXX_
00024
00025 # include "linear_regression_synchronizer.hh"
00026
00027 # include <wipal/tool/linear_regression.hh>
00028 # include <wipal/tool/window.hh>
00029 # include <wipal/wifi/frame/filter/intersector.hh>
00030 # include <wipal/wifi/frame/filter/reference_blacklist.hh>
00031
00032 namespace wifi
00033 {
00034 namespace frame
00035 {
00036 namespace filter
00037 {
00038
00039 template <class OriginalFrameType, class ImplType>
00040 synchronized_frame<OriginalFrameType, ImplType>::
00041 synchronized_frame(const OriginalFrameType& orig,
00042 const coefs_type& coefs):
00043 OriginalFrameType (orig),
00044 coefs (coefs)
00045 {
00046 }
00047
00048 namespace internals
00049 {
00050
00051 template <class I, class B1, class B2>
00052 lr_sync_iterator<I, B1, B2>::
00053 lr_sync_iterator(const iterable_type& iterable, bool end):
00054 iterable_ (&iterable),
00055 win_ (end ? iterable.last_ : iterable.first_),
00056 wpos_ (0)
00057 {
00058 if (not end and win_ != iterable_->last_)
00059 while (not update_value() and advance())
00060 ;
00061 }
00062
00063 template <class I, class B1, class B2>
00064 bool
00065 lr_sync_iterator<I, B1, B2>::equal(const exact_type& rhs) const
00066 {
00067 if (not rhs.value())
00068 return not this->value();
00069 return wpos_ == rhs.wpos_ and win_ == rhs.win_;
00070 }
00071
00072 template <class I, class B1, class B2>
00073 bool
00074 lr_sync_iterator<I, B1, B2>::advance()
00075 {
00076 assert(win_ != iterable_->last_);
00077
00078 const size_t win_size = win_->size();
00079
00080 if (wpos_ < win_size / 2)
00081 ++wpos_;
00082 else if (not win_.last())
00083 ++win_;
00084 else if (++wpos_ >= win_size)
00085 {
00086
00087 this->value() = boost::none_t ();
00088
00089
00090 ++win_;
00091 wpos_ = 0;
00092
00093 assert(win_ == iterable_->last_);
00094 return false;
00095 }
00096 assert(win_ != iterable_->last_);
00097 return true;
00098 }
00099
00100 template <class I, class B1, class B2>
00101 bool
00102 lr_sync_iterator<I, B1, B2>::update_value()
00103 {
00104 typedef typename I::value_type::value_type ref_type;
00105
00106 assert(win_ != iterable_->last_);
00107
00108 try
00109 {
00110 typedef typename value_type::impl_type impl_type;
00111 typedef typename
00112 tool::lr::pair_with_microseconds<impl_type> adapter_type;
00113
00114 const std::pair<impl_type, impl_type> p =
00115 tool::linear_regression<impl_type, adapter_type>(win_->begin(),
00116 win_->end());
00117
00118 const ref_type& ref = win_[wpos_];
00119 const impl_type t1 = ref.first.microseconds();
00120 const impl_type t2 = ref.second.microseconds();
00121 const impl_type error = t2 - t1 * p.first - p.second;
00122 const impl_type precision = iterable_->precision_;
00123
00124 if (error < -precision or precision < error)
00125 {
00126 std::cerr << ref.first << '-' << ref.second
00127 << ": Ignoring this ref. because of a "
00128 << "high sync. error (" << error << ")."
00129 << std::endl;
00130 return false;
00131 }
00132 if (p.first < 0.9 or 1.1 < p.first)
00133 std::cerr << ref.first << '-' << ref.second
00134 << ": Dubious sync. coef. of " << p.first
00135 << '.' << std::endl;
00136
00137 this->value() = value_type (ref, p);
00138 return true;
00139 }
00140 catch (const std::invalid_argument& i)
00141 {
00142 assert(not win_->empty());
00143
00144 const ref_type& b = win_->front();
00145 const ref_type& e = win_->back();
00146
00147 std::cerr << b.first << '-' << b.second << ": " << i.what()
00148 << ".\n" << e.first << '-' << e.second
00149 << ": Sync. window's last reference." << std::endl;
00150 return false;
00151 }
00152 }
00153
00154 template <class I, class B1, class B2>
00155 void
00156 lr_sync_iterator<I, B1, B2>::increment()
00157 {
00158 while (advance() and not update_value())
00159 ;
00160 }
00161
00162 }
00163
00164 template <class I, class B>
00165 linear_regression_synchronizer<I, B>::
00166 linear_regression_synchronizer(const I& first,
00167 const I& last,
00168 const unsigned precision):
00169 first_ (first),
00170 last_ (last),
00171 precision_ (precision)
00172 {
00173 }
00174
00175 namespace internals
00176 {
00177
00178 template <class F>
00179 struct provide_lr_synchronizer
00180 {
00181 enum
00182 {
00183 window_size =
00184
00185 #ifdef WP_LRSYNC_WINDOW_SIZE
00186 WP_LRSYNC_WINDOW_SIZE
00187 #else // ! WP_LRSYNC_WINDOW_SIZE
00188 3
00189 #endif
00190
00191 };
00192
00193 typedef std::set< std::pair<unsigned, unsigned> > ref_blacklist;
00194
00195 provide_lr_synchronizer(F& func,
00196 const ref_blacklist& blist,
00197 const unsigned& prec):
00198 func_ (func),
00199 blist_ (blist),
00200 prec_ (prec)
00201 {
00202 }
00203
00204 template <class Intersector>
00205 void
00206 operator () (const Intersector& i)
00207 {
00208 typedef typename Intersector::const_iterator i_iterator;
00209 typedef reference_blacklist<i_iterator> blist;
00210 typedef typename blist::const_iterator b_iterator;
00211 typedef tool::window_maker<b_iterator, window_size> window_maker;
00212 typedef typename window_maker::const_iterator w_iterator;
00213 typedef linear_regression_synchronizer<w_iterator> synchronizer;
00214
00215 blist l (i.begin(), i.end(), blist_);
00216 window_maker w (l.begin(), l.end());
00217 synchronizer s (w.begin(), w.end(), prec_);
00218
00219 func_(s);
00220 }
00221
00222 private:
00223 F& func_;
00224 const ref_blacklist& blist_;
00225 const unsigned& prec_;
00226 };
00227
00228 }
00229
00230 template <class U, class HT, template <class, class, class> class Int,
00231 class I1, class I2, class F>
00232 void
00233 provide_lr_synchronizer(const I1& first1, const I1& last1,
00234 const I2& first2, const I2& last2,
00235 tool::opt::list& options,
00236 F& func)
00237 {
00238 typedef internals::provide_lr_synchronizer<F> provider_ftor;
00239 typedef typename provider_ftor::ref_blacklist ref_blacklist;
00240
00241 const ref_blacklist& blist = (options["ref_blacklist"]
00242 .get<ref_blacklist>());
00243 const unsigned& prec = options["precision"].get<unsigned>();
00244 provider_ftor func2 (func, blist, prec);
00245
00246 provide_intersector<U, HT, Int>(first1, last1, first2, last2,
00247 options, func2);
00248 }
00249
00250
00251 }
00252
00253 }
00254
00255 }
00256
00257 #endif // ! WIFI_FRAME_FILTER_SYNCHRONIZER_HXX_