map.clear
end
+ redef fun add_all(other) do
+ for k, v in other do
+ self[k] += v
+ end
+ end
+
# Count one more occurrence of `e`
fun inc(e: E)
do
# @toimplement by default just call `to_s` on the element
protected fun element_to_s(e: E): String
do
+ if e == null then return "null"
return e.to_s
end
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
+
+ # Prints the content of the counter along with statistics
+ #
+ # Content is printed in order (if available) from lowest to highest on the keys.
+ # Else, it is printed as-is
+ fun print_content do
+ var a = keys.to_a
+ if a isa Array[Comparable] then default_comparator.sort(a)
+ var subtotal = 0
+ for i in a do
+ subtotal += self[i]
+ printn("* ", i or else "null", " = ", self[i], " => occurences ", self[i].to_f / sum.to_f * 100.0, "%, cumulative ", subtotal.to_f / sum.to_f * 100.0, "% \n")
+ end
+ end
+
+ # Packs elements into separate arrays based on their occurences
+ #
+ # ~~~nit
+ # var x = "aaaabbbeeecccddhhgjt"
+ # var c = new Counter[Char]
+ # for i in x do c.inc i
+ # var ret = c.pack
+ # assert ret.join(", ") == """[t,g,j], [d,h], [c,b,e], [a]"""
+ # ~~~
+ fun pack: Array[Array[E]] do
+ var ret = new Array[Array[E]]
+ var base = self.sort
+ if base.is_empty then return ret
+ var curr = new Array[E]
+ curr.push base.first
+ var curr_score = self[base.first]
+ base.shift
+ for i in base do
+ if self[i] == curr_score then
+ curr.push i
+ continue
+ end
+ curr_score = self[i]
+ ret.push curr
+ curr = new Array[E]
+ curr.push i
+ end
+ if not curr.is_empty then ret.push curr
+ return ret
+ 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
end
private class CounterComparator[E]