예제 #1
0
 def __init__(self, pool, terms_number, max_factors_in_term, sparsity = None, eq_search_iters = 100):
     self.tokens_indep = TF_Pool(pool.families_meaningful) #[family for family in token_families if family.status['meaningful']]
     self.tokens_dep = TF_Pool(pool.families_supplementary) #[family for family in token_families if not family.status['meaningful']]
     self.equation_number = np.size(self.tokens_indep.families_cardinality())
     
     if sparsity is not None: self.vals = sparsity 
     self.max_terms_number = terms_number; self.max_factors_in_term = max_factors_in_term
     self.moeadd_set = False; self.eq_search_operator_set = False# ; self.evaluated = False
     self.def_eq_search_iters = eq_search_iters
예제 #2
0
def test_custom_evaluator():
    x = np.linspace(0, 4*np.pi, 1000)
#    ts = np.ones()
    
    global_var.init_caches(set_grids=True)
#    global_var.tensor_cache.memory_usage_properties(obj_test_case=ts, mem_for_cache_frac = 5)  
    global_var.grid_cache.memory_usage_properties(obj_test_case=x, mem_for_cache_frac = 5)
    upload_grids(x, global_var.grid_cache)     
    
    test_lambdas = {'cos' : lambda *grids, **kwargs: np.cos(kwargs['freq'] * grids[int(kwargs['dim'])]) ** kwargs['power'], 
                   'sin' : lambda *grids, **kwargs: np.sin(kwargs['freq'] * grids[int(kwargs['dim'])]) ** kwargs['power']}
    test_eval = Custom_Evaluator(test_lambdas, eval_fun_params_labels = ['freq', 'dim', 'power'], use_factors_grids = True)

    trig_tokens = Token_family('Trigonometric')
    trig_names = ['sin', 'cos']
    trig_tokens.set_status(unique_specific_token=True, unique_token_type=True, 
                           meaningful = False, unique_for_right_part = False)
    trig_token_params = OrderedDict([('power', (1, 1)), ('freq', (0.95, 1.05)), ('dim', (0, 0))])
    trig_equal_params = {'power' : 0, 'freq' : 0.05, 'dim' : 0}
    trig_tokens.set_params(trig_names, trig_token_params, trig_equal_params)
    trig_tokens.set_evaluator(test_eval, [])
    
    global_var.tensor_cache.use_structural()

    pool = TF_Pool([trig_tokens])
    pool.families_cardinality()    
    _, test_factor = pool.create()
    test_factor.evaluate()
    
    test_lambdas = lambda *grids, **kwargs: np.cos(kwargs['freq'] * grids[int(kwargs['dim'])]) ** kwargs['power']
    test_eval = Custom_Evaluator(test_lambdas, eval_fun_params_labels = ['freq', 'dim', 'power'], use_factors_grids = True)    
    trig_tokens.set_evaluator(test_eval, [])

    pool = TF_Pool([trig_tokens])
    pool.families_cardinality()    
    _, test_factor = pool.create()
    test_factor.evaluate()
    
    
    
#    test_factor = 
    
