+
+ # Return the element with the highest value (aka. the mode)
+ #
+ # ~~~
+ # var c = new Counter[String].from(["a", "a", "b", "b", "b", "c"])
+ # assert c.max == "b"
+ # ~~~
+ #
+ # If more than one max exists, the first one is returned.
+ fun max: nullable E do
+ var max: nullable Int = null
+ var elem: nullable E = null
+ for e in map.keys do
+ var v = map[e]
+ if max == null or v > max then
+ max = v
+ elem = e
+ end
+ end
+ return elem
+ end
+
+ # Return the couple with the lowest value
+ #
+ # ~~~
+ # var c = new Counter[String].from(["a", "a", "b", "b", "b", "c"])
+ # assert c.min == "c"
+ # ~~~
+ #
+ # If more than one min exists, the first one is returned.
+ fun min: nullable E do
+ var min: nullable Int = null
+ var elem: nullable E = null
+ for e in map.keys do
+ var v = map[e]
+ if min == null or v < min then
+ min = v
+ elem = e
+ end
+ end
+ return elem
+ end
+
+ # Values average (aka. arithmetic mean)
+ #
+ # ~~~
+ # var c = new Counter[String].from(["a", "a", "b", "b", "b", "c"])
+ # assert c.avg == 2.0
+ # ~~~
+ fun avg: Float do
+ if values.is_empty then return 0.0
+ return (sum / values.length).to_f
+ end
+
+ # The standard derivation of the counter values
+ #
+ # ~~~
+ # var c = new Counter[String].from(["a", "a", "b", "b", "b", "c"])
+ # assert c.std_dev > 0.81
+ # assert c.std_dev < 0.82
+ # ~~~
+ fun std_dev: Float do
+ var avg = self.avg
+ var sum = 0.0
+ for value in map.values do
+ sum += (value.to_f - avg).pow(2.0)
+ end
+ return (sum / map.length.to_f).sqrt
+ end
+
+ # The information entropy (Shannon entropy) of the elements in the counter (in bits).
+ fun entropy: Float
+ do
+ var res = 0.0
+ var sum = self.sum.to_f
+ for k, v in self do
+ var f = v.to_f / sum
+ res = res - f * f.log_base(2.0)
+ end
+ return res
+ end
+end
+
+redef class Collection[E]
+ # Create and fill up a counter with the elements of `self.
+ #
+ # ~~~
+ # var cpt = "abaa".chars.to_counter
+ # assert cpt['a'] == 3
+ # assert cpt['b'] == 1
+ # assert cpt.length == 2
+ # assert cpt.sum == 4
+ # ~~~
+ fun to_counter: Counter[E]
+ do
+ var res = new Counter[E]
+ res.inc_all(self)
+ return res
+ end