Skip to content

Commit

Permalink
Release branch actualization
Browse files Browse the repository at this point in the history
  • Loading branch information
Maslyaev committed Nov 2, 2023
1 parent 24af5aa commit 78315f5
Show file tree
Hide file tree
Showing 16 changed files with 451 additions and 254 deletions.
6 changes: 6 additions & 0 deletions epde/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from .interface.interface import EpdeSearch
from .interface.logger import Logger
from .interface.equation_translator import translate_equation

from .interface.prepared_tokens import CustomTokens, CacheStoredTokens, ExternalDerivativesTokens
from .interface.prepared_tokens import GridTokens, TrigonometricTokens, PhasedSine1DTokens
57 changes: 1 addition & 56 deletions epde/evaluators.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,20 +134,14 @@ def phased_sine(*grids, **kwargs):

def phased_sine_1d(*grids, **kwargs):
coordwise_elems = kwargs['freq'] * 2*np.pi*(grids[0] + kwargs['phase']/kwargs['freq'])
# for dim in range(len(grids))]
return np.power(np.sin(coordwise_elems), kwargs['power'])

# def grid_eval_fun(*grids, **kwargs):
# return np.power(grids[int(kwargs['dim'])], kwargs['power'])

def const_eval_fun(*grids, **kwargs):
return np.full_like(a=grids[0], fill_value=kwargs['value'])


def const_grad_fun(*grids, **kwargs):
return np.zeros_like(a=grids[0])


def get_velocity_common(*grids, **kwargs):
a = [kwargs['p' + str(idx*3+1)] * grids[0]**2 + kwargs['p' + str(idx*3 + 2)] * grids[0] + kwargs['p' + str(idx*3 + 3)] for idx in range(5)]
alpha = np.exp(a[0] * grids[1] + a[1]); beta = a[2] * grids[1]**2 + a[3] * grids[1] + a[4]
Expand All @@ -157,115 +151,66 @@ def velocity_heating_eval_fun(*grids, **kwargs):
'''
Assumption of the velocity field for two-dimensional heat equation with convetion.
'''
# a = [kwargs['p' + str(idx*3+1)] * grids[0]**2 + kwargs['p' + str(idx*3 + 2)] * grids[0] + kwargs['p' + str(idx*3 + 3)] for idx in range(5)]
# alpha = np.exp(a[0] * grids[1] + a[1]); beta = a[2] * grids[1]**2 + a[3] * grids[1] + a[4]
alpha, beta = get_velocity_common(*grids, **kwargs)
return alpha * beta

# Proof of concept, if works properly, replace with permutations approach to gradient construction


def vhef_grad_1(*grids, **kwargs):
# a = [kwargs['p' + str(idx*3+1)] * grids[0]**2 + kwargs['p' + str(idx*3 + 2)] * grids[0] + kwargs['p' + str(idx*3 + 3)] for idx in range(5)]
# alpha = np.exp(a[0] * grids[1] + a[1]); beta = a[2] * grids[1]**2 + a[3] * grids[1] + a[4]
alpha, beta = get_velocity_common(*grids, **kwargs)
return grids[0]**2 * grids[1] * alpha * beta


def vhef_grad_2(*grids, **kwargs):
# a = [kwargs['p' + str(idx*3+1)] * grids[0]**2 + kwargs['p' + str(idx*3 + 2)] * grids[0] + kwargs['p' + str(idx*3 + 3)] for idx in range(5)]
# alpha = np.exp(a[0] * grids[1] + a[1]); beta = a[2] * grids[1]**2 + a[3] * grids[1] + a[4]
alpha, beta = get_velocity_common(*grids, **kwargs)
return grids[0] * grids[1] * alpha * beta


def vhef_grad_3(*grids, **kwargs):
# a = [kwargs['p' + str(idx*3+1)] * grids[0]**2 + kwargs['p' + str(idx*3 + 2)] * grids[0] + kwargs['p' + str(idx*3 + 3)] for idx in range(5)]
# alpha = np.exp(a[0] * grids[1] + a[1]); beta = a[2] * grids[1]**2 + a[3] * grids[1] + a[4]
alpha, beta = get_velocity_common(*grids, **kwargs)
return grids[1] * alpha * beta


