Skip to content

Commit c02be9f

Browse files
authored
Merge pull request #56 from Gromwud/main
Cumulitive update
2 parents cd3256e + 55cf1cb commit c02be9f

40 files changed

Lines changed: 2270 additions & 299 deletions

epde/cache/cache.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,8 @@ def set_boundaries(self, boundary_width: Union[int, list, tuple]):
236236
Setting the number of unaccounted elements at the edges
237237
"""
238238
assert '0' in self.memory_default['numpy'].keys(), 'Boundaries should be specified for grid cache.'
239-
shape = self.get('0')[1].shape
239+
shape = self.get('0').shape
240+
self.initial_shape = shape
240241
if isinstance(boundary_width, int):
241242
if any([elem <= 2*boundary_width for elem in shape]):
242243
raise IndexError(f'Mismatching shapes: boundary of {boundary_width} does not fit data of shape {shape}')
@@ -247,6 +248,10 @@ def set_boundaries(self, boundary_width: Union[int, list, tuple]):
247248
raise TypeError(f'Incorrect type of boundaries: {type(boundary_width)}, instead of expected int or list/tuple')
248249

249250
self.boundary_width = boundary_width
251+
if isinstance(boundary_width, int):
252+
self.inner_shape = np.array(self.get('0').shape) - 2 * boundary_width
253+
elif isinstance(boundary_width, (list, tuple)):
254+
self.inner_shape = np.array(self.get('0').shape) - np.multiply(np.array(boundary_width), 2)
250255

251256
def memory_usage_properties(self, obj_test_case=None, mem_for_cache_frac=None, mem_for_cache_abs=None):
252257
"""
@@ -444,6 +449,11 @@ def __contains__(self, obj):
444449
return (obj[0] in self.memory_normalized['numpy'].keys()) or (obj[0] in self.memory_normalized['torch'].keys())
445450
else:
446451
return (obj[0] in self.memory_default['numpy'].keys()) or (obj[0] in self.memory_default['torch'].keys())
452+
elif (type(obj) == tuple or type(obj) == list) and type(obj[0]) == frozenset and type(obj[1]) == bool:
453+
if obj[1]:
454+
return (obj[0] in self.memory_normalized['numpy'].keys()) or (obj[0] in self.memory_normalized['torch'].keys())
455+
else:
456+
return (obj[0] in self.memory_default['numpy'].keys()) or (obj[0] in self.memory_default['torch'].keys())
447457
elif type(obj) == np.ndarray:
448458
try:
449459
return np.any([np.all(obj == entry_values) for entry_values in self.memory_default['numpy'].values()])

epde/eq_mo_objectives.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def generate_partial(obj_function, equation_key):
1616
return partial(obj_function, equation_key=equation_key)
1717

1818

19-
def equation_fitness(system, equation_key):
19+
def equation_fitness(system, equation_key = None):
2020
'''
2121
Evaluate the quality of the system of PDEs, using the individual values of fitness function for equations.
2222
@@ -30,8 +30,14 @@ def equation_fitness(system, equation_key):
3030
error : float.
3131
The value of the error metric.
3232
'''
33-
assert system.vals[equation_key].fitness_calculated, 'Trying to call fitness before its evaluation.'
34-
res = system.vals[equation_key].fitness_value
33+
if equation_key:
34+
assert all(equation.fitness_calculated for equation in system.vals), 'Trying to call fitness before its evaluation.'
35+
res = system.vals[equation_key].fitness_calculated
36+
else:
37+
for equation in system.vals:
38+
assert equation.fitness_value
39+
# res = np.mean([equation.fitness_value for equation in system.vals])
40+
res = tuple([equation.fitness_value for equation in system.vals])
3541
return res
3642

3743

@@ -97,9 +103,15 @@ def equation_complexity_by_factors(system, equation_key):
97103
return eq_compl
98104

99105

100-
def equation_terms_stability(system, equation_key):
101-
assert system.vals[equation_key].stability_calculated
102-
res = system.vals[equation_key].coefficients_stability
106+
def equation_terms_stability(system, equation_key = None):
107+
if equation_key:
108+
assert system.vals[equation_key].stability_calculated
109+
res = system.vals[equation_key].coefficients_stability
110+
else:
111+
for equation in system.vals:
112+
assert equation.stability_calculated
113+
# res = np.mean([equation.coefficients_stability for equation in system.vals])
114+
res = tuple([equation.coefficients_stability for equation in system.vals])
103115
return res
104116

105117
def equation_aic(system, equation_key):

