4 #include <unordered_map> 
   83     template <
typename Weightset>
 
   86       template <
typename Reduc, 
typename Vector>
 
   89                  unsigned begin, 
unsigned* permutation)
 
   91         return that->find_pivot(v, begin, permutation);
 
   94       template <
typename Reduc, 
typename Vector>
 
   97                     Vector& current, 
unsigned b, 
unsigned* permutation)
 
   99         that->reduce_vector(vbasis, current, b, permutation);
 
  102       template <
typename Reduc, 
typename Vector>
 
  105                            unsigned pivot, 
unsigned* permutation)
 
  107         that->normalisation_vector(v, pivot, permutation);
 
  110       template <
typename Reduc, 
typename Basis>
 
  114         that->bottom_up_reduction(basis, permutation);
 
  117       template <
typename Reduc, 
typename Basis, 
typename Vector>
 
  120                           Vector& current, Vector& new_vector,
 
  121                           unsigned* permutation)
 
  123         that->vector_in_new_basis(basis, current, new_vector, permutation);
 
  130       template <
typename Reduc, 
typename Vector>
 
  133                  unsigned begin, 
unsigned* permutation)
 
  135         return that->find_pivot_by_norm(v, begin, permutation);
 
  142       template <
typename Reduc, 
typename Vector>
 
  145                  unsigned begin, 
unsigned* permutation)
 
  147         return that->find_pivot_by_norm(v, begin, permutation);
 
  154       template <
typename Reduc, 
typename Vector>
 
  157                  unsigned begin, 
unsigned* permutation)
 
  159         return that->find_pivot_by_norm(v, begin, permutation);
 
  162       template <
typename Reduc, 
typename Vector>
 
  165                     Vector& current, 
unsigned b, 
unsigned* permutation)
 
  167         that->z_reduce_vector(vbasis, current, b, permutation);
 
  170       template <
typename Reduc, 
typename Vector>
 
  174       template <
typename Reduc, 
typename Basis>
 
  178       template <
typename Reduc, 
typename Basis, 
typename Vector>
 
  181                           Vector& current, Vector& new_vector,
 
  182                           unsigned* permutation)
 
  184         that->z_vector_in_new_basis(basis, current, new_vector, permutation);
 
  188     template <Automaton Aut>
 
  192                     "reduce: requires free labelset");
 
  203       using matrix_t = std::vector<std::map<std::size_t, weight_t> > ;
 
  215         std::unordered_map<state_t, unsigned> state_to_index;
 
  217         for (
auto s: 
input_->states())
 
  218           state_to_index[s] = i++;
 
  229           final[state_to_index[
input_->src_of(t)]] = 
input_->weight_of(t);
 
  237             it->second[state_to_index[
input_->src_of(t)]]
 
  238               [state_to_index[
input_->dst_of(t)]] = 
input_->weight_of(t);
 
  252               unsigned j = it.first;
 
  253               res[j] = 
ws_.add(res[j], 
ws_.mul(v[i], it.second));
 
  263           res = 
ws_.add(res, 
ws_.mul(v[i], w[i]));
 
  290         return fabs(w)+fabs(1/w);
 
  302                          unsigned* permutation)
 
  306         for (
unsigned i = begin; i < 
dimension; ++i)
 
  307           if (!
ws_.is_zero(v[permutation[i]])
 
  308               && (pivot == dimension
 
  309                   || 
ws_.less(
norm(v[permutation[i]]), min)))
 
  312               min = 
norm(v[permutation[i]]);
 
  337             res = 
gcd(-x, y, a, b);
 
  342             res = 
gcd(x, -y, a, b);
 
  346           res = 
gcd(y, x, b, a);
 
  350             res = 
gcd(y, z, b, a);
 
  354         assert(res == a * x + b * y);
 
  366                            unsigned nb, 
unsigned* permutation)
 
  368         unsigned pivot = permutation[nb]; 
 
  369         if (
ws_.is_zero(current[pivot]))
 
  377         for (
unsigned i = nb; i < 
dimension; ++i)
 
  379             weight_t tmp = current[permutation[i]];
 
  380             current[permutation[i]] = bp*tmp - cp*vbasis[permutation[i]];
 
  381             vbasis[permutation[i]] = a*vbasis[permutation[i]] + b*tmp;
 
  387                                  unsigned* permutation)
 
  389         for (
unsigned b = 0; 
b < basis.size(); ++
b)
 
  392             unsigned pivot = permutation[
b]; 
 
  393             new_vector[
b] = current[pivot] / vbasis[pivot];
 
  394             if (!
ws_.is_zero(new_vector[
b]))
 
  396                 current[pivot] = 