def vhef_grad_4(*grids, **kwargs):
# a = [kwargs['p' + str(idx*3+1)] * grids[0]**2 + kwargs['p' + str(idx*3 + 2)] * grids[0] + kwargs['p' + str(idx*3 + 3)] for idx in range(5)]
# alpha = np.exp(a[0] * grids[1] + a[1]); beta = a[2] * grids[1]**2 + a[3] * grids[1] + a[4]
alpha, beta = get_velocity_common(*grids, **kwargs)
return grids[0]**2 * alpha * beta


def vhef_grad_5(*grids, **kwargs):
# a = [kwargs['p' + str(idx*3+1)] * grids[0]**2 + kwargs['p' + str(idx*3 + 2)] * grids[0] + kwargs['p' + str(idx*3 + 3)] for idx in range(5)]
# alpha = np.exp(a[0] * grids[1] + a[1]); beta = a[2] * grids[1]**2 + a[3] * grids[1] + a[4]
alpha, beta = get_velocity_common(*grids, **kwargs)
return grids[0] * alpha * beta


def vhef_grad_6(*grids, **kwargs):
# a = [kwargs['p' + str(idx*3+1)] * grids[0]**2 + kwargs['p' + str(idx*3 + 2)] * grids[0] + kwargs['p' + str(idx*3 + 3)] for idx in range(5)]
# alpha = np.exp(a[0] * grids[1] + a[1]); beta = a[2] * grids[1]**2 + a[3] * grids[1] + a[4]
alpha, beta = get_velocity_common(*grids, **kwargs)
return alpha * beta


def vhef_grad_7(*grids, **kwargs):
# a = [kwargs['p' + str(idx*3+1)] * grids[0]**2 + kwargs['p' + str(idx*3 + 2)] * grids[0] + kwargs['p' + str(idx*3 + 3)] for idx in range(5)]
# alpha = np.exp(a[0] * grids[1] + a[1]); beta = a[2] * grids[1]**2 + a[3] * grids[1] + a[4]
alpha, beta = get_velocity_common(*grids, **kwargs)
return grids[0]**2 * grids[1]**2 * alpha


def vhef_grad_8(*grids, **kwargs):
# a = [kwargs['p' + str(idx*3+1)] * grids[0]**2 + kwargs['p' + str(idx*3 + 2)] * grids[0] + kwargs['p' + str(idx*3 + 3)] for idx in range(5)]
# alpha = np.exp(a[0] * grids[1] + a[1]); beta = a[2] * grids[1]**2 + a[3] * grids[1] + a[4]
alpha, beta = get_velocity_common(*grids, **kwargs)
return grids[0] * grids[1]**2 * alpha


def vhef_grad_9(*grids, **kwargs):
# a = [kwargs['p' + str(idx*3+1)] * grids[0]**2 + kwargs['p' + str(idx*3 + 2)] * grids[0] + kwargs['p' + str(idx*3 + 3)] for idx in range(5)]
# alpha = np.exp(a[0] * grids[1] + a[1]); beta = a[2] * grids[1]**2 + a[3] * grids[1] + a[4]
alpha, beta = get_velocity_common(*grids, **kwargs)
return grids[1]**2 * alpha


def vhef_grad_10(*grids, **kwargs):
# a = [kwargs['p' + str(idx*3+1)] * grids[0]**2 + kwargs['p' + str(idx*3 + 2)] * grids[0] + kwargs['p' + str(idx*3 + 3)] for idx in range(5)]
# alpha = np.exp(a[0] * grids[1] + a[1]); beta = a[2] * grids[1]**2 + a[3] * grids[1] + a[4]
alpha, beta = get_velocity_common(*grids, **kwargs)
return grids[0]**2 * grids[1] * alpha


def vhef_grad_11(*grids, **kwargs):
# a = [kwargs['p' + str(idx*3+1)] * grids[0]**2 + kwargs['p' + str(idx*3 + 2)] * grids[0] + kwargs['p' + str(idx*3 + 3)] for idx in range(5)]
# alpha = np.exp(a[0] * grids[1] + a[1]); beta = a[2] * grids[1]**2 + a[3] * grids[1] + a[4]
alpha, beta = get_velocity_common(*grids, **kwargs)
return grids[0] * grids[1] * alpha


