import amachine as am

# Seeds random and np.random globally (alternatively pass a random seed directly to random_machine)
am.srand_global( 42 )

# May have multiple recurrent subgraphs, terminal states, or tranistory states
m = am.random_machine( 
	n_states=23, 
	symbols=[ '0', '1' ],
	connectedness=0.35,
	randomness=0.25 )

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

# Minimize the machine in case it's not minimal -> epsilon-machine.
m.minimize( retain_names=True )

# Single symbol entropy, entropy rate, Statistical complexity
print( f"H(1) : {m.H_1():.3f}" )
print( f"h_mu : {m.h_mu():.3f}" )
print( f"C_mu : {m.C_mu():.3f}" )

# Excess entropy, transient information, synchronization information 
print( f"E : {m.E():.3f}" )
print( f"T : {m.T_inf():.3f}" )
print( f"S : {m.S():.3f}" )

# Crypticity
print( f"chi : {m.chi():.3f}" )

# Display the epislon machine
m.draw_graph()