amachine.am_generator API documentation

GitLab Repo

# amachine.am_generator

View Source

      1import random
      2import numpy as np
      3import matplotlib.pyplot as plt
      4from pathlib import Path
      5from copy import deepcopy
      6
      7from .am_create import star, star_join, isomorphic_to
      8import random
      9
     10class Generator :
     11
     12	def __init__(self, random_seed=None ) -> None :
     13
     14		if random_seed :
     15
     16			np.random.seed( random_seed )
     17			random.seed( random_seed )
     18
     19		self.vocabulary = {
     20
     21			# 1. Printable ASCII: space (32) through tilde (126) → 95 chars
     22			"ASCII" : [chr(i) for i in range(32, 127)],
     23
     24			# 2. Greek capitals Α–Τ (19), skipping U+03A2 (undefined slot)
     25			"greek_upper" : [chr(i) for i in range(0x0391, 0x03A5) if i != 0x03A2][:19],
     26
     27			# 3. Greek smalls α–τ (19), skipping U+03C2 (ς, final-sigma variant)
     28			"greek_lower" : [chr(i) for i in range(0x03B1, 0x03C5) if i != 0x03C2][:19],
     29
     30			# 4. Geometric Shapes block: U+25A0–U+25FF → 96 chars
     31			"geometric" : [chr(i) for i in range(0x25A0, 0x2600)]
     32		}
     33
     34		self.exit_symbol = self.vocabulary[ "geometric" ][ 0 ]
     35
     36	def generate(
     37		self, n_states : int,
     38		n_symbols,
     39		n_modes : int,
     40		mode_alphas : list[float],
     41		residency_factor : float,
     42		levels : int ) :
     43
     44		# 0-9 ASCII + lowercase letters + uppercase letters
     45		normal_symbols  = [ chr(i) for i in range( 48,  58 ) ]
     46		normal_symbols += [ chr(i) for i in range( 97, 123 ) ]
     47		normal_symbols += [ chr(i) for i in range( 65,  91 ) ]
     48		enter_symbols = self.vocabulary[ "greek_lower" ] + self.vocabulary[ "greek_upper" ]
     49
     50		n_gen = n_modes*2
     51
     52		# n_gen^levels leaves
     53		machines = [
     54		    star(
     55		        exit_symbol=self.exit_symbol,
     56		        enter_symbols=enter_symbols[ 0:n_modes*2 ],
     57		        normal_symbols=normal_symbols,
     58		        n_modes=n_modes,
     59		        n_isomorphic=2,
     60		        randomness=0.3,
     61		        connectedness=0.5,
     62		        residency_factor=residency_factor,
     63		        n_normal_symbols=n_symbols,
     64		        t_states_per_machine=n_states
     65		    )
     66		    for i in range( n_gen**levels )
     67		]
     68
     69		es_per_lev = n_gen
     70		es_offset = n_modes*2
     71
     72		# Reduce bottom-up, levels-1 times
     73		for i in range( levels - 1 ) :
     74		    next_level = []
     75		    x = 0
     76
     77		    es = enter_symbols[ es_offset + es_per_lev*i : es_offset+es_per_lev*(i+1) ]
     78
     79		    for k in range( len(machines) // n_gen ) :  # shrinks each pass
     80		        m = star_join(
     81		            exit_symbol=self.exit_symbol,
     82		            enter_symbols=es,
     83		            machines=machines[ x:x+n_gen ],
     84		            mode_residency_factor=0.5
     85		        )
     86		        next_level.append( m )
     87		        x += n_gen
     88		    machines = deepcopy( next_level )
     89
     90		# machines now has exactly n_gen elements — join into root
     91		return star_join(
     92		    exit_symbol=self.exit_symbol,
     93		    enter_symbols=normal_symbols,
     94		    machines=machines,
     95		    mode_residency_factor=0.5
     96		)
     97
     98if __name__ == "__main__":
     99
    100	n_modes = 1
    101	alpha = 0.3
    102	residency_factor = 0.5
    103	n_symbols = 4
    104	n_states = 27
    105	random_seed=42
    106
    107	generator = Generator( random_seed=random_seed )
    108
    109	path = Path("../data/aM_7-mode-iso" )
    110	path.mkdir(parents=True, exist_ok=True)
    111
    112	aM = generator.generate(
    113		n_states=n_states,
    114		n_symbols=n_symbols,
    115		n_modes=n_modes,
    116		mode_alphas=[ alpha ]*n_modes,
    117		residency_factor=residency_factor,
    118		levels=3 )
    119
    120	aM.minimize(retain_names=True)
    121	print( aM.is_epsilon_HMM() )
    122
    123	aM.draw_graph()
    124
    125	print( f"h_mu : {aM.h_mu()}" )
    126	print( f"C_mu : {aM.C_mu()}" )

class Generator: View Source

    11class Generator :
    12
    13	def __init__(self, random_seed=None ) -> None :
    14
    15		if random_seed :
    16
    17			np.random.seed( random_seed )
    18			random.seed( random_seed )
    19
    20		self.vocabulary = {
    21
    22			# 1. Printable ASCII: space (32) through tilde (126) → 95 chars
    23			"ASCII" : [chr(i) for i in range(32, 127)],
    24
    25			# 2. Greek capitals Α–Τ (19), skipping U+03A2 (undefined slot)
    26			"greek_upper" : [chr(i) for i in range(0x0391, 0x03A5) if i != 0x03A2][:19],
    27
    28			# 3. Greek smalls α–τ (19), skipping U+03C2 (ς, final-sigma variant)
    29			"greek_lower" : [chr(i) for i in range(0x03B1, 0x03C5) if i != 0x03C2][:19],
    30
    31			# 4. Geometric Shapes block: U+25A0–U+25FF → 96 chars
    32			"geometric" : [chr(i) for i in range(0x25A0, 0x2600)]
    33		}
    34
    35		self.exit_symbol = self.vocabulary[ "geometric" ][ 0 ]
    36
    37	def generate(
    38		self, n_states : int,
    39		n_symbols,
    40		n_modes : int,
    41		mode_alphas : list[float],
    42		residency_factor : float,
    43		levels : int ) :
    44
    45		# 0-9 ASCII + lowercase letters + uppercase letters
    46		normal_symbols  = [ chr(i) for i in range( 48,  58 ) ]
    47		normal_symbols += [ chr(i) for i in range( 97, 123 ) ]
    48		normal_symbols += [ chr(i) for i in range( 65,  91 ) ]
    49		enter_symbols = self.vocabulary[ "greek_lower" ] + self.vocabulary[ "greek_upper" ]
    50
    51		n_gen = n_modes*2
    52
    53		# n_gen^levels leaves
    54		machines = [
    55		    star(
    56		        exit_symbol=self.exit_symbol,
    57		        enter_symbols=enter_symbols[ 0:n_modes*2 ],
    58		        normal_symbols=normal_symbols,
    59		        n_modes=n_modes,
    60		        n_isomorphic=2,
    61		        randomness=0.3,
    62		        connectedness=0.5,
    63		        residency_factor=residency_factor,
    64		        n_normal_symbols=n_symbols,
    65		        t_states_per_machine=n_states
    66		    )
    67		    for i in range( n_gen**levels )
    68		]
    69
    70		es_per_lev = n_gen
    71		es_offset = n_modes*2
    72
    73		# Reduce bottom-up, levels-1 times
    74		for i in range( levels - 1 ) :
    75		    next_level = []
    76		    x = 0
    77
    78		    es = enter_symbols[ es_offset + es_per_lev*i : es_offset+es_per_lev*(i+1) ]
    79
    80		    for k in range( len(machines) // n_gen ) :  # shrinks each pass
    81		        m = star_join(
    82		            exit_symbol=self.exit_symbol,
    83		            enter_symbols=es,
    84		            machines=machines[ x:x+n_gen ],
    85		            mode_residency_factor=0.5
    86		        )
    87		        next_level.append( m )
    88		        x += n_gen
    89		    machines = deepcopy( next_level )
    90
    91		# machines now has exactly n_gen elements — join into root
    92		return star_join(
    93		    exit_symbol=self.exit_symbol,
    94		    enter_symbols=normal_symbols,
    95		    machines=machines,
    96		    mode_residency_factor=0.5
    97		)

Generator(random_seed=None) View Source

    13	def __init__(self, random_seed=None ) -> None :
    14
    15		if random_seed :
    16
    17			np.random.seed( random_seed )
    18			random.seed( random_seed )
    19
    20		self.vocabulary = {
    21
    22			# 1. Printable ASCII: space (32) through tilde (126) → 95 chars
    23			"ASCII" : [chr(i) for i in range(32, 127)],
    24
    25			# 2. Greek capitals Α–Τ (19), skipping U+03A2 (undefined slot)
    26			"greek_upper" : [chr(i) for i in range(0x0391, 0x03A5) if i != 0x03A2][:19],
    27
    28			# 3. Greek smalls α–τ (19), skipping U+03C2 (ς, final-sigma variant)
    29			"greek_lower" : [chr(i) for i in range(0x03B1, 0x03C5) if i != 0x03C2][:19],
    30
    31			# 4. Geometric Shapes block: U+25A0–U+25FF → 96 chars
    32			"geometric" : [chr(i) for i in range(0x25A0, 0x2600)]
    33		}
    34
    35		self.exit_symbol = self.vocabulary[ "geometric" ][ 0 ]

vocabulary
exit_symbol
def generate( self, n_states: int, n_symbols, n_modes: int, mode_alphas: list[float], residency_factor: float, levels: int): View Source

    37	def generate(
    38		self, n_states : int,
    39		n_symbols,
    40		n_modes : int,
    41		mode_alphas : list[float],
    42		residency_factor : float,
    43		levels : int ) :
    44
    45		# 0-9 ASCII + lowercase letters + uppercase letters
    46		normal_symbols  = [ chr(i) for i in range( 48,  58 ) ]
    47		normal_symbols += [ chr(i) for i in range( 97, 123 ) ]
    48		normal_symbols += [ chr(i) for i in range( 65,  91 ) ]
    49		enter_symbols = self.vocabulary[ "greek_lower" ] + self.vocabulary[ "greek_upper" ]
    50
    51		n_gen = n_modes*2
    52
    53		# n_gen^levels leaves
    54		machines = [
    55		    star(
    56		        exit_symbol=self.exit_symbol,
    57		        enter_symbols=enter_symbols[ 0:n_modes*2 ],
    58		        normal_symbols=normal_symbols,
    59		        n_modes=n_modes,
    60		        n_isomorphic=2,
    61		        randomness=0.3,
    62		        connectedness=0.5,
    63		        residency_factor=residency_factor,
    64		        n_normal_symbols=n_symbols,
    65		        t_states_per_machine=n_states
    66		    )
    67		    for i in range( n_gen**levels )
    68		]
    69
    70		es_per_lev = n_gen
    71		es_offset = n_modes*2
    72
    73		# Reduce bottom-up, levels-1 times
    74		for i in range( levels - 1 ) :
    75		    next_level = []
    76		    x = 0
    77
    78		    es = enter_symbols[ es_offset + es_per_lev*i : es_offset+es_per_lev*(i+1) ]
    79
    80		    for k in range( len(machines) // n_gen ) :  # shrinks each pass
    81		        m = star_join(
    82		            exit_symbol=self.exit_symbol,
    83		            enter_symbols=es,
    84		            machines=machines[ x:x+n_gen ],
    85		            mode_residency_factor=0.5
    86		        )
    87		        next_level.append( m )
    88		        x += n_gen
    89		    machines = deepcopy( next_level )
    90
    91		# machines now has exactly n_gen elements — join into root
    92		return star_join(
    93		    exit_symbol=self.exit_symbol,
    94		    enter_symbols=normal_symbols,
    95		    machines=machines,
    96		    mode_residency_factor=0.5
    97		)