def vhef_grad_12(*grids, **kwargs):
# a = [kwargs['p' + str(idx*3+1)] * grids[0]**2 + kwargs['p' + str(idx*3 + 2)] * grids[0] + kwargs['p' + str(idx*3 + 3)] for idx in range(5)]
# alpha = np.exp(a[0] * grids[1] + a[1]); beta = a[2] * grids[1]**2 + a[3] * grids[1] + a[4]
alpha, beta = get_velocity_common(*grids, **kwargs)
return grids[1] * alpha


def vhef_grad_13(*grids, **kwargs):
# a = [kwargs['p' + str(idx*3+1)] * grids[0]**2 + kwargs['p' + str(idx*3 + 2)] * grids[0] + kwargs['p' + str(idx*3 + 3)] for idx in range(5)]
# alpha = np.exp(a[0] * grids[1] + a[1]); beta = a[2] * grids[1]**2 + a[3] * grids[1] + a[4]
alpha, beta = get_velocity_common(*grids, **kwargs)
return grids[0]**2 * alpha


def vhef_grad_14(*grids, **kwargs):
# a = [kwargs['p' + str(idx*3+1)] * grids[0]**2 + kwargs['p' + str(idx*3 + 2)] * grids[0] + kwargs['p' + str(idx*3 + 3)] for idx in range(5)]
# alpha = np.exp(a[0] * grids[1] + a[1]); beta = a[2] * grids[1]**2 + a[3] * grids[1] + a[4]
alpha, beta = get_velocity_common(*grids, **kwargs)
return grids[0] * alpha


def vhef_grad_15(*grids, **kwargs):
# a = [kwargs['p' + str(idx*3+1)] * grids[0]**2 + kwargs['p' + str(idx*3 + 2)] * grids[0] + kwargs['p' + str(idx*3 + 3)] for idx in range(5)]
# alpha = np.exp(a[0] * grids[1] + a[1]); beta = a[2] * grids[1]**2 + a[3] * grids[1] + a[4]
alpha, beta = get_velocity_common(*grids, **kwargs)
return alpha

Expand All @@ -287,4 +232,4 @@ def vhef_grad_15(*grids, **kwargs):

