from pprint import pprint
import random

import numpy as np
from amachine.am_create import random_machine, isomorphic_to, star_join

np.random.seed( 42 ) 
random.seed(    42 )

# May have multiple recurrent subgraphs, terminal states, or tranistory states
m = random_machine( 
	n_states=19, 
	symbols=[ '0', '1', '2' ],
	connectedness=0.61,
	randomness=0.37 )

# # Collapse to the largest recurrent subgraph
m.collapse_to_largest_strongly_connected_subgraph()

# # Minimize the machine -> epsilon-machine.
m.minimize()

#Entropy rate and statistical complexity, and H_1 (uncertainty when ignorance of the past) 
#Always efficient to compute
print( f"h_mu : {m.h_mu():.3f}" )
print( f"C_mu : {m.C_mu():.3f}" )
print( f"H_1 : {m.H_1():.3f}" )

#Excess entropy, crypticity, synchronization information, transient information
#Relys on msp+spectral by default
#If MSP explodes massively, it approximates it. 
print( f"E    : {m.E():.3f}" )
print( f"T    : {m.T_inf():.3f}" )
print( f"S    : {m.S():.3f}" )
print( f"Chi  : {m.Chi():.3f}" )

#Block entropy convergence estimates E together with other measures
#If MSP based approach was estimated, may want to compare result with block entropy based estimation
# Cb = m.block_convergence() 
# pprint( Cb )

# # Draw the graph 
# m.draw_graph( output_dir=".", show=True, engine='dot' )

