GitLab Repo

amachine.am_create.am_full_isomorphic_rotation

 1import copy
 2import random
 3
 4import numpy as np
 5
 6from ..am_hmm          import HMM
 7from ..am_causal_state import CausalState
 8from ..am_transition   import Transition
 9
10from ..am_random import exp_uniform_blend, resolve_rng
11from ..am_vocabulary import Vocabulary
12
13from .am_random_machine import random_machine
14from .am_isomorphic_to import isomorphic_to
15from .am_star_join import star_join
16
17def full_isomorphic_rotation(
18    isoclass_name : str, 
19    n_states : int,
20    n_base_symbols : int,
21    connectedness : float,
22    randomness : float,
23    star_joined : bool,
24    mode_residency_factor : float | None = None,
25    random_seed : int | None = None )  -> HMM | list[HMM] :
26
27    if star_joined and mode_residency_factor is None :
28        raise ValueError( "star_join requires mode_residency factor" )
29
30    base_symbol_pool  = Vocabulary.digits()      + Vocabulary.letters_lower()
31    enter_symbol_pool = Vocabulary.greek_lower() + Vocabulary.greek_upper()
32    exit_symbol = '*'
33
34    max_n_symbols = min( len(base_symbol_pool), len(enter_symbol_pool) )
35
36    if n_base_symbols > max_n_symbols :
37        raise ValueError( f"Only up to {len(base_symbol_pool)} base symbols supported" )
38
39    alphabet = base_symbol_pool[ 0:n_base_symbols ]
40    enter_symbols = enter_symbol_pool[ 0:n_base_symbols ]
41
42    m = random_machine( 
43        n_states=n_states, 
44        symbols=alphabet, 
45        randomness=randomness,
46        connectedness=connectedness,
47        ensure_strongly_connected=True,
48        ensure_minimal=True,
49        random_seed=random_seed )
50    
51    machines = []
52    for i in range( n_base_symbols ) :
53        
54        alphabet = alphabet[ -1: ] + alphabet[ 0 : n_base_symbols - 1 ]
55        im = isomorphic_to( m, alphabet=alphabet, decorator=enter_symbols[ i ] )
56        im.isoclass = isoclass_name
57        machines.append( im )
58
59    for im in machines :
60        for state in im.states :
61            
62            # get the undecorated name
63            undecorated   = state.name[ 0:-1 ]
64            my_decoration = state.name[-1]
65
66            # capture decorated names of all isomorphic states
67            for a in enter_symbols :
68
69                # self not storing self as isomorph
70                if a == my_decoration :
71                    continue
72
73                decorated = undecorated + a
74                state.add_isomorph( decorated )
75
76    final_machine = star_join(  
77        exit_symbol=exit_symbol, 
78        enter_symbols=enter_symbols,
79        machines=machines,
80        mode_residency_factor=mode_residency_factor
81    )
82
83    return final_machine
def full_isomorphic_rotation( isoclass_name: str, n_states: int, n_base_symbols: int, connectedness: float, randomness: float, star_joined: bool, mode_residency_factor: float | None = None, random_seed: int | None = None) -> amachine.am_hmm.HMM | list[amachine.am_hmm.HMM]:
18def full_isomorphic_rotation(
19    isoclass_name : str, 
20    n_states : int,
21    n_base_symbols : int,
22    connectedness : float,
23    randomness : float,
24    star_joined : bool,
25    mode_residency_factor : float | None = None,
26    random_seed : int | None = None )  -> HMM | list[HMM] :
27
28    if star_joined and mode_residency_factor is None :
29        raise ValueError( "star_join requires mode_residency factor" )
30
31    base_symbol_pool  = Vocabulary.digits()      + Vocabulary.letters_lower()
32    enter_symbol_pool = Vocabulary.greek_lower() + Vocabulary.greek_upper()
33    exit_symbol = '*'
34
35    max_n_symbols = min( len(base_symbol_pool), len(enter_symbol_pool) )
36
37    if n_base_symbols > max_n_symbols :
38        raise ValueError( f"Only up to {len(base_symbol_pool)} base symbols supported" )
39
40    alphabet = base_symbol_pool[ 0:n_base_symbols ]
41    enter_symbols = enter_symbol_pool[ 0:n_base_symbols ]
42
43    m = random_machine( 
44        n_states=n_states, 
45        symbols=alphabet, 
46        randomness=randomness,
47        connectedness=connectedness,
48        ensure_strongly_connected=True,
49        ensure_minimal=True,
50        random_seed=random_seed )
51    
52    machines = []
53    for i in range( n_base_symbols ) :
54        
55        alphabet = alphabet[ -1: ] + alphabet[ 0 : n_base_symbols - 1 ]
56        im = isomorphic_to( m, alphabet=alphabet, decorator=enter_symbols[ i ] )
57        im.isoclass = isoclass_name
58        machines.append( im )
59
60    for im in machines :
61        for state in im.states :
62            
63            # get the undecorated name
64            undecorated   = state.name[ 0:-1 ]
65            my_decoration = state.name[-1]
66
67            # capture decorated names of all isomorphic states
68            for a in enter_symbols :
69
70                # self not storing self as isomorph
71                if a == my_decoration :
72                    continue
73
74                decorated = undecorated + a
75                state.add_isomorph( decorated )
76
77    final_machine = star_join(  
78        exit_symbol=exit_symbol, 
79        enter_symbols=enter_symbols,
80        machines=machines,
81        mode_residency_factor=mode_residency_factor
82    )
83
84    return final_machine