First commit of partial RosettaCode contents.

Pushing this for testing purposes. Lots of work still needed.
This commit is contained in:
Ingy döt Net 2013-04-08 13:02:41 -07:00
commit 1e05ecd7ee
781 changed files with 9080 additions and 0 deletions

View file

@ -0,0 +1,7 @@
Calculate the [[wp:Entropy (information theory)|information entropy]] (Shannon entropy) of a given input string.
Entropy is the [[wp:Expected value|expected value]] of the measure of [[wp:Self-information|information]] content in a system. In general, the Shannon entropy of a variable <math>X</math> is defined as:
:<math>H(X) = \sum_{x\in\Omega} P(x) I(x)</math>
where the information content <math>I(x) = -\log_{b} P(x)</math>. If the base of the logarithm <math>b = 2</math>, the result is expressed in ''bits'', a [[wp:Units of information|unit of information]]. Therefore, given a string <math>S</math> of length <math>n</math> where <math>P(s_i)</math> is the relative frequency of each character, the entropy of a string in bits is:
:<math>H(S) = -\sum_{i=0}^n P(s_i) \log_2 (P(s_i))</math>
For this task, use "<tt>1223334444</tt>" as an example. The result should be around 1.84644 bits.

2
Task/Entropy/1META.yaml Normal file
View file

@ -0,0 +1,2 @@
---
note: Mathematics

View file

@ -0,0 +1,8 @@
import Data.List
main = print $ entropy "1223334444"
entropy s =
sum . map lg' . fq' . map (fromIntegral.length) . group . sort $ s
where lg' c = (c * ) . logBase 2 $ 1.0 / c
fq' c = map (\x -> x / (sum c)) c

View file

@ -0,0 +1,9 @@
sub entropy {
my %count; $count{$_}++ for @_;
my @p = map $_/@_, values %count;
my $entropy = 0;
$entropy += - $_ * log $_ for @p;
$entropy / log 2
}
print entropy split //, "1223334444";

View file

@ -0,0 +1,34 @@
from __future__ import division
import math
def hist(source):
hist = {}; l = 0;
for e in source:
l += 1
if e not in hist:
hist[e] = 0
hist[e] += 1
return (l,hist)
def entropy(hist,l):
elist = []
for v in hist.values():
c = v / l
elist.append(-c * math.log(c ,2))
return sum(elist)
def printHist(h):
flip = lambda (k,v) : (v,k)
h = sorted(h.iteritems(), key = flip)
print 'Sym\thi\tfi\tInf'
for (k,v) in h:
print '%s\t%f\t%f\t%f'%(k,v,v/l,-math.log(v/l, 2))
source = "1223334444"
(l,h) = hist(source);
print '.[Results].'
print 'Length',l
print 'Entropy:', entropy(h, l)
printHist(h)

View file

@ -0,0 +1,30 @@
/*REXX program calculates the information entropy for a given char str.*/
numeric digits 30 /*use thirty digits for precision*/
parse arg $; if $=='' then $=1223334444 /*obtain optional input*/
n=0; @.=0; L=length($); $$=
do j=1 for L; _=substr($,j,1) /*process each character in $ str*/
if @._==0 then do; n=n+1 /*if unique, bump char counter. */
$$=$$ || _ /*add this character to the list.*/
end
@._ = @._+1 /*keep track of this char count. */
end /*j*/
sum=0 /*calc info entropy for each char*/
do i=1 for n; _=substr($$,i,1) /*obtain a char from unique list.*/
sum=sum - @._/L * log2(@._/L) /*add (negatively) the entropies.*/
end /*i*/
say ' input string: ' $
say 'string length: ' L
say ' unique chars: ' n ; say
say 'the information entropy of the string ──► ' format(sum,,12) " bits."
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────LOG2 subroutine─────────────────────*/
log2: procedure; parse arg x 1 xx; ig= x>1.5; is=1-2*(ig\==1); ii=0
numeric digits digits()+5 /* [↓] precision of E must be > digits().*/
e=2.7182818284590452353602874713526624977572470936999595749669676277240766303535
do while ig & xx>1.5 | \ig&xx<.5; _=e; do k=-1; iz=xx* _**-is
if k>=0 & (ig & iz<1 | \ig&iz>.5) then leave; _=_*_; izz=iz; end
xx=izz; ii=ii+is*2**k; end; x=x* e**-ii-1; z=0; _=-1; p=z
do k=1; _=-_*x; z=z+_/k; if z=p then leave; p=z; end /*k*/
r=z+ii; if arg()==2 then return r; return r/log2(2,0)

View file

@ -0,0 +1,84 @@
/* Rexx ***************************************************************
* 28.02.2013 Walter Pachl
* 12.03.2013 Walter Pachl typo in log corrected. thanx for testing
**********************************************************************/
s="1223334444"
occ.=0
n=0
Do i=1 To length(s)
c=substr(s,i,1)
occ.c=occ.c+1
n=n+1
End
do c=1 To 4
p.c=occ.c/n
say c p.c
End
e=0
Do c=1 To 4
e=e+p.c*log(p.c,,2)
End
Say 'Entropy of' s 'is' (-e)
Exit
log: Procedure
/***********************************************************************
* Return log(x) -- with specified precision and a specified base
* Three different series are used for the ranges 0 to 0.5
* 0.5 to 1.5
* 1.5 to infinity
* 03.09.1992 Walter Pachl
***********************************************************************/
Parse Arg x,prec,b
If prec='' Then prec=9
Numeric Digits (2*prec)
Numeric Fuzz 3
Select
When x<=0 Then r='*** invalid argument ***'
When x<0.5 Then Do
z=(x-1)/(x+1)
o=z
r=z
k=1
Do i=3 By 2
ra=r
k=k+1
o=o*z*z
r=r+o/i
If r=ra Then Leave
End
r=2*r
End
When x<1.5 Then Do
z=(x-1)
o=z
r=z
k=1
Do i=2 By 1
ra=r
k=k+1
o=-o*z
r=r+o/i
If r=ra Then Leave
End
End
Otherwise /* 1.5<=x */ Do
z=(x+1)/(x-1)
o=1/z
r=o
k=1
Do i=3 By 2
ra=r
k=k+1
o=o/(z*z)
r=r+o/i
If r=ra Then Leave
End
r=2*r
End
End
If b<>'' Then
r=r/log(b)
Numeric Digits (prec)
r=r+0
Return r

View file

@ -0,0 +1,3 @@
def entropy2(s)
s.each_char.group_by(&:to_s).values.map { |x| x.length / s.length.to_f }.reduce(0) { |e, x| e - x*Math.log2(x) }
end

View file

@ -0,0 +1,9 @@
def entropy(s)
counts = Hash.new(0)
s.each_char { |c| counts[c] += 1 }
counts.values.reduce(0) do |entropy, count|
freq = count / s.length.to_f
entropy - freq * Math.log2(freq)
end
end

View file

@ -0,0 +1,12 @@
import scala.math._
def entropy( v:String ) = { v
.groupBy (a => a)
.values
.map( i => i.length.toDouble / v.length )
.map( p => -p * log10(p) / log10(2))
.sum
}
// Confirm that "1223334444" has an entropy of about 1.84644
assert( math.round( entropy("1223334444") * 100000 ) * 0.00001 == 1.84644 )

View file

@ -0,0 +1,2 @@
puts [format "entropy = %.5f" [entropy "1223334444"]]
puts [format "entropy = %.5f" [entropy "Rosetta Code"]]

View file

@ -0,0 +1,10 @@
proc entropy {str} {
set log2 [expr log(2)]
foreach char [split $str ""] {dict incr counts $char}
set entropy 0.0
foreach count [dict values $counts] {
set freq [expr {$count / double([string length $str])}]
set entropy [expr {$entropy - $freq * log($freq)/$log2}]
}
return $entropy
}