1 #ifndef VCSN_CORE_RAT_EXPANSIONSET_HH
2 # define VCSN_CORE_RAT_EXPANSIONSET_HH
17 template <
typename RatExpSet>
25 using ratexp_t =
typename ratexpset_t::value_t;
27 using weight_t =
typename weightset_t::value_t;
33 constexpr
static const char*
me() {
return "expansion"; }
38 using polys_t = std::map<label_t, polynomial_t, vcsn::less<labelset_t>>;
58 std::string
vname(
bool full =
true)
const
60 return "expansionset<" +
rs_.vname(full) +
">";
64 std::ostream&
print(
const value_t& v, std::ostream& o,
68 if (!
ws_.is_zero(v.constant) || v.polynomials.empty())
70 o << (format ==
"latex" ?
"\\left\\langle " :
"<");
71 ws_.print(v.constant, o, format);
72 o << (format ==
"latex" ?
"\\right\\rangle " :
">");
75 for (
const auto& p: v.polynomials)
78 o << (format ==
"latex" ?
" \\oplus " :
" + ");
80 rs_.labelset()->print(p.first, o, format);
81 o << (format ==
"latex" ?
" \\odot \\left[" :
".[");;
83 o << (format ==
"latex" ?
"\\right]" :
"]");;
93 auto one =
rs_.labelset()->one();
94 auto i = res.polynomials.find(
one);
95 if (i != std::end(res.polynomials))
97 auto j = i->second.find(
rs_.one());
98 if (j != std::end(i->second))
100 res.constant =
ws_.add(res.constant, j->second);
102 if (i->second.empty())
103 res.polynomials.erase(i);
116 auto has_one = std::integral_constant<bool, context_t::has_one()>();
124 auto one =
rs_.labelset()->one();
125 if (!
ws_.is_zero(res.constant))
141 auto has_one = std::integral_constant<bool, context_t::has_one()>();
142 return denormalize_(res, has_one);
148 return {ws_.zero(),
polys_t{}};
160 return {ws_.zero(), {{l, ps_.one()}}};
164 void add_here(value_t& lhs,
const value_t& rhs)
const
166 lhs.constant = ws_.add(lhs.constant, rhs.constant);
167 for (
const auto& p: rhs.polynomials)
168 ps_.add_here(lhs.polynomials[p.first], p.second);
174 res.constant = ws_.mul(w, res.constant);
175 for (
auto& p: res.polynomials)
176 p.second = ps_.lmul(w, p.second);
183 value_t res = {ws_.mul(lhs.constant, w),
polys_t{}};
184 for (
auto& p: lhs.polynomials)
185 for (
const auto& m: p.second)
186 ps_.add_here(res.polynomials[p.first],
187 rs_.rmul(m.first, w), m.second);
194 for (
auto& p: res.polynomials)
195 p.second = ps_.rmul(p.second, rhs);
202 res.constant = ws_.ldiv(w, res.constant);
203 for (
auto& p: res.polynomials)
204 for (
auto& m: p.second)
205 m.second = ws_.ldiv(w, m.second);
211 const value_t&,
const value_t&,
212 std::false_type)
const
217 const value_t& l,
const value_t&
r,
218 std::true_type)
const
221 auto one = rs_.labelset()->one();
223 auto i = l.polynomials.find(
one);
224 if (i != std::end(l.polynomials))
225 for (
const auto& rhs: r.polynomials)
226 if (!rs_.labelset()->is_one(rhs.first))
227 ps_.add_here(res.polynomials[
one],
228 ps_.conjunction(i->second,
229 ps_.lmul(rs_.atom(rhs.first),
234 auto i = r.polynomials.find(
one);
235 if (i != std::end(r.polynomials))
236 for (
const auto& lhs: l.polynomials)
237 if (!rs_.labelset()->is_one(lhs.first))
238 ps_.add_here(res.polynomials[
one],
239 ps_.conjunction(ps_.lmul(rs_.atom(lhs.first),
249 value_t res =
zero();
252 res.constant = ws_.mul(l.constant, r.constant);
253 for (
const auto& p:
zip_maps(l.polynomials, r.polynomials))
254 res.polynomials[p.first]
255 = ps_.conjunction(std::get<0>(p.second), std::get<1>(p.second));
257 auto has_one = std::integral_constant<bool, context_t::has_one()>();
258 conjunctions_with_one_(res, l, r, has_one);
269 ps_.add_here(res, rs_.one(), v.constant);
270 for (
const auto& p: v.polynomials)
276 if (!ps_.is_zero(p.second))
278 rs_.mul(rs_.atom(p.first), as_ratexp(p.second)),
287 for (
const auto& m: p)
288 res = rs_.add(res, rs_.lmul(m.second, m.first));
303 #endif // !VCSN_CORE_RAT_EXPANSIONSET_HH
Linear combination of labels: map labels to weights.
label_t_of< context_t > label_t
value_t & add_here(value_t &v, const value_t &p) const
v += p.
value_t & rmul_here(value_t &res, const ratexp_t &rhs) const
In place right multiplication by a ratexp.
ratexp_polynomialset_t< RatExpSet > make_ratexp_polynomialset(const RatExpSet &rs)
From a RatExpSet to its polynomialset.
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
typename polynomialset_t::monomial_t monomial_t
typename weightset_t::value_t weight_t
void conjunctions_with_one_(value_t &, const value_t &, const value_t &, std::false_type) const
static constexpr const char * me()
value_t & normalize_(value_t &res, std::false_type) const
value_t & denormalize(value_t &res) const
polynomialset_t ps_
The polynomialset for the polynomials.
boost::flyweight< std::string, boost::flyweights::no_tracking > symbol
An internalized string.
value_t conjunction(value_t l, value_t r) const
The conjunction of l and r.
value_t & normalize(value_t &res) const
value_t & lmul_here(const weight_t &w, value_t &res) const
Inplace left-multiplication by w of res.
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
void add_here(value_t &lhs, const value_t &rhs) const
In place addition.
typename value_t::value_type monomial_t
A pair
weightset_t ws_
Shorthand to the weightset.
static std::string sname()
The static name.
value_t & ldiv_here(const weight_t &w, value_t &res) const
Inplace left-division by w of res.
value_t & denormalize_(value_t &res, std::false_type) const
typename detail::label_t_of_impl< base_t< ValueSet >>::type label_t_of
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
value_t rmul(const value_t &lhs, const weight_t &w) const
Right-multiplication of lhs by w.
std::map< label_t, polynomial_t, vcsn::less< labelset_t >> polys_t
std::string vname(bool full=true) const
The dynamic name.
std::ostream & print(const monomial_t &m, std::ostream &out, symbol format=symbol{"text"}) const
Print a monomial.
typename ratexpset_t::value_t ratexp_t
value_t atom(const label_t &l) const
A single label.
constant< type_t::zero, Context > zero
auto normalize(const Aut &a) -> decltype(copy(a))
Normalize a automaton.
Provide a variadic mul on top of a binary mul(), and one().
polynomial_t as_polynomial(const value_t &v) const
Convert an expansion to a polynomial.
weightset_t_of< ratexpset_t > weightset_t
ratexpset_t rs_
The ratexpset used for the expressions.
std::map< label_t, weight_t, vcsn::less< labelset_t >> value_t
value_t & denormalize_(value_t &res, std::true_type) const
Denormalize res move the constant to the polynomial associated to one.
context_t_of< ratexpset_t > context_t
value_t zero() const
The zero.
zipped_maps< Dereference, Maps...> zip_maps(Maps &&...maps)
void conjunctions_with_one_(value_t &res, const value_t &l, const value_t &r, std::true_type) const
value_t one() const
The one.
std::ostream & print(const value_t &v, std::ostream &o, symbol format=symbol{"text"}) const
Print a first order development.
ratexp_t as_ratexp(const polynomial_t &p) const
typename polynomialset_t::value_t polynomial_t
expansionset(const ratexpset_t &rs)
value_t & normalize_(value_t &res, std::true_type) const
Normalize res: There must not remain a constant-term associated to one: put it with the constant term...
labelset_t_of< context_t > labelset_t