ws_.zero();
 
  397                 for (
unsigned i = b+1; i < 
dimension; ++i)
 
  398                   current[permutation[i]]
 
  399                     -= new_vector[b] * vbasis[permutation[i]];
 
  414                           unsigned* permutation)
 
  416         for (
unsigned i = begin; i < 
dimension; ++i)
 
  417           if (!
ws_.is_zero(v[permutation[i]]))
 
  432                              unsigned* permutation)
 
  434         unsigned pivot = permutation[
b]; 
 
  436         if (
ws_.is_zero(ratio))
 
  439         current[pivot] = 
ws_.zero();
 
  440         for (
unsigned i = b+1; i < 
dimension; ++i)
 
  441           current[permutation[i]]
 
  442             = 
ws_.sub(current[permutation[i]],
 
  443                       ws_.mul(ratio, vbasis[permutation[i]]));
 
  449                                 unsigned* permutation)
 
  454             v[permutation[pivot]] = 
ws_.one();
 
  456               v[permutation[
r]] = 
ws_.rdivide(v[permutation[
r]], k);
 
  463                                unsigned* permutation)
 
  465         for (
unsigned b = basis.size()-1; 0 < 
b; --
b)
 
  466           for (
unsigned c = 0; c < 
b; ++c)
 
  473                                unsigned* permutation)
 
  475         for (
unsigned b = 0; 
b < basis.size(); ++
b)
 
  495         std::vector<vector_t> basis;
 
  505         unsigned pivot = type_t::find_pivot(
this, 
init, 0, permutation);
 
  506         if (pivot == dimension) 
 
  509         permutation[0] = pivot;
 
  510         permutation[pivot] = 0;
 
  514         type_t::normalisation_vector(
this, first, 0, permutation);
 
  515         basis.push_back(first);
 
  520         for (
unsigned nb = 0; nb < basis.size(); ++nb)
 
  527               for (
unsigned b = 0; 
b < basis.size(); ++
b)
 
  528                 type_t::reduce_vector(
this, basis[
b],
 
  529                                       current, b, permutation);
 
  532               pivot = type_t::find_pivot(
this, current, basis.size(),
 
  534               if (pivot != dimension) 
 
  536                   if (pivot != basis.size())
 
  537                     std::swap(permutation[pivot], permutation[basis.size()]);
 
  538                   type_t::normalisation_vector(
this, current,
 
  539                                                basis.size(), permutation);
 
  540                   basis.push_back(current);
 
  546         type_t::bottom_up_reduction(
this, basis, permutation);
 
  550         std::vector<output_state_t> states(basis.size());
 
  551         for (
unsigned b = 0; 
b < basis.size(); ++
b)
 
  552           states[
b] = 
res_->new_state();
 
  554         vector_t vect_new_basis(basis.size());
 
  555         type_t::vector_in_new_basis(
this, basis, 
init,
 
  556                                     vect_new_basis, permutation);
 
  557         for (
unsigned b = 0; 
b < basis.size(); ++
b)
 
  558           res_->set_initial(states[
b], vect_new_basis[b]);
 
  561         for (
unsigned v = 0; 
v < basis.size(); ++
v)
 
  565               res_->set_final(states[v],k);
 
  566             for (
auto mu : letter_matrix_set)
 
  571                 type_t::vector_in_new_basis(
this, basis, current,
 
  572                                             vect_new_basis, permutation);
 
  573                 for (
unsigned b = 0; b < basis.size(); ++
b)
 
  574                   res_->new_transition(states[v], states[b],
 
  575                                        mu.first, vect_new_basis[b]);
 
  596   template <Automaton Aut>
 
  599     -> decltype(
copy(input))
 
  606   template <Automaton Aut>
 
  609     -> decltype(
copy(input))
 
  619       template <Automaton Aut>
 
  623         const auto& a = aut->
as<Aut>();
 
void z_vector_in_new_basis(std::vector< vector_t > &basis, vector_t ¤t, vector_t &new_vector, unsigned *permutation)
auto transitions(const Aut &aut) -> decltype(all_transitions(aut, is_special_t< Aut >
All the transition indexes between visible states. 
typename context_t::weightset_t weightset_t
static void vector_in_new_basis(Reduc *that, Basis &basis, Vector ¤t, Vector &new_vector, unsigned *permutation)
static void reduce_vector(Reduc *that, Vector &vbasis, Vector ¤t, unsigned b, unsigned *permutation)
void vector_in_new_basis(std::vector< vector_t > &basis, vector_t ¤t, vector_t &new_vector, unsigned *permutation)
Compute the coordinate of a vector in the new basis. 
unsigned find_pivot(const vector_t &v, unsigned begin, unsigned *permutation)
Return the first (w.r.t the column permutation) non zero element as pivot. 
weight_t scalar_product(const vector_t &v, const vector_t &w)
Computes the scalar product of two vectors. 
unsigned find_pivot_by_norm(const vector_t &v, unsigned begin, unsigned *permutation)
static weight_t norm(const z_weight_t &w)
Norm for integers. 
std::vector< weight_t > vector_t
auto final_transitions(const Aut &aut) -> decltype(aut->all_in(aut->post()))            
Indexes of transitions from (visible) final states. 
weightset_mixin< detail::r_impl > r
type_t
The possible types of expressions. 
Provide a variadic mul on top of a binary mul(), and one(). 
weightset_mixin< detail::b_impl > b
output_automaton_t operator()()
Core algorithm This algorithm computes a basis of I.mu(w). 
typename detail::label_t_of_impl< base_t< ValueSet >>::type label_t_of
typename Aut::element_type::template fresh_automaton_t< Context > fresh_automaton_t_of
Given an automaton type, the type of its copies. 
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
label_t_of< automaton_t > label_t
auto initial_transitions(const Aut &aut) -> decltype(aut->all_out(aut->pre()))            
Indexes of transitions to (visible) initial states. 
std::vector< std::map< std::size_t, weight_t > > matrix_t
std::map< label_t, matrix_t > matrix_set_t
left_reductioner(const automaton_t &input)
static void vector_in_new_basis(Reduc *that, Basis &basis, Vector ¤t, Vector &new_vector, unsigned *permutation)
static void normalisation_vector(Reduc *, Vector &, unsigned, unsigned *)
static weight_t norm(const r_weight_t &w)
Norm for real numbers; a "stable" pivot should minimize this norm. 
static void reduce_vector(Reduc *that, Vector &vbasis, Vector ¤t, unsigned b, unsigned *permutation)
fresh_automaton_t_of< automaton_t > output_automaton_t
void z_reduce_vector(vector_t &vbasis, vector_t ¤t, unsigned nb, unsigned *permutation)
AutOut make_fresh_automaton(const AutIn &model)
Create an empty, mutable, automaton, based on another one. 
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
vcsn::detail::r_impl::value_t r_weight_t
void product_vector_matrix(const vector_t &v, const matrix_t &m, vector_t &res)
Computes the product of a row vector with a matrix. 
const weightset_t_of< automaton_t > ws_
static unsigned find_pivot(Reduc *that, const Vector &v, unsigned begin, unsigned *permutation)
static weight_t norm(const q_weight_t &w)
static void normalisation_vector(Reduc *that, Vector &v, unsigned pivot, unsigned *permutation)
auto left_reduce(const Aut &input) -> decltype(copy(input))
vcsn::detail::z_impl::value_t z_weight_t
Specializations for Q and R. 
auto reduce(const Aut &input) -> decltype(copy(input))
state_t_of< automaton_t > state_t
void linear_representation()
Create the linear representation of the input. 
weight_t reduce_vector(vector_t &vbasis, vector_t ¤t, unsigned b, unsigned *permutation)
Reduce a vector w.r.t. 
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
state_t_of< output_automaton_t > output_state_t
auto copy(const AutIn &input, KeepState keep_state, KeepTrans keep_trans) -> decltype(keep_state(input->null_state()),                                                           keep_trans(input->null_transition()),                                                           make_fresh_automaton< AutIn, AutOut >(input))
A copy of input keeping only its states that are accepted by keep_state, and transitions accepted by ...
automaton reduce(const automaton &aut)
Bridge. 
void normalisation_vector(vector_t &v, unsigned pivot, unsigned *permutation)
Normalize the basis vector such that its pivot is equal to 1. 
auto & as()
Extract wrapped typed automaton. 
matrix_set_t letter_matrix_set
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
void bottom_up_reduction(std::vector< vector_t > &basis, unsigned *permutation)
Apply reduction to vectors of the basis to maximize the number of zeros. 
static unsigned find_pivot(Reduc *that, const Vector &v, unsigned begin, unsigned *permutation)
typename context_t::weight_t weight_t
static z_weight_t gcd(z_weight_t x, z_weight_t y, z_weight_t &a, z_weight_t &b)
context_t_of< automaton_t > context_t
Aut transpose(const transpose_automaton< Aut > &aut)
The transpose of a transpose automaton is the original automaton. 
static void bottom_up_reduction(Reduc *, Basis &, unsigned *)
static void bottom_up_reduction(Reduc *that, Basis &basis, unsigned *permutation)
static unsigned find_pivot(Reduc *that, const Vector &v, unsigned begin, unsigned *permutation)
static unsigned find_pivot(Reduc *that, const Vector &v, unsigned begin, unsigned *permutation)