00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef FILTER_SYNCHRONIZER_HXX_
00023 # define 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/filter/intersector.hh>
00030 # include <wipal/filter/reference_blacklist.hh>
00031
00032 namespace wpl
00033 {
00034
00035 namespace filter
00036 {
00037
00038 template <class OriginalFrameType, class ImplType>
00039 synchronized_frame<OriginalFrameType, ImplType>::
00040 synchronized_frame(const OriginalFrameType& orig,
00041 const coefs_type& coefs):
00042 OriginalFrameType (orig),
00043 coefs (coefs)
00044 {
00045 }
00046
00047 namespace internals
00048 {
00049
00050 template <class I, class B1, class B2>
00051 lr_sync_iterator<I, B1, B2>::
00052 lr_sync_iterator(const iterable_type& iterable, bool end):
00053 iterable_ (&iterable),
00054 win_ (end ? iterable.last_ : iterable.first_),
00055 wpos_ (0)
00056 {
00057 if (not end and win_ != iterable_->last_)
00058 while (not update_value() and advance())
00059 ;
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 const impl_type precision = iterable_->precision_;
00122
00123 if (error < -precision or precision < 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,
00166 const I& last,
00167 const unsigned precision):
00168 first_ (first),
00169 last_ (last),
00170 precision_ (precision)
00171 {
00172 }
00173
00174 namespace internals
00175 {
00176
00177 template <class F>
00178 struct lrsync_wrapper
00179 {
00180 enum
00181 {
00182 window_size =
00183
00184 #ifdef WP_LRSYNC_WINDOW_SIZE
00185 WP_LRSYNC_WINDOW_SIZE
00186 #else // ! WP_LRSYNC_WINDOW_SIZE
00187 4
00188 #endif
00189
00190 };
00191
00192 typedef std::set< std::pair<unsigned, unsigned> > ref_blacklist;
00193
00194 lrsync_wrapper(F& func,
00195 const ref_blacklist& blist,
00196 const unsigned& prec):
00197 func_ (func),
00198 blist_ (blist),
00199 prec_ (prec)
00200 {
00201 }
00202
00203 template <class Intersector>
00204 void
00205 operator () (const Intersector& i)
00206 {
00207 typedef typename Intersector::const_iterator i_iterator;
00208 typedef reference_blacklist<i_iterator> blist;
00209 typedef typename blist::const_iterator b_iterator;
00210 typedef tool::window_maker<b_iterator, window_size> window_maker;
00211 typedef typename window_maker::const_iterator w_iterator;
00212 typedef linear_regression_synchronizer<w_iterator> synchronizer;
00213
00214 blist l (i.begin(), i.end(), blist_);
00215 window_maker w (l.begin(), l.end());
00216 synchronizer s (w.begin(), w.end(), prec_);
00217
00218 func_(s);
00219 }
00220
00221 private:
00222 F& func_;
00223 const ref_blacklist& blist_;
00224 const unsigned& prec_;
00225 };
00226
00227 }
00228
00229 template <class U, class HT, template <class, class, class> class Int,
00230 class I1, class I2, class F>
00231 void
00232 provide_lr_synchronizer(const I1& first1, const I1& last1,
00233 const I2& first2, const I2& last2,
00234 opt::list& options,
00235 F& func)
00236 {
00237 typedef internals::lrsync_wrapper<F> wrapper;
00238 typedef typename wrapper::ref_blacklist blacklist;
00239
00240 const blacklist& blist = (options["ref_blacklist"].get<blacklist>());
00241 const unsigned& prec = options["precision"].get<unsigned>();
00242 wrapper wrap (func, blist, prec);
00243
00244 provide_intersector<U, HT, Int>(first1, last1,
00245 first2, last2, options, wrap);
00246 }
00247
00248 }
00249
00250 }
00251
00252 #endif // ! FILTER_SYNCHRONIZER_HXX_