velocity_evaluator = CustomEvaluator(velocity_heating_eval_fun, ['p' + str(idx+1) for idx in range(15)])
velocity_grad_evaluators = [CustomEvaluator(component, ['p' + str(idx+1) for idx in range(15)])
for component in vhef_grad]
for component in vhef_grad]
60 changes: 44 additions & 16 deletions epde/interface/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,32 @@
@author: mike_ubuntu
"""
import time
import pickle
import numpy as np
from typing import Union, Callable
from collections import OrderedDict
import warnings

import epde.globals as global_var

from epde.optimizers.builder import StrategyBuilder

from epde.optimizers.moeadd.moeadd import *
from epde.optimizers.moeadd.supplementary import *
from epde.optimizers.moeadd.strategy import MOEADDDirector
from epde.optimizers.moeadd.strategy_elems import MOEADDSectorProcesser
#from epde.optimizers.moeadd.population_constr import SystemsPopulationConstructor as MOEADDSystemPopConstr

from epde.optimizers.single_criterion.optimizer import EvolutionaryStrategy, SimpleOptimizer
# from epde.optimizers.single_criterion.population_constr import SystemsPopulationConstructor as SOSystemPopConstr
from epde.optimizers.single_criterion.strategy import BaselineDirector
from epde.optimizers.single_criterion.supplementary import simple_sorting
# from epde.optimizers.moeadd.strategy_elems import SectorProcesserBuilder

from epde.preprocessing.domain_pruning import DomainPruner
from epde.operators.utils.default_parameter_loader import EvolutionaryParams

from epde.optimizers.builder import StrategyBuilder
from epde.optimizers.single_criterion.optimizer import EvolutionaryStrategy, SimpleOptimizer
from epde.optimizers.moeadd.strategy_elems import MOEADDSectorProcesser
from epde.decorators import BoundaryExclusion

from epde.optimizers.single_criterion.population_constr import SystemsPopulationConstructor as SOSystemPopConstr
from epde.optimizers.moeadd.population_constr import SystemsPopulationConstructor as MOEADDSystemPopConstr
from epde.optimizers.single_criterion.strategy import BaselineDirector
from epde.optimizers.moeadd.strategy import MOEADDDirector

from epde.evaluators import simple_function_evaluator, trigonometric_evaluator
from epde.supplementary import define_derivatives
from epde.cache.cache import upload_simple_tokens, upload_grids, prepare_var_tensor #, np_ndarray_section
Expand Down Expand Up @@ -97,12 +96,8 @@ def use_global_cache(self):
"""
Method for add calculated derivatives in the cache
"""
# print(f'self.data_tensor: {self.data_tensor.shape}')
# print(f'self.derivatives: {self.derivatives.shape}')
derivs_stacked = prepare_var_tensor(self.data_tensor, self.derivatives, time_axis=global_var.time_axis)
# print(f'derivs_stacked: {derivs_stacked.shape}')

# raise Exception('ZUL LUL')
try:
upload_simple_tokens(self.names, global_var.tensor_cache, derivs_stacked)
upload_simple_tokens([self.var_name,], global_var.initial_data_cache, [self.data_tensor,])
Expand Down Expand Up @@ -521,6 +516,31 @@ def create_pool(self, data: Union[np.ndarray, list, tuple], variable_names=['u',
self.set_preprocessor()

data_tokens = []

def latex_form(label, **params):
'''
Parameters
----------
label : str
label of the token, for which we construct the latex form.
**params : dict
dictionary with parameter labels as keys and tuple of parameter values
and their output text forms as values.
Returns
-------
form : str
LaTeX-styled text form of token.
'''
if '/' in label:
label = label[:label.find('x')+1] + '_' + label[label.find('x')+1:]
label = label.replace('d', r'\partial ').replace('/', r'}{')
label = r'\frac{' + label + r'}'

if params['power'][0] > 1:
label = r'\left(' + label + r'\right)^{{{0}}}'.format(params["power"][1])
return label

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 = InputDataEntry(var_name=variable_names[data_elem_idx],
Expand All @@ -530,9 +550,11 @@ def create_pool(self, data: Union[np.ndarray, list, tuple], variable_names=['u',
grid=global_var.grid_cache.get_all()[1], max_order=max_deriv_order)
entry.use_global_cache()

self.set_derivatives(variable=variable_names[data_elem_idx], deriv=entry.derivatives)

self.set_derivatives(variable=variable_names[data_elem_idx], deriv=entry.derivatives)


entry_token_family = TokenFamily(entry.var_name, family_of_derivs=True)
entry_token_family.set_latex_form_constructor(latex_form)
entry_token_family.set_status(demands_equation=True, unique_specific_token=False,
unique_token_type=False, s_and_d_merged=False,
meaningful=True)
Expand Down Expand Up @@ -826,3 +848,9 @@ def predict(self, system : SoEq, boundary_conditions : BoundaryConditions, grid
solution_model = adapter.solve_epde_system(system = system, grids = grid, data = data,
boundary_conditions = boundary_conditions, strategy = strategy)
return solution_model(adapter.convert_grid(grid)).detach().numpy()

def visualize_solutions(self, dimensions:list = [0, 1], **visulaizer_kwargs):
if self.multiobjective_mode:
self.optimizer.plot_pareto(dimensions=dimensions, **visulaizer_kwargs)
else:
raise NotImplementedError('Solution visualization is implemented only for multiobjective mode.')
91 changes: 63 additions & 28 deletions epde/interface/prepared_tokens.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,27 @@ def __init__(self, freq: tuple = (np.pi/2., 2*np.pi), dimensionality=1):
self._token_family = TokenFamily(token_type='trigonometric')
self._token_family.set_status(unique_specific_token=True, unique_token_type=True,
meaningful=False)


def latex_form(label, **params):
'''
Parameters
----------
label : str
label of the token, for which we construct the latex form.
**params : dict
dictionary with parameter labels as keys and tuple of parameter values
and their output text forms as values.
Returns
-------
form : str
LaTeX-styled text form of token.
'''
form = label + r'^{{{0}}}'.format(params["power"][1]) + \
r'(' + params["freq"][1] + r' x_{' + params["dim"][1] + r'})'
return form

self._token_family.set_latex_form_constructor(latex_form)
trig_token_params = OrderedDict([('power', (1, 1)),
('freq', freq),
('dim', (0, dimensionality))])
Expand All @@ -70,45 +90,38 @@ def __init__(self, freq: tuple = (np.pi/2., 2*np.pi), dimensionality=1):
self._token_family.set_evaluator(trigonometric_evaluator, [])


# class PhasedSineTokens(PreparedTokens):
# def __init__(self, freq: tuple = ((np.pi/2., 2*np.pi),), dimensionality = 1):
# assert len(freq) == dimensionality or len(freq) == 1, 'Incorrect params'
# self._token_family = TokenFamily(token_type='phased_sine')
# self._token_family.set_status(unique_specific_token=True, unique_token_type=True,
# meaningful=False)

# if len(freq) == 1: # dimensionality > 1 and
# freqs_matched = tuple([freq[0] for idx in range(dimensionality)])

# sine_token_params = OrderedDict([('power', (1, 1)),#tuple([(1, 1) for idx in range(dimensionality)])),
# ('freq', freqs_matched),
# ('phase', tuple([(0, 1) for idx in range(dimensionality)]))])

# freq_equality_fraction = 0.05 # fraction of allowed frequency interval, that is considered as the same

# freqs_equality = [(freq[idx][1] - freq[idx][0]) / freq_equality_fraction for idx in range(dimensionality)]
# sine_equal_params = {'power': 0, 'freq': freqs_equality,
# 'phase': 0.05}
# self._token_family.set_params(['sine',], sine_token_params, sine_equal_params)
# self._token_family.set_evaluator(phased_sine_evaluator, [])

class PhasedSine1DTokens(PreparedTokens):
def __init__(self, freq: tuple = (np.pi/2., 2*np.pi)):
# assert len(freq) == dimensionality or len(freq) == 1, 'Incorrect params'
self._token_family = TokenFamily(token_type='phased_sine_1d')
self._token_family.set_status(unique_specific_token=True, unique_token_type=True,
meaningful=False)

# if len(freq) == 1: # dimensionality > 1 and
# freqs_matched = tuple([freq[0] for idx in range(dimensionality)])

sine_token_params = OrderedDict([('power', (1, 1)),#tuple([(1, 1) for idx in range(dimensionality)])),
('freq', freq),
('phase', (0., 1.))])

freq_equality_fraction = 0.05 # fraction of allowed frequency interval, that is considered as the same

# freqs_equality = [(freq[idx][1] - freq[idx][0]) / freq_equality_fraction for idx in range(dimensionality)]
def latex_form(label, **params):
'''
Parameters
----------
label : str
label of the token, for which we construct the latex form.
**params : dict
dictionary with parameter labels as keys and tuple of parameter values
and their output text forms as values.
Returns
-------
form : str
LaTeX-styled text form of token.
'''
pwr_sign = r'^{{{0}}}'.format(params["power"][1]) if params["power"][0] != 1 else ''
return label + pwr_sign + r'(' + params["freq"][1] + r' x_{1} + ' \
+ params["phase"][1] + r')'

self._token_family.set_latex_form_constructor(latex_form)
sine_equal_params = {'power': 0, 'freq': (freq[1] - freq[0]) / freq_equality_fraction,
'phase': 0.05}
self._token_family.set_params(['sine',], sine_token_params, sine_equal_params)
Expand All @@ -133,6 +146,28 @@ def __init__(self, labels = ['t',], dimensionality=1):
self._token_family.set_status(unique_specific_token=True, unique_token_type=True,
meaningful=True)

def latex_form(label, **params):
'''
Parameters
----------
label : str
label of the token, for which we construct the latex form.
**params : dict
dictionary with parameter labels as keys and tuple of parameter values
and their output text forms as values.
Returns
-------
form : str
LaTeX-styled text form of token.
'''
form = label
if params['power'][0] > 1:
form = r'(' + form + r')^{{{0}}}'.format(params["power"][0])
return form


self._token_family.set_latex_form_constructor(latex_form)
grid_token_params = OrderedDict([('power', (1, 1)), ('dim', (0, dimensionality))])

grid_equal_params = {'power': 0, 'dim': 0}
Expand Down
Loading

0 comments on commit 78315f5

Please sign in to comment.