#include <fstream>
#include <iostream>
#include <cmath>
#include <string>

/*
    Program to calculate entropy of a file.   <H> = - sum_i  P[i] log2( P[i] )
*/

using namespace std;

double log2(double x)
// Rule:
// logB(x) = logA(x)/logA(B)
//
{
   return log(x)/log(2);
}

int main()
{
// Characters are 8 bit, hence they have values from 0..255 
  const int N=256;
  int charcount[N];
  for (int i=0;i<N;i++) charcount[i]=0;
  
// read in file
  ifstream fi("monet.jpeg");
  int total=0;
  unsigned char c;  // Important
  while (fi >> c)
     {
       charcount[c]++;
       total++;
     }

// Print out histogram and calculate entropy
  double H=0;
  for (int i=0;i<N;i++)
    {
      double Pi=double(charcount[i])/total;

      if (charcount[i]>0)
        {
          cout << "P(" << char(i) << ") = " << Pi << "\n"; 
          H+=-Pi*log2(Pi);
        }
    }    
   cout << "Entropy per symbol : " << H << " bits\n";

// Calculate maximal entropy assuming Pi = const or zero.
  int Nsymbols=0;
  string symbols;
  for (int i=0;i<N;i++)
    {
      if (charcount[i]>0) 
        {
           Nsymbols++;
           symbols.push_back( char(i) );
        }
    }    

   cout << "File contained " << Nsymbols << " unique symbols: " << symbols << "\n";
   cout << "Maximal entropy per symbol : " << log2(Nsymbols) << " bits\n";


   return 0;
}
