Vcsn  2.0
Be Rational
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
reduce.hh
Go to the documentation of this file.
1 #ifndef VCSN_ALGOS_REDUCE_HH
2 # define VCSN_ALGOS_REDUCE_HH
3 
4 # include <map>
5 # include <unordered_map>
6 # include <vector>
7 
8 # include <vcsn/algos/copy.hh>
9 # include <vcsn/algos/transpose.hh>
11 # include <vcsn/dyn/automaton.hh>
12 # include <vcsn/weightset/q.hh>
13 # include <vcsn/weightset/r.hh>
14 # include <vcsn/weightset/z.hh>
15 
16 namespace vcsn
17 {
18  namespace detail
19  {
20  /*
21  The core algorithm computes a scaled basis from a list of
22  vectors. There is a permutation on entries in such a way that
23  the first non-zero entry of the i-th vector of the basis has
24  index i. (in the field case, this entry is equal to 1)
25 
26  If v is a new vector, for every vector b_i of the bases:
27 
28  - either v[i] is zero and there is nothing to do
29 
30  - or v[i] is different from 0 in this case, v is modified as v:=
31  v - v[i].b which makes v[i]=0 (in the Z case, b may also be
32  modified) This is performed by the reduce_vector method
33 
34  After the iteration, if v is null, it means that the vector was in the
35  vector space (or the Z-module) generated by the basis.
36  Otherwise, a non zero entry of v is selected (find_pivot),
37  v is normalized (normalization_vector) and the permutation is
38  updated in such a way that the pivot becomes the first non zero
39  entry of v, which is inserted in the basis.
40 
41  Once the basis is stabilized, a bottom-up reduction is applied
42  to the scaled basis in order to make it more "diagonal".
43  Finally, the new automaton is built w.r.t. the computed basis.
44  The construction of the automaton can not be done on-the-fly due
45  to both the Z case where the basis is modified and the bottom-up
46  reduction.
47  */
48 
49 
50  /*
51 
52  The implementation of elementary methods slightly differ
53  w.r.t. the weightset.
54 
55  Generically,
56 
57  find_pivot returns the first non zero entry
58 
59  reduce_vector computes current := current - current[i].b_i
60 
61  normalisation_vector applied a ratio in such a way that
62  the pivot is 1
63 
64  bottom_up_reduction applies, for each vector of the
65  basis, reduce_vector to every preceding vector in the
66  basis.
67 
68 
69  In Q : find_pivot searchs for the entry where
70  |numerator|+|denominator| is minimal
71 
72  In R : find_pivot searchs for the entry x where |x|+1/|x|
73  is minimal
74 
75  In Z : find_pivot searchs for the (non zero) entry x where
76  |x| is minimal
77  reduce_vector both reduce the current and the basis vector
78  (w.r.t. the gcd of current[i] and b_i[i])
79  normalisation_vector does not apply
80  bottom_up_reduction does not apply
81 
82  */
83 
84  template<typename Weightset>
85  struct select
86  {
87  template<typename Reduc, typename Vector>
88  static unsigned
89  find_pivot(Reduc* that, const Vector& v,
90  unsigned begin, unsigned* permutation)
91  {
92  return that->find_pivot(v, begin, permutation);
93  }
94 
95  template<typename Reduc, typename Vector>
96  static void
97  reduce_vector(Reduc* that, Vector& vbasis,
98  Vector& current, unsigned b, unsigned* permutation)
99  {
100  that->reduce_vector(vbasis, current, b, permutation);
101  }
102 
103  template<typename Reduc, typename Vector>
104  static void
105  normalisation_vector(Reduc* that, Vector& v,
106  unsigned pivot, unsigned* permutation)
107  {
108  that->normalisation_vector(v, pivot, permutation);
109  }
110 
111  template<typename Reduc, typename Basis>
112  static void
113  bottom_up_reduction(Reduc* that, Basis& basis, unsigned* permutation)
114  {
115  that->bottom_up_reduction(basis, permutation);
116  }
117 
118  template<typename Reduc, typename Basis, typename Vector>
119  static void
120  vector_in_new_basis(Reduc* that, Basis& basis,
121  Vector& current, Vector& new_vector,
122  unsigned* permutation)
123  {
124  that->vector_in_new_basis(basis, current, new_vector, permutation);
125  }
126  };
127 
128  template <>
129  struct select<q> : select<void>
130  {
131  template<typename Reduc, typename Vector>
132  static unsigned
133  find_pivot(Reduc* that, const Vector& v,
134  unsigned begin, unsigned* permutation)
135  {
136  return that->find_pivot_by_norm(v, begin, permutation);
137  }
138  };
139 
140  template <>
141  struct select<r> : select<void>
142  {
143  template<typename Reduc, typename Vector>
144  static unsigned
145  find_pivot(Reduc* that, const Vector& v,
146  unsigned begin, unsigned* permutation)
147  {
148  return that->find_pivot_by_norm(v, begin, permutation);
149  }
150  };
151 
152  template <>
153  struct select<z> : select<void>
154  {
155  template<typename Reduc, typename Vector>
156  static unsigned
157  find_pivot(Reduc* that, const Vector& v,
158  unsigned begin, unsigned* permutation)
159  {
160  return that->find_pivot_by_norm(v, begin, permutation);
161  }
162 
163  template <typename Reduc, typename Vector>
164  static void
165  reduce_vector(Reduc* that, Vector& vbasis,
166  Vector& current, unsigned b, unsigned* permutation)
167  {
168  that->z_reduce_vector(vbasis, current, b, permutation);
169  }
170 
171  template <typename Reduc, typename Vector>
172  static void normalisation_vector(Reduc*, Vector&, unsigned, unsigned*)
173  {}
174 
175  template<typename Reduc, typename Basis>
176  static void bottom_up_reduction(Reduc*, Basis&, unsigned*)
177  {}
178 
179  template<typename Reduc, typename Basis, typename Vector>
180  static void
181  vector_in_new_basis(Reduc* that, Basis& basis,
182  Vector& current, Vector& new_vector,
183  unsigned* permutation)
184  {
185  that->z_vector_in_new_basis(basis, current, new_vector, permutation);
186  }
187  };
188 
189  template <typename Aut>
191  {
192  static_assert(labelset_t_of<Aut>::is_free(),
193  "reduce: requires free labelset");
194 
195  using automaton_t = Aut;
197  using weightset_t = typename context_t::weightset_t;
198  using output_automaton_t
199  = typename automaton_t::element_type::automaton_nocv_t;
203  using weight_t = typename context_t::weight_t;
204  using vector_t = std::vector<weight_t>;
205  using matrix_t = std::vector<std::map<std::size_t, weight_t> > ;
206  using matrix_set_t = std::map<label_t, matrix_t>;
207 
208  public:
210  : input_(input)
212  {}
213 
216  {
217  std::unordered_map<state_t, unsigned> state_to_index;
218  unsigned i = 0;
219  for (auto s: input_->states())
220  state_to_index[s] = i++;
221  dimension = i;
222  if (dimension == 0)
223  return;
224  init.resize(i);
225  final.resize(i);
226  // Computation of the initial vector.
227  for (auto t : input_->initial_transitions())
228  init[state_to_index[input_->dst_of(t)]] = input_->weight_of(t);
229  // Computation of the final vector.
230  for (auto t : input_->final_transitions())
231  final[state_to_index[input_->src_of(t)]] = input_->weight_of(t);
232  // For each letter, we define an adjency matrix.
233  for (auto t : input_->transitions())
234  {
235  auto it = letter_matrix_set.find(input_->label_of(t));
236  if (it == letter_matrix_set.end())
237  it = letter_matrix_set.emplace(input_->label_of(t),
238  matrix_t(dimension)).first;
239  it->second[state_to_index[input_->src_of(t)]]
240  [state_to_index[input_->dst_of(t)]] = input_->weight_of(t);
241  }
242  }
243 
244  //utility methods
245 
248  const matrix_t& m,
249  vector_t& res)
250  {
251  for (unsigned i = 0; i < dimension; i++)
252  for (auto it : m[i])
253  {
254  unsigned j = it.first;
255  res[j] = ws_.add(res[j], ws_.mul(v[i], it.second));
256  }
257  }
258 
261  const vector_t& w)
262  {
263  weight_t res = ws_.zero();
264  for (unsigned i = 0; i < dimension; ++i)
265  res = ws_.add(res, ws_.mul(v[i], w[i]));
266  return res;
267  }
268 
273 
274  /*
275  The pivot is the entry x of the vector such that norm(x) is minimal.
276  This "norm" highly depends on the semiring.
277 
278  For rational numbers, it is the sum of the numerator and the
279  denominator (absolute value)
280 
281  For "real" numbers, it is |x|+|1/x| .
282  */
283 
284  static weight_t norm(const q_weight_t& w)
285  {
286  return w.den+abs(w.num);
287  }
288 
290  static weight_t norm(const r_weight_t& w)
291  {
292  return fabs(w)+fabs(1/w);
293  }
294 
296  static weight_t norm(const z_weight_t& w)
297  {
298  return abs(w);
299  }
300 
301  // Works for both Q and R.
302  unsigned
303  find_pivot_by_norm(const vector_t& v, unsigned begin,
304  unsigned* permutation)
305  {
306  weight_t min;
307  unsigned pivot = dimension;
308  for (unsigned i = begin; i < dimension; ++i)
309  if (!ws_.is_zero(v[permutation[i]])
310  && (pivot == dimension
311  || ws_.less_than(norm(v[permutation[i]]), min)))
312  {
313  pivot = i;
314  min = norm(v[permutation[i]]);
315  }
316  return pivot;
317  }
318 
319  // End of Q/R specializations.
320 
321 
322  // Specialization for Z.
323 
324  // Gcd function that also computes the Bezout coefficients.
325  // Used in the z reduction.
326  static z_weight_t
328  {
329  z_weight_t res = 0;
330  //gcd = ax + by
331  if (y == 0)
332  {
333  a = 1;
334  b = 0;
335  res = x;
336  }
337  else if (x < 0)
338  {
339  res = gcd(-x, y, a, b);
340  a = -a;
341  }
342  else if (y < 0)
343  {
344  res = gcd(x, -y, a, b);
345  b = -b;
346  }
347  else if (x < y)
348  res = gcd(y, x, b, a);
349  else
350  {
351  z_weight_t z = x % y; // z= x- (x/y)*y;
352  res = gcd(y, z, b, a);
353  //res=by+az = (b-a(x/y)) y + ax
354  b -= a * (x / y);
355  }
356  assert(res == a * x + b * y);
357  return res;
358  }
359 
360  /*
361  gcd = a.vbasis[pivot] + b.current[pivot]
362  current[pivot] is made zero with a unimodular linear transformation
363  This also modifies the basis vector
364  [ vbasis ] := [ a b ] . [ vbasis ]
365  [ current ] [-current[pivot]/gcd vbasis[pivot]/gcd] [ current ]
366  */
367  void z_reduce_vector(vector_t& vbasis, vector_t& current,
368  unsigned nb, unsigned* permutation)
369  {
370  unsigned pivot = permutation[nb]; //pivot of vector vbasis
371  if (ws_.is_zero(current[pivot]))
372  return;
373  weight_t bp = vbasis[pivot];
374  weight_t cp = current[pivot];
375  weight_t a,b;
376  weight_t g = gcd(bp, cp, a, b);
377  bp /= g;
378  cp /= g;
379  for (unsigned i = nb; i < dimension; ++i)
380  {
381  weight_t tmp = current[permutation[i]];
382  current[permutation[i]] = bp*tmp - cp*vbasis[permutation[i]];
383  vbasis[permutation[i]] = a*vbasis[permutation[i]] + b*tmp;
384  }
385  }
386 
387  void z_vector_in_new_basis(std::vector<vector_t>& basis,
388  vector_t& current, vector_t& new_vector,
389  unsigned* permutation)
390  {
391  for (unsigned b = 0; b < basis.size(); ++b)
392  {
393  vector_t& vbasis = basis[b];
394  unsigned pivot = permutation[b]; //pivot of vector vbasis
395  new_vector[b] = current[pivot] / vbasis[pivot];
396  if (!ws_.is_zero(new_vector[b]))
397  {
398  current[pivot] = ws_.zero();
399  for (unsigned i = b+1; i < dimension; ++i)
400  current[permutation[i]]
401  -= new_vector[b] * vbasis[permutation[i]];
402  }
403  }
404  }
405  // End of Z specializations.
406 
407  /* Generic subroutines.
408  These methods are written for any (skew) field.
409  Some are specialized for Q and R for stability issues.
410  Some are specialized for Z which is an Euclidean domain.
411  */
412 
415  unsigned find_pivot(const vector_t& v, unsigned begin,
416  unsigned* permutation)
417  {
418  for (unsigned i = begin; i < dimension; ++i)
419  if (!ws_.is_zero(v[permutation[i]]))
420  return i;
421  return dimension;
422  }
423 
433  vector_t& current, unsigned b,
434  unsigned* permutation)
435  {
436  unsigned pivot = permutation[b]; //pivot of vector vbasis
437  weight_t ratio = current[pivot];// vbasis[pivot] is one
438  if (ws_.is_zero(ratio))
439  return ratio;
440  // This is safer than current[p] = current[p]-ratio*vbasis[p];
441  current[pivot] = ws_.zero();
442  for (unsigned i = b+1; i < dimension; ++i)
443  current[permutation[i]]
444  = ws_.sub(current[permutation[i]],
445  ws_.mul(ratio, vbasis[permutation[i]]));
446  return ratio;
447  }
448 
450  void normalisation_vector(vector_t& v, unsigned pivot,
451  unsigned* permutation)
452  {
453  weight_t k = v[permutation[pivot]];
454  if (!ws_.is_one(k))
455  {
456  v[permutation[pivot]] = ws_.one();
457  for (unsigned r = pivot + 1; r < dimension; ++r)
458  v[permutation[r]] = ws_.rdiv(v[permutation[r]], k);
459  }
460  }
461 
464  void bottom_up_reduction(std::vector<vector_t>& basis,
465  unsigned* permutation)
466  {
467  for (unsigned b = basis.size()-1; 0 < b; --b)
468  for (unsigned c = 0; c < b; ++c)
469  reduce_vector(basis[b], basis[c], b, permutation);
470  }
471 
473  void vector_in_new_basis(std::vector<vector_t>& basis,
474  vector_t& current, vector_t& new_vector,
475  unsigned* permutation)
476  {
477  for (unsigned b = 0; b < basis.size(); ++b)
478  new_vector[b] = reduce_vector(basis[b], current, b, permutation);
479  }
480 
488  public:
490  {
491  // Used to select the proper overload depending on weightset_t.
492  using type_t = select<weightset_t>;
493 
495  // The basis is a list of vectors, each vector is associated with
496  // a state of the output
497  std::vector<vector_t> basis;
498  // The permutation array corresponds to a permutation of the indices
499  // (i.e. the columns of the matrices) such that permtuation[k]
500  // is the pivot of the k-th vector of the basis.
501  unsigned permutation[dimension];
502  for (unsigned i = 0; i < dimension; ++i)
503  permutation[i] = i;
504  // If the initial vector is null, the function immediatly returns
505 
506  // A non zero entry is chosen as pivot
507  unsigned pivot = type_t::find_pivot(this, init, 0, permutation);
508  if (pivot == dimension) //all components of init are 0
509  return res_;
510  // The pivot of the first basis vector is permutation[0];
511  permutation[0] = pivot;
512  permutation[pivot] = 0;
513  // The initial vector is the first element of the new basis
514  // (up to the normalisation w.r.t the pivot)
515  vector_t first(init);
516  type_t::normalisation_vector(this, first, 0, permutation);
517  basis.push_back(first);
518  // To each vector of the basis, all the successor vectors are
519  // computed, reduced to respect to the basis, and finally, if
520  // linearly independant, pushed at the end of the basis
521  // itself.
522  for (unsigned nb = 0; nb < basis.size(); ++nb)
523  // All the vectors basis[nb].mu(a) are processed
524  for (auto mu : letter_matrix_set) //mu is a pair (letter,matrix)
525  {
526  vector_t current(dimension);
527  product_vector_matrix(basis[nb], mu.second, current);
528  //reduction of current w.r.t each basis vector;
529  for (unsigned b = 0; b < basis.size(); ++b)
530  type_t::reduce_vector(this, basis[b],
531  current, b, permutation);
532  // After reduction, we put current in the basis if it is
533  // not null and we search for the pivot of current.
534  pivot = type_t::find_pivot(this, current, basis.size(),
535  permutation);
536  if (pivot != dimension) //otherwise, current is null
537  {
538  if (pivot != basis.size())
539  std::swap(permutation[pivot], permutation[basis.size()]);
540  type_t::normalisation_vector(this, current,
541  basis.size(), permutation);
542  basis.push_back(current);
543  }
544  }
545 
546  // now, we use each vector to reduce the preceding vectors in
547  // the basis. If weightset=Z we do not do it.
548  type_t::bottom_up_reduction(this, basis, permutation);
549 
550  // Construction of the output automaton
551  // 1. States
552  std::vector<output_state_t> states(basis.size());
553  for (unsigned b = 0; b < basis.size(); ++b)
554  states[b] = res_->new_state();
555  // 2. Initial vector
556  vector_t vect_new_basis(basis.size());
557  type_t::vector_in_new_basis(this, basis, init,
558  vect_new_basis, permutation);
559  for (unsigned b = 0; b < basis.size(); ++b)
560  res_->set_initial(states[b], vect_new_basis[b]);
561  // 3. Each vector of the basis is a state; computation of the
562  // final function and the successor function
563  for (unsigned v = 0; v < basis.size(); ++v)
564  {
565  weight_t k = scalar_product(basis[v],final);
566  if(!ws_.is_zero(k))
567  res_->set_final(states[v],k);
568  for (auto mu : letter_matrix_set)
569  {
570  // mu is a pair (letter,matrix).
571  vector_t current(dimension);
572  product_vector_matrix(basis[v], mu.second, current);
573  type_t::vector_in_new_basis(this, basis, current,
574  vect_new_basis, permutation);
575  for (unsigned b = 0; b < basis.size(); ++b)
576  res_->new_transition(states[v], states[b],
577  mu.first, vect_new_basis[b]);
578  }
579  }
580  return res_;
581  }
582 
583  private:
585  const weightset_t_of<automaton_t> ws_ = *input_->weightset();
586 
588 
589  // Linear representation of the input.
590  unsigned dimension;
592  vector_t final;
594  };
595 
596  }
597 
598  template<typename Aut>
599  auto
600  left_reduce(const Aut& input)
601  -> decltype(copy(input))
602  {
604  return left_reduce();
605  }
606 
607 
608  template<typename Aut>
609  auto
610  reduce(const Aut& input)
611  -> decltype(copy(input))
612  {
613  return left_reduce(transpose(left_reduce(transpose(input))));
614  }
615 
616  namespace dyn
617  {
618  namespace detail
619  {
621  template <typename Aut>
622  automaton
623  reduce(const automaton& aut)
624  {
625  const auto& a = aut->as<Aut>();
626  return make_automaton(reduce(a));
627  }
628 
630  (const automaton& aut) -> automaton);
631  }
632  }
633 
634 }
635 
636 #endif
matrix_set_t letter_matrix_set
Definition: reduce.hh:593
static void bottom_up_reduction(Reduc *, Basis &, unsigned *)
Definition: reduce.hh:176
vcsn::detail::r_impl::value_t r_weight_t
Definition: reduce.hh:272
static weight_t norm(const r_weight_t &w)
Norm for real numbers; a "stable" pivot should minimize this norm.
Definition: reduce.hh:290
REGISTER_DECLARE(accessible,(const automaton &) -> automaton)
std::shared_ptr< detail::automaton_base > automaton
Definition: automaton.hh:71
typename context_t::weightset_t weightset_t
Definition: reduce.hh:197
static weight_t norm(const q_weight_t &w)
Definition: reduce.hh:284
void z_vector_in_new_basis(std::vector< vector_t > &basis, vector_t &current, vector_t &new_vector, unsigned *permutation)
Definition: reduce.hh:387
context_t_of< automaton_t > context_t
Definition: reduce.hh:196
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
Definition: traits.hh:34
const weightset_t_of< automaton_t > ws_
Definition: reduce.hh:585
static void normalisation_vector(Reduc *, Vector &, unsigned, unsigned *)
Definition: reduce.hh:172
state_t_of< output_automaton_t > output_state_t
Definition: reduce.hh:202
typename context_t::weight_t weight_t
Definition: reduce.hh:203
auto reduce(const Aut &input) -> decltype(copy(input))
Definition: reduce.hh:610
static void vector_in_new_basis(Reduc *that, Basis &basis, Vector &current, Vector &new_vector, unsigned *permutation)
Definition: reduce.hh:120
automaton make_automaton(const Aut &aut)
Build a dyn::automaton.
Definition: automaton.hh:77
variadic_mul_mixin< detail::b_impl > b
Definition: fwd.hh:38
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.
Definition: reduce.hh:247
unsigned int den
Definition: q.hh:61
typename automaton_t::element_type::automaton_nocv_t output_automaton_t
Definition: reduce.hh:199
static void normalisation_vector(Reduc *that, Vector &v, unsigned pivot, unsigned *permutation)
Definition: reduce.hh:105
static void reduce_vector(Reduc *that, Vector &vbasis, Vector &current, unsigned b, unsigned *permutation)
Definition: reduce.hh:97
weight_t reduce_vector(vector_t &vbasis, vector_t &current, unsigned b, unsigned *permutation)
Reduce a vector w.r.t.
Definition: reduce.hh:432
left_reductioner(const automaton_t &input)
Definition: reduce.hh:209
static unsigned find_pivot(Reduc *that, const Vector &v, unsigned begin, unsigned *permutation)
Definition: reduce.hh:133
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
Definition: traits.hh:32
AutOut copy(const AutIn &input, Pred keep_state)
A copy of input keeping only its states that are accepted by keep_state.
Definition: copy.hh:171
std::map< label_t, matrix_t > matrix_set_t
Definition: reduce.hh:206
automaton reduce(const automaton &aut)
Bridge.
Definition: reduce.hh:623
static weight_t norm(const z_weight_t &w)
Norm for integers.
Definition: reduce.hh:296
type_t
The possible types of ratexps.
Definition: fwd.hh:31
unsigned find_pivot_by_norm(const vector_t &v, unsigned begin, unsigned *permutation)
Definition: reduce.hh:303
auto left_reduce(const Aut &input) -> decltype(copy(input))
Definition: reduce.hh:600
typename detail::label_t_of_impl< base_t< ValueSet >>::type label_t_of
Definition: traits.hh:33
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
Definition: traits.hh:38
void bottom_up_reduction(std::vector< vector_t > &basis, unsigned *permutation)
Apply reduction to vectors of the basis to maximize the number of zeros.
Definition: reduce.hh:464
static unsigned find_pivot(Reduc *that, const Vector &v, unsigned begin, unsigned *permutation)
Definition: reduce.hh:145
std::vector< weight_t > vector_t
Definition: reduce.hh:204
static void vector_in_new_basis(Reduc *that, Basis &basis, Vector &current, Vector &new_vector, unsigned *permutation)
Definition: reduce.hh:181
state_t_of< automaton_t > state_t
Definition: reduce.hh:201
static void reduce_vector(Reduc *that, Vector &vbasis, Vector &current, unsigned b, unsigned *permutation)
Definition: reduce.hh:165
double value_t
Definition: r.hh:44
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:36
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.
Definition: reduce.hh:415
output_automaton_t operator()()
Core algorithm This algorithm computes a basis of I.mu(w).
Definition: reduce.hh:489
static void bottom_up_reduction(Reduc *that, Basis &basis, unsigned *permutation)
Definition: reduce.hh:113
output_automaton_t res_
Definition: reduce.hh:587
std::vector< std::map< std::size_t, weight_t > > matrix_t
Definition: reduce.hh:205
Aut transpose(const transpose_automaton< Aut > &aut)
Definition: transpose.hh:230
void vector_in_new_basis(std::vector< vector_t > &basis, vector_t &current, vector_t &new_vector, unsigned *permutation)
Compute the coordinate of a vector in the new basis.
Definition: reduce.hh:473
label_t_of< automaton_t > label_t
Definition: reduce.hh:200
static unsigned find_pivot(Reduc *that, const Vector &v, unsigned begin, unsigned *permutation)
Definition: reduce.hh:89
void normalisation_vector(vector_t &v, unsigned pivot, unsigned *permutation)
Normalize the basis vector such that its pivot is equal to 1.
Definition: reduce.hh:450
static z_weight_t gcd(z_weight_t x, z_weight_t y, z_weight_t &a, z_weight_t &b)
Definition: reduce.hh:327
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:35
SharedPtr make_shared_ptr(Args &&...args)
Same as std::make_shared, but parameterized by the shared_ptr type, not the (pointed to) element_type...
Definition: memory.hh:15
void linear_representation()
Create the linear representation of the input.
Definition: reduce.hh:215
void z_reduce_vector(vector_t &vbasis, vector_t &current, unsigned nb, unsigned *permutation)
Definition: reduce.hh:367
vcsn::detail::z_impl::value_t z_weight_t
Specializations for Q and R.
Definition: reduce.hh:270
weight_t scalar_product(const vector_t &v, const vector_t &w)
Computes the scalar product of two vectors.
Definition: reduce.hh:260
variadic_mul_mixin< detail::r_impl > r
Definition: fwd.hh:42
static unsigned find_pivot(Reduc *that, const Vector &v, unsigned begin, unsigned *permutation)
Definition: reduce.hh:157