X-Git-Url: http://nitlanguage.org diff --git a/lib/counter.nit b/lib/counter.nit index 818264e..e539bc5 100644 --- a/lib/counter.nit +++ b/lib/counter.nit @@ -80,6 +80,12 @@ class Counter[E] 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 @@ -133,6 +139,7 @@ class Counter[E] # @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 @@ -254,6 +261,63 @@ class Counter[E] 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]