RosettaCodeData/Task/Entropy/NetRexx/entropy.netrexx

74 lines
2.0 KiB
Plaintext

/* NetRexx */
options replace format comments java crossref savelog symbols
runSample(Arg)
return
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* REXX ***************************************************************
* 28.02.2013 Walter Pachl
**********************************************************************/
method getShannonEntropy(s = "1223334444") public static
--trace var occ c chars n cn i e p pl
Numeric Digits 30
occ = 0
chars = ''
n = 0
cn = 0
Loop i = 1 To s.length()
c = s.substr(i, 1)
If chars.pos(c) = 0 Then Do
cn = cn + 1
chars = chars || c
End
occ[c] = occ[c] + 1
n = n + 1
End i
p = ''
Loop ci = 1 To cn
c = chars.substr(ci, 1)
p[c] = occ[c] / n
End ci
e = 0
Loop ci = 1 To cn
c = chars.substr(ci, 1)
pl = log2(p[c])
e = e + p[c] * pl
End ci
Return -e
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method log2(a = double) public static binary returns double
return Math.log(a) / Math.log(2)
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method runSample(Arg) public static
parse Arg sstr
if sstr = '' then
sstr = '1223334444' -
'1223334444555555555' -
'122333' -
'1227774444' -
'aaBBcccDDDD' -
'1234567890abcdefghijklmnopqrstuvwxyz' -
'Rosetta_Code'
say 'Calculating Shannon''s entropy for the following list:'
say '['(sstr.space(1, ',')).changestr(',', ', ')']'
say
entropies = 0
ssMax = 0
-- This crude sample substitutes a '_' character for a space in the input strings
loop w_ = 1 to sstr.words()
ss = sstr.word(w_)
ssMax = ssMax.max(ss.length())
ss_ = ss.changestr('_', ' ')
entropy = getShannonEntropy(ss_)
entropies[ss] = entropy
end w_
loop report = 1 to sstr.words()
ss = sstr.word(report)
ss_ = ss.changestr('_', ' ')
Say 'Shannon entropy of' ('"'ss_'"').right(ssMax + 2)':' entropies[ss].format(null, 12)
end report
return