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