예제 #3
0
def create_pool(data : Union[np.ndarray, list, tuple], time_axis : int = 0, boundary : int = 0, 
                variable_names = ['u',], derivs = None, max_deriv_order = 1, additional_tokens = [], 
                coordinate_tensors = None, memory_for_cache = 5, data_fun_pow : int = 1):
    assert (isinstance(derivs, list) and isinstance(derivs[0], np.ndarray)) or derivs is None
    if isinstance(data, np.ndarray):
        data = [data,]

    set_grids = coordinate_tensors is not None
    set_grids_among_tokens = coordinate_tensors is not None
    if derivs is None:
        if len(data) != len(variable_names):
            print(len(data), len(variable_names))
            raise ValueError('Mismatching lengths of data tensors and the names of the variables')
    else:
        if not (len(data) == len(variable_names) == len(derivs)): 
            raise ValueError('Mismatching lengths of data tensors, names of the variables and passed derivatives')            
    data_tokens = []
    for data_elem_idx, data_tensor in enumerate(data):
        assert isinstance(data_tensor, np.ndarray), 'Input data must be in format of numpy ndarrays or iterable (list or tuple) of numpy arrays'
        entry = Input_data_entry(var_name = variable_names[data_elem_idx],
                                 data_tensor = data_tensor, 
                                 coord_tensors = coordinate_tensors)
        derivs_tensor = derivs[data_elem_idx] if derivs is not None else None
        entry.set_derivatives(deriv_tensors = derivs_tensor, max_order = max_deriv_order)
        print(f'set grids parameter is {set_grids}')
        entry.use_global_cache(grids_as_tokens = set_grids_among_tokens,
                               set_grids=set_grids, memory_for_cache=memory_for_cache, boundary=boundary)
        set_grids = False; set_grids_among_tokens = False
        
        entry_token_family = TokenFamily(entry.var_name, family_of_derivs = True)
        entry_token_family.set_status(unique_specific_token=False, unique_token_type=False, 
                             s_and_d_merged = False, meaningful = True)     
        entry_token_family.set_params(entry.names, OrderedDict([('power', (1, data_fun_pow))]),
                                      {'power' : 0}, entry.d_orders)
        entry_token_family.set_evaluator(simple_function_evaluator, [])
            
        print(entry_token_family.tokens)
        data_tokens.append(entry_token_family)
 
    if isinstance(additional_tokens, list):
        if not all([isinstance(tf, (TokenFamily, Prepared_tokens)) for tf in additional_tokens]):
            raise TypeError(f'Incorrect type of additional tokens: expected list or TokenFamily/Prepared_tokens - obj, instead got list of {type(additional_tokens[0])}')                
    elif isinstance(additional_tokens, (TokenFamily, Prepared_tokens)):
        additional_tokens = [additional_tokens,]
    else:
        print(isinstance(additional_tokens, Prepared_tokens))
        raise TypeError(f'Incorrect type of additional tokens: expected list or TokenFamily/Prepared_tokens - obj, instead got {type(additional_tokens)}')
    return TF_Pool(data_tokens + [tf if isinstance(tf, TokenFamily) else tf.token_family 
                                  for tf in additional_tokens])
예제 #4
0
def test_equation():
    '''
    
    Use trigonometric identity sin^2 (x) + cos^2 (x) = 1 to generate data, with it: initialize the equation, 
    equation splitting & weights discovery? output format, latex format. Additionally, test evaluator for trigonometric functions
    
    '''
    global_var.init_caches(set_grids=True)
    global_var.tensor_cache.memory_usage_properties(obj_test_case=np.ones((10,10,10)), mem_for_cache_frac = 25)  
    
    from epde.eq_search_strategy import Strategy_director
    from epde.operators.ea_stop_criteria import Iteration_limit
    
    director = Strategy_director(Iteration_limit, {'limit' : 100})
    director.strategy_assembly()
    
    x = np.linspace(0, 2*np.pi, 100)
    global_var.grid_cache.memory_usage_properties(obj_test_case=x, mem_for_cache_frac = 25)  
    upload_grids(x, global_var.grid_cache)
    names = ['sin', 'cos'] # simple case: single parameter of a token - power
    
    trig_tokens = Token_family('trig')    
    trig_tokens.set_status(unique_specific_token=False, unique_token_type=False, meaningful = True, 
                           unique_for_right_part = False)
    
    equal_params = {'power' : 0, 'freq' : 0.2, 'dim' : 0}
    
    trig_params = OrderedDict([('power', (1., 1.)), ('freq', (0.5, 1.5)), ('dim', (0., 0.))])
    trig_tokens.set_params(names, trig_params, equal_params)
    trig_tokens.set_evaluator(trigonometric_evaluator)  
    
    set_family(trig_tokens, names, trig_params, equal_params, trigonometric_evaluator, True)
    pool = TF_Pool([trig_tokens,])
    
    eq1 = Equation(pool , basic_structure = [], 
                   terms_number = 3, max_factors_in_term = 2)   # Задать возможности выбора вероятностей кол-ва множителей
    director.constructor.strategy.modify_block_params(block_label = 'rps1', param_label = 'sparsity', 
                                                             value = 1., suboperator_sequence = ['eq_level_rps', 'fitness_calculation', 'sparsity'])

    director._constructor._strategy.apply_block('rps1', 
                                                {'population' : [eq1,], 'separate_vars' : []})
    
    eq1.described_variables
    eq1.evaluate(normalize = False, return_val = True)
    eq1.weights_internal
    eq1.weights_final
    print(eq1.text_form)
예제 #5
0
def test_term():
    '''
    Check both (random and determined) ways to initialize the term, check correctness of term value evaluation & terms equality, 
    output format, latex format.

    '''

    x = np.linspace(0, 2*np.pi, 100)   
    global_var.init_caches(set_grids=True)
    global_var.tensor_cache.memory_usage_properties(obj_test_case=x, mem_for_cache_frac = 5)  
    global_var.grid_cache.memory_usage_properties(obj_test_case=x, mem_for_cache_frac = 5)  
    upload_grids(x, global_var.grid_cache)    
    mock_equal_params = {'not_power' : 0, 'power' : 0}
    mock_params = {'not_power' : (1, 4), 'power' : (1, 1)}

    f1 = Token_family('type_1')
    f2 = Token_family('type_2')
    f3 = Token_family('type_3')
    set_family(f1, names = ['t1_1', 't1_2', 't1_3'], params = mock_params, 
               equal_params=mock_equal_params, evaluator=mock_eval_function, meaningful=True);
    set_family(f2, names = ['t2_1', 't2_2', 't2_3', 't2_4'], params = mock_params, 
               equal_params=mock_equal_params, evaluator=mock_eval_function, meaningful=False); 
    set_family(f3, names = ['t3_1', 't3_2'], params = mock_params, 
               equal_params=mock_equal_params, evaluator=mock_eval_function, meaningful=True)
    
    pool = TF_Pool([f1, f2, f3])
    test_term_1 = Term(pool)

    print(test_term_1.name)
    print('avalable', test_term_1.available_tokens[0].tokens)
#    assert test_term_1.available_tokens[0].tokens == names
#    assert type(test_term_1) == Term

    test_term_2 = Term(pool, passed_term = 't1_1')
    print(test_term_2.name)
    print(test_term_2.solver_form)
    assert test_term_2.solver_form[1] is None and test_term_2.solver_form[2] == 1
예제 #6
0
def test_ode_auto():
    '''
    
    В этой задаче мы ищем уравнение u sin(x) + u' cos(x) = 1 по его решению: u = sin(x) + C cos(x), 
    где у частного решения C = 1.3.
    
    Задаём x - координатную ось по времени; ts - временной ряд условных измерений
    ff_filename - имя файла, куда сохраняется временной ряд; output_file_name - имя файла для производных
    step - шаг по времени
    '''

    #    delim = '/' if sys.platform == 'linux' else '\\'

    x = np.linspace(0, 4 * np.pi, 1000)
    print('path:', sys.path)
    ts = np.load(
        '/media/mike_ubuntu/DATA/EPDE_publication/tests/system/Test_data/fill366.npy'
    )  # tests/system/
    new_derivs = True

    ff_filename = '/media/mike_ubuntu/DATA/EPDE_publication/tests/system/Test_data/smoothed_ts.npy'
    output_file_name = '/media/mike_ubuntu/DATA/EPDE_publication/tests/system/Test_data/derivs.npy'
    step = x[1] - x[0]
    '''

    '''

    max_order = 1  # presence of the 2nd order derivatives leads to equality u = d^2u/dx^2 on this data (elaborate)

    if new_derivs:
        _, derivs = Preprocess_derivatives(ts,
                                           data_name=ff_filename,
                                           output_file_name=output_file_name,
                                           steps=(step, ),
                                           smooth=False,
                                           sigma=1,
                                           max_order=max_order)
        ts_smoothed = np.load(ff_filename)
    else:
        try:
            ts_smoothed = np.load(ff_filename)
            derivs = np.load(output_file_name)
        except FileNotFoundError:
            _, derivs = Preprocess_derivatives(
                ts,
                data_name=ff_filename,
                output_file_name=output_file_name,
                steps=(step, ),
                smooth=False,
                sigma=1,
                max_order=max_order)
            ts_smoothed = np.load(ff_filename)

    global_var.init_caches(set_grids=True)
    global_var.tensor_cache.memory_usage_properties(obj_test_case=ts,
                                                    mem_for_cache_frac=5)
    global_var.grid_cache.memory_usage_properties(obj_test_case=x,
                                                  mem_for_cache_frac=5)

    print(type(derivs))

    boundary = 10
    upload_grids(x[boundary:-boundary], global_var.grid_cache)
    u_derivs_stacked = prepare_var_tensor(ts_smoothed,
                                          derivs,
                                          time_axis=0,
                                          boundary=boundary)

    u_names, u_deriv_orders = Define_Derivatives('u', 1, 1)
    u_names = u_names
    u_deriv_orders = u_deriv_orders
    upload_simple_tokens(u_names, global_var.tensor_cache, u_derivs_stacked)

    u_tokens = Token_family('Function', family_of_derivs=True)
    u_tokens.set_status(unique_specific_token=False,
                        unique_token_type=False,
                        s_and_d_merged=False,
                        meaningful=True,
                        unique_for_right_part=False)
    u_token_params = OrderedDict([('power', (1, 1))])
    u_equal_params = {'power': 0}
    u_tokens.set_params(u_names, u_token_params, u_equal_params,
                        u_deriv_orders)
    u_tokens.set_evaluator(simple_function_evaluator, [])

    grid_names = [
        't',
    ]
    grid_tokens = Token_family('Grids')
    grid_tokens.set_status(unique_specific_token=True,
                           unique_token_type=True,
                           s_and_d_merged=False,
                           meaningful=False,
                           unique_for_right_part=False)
    grid_token_params = OrderedDict([('power', (1, 1))])
    grid_equal_params = {'power': 0}
    grid_tokens.set_params(grid_names, grid_token_params, grid_equal_params)
    grid_tokens.set_evaluator(simple_function_evaluator, [])
    #
    trig_tokens = Token_family('Trigonometric')
    trig_names = ['sin', 'cos']
    trig_tokens.set_status(unique_specific_token=True,
                           unique_token_type=True,
                           meaningful=False,
                           unique_for_right_part=False)
    trig_token_params = OrderedDict([('power', (1, 1)), ('freq', (0.95, 1.05)),
                                     ('dim', (0, 0))])
    trig_equal_params = {'power': 0, 'freq': 0.05, 'dim': 0}
    trig_tokens.set_params(trig_names, trig_token_params, trig_equal_params)
    trig_tokens.set_evaluator(trigonometric_evaluator, [])

    upload_simple_tokens(grid_names, global_var.tensor_cache, [
        x[boundary:-boundary],
    ])
    global_var.tensor_cache.use_structural()

    pool = TF_Pool([u_tokens, trig_tokens])  # grid_tokens,
    pool.families_cardinality()
    '''
    Используем базовый эволюционный оператор.
    '''
    #    test_strat = Strategy_director(Iteration_limit, {'limit' : 300})
    test_strat = Strategy_director_solver(Iteration_limit, {'limit': 50})
    test_strat.strategy_assembly()

    #    test_system = SoEq(pool = pool, terms_number = 4, max_factors_in_term=2, sparcity = (0.1,))
    #    test_system.set_eq_search_evolutionary(director.constructor.operator)
    #    test_system.create_equations(population_size=16, eq_search_iters=300)

    #    tokens=[h_tokens, trig_tokens]
    '''
    Настраиваем генератор новых уравнений, которые будут составлять популяцию для 
    алгоритма многокритериальной оптимизации.
    '''
    pop_constructor = operators.systems_population_constructor(
        pool=pool,
        terms_number=6,
        max_factors_in_term=2,
        eq_search_evo=test_strat.constructor.strategy,
        sparcity_interval=(0.0, 0.5))
    '''
    Задаём объект многокритериального оптимизатора, эволюционный оператор и задаём лучшие возможные 
    значения целевых функций.
    '''
    optimizer = moeadd_optimizer(pop_constructor,
                                 3,
                                 3,
                                 delta=1 / 50.,
                                 neighbors_number=3,
                                 solution_params={})
    evo_operator = operators.sys_search_evolutionary_operator(
        operators.mixing_xover, operators.gaussian_mutation)

    optimizer.set_evolutionary(operator=evo_operator)
    best_obj = np.concatenate((np.ones([
        1,
    ]),
                               np.zeros(shape=len([
                                   1 for token_family in pool.families
                                   if token_family.status['meaningful']
                               ]))))
    optimizer.pass_best_objectives(*best_obj)

    def simple_selector(sorted_neighbors, number_of_neighbors=4):
        return sorted_neighbors[:number_of_neighbors]

    '''
    Запускаем оптимизацию
    '''

    optimizer.optimize(
        simple_selector, 0.95, (4, ), 100,
        0.75)  # Простая форма искомого уравнения найдется и за 10 итераций

    for idx in range(len(optimizer.pareto_levels.levels)):
        print('\n')
        print(f'{idx}-th non-dominated level')
        [
            print(solution.structure[0].text_form, solution.evaluate())
            for solution in optimizer.pareto_levels.levels[idx]
        ]

    raise NotImplementedError
    '''
예제 #7
0
class SoEq(Complex_Structure, moeadd.moeadd_solution):
    # __slots__ = ['tokens_indep', 'tokens_dep', 'equation_number']
    def __init__(self, pool, terms_number, max_factors_in_term, sparsity = None, eq_search_iters = 100):
        self.tokens_indep = TF_Pool(pool.families_meaningful) #[family for family in token_families if family.status['meaningful']]
        self.tokens_dep = TF_Pool(pool.families_supplementary) #[family for family in token_families if not family.status['meaningful']]
        self.equation_number = np.size(self.tokens_indep.families_cardinality())
        
        if sparsity is not None: self.vals = sparsity 
        self.max_terms_number = terms_number; self.max_factors_in_term = max_factors_in_term
        self.moeadd_set = False; self.eq_search_operator_set = False# ; self.evaluated = False
        self.def_eq_search_iters = eq_search_iters
        
    def use_default_objective_function(self):
        from epde.eq_mo_objectives import system_discrepancy, system_complexity_by_terms, system_complexity_by_factors
        self.set_objective_functions([system_discrepancy, system_complexity_by_factors])
        
    def set_objective_functions(self, obj_funs):
        '''
        Method to set the objective functions to evaluate the "quality" of the system of equations.
        
        Parameters:
        -----------
            obj_funs - callable or list of callables;
            function/functions to evaluate quality metrics of system of equations. Can return a single 
            metric (for example, quality of the process modelling with specific system), or 
            a list of metrics (for example, number of terms for each equation in the system).
            The function results will be flattened after their application. 
            
        '''
        assert callable(obj_funs) or all([callable(fun) for fun in obj_funs])
        self.obj_funs = obj_funs
#        import time
#        print(len(self.obj_funs))
#        time.sleep(10)
    
    def set_eq_search_evolutionary(self, evolutionary):
#        raise NotImplementedError('In current version, the evolutionary operatorshall be taken from global variables')
#        assert type(evolutionary.coeff_calculator) != type(None), 'Defined evolutionary operator lacks coefficient calculator'
        self.eq_search_evolutionary_strategy = evolutionary
        self.eq_search_operator_set = True
        
    def create_equations(self, population_size = 16, sparsity = None, eq_search_iters = None, EA_kwargs = dict()):
#        if type(eq_search_iters) == type(None) and type(self.def_eq_search_iters) == type(None):
#            raise ValueError('Number of iterations is not defied both in method parameter or in object attribute')
        assert self.eq_search_operator_set
        
        if eq_search_iters is None: eq_search_iters = self.def_eq_search_iters
        if sparsity is None: 
            sparsity = self.vals
        else:
            self.vals = sparsity

        self.population_size = population_size
        self.eq_search_evolutionary_strategy.modify_block_params(block_label = 'truncation', 
                                                                 param_label = 'population_size', 
                                                                 value = population_size)
        
        self.structure = []; self.eq_search_iters = eq_search_iters
        token_selection = self.tokens_indep
        
        self.vars_to_describe = {token_family.type for token_family in self.tokens_dep.families}
        self.vars_to_describe = self.vars_to_describe.union({token_family.type for token_family in self.tokens_indep.families})
        self.separated_vars = set()
        
        for eq_idx in range(self.equation_number):
            current_tokens = token_selection + self.tokens_dep
#            print('Equation index', eq_idx, self.vals)
            self.eq_search_evolutionary_strategy.modify_block_params(block_label = 'rps1', param_label = 'sparsity', 
                                                                     value = self.vals[eq_idx], suboperator_sequence = ['eq_level_rps', 'fitness_calculation', 'sparsity'])#(sparsity_value = self.vals[eq_idx])
            self.eq_search_evolutionary_strategy.modify_block_params(block_label = 'rps2', param_label = 'sparsity', 
                                                                     value = self.vals[eq_idx], suboperator_sequence = ['eq_level_rps', 'fitness_calculation', 'sparsity'])#(sparsity_value = self.vals[eq_idx])

            cur_equation, cur_eq_operator_error_abs, cur_eq_operator_error_structural = self.optimize_equation(pool = current_tokens, 
                                                  strategy = self.eq_search_evolutionary_strategy, population_size = self.population_size,
                                                  separate_vars = self.separated_vars, EA_kwargs = EA_kwargs)
            self.vars_to_describe.difference_update(cur_equation.described_variables)
            self.separated_vars.add(frozenset(cur_equation.described_variables))

            self.structure.append(cur_equation)
#            self.single_vars_in_equation.update()
#            cache.clear(full = False)
            if not eq_idx == self.equation_number - 1:
                global_var.tensor_cache.change_variables(cur_eq_operator_error_abs, 
                                                         cur_eq_operator_error_structural)
#            for idx, _ in enumerate(token_selection):
#                 token_selection[idx].change_variables(cur_eq_operator_error)               
        
#        obj_funs = np.array(flatten([func(self) for func in self.obj_funs]))
#        np.array([self.evaluate(normalize = False),] + [eq.L0_norm for eq in self.structure])
        moeadd.moeadd_solution.__init__(self, self.vals, self.obj_funs) # , return_val = True, self) super(
        self.moeadd_set = True
            
    def optimize_equation(self, pool, strategy, population_size, basic_terms : list = [], 
                          separate_vars : set = None, EA_kwargs = dict()):
        population = [Equation(pool, basic_terms, self.max_terms_number, self.max_factors_in_term) 
                        for i in range(population_size)]
        EA_kwargs['separate_vars'] = separate_vars
        strategy.run(initial_population = population, EA_kwargs = EA_kwargs)
        result = strategy.result
        
        return result[0], result[0].evaluate(normalize = False, return_val=True)[0], result[0].evaluate(normalize = True, return_val=True)[0]
        
    @staticmethod
    def equation_opt_iteration(population, evol_operator, population_size, iter_index, separate_vars, strict_restrictions = True):
        for equation in population:
            if equation.described_variables in separate_vars:
                equation.penalize_fitness(coeff = 0.)           
        population = Population_Sort(population)
        population = population[:population_size]
        gc.collect()
        population = evol_operator.apply(population, separate_vars)
        return population
        
    def evaluate(self, normalize = True):
        if len(self.structure) == 1:
            value = self.structure[0].evaluate(normalize = normalize, return_val = True)[0]
        else:
            value = np.sum([equation.evaluate(normalize, return_val = True)[0] for equation in self.structure])
        value = np.sum(np.abs(value))
        return value

    @property
    def obj_fun(self):
#        print('objective functions:', self.obj_funs)
#        print('objective function values:', [func(self) for func in self.obj_funs], flatten([func(self) for func in self.obj_funs]))
        return np.array(flatten([func(self) for func in self.obj_funs]))
        
    def __call__(self):
        assert self.moeadd_set, 'The structure of the equation is not defined, therefore no moeadd operations can be called'
        return self.obj_fun

    @property
    def text_form(self):
        form = ''
        if len(self.structure) > 1:
            for eq_idx, equation in enumerate(self.structure):
                if eq_idx == 0:
                    form += ' / ' + equation.text_form + '\n'                                        
                elif eq_idx == len(self.structure) - 1:
                    form += ' \ ' + equation.text_form + '\n'
                else:
                    form += ' | ' + equation.text_form + '\n'
        else:
            form += self.structure[0].text_form + '\n'
        return form

    def __eq__(self, other):
        assert self.moeadd_set, 'The structure of the equation is not defined, therefore no moeadd operations can be called'        
#        eps = 1e-9
        return (all([any([other_elem == self_elem for other_elem in other.structure]) for self_elem in self.structure]) and 
                all([any([other_elem == self_elem for self_elem in self.structure]) for other_elem in other.structure]) and 
                len(other.structure) == len(self.structure)) or all(np.isclose(self.obj_fun, other.obj_fun))        

    @property
    def latex_form(self):
        form = r"\begin{eqnarray*}"
        for equation in self.structure:
            form += equation.latex_form + r", \\ "
        form += r"\end{eqnarray*}"
        
            
    def __hash__(self):
        return hash(tuple(self.vals))
        
    def __deepcopy__(self, memo = None):
        clss = self.__class__
        new_struct = clss.__new__(clss)
        memo[id(self)] = new_struct
        
        new_struct.__dict__.update(self.__dict__)
        
        for k in self.__slots__:
                try:
                    if not isinstance(k, list):
                        setattr(new_struct, k, copy.deepcopy(getattr(self, k), memo))
                    else:
                        temp = []
                        for elem in getattr(self, k):
                            temp.append(copy.deepcopy(elem, memo))
                        setattr(new_struct, k, temp)                            
                except AttributeError:
                    pass     

        for idx, eq in enumerate(self.structure):
            eq.copy_properties_to(new_struct)
        return new_struct
    
    def solver_params(self, full_domain):
        '''
        Returns solver form, grid and boundary conditions
        '''
        if len(self.structure) > 1:
            raise Exception('Solver form is defined only for a "system", that contains a single equation.')
        else:
            form = self.structure[0].solver_form()
            grid = solver_formed_grid()
            bconds = self.structure[0].boundary_conditions(full_domain = full_domain)
            return form, grid, bconds
예제 #8
0
def test_solver_forms():
    from epde.cache.cache import upload_simple_tokens, upload_grids, prepare_var_tensor
    from epde.prep.derivatives import Preprocess_derivatives
    from epde.supplementary import Define_Derivatives
    from epde.evaluators import simple_function_evaluator, trigonometric_evaluator
    from epde.operators.ea_stop_criteria import Iteration_limit
    from epde.eq_search_strategy import Strategy_director
    
#    delim = '/' if sys.platform == 'linux' else '\\'
    
    x = np.linspace(0, 4*np.pi, 1000)
    print('path:', sys.path)
    ts = np.load('/media/mike_ubuntu/DATA/EPDE_publication/tests/system/Test_data/fill366.npy') # tests/system/
    new_derivs = True
    
    ff_filename = '/media/mike_ubuntu/DATA/EPDE_publication/tests/system/Test_data/smoothed_ts.npy'
    output_file_name = '/media/mike_ubuntu/DATA/EPDE_publication/tests/system/Test_data/derivs.npy'
    step = x[1] - x[0]
    
    '''

    '''
    
    max_order = 1 # presence of the 2nd order derivatives leads to equality u = d^2u/dx^2 on this data (elaborate)
    
    if new_derivs:
        _, derivs = Preprocess_derivatives(ts, data_name = ff_filename, 
                                output_file_name = output_file_name,
                                steps = (step,), smooth = False, sigma = 1, max_order = max_order)
        ts_smoothed = np.load(ff_filename)        
    else:
        try:
            ts_smoothed = np.load(ff_filename)
            derivs = np.load(output_file_name)
        except FileNotFoundError:
            _, derivs = Preprocess_derivatives(ts, data_name = ff_filename, 
                                    output_file_name = output_file_name,
                                    steps = (step,), smooth = False, sigma = 1, max_order = max_order)            
            ts_smoothed = np.load(ff_filename) 
    for i in np.arange(10):
        global_var.init_caches(set_grids=True)
        global_var.tensor_cache.memory_usage_properties(obj_test_case=ts, mem_for_cache_frac = 5)  
        global_var.grid_cache.memory_usage_properties(obj_test_case=x, mem_for_cache_frac = 5)
    
        
        print(type(derivs))
    
        boundary = 10
        upload_grids(x[boundary:-boundary], global_var.grid_cache)   
        u_derivs_stacked = prepare_var_tensor(ts_smoothed, derivs, time_axis = 0, boundary = boundary)
        
        u_names, u_deriv_orders = Define_Derivatives('u', 1, 1) 
        u_names = u_names; u_deriv_orders = u_deriv_orders 
        upload_simple_tokens(u_names, global_var.tensor_cache, u_derivs_stacked)
        
        u_tokens = Token_family('Function', family_of_derivs = True)
        u_tokens.set_status(unique_specific_token=False, unique_token_type=False, s_and_d_merged = False, 
                            meaningful = True, unique_for_right_part = False)
        u_token_params = OrderedDict([('power', (1, 1))])
        u_equal_params = {'power' : 0}
        u_tokens.set_params(u_names, u_token_params, u_equal_params, u_deriv_orders)
        u_tokens.set_evaluator(simple_function_evaluator, [])
    
    
        grid_names = ['t',]    
        upload_simple_tokens(grid_names, global_var.tensor_cache, [x[boundary:-boundary],])    
        global_var.tensor_cache.use_structural()
    
    
        grid_tokens = Token_family('Grids')
        grid_tokens.set_status(unique_specific_token=True, unique_token_type=True, s_and_d_merged = False, 
                            meaningful = True, unique_for_right_part = False)
        grid_token_params = OrderedDict([('power', (1, 1))])
        grid_equal_params = {'power' : 0}
        grid_tokens.set_params(grid_names, grid_token_params, grid_equal_params)
        grid_tokens.set_evaluator(simple_function_evaluator, [])
        
        trig_tokens = Token_family('Trigonometric')
        trig_names = ['sin', 'cos']
        trig_tokens.set_status(unique_specific_token=True, unique_token_type=True, 
                               meaningful = False, unique_for_right_part = False)
        trig_token_params = OrderedDict([('power', (1, 1)), ('freq', (0.95, 1.05)), ('dim', (0, 0))])
        trig_equal_params = {'power' : 0, 'freq' : 0.05, 'dim' : 0}
        trig_tokens.set_params(trig_names, trig_token_params, trig_equal_params)
        trig_tokens.set_evaluator(trigonometric_evaluator, [])
    
        pool = TF_Pool([grid_tokens, u_tokens, trig_tokens])
        pool.families_cardinality()
    
        test_strat = Strategy_director(Iteration_limit, {'limit' : 300})
        test_strat.strategy_assembly()        
        
        eq1 = Equation(pool , basic_structure = [], 
                       terms_number = 6, max_factors_in_term = 2)   # Задать возможности выбора вероятностей кол-ва множителей
        test_strat.constructor.strategy.modify_block_params(block_label = 'rps1', param_label = 'sparsity', 
                                                                 value = 0.1, suboperator_sequence = ['eq_level_rps', 'fitness_calculation', 'sparsity'])
    
        test_strat._constructor._strategy.apply_block('rps1', 
                                                    {'population' : [eq1,], 'separate_vars' : []})
        
        print('text form:', eq1.text_form)
    #    print('solver form:', eq1.solver_form())
        print(eq1.max_deriv_orders())
    raise Exception('Test exception')