3333from epde .structure .encoding import Chromosome
3434from epde .structure .factor import Factor
3535from epde .structure .structure_template import ComplexStructure , check_uniqueness
36- from epde .supplementary import filter_powers , normalize_ts , population_sort , flatten , rts , exp_form
36+ from epde .supplementary import filter_powers , normalize_ts , population_sort , flatten , rts , exp_form , minmax_normalize
3737
3838
3939class Term (ComplexStructure ):
@@ -71,23 +71,23 @@ def __init__(self, pool, passed_term=None, mandatory_family=None, max_factors_in
7171 self .use_cache ()
7272 # key - state of normalization, value - if the variable is saved in cache
7373 self .reset_saved_state ()
74-
74+
7575 def manual_reconst (self , attribute :str , value , except_attrs :dict ):
76- from epde .loader import attrs_from_dict , get_typespec_attrs
76+ from epde .loader import attrs_from_dict , get_typespec_attrs
7777 supported_attrs = ['structure' ]
7878 if attribute not in supported_attrs :
7979 raise ValueError (f'Attribute { attribute } is not supported by manual_reconst method.' )
80-
80+
8181 if attribute == supported_attrs [0 ]:
8282 # Validate correctness of a term definition
8383 self .structure = []
8484 for factor_elem in value :
8585 factor = Factor .__new__ (Factor )
86-
86+
8787 attrs_from_dict (factor , factor_elem , except_attrs )
8888 factor .evaluator = self .pool
8989 self .structure .append (factor )
90-
90+
9191 @property
9292 def cache_label (self ):
9393 if len (self .structure ) > 1 :
@@ -171,7 +171,7 @@ def update_token_status(token_status, changes):
171171
172172 self .descr_variable_marker = mandatory_family if mandatory_family is not None else False
173173
174- if not mandatory_family :
174+ if not mandatory_family :
175175 occupied_by_factor , factor = self .pool .create (label = None , create_meaningful = True ,
176176 token_status = self .occupied_tokens_labels ,
177177 create_derivs = create_derivs , ** kwargs )
@@ -216,13 +216,15 @@ def evaluate(self, structural, grids=None):
216216 value = super ().evaluate (structural )
217217 if normalize :
218218 if np .ndim (value ) != 1 :
219- if len (self .structure ) > 1 :
220- value = np .ones_like (value )
221- for factor in self .structure :
222- temp = factor .evaluate ()
223- value *= normalize_ts (temp )
224- else :
225- value = normalize_ts (value )
219+ value = np .ones_like (value )
220+ for factor in self .structure :
221+ temp = factor .evaluate ()
222+ # value *= normalize_ts(temp)
223+ value *= minmax_normalize (temp )
224+ # value *= factor.evaluate(structural)
225+ # else:
226+ # # value = normalize_ts(value)
227+ # value = minmax_normalize(value)
226228 else :
227229 if np .std (value ) != 0 :
228230 value = (value - np .mean (value )) / np .std (value )
@@ -239,7 +241,7 @@ def evaluate(self, structural, grids=None):
239241 def filter_tokens_by_right_part (self , reference_target , equation , equation_position ):
240242 warnings .warn (message = 'Tokens can no longer be set as right-part-unique' ,
241243 category = DeprecationWarning )
242- taken_tokens = [factor .label for factor in reference_target .structure
244+ taken_tokens = [factor .label for factor in reference_target .structure
243245 if factor .status ['unique_for_right_part' ]]
244246 meaningful_taken = any ([factor .status ['meaningful' ] for factor in reference_target .structure
245247 if factor .status ['unique_for_right_part' ]])
@@ -355,10 +357,10 @@ def __deepcopy__(self, memo=None):
355357class Equation (ComplexStructure ):
356358 __slots__ = ['_history' , 'structure' , 'interelement_operator' , 'n_immutable' , 'pool' ,
357359 # '_target', '_features', 'saved', 'saved_as','max_factors_in_term', 'operator',
358- 'target_idx' , 'right_part_selected' , '_weights_final' , 'weights_final_evald' ,
360+ 'target_idx' , 'right_part_selected' , '_weights_final' , 'weights_final_evald' ,
359361 '_weights_internal' , 'weights_internal_evald' , 'fitness_calculated' , 'stability_calculated' , 'aic_calculated' , 'solver_form_defined' ,
360362 '_fitness_value' , '_coefficients_stability' , '_aic' , 'metaparameters' , 'main_var_to_explain' ] # , '_solver_form'
361-
363+
362364
363365 def __init__ (self , pool : TFPool , basic_structure : Union [list , tuple , set ], var_to_explain : str = None ,
364366 metaparameters : dict = {'sparsity' : {'optimizable' : True , 'value' : 1. },
@@ -383,7 +385,7 @@ def __init__(self, pool: TFPool, basic_structure: Union[list, tuple, set], var_t
383385 matrix, composed of terms, not included in target, value columns, designated as features for application in sparse regression;
384386
385387 fitness_value : float \r \n
386- Inverse value of squared error for the selected target 2function and features and discovered weights;
388+ Inverse value of squared error for the selected target 2function and features and discovered weights;
387389
388390 estimator : sklearn estimator of selected type \r \n
389391
@@ -431,29 +433,29 @@ def __init__(self, pool: TFPool, basic_structure: Union[list, tuple, set], var_t
431433 if check_uniqueness (new_term , self .structure ):
432434 force_var_to_explain = False
433435 break
434-
436+
435437 self .structure .append (new_term )
436438
437439 for idx , _ in enumerate (self .structure ):
438440 self .structure [idx ].use_cache ()
439441# self.coefficients_stability = np.inf
440-
442+
441443 def manual_reconst (self , attribute :str , value , except_attrs :dict ):
442- from epde .loader import attrs_from_dict , get_typespec_attrs
444+ from epde .loader import attrs_from_dict , get_typespec_attrs
443445 supported_attrs = ['structure' ]
444446 if attribute not in supported_attrs :
445447 raise ValueError (f'Attribute { attribute } is not supported by manual_reconst method.' )
446-
448+
447449 if attribute == supported_attrs [0 ]:
448450 # Validate correctness of a term definition
449451 self .structure = []
450452 for term_elem in value :
451453 term = Term .__new__ (Term )
452454 # except_attr, _ = get_typespec_attrs(term)
453-
455+
454456 attrs_from_dict (term , term_elem , except_attrs )
455457 self .structure .append (term )
456-
458+
457459 def reset_explaining_term (self , term_idx = 0 ):
458460 for idx , term in enumerate (self .structure ):
459461 if idx == term_idx :
@@ -533,21 +535,21 @@ def reconstruct_by_right_part(self, right_part_idx):
533535
534536 def evaluate (self , normalize = True , return_val = False , grids = None ):
535537 target = self .structure [self .target_idx ].evaluate (normalize , grids = grids )
536-
538+
537539 # Place for improvent: introduce shifted_idx where necessary
538540 def shifted_idx (idx ):
539541 if idx < self .target_idx :
540- return idx
542+ return idx
541543 elif idx > self .target_idx :
542544 return idx - 1
543545 else :
544546 return - 1
545-
547+
546548 if normalize :
547549 feature_indexes = list (range (len (self .structure )))
548550 feature_indexes .remove (self .target_idx )
549551 else :
550- feature_indexes = [idx for idx in range (len (self .structure ))
552+ feature_indexes = [idx for idx in range (len (self .structure ))
551553 if self .weights_internal [shifted_idx (idx )] != 0 and idx != self .target_idx ]
552554 if len (feature_indexes ) > 0 :
553555 for feat_idx in range (len (feature_indexes )):
@@ -564,15 +566,15 @@ def shifted_idx(idx):
564566 temp_feats = np .transpose (temp_feats )
565567 else :
566568 features = None
567-
569+
568570 if return_val :
569571 self .prev_normalized = normalize
570572 if normalize :
571573 elem1 = np .expand_dims (target , axis = 1 )
572574 value = np .add (elem1 , - reduce (lambda x , y : np .add (x , y ), [np .multiply (self .weights_internal [idx_full ], temp_feats [:, idx_sparse ])
573575 for idx_sparse , idx_full in enumerate (feature_indexes )]))
574576 # for feature_idx, weight in np.ndenumerate(self.weights_internal)]))
575- else :
577+ else :
576578 elem1 = np .expand_dims (target , axis = 1 )
577579 if features is not None :
578580 features_val = reduce (lambda x , y : np .add (x , y ), [np .multiply (self .weights_final [idx_full ], temp_feats [:, idx_sparse ])
@@ -723,7 +725,7 @@ def text_form(self):
723725 self .structure [term_idx ].name + ' + '
724726 form += 'k_' + str (len (self .structure )) + ' = 0'
725727 return form
726-
728+
727729 @property
728730 def latex_form (self ):
729731 form = self .structure [self .target_idx ].latex_form + r' = '
@@ -736,13 +738,13 @@ def latex_form(self):
736738 mnt , exp = exp_form (self .weights_final [idx_corrected ], digits_rounding_max )
737739 exp_str = r'\cdot 10^{{{0}}} ' .format (str (exp )) if exp != 0 else ''
738740 form += str (mnt ) + exp_str + term .latex_form + r' + '
739-
741+
740742 mnt , exp = exp_form (self .weights_final [- 1 ], digits_rounding_max )
741743 exp_str = r'\cdot 10^{{{0}}} ' .format (str (exp )) if exp != 0 else ''
742-
744+
743745 form += str (mnt ) + exp_str
744746 return form
745-
747+
746748 @property
747749 def state (self ):
748750 return self .text_form
@@ -786,26 +788,26 @@ def count_order(obj, deriv_ax):
786788 if np .max (max_orders ) > 4 :
787789 raise NotImplementedError ('The current implementation allows does not allow higher orders of equation, than 2.' )
788790 return max_orders
789-
791+
790792 def boundary_conditions (self , max_deriv_orders = (1 ,), main_var_key = ('u' , (1.0 ,)), full_domain : bool = False ,
791793 grids : list = None ):
792794 required_bc_ord = max_deriv_orders # We assume, that the maximum order of the equation here is 2
793795 if global_var .grid_cache is None :
794796 raise NameError ('Grid cache has not been initialized yet.' )
795-
797+
796798 bconds = []
797799 hardcoded_bc_relative_locations = {0 : (), 1 : (0 ,), 2 : (0 , 1 ),
798800 3 : (0. , 0.5 , 1. ), 4 : (0. , 1 / 3. , 2 / 3. , 1. )}
799-
801+
800802 if full_domain :
801803 grid_cache = global_var .initial_data_cache
802804 tensor_cache = global_var .initial_data_cache
803805 else :
804806 grid_cache = global_var .grid_cache
805807 tensor_cache = global_var .tensor_cache
806-
808+
807809 tensor_shape = grid_cache .get ('0' ).shape
808-
810+
809811 def get_boundary_ind (tensor_shape , axis , rel_loc ):
810812 return tuple (np .meshgrid (* [np .arange (shape ) if dim_idx != axis else min (int (rel_loc * shape ), shape - 1 )
811813 for dim_idx , shape in enumerate (tensor_shape )], indexing = 'ij' ))
@@ -818,12 +820,12 @@ def get_boundary_ind(tensor_shape, axis, rel_loc):
818820 if coords .ndim > 2 :
819821 coords = coords .squeeze ()
820822 vals = np .expand_dims (tensor_cache .get (main_var_key )[indexes ], axis = 0 ).T
821-
823+
822824 coords = torch .from_numpy (coords ).type (torch .FloatTensor )
823-
825+
824826 vals = torch .from_numpy (vals ).type (torch .FloatTensor )
825- bconds .append ([coords , vals , 'dirichlet' ])
826-
827+ bconds .append ([coords , vals , 'dirichlet' ])
828+
827829 return bconds
828830
829831 def clear_after_solver (self ):
@@ -876,13 +878,13 @@ def __init__(self, pool: TFPool, metaparameters: dict):
876878 self .moeadd_set = False
877879
878880 self .vars_to_describe = [token_family .variable for token_family in self .tokens_for_eq .families ]
879-
881+
880882 def manual_reconst (self , attribute :str , value , except_attrs :dict ):
881883 from epde .loader import attrs_from_dict , get_typespec_attrs
882884 supported_attrs = ['vals' ]
883885 if attribute not in supported_attrs :
884886 raise ValueError (f'Attribute { attribute } is not supported by manual_reconst method.' )
885-
887+
886888 if attribute == supported_attrs [0 ]:
887889 # Validate correctness of a term definition
888890 equations = {}
@@ -892,7 +894,7 @@ def manual_reconst(self, attribute:str, value, except_attrs:dict):
892894 equations [self .vars_to_describe [idx ]] = eq
893895 self .vals = Chromosome (equations , {key : val for key , val in self .metaparameters .items ()
894896 if val ['optimizable' ]})
895-
897+
896898 def use_default_multiobjective_function (self , use_pic : bool = False ):
897899 if use_pic :
898900 self .use_pic_multiobjective_function ()
@@ -935,35 +937,35 @@ def set_objective_functions(self, obj_funs):
935937 Parameters:
936938 -----------
937939 obj_funs - callable or list of callables;
938- function/functions to evaluate quality metrics of system of equations. Can return a single
939- metric (for example, quality of the process modelling with specific system), or
940+ function/functions to evaluate quality metrics of system of equations. Can return a single
941+ metric (for example, quality of the process modelling with specific system), or
940942 a list of metrics (for example, number of terms for each equation in the system).
941- The function results will be flattened after their application.
943+ The function results will be flattened after their application.
942944
943945 '''
944946 assert callable (obj_funs ) or all ([callable (fun ) for fun in obj_funs ])
945947 self .obj_funs = obj_funs
946948
947949 def matches_complexitiy (self , complexity : Union [int , list ]):
948- if isinstance (complexity , (int , float )):
950+ if isinstance (complexity , (int , float )):
949951 complexity = [complexity ,]
950-
952+
951953 if not isinstance (complexity , list ) or len (self .vars_to_describe ) != len (complexity ):
952954 raise ValueError ('Incorrect list of complexities passed.' )
953955 adj_complexity = copy .copy (complexity )
954956 for idx , compl in enumerate (adj_complexity ):
955957 if compl is None :
956958 adj_complexity [idx ] = self .obj_fun [- len (complexity ) + idx ]
957-
959+
958960 return list (self .obj_fun [- len (adj_complexity ):]) == adj_complexity
959961
960962 def create (self , passed_equations : list = None ):
961963 if passed_equations is None :
962964 structure = {}
963-
965+
964966 token_selection = self .tokens_supp
965967 current_tokens_pool = token_selection + self .tokens_for_eq
966-
968+
967969 for eq_idx , variable in enumerate (self .vars_to_describe ):
968970 structure [variable ] = Equation (current_tokens_pool , basic_structure = [],
969971 var_to_explain = variable ,
@@ -988,7 +990,7 @@ def equation_opt_iteration(population, evol_operator, population_size, iter_inde
988990 gc .collect ()
989991 population = evol_operator .apply (population , unexplained_vars )
990992 return population
991-
993+
992994 @property
993995 def obj_fun (self ):
994996 return np .array (flatten ([func (self ) for func in self .obj_funs ]))
0 commit comments