@@ -45,41 +45,93 @@ class EqRightPartSelector(CompoundOperator):
4545 @HistoryExtender ('\n -> The equation structure was detected: ' , 'a' )
4646 def apply (self , objective : Equation , arguments : dict ):
4747 self_args , subop_args = self .parse_suboperator_args (arguments = arguments )
48-
49- if not objective .right_part_selected :
48+
49+ objective .reset_state (True )
50+
51+ while not (objective .right_part_selected and objective .simplified ):
5052 min_fitness = np .inf
53+ weights_internal = np .zeros_like (objective .structure )
5154 min_idx = 0
5255 if not objective .contains_deriv (objective .main_var_to_explain ):
5356 objective .restore_property (deriv = True )
5457 if not objective .contains_variable (objective .main_var_to_explain ):
5558 objective .restore_property (mandatory_family = objective .main_var_to_explain )
5659
57-
58-
5960 for target_idx , target_term in enumerate (objective .structure ):
6061 if not objective .structure [target_idx ].contains_deriv (objective .main_var_to_explain ):
6162 continue
6263 objective .target_idx = target_idx
63- # self.suboperators['sparsity'].apply(objective, subop_args['sparsity'])
64- # self.suboperators['coeff_calc'].apply(objective, subop_args['coeff_calc'])
6564 fitness = self .suboperators ['fitness_calculation' ].apply (objective ,
6665 arguments = subop_args ['fitness_calculation' ],
6766 force_out_of_place = True )
6867 if fitness < min_fitness :
6968 min_fitness = fitness
7069 min_idx = target_idx
70+ weights_internal = objective .weights_internal
7171 else :
7272 pass
7373
74+ objective .weights_internal = weights_internal
7475 objective .target_idx = min_idx
75- objective .reset_explaining_term (objective .target_idx )
7676 # self.suboperators['fitness_calculation'].apply(objective, arguments = subop_args['fitness_calculation'])
7777 # if not np.isclose(objective.fitness_value, max_fitness) and global_var.verbose.show_warnings:
7878 # warnings.warn('Reevaluation of fitness function for equation has obtained different result. Not an error, if ANN DE solver is used.')
79- objective .right_part_selected = True
79+ self .simplify_equation (objective )
80+ else :
81+ objective .reset_explaining_term (objective .target_idx )
82+
83+ def simplify_equation (self , objective : Equation ):
84+ # Get nonzero terms
85+ nonzero_terms_mask = np .array ([False if weight == 0 else True for weight in objective .weights_internal ], dtype = np .integer )
86+ nonrs_terms = [term for i , term in enumerate (objective .structure ) if i != objective .target_idx ]
87+ nonzero_terms = [item for item , keep in zip (nonrs_terms , nonzero_terms_mask ) if keep ]
88+ nonzero_terms .append (objective .structure [objective .target_idx ])
89+ nonzero_terms_labels = [[term .cache_label [0 ]] if not isinstance (term .cache_label [0 ], tuple ) else list (next (zip (* term .cache_label ))) for term in nonzero_terms ]
90+
91+ # If amount nonzero terms is more than one -- get their intersection
92+ if len (nonzero_terms ) > 1 :
93+ common_factor = np .array (list (set .intersection (* map (set , nonzero_terms_labels )))).flatten ()
94+ common_dim = []
95+ if len (common_factor ) > 0 :
96+ # Find if this intersection in the same dimension (i.e. trigonometry functions) + it's minimal order
97+ min_order = np .inf
98+ for term in nonzero_terms :
99+ for factor in term .structure :
100+ if factor .cache_label [0 ] == common_factor [0 ]:
101+ if len (factor .params ) > 1 :
102+ common_dim .append (factor .params [- 1 ])
103+ if factor .cache_label [1 ][0 ] < min_order :
104+ min_order = factor .cache_label [1 ][0 ]
105+ if len (set (common_dim )) < 2 :
106+ # If dimension is the same -- reduce order of terms' factor
107+ for term in nonzero_terms :
108+ temp = deepcopy (term )
109+ factors_simplified = []
110+ for factor in term .structure :
111+ if factor .cache_label [0 ] == common_factor [0 ]:
112+ for i , value in enumerate (factor .params_description ):
113+ if factor .params_description [i ]["name" ] == "power" :
114+ factor .params [i ] -= min_order
115+ if factor .params [i ] == 0 :
116+ factors_simplified .append (factor )
117+ term .structure = [factor for factor in term .structure if factor not in factors_simplified ]
118+ term .reset_saved_state ()
119+ # If term's order became zero -- replace term
120+ if len (term .structure ) == 0 :
121+ term .randomize ()
122+ term .reset_saved_state ()
123+ while objective .structure .count (term ) > 1 or term == temp :
124+ term .randomize ()
125+ term .reset_saved_state ()
126+ objective .simplified = False
127+ objective .right_part_selected = False
128+ return
129+ objective .simplified = True
130+ objective .right_part_selected = True
80131
81132 def use_default_tags (self ):
82133 self ._tags = {'equation right part selection' , 'gene level' , 'contains suboperators' , 'inplace' }
134+
83135
84136class RandomRHPSelector (CompoundOperator ):
85137 '''
0 commit comments