Skip to content

Instantly share code, notes, and snippets.

@faustind
Created July 3, 2018 00:22
Show Gist options
  • Save faustind/d9099ab4b0edb08929126f1f8d88b803 to your computer and use it in GitHub Desktop.
Save faustind/d9099ab4b0edb08929126f1f8d88b803 to your computer and use it in GitHub Desktop.
# table.py
import sys
from pathlib import Path
from math import log2
def H(p):
"""Return the value of the entropy function a p."""
return -p*log2(p) - (1-p)*log2(1-p)
def print_table(filename=''):
"""Print the table of values of the entropy function.
If filename is not provided, will print to stdout.
If filename is provided but does not exists it will be created.
The file will be truncated to the first line if already existing.
"""
if not filename: # print to stdout
print(" p | -log(p) | -plog(p) | H(p)")
# for p = 0
print("0 | _ | 0 | 0 ")
# for p between 0 and 1
p = 0.01
while p < 1.0:
print("{0:.2f} | {1:.7f} | {2:.7f} | {3:.7f}"
.format(p, -log2(p), -p*log2(p), H(p)))
p += 0.01
# for p = 1
print("1.00 | 0 | 0 | 0 ")
else:
filepath = Path(filename)
if not Path.is_file(filepath):
# file does not exists, create it
with open(filename, 'x'):
pass
with open(filename, 'w') as f:
f.write(" p | -log(p) | -plog(p) | H(p)\n")
# for p = 0
f.write("0 | _ | 0 | 0 \n")
p = 0.01
while p < 1.0:
f.write("{0:.2f} | {1:.7f} | {2:.7f} | {3:.7f}\n"
.format(p, -log2(p), -p*log2(p), H(p)))
p += 0.01
# for p = 1
f.write("1.00 | 0 | 0 | 0 \n")
def interactive_computation():
"""Enter interactive computation of entropy."""
print("""
This is an interactive mode.
Enter a value between -10 and 0 or 1 and 10 to see the entropy H of the distribution
Enter a value less than -10 or greater than 10 to exit
""")
cumulative, entropy = 0, 0
while True:
try:
p = float(input('Input pi : '))
except (KeyboardInterrupt, EOFError):
print("\nBye")
exit()
if 0 <= p <= 1:
# compute the cumulative
cumulative += p
# if p == 0, compute the entropy for p == 1
if p == 0:
p = 1
# entropy up to that input
entropy += -p*log2(p)
# print log(p) -p.log(p)
print('-log(pi) = {:.7f}'.format(-log2(p)))
print('-pi log(pi) = {:.7f}'.format(-p*log2(p)))
# test for distribution validity
if cumulative > 1:
print("""
WARNING: The numbers may not form a probability distribution:
cumulative is greater than 1
""")
print("cumulative = {:.2f}".format(cumulative))
elif -10 < p < 0 or 1 < p < 10:
if cumulative != 1:
print("""
WARNING: The numbers may not form a probability distribution:
cumulative is greater than 1
""")
print("cumulative = {:.2f}".format(cumulative))
# print the entropy
print("The entropy H = {:.7f}".format(entropy))
# clean cumulative and entropy for subsequent input
cumulative, entropy = 0, 0
else:
print("\nBye")
exit()
def print_usage():
"""Print usage information and exit."""
print("""
Usage: python3 entropy.py [-o [ FILENAME ]]
If no option is provided enter interactive computation mode
OPTIONS
-o   Print the entropy function values between 0 and 1 to stdout.
  Print to FILENAME if provided. FILENAME is created if not
  already existing.
   """)
if __name__ == '__main__':
argc = len(sys.argv)
if argc == 1:
interactive_computation()
elif argc == 2:
name, option = sys.argv
if option != '-o':
print_usage()
exit()
print_table()
elif argc == 3:
name, option, filename = sys.argv
if option != '-o':
print_usage()
else:
print_table(filename)
else:
print_usage()
exit()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment