00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef VCSN_ALGORITHMS_EVAL_HXX
00018 # define VCSN_ALGORITHMS_EVAL_HXX
00019
00020 # include <vaucanson/algorithms/eval.hh>
00021 # include <vaucanson/automata/concept/automata_base.hh>
00022 # include <vaucanson/misc/selectors.hh>
00023 # include <vaucanson/misc/usual_macros.hh>
00024 # include <algorithm>
00025 # include <vector>
00026
00027 namespace vcsn {
00028
00029
00030
00031
00032
00033 template <typename auto_t, typename input_t, typename Selt>
00034 struct eval_functor
00035 {
00036 AUTOMATON_TYPES(auto_t);
00037
00038 typedef std::vector<semiring_elt_t> weights;
00039
00040 const auto_t& a;
00041 int max_hstate;
00042
00043 weights v1, v2;
00044
00045 typename weights::const_iterator w;
00046 typename input_t::const_iterator l;
00047
00048 template <typename A>
00049 eval_functor(const AutomataBase<A>&, const auto_t& aut)
00050 : a(aut), max_hstate(a.states().back() + 1),
00051 v1(max_hstate, a.series().semiring().wzero_), v2(max_hstate)
00052 {}
00053
00054 void operator() (htransition_t t)
00055 {
00056 v2[a.dst_of(t)] += *w *
00057 a.series_of(t).get(monoid_elt_t(a.structure().series().monoid(), *l));
00058 }
00059
00060 void execute(const input_t& word, Selt& result)
00061 {
00062 const monoid_elt_t empty = algebra::identity_as<monoid_elt_value_t>::of(a.series().monoid());
00063
00064
00065 for_all_const_initial_states(i, a)
00066 v1[*i] = a.get_initial(*i).get(empty);
00067
00068 const semiring_elt_t zero = a.series().semiring().wzero_;
00069
00070
00071 l = word.begin();
00072 for (typename input_t::const_iterator w_end = word.end();
00073 l != w_end; ++l)
00074 {
00075 std::fill(v2.begin(), v2.end(), zero);
00076 int i = 0;
00077 w = v1.begin();
00078 for (typename weights::const_iterator v1_end = v1.end();
00079 w != v1_end; ++w)
00080 {
00081 if (*w != zero)
00082 a.letter_deltaf(*this, i, *l, delta_kind::transitions());
00083 ++i;
00084 }
00085 std::swap(v1, v2);
00086 }
00087
00088
00089 result = zero;
00090 int i = 0;
00091 for_all_const_ (weights, w, v1)
00092 {
00093 if (*w != zero)
00094 result += *w * a.get_final(i).get(empty);
00095 ++i;
00096 }
00097 }
00098 };
00099
00100
00101
00102
00103 template<typename A, typename T, typename W>
00104 typename Element<A, T>::semiring_elt_t
00105 eval(const Element<A, T>& a, const W& word)
00106 {
00107 TIMER_SCOPED("eval");
00108 typedef Element<A, T> auto_t;
00109 AUTOMATON_TYPES(auto_t);
00110 semiring_elt_t ret(a.structure().series().semiring());
00111 eval_functor<auto_t, W, semiring_elt_t> evalf(a.structure(), a);
00112
00113 evalf.execute(word, ret);
00114 return ret;
00115 }
00116
00117 }
00118
00119 #endif // ! VCSN_ALGORITHMS_EVAL_HXX