18 #ifndef AWALI_ALGOS_REDUCE_HH
19 # define AWALI_ALGOS_REDUCE_HH
22 # include <unordered_map>
33 namespace awali {
namespace sttc {
101 template<
typename Weightset>
104 template<
typename Reduc,
typename Vector>
107 unsigned begin,
unsigned* permutation)
109 return that->find_pivot(v, begin, permutation);
112 template<
typename Reduc,
typename Vector>
115 Vector& current,
unsigned b,
unsigned* permutation)
117 that->reduce_vector(vbasis, current,
b, permutation);
120 template<
typename Reduc,
typename Vector>
123 unsigned pivot,
unsigned* permutation)
125 that->normalisation_vector(v, pivot, permutation);
128 template<
typename Reduc,
typename Basis>
132 that->bottom_up_reduction(basis, permutation);
135 template<
typename Reduc,
typename Basis,
typename Vector>
138 Vector& current, Vector& new_vector,
139 unsigned* permutation)
141 that->vector_in_new_basis(basis, current, new_vector, permutation);
148 template<
typename Reduc,
typename Vector>
151 unsigned begin,
unsigned* permutation)
153 return that->find_pivot_by_norm(v, begin, permutation);
160 template<
typename Reduc,
typename Vector>
163 unsigned begin,
unsigned* permutation)
165 return that->find_pivot_by_norm(v, begin, permutation);
172 template<
typename Reduc,
typename Vector>
175 unsigned begin,
unsigned* permutation)
177 return that->find_pivot_by_norm(v, begin, permutation);
180 template <
typename Reduc,
typename Vector>
183 Vector& current,
unsigned b,
unsigned* permutation)
185 that->z_reduce_vector(vbasis, current,
b, permutation);
188 template <
typename Reduc,
typename Vector>
192 template<
typename Reduc,
typename Basis>
196 template<
typename Reduc,
typename Basis,
typename Vector>
199 Vector& current, Vector& new_vector,
200 unsigned* permutation)
202 that->z_vector_in_new_basis(basis, current, new_vector, permutation);
206 template <
typename Aut,
typename AutOutput>
210 "requires free labelset");
212 using automaton_t = Aut;
214 using weightset_t =
typename context_t::weightset_t;
215 using output_automaton_t = AutOutput;
218 using vector_t = std::vector<weight_t>;
219 using matrix_t = std::vector<std::map<std::size_t, weight_t> > ;
220 using matrix_set_t = std::map<label_t, matrix_t>;
231 std::unordered_map<state_t, unsigned> state_to_index;
233 for (
auto s: input_->states())
234 state_to_index[s] = i++;
241 for (
auto t : input_->initial_transitions())
242 init[state_to_index[input_->dst_of(t)]] = input_->weight_of(t);
244 for (
auto t : input_->final_transitions())
245 final[state_to_index[input_->src_of(t)]] = input_->weight_of(t);
247 for (
auto t : input_->transitions())
249 auto it = letter_matrix_set.find(input_->label_of(t));
250 if (it == letter_matrix_set.end())
251 it = letter_matrix_set.emplace(input_->label_of(t),
252 matrix_t(dimension)).first;
253 it->second[state_to_index[input_->src_of(t)]]
254 [state_to_index[input_->dst_of(t)]] = input_->weight_of(t);
265 for (
unsigned i = 0; i < dimension; i++)
268 unsigned j = it.first;
269 res[j] = ws_.add(res[j], ws_.mul(v[i], it.second));
277 weight_t res = ws_.zero();
278 for (
unsigned i = 0; i < dimension; ++i)
279 res = ws_.add(res, ws_.mul(v[i], w[i]));
306 return std::fabs(w)+std::fabs(1/w);
318 unsigned* permutation)
321 for(; i < dimension && ws_.is_zero(v[permutation[i]]); ++i)
326 auto min =
norm(v[permutation[i++]]);
327 for (; i < dimension; ++i)
328 if (!ws_.is_zero(v[permutation[i]])
329 && (pivot == dimension
330 ||
norm(v[permutation[i]])<
min))
351 int sx=(x<0)?-1:1, sy=(y<0)?-1:1;
364 a0=a-
q*a0; b0=
b-
q*b0;
383 unsigned nb,
unsigned* permutation)
385 unsigned pivot = permutation[nb];
386 if (ws_.is_zero(current[pivot]))
388 weight_t bp = vbasis[pivot];
389 weight_t cp = current[pivot];
391 weight_t g =
gcd(bp, cp, a,
b);
394 for (
unsigned i = nb; i < dimension; ++i)
396 weight_t tmp = current[permutation[i]];
397 current[permutation[i]] = bp*tmp - cp*vbasis[permutation[i]];
398 vbasis[permutation[i]] = a*vbasis[permutation[i]] +
b*tmp;
403 vector_t& current, vector_t& new_vector,
404 unsigned* permutation)
406 for (
unsigned b = 0;
b < basis.size(); ++
b)
408 vector_t& vbasis = basis[
b];
409 unsigned pivot = permutation[
b];
410 new_vector[
b] = current[pivot] / vbasis[pivot];
411 if (!ws_.is_zero(new_vector[
b]))
413 current[pivot] = ws_.zero();
414 for (
unsigned i =
b+1; i < dimension; ++i)
415 current[permutation[i]]
416 -= new_vector[
b] * vbasis[permutation[i]];
431 unsigned* permutation)
433 for (
unsigned i = begin; i < dimension; ++i)
434 if (!ws_.is_zero(v[permutation[i]]))
448 vector_t& current,
unsigned b,
449 unsigned* permutation)
451 unsigned pivot = permutation[
b];
452 weight_t ratio = current[pivot];
453 if (ws_.is_zero(ratio))
456 current[pivot] = ws_.zero();
457 for (
unsigned i =
b+1; i < dimension; ++i)
458 current[permutation[i]]
459 = ws_.sub(current[permutation[i]],
460 ws_.mul(ratio, vbasis[permutation[i]]));
466 unsigned* permutation)
468 weight_t k = v[permutation[pivot]];
471 v[permutation[pivot]] = ws_.one();
472 for (
unsigned r = pivot + 1;
r < dimension; ++
r)
473 v[permutation[
r]] = ws_.rdiv(v[permutation[
r]], k);
480 unsigned* permutation)
482 for (
unsigned b = basis.size()-1; 0 <
b; --
b)
483 for (
unsigned c = 0;
c <
b; ++
c)
489 vector_t& current, vector_t& new_vector,
490 unsigned* permutation)
492 for (
unsigned b = 0;
b < basis.size(); ++
b)
510 std::vector<vector_t> basis;
514 unsigned* permutation =
new unsigned[dimension];
515 for (
unsigned i = 0; i < dimension; ++i)
520 unsigned pivot = type_t::find_pivot(
this, init, 0, permutation);
521 if (pivot == dimension)
524 permutation[0] = pivot;
525 permutation[pivot] = 0;
528 vector_t first(init);
529 type_t::normalisation_vector(
this, first, 0, permutation);
530 basis.push_back(first);
535 for (
unsigned nb = 0; nb < basis.size(); ++nb)
537 for (
auto mu : letter_matrix_set)
539 vector_t current(dimension);
542 for (
unsigned b = 0;
b < basis.size(); ++
b)
543 type_t::reduce_vector(
this, basis[
b],
544 current,
b, permutation);
547 pivot = type_t::find_pivot(
this, current, basis.size(),
549 if (pivot != dimension)
551 if (pivot != basis.size())
552 std::swap(permutation[pivot], permutation[basis.size()]);
553 type_t::normalisation_vector(
this, current,
554 basis.size(), permutation);
555 basis.push_back(current);
561 type_t::bottom_up_reduction(
this, basis, permutation);
565 std::vector<state_t>
states(basis.size());
566 for (
unsigned b = 0;
b < basis.size(); ++
b)
569 vector_t vect_new_basis(basis.size());
570 type_t::vector_in_new_basis(
this, basis, init,
571 vect_new_basis, permutation);
572 for (
unsigned b = 0;
b < basis.size(); ++
b)
573 res_->set_initial(
states[
b], vect_new_basis[
b]);
576 for (
unsigned v = 0; v < basis.size(); ++v)
580 res_->set_final(
states[v],k);
581 for (
auto mu : letter_matrix_set)
584 vector_t current(dimension);
586 type_t::vector_in_new_basis(
this, basis, current,
587 vect_new_basis, permutation);
588 for (
unsigned b = 0;
b < basis.size(); ++
b)
590 mu.first, vect_new_basis[
b]);
593 delete[] permutation;
606 output_automaton_t res_;
612 matrix_set_t letter_matrix_set;
618 template<
typename Aut>
627 auto ret=
copy(algo2.get_output());
628 if(ret->num_states() >= input->num_states())
630 if(!input->get_name().empty()) {
631 ret->set_desc(
"Reduction of "+input->get_name());
632 ret->set_name(
"red-"+input->get_name());
635 ret->set_desc(
"Reduction");
636 ret->set_name(
"red");
641 template<
typename Aut>
646 return copy(algo.get_output());
Definition: qfraction.hh:26
den_t den
Definition: qfraction.hh:32
num_t num
Definition: qfraction.hh:31
The Boolean semring.
Definition: b.hh:38
The semiring of complex numbers.
Definition: c.hh:44
carries the algebraic settings of automata
Definition: context.hh:40
Definition: reduce.hh:208
sttc::r::value_t r_weight_t
Definition: reduce.hh:286
static unsigned norm(const z_weight_t &w)
Norm for integers.
Definition: reduce.hh:310
void z_reduce_vector(vector_t &vbasis, vector_t ¤t, unsigned nb, unsigned *permutation)
Definition: reduce.hh:382
void left_reduce()
Core algorithm This algorithm computes a basis of I.mu(w).
Definition: reduce.hh:502
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.
Definition: reduce.hh:488
unsigned find_pivot_by_norm(const vector_t &v, unsigned begin, unsigned *permutation)
Definition: reduce.hh:317
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:430
weight_t scalar_product(const vector_t &v, const vector_t &w)
Computes the scalar product of two vectors.
Definition: reduce.hh:274
static z_weight_t gcd(z_weight_t x, z_weight_t y, z_weight_t &a, z_weight_t &b)
Definition: reduce.hh:347
reductioner(const automaton_t &input)
Definition: reduce.hh:223
sttc::z::value_t z_weight_t
Specializations for Q and R.
Definition: reduce.hh:284
weight_t reduce_vector(vector_t &vbasis, vector_t ¤t, unsigned b, unsigned *permutation)
Reduce a vector w.r.t.
Definition: reduce.hh:447
void linear_representation()
Create the linear representation of the input.
Definition: reduce.hh:229
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:465
output_automaton_t get_output() const
Definition: reduce.hh:597
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:479
void z_vector_in_new_basis(std::vector< vector_t > &basis, vector_t ¤t, vector_t &new_vector, unsigned *permutation)
Definition: reduce.hh:402
static unsigned norm(const q_weight_t &w)
Definition: reduce.hh:298
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:261
static double norm(const r_weight_t &w)
Norm for real numbers; a "stable" pivot should minimize this norm.
Definition: reduce.hh:304
The semiring of rational numbers.
Definition: q.hh:42
q_fraction_t value_t
Definition: q.hh:63
The semiring of floating Numbers.
Definition: r.hh:35
double value_t
Definition: r.hh:56
The semiring of Integers.
Definition: z.hh:35
int value_t
Definition: z.hh:56
std::vector< state_t > states(abstract_automaton_t const *aut, bool all)
any_t weight_t
Type for (transition) weights; it is an alias to any_t since the its precise type depends on the weig...
Definition: typedefs.hh:61
type_t
The possible types of ratexps.
Definition: fwd.hh:48
typename internal::label_t_of_impl< internal::base_t< ValueSet > >::type label_t_of
Helper to retrieve the type of the labels of a value set.
Definition: traits.hh:71
Aut left_reduce(const Aut &input)
Definition: reduce.hh:642
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:29
typename internal::context_t_of_impl< internal::base_t< ValueSet > >::type context_t_of
Helper to retrieve the type of the context of a value set.
Definition: traits.hh:66
AutOut copy(const AutIn &input, Pred keep_state, bool keep_history=true, bool transpose=false)
A copy of input keeping only its states that are accepted by keep_state.
Definition: copy.hh:189
Aut reduce(const Aut &input)
Definition: reduce.hh:619
std::shared_ptr< internal::transpose_view_impl< Aut > > transpose_view(std::shared_ptr< Aut > aut)
Definition: transpose_view.hh:265
typename internal::weightset_t_of_impl< internal::base_t< ValueSet > >::type weightset_t_of
Helper to retrieve the type of the weightset of a value set.
Definition: traits.hh:86
ATTRIBUTE_CONST int min(int a, int b)
Definition: arith.hh:48
Main namespace of Awali.
Definition: ato.hh:22
static unsigned find_pivot(Reduc *that, const Vector &v, unsigned begin, unsigned *permutation)
Definition: reduce.hh:150
static unsigned find_pivot(Reduc *that, const Vector &v, unsigned begin, unsigned *permutation)
Definition: reduce.hh:162
static void normalisation_vector(Reduc *, Vector &, unsigned, unsigned *)
Definition: reduce.hh:189
static void bottom_up_reduction(Reduc *, Basis &, unsigned *)
Definition: reduce.hh:193
static unsigned find_pivot(Reduc *that, const Vector &v, unsigned begin, unsigned *permutation)
Definition: reduce.hh:174
static void reduce_vector(Reduc *that, Vector &vbasis, Vector ¤t, unsigned b, unsigned *permutation)
Definition: reduce.hh:182
static void vector_in_new_basis(Reduc *that, Basis &basis, Vector ¤t, Vector &new_vector, unsigned *permutation)
Definition: reduce.hh:198
Definition: reduce.hh:103
static void normalisation_vector(Reduc *that, Vector &v, unsigned pivot, unsigned *permutation)
Definition: reduce.hh:122
static void vector_in_new_basis(Reduc *that, Basis &basis, Vector ¤t, Vector &new_vector, unsigned *permutation)
Definition: reduce.hh:137
static unsigned find_pivot(Reduc *that, const Vector &v, unsigned begin, unsigned *permutation)
Definition: reduce.hh:106
static void bottom_up_reduction(Reduc *that, Basis &basis, unsigned *permutation)
Definition: reduce.hh:130
static void reduce_vector(Reduc *that, Vector &vbasis, Vector ¤t, unsigned b, unsigned *permutation)
Definition: reduce.hh:114