Entropy: Difference between revisions

234 bytes added ,  8 years ago
m
→‎version 2: added/changed whitespace and comments.
(added FreeBasic)
m (→‎version 2: added/changed whitespace and comments.)
Line 1,542:
 
===version 2===
REXX doesn't have a BIF for   '''LOG'''   or   '''LN''',   so the subroutine (function)   '''LOG2'''   is included herein.
<br>The LOG2 subroutine is only included here for functionality, not to document how to calculate LOG2 using REXX.
<lang rexx>/*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($); $$=
 
<br>The &nbsp; '''LOG2''' &nbsp; subroutine is only included here for functionality, not to document how to calculate LOG2&nbsp; LOG<sub>2</sub> &nbsp; using REXX.
do j=1 for L; _=substr($,j,1) /*process each character in $ str*/
<lang rexx>/*REXX program calculates the information entropy for a given charcharacter str.string*/
if @._==0 then do; n=n+1 /*if unique, bump char counter. */
numeric digits 50 $$=$$ || _ /*adduse this50 characterdecimal todigits thefor listprecision. */
parse arg $; if $=='' then $=1223334444 /*obtain the optional input from the CL*/
#=0; @.=0; L=length($); $$= /*define handy-dandy REXX variables. */
 
do j=1 for L; _=substr($,j,1) /*process each character in $ str string.*/
if @._==0 then do; n#=n#+1 /*ifUnique? unique Yes, bump charcharacter counter. */
$$=$$ || _ /*add this character to the $$ list. */
end
@._ = @._+1 /*keep track of this charcharacter's count. */
end /*j*/
sum=0 /*calccalculate info entropy for each char.*/
do i=1 for n#; _=substr($$,i,1) /*obtain a charcharacter from unique list. */
sum=sum - @._/L * log2(@._/L) /*add (negatively) the char 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 all done. */
/*──────────────────────────────────LOG2 subroutine───────────────────────────*/
log2: procedure; parse arg x 1 xxox; 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 & xxox>1.5 | \ig&xxox<.5; _=e; do jk=-1; iz=xxox* _**-is
if jk>=0 then if& (ig & iz<1 | \ig&iz>.5) then leave; _=_*_; izz=iz; end /*j*/
xx ox=izz; ii=ii+is*2**jk; end /*while*/; 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)</lang>
{{out}} when using the default input of: <tt> 1223334444 </tt>
<pre>