epde/evaluators.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,17 @@ def __call__(self, factor, structural: bool = False, func_args: List[Union[torch
8484
self.indexes_vect[tensor_idx] = tuple([subarg[tensor_idx]
8585
for subarg in func_args])
8686
value = grid_function(self.indexes_vect)
87+
if len(global_var.grid_cache.initial_shape) > 1:
88+
value = value.reshape(*global_var.grid_cache.initial_shape)
89+
if isinstance(global_var.grid_cache.boundary_width, int):
90+
for dim in range(value.ndim):
91+
value[dim] = value[global_var.grid_cache.boundary_width:-global_var.grid_cache.boundary_width]
92+
elif isinstance(global_var.grid_cache.boundary_width, (list, tuple)):
93+
for dim in range(value.ndim):
94+
value[dim] = value[global_var.grid_cache.boundary_width[dim]:-global_var.grid_cache.boundary_width[dim]]
95+
value = value.reshape(-1)
96+
else:
97+
value = value[global_var.grid_cache.boundary_width:-global_var.grid_cache.boundary_width]
8798
return value
8899

89100

epde/interface/interface.py

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class InputDataEntry(object):
6565
derivatives (`np.ndarray`): values of derivatives
6666
deriv_properties (`dict`): settings of derivatives
6767
"""
68-
def __init__(self, var_name: str, var_idx: int, data_tensor: Union[List[np.ndarray], np.ndarray]):
68+
def __init__(self, var_name: str, var_idx: int, data_tensor: Union[List[np.ndarray], np.ndarray], boundary):
6969
self.var_name = var_name
7070
self.var_idx = var_idx
7171
if isinstance(data_tensor, np.ndarray):
@@ -76,6 +76,7 @@ def __init__(self, var_name: str, var_idx: int, data_tensor: Union[List[np.ndarr
7676
assert all([data_tensor[0].ndim == tensor.ndim for tensor in data_tensor]), 'Mismatching dimensionalities of data tensors.'
7777
self.ndim = data_tensor[0].ndim
7878
self.data_tensor = data_tensor
79+
self.boundary = boundary
7980

8081

8182
def set_derivatives(self, preprocesser: PreprocessingPipe, deriv_tensors: Union[list, np.ndarray] = None,
@@ -135,6 +136,8 @@ def use_global_cache(self): # , var_idx: int, deriv_codes: list
135136
"""
136137
var_idx = self.var_idx
137138
deriv_codes = self.d_orders
139+
self.data_tensor = self.data_tensor[self.boundary != 0]
140+
self.derivatives = np.array([derivative[self.boundary.flatten() != 0] for derivative in self.derivatives.T]).T
138141
derivs_stacked = prepare_var_tensor(self.data_tensor, self.derivatives,
139142
time_axis=global_var.time_axis)
140143
deriv_codes = [(var_idx, code) for code in deriv_codes]
@@ -351,7 +354,7 @@ def set_memory_properties(self, example_tensor, mem_for_cache_frac=None, mem_for
351354
global_var.tensor_cache.memory_usage_properties(example_tensor, mem_for_cache_frac, mem_for_cache_abs)
352355

353356
def set_moeadd_params(self, population_size: int = 6, solution_params: dict = {},
354-
delta: float = 1/50., neighbors_number: int = 3,
357+
H: int = 15, neighbors_number: int = 3,
355358
nds_method: Callable = fast_non_dominated_sorting,
356359
ndl_update_method: Callable = ndl_update,
357360
subregion_mating_limitation: float = .95,
@@ -367,7 +370,7 @@ def set_moeadd_params(self, population_size: int = 6, solution_params: dict = {}
367370
The size of the population of solutions, created during MO - optimization, default 6.
368371
solution_params (`dict`): optional
369372
Dictionary, containing additional parameters to be sent into the newly created solutions.
370-
delta (`float`): optional
373+
H (`float`): optional
371374
parameter of uniform spacing between the weight vectors; *H = 1 / delta*
372375
should be integer - a number of divisions along an objective coordinate axis.
373376
neighbors_number (`int`): *> 0*, optional
@@ -407,8 +410,8 @@ def set_moeadd_params(self, population_size: int = 6, solution_params: dict = {}
407410
Returns:
408411
None
409412
"""
410-
self.optimizer_init_params = {'weights_num': population_size, 'pop_size': population_size,
411-
'delta': delta, 'neighbors_number': neighbors_number,
413+
self.optimizer_init_params = {'pop_size': population_size,
414+
'H': population_size-1, 'neighbors_number': neighbors_number,
412415
'solution_params': solution_params,
413416
'nds_method' : nds_method,
414417
'ndl_update' : ndl_update_method}
@@ -534,7 +537,12 @@ def uniformize(data):
534537
exponent = np.multiply.reduce(exponent_partial, axis=0)
535538
return exponent
536539

537-
global_var.grid_cache.g_func = decorator(baseline_exp_function)
540+
def return_ones(grids):
541+
ones_partial = np.array([np.ones_like(grid) for grid in grids])
542+
ones = np.multiply.reduce(ones_partial, axis=0)
543+
return ones
544+
# global_var.grid_cache.g_func = decorator(baseline_exp_function)
545+
global_var.grid_cache.g_func = decorator(return_ones)
538546
else:
539547
global_var.grid_cache.g_func = decorator(function_form)
540548

@@ -671,7 +679,7 @@ def create_pool(self, data: Union[np.ndarray, list, tuple], variable_names=['u',
671679

672680
for data_elem_idx, data_tensor in enumerate(data):
673681
entry = InputDataEntry(var_name=variable_names[data_elem_idx], var_idx=data_elem_idx,
674-
data_tensor=data_tensor)
682+
data_tensor=data_tensor, boundary=self.cache[0].g_func)
675683
derivs_tensor = derivs[data_elem_idx] if derivs is not None else None
676684
entry.set_derivatives(preprocesser=self.preprocessor_pipeline, deriv_tensors=derivs_tensor,
677685
grid=grid, max_order=max_deriv_order)
@@ -847,18 +855,16 @@ def _create_optimizer(multiobjective_mode: bool, optimizer_init_params: dict,
847855
opt_strategy_director: OptimizationPatternDirector,
848856
population: List[SoEq] = None, use_pic: bool = False):
849857
if multiobjective_mode:
858+
best_sol_vals = [0., 0.] if use_pic else [0., 1.]
859+
optimizer_init_params['best_sol_vals'] = best_sol_vals
850860
optimizer_init_params['passed_population'] = population
851861
optimizer = MOEADDOptimizer(**optimizer_init_params)
852-
853-
# if best_sol_vals is None:
854-
best_sol_vals = [0., 0.] if use_pic else [0., 1.]
855-
# best_sol_vals = [0., 0.] if use_pic else [0., 1.]
856-
857862
same_obj_count = sum([1 for token_family in optimizer_init_params['population_instruct']['pool'].families
858863
if token_family.status['demands_equation']])
859864
best_obj = np.concatenate([np.full(same_obj_count, fill_value = fval) for fval in best_sol_vals])
860865
print('best_obj', len(best_obj))
861-
optimizer.pass_best_objectives(*best_obj)
866+
# optimizer.pass_best_objectives(*best_obj)
867+
optimizer.pass_best_objectives(*best_sol_vals)
862868
else:
863869
optimizer_init_params['passed_population'] = population
864870
optimizer = SimpleOptimizer(**optimizer_init_params)

epde/interface/prepared_tokens.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,7 @@ def __init__(self, token_type: str, token_labels: list, token_tensors: dict, par
419419
non_default_power = True):
420420
if set(token_labels) != set(list(token_tensors.keys())):
421421
raise KeyError('The labels of tokens do not match the labels of passed tensors')
422+
token_tensors = {key: value[global_var.grid_cache.g_func != 0] for key, value in token_tensors.items()}
422423
upload_simple_tokens(list(token_tensors.keys()), global_var.tensor_cache, list(token_tensors.values()))
423424
super().__init__(token_type=token_type, token_labels=token_labels, evaluator=simple_function_evaluator,
424425
params_ranges=params_ranges, params_equality_ranges=params_equality_ranges,

epde/interface/token_family.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"""
88

99
import numpy as np
10+
import math
1011
import itertools
1112
from typing import Union, Callable, List
1213
try:
@@ -273,7 +274,7 @@ def chech_constancy(self, **tfkwargs):
273274
data_label = (label, (1.0,))
274275
data = global_var.tensor_cache.memory_default["numpy"].get(data_label)
275276
try:
276-
constancy = np.isclose(np.min(data), np.max(data))
277+
constancy = math.isclose(np.min(data), np.max(data))
277278
except TypeError:
278279
print(f"No {label} data in cache for constancy check. Functionality of eval-d token check TBD.")
279280
continue

epde/operators/common/coeff_calculation.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"""
88

99
import numpy as np
10-
from sklearn.linear_model import LinearRegression
10+
from sklearn.linear_model import LinearRegression, Ridge
1111

1212
import epde.globals as global_var
1313
from epde.operators.utils.template import CompoundOperator
@@ -67,11 +67,13 @@ def apply(self, objective : Equation, arguments : dict = None):
6767
features = np.vstack([features, features_vals[i]])
6868
features = np.vstack([features, np.ones(features_vals[0].shape)]) # Добавляем константную фичу
6969
features = np.transpose(features)
70-
estimator = LinearRegression(fit_intercept=False)
70+
estimator = LinearRegression(copy_X=True, fit_intercept=False, n_jobs=-1,
71+
positive=False, tol=0.0001)
72+
# estimator = LinearRegression(fit_intercept=False)
7173
if features.ndim == 1:
7274
features = features.reshape(-1, 1)
7375
try:
74-
self.g_fun_vals = global_var.grid_cache.g_func.reshape(-1)
76+
self.g_fun_vals = global_var.grid_cache.g_func[global_var.grid_cache.g_func != 0]
7577
except AttributeError:
7678
self.g_fun_vals = None
7779
estimator.fit(features, target_vals, sample_weight = self.g_fun_vals)

0 commit comments

Comments
 (0)