Vcsn  2.8
Be Rational
log.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <cmath>
4 #include <iostream>
5 #include <string>
6 
7 #include <vcsn/core/join.hh>
8 #include <vcsn/misc/format.hh>
9 #include <vcsn/misc/functional.hh> // hash_value
10 #include <vcsn/misc/math.hh>
11 #include <vcsn/misc/raise.hh>
12 #include <vcsn/misc/star-status.hh>
13 #include <vcsn/misc/stream.hh> // eat
14 #include <vcsn/misc/symbol.hh>
15 #include <vcsn/weightset/fwd.hh>
17 
18 namespace vcsn
19 {
20  namespace detail
21  {
22  class log_impl
23  {
24  public:
25  using self_t = log;
26  using value_t = double;
27 
28  static symbol sname()
29  {
30  static auto res = symbol{"log"};
31  return res;
32  }
33 
35  static log make(std::istream& is)
36  {
37  eat(is, sname());
38  return {};
39  }
40 
42  static value_t zero()
43  {
44  return std::numeric_limits<value_t>::infinity();
45  }
46 
48  static value_t one()
49  {
50  return 0;
51  }
52 
53  static value_t
54  min()
55  {
57  }
58 
59  static value_t
60  max()
61  {
62  return std::numeric_limits<value_t>::max();
63  }
64 
65  static value_t add(const value_t l, const value_t r)
66  {
67  // https://lingpipe-blog.com/2009/06/25/log-sum-of-exponentials/
68  auto diff = l - r;
69  if (0 < diff)
70  return r - std::log1p(std::exp(-diff));
71  else if (diff <= 0)
72  return l - std::log1p(std::exp(diff));
73  else // NaN
74  return zero();
75  }
76 
77  static value_t sub(const value_t l, const value_t r)
78  {
79  return - std::log(std::exp(-l) - std::exp(-r));
80  }
81 
82  static value_t mul(const value_t l, const value_t r)
83  {
84  // We have to check if a member is +oo
85  return is_zero(l) || is_zero(r) ? zero() : l + r;
86  }
87 
88  value_t
89  rdivide(const value_t l, const value_t r) const
90  {
91  require(!is_zero(r), *this, ": div: division by zero");
92  return is_zero(l) ? l : l - r;
93  }
94 
95  value_t
96  ldivide(const value_t l, const value_t r) const
97  {
98  return rdivide(r, l);
99  }
100 
101  value_t star(const value_t v) const
102  {
103  if (v < 0)
104  raise_not_starrable(*this, v);
105  return std::log1p(-std::exp(-v));
106  }
107 
109  static int compare(const value_t l, const value_t r)
110  {
111  // Beware of infinity.
112  if (equal(l, r))
113  return 0;
114  else
115  return l - r;
116  }
117 
119  static bool equal(const value_t l, const value_t r)
120  {
121  return l == r;
122  }
123 
125  static bool less(const value_t l, const value_t r)
126  {
127  return l < r;
128  }
129 
130  constexpr static bool is_special(const value_t)
131  {
132  return false;
133  }
134 
135  static bool is_zero(const value_t v)
136  {
137  return v == zero();
138  }
139 
140  static bool is_one(const value_t v)
141  {
142  return v == one();
143  }
144 
145  static constexpr bool is_commutative() { return true; }
146  static constexpr bool is_idempotent() { return false; }
147  static constexpr bool has_lightening_weights() { return true; }
148 
149  static constexpr bool show_one() { return true; }
150  static constexpr star_status_t star_status()
151  {
153  }
154 
155  static value_t
157  {
158  return v;
159  }
160 
161  static size_t hash(const value_t v)
162  {
163  return hash_value(v);
164  }
165 
166  static value_t
168  {
169  return v;
170  }
171 
172  value_t
173  conv(std::istream& i, bool = true) const
174  {
175  value_t res;
176  if (i.peek() == 'o')
177  {
178  eat(i, "oo");
179  res = zero();
180  }
181  else if (! (i >> res))
182  raise_invalid_value(*this, i);
183  return res;
184  }
185 
186  static std::ostream&
187  print(const value_t v, std::ostream& o = std::cout,
188  format fmt = {})
189  {
190  if (is_zero(v))
191  return o << (fmt == format::latex ? "\\infty" : "oo");
192  else
193  return o << v;
194  }
195 
196  std::ostream&
197  print_set(std::ostream& o, format fmt = {}) const
198  {
199  switch (fmt.kind())
200  {
201  case format::latex:
202  o << "\\mathrm{Log}";
203  break;
204  case format::sname:
205  o << sname();
206  break;
207  case format::text:
208  case format::utf8:
209  o << "Log";
210  break;
211  case format::raw:
212  assert(0);
213  break;
214  }
215  return o;
216  }
217  };
218 
219  // Random generation.
220  template <typename RandomGenerator>
221  class random_weight<log, RandomGenerator>
222  : public random_weight_base<log, RandomGenerator>
223  {
224  public:
226  using value_t = typename super_t::weight_t;
227 
228  using super_t::super_t;
229 
230  private:
232  {
233  auto dis =
234  std::uniform_real_distribution<log::value_t>(super_t::min_, super_t::max_);
235  return dis(super_t::gen_);
236  }
237  };
238 
239 
240  /*-------.
241  | join. |
242  `-------*/
243 
245  }// detail::
246 }
static value_t zero()
The zero for the log semiring is +oo.
Definition: log.hh:42
Print as a parsable type string.
Definition: format.hh:26
static value_t mul(const value_t l, const value_t r)
Definition: log.hh:82
static value_t min()
Definition: log.hh:54
weightset_mixin< detail::r_impl > r
Definition: fwd.hh:54
static value_t max()
Definition: log.hh:60
static value_t transpose(const value_t v)
Definition: log.hh:156
value_t rdivide(const value_t l, const value_t r) const
Definition: log.hh:89
ATTRIBUTE_NORETURN void raise_invalid_value(const ValueSet &vs, Args &&... args)
Cannot make a value from this.
Definition: weightset.hh:227
static bool equal(const value_t l, const value_t r)
Whether l == r.
Definition: log.hh:119
char eat(std::istream &is, char c)
Check lookahead character and advance.
Definition: stream.cc:147
return exp min
Definition: multiply.hh:362
static constexpr star_status_t star_status()
Definition: log.hh:150
always valid.
Definition: star-status.hh:17
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string.
Definition: symbol.hh:21
static value_t one()
The neutral element for the log semiring is 0.
Definition: log.hh:48
static constexpr bool is_special(const value_t)
Definition: log.hh:130
static int compare(const value_t l, const value_t r)
Three-way comparison between l and r.
Definition: log.hh:109
static size_t hash(const value_t v)
Definition: log.hh:161
static constexpr bool show_one()
Definition: log.hh:149
static std::ostream & print(const value_t v, std::ostream &o=std::cout, format fmt={})
Definition: log.hh:187
Print as rich UTF-8 text, escaped.
Definition: format.hh:30
An input/output format for valuesets.
Definition: format.hh:13
Abstract class for random weight generation.
Definition: weightset.hh:118
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
static bool less(const value_t l, const value_t r)
Whether l < r.
Definition: log.hh:125
static value_t conv(self_t, const value_t v)
Definition: log.hh:167
auto hash_value(const T &v) -> decltype(std::hash< T >
Following the naming convention of Boost.
Definition: functional.hh:45
static bool is_one(const value_t v)
Definition: log.hh:140
Definition: a-star.hh:8
static symbol sname()
Definition: log.hh:28
weightset_mixin< detail::log_impl > log
Definition: fwd.hh:50
star_status_t
Definition: star-status.hh:5
static constexpr bool is_commutative()
Definition: log.hh:145
Print as plain (ASCII) text, escaped.
Definition: format.hh:28
static constexpr bool is_idempotent()
Definition: log.hh:146
static value_t add(const value_t l, const value_t r)
Definition: log.hh:65
static log make(std::istream &is)
Build from the description in is.
Definition: log.hh:35
ATTRIBUTE_NORETURN void raise_not_starrable(const WeightSet &ws, const typename WeightSet::value_t &w)
This value is not starrable.
Definition: weightset.hh:235
Print as is. For instance, don&#39;t try to escape labels.
Definition: format.hh:24
std::ostream & print_set(std::ostream &o, format fmt={}) const
Definition: log.hh:197
Print for LaTeX.
Definition: format.hh:22
VCSN_JOIN_SIMPLE(b, b)
Generic declaration of the class which is specialized in each weightset.
Definition: weightset.hh:208
void require(Bool b, Args &&... args)
If b is not verified, raise an error with args as message.
Definition: raise.hh:87
value_t conv(std::istream &i, bool=true) const
Definition: log.hh:173
static bool is_zero(const value_t v)
Definition: log.hh:135
value_t star(const value_t v) const
Definition: log.hh:101
static value_t sub(const value_t l, const value_t r)
Definition: log.hh:77
return res
Definition: multiply.hh:399
static constexpr bool has_lightening_weights()
Definition: log.hh:147
value_t ldivide(const value_t l, const value_t r) const
Definition: log.hh:96