sdl2: update window_handle to support Windows and intro display_handle
[nit.git] / lib / counter.nit
index befce9c..ceecb48 100644 (file)
@@ -254,6 +254,81 @@ 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]
+       # 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]