amachine.am_create.am_full_random_structured_isomorphic_rotation
1from collections import defaultdict 2import copy 3import random 4 5import numpy as np 6 7from ..am_hmm import HMM 8from ..am_causal_state import CausalState 9from ..am_transition import Transition 10 11from ..am_random import exp_uniform_blend, resolve_rng 12from ..am_vocabulary import Vocabulary 13from ..am_structured_symbol_set import StructuredSymbolSet 14 15from .am_random_structured import random_structured 16from .am_isomorphic_to_with_category_rotation import isomorphic_to_with_category_rotation 17from .am_star_join import star_join 18 19def full_random_structured_isomorphic_rotation( 20 isoclass_name : int, 21 n_states : int, 22 symbol_set : StructuredSymbolSet, 23 connectedness : float, 24 randomness : float, 25 star_joined : bool, 26 mode_residency_factor : float | None = None, 27 existing_symbol_cohesion : np.ndarray | None = None, 28 existing_symbol_categories : dict[str, int] | None = None, 29 max_search_time : float = 120.0, 30 n_search_workers = 3, 31 random_seed : int | None = None 32) -> HMM | list[HMM]: 33 34 if star_joined and mode_residency_factor is None : 35 raise ValueError( "star_join requires mode_residency factor" ) 36 37 m = random_structured( 38 n_states=n_states, 39 symbol_set=symbol_set, 40 connectedness=connectedness, 41 randomness=randomness, 42 max_search_time=max_search_time, 43 n_search_workers=n_search_workers, 44 random_seed=random_seed 45 ) 46 47 # Collapse to the largest recurrent subgraph 48 m.collapse_to_largest_strongly_connected_subgraph() 49 50 # Minimize the machine -> epsilon-machine. 51 m.minimize() 52 53 m.isoclass = isoclass_name 54 55 n_isomorphic = len( symbol_set.symbols ) // len( symbol_set.categories ) - 1 56 m_isos = [] 57 58 enter_symbol_pool = list( set( 59 Vocabulary.digits() 60 + Vocabulary.letters_lower() 61 + Vocabulary.letters_upper() 62 + Vocabulary.greek_lower() 63 + Vocabulary.greek_upper() ) - set( m.alphabet ) ) 64 65 if len( enter_symbol_pool ) < n_isomorphic + 1 : 66 raise ValueError( "Not enough symbols left over to construct star join." ) 67 68 for i in range( 1, n_isomorphic+1 ) : 69 70 m_iso = isomorphic_to_with_category_rotation( 71 m=m, 72 symbol_categories=symbol_set.symbol_categories, 73 categories_to_rotate=symbol_set.categories, 74 shift=i, 75 decorator=f"@{i}" 76 ) 77 78 m_iso.isoclass = isoclass_name 79 m_isos.append( m_iso ) 80 81 all_machines = [ m ] + m_isos 82 83 for ma in all_machines : 84 for mb in all_machines : 85 if ma != mb : 86 for j, state in enumerate( ma.states ) : 87 ma.states[ j ].add_isomorph( mb.states[ j ].name ) 88 mb.states[ j ].add_isomorph( ma.states[ j ].name ) 89 90 if star_joined : 91 92 # Join them together 93 m_star = star_join( 94 exit_symbol='x', 95 enter_symbols=enter_symbol_pool[ 0:len(all_machines) ], 96 machines=all_machines, 97 mode_residency_factor=mode_residency_factor 98 ) 99 100 return m_star 101 102 else : 103 return all_machines
def
full_random_structured_isomorphic_rotation( isoclass_name: int, n_states: int, symbol_set: amachine.am_structured_symbol_set.StructuredSymbolSet, connectedness: float, randomness: float, star_joined: bool, mode_residency_factor: float | None = None, existing_symbol_cohesion: numpy.ndarray | None = None, existing_symbol_categories: dict[str, int] | None = None, max_search_time: float = 120.0, n_search_workers=3, random_seed: int | None = None) -> amachine.am_hmm.HMM | list[amachine.am_hmm.HMM]:
20def full_random_structured_isomorphic_rotation( 21 isoclass_name : int, 22 n_states : int, 23 symbol_set : StructuredSymbolSet, 24 connectedness : float, 25 randomness : float, 26 star_joined : bool, 27 mode_residency_factor : float | None = None, 28 existing_symbol_cohesion : np.ndarray | None = None, 29 existing_symbol_categories : dict[str, int] | None = None, 30 max_search_time : float = 120.0, 31 n_search_workers = 3, 32 random_seed : int | None = None 33) -> HMM | list[HMM]: 34 35 if star_joined and mode_residency_factor is None : 36 raise ValueError( "star_join requires mode_residency factor" ) 37 38 m = random_structured( 39 n_states=n_states, 40 symbol_set=symbol_set, 41 connectedness=connectedness, 42 randomness=randomness, 43 max_search_time=max_search_time, 44 n_search_workers=n_search_workers, 45 random_seed=random_seed 46 ) 47 48 # Collapse to the largest recurrent subgraph 49 m.collapse_to_largest_strongly_connected_subgraph() 50 51 # Minimize the machine -> epsilon-machine. 52 m.minimize() 53 54 m.isoclass = isoclass_name 55 56 n_isomorphic = len( symbol_set.symbols ) // len( symbol_set.categories ) - 1 57 m_isos = [] 58 59 enter_symbol_pool = list( set( 60 Vocabulary.digits() 61 + Vocabulary.letters_lower() 62 + Vocabulary.letters_upper() 63 + Vocabulary.greek_lower() 64 + Vocabulary.greek_upper() ) - set( m.alphabet ) ) 65 66 if len( enter_symbol_pool ) < n_isomorphic + 1 : 67 raise ValueError( "Not enough symbols left over to construct star join." ) 68 69 for i in range( 1, n_isomorphic+1 ) : 70 71 m_iso = isomorphic_to_with_category_rotation( 72 m=m, 73 symbol_categories=symbol_set.symbol_categories, 74 categories_to_rotate=symbol_set.categories, 75 shift=i, 76 decorator=f"@{i}" 77 ) 78 79 m_iso.isoclass = isoclass_name 80 m_isos.append( m_iso ) 81 82 all_machines = [ m ] + m_isos 83 84 for ma in all_machines : 85 for mb in all_machines : 86 if ma != mb : 87 for j, state in enumerate( ma.states ) : 88 ma.states[ j ].add_isomorph( mb.states[ j ].name ) 89 mb.states[ j ].add_isomorph( ma.states[ j ].name ) 90 91 if star_joined : 92 93 # Join them together 94 m_star = star_join( 95 exit_symbol='x', 96 enter_symbols=enter_symbol_pool[ 0:len(all_machines) ], 97 machines=all_machines, 98 mode_residency_factor=mode_residency_factor 99 ) 100 101 return m_star 102 103 else : 104 return all_machines