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 update_value();
00060 }
00061
00062 template <class I, class B1, class B2>
00063 bool
00064 lr_sync_iterator<I, B1, B2>::equal(const exact_type& rhs) const
00065 {
00066 if (not rhs.value())
00067 return not this->value();
00068 return wpos_ == rhs.wpos_ and win_ == rhs.win_;
00069 }
00070
00071 template <class I, class B1, class B2>
00072 bool
00073 lr_sync_iterator<I, B1, B2>::advance()
00074 {
00075 assert(win_ != iterable_->last_);
00076
00077 const size_t win_size = win_->size();
00078
00079 if (wpos_ < win_size / 2)
00080 ++wpos_;
00081 else if (not win_.last())
00082 ++win_;
00083 else if (++wpos_ >= win_size)
00084 {
00085
00086 this->value() = boost::none_t ();
00087
00088
00089 ++win_;
00090 wpos_ = 0;
00091
00092 assert(win_ == iterable_->last_);
00093 return false;
00094 }
00095 assert(win_ != iterable_->last_);
00096 return true;
00097 }
00098
00099 template <class I, class B1, class B2>
00100 bool
00101 lr_sync_iterator<I, B1, B2>::update_value()
00102 {
00103 typedef typename I::value_type::value_type ref_type;
00104
00105 assert(win_ != iterable_->last_);
00106
00107 try
00108 {
00109 typedef typename value_type::impl_type impl_type;
00110 typedef typename
00111 tool::lr::pair_with_microseconds<impl_type> adapter_type;
00112
00113 const std::pair<impl_type, impl_type> p =
00114 tool::linear_regression<impl_type, adapter_type>(win_->begin(),
00115 win_->end());
00116
00117 const ref_type& ref = win_[wpos_];
00118 const impl_type t1 = ref.first.microseconds();
00119 const impl_type t2 = ref.second.microseconds();
00120 const impl_type error = t2 - t1 * p.first - p.second;
00121
00122 if (error < -acceptable_error_threshold or
00123 acceptable_error_threshold < error)
00124 {
00125 std::cerr << ref.first << '-' << ref.second
00126 << ": Ignoring this ref. because of a "
00127 << "high sync. error (" << error << ")."
00128 << std::endl;
00129 return false;
00130 }
00131 if (p.first < 0.9 or 1.1 < p.first)
00132 std::cerr << ref.first << '-' << ref.second
00133 << ": Dubious sync. coef. of " << p.first
00134 << '.' << std::endl;
00135
00136 this->value() = value_type (ref, p);
00137 return true;
00138 }
00139 catch (const std::invalid_argument& i)
00140 {
00141 assert(not win_->empty());
00142
00143 const ref_type& b = win_->front();
00144 const ref_type& e = win_->back();
00145
00146 std::cerr << b.first << '-' << b.second << ": " << i.what()
00147 << ".\n" << e.first << '-' << e.second
00148 << ": Sync. window's last reference." << std::endl;
00149 return false;
00150 }
00151 }
00152
00153 template <class I, class B1, class B2>
00154 void
00155 lr_sync_iterator<I, B1, B2>::increment()
00156 {
00157 while (advance() and not update_value())
00158 ;
00159 }
00160
00161 }
00162
00163 template <class I, class B>
00164 linear_regression_synchronizer<I, B>::
00165 linear_regression_synchronizer(const I& first, const I& last):
00166 first_ (first),
00167 last_ (last)
00168 {
00169 }
00170
00171 namespace internals
00172 {
00173
00174 template <class F>
00175 struct provide_lr_synchronizer
00176 {
00177 enum
00178 {
00179 window_size =
00180
00181 #ifdef WP_LRSYNC_WINDOW_SIZE
00182 WP_LRSYNC_WINDOW_SIZE
00183 #else // ! WP_LRSYNC_WINDOW_SIZE
00184 3
00185 #endif
00186
00187 };
00188
00189 typedef std::set< std::pair<unsigned, unsigned> > ref_blacklist;
00190
00191 provide_lr_synchronizer(F& func, const ref_blacklist& blist):
00192 func_ (func),
00193 blist_ (blist)
00194 {
00195 }
00196
00197 template <class Intersector>
00198 void
00199 operator () (const Intersector& i)
00200 {
00201 typedef typename Intersector::const_iterator i_iterator;
00202 typedef reference_blacklist<i_iterator> blist;
00203 typedef typename blist::const_iterator b_iterator;
00204 typedef tool::window_maker<b_iterator, window_size> window_maker;
00205 typedef typename window_maker::const_iterator w_iterator;
00206 typedef linear_regression_synchronizer<w_iterator> synchronizer;
00207
00208 blist l (i.begin(), i.end(), blist_);
00209 window_maker w (l.begin(), l.end());
00210 synchronizer s (w.begin(), w.end());
00211
00212 func_(s);
00213 }
00214
00215 private:
00216 F& func_;
00217 const ref_blacklist& blist_;
00218 };
00219
00220 }
00221
00222 template <class U, class HT, template <class, class, class> class Int,
00223 class I1, class I2, class F>
00224 void
00225 provide_lr_synchronizer(const I1& first1, const I1& last1,
00226 const I2& first2, const I2& last2,
00227 tool::opt::list& options,
00228 F& func)
00229 {
00230 typedef internals::provide_lr_synchronizer<F> provider_ftor;
00231 typedef typename provider_ftor::ref_blacklist ref_blacklist;
00232
00233 const ref_blacklist& blist = (options["ref_blacklist"]
00234 .get<ref_blacklist>());
00235 provider_ftor func2 (func, blist);
00236
00237 provide_intersector<U, HT, Int>(first1, last1, first2, last2,
00238 options, func2);
00239 }
00240
00241
00242 }
00243
00244 }
00245
00246 }
00247
00248 #endif // ! WIFI_FRAME_FILTER_SYNCHRONIZER_HXX_