From 9104e9864f8ad184ae6a85e490df94613ab20637 Mon Sep 17 00:00:00 2001 From: Ivan Olarte Rodriguez <126246479+olarterodriguezivan@users.noreply.github.com> Date: Mon, 10 Mar 2025 14:05:53 +0100 Subject: [PATCH 1/6] Add files via upload --- gen_config.py | 292 ++-- my_logger.py | 285 ++-- requirements2.txt | 165 +++ run_experiment.py | 347 +++-- total_config.json | 25 +- wrapper.py | 3232 +++++++++++++++++++++++++++++++-------------- wrapper_helper.py | 95 ++ 7 files changed, 3107 insertions(+), 1334 deletions(-) create mode 100644 requirements2.txt create mode 100644 wrapper_helper.py diff --git a/gen_config.py b/gen_config.py index 126b923..9d03d41 100644 --- a/gen_config.py +++ b/gen_config.py @@ -1,132 +1,160 @@ -import sys -import os -import json -import datetime -import subprocess - -class ExperimentEnvironment: - SLURM_SCRIPT_TEMPLATE = '''#!/bin/bash - -#SBATCH --job-name=##folder## -#SBATCH --array=0-##jobs_count## -#SBATCH --clusters=serial -#SBATCH --partition=serial_std -#SBATCH --mem=2048MB -#SBATCH --time=96:00:00 -#SBATCH --mail-user=your_email@domain.com -#SBATCH --mail-type=END,FAIL -#SBATCH --ntasks=1 -#SBATCH --cpus-per-task=4 -#SBATCH --output=##logs_out## -#SBATCH --error=##logs_err## - -num=##from_number## -FILE_ID=$((${SLURM_ARRAY_TASK_ID}+$num)) -python ../run_experiment.py configs/*${FILE_ID}.json -''' - - def __init__(self): - now = datetime.datetime.now() - suffix = now.strftime('%d-%m-%Y_%Hh%Mm%Ss') - folder_name = 'run_' + suffix - os.makedirs(folder_name, exist_ok=False) - print(f'Experiment root is: {folder_name}') - self.experiment_root = os.path.abspath(folder_name) - self.__max_array_size = 100 - self.__number_of_slurm_scripts = 0 - - def set_up_by_experiment_config_file(self, experiment_config_file_name): - self.__generate_configs(experiment_config_file_name) - self.__create_log_dir() - self.__generate_slurm_script() - - def __create_log_dir(self): - self.logs_folder = os.path.join(self.experiment_root, 'logs') - os.mkdir(self.logs_folder) - - def __generate_slurm_script(self): - self.__number_of_slurm_scripts = 0 - logs_out = os.path.join(self.logs_folder, '%A_%a.out') - logs_err = os.path.join(self.logs_folder, '%A_%a.err') - script = ExperimentEnvironment.SLURM_SCRIPT_TEMPLATE - script = script\ - .replace('##folder##', self.result_folder_prefix)\ - .replace('##logs_out##', logs_out)\ - .replace('##logs_err##', logs_err) - offset = 0 - for i in range(self.generated_configs // self.__max_array_size): - with open(os.path.join(self.experiment_root, f'slurm{self.__number_of_slurm_scripts}.sh'), 'w') as f: - f.write(script\ - .replace('##from_number##', str(offset))\ - .replace('##jobs_count##', str(self.__max_array_size - 1))) - offset += self.__max_array_size - self.__number_of_slurm_scripts += 1 - r = self.generated_configs % self.__max_array_size - if r > 0: - with open(os.path.join(self.experiment_root, f'slurm{self.__number_of_slurm_scripts}.sh'), 'w') as f: - f.write(script\ - .replace('##from_number##', str(offset))\ - .replace('##jobs_count##', str(r - 1))) - offset += r - self.__number_of_slurm_scripts += 1 - - def __generate_configs(self, experiment_config_file_name): - with open(experiment_config_file_name, 'r') as f: - config = json.load(f) - self.result_folder_prefix = config['folder'] - fids = config['fids'] - iids = config['iids'] - dims = config['dims'] - reps = config['reps'] - if 'extra' not in config.keys(): - config['extra'] = '' - optimizers = config['optimizers'] - lb, ub = config['lb'], config['ub'] - runs_number = len(optimizers) * len(fids) * len(iids) * len(dims) * reps - cur_config_number = 0 - configs_dir = os.path.join(self.experiment_root, 'configs') - os.makedirs(configs_dir, exist_ok=False) - with open(os.path.join(self.experiment_root, 'description.json'), 'w') as f: - json.dump(config, f, indent=4) - for my_optimizer_name in optimizers: - for fid in fids: - for iid in iids: - for dim in dims: - # print(f'Ids for opt={my_optimizer_name}, fid={fid}, iid={iid}, dim={dim} are [{cur_config_number}, {cur_config_number+reps-1}]') - for rep in range(reps): - experiment_config = { - 'folder': f'{self.result_folder_prefix}_Opt-{my_optimizer_name}_F-{fid}_Id-{iid}_Dim-{dim}_Rep-{rep}_NumExp-{cur_config_number}', - 'opt': my_optimizer_name, - 'fid': fid, - 'iid': iid, - 'dim': dim, - 'seed': rep, - 'lb': lb, - 'ub': ub, - } - cur_config_file_name = f'Opt-{my_optimizer_name}_F-{fid}_Id-{iid}_Dim-{dim}_Rep-{rep}_NumExp-{cur_config_number}.json' - with open(os.path.join(configs_dir, cur_config_file_name), 'w') as f: - json.dump(experiment_config, f) - cur_config_number += 1 - print(f'Generated {cur_config_number} files') - self.generated_configs = cur_config_number - def is_slurm_available(self): - try: - subprocess.run(["sbatch", "--version"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) - return True - except FileNotFoundError: - return False - - def print_helper(self): - if self.is_slurm_available(): - print(f'cd {self.experiment_root} && for (( i=0; i<{self.__number_of_slurm_scripts}; ++i )); do sbatch slurm$i.sh; done') - - -def main(argv): - env = ExperimentEnvironment() - env.set_up_by_experiment_config_file(argv[1]) - env.print_helper() - - -if __name__ == '__main__': - main(sys.argv) +import sys +import os +import json +import datetime +import subprocess + +# #SBATCH --clusters=serial +class ExperimentEnvironment: + SLURM_SCRIPT_TEMPLATE = '''#!/bin/bash + +#SBATCH --job-name=##folder## +#SBATCH --array=0-##jobs_count## +#SBATCH --partition=gpu-medium +#SBATCH --mem=4096MB +#SBATCH --time=48:00:00 +#SBATCH --mail-user=olarterodriguezi@vuw.leidenuniv.nl +#SBATCH --mail-type=END,FAIL +#SBATCH --ntasks=1 +#SBATCH --cpus-per-task=4 +#SBATCH --output=##logs_out## +#SBATCH --error=##logs_err## + + +#// LOAD PYTHON +module load Python/3.10.4-GCCcore-11.3.0 + +#// ACTIVATE MODULE +source $HOME/BO_torch/bo-torch-run/bin/activate + +num=##from_number## +FILE_ID=$((${SLURM_ARRAY_TASK_ID}+$num)) + +# Define the directory containing the config files +CONFIG_DIR="##folder_name_configs##" + +# Find the file where NumExp-% matches TASK_ID +CONFIG_FILE=$(find "$CONFIG_DIR" -type f -name "*.json" | grep "NumExp-${FILE_ID}\.json") + +# Check if a config file was found +if [ -z "$CONFIG_FILE" ]; then + echo "Error: No matching config file found for NumExp-${FILE_ID}!" + exit 1 +fi + +echo $CONFIG_FILE + +python3 ../run_experiment.py $CONFIG_FILE +''' + + def __init__(self): + now = datetime.datetime.now() + suffix = now.strftime('%d-%m-%Y_%Hh%Mm%Ss') + folder_name = 'run_' + suffix + os.makedirs(folder_name, exist_ok=False) + print(f'Experiment root is: {folder_name}') + self.experiment_root = os.path.abspath(folder_name) + self.__max_array_size = 1000 + self.__number_of_slurm_scripts = 0 + + def set_up_by_experiment_config_file(self, experiment_config_file_name): + self.__generate_configs(experiment_config_file_name) + self.__create_log_dir() + self.__generate_slurm_script() + + def __create_log_dir(self): + self.logs_folder = os.path.join(self.experiment_root, 'logs') + os.mkdir(self.logs_folder) + + def __generate_slurm_script(self): + self.__number_of_slurm_scripts = 0 + logs_out = os.path.join(self.logs_folder, '%A_%a.out') + logs_err = os.path.join(self.logs_folder, '%A_%a.err') + script = ExperimentEnvironment.SLURM_SCRIPT_TEMPLATE + script = script\ + .replace('##folder##', self.result_folder_prefix)\ + .replace('##logs_out##', logs_out)\ + .replace('##logs_err##', logs_err)\ + .replace('##folder_name_configs##', + os.path.join(self.experiment_root,"configs")) + offset = 0 + for _ in range(self.generated_configs // self.__max_array_size): + with open(os.path.join(self.experiment_root, f'slurm{self.__number_of_slurm_scripts}.sh'), 'w') as f: + f.write(script\ + .replace('##from_number##', str(offset))\ + .replace('##jobs_count##', str(self.__max_array_size - 1))) + offset += self.__max_array_size + self.__number_of_slurm_scripts += 1 + r = self.generated_configs % self.__max_array_size + if r > 0: + with open(os.path.join(self.experiment_root, f'slurm{self.__number_of_slurm_scripts}.sh'), 'w') as f: + f.write(script\ + .replace('##from_number##', str(offset))\ + .replace('##jobs_count##', str(r - 1))) + offset += r + self.__number_of_slurm_scripts += 1 + + def __generate_configs(self, experiment_config_file_name): + with open(experiment_config_file_name, 'r') as f: + config = json.load(f) + self.result_folder_prefix = config['folder'] + fids = config['fids'] + iids = config['iids'] + dims = config['dims'] + reps = config['reps'] + logger_mode = config["logger"] + sample_zero = bool(config["sample_zero"]) + if 'extra' not in config.keys(): + config['extra'] = '' + optimizers = config['optimizers'] + lb, ub = config['lb'], config['ub'] + runs_number = len(optimizers) * len(fids) * len(iids) * len(dims) * reps + cur_config_number = 0 + configs_dir = os.path.join(self.experiment_root, 'configs') + os.makedirs(configs_dir, exist_ok=False) + with open(os.path.join(self.experiment_root, 'description.json'), 'w') as f: + json.dump(config, f, indent=4) + for my_optimizer_name in optimizers: + for fid in fids: + for iid in iids: + for dim in dims: + # print(f'Ids for opt={my_optimizer_name}, fid={fid}, iid={iid}, dim={dim} are [{cur_config_number}, {cur_config_number+reps-1}]') + for rep in range(reps): + experiment_config = { + 'folder': f'{self.result_folder_prefix}_Opt-{my_optimizer_name}_F-{fid}_Id-{iid}_Dim-{dim}_Rep-{rep}_NumExp-{cur_config_number}', + 'opt': my_optimizer_name, + 'fid': fid, + 'iid': iid, + 'dim': dim, + 'seed': rep, + 'lb': lb, + 'ub': ub, + 'logger':logger_mode, + 'sample_zero':int(sample_zero) + } + cur_config_file_name = f'Opt-{my_optimizer_name}_F-{fid}_Id-{iid}_Dim-{dim}_Rep-{rep}_NumExp-{cur_config_number}.json' + with open(os.path.join(configs_dir, cur_config_file_name), 'w') as f: + json.dump(experiment_config, f) + cur_config_number += 1 + print(f'Generated {cur_config_number} files') + self.generated_configs = cur_config_number + def is_slurm_available(self): + try: + subprocess.run(["sbatch", "--version"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + return True + except FileNotFoundError: + return False + + def print_helper(self): + if self.is_slurm_available(): + print(f'cd {self.experiment_root} && for (( i=0; i<{self.__number_of_slurm_scripts}; ++i )); do sbatch slurm$i.sh; done') + + +def main(argv): + env = ExperimentEnvironment() + env.set_up_by_experiment_config_file(argv[1]) + env.print_helper() + + +if __name__ == '__main__': + main(sys.argv) diff --git a/my_logger.py b/my_logger.py index fd65ad5..58aac45 100644 --- a/my_logger.py +++ b/my_logger.py @@ -1,110 +1,175 @@ -import os -import time -from ioh import get_problem - - -class MyIOHFormatOnEveryEvaluationLogger: - def __init__(self, folder_name='TMP', algorithm_name='UNKNOWN', suite='unkown suite', algorithm_info='algorithm_info'): - self.folder_name = MyIOHFormatOnEveryEvaluationLogger.__generate_dir_name(folder_name) - self.algorithm_name = algorithm_name - self.algorithm_info = algorithm_info - self.suite = suite - self.create_time = time.process_time() - - @staticmethod - def __generate_dir_name(name, x=0): - while True: - dir_name = (name + ('-' + str(x))).strip() - if not os.path.exists(dir_name): - os.mkdir(dir_name) - return dir_name - else: - x = x + 1 - - def watch(self, algorithm, extra_data): - self.algorithm = algorithm - self.extra_info_getters = extra_data - - def _set_up_logger(self, fid, iid, dim, func_name): - self.log_info_path = f'{self.folder_name}/IOHprofiler_f{fid}_{func_name}.info' - with open(self.log_info_path, 'a') as f: - f.write(f'suite = \"{self.suite}\", funcId = {fid}, funcName = \"{func_name}\", DIM = {dim}, maximization = \"F\", algId = \"{self.algorithm_name}\", algInfo = \"{self.algorithm_info}\"\n') - self.log_file_path = f'data_f{fid}_{func_name}/IOHprofiler_f{fid}_DIM{dim}.dat' - self.log_file_full_path = f'{self.folder_name}/{self.log_file_path}' - os.makedirs(os.path.dirname(self.log_file_full_path), exist_ok=True) - self.first_line = 0 - self.last_line = 0 - with open(self.log_file_full_path, 'a') as f: - f.write('\"function evaluation\" \"current f(x)\" \"best-so-far f(x)\" \"current af(x)+b\" \"best af(x)+b\"') - for extra_info in self.extra_info_getters: - f.write(f' {extra_info}') - f.write('\n') - - def log(self, cur_evaluation, cur_fitness, best_so_far, loss_f, best_loss_f): - with open(self.log_file_full_path, 'a') as f: - f.write(f'{cur_evaluation} {loss_f} {best_loss_f} {cur_fitness} {best_so_far}') - for fu in self.extra_info_getters: - try: - extra_info = getattr(self.algorithm, fu) - except Exception as e: - extra_info = 'None' - f.write(f' {extra_info}') - f.write('\n') - self.last_line += 1 - - def finish_logging(self): - time_taken = time.process_time() - self.create_time - with open(self.log_info_path, 'a') as f: - f.write('%\n') - f.write(f'{self.log_file_path}, {self.first_line}:{self.last_line}|{time_taken}\n') - - -class MyObjectiveFunctionWrapper: - def __init__(self, fid, iid, dim, directed_by='IOH'): - self.fid = fid - self.iid = iid - self.dim = dim - self.my_loggers = [] - if directed_by == 'Hao': - self.my_function, self.optimum = bn.instantiate(ifun=fid, iinstance=iid) - iohf = get_problem(fid, dimension=dim, instance=iid, problem_type = 'Real') - self.func_name = iohf.meta_data.name - elif directed_by == 'IOH': - self.my_function = get_problem(fid, dimension=dim, instance=iid, problem_type = 'Real') - self.func_name = self.my_function.meta_data.name - self.optimum = self.my_function.objective.y - else: - raise ValueError('Unknown way to create function using', directed_by) - self.cnt_eval = 0 - self.best_so_far = float('inf') - self.min_distance = float('inf') - self.best_loss = float('inf') - - # def __call__(self, x): - # cur_value = self.my_function(x) - # distance = cur_value - # self.best_so_far = min(self.best_so_far, cur_value) - # self.min_distance = min(self.min_distance, distance) - # self.cnt_eval += 1 - # for l in self.my_loggers: - # l.log(self.cnt_eval, distance, self.min_distance) - # return cur_value - - def __call__(self, x): - cur_value = self.my_function(x) - distance = cur_value - optimumy = self.optimum - loss = (cur_value - optimumy) - self.best_so_far = min(self.best_so_far, cur_value) - self.min_distance = min(self.min_distance, distance) - self.best_loss = min(self.best_loss,loss) - self.cnt_eval += 1 - for l in self.my_loggers: - l.log(self.cnt_eval, distance, self.min_distance, loss, self.best_loss) - return cur_value - - def attach_logger(self, logger): - self.my_loggers.append(logger) - logger._set_up_logger(self.fid, self.iid, self.dim, self.func_name) - - +import os +import time +from ioh import get_problem +import ioh +from typing import List, Optional, Union +from numpy import ndarray +from numpy import matrix +from numpy import ravel +import warnings +from typing import overload + + + + +class MyIOHFormatOnEveryEvaluationLogger: + def __init__(self, folder_name='TMP', algorithm_name='UNKNOWN', suite='unknown suite', algorithm_info='algorithm_info'): + self.folder_name = MyIOHFormatOnEveryEvaluationLogger.__generate_dir_name(folder_name) + self.algorithm_name = algorithm_name + self.algorithm_info = algorithm_info + self.suite = suite + self.create_time = time.process_time() + + @staticmethod + def __generate_dir_name(name, x=0): + while True: + dir_name = (name + ('-' + str(x))).strip() + if not os.path.exists(dir_name): + os.mkdir(dir_name) + return dir_name + else: + x = x + 1 + + def watch(self, algorithm, extra_data): + self.algorithm = algorithm + self.extra_info_getters = extra_data + + def _set_up_logger(self, fid, iid, dim, func_name): + self.log_info_path = f'{self.folder_name}/IOHprofiler_f{fid}_{func_name}.info' + with open(self.log_info_path, 'a') as f: + f.write(f'suite = \"{self.suite}\", funcId = {fid}, funcName = \"{func_name}\", DIM = {dim}, maximization = \"F\", algId = \"{self.algorithm_name}\", algInfo = \"{self.algorithm_info}\"\n') + self.log_file_path = f'data_f{fid}_{func_name}/IOHprofiler_f{fid}_DIM{dim}.dat' + self.log_file_full_path = f'{self.folder_name}/{self.log_file_path}' + os.makedirs(os.path.dirname(self.log_file_full_path), exist_ok=True) + self.first_line = 0 + self.last_line = 0 + with open(self.log_file_full_path, 'a') as f: + f.write('\"function evaluation\" \"current f(x)\" \"best-so-far f(x)\" \"current af(x)+b\" \"best af(x)+b\"') + for extra_info in self.extra_info_getters: + f.write(f' {extra_info}') + f.write('\n') + + def log(self, cur_evaluation, cur_fitness, best_so_far, loss_f, best_loss_f): + with open(self.log_file_full_path, 'a') as f: + f.write(f'{cur_evaluation} {loss_f} {best_loss_f} {cur_fitness} {best_so_far}') + for fu in self.extra_info_getters: + try: + extra_info = getattr(self.algorithm, fu) + except Exception as e: + extra_info = 'None' + f.write(f' {extra_info}') + f.write('\n') + self.last_line += 1 + + def finish_logging(self): + time_taken = time.process_time() - self.create_time + with open(self.log_info_path, 'a') as f: + f.write('%\n') + f.write(f'{self.log_file_path}, {self.first_line}:{self.last_line}|{time_taken}\n') + + +class MyIOHFormatOnEveryEvaluationLogger2(ioh.iohcpp.logger.AbstractLogger): + r""" + This is a handler to perform the same kind of logging performed by Maria Laura in order to follow the + IOH Analyzer guidelines. + """ + def __init__(self, + triggers = ..., + properties = ..., + root = ..., + folder_name = ..., + algorithm_name = ..., + algorithm_info = ..., + suite='unknown suite', + ):#store_positions = False): + r""" + Just the same constructor as the superclass (`ioh.logger.Analyzer`). + """ + super().__init__(triggers, properties) + + # Fill up the properties + self.root = root + self.folder_name = self.__generate_dir_name(folder_name) + self.algorithm_name =algorithm_name + self.algorithm_info = algorithm_info + self.suite = suite + + self._setup_generated:bool = False + self.create_time = time.process_time() + + def __call__(self, logInfo:ioh.iohcpp.LogInfo, *args, **kwds): + #print(logInfo,args,kwds) + #return super().__call__(*args, **kwds) + if not self._setup_generated: + self._set_up_logger(fid= self.problem.problem_id, + iid =self.problem.instance, + dim = self.problem.n_variables, + func_name=self.problem.name) + + self._setup_generated = True + + # log the info + self.log(logInfo.evaluations, + logInfo.y, + logInfo.y_best, + logInfo.y - logInfo.objective.y, + logInfo.y_best - logInfo.objective.y) + + + def __generate_dir_name(self,name, x=0): + while True: + dir_name = (name + ('-' + str(x))).strip() + if not os.path.exists(os.path.join(self.root,dir_name)): + os.mkdir(dir_name) + return dir_name + else: + x = x + 1 + + def _set_up_logger(self, fid, iid, dim, func_name): + self.log_info_path = f'{self.folder_name}/IOHprofiler_f{fid}_{func_name}.info' + with open(self.log_info_path, 'a') as f: + f.write(f'suite = \"{self.suite}\", funcId = {fid}, funcName = \"{func_name}\", DIM = {dim}, maximization = \"F\", algId = \"{self.algorithm_name}\", algInfo = \"{self.algorithm_info}\"\n') + self.log_file_path = f'data_f{fid}_{func_name}/IOHprofiler_f{fid}_DIM{dim}.dat' + self.log_file_full_path = f'{self.folder_name}/{self.log_file_path}' + os.makedirs(os.path.dirname(self.log_file_full_path), exist_ok=True) + self.first_line = 0 + self.last_line = 0 + with open(self.log_file_full_path, 'a') as f: + f.write('\"function evaluation\" \"current f(x)\" \"best-so-far f(x)\" \"current af(x)+b\" \"best af(x)+b\"') + for extra_info in self.extra_info_getters: + f.write(f' {extra_info}') + f.write('\n') + + def log(self, cur_evaluation, cur_fitness, best_so_far, loss_f, best_loss_f): + with open(self.log_file_full_path, 'a') as f: + f.write(f'{cur_evaluation} {loss_f} {best_loss_f} {cur_fitness} {best_so_far}') + for fu in self.extra_info_getters: + try: + extra_info = getattr(self.algorithm, fu) + except Exception as e: + extra_info = 'None' + f.write(f' {extra_info}') + f.write('\n') + self.last_line += 1 + + @overload + def watch(self, algorithm, extra_data)->None: ... + + def watch(self,obj:object,extra_props:list)->None: + self.algorithm = obj + self.extra_info_getters = extra_props + + def finish_logging(self): + time_taken = time.process_time() - self.create_time + with open(self.log_info_path, 'a') as f: + f.write('%\n') + f.write(f'{self.log_file_path}, {self.first_line}:{self.last_line}|{time_taken}\n') + + + + + + + + + diff --git a/requirements2.txt b/requirements2.txt new file mode 100644 index 0000000..38c12df --- /dev/null +++ b/requirements2.txt @@ -0,0 +1,165 @@ +about-time==4.2.1 +absl-py==1.0.0 +alembic==1.14.0 +alive-progress==3.2.0 +aniso8601==9.0.1 +attrs==21.4.0 +autograd==1.7.0 +ax-platform<=0.4.3 +azure-common==1.1.28 +azure-nspkg==3.0.2 +azure-storage==0.32.0 +blinker==1.9.0 +botorch>=0.6, <=0.9 +catboost==1.2.7 +certifi==2021.10.8 +charset-normalizer==2.0.12 +click==8.1.7 +cloudpickle==3.1.0 +cma==3.2.2 +coco-experiment==2.6.100 +cocopp==2.6.4 +coloredlogs==15.0.1 +ConfigSpace==1.2.1 +contourpy==1.3.1 +cycler==0.11.0 +Cython==3.0.11 +dask==2024.11.2 +dask-jobqueue==0.9.0 +decorator==5.1.1 +Deprecated==1.2.15 +dill==0.3.4 +disjoint_set==0.8.0 +distributed==2024.11.2 +docker==7.1.0 +emcee==3.1.6 +entrypoints==0.4 +filelock==3.16.1 +Flask==3.1.0 +flatbuffers==2.0 +fonttools==4.33.3 +fsspec==2024.10.0 +gitdb==4.0.11 +GitPython==3.1.43 +gpytorch>=1.6,<=1.8.1 +grapheme==0.6.0 +graphene==3.4.3 +graphql-core==3.2.5 +graphql-relay==3.2.0 +graphviz==0.20.3 +greenlet==3.1.1 +gunicorn==21.2.0 +h5py==3.12.1 +HEBO==0.3.6 +humanfriendly==10.0 +idna==3.3 +importlib_metadata==7.2.1 +iniconfig==1.1.1 +ioh==0.3.18 +ipywidgets==8.1.5 +isodate==0.6.1 +itsdangerous==2.2.0 +jax==0.4.35 +jaxlib==0.4.35 +jaxtyping==0.2.19 +Jinja2==3.1.4 +joblib==1.4.2 +jupyterlab_widgets==3.0.13 +kiwisolver==1.4.2 +linear-operator==0.5.3 +locket==1.0.0 +Mako==1.3.6 +Markdown==3.7 +MarkupSafe==3.0.2 +matplotlib==3.9.2 +mkl-service==2.4.0 +ml_dtypes==0.5.0 +mlflow==2.11.3 +more-itertools==10.5.0 +mpmath==1.3.0 +msgpack==1.1.0 +msrest==0.6.21 +multipledispatch==0.6.0 +mypy-extensions==1.0.0 +networkx==3.4.2 +numpy==1.24.4 +numpyro==0.15.3 +nvidia-cublas-cu12==12.4.5.8 +nvidia-cuda-cupti-cu12==12.4.127 +nvidia-cuda-nvrtc-cu12==12.4.127 +nvidia-cuda-runtime-cu12==12.4.127 +nvidia-cudnn-cu12==9.1.0.70 +nvidia-cufft-cu12==11.2.1.3 +nvidia-curand-cu12==10.3.5.147 +nvidia-cusolver-cu12==11.6.1.9 +nvidia-cusparse-cu12==12.3.1.170 +nvidia-nccl-cu12==2.21.5 +nvidia-nvjitlink-cu12==12.4.127 +nvidia-nvtx-cu12==12.4.127 +oauthlib==3.2.2 +opt-einsum==3.3.0 +packaging==23.2 +pandas==2.2.3 +parameterized==0.9.0 +paramz==0.9.6 +partd==1.4.2 +pillow==11.0.0 +plotly==5.24.1 +pluggy==1.0.0 +protobuf==4.25.5 +psutil==6.1.0 +py==1.11.0 +py-expression-eval==0.3.14 +pyaml==24.9.0 +pyarrow==15.0.2 +pyDOE==0.3.8 +pymoo==0.6.0 +pynisher==1.0.10 +pyparsing==3.0.8 +pyre-extensions==0.0.31 +pyrfr==0.9.0 +pyro-api==0.1.2 +pyro-ppl==1.9.1 +pytest==7.1.2 +python-dateutil==2.8.2 +pytz==2024.2 +PyYAML==6.0 +querystring-parser==1.2.4 +regex==2024.11.6 +requests==2.27.1 +requests-oauthlib==1.3.1 +ruamel.yaml==0.18.6 +ruamel.yaml.clib==0.2.12 +scikit-learn==1.5.2 +scikit-optimize==0.10.2 +scipy==1.12.0 +seaborn==0.13.2 +six==1.16.0 +smac==2.2.0 +smmap==5.0.1 +sobol-seq==0.2.0 +sortedcontainers==2.4.0 +SQLAlchemy==2.0.36 +sqlparse==0.5.2 +sympy==1.13.1 +tabulate==0.8.9 +tblib==3.0.0 +tenacity==9.0.0 +threadpoolctl==3.1.0 +tomli==2.0.1 +toolz==1.0.0 +torch==2.5.1 +torchvision==0.20.1 +tornado==6.4.2 +tqdm==4.64.0 +triton==3.1.0 +typeguard==4.4.1 +typing-inspect==0.9.0 +typing_extensions==4.12.2 +tzdata==2024.2 +urllib3==1.26.9 +Werkzeug==3.1.3 +widgetsnbextension==4.0.13 +wrapt==1.17.0 +zict==3.0.0 +zipp==3.8.0 diff --git a/run_experiment.py b/run_experiment.py index 5f3c71e..e5aefda 100644 --- a/run_experiment.py +++ b/run_experiment.py @@ -1,114 +1,233 @@ -from functools import partial -import random -from wrapper import wrapopt -from my_logger import MyIOHFormatOnEveryEvaluationLogger, MyObjectiveFunctionWrapper -import sys -import os -import json -from ioh import Experiment, get_problem, logger, problem, OptimizationType -import numpy as np -import copy -import time -from datetime import timedelta - - -def decide_doe_size(dim): - return dim - - -def decide_total_budget(dim, doe_size): - return 10 * dim + 50 - - -class AlgorithmWrapper: - def __init__(self, seed): - self.opt = None - self.seed = seed - - @staticmethod - def __fitness_function_wrapper(x, f): - if type(x) is np.ndarray: - x = x.tolist() - return f(x) - - @staticmethod - def create_fitness(my_function): - return partial(AlgorithmWrapper.__fitness_function_wrapper, f=my_function) - - def __call__(self, optimizer_name, f, fid, iid, dim): - self.dim = dim - self.optimizer_name = optimizer_name - func = partial(AlgorithmWrapper.__fitness_function_wrapper, f=f) - doe_size = decide_doe_size(self.dim) - total_budget = decide_total_budget(self.dim, doe_size) - self.opt = wrapopt( - optimizer_name, func, self.dim, total_budget, doe_size, self.seed) - self.opt.run() - - - # @property - # def lower_space_dim(self) -> int: - # if self.optimizer_name == 'BO': - # return self.dim - # return self.opt.get_lower_space_dimensionality() - # - # @property - # def extracted_information(self) -> float: - # if self.optimizer_name == 'BO': - # return 1.0 - # return self.opt.get_extracted_information() - # - # @property - # def kernel_config(self) -> str: - # return self.opt._pca.get_kernel_parameters() - # - # @property - # def out_of_the_box_solutions(self) -> int: - # return self.opt.out_solutions - - @property - def acq_opt_time(self) -> float: - return self.opt.get_acq_time() - - @property - def model_fit_time(self) -> float: - return self.opt.get_mode_time() - - @property - def cum_iteration_time(self) -> float: - return self.opt.get_iter_time() - -def run_particular_experiment(my_optimizer_name, fid, iid, dim, rep, folder_name): - algorithm = AlgorithmWrapper(rep) - l = MyIOHFormatOnEveryEvaluationLogger( - folder_name=folder_name, algorithm_name=my_optimizer_name) - print(f' Logging to the folder {l.folder_name}') - sys.stdout.flush() - # l.watch(algorithm, []) - l.watch(algorithm, ['acq_opt_time', 'model_fit_time', 'cum_iteration_time']) - p = MyObjectiveFunctionWrapper(fid, iid, dim) - p.attach_logger(l) - print("dim = ", dim) - algorithm(my_optimizer_name, p, fid, iid, dim) - l.finish_logging() - - -def run_experiment(): - if len(sys.argv) == 1: - print('No configs given') - return - with open(sys.argv[1]) as f: - m = json.load(f) - print(f'Running with config {m} ...') - start = time.process_time() - run_particular_experiment( - m['opt'], m['fid'], m['iid'], m['dim'], m['seed'], m['folder']) - end = time.process_time() - sec = int(round(end - start)) - x = str(timedelta(seconds=sec)).split(':') - print( - f' Done in {sec} seconds. Which is {x[0]} hours, {x[1]} minutes and {x[2]} seconds') - - -if __name__ == '__main__': - run_experiment() +from functools import partial +import random +from wrapper import wrapopt, Abstract_Optimizer_Wrapper +from my_logger import MyIOHFormatOnEveryEvaluationLogger2 +import sys +import os +import json + + +from typing import Callable + +import ioh + +import numpy as np +from numpy import ndarray +import copy +import time +from typing import List, Tuple, Optional, Union +#from warnings import deprecated +from datetime import timedelta + + +def decide_doe_size(dim): + return dim + + +def decide_total_budget(dim, doe_size): + return min(100 * dim , 1000) + +### ============================================ +### CONSTANTS +### ============================================ +TRIGGER = ioh.logger.trigger.Each(10) +ONIMPROVEMENT = ioh.logger.trigger.ON_IMPROVEMENT +ALWAYS = ioh.logger.trigger.ALWAYS + +### DEPRECATED CLASS ### +class AlgorithmWrapper: + def __init__(self, + seed:int): + self.opt = None + self.seed = seed + + + def __call__(self, + optimizer_name:str, + f:ioh.problem.RealSingleObjective, + fid, iid, dim, sample_zero): + self.dim = dim + self.optimizer_name = optimizer_name + doe_size = decide_doe_size(self.dim) + total_budget = decide_total_budget(self.dim, doe_size) + self.opt = wrapopt( + optimizer_name, f, self.dim, total_budget, doe_size, self.seed, sample_zero) + self.opt.run() + + + # @property + # def lower_space_dim(self) -> int: + # if self.optimizer_name == 'BO': + # return self.dim + # return self.opt.get_lower_space_dimensionality() + # + # @property + # def extracted_information(self) -> float: + # if self.optimizer_name == 'BO': + # return 1.0 + # return self.opt.get_extracted_information() + # + # @property + # def kernel_config(self) -> str: + # return self.opt._pca.get_kernel_parameters() + # + # @property + # def out_of_the_box_solutions(self) -> int: + # return self.opt.out_solutions + + @property + def acq_opt_time(self) -> float: + return self.opt.get_acq_time() + + @property + def model_fit_time(self) -> float: + return self.opt.get_mode_time() + + @property + def cum_iteration_time(self) -> float: + return self.opt.get_iter_time() + + + +def logger_func(folder_name,my_optimizer_name,sample_zero:bool,**kwargs)->ioh.logger.Analyzer: + # Set up the logger + triggers = [ONIMPROVEMENT, + TRIGGER] + + alg_info:str = "" + + if sample_zero: + alg_info = "with sampling zero vector" + + l = ioh.logger.Analyzer(triggers=triggers, + additional_properties=[ioh.logger.property.RAWYBEST], + root=os.getcwd(), + folder_name=folder_name, + algorithm_name=my_optimizer_name, + algorithm_info=alg_info, + store_positions=False) + + return l + +def logger_func_2(folder_name,my_optimizer_name,sample_zero:bool,**kwargs)->ioh.logger.Analyzer: + # Set up the logger + triggers = [ALWAYS] + + alg_info:str = "" + + if sample_zero: + alg_info = "with sampling zero vector" + + l = MyIOHFormatOnEveryEvaluationLogger2(triggers=triggers, + properties=[], + root=os.getcwd(), + folder_name=folder_name, + algorithm_name=my_optimizer_name, + algorithm_info=alg_info) + + return l + +def run_particular_experiment(**kwargs): + + + my_optimizer_name = str(kwargs.pop('opt',"BO_botorch")).strip() + fid = int(kwargs.pop('fid',1)) # Run the sphere function as default + iid = int(kwargs.pop('iid',0)) # Run the instance 0 as default + dim = int(kwargs.pop('dim',5)) # Run dimension 5 as a default + seed = int(kwargs.pop('seed',43)) # Use seed 43 as a default + rep = int(kwargs.pop('rep',1)) # Set a default of 1 repetition of the experiment + folder_name = str(kwargs.pop('folder')).strip() + logger_type = str(kwargs.pop('logger','simple')).lower().strip() + sample_zero = bool(kwargs.pop('sample_zero',False)) + + # Perform some checks + if len(folder_name) == 0 or folder_name=="": + raise ValueError("The folder name is empty!") + + + p:ioh.problem.RealSingleObjective = ioh.get_problem(fid=fid, + instance=iid, + dimension=dim, + problem_class=ioh.ProblemClass.BBOB) + + algorithm:Abstract_Optimizer_Wrapper = wrapopt(optimizer_name=my_optimizer_name, + func=p, + ml_dim=dim, + ml_total_budget=decide_total_budget(dim,decide_doe_size(dim)), + ml_DoE_size=decide_doe_size(dim), + random_seed=seed, + sample_zero=sample_zero + ) + print("dim = ", dim) + + if logger_type == "complete": + l = logger_func_2( + folder_name=folder_name, my_optimizer_name=my_optimizer_name, + sample_zero=sample_zero) + #print(f' Logging to the folder {l.folder_name}') + #sys.stdout.flush() + l.watch(algorithm, ['acq_opt_time', 'model_fit_time', 'cum_iteration_time']) + # try: + # l.watch(algorithm,'loss') + # except Exception as e: + # print(e.args) + #l.watch(p,["loss","best_loss"]) + p.attach_logger(l) + + elif logger_type == "simple": + # Use the default logger from IOH + + + # Set up the logger + l = logger_func(folder_name=folder_name, + my_optimizer_name=my_optimizer_name, + sample_zero=sample_zero) + + p.attach_logger(l) + else: + raise AttributeError("The logger type is not either set to 'simple' or 'complete'!", + name="logger_type", + obj=logger_type) + + + try: + algorithm.run() + + except KeyboardInterrupt as e: + print("---Keyboard Cancellation---", + e.args) + if isinstance(l,MyIOHFormatOnEveryEvaluationLogger2): + l.finish_logging() + except ValueError as e: + print("---Value error---", + e.args) + if isinstance(l,MyIOHFormatOnEveryEvaluationLogger2): + l.finish_logging() + + except Exception as e: + print("---Unexpected error---", + e.args) + if isinstance(l,MyIOHFormatOnEveryEvaluationLogger2): + l.finish_logging() + else: + p.detach_logger() + + +def run_experiment(): + if len(sys.argv) == 1: + print('No configs given') + return + with open(sys.argv[1]) as f: + m = json.load(f) + print(f'Running with config {m} ...') + start = time.process_time() + run_particular_experiment(**m) + end = time.process_time() + sec = int(round(end - start)) + x = str(timedelta(seconds=sec)).split(':') + print( + f' Done in {sec} seconds. Which is {x[0]} hours, {x[1]} minutes and {x[2]} seconds') + + +if __name__ == '__main__': + run_experiment() diff --git a/total_config.json b/total_config.json index 40479f4..8b321b1 100644 --- a/total_config.json +++ b/total_config.json @@ -1,11 +1,14 @@ -{ - "folder": "test", - "optimizers": ["turbo1", "turbom"], - "fids": [1, 2], - "iids": [0, 1], - "dims": [10, 20], - "reps": 2, - "lb": -5, - "ub": 5, - "extra": "Tests" -} +{ + "folder": "Benchmark_linearPCABO_medium_correct", + "optimizers": ["linearPCABO","turbom"], + "fids": [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24], + "iids": [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14], + "dims": [20,40], + "seed": [43], + "reps": 1, + "lb": -5, + "ub": 5, + "logger":"simple", + "sample_zero":0, + "extra": "Trial_linearPCABO_medium_correct" +} diff --git a/wrapper.py b/wrapper.py index b4bd1d5..83126c6 100644 --- a/wrapper.py +++ b/wrapper.py @@ -1,967 +1,2265 @@ -import time - -import numpy as np -import sys -import os -from ioh import get_problem - -class Py_CMA_ES_Wrapper: - def __init__(self, func, dim, ub, lb, total_budget, random_seed): - import pathlib - my_dir = pathlib.Path(__file__).parent.resolve() - bayes_bo_lib = os.path.join( - my_dir, 'mylib', 'lib_BO_bayesoptim', 'Bayesian-Optimization') - self.func = func - self.dim = dim - self.total_budget = total_budget - self.random_seed = random_seed - self.ub = ub - self.lb = lb - - def run(self): - from bayes_optim import RandomForest, BO, GaussianProcess - import cma - from bayes_optim.extension import RealSpace - - import random - space = RealSpace([self.lb, self.ub], random_seed=self.random_seed) * self.dim - ma = float('-inf') - argmax = None - for i in range(10*self.dim): - x = space.sample(1)[0] - def generate_initial_point(): - return np.random.uniform(low=self.lb, high=self.ub, size = self.dim) - - cma.fmin2(self.func, generate_initial_point, 1., restarts=5,options={'bounds': [ - - [self.lb]*self.dim, [self.ub]*self.dim], 'maxfevals': self.total_budget, 'seed': self.random_seed, 'tolx': 1e-8}) - - - - - def get_acq_time(self): - return self.opt.acq_opt_time - - def get_mode_time(self): - return self.opt.mode_fit_time - - def get_iter_time(self): - return self.opt.cum_iteration_time - -class SaasboWrapper: - def __init__(self, func, dim, ub, lb, total_budget, DoE_size, random_seed): - import pathlib - my_dir = pathlib.Path(__file__).parent.resolve() - sys.path.append(os.path.join(my_dir, 'mylib', 'lib_saasbo')) - - self.func = func - self.dim = dim - self.ub = ub - self.lb = lb - self.total_budget = total_budget - self.Doe_size = DoE_size - self.random_seed = random_seed - - def run(self): - #from saasbo import run_saasbo, get_acq_time, get_mode_time - from saasbo import Saasbo - - - # run_saasbo( - # self.func, - # np.ones(self.dim) * self.ub, - # np.ones(self.dim) * self.lb, - # self.total_budget, - # self.Doe_size, - # self.random_seed, - # alpha=0.01, - # num_warmup=256, - # num_samples=256, - # thinning=32, - # device="cpu", - # ) - - self.opt = Saasbo(func=self.func, - dim=self.dim, - ub=self.ub, - lb=self.lb, - total_budget=self.total_budget, - DoE_size=self.Doe_size, - random_seed=self.random_seed) - - print(self.opt.run_saasbo(self.func,np.ones(self.dim) * self.ub,np.ones(self.dim) * self.lb,self.total_budget,self.Doe_size,self.random_seed,alpha=0.01,num_warmup=256,num_samples=256,thinning=32,device="cpu",)) - - def get_acq_time(self): - return self.opt.acq_opt_time - - def get_mode_time(self): - return self.opt.mode_fit_time - - def get_iter_time(self): - return self.opt.cum_iteration_time - - - -class BO_sklearnWrapper: - def __init__(self, func, dim, ub, lb, total_budget, DoE_size, random_seed): - import pathlib - my_dir = pathlib.Path(__file__).parent.resolve() - sys.path.append(os.path.join(my_dir, 'mylib', 'lib_BO_sklearn')) - - self.func = func - self.dim = dim - self.ub = ub - self.lb = lb - self.total_budget = total_budget - self.Doe_size = DoE_size - self.random_seed = random_seed - - def run(self): - from bosklearn import bosklearn - - self.opt= bosklearn(func=self.func, - dim=self.dim, - ub=self.ub, - lb=self.lb, - total_budget=self.total_budget, - DoE_size=self.Doe_size, - random_seed=self.random_seed) - self.opt.gp_minimize(self.func, # the function to minimize - # the bounds on each dimension of x - list((((self.lb, self.ub),) * self.dim)), - acq_func="EI", # the acquisition function - n_calls=self.total_budget, # the number of evaluations of f - n_random_starts=self.Doe_size, # the number of random initialization points - noise=0.1 ** 2, # the noise level (optional) - random_state=self.random_seed) - - def get_acq_time(self): - return self.opt.acq_opt_time - - def get_mode_time(self): - return self.opt.mode_fit_time - - def get_iter_time(self): - return self.opt.cum_iteration_time - -class BO_bayesoptimWrapper: - # BO of Hao - def __init__(self, func, dim, ub, lb, total_budget, DoE_size, random_seed): - sys.path.append('./mylib/' + 'lib_' + "BO_bayesoptim") - print(sys.path) - - self.func = func - self.dim = dim - self.ub = ub - self.lb = lb - self.total_budget = total_budget - self.Doe_size = DoE_size - self.random_seed = random_seed - - def run(self): - from bayes_optim import BO, RealSpace - from bayes_optim.surrogate import GaussianProcess - - space = RealSpace([self.lb, self.ub]) * \ - self.dim # create the search space - - # hyperparameters of the GPR model - thetaL = 1e-10 * (self.ub - self.lb) * np.ones(self.dim) - thetaU = 10 * (self.ub - self.lb) * np.ones(self.dim) - model = GaussianProcess( # create the GPR model - thetaL=thetaL, thetaU=thetaU - ) - - opt = BO( - search_space=space, - obj_fun=self.func, - model=model, - DoE_size=self.Doe_size, # number of initial sample points - max_FEs=self.total_budget, # maximal function evaluation - verbose=True - ) - opt.run() - - -class BO_development_bayesoptimWrapper: - # Latest changes from Hao's repository - def __init__(self, func, dim, ub, lb, total_budget, DoE_size, random_seed): - import pathlib - my_dir = pathlib.Path(__file__).parent.resolve() - bayes_bo_lib = os.path.join( - my_dir, 'mylib', 'lib_BO_bayesoptim', 'Bayesian-Optimization') - if not os.path.isdir(bayes_bo_lib): - raise ImportError( - 'No such module Bayesian-Optimization, please consider cloning this repository: https://github.com/wangronin/Bayesian-Optimization to the folder mylib/lib_BO_bayesoptim/') - sys.path.insert(0, bayes_bo_lib) - print(sys.path) - - self.func = func - self.dim = dim - self.ub = ub - self.lb = lb - self.total_budget = total_budget - self.Doe_size = DoE_size - self.random_seed = random_seed - - def run(self): - from bayes_optim.extension import RealSpace - from bayes_optim.bayes_opt import BO - - space = RealSpace([self.lb, self.ub], random_seed=self.random_seed) * self.dim - opt = BO( - search_space=space, - obj_fun=self.func, - DoE_size=self.Doe_size, - n_point=1, - random_seed=self.random_seed, - acquisition_optimization={"optimizer": "BFGS"}, - max_FEs=self.total_budget, - verbose=False, - ) - opt.run() - -class KPCABOWrapper: - # Latest changes from Hao's repository - def __init__(self, func, dim, ub, lb, total_budget, DoE_size, random_seed): - import pathlib - my_dir = pathlib.Path(__file__).parent.resolve() - bayes_bo_lib = os.path.join( - my_dir, 'mylib', 'lib_BO_bayesoptim', 'Bayesian-Optimization') - if not os.path.isdir(bayes_bo_lib): - raise ImportError( - 'No such module Bayesian-Optimization, please unzip the folder Bayesian-Optimization.zip and move the unzip folder to mylib/lib_BO_bayesoptim/') - sys.path.insert(0, bayes_bo_lib) - print(sys.path) - - self.func = func - self.dim = dim - self.ub = ub - self.lb = lb - self.total_budget = total_budget - self.Doe_size = DoE_size - self.random_seed = random_seed - - def run(self): - - - from bayes_optim import RandomForest, BO, GaussianProcess - - from bayes_optim.extension import PCABO, RealSpace, KernelPCABO, KernelFitStrategy - from bayes_optim.mylogging import eprintf - - import random - - - space = RealSpace([self.lb, self.ub], random_seed=self.random_seed) * self.dim - self.opt = KernelPCABO( - search_space=space, - obj_fun=self.func, - DoE_size=self.Doe_size, - max_FEs=self.total_budget, - verbose=False, - n_point=1, - acquisition_optimization={"optimizer": "BFGS"}, - max_information_loss=0.1, - kernel_fit_strategy=KernelFitStrategy.AUTO, - NN=self.dim, - random_seed=self.random_seed - ) - - print(self.opt.run()) - - def get_acq_time(self): - return self.opt.acq_opt_time - - def get_mode_time(self): - return self.opt.mode_fit_time - - def get_iter_time(self): - return self.opt.cum_iteration_time - - -class randomWrapper: - def __init__(self, func, dim, ub, lb, total_budget, DoE_size, random_seed): - - self.func = func - self.dim = dim - self.ub = ub - self.lb = lb - self.total_budget = total_budget - self.Doe_size = DoE_size - self.random_seed = random_seed - - def run(self): - import ioh - - def random_search(func, search_space, budget): - """ - Implementa la ricerca casuale per minimizzare un problema di dimensione n. - - Parameters: - - objective_function: La funzione obiettivo da minimizzare. Deve accettare un vettore di dimensione n come input e restituire un valore numerico. - - search_space: Una lista di tuple, ognuna contenente il range di valori ammissibili per ciascuna dimensione. - - budget: Il numero massimo di valutazioni della funzione obiettivo consentite. - - Returns: - - best_solution: La migliore soluzione trovata. - - best_score: Il valore minimo della funzione obiettivo associato alla migliore soluzione. - """ - best_solution = None - best_score = float('inf') - - for _ in range(budget): - solution = [np.random.uniform(low, high) for (low, high) in search_space] - score = self.func(solution) - - # Aggiorna la migliore soluzione se necessario - if score < best_score: - best_solution = solution - best_score = score - print(best_score) - return best_solution, best_score - search_space = [(self.lb, self.ub) for _ in range(self.dim)] - budget = self.total_budget - random_search(self.func, search_space, budget) - - -class linearPCABOWrapper: - def __init__(self, func, dim, ub, lb, total_budget, DoE_size, random_seed): - #import sys - #sys.path.append('./mylib/' + 'lib_' + "linearPCABO") - #print(sys.path) - import pathlib - my_dir = pathlib.Path(__file__).parent.resolve() - bayes_bo_lib = os.path.join( - my_dir, 'mylib', 'lib_BO_bayesoptim', 'Bayesian-Optimization') - if not os.path.isdir(bayes_bo_lib): - raise ImportError( - 'No such module Bayesian-Optimization, please unzip the folder Bayesian-Optimization.zip and move the unzip folder to mylib/lib_BO_bayesoptim/') - sys.path.insert(0, bayes_bo_lib) - print(sys.path) - #sys.path.insert(0, bayes_bo_lib) - #print(sys.path) - self.func = func - self.dim = dim - self.ub = ub - self.lb = lb - self.total_budget = total_budget - self.Doe_size = DoE_size - self.random_seed = random_seed - - def run(self): - #import sys - #sys.path.insert(0, "./mylib/lib_linearPCABO/Bayesian-Optimization") - from bayes_optim.extension import PCABO, RealSpace - - space = RealSpace([self.lb, self.ub]) * self.dim - self.opt = PCABO( - search_space=space, - obj_fun=self.func, - DoE_size=self.Doe_size, - max_FEs=self.total_budget, - verbose=False, - n_point=1, - n_components=0.90, - acquisition_optimization={"optimizer": "BFGS"}, - random_seed=self.random_seed - ) - - print(self.opt.run()) - - def get_acq_time(self): - return self.opt.acq_opt_time - - def get_mode_time(self): - return self.opt.mode_fit_time - - def get_iter_time(self): - return self.opt.cum_iteration_time - - -class RDUCBWrapper: - def __init__(self, func, dim, ub, lb, total_budget, DoE_size, random_seed): - # import sys - # sys.path.append('./mylib/' + 'lib_' + "linearPCABO") - # print(sys.path) - import pathlib - my_dir = pathlib.Path(__file__).parent.resolve() - sys.path.append(os.path.join(my_dir, 'mylib', 'lib_RDUCB/HEBO/RDUCB')) - print(sys.path) - # sys.path.insert(0, bayes_bo_lib) - # print(sys.path) - self.func = func - self.dim = dim - self.ub = ub - self.lb = lb - self.total_budget = total_budget - self.Doe_size = DoE_size - self.random_seed = random_seed - - def run(self): - # import sys - # sys.path.insert(0, "./mylib/lib_linearPCABO/Bayesian-Optimization") - - from hdbo.algorithms import RDUCB - self.opt = RDUCB( algorithm_random_seed=self.random_seed, - eps=-1, - exploration_weight= 'lambda t: 0.5 * np.log(2*t)', - graphSamplingNumIter=100, - learnDependencyStructureRate=1, - lengthscaleNumIter=2, - max_eval=-4, - noise_var= 0.1, - param_n_iter=16, - size_of_random_graph=0.2, - # data_random_seed=self.random_seed, - fn_noise_var=0.15, - grid_size=150, - fn= self.func, -n_iter=self.total_budget-self.Doe_size, -n_rand=self.Doe_size, dim=self.dim,) - self.opt.run() - - def get_acq_time(self): - return self.opt.mybo.acq_opt_time - - def get_mode_time(self): - return self.opt.mybo.mode_fit_time - - def get_iter_time(self): - return self.opt.mybo.cum_iteration_time - - -class turbo1Wrapper: - def __init__(self, func, dim, ub, lb, total_budget, DoE_size, random_seed): - #import sys - #sys.path.append('./mylib/' + 'lib_' + "turbo1") - #print(sys.path) - import pathlib - my_dir = pathlib.Path(__file__).parent.resolve() - sys.path.append(os.path.join(my_dir, 'mylib', 'lib_turbo1')) - print(sys.path) - - self.func = func - self.dim = dim - self.ub = ub - self.lb = lb - self.total_budget = total_budget - self.Doe_size = DoE_size - self.random_seed = random_seed - - def run(self): - from turbo import Turbo1 - import torch - import math - import matplotlib - import matplotlib.pyplot as plt - self.opt = Turbo1( - f=self.func, # Handle to objective function - lb=np.ones(self.dim) * self.lb, # Numpy array specifying lower bounds - ub=np.ones(self.dim) * self.ub, # Numpy array specifying upper bounds - n_init=self.Doe_size, # Number of initial bounds from an Latin hypercube design - max_evals=self.total_budget, # Maximum number of evaluations - batch_size=5, # How large batch size TuRBO uses - verbose=True, # Print information from each batch - use_ard=True, # Set to true if you want to use ARD for the GP kernel - max_cholesky_size=2000, # When we switch from Cholesky to Lanczos - n_training_steps=50, # Number of steps of ADAM to learn the hypers - min_cuda=1024, # Run on the CPU for small datasets - device="cpu", # "cpu" or "cuda" - dtype="float64", # float64 or float32 - ) - self.opt.optimize() - - def get_acq_time(self): - return self.opt.acq_opt_time - - def get_mode_time(self): - return self.opt.mode_fit_time - - def get_iter_time(self): - return self.opt.cum_iteration_time - - -class turbomWrapper: - def __init__(self, func, dim, ub, lb, total_budget, DoE_size, random_seed): - #import sys - #sys.path.append('./mylib/' + 'lib_' + "turbom") - #print(sys.path) - - import pathlib - my_dir = pathlib.Path(__file__).parent.resolve() - sys.path.append(os.path.join(my_dir, 'mylib', 'lib_turbo1')) - print(sys.path) - - self.func = func - self.dim = dim - self.ub = ub - self.lb = lb - self.total_budget = total_budget - self.Doe_size = DoE_size - self.random_seed = random_seed - - def run(self): - from turbo import TurboM - import torch - import math - import matplotlib - import matplotlib.pyplot as plt - #tr = math.floor(self.total_budget / self.Doe_size) - 1 - tr = int(self.dim/5) - n_init = math.floor(self.Doe_size/tr) - self.opt = TurboM( - f=self.func, # Handle to objective function - lb=np.ones(self.dim) * self.lb, # Numpy array specifying lower bounds - ub=np.ones(self.dim) * self.ub, # Numpy array specifying upper bounds - n_init=n_init, # Number of initial bounds from an Symmetric Latin hypercube design - max_evals=self.total_budget, # Maximum number of evaluations - n_trust_regions=tr, # Number of trust regions - batch_size=5, # How large batch size TuRBO uses - verbose=True, # Print information from each batch - use_ard=True, # Set to true if you want to use ARD for the GP kernel - max_cholesky_size=2000, # When we switch from Cholesky to Lanczos - n_training_steps=50, # Number of steps of ADAM to learn the hypers - min_cuda=1024, # Run on the CPU for small datasets - device="cpu", # "cpu" or "cuda" - dtype="float64", # float64 or float32 - ) - self.opt.optimize() - - def get_acq_time(self): - return self.opt.acq_opt_time - - def get_mode_time(self): - return self.opt.mode_fit_time - - def get_iter_time(self): - return self.opt.cum_iteration_time - -class EBOWrapper: - def __init__(self, func, dim, ub, lb, total_budget, DoE_size, random_seed): - # import sys - # sys.path.append('./mylib/' + 'lib_' + "EBO") - # print(sys.path) - - import pathlib - my_dir = pathlib.Path(__file__).parent.resolve() - sys.path.append(os.path.join(my_dir, 'mylib', 'lib_EBO')) - print(sys.path) - - self.func = func - self.dim = dim - self.ub = ub - self.lb = lb - self.total_budget = total_budget - self.Doe_size = DoE_size - self.random_seed = random_seed - - def run(self): - import numpy.matlib as nm - import functools - from ebo_core.ebo import ebo - from test_functions.simple_functions import sample_z - import time - import logging - - dx = self.dim - z = sample_z(dx) - k = np.array([10] * dx) - x_range = nm.repmat([[self.lb], [self.ub]], 1, self.dim) - x_range = x_range.astype(float) - sigma = 0.01 - n = self.Doe_size - budget = self.total_budget - f = self.func - f = functools.partial(lambda f, x: -f(x), f) - options = {'x_range': x_range, # input domain - 'dx': x_range.shape[1], # input dimension - 'max_value': 0, # target value - 'T': budget, # number of iterations - 'B': 1, # number of candidates to be evaluated - 'dim_limit': 3, # max dimension of the input for each additive function component - 'isplot': 0, # 1 if plotting the result; otherwise 0. - 'z': None, 'k': None, # group assignment and number of cuts in the Gibbs sampling subroutine - 'alpha': 1., # hyperparameter of the Gibbs sampling subroutine - 'beta': np.array([5., 2.]), - 'opt_n': 1000, # points randomly sampled to start continuous optimization of acfun - 'pid': 'test3', # process ID for Azure - 'datadir': 'tmp_data/', # temporary data directory for Azure - 'gibbs_iter': 10, # number of iterations for the Gibbs sampling subroutine - 'useAzure': False, # set to True if use Azure for batch evaluation - 'func_cheap': True, # if func cheap, we do not use Azure to test functions - 'n_add': None, # this should always be None. it makes dim_limit complicated if not None. - 'nlayers': 100, # number of the layers of tiles - 'gp_type': 'l1', # other choices are l1, sk, sf, dk, df - 'gp_sigma': 0.1, # noise standard deviation - 'n_bo': 10, # min number of points selected for each partition - 'n_bo_top_percent': 0.5, # percentage of top in bo selections - 'n_top': 10, # how many points to look ahead when doing choose Xnew - 'min_leaf_size': 10, # min number of samples in each leaf - 'max_n_leaves': 10, # max number of leaves - 'thresAzure': 1, # if batch size > thresAzure, we use Azure - 'save_file_name': 'tmp/tmp.pk', - } - self.opt = ebo(f, options) - start = time.time() - self.opt.run() - - print("elapsed time: ", time.time() - start) - - def get_acq_time(self): - return self.opt.acq_opt_time - - def get_mode_time(self): - return self.opt.mode_fit_time - - def get_iter_time(self): - return self.opt.cum_iteration_time - -class EBO_BWrapper: - def __init__(self, func, dim, ub, lb, total_budget, DoE_size, random_seed): - # import sys - # sys.path.append('./mylib/' + 'lib_' + "EBO") - # print(sys.path) - - import pathlib - my_dir = pathlib.Path(__file__).parent.resolve() - sys.path.append(os.path.join(my_dir, 'mylib', 'lib_EBO')) - print(sys.path) - - self.func = func - self.dim = dim - self.ub = ub - self.lb = lb - self.total_budget = total_budget - self.Doe_size = DoE_size - self.random_seed = random_seed - - def run(self): - import numpy.matlib as nm - import functools - from ebo_core.ebo import ebo - from test_functions.simple_functions import sample_z - import time - import logging - - dx = self.dim - z = sample_z(dx) - k = np.array([10] * dx) - x_range = nm.repmat([[self.lb], [self.ub]], 1, self.dim) - x_range = x_range.astype(float) - sigma = 0.01 - n = self.Doe_size - budget = self.total_budget - t= int (float(budget)/10) - f = self.func - f = functools.partial(lambda f, x: -f(x), f) - options = {'x_range': x_range, # input domain - 'dx': x_range.shape[1], # input dimension - 'max_value': 0, # target value - 'T': t, # number of iterations - 'B': 10, # number of candidates to be evaluated - 'dim_limit': 3, # max dimension of the input for each additive function component - 'isplot': 0, # 1 if plotting the result; otherwise 0. - 'z': None, 'k': None, # group assignment and number of cuts in the Gibbs sampling subroutine - 'alpha': 1., # hyperparameter of the Gibbs sampling subroutine - 'beta': np.array([5., 2.]), - 'opt_n': 1000, # points randomly sampled to start continuous optimization of acfun - 'pid': 'test3', # process ID for Azure - 'datadir': 'tmp_data/', # temporary data directory for Azure - 'gibbs_iter': 10, # number of iterations for the Gibbs sampling subroutine - 'useAzure': False, # set to True if use Azure for batch evaluation - 'func_cheap': True, # if func cheap, we do not use Azure to test functions - 'n_add': None, # this should always be None. it makes dim_limit complicated if not None. - 'nlayers': 100, # number of the layers of tiles - 'gp_type': 'l1', # other choices are l1, sk, sf, dk, df - 'gp_sigma': 0.1, # noise standard deviation - 'n_bo': 10, # min number of points selected for each partition - 'n_bo_top_percent': 0.5, # percentage of top in bo selections - 'n_top': 10, # how many points to look ahead when doing choose Xnew - 'min_leaf_size': 10, # min number of samples in each leaf - 'max_n_leaves': 10, # max number of leaves - 'thresAzure': 1, # if batch size > thresAzure, we use Azure - 'save_file_name': 'tmp/tmp.pk', - } - self.opt = ebo(f, options) - start = time.time() - self.opt.run() - - print("elapsed time: ", time.time() - start) - - def get_acq_time(self): - return self.opt.acq_opt_time - - def get_mode_time(self): - return self.opt.mode_fit_time - - def get_iter_time(self): - return self.opt.cum_iteration_time - -class ALEBOWrapper: - def __init__(self, func, dim, ub, lb, total_budget, DoE_size, random_seed): - # import sys - # sys.path.append('./mylib/' + 'lib_' + "linearPCABO") - # print(sys.path) - - # from ax.modelbridge.strategies.alebo import ALEBOStrategy - # sys.path.insert(0, bayes_bo_lib) - # print(sys.path) - self.func = func - self.dim = dim - self.ub = ub - self.lb = lb - self.total_budget = total_budget - self.Doe_size = DoE_size - self.random_seed = random_seed - self.iter = 0 - - def run(self): - # import pathlib - # my_dir = pathlib.Path(__file__).parent.resolve() - # sys.path.append(os.path.join(my_dir, 'mylib', 'lib_ALEBO')) - # import numpy as np - from ax.utils.measurement.synthetic_functions import branin - print(sys.path) - - def branin_evaluation_function(parameterization): - # Evaluates Branin on the first two parameters of the parameterization. - # Other parameters are unused. - x = np.array([parameterization["x0"], parameterization["x1"]]) - - return {"objective": (branin(x), 0.0)} - def function(parameterization): - # Evaluates Branin on the first two parameters of the parameterization. - # Other parameters are unused. - x = np.array([parameterization[f'x{i}'] for i in range(self.dim)]) - self.iter+=1 - if self.iter == self.total_budget: - print("Optimization is complete, cannot run another trial.") - exit() - return {"objective": (self.func(x), 0.0)} - - parameters = [ - {"name": "x0", "type": "range", "bounds": [self.lb, self.ub], "value_type": "float"}, - {"name": "x1", "type": "range", "bounds": [self.lb, self.ub], "value_type": "float"}, - ] - parameters.extend([ - {"name": f"x{i}", "type": "range", "bounds": [self.lb, self.ub], "value_type": "float"} - for i in range(2, self.dim) - ]) - from ax.modelbridge.strategies.alebo import ALEBOStrategy - alebo_strategy = ALEBOStrategy(D=self.dim, d=4, init_size=self.Doe_size) - alebo_strategy._steps[0].model_kwargs.update({"seed": self.random_seed}) - from ax.service.managed_loop import optimize - self.opt = optimize( - parameters=parameters, - experiment_name="test", - objective_name="objective", - evaluation_function=function, - minimize=True, - total_trials=self.total_budget, - generation_strategy=alebo_strategy, - ) - self.opt() -# def run(self): -# # import sys -# # sys.path.insert(0, "./mylib/lib_linearPCABO/Bayesian-Optimization") -# parameters = [ -# {"name": "x0", "type": "range", "bounds": [self.lb, self.ub], "value_type": "float"}, -# {"name": "x1", "type": "range", "bounds": [self.lb, self.ub], "value_type": "float"}, -# ] -# parameters.extend([ -# {"name": f"x{i}", "type": "range", "bounds": [self.lb, self.ub], "value_type": "float"} -# for i in range(2, self.dim) -# ]) -# alebo_strategy = ALEBOStrategy(D=self.dim, d=10, init_size=self.Doe_size) -# from ax.service.managed_loop import optimize -# self.opt = optimize( -# parameters=parameters, -# experiment_name="test", -# objective_name="objective", -# evaluation_function=self.func, -# minimize=True, -# total_trials=self.total_budget, -# generation_strategy=alebo_strategy, -# ) -# self.opt() - - def get_acq_time(self): - return self.opt.acq_opt_time - - def get_mode_time(self): - return self.opt.mode_fit_time - - def get_iter_time(self): - return self.opt.cum_iteration_time - -class HEBOWrapper: - def __init__(self, func, dim, ub, lb, total_budget, DoE_size, random_seed): - # import sys - # sys.path.append('./mylib/' + 'lib_' + "linearPCABO") - # print(sys.path) - # import pathlib - # my_dir = pathlib.Path(__file__).parent.resolve() - # sys.path.append(os.path.join(my_dir, 'mylib', 'lib_RDUCB/HEBO/RDUCB')) - # print(sys.path) - # sys.path.insert(0, bayes_bo_lib) - # print(sys.path) - self.func = func - self.dim = dim - self.ub = ub - self.lb = lb - self.total_budget = total_budget - self.Doe_size = DoE_size - self.random_seed = random_seed - - def run(self): - # import sys - # sys.path.insert(0, "./mylib/lib_linearPCABO/Bayesian-Optimization") - import pandas as pd - import numpy as np - from hebo.design_space.design_space import DesignSpace - from hebo.optimizers.hebo import HEBO - # def obj(params: pd.DataFrame) -> np.ndarray: - # return ((params.values - 0.37) ** 2).sum(axis=1).reshape(-1, 1) - def obj(params: pd.DataFrame) -> np.ndarray: - # Imposta la funzione BBOB desiderata (ad esempio, la funzione 1) - problem = self.func # Parametri: dimensione, funzione BBOB (1-24) - - # Calcola il valore della funzione obiettivo per ciascuna riga dei parametri - values = [problem(np.squeeze(row.values)) for _, row in params.iterrows()] - - # Restituisci i valori come un array numpy - return np.array(values).reshape(-1, 1) - - dimension_specs = [{"name": f"param{i}", "type": "num", 'lb' : self.lb, 'ub' : self.ub } for i in - range(1, self.dim + 1)] - space = DesignSpace().parse(dimension_specs) - #space = DesignSpace().parse([{'name': 'x', 'type': 'int', 'lb': self.lb, 'ub': self.ub}]) - self.opt = HEBO(space, rand_sample=self.Doe_size, scramble_seed=self.random_seed ) - for i in range(self.total_budget): - rec = self.opt.suggest(n_suggestions=1) - self.opt.observe(rec, obj(rec)) - print('After %d iterations, best obj is %.2f' % (i, self.opt.y.min())) - self.opt.cum_iteration_time = time.process_time() - - def get_acq_time(self): - return self.opt.acq_opt_time - - def get_mode_time(self): - return self.opt.mode_fit_time - - def get_iter_time(self): - return self.opt.cum_iteration_time - -import torch -import os -import sys -from botorch.models import SingleTaskGP -from botorch.fit import fit_gpytorch_mll -from botorch.acquisition import LogExpectedImprovement -from botorch.optim.optimize import optimize_acqf -from botorch.sampling import SobolQMCNormalSampler -from gpytorch.mlls import ExactMarginalLogLikelihood -from botorch.models.transforms import Normalize, Standardize -class BO_botorchWrapper: - def __init__(self, func, dim, ub, lb, total_budget, DoE_size, random_seed): - self.func = func - self.dim = dim - self.lb = torch.tensor([lb] * dim, dtype=torch.float32) - self.ub = torch.tensor([ub] * dim, dtype=torch.float32) - bounds = torch.stack([self.lb, self.ub]) - self.total_budget = total_budget - self.DoE_size = DoE_size - self.random_seed = random_seed - torch.manual_seed(random_seed) - def run(self): - self.X = self.lb + (self.ub - self.lb) * torch.rand((self.DoE_size, self.dim)) - results = [[self.func(x.tolist())] for x in self.X] - self.Y = torch.tensor(results, dtype=torch.float32).view(-1, 1) - - for i in range(self.total_budget - self.DoE_size): - self.model = SingleTaskGP(self.X, self.Y, input_transform=Normalize(d=self.dim), - outcome_transform=Standardize(m=1),) - self.mll = ExactMarginalLogLikelihood(self.model.likelihood, self.model) - fit_gpytorch_mll(self.mll) - - EI = LogExpectedImprovement(self.model, best_f=self.Y.max(), maximize=False) - bounds = torch.stack([self.lb, self.ub]).unsqueeze(1) if self.dim == 1 else torch.stack([self.lb, self.ub]) - candidate, _ = optimize_acqf( - EI, - bounds=bounds, - q=1, - num_restarts=5, - raw_samples=20, - ) - - new_y = torch.tensor([[self.func(candidate.tolist()[0])]]) - - self.X = torch.cat([self.X, candidate]) - self.Y = torch.cat([self.Y, new_y]) - - -def wrapopt(optimizer_name, func, ml_dim, ml_total_budget, ml_DoE_size, random_seed): - ub = +5 - lb = -5 - if optimizer_name == "saasbo": - return SaasboWrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, DoE_size=ml_DoE_size, - random_seed=random_seed) - if optimizer_name == "BO_sklearn": - return BO_sklearnWrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, DoE_size=ml_DoE_size, - random_seed=random_seed) - if optimizer_name == "BO_bayesoptim": - return BO_bayesoptimWrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, DoE_size=ml_DoE_size, - random_seed=random_seed) - if optimizer_name == "random": - return randomWrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, DoE_size=ml_DoE_size, - random_seed=random_seed) - if optimizer_name == "linearPCABO": - return linearPCABOWrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, DoE_size=ml_DoE_size, - random_seed=random_seed) - if optimizer_name == "turbo1": - return turbo1Wrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, DoE_size=ml_DoE_size, - random_seed=random_seed) - if optimizer_name == "turbom": - return turbomWrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, DoE_size=ml_DoE_size, - random_seed=random_seed) - if optimizer_name == 'BO_dev_Hao': - return BO_development_bayesoptimWrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, DoE_size=ml_DoE_size, - random_seed=random_seed) - if optimizer_name == 'EBO': - return EBOWrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, DoE_size=ml_DoE_size, - random_seed=random_seed) - if optimizer_name == 'EBO_B': - return EBO_BWrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, DoE_size=ml_DoE_size, - random_seed=random_seed) - if optimizer_name == 'KPCABO': - return KPCABOWrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, DoE_size=ml_DoE_size, - random_seed=random_seed) - if optimizer_name == 'pyCMA': - return Py_CMA_ES_Wrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, - random_seed=random_seed) - - if optimizer_name == 'RDUCB': - return RDUCBWrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, DoE_size=ml_DoE_size, - random_seed=random_seed) - if optimizer_name == 'ALEBO': - return ALEBOWrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, DoE_size=ml_DoE_size, - random_seed=random_seed) - if optimizer_name == 'HEBO': - return HEBOWrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, DoE_size=ml_DoE_size, - random_seed=random_seed) - if optimizer_name == 'BO_botorch': - return BO_botorchWrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, DoE_size=ml_DoE_size, - random_seed=random_seed) - -if __name__ == "__main__": - dim = 10 - total_budget = 30 - doe_size = dim - seed = 2 - # Algorithm alternatives: - algorithm_name = "turbo1" - f = get_problem(1, dimension=dim, instance=1, problem_type='Real') - - opt = wrapopt(algorithm_name, f, dim, total_budget, doe_size, seed) - opt.run() +import time + +import numpy as np +import sys +import os +from ioh import get_problem +from ioh.iohcpp.problem import RealSingleObjective + +from abc import ABC, abstractmethod + +from copy import copy, deepcopy + +import pathlib + +from typing import Union, List, Tuple, Optional, Callable + +import warnings + +## TODO: ADDENDA TO HANDLE IOH Objects +from ioh.iohcpp.problem import RealSingleObjective + +__set_directory__= os.path.abspath(os.path.dirname(__file__)) +print(__set_directory__) + + + +## TODO: ADDENDA TO GENERATE AN 'ABSTRACT CLASS' FOR THE OTHER METHODS TO INHERIT FROM + +class Abstract_Optimizer_Wrapper(ABC): + r""" + This is an abstract class to avoid further repetition of methods along all the + upcoming wrappers. + """ + + # The library pointing to the library + libpath:Union[pathlib.Path,str]= pathlib.Path("") + + # The base directory (which is the same as this file) + _base_dir:pathlib.Path = pathlib.Path(__file__).parent.resolve() + + def __init__(self, + func:Callable, + dim:int, + ub:np.ndarray, + lb:np.ndarray, + total_budget:Optional[int]=100, + random_seed:Optional[int]=42): + + r""" + This is the class initializer for the optimizer wrapper; + + Args: + ------------------- + - func: `Callable`: A callable object which returns a function evaluation given a set of parameters. + - dim: `int`: The dimension of the optimization problem. + - ub: `np.ndarray`: The general upper bound of the problem. + - lb: `np.ndarray`: The general lower bound of the problem. + - total_budget: `Optional[int]`: The budget of evaluations of the optimizer. Set to 100 by default. + - random_seed: `Optional[int]`: An integer denoting the initial seed of the pseudo-random number generator. By default, it is set to 42. + """ + + # Append the search library + full_path = pathlib.Path(os.path.join(self._base_dir,self.libpath)).absolute() + + #Register + self._register_new_library(full_path) + + + # Set the primary properties + self.func = func + self.dim = dim + self.total_budget = total_budget + self.random_seed = random_seed + self.ub = ub + self.lb = lb + + @abstractmethod + def run(self,*args,**kwargs)->None: + r""" + This is a method to kickstart the optimization procedure. + """ + pass + + @staticmethod + def _register_new_library(ppath:Union[pathlib.Path,str])->None: + r""" + This function registers the dynamic library and points the folder to point to + the files required to run some optimization algorithm. + + Args: + ---------- + - ppath: `Union[pathlib.Path,str]`: A composite path to point the location of the library + """ + + # Appends the library path given by parameter + if not isinstance(ppath,pathlib.Path): + # Modify the instance to be an instance of the library `pathlib.Path` + ppath = pathlib.Path(ppath) + + if not ppath.exists(): + raise AttributeError(f"The current path doesn't exist, please check the dependency {ppath.absolute()} exists!", + name="libpath", + obj=ppath) + else: + # Append the library in case this exists + sys.path.append(str(ppath.absolute())) + + # @property + # def libpath(self)->str: + # r""" + # Defines the library path to add + # """ + + # return self.libpath.absolute() + + @property + def full_libpath(self)->str: + r""" + Returns the complete full path to the library + """ + + return str(self._base_dir.joinpath(self.libpath).absolute()) + + @property + def func(self)->Callable: + r""" + Refers to the function object attached to the optimizer + """ + + return self.__func + + @func.setter + def func(self,new_func:Callable)->None: + r""" + This is the setter of the `func` property. + """ + + if callable(new_func): + # Set the function if this is the case + self.__func = new_func + + ### TODO: This is a handler in case the instance of the problem is an IOH instance + if issubclass(type(new_func),RealSingleObjective): + # Write in this case the information about the problem + self.dim = new_func.meta_data.n_variables + self.lb = new_func.bounds.lb + self.ub = new_func.bounds.ub + else: + raise AttributeError("The passed function is not a `callable`!", + name="func", + obj=new_func) + + @func.deleter + def func(self)->bool: + return_val:bool = True + try: + del self.__func + except: + return_val = False + print("There is no function object attached to this class.") + else: + return return_val + + @property + def dim(self)->int: + r""" + This property refers to the dimensionality of the evaluated problem, + and, therefore, the dimensionality handled by the algorithm. + """ + + return self.__dim + + @dim.setter + def dim(self,new_dim)->None: + r""" + Setter of the problem dimensionality + """ + + if isinstance(new_dim,int) and new_dim > 0: + # Change the dimension if the condition of positivity is fulfilled + self.__dim = new_dim + + else: + raise AttributeError("The dimensionality must be a positive integer", + name="new_dim", + obj=new_dim) + + @property + def lb(self)->float: + r""" + The lower bound of the problem + """ + + return self.__lb + + @lb.setter + def lb(self, + new_lb:Union[List[float],np.ndarray,float,int])->None: + r""" + The setter of the lower bound of the problem + """ + + if isinstance(new_lb,(np.ndarray,np.matrix,list)): + warnings.warn("Using the first element as the lower bound!") + new_lb = new_lb[0] + + self.__lb = float(new_lb) + + + + @property + def ub(self)->float: + r""" + The upper bound of the problem + """ + + return self.__ub + + + @ub.setter + def ub(self, + new_ub:Union[List[float],np.ndarray,float])->None: + r""" + The setter of the upper bound of the problem + """ + + if isinstance(new_ub,(np.ndarray,np.matrix,list)): + warnings.warn("Using the first element as the lower bound!") + new_ub = new_ub[0] + + self.__ub = float(new_ub) + + + + @property + def total_budget(self)->int: + r""" + This returns the total budget as a class property + """ + + return self.__total_budget + + @total_budget.setter + def total_budget(self,new_budget:int)->None: + r""" + This sets the total budget of evaluations of the optimizer. + """ + + if isinstance(new_budget,int) and new_budget>0: + self.__total_budget = new_budget + + else: + raise AttributeError("The total budget must be a positive integer", + name="new_budget", + obj=new_budget) + + @property + def random_seed(self)->int: + r""" + Returns the random seed property given to the algorithm + """ + + return self.__random_seed + + @random_seed.setter + def random_seed(self, new_random_seed:int)->None: + r""" + Sets a new random seed to kickstart the algorithm + """ + + if isinstance(new_random_seed,int) and new_random_seed > -1: + # Set the random seed if this condition is fulfilled + self.__random_seed = new_random_seed + + else: + raise AttributeError("The random seed must be a positive integer or 0", + name="new_random_seed", + obj= new_random_seed) + + @property + def opt(self)->Union[Callable,None]: + r""" + A representer of the optimizer + """ + + return self.__opt + + @opt.setter + def opt(self, new_opt:Callable)->None: + r""" + The setter of the optimizer defined for the wrapper. + """ + self.__opt = new_opt + + + @opt.deleter + def opt(self)->bool: + r""" + The deleter object of the optimizer property + """ + return_val:bool = True + try: + del self.__opt + except: + return_val = False + print("There is no optimizer attached to this class.") + else: + return return_val + + ### NOTE: The following functions are only defined for Bayesian Optimizer types, + ### but will be defined within this abstract class for logging purposes. + + @property + def acq_opt_time(self)->float: + return self.get_acq_time() + + def get_acq_time(self)->float: + r""" + Get the time elapsed by the acquisition at each iteration of the algorithm + """ + + if self.opt is not None: + if hasattr(self.opt,"acq_opt_time"): + return getattr(self.opt,"acq_opt_time") + else: + warnings.warn("The optimizer doesn't have the `acq_opt_time` attribute") + return 0 + + else: + raise ValueError("The optimizer is not set") + + @property + def mode_fit_time(self)->float: + return self.get_mode_time() + + + def get_mode_time(self)->float: + r""" + Get the model fitting time + """ + + if self.opt is not None: + if hasattr(self.opt,"mode_fit_time"): + return getattr(self.opt,"mode_fit_time") + else: + warnings.warn("The optimizer doesn't have the `mode_fit_time` attribute") + return 0 + + else: + raise ValueError("The optimizer is not set") + + @property + def cum_iteration_time(self)->float: + return self.get_iter_time() + + + def get_iter_time(self)->float: + r""" + Get the cumulative iteration time + """ + + if self.opt is not None: + if hasattr(self.opt,"cum_iteration_time"): + return getattr(self.opt,"cum_iteration_time") + else: + warnings.warn("The optimizer doesn't have the `cum_iteration_time` attribute") + return 0 + + else: + raise ValueError("The optimizer is not set") + + +class Abstract_Bayesian_Optimizer_Wrapper(Abstract_Optimizer_Wrapper): + r""" + This is a "byproduct" class to manage the Bayesian Optimization Algorithms. + This class just adds a DoE property to define the size of the initial DoE for any corresponding + Bayesian Optimization class algorithm. + """ + + libpath = pathlib.Path("") + + def __init__(self, + func, + dim, + ub, + lb, + DoE_size:Optional[int]=None, + sample_zero:bool = False, + total_budget = ..., + random_seed = ...): + + r""" + This is the initializer for the corresponding Bayesian Optimizers. + """ + + + # Set the primary properties + self.func = func + self.dim = dim + self.total_budget = total_budget + self.random_seed = random_seed + self.ub = ub + self.lb = lb + + # Set the DoE Size + if DoE_size is None: + # Set this to the dimension + DoE_size = dim + + self.Doe_size = DoE_size + + + # This is a new add-on to tell the optimizer to sample a 0 vector on the LHS/Initial sampling stage + self.sample_zero = sample_zero + + # Append the search library + full_path = str(self._base_dir.joinpath(self.libpath)) + + #Register + self._register_new_library(full_path) + + @abstractmethod + def run(self, *args, **kwargs): + pass + + @property + def Doe_size(self)->int: + r""" + This property returns the DoE Size + """ + + return self.__doe_size + + @Doe_size.setter + def Doe_size(self, new_doe_size:int)->int: + r""" + This is the setter of the DoE Size property + """ + + if isinstance(new_doe_size,int) and new_doe_size>0: + self.__doe_size = new_doe_size + + else: + raise AttributeError("The new DoE Size must be a positive integer", + name="new_doe_size", + obj=new_doe_size) + + @property + def sample_zero(self)->bool: + return self.__sample_zero + + @sample_zero.setter + def sample_zero(self,new_change:bool)->None: + try: + new_change = bool(new_change) + except Exception as e: + print(e.args) + + # Set the value + self.__sample_zero = new_change + + + + +class Py_CMA_ES_Wrapper(Abstract_Optimizer_Wrapper): + + r""" + A wrapper for CMA-ES method to compare the other methods. + The library is the one from Nikolaus Hansen. + """ + + + libpath = pathlib.Path(os.path.join('mylib', 'lib_BO_bayesoptim', 'Bayesian-Optimization')) + def __init__(self, func, dim, ub, lb, total_budget, random_seed): + + # Use the superclass to initialize this wrapper + super().__init__(func, + dim, + ub, + lb, + total_budget, + random_seed) + + def run(self): + from bayes_optim import RandomForest, BO, GaussianProcess + import cma + from bayes_optim.extension import RealSpace + + import random + space = RealSpace([self.lb, self.ub], random_seed=self.random_seed) * self.dim + ma = float('-inf') + argmax = None + for i in range(10*self.dim): + x = space.sample(1)[0] + + self.opt = cma.fmin + + self.opt(self.func, x, 1., options={'bounds': [ + [self.lb]*self.dim, [self.ub]*self.dim], 'maxfevals': self.total_budget, 'seed': self.random_seed}) + + + +class SaasboWrapper(Abstract_Bayesian_Optimizer_Wrapper): + r""" + This is the wrapper of SAASBO algorithm. + """ + + libpath = pathlib.Path(os.path.join('mylib', 'lib_saasbo')) + + def __init__(self, func, dim, ub, lb, total_budget, DoE_size, random_seed,sample_zero): + + # Initialize the abstract super class + super().__init__(func, + dim, + ub, + lb, + DoE_size, + total_budget, + random_seed, + sample_zero) + + def run(self,**kwargs): + #from saasbo import run_saasbo, get_acq_time, get_mode_time + from saasbo import Saasbo + + + # run_saasbo( + # self.func, + # np.ones(self.dim) * self.ub, + # np.ones(self.dim) * self.lb, + # self.total_budget, + # self.Doe_size, + # self.random_seed, + # alpha=0.01, + # num_warmup=256, + # num_samples=256, + # thinning=32, + # device="cpu", + # ) + + # Use the other properties as given by parameter + alpha:float = float(kwargs.pop("alpha",0.01)) + num_warmup:int = int(kwargs.pop("num_warmup",256)) + num_samples:int = int(kwargs.pop("num_samples",256)) + thinning:int = int(kwargs.pop("thinning",32)) + device:str = str(kwargs.pop("device","cpu")).lower() + + self.opt = Saasbo(func=self.func, + dim=self.dim, + ub=self.ub, + lb=self.lb, + total_budget=self.total_budget, + DoE_size=self.Doe_size, + random_seed=self.random_seed) + + print(self.opt.run_saasbo(self.func,np.ones(self.dim) * self.ub,np.ones(self.dim) * self.lb,self.total_budget, + self.Doe_size, + self.random_seed, + alpha=alpha, + num_warmup=num_warmup, + num_samples=num_samples, + thinning=thinning, + device=device,)) + + # def get_acq_time(self): + # return self.opt.acq_opt_time + + # def get_mode_time(self): + # return self.opt.mode_fit_time + + # def get_iter_time(self): + # return self.opt.cum_iteration_time + + + +class BO_sklearnWrapper(Abstract_Bayesian_Optimizer_Wrapper): + r""" + This uses the default Bayesian Optimization defined in + scikit-optimize and derivatives from scikit-learn library. + """ + + libpath = pathlib.Path(os.path.join('mylib', 'lib_BO_sklearn')) + + def __init__(self, func, dim, ub, lb, total_budget, DoE_size, random_seed,sample_zero): + + # Initialize the abstract super class + super().__init__(func, + dim, + ub, + lb, + DoE_size, + total_budget, + random_seed, + sample_zero) + + def run(self,**kwargs): + from bosklearn import bosklearn + + acq_func:str = str(kwargs.pop("acq_func","EI")) + noise:float = float(kwargs.pop("noise",0.1**2)) + + self.opt= bosklearn(func=self.func, + dim=self.dim, + ub=self.ub, + lb=self.lb, + total_budget=self.total_budget, + DoE_size=self.Doe_size, + random_seed=self.random_seed) + self.opt.gp_minimize(self.func, # the function to minimize + # the bounds on each dimension of x + list((((self.lb, self.ub),) * self.dim)), + acq_func=acq_func, # the acquisition function + n_calls=self.total_budget, # the number of evaluations of f + n_random_starts=self.Doe_size, # the number of random initialization points + noise=noise, # the noise level (optional) + random_state=self.random_seed) + + # def get_acq_time(self): + # return self.opt.acq_opt_time + + # def get_mode_time(self): + # return self.opt.mode_fit_time + + # def get_iter_time(self): + # return self.opt.cum_iteration_time + +class BO_bayesoptimWrapper(Abstract_Bayesian_Optimizer_Wrapper): + r""" This is the BO of Hao Wang's library""" + + libpath = pathlib.Path(os.path.join('mylib', 'lib_' + "BO_bayesoptim")) + + + def __init__(self, func, dim, ub, lb, total_budget, DoE_size, random_seed,sample_zero): + + # Use the super class initializer + super().__init__(func, + dim, + ub, + lb, + DoE_size, + total_budget, + random_seed, + sample_zero) + + print(sys.path) + + def run(self): + from bayes_optim import BO, RealSpace + from bayes_optim.surrogate import GaussianProcess + + space = RealSpace([self.lb, self.ub]) * \ + self.dim # create the search space + + # hyperparameters of the GPR model + thetaL = 1e-10 * (self.ub - self.lb) * np.ones(self.dim) + thetaU = 10 * (self.ub - self.lb) * np.ones(self.dim) + model = GaussianProcess( # create the GPR model + thetaL=thetaL, thetaU=thetaU + ) + + self.opt = BO( + search_space=space, + obj_fun=self.func, + model=model, + DoE_size=self.Doe_size, # number of initial sample points + max_FEs=self.total_budget, # maximal function evaluation + verbose=True + ) + self.opt.run() + + +class BO_development_bayesoptimWrapper(Abstract_Bayesian_Optimizer_Wrapper): + r""" + This is the latest development from Hao Wang's Library + """ + + libpath = pathlib.Path(os.path.join('mylib', 'lib_BO_bayesoptim', 'Bayesian-Optimization')) + # Latest changes from Hao's repository + def __init__(self, func, dim, ub, lb, total_budget, DoE_size, random_seed,sample_zero): + + # Use the superclass initializer + super().__init__(func, + dim, + ub, + lb, + DoE_size, + total_budget, + random_seed, + sample_zero) + + @staticmethod + def _register_new_library(libpath): + r""" + This is a re-interpretation of this function from the `Abstract_Optimizer_Wrapper` class. + The modification with respect to the 'default' function is the advice on where to get the + 'Bayesian-Optimization' module. + + Args: + ---------- + - libpath: `Union[pathlib.Path,str]`: A composite path to point the location of the library + """ + + # Appends the library path given by parameter + if not isinstance(libpath,pathlib.Path): + # Modify the instance to be an instance of the library `pathlib.Path` + libpath = pathlib.Path(libpath) + + if not libpath.exists(): + raise AttributeError(f'No such module Bayesian-Optimization, please consider cloning this repository: https://github.com/wangronin/Bayesian-Optimization to the folder mylib/lib_BO_bayesoptim/', + name="libpath", + obj=libpath) + else: + # Append the library in case this exists + sys.path.append(libpath) + + def run(self): + from bayes_optim.extension import RealSpace + from bayes_optim.bayes_opt import BO + + space = RealSpace([self.lb, self.ub], random_seed=self.random_seed) * self.dim + self.opt = BO( + search_space=space, + obj_fun=self.func, + DoE_size=self.Doe_size, + n_point=1, + random_seed=self.random_seed, + acquisition_optimization={"optimizer": "BFGS"}, + max_FEs=self.total_budget, + verbose=False, + ) + self.opt.run() + +class KPCABOWrapper(Abstract_Bayesian_Optimizer_Wrapper): + r""" + The KPCABO Method from Kirill and Elena (and the others). + """ + + libpath = pathlib.Path(os.path.join('mylib', 'lib_BO_bayesoptim', 'Bayesian-Optimization')) + + # Latest changes from Hao's repository + def __init__(self, func, dim, ub, lb, total_budget, DoE_size, random_seed,sample_zero): + + # Use the superclass initializer + super().__init__(func=func, + dim=dim, + ub=ub, + lb=lb, + DoE_size=DoE_size, + total_budget=total_budget, + random_seed=random_seed, + sample_zero=sample_zero) + + @staticmethod + def _register_new_library(libpath): + r""" + This is a re-interpretation of this function from the `Abstract_Optimizer_Wrapper` class. + The modification with respect to the 'default' function is the advice on where to get the + 'Bayesian-Optimization' module. + + Args: + ---------- + - libpath: `Union[pathlib.Path,str]`: A composite path to point the location of the library + """ + + # Appends the library path given by parameter + if not isinstance(libpath,pathlib.Path): + # Modify the instance to be an instance of the library `pathlib.Path` + libpath = pathlib.Path(libpath) + + if not libpath.exists(): + raise AttributeError(f'No such module Bayesian-Optimization, please consider cloning this repository: https://github.com/wangronin/Bayesian-Optimization to the folder mylib/lib_BO_bayesoptim/', + name="libpath", + obj=libpath) + else: + # Append the library in case this exists + sys.path.insert(0,str(libpath.absolute())) + + print(sys.path) + + def run(self, **kwargs): + + + from bayes_optim import RandomForest, BO, GaussianProcess + + from bayes_optim.extension import PCABO, RealSpace, KernelPCABO, KernelFitStrategy + from bayes_optim.mylogging import eprintf + + import random + + + verbose = bool(kwargs.pop("verbose",False)) + n_point = int((kwargs.pop("n_point",1))) + max_information_loss = float((kwargs.pop("max_information_loss",0.1))) + acquisition_optimizer:str = str(kwargs.pop("acquisition_optimizer","BFGS")) + + space = RealSpace([self.lb, self.ub], random_seed=self.random_seed) * self.dim + + warm_data = None + # This is to define the case to sample the zero during the DoE Stage + if self.sample_zero: + x_init:np.ndarray = np.zeros((1,self.dim)) + fX_init = self.func(x_init) + warm_data = (x_init,fX_init) + self.Doe_size = self.Doe_size-1 + + self.opt = KernelPCABO( + search_space=space, + obj_fun=self.func, + DoE_size=self.Doe_size, + max_FEs=self.total_budget, + verbose=verbose, + n_point=n_point, + acquisition_optimization={"optimizer": acquisition_optimizer}, + max_information_loss=max_information_loss, + kernel_fit_strategy=KernelFitStrategy.AUTO, + NN=self.dim, + random_seed=self.random_seed, + warm_data = warm_data + ) + + print(self.opt.run()) + + # def get_acq_time(self): + # return self.opt.acq_opt_time + + # def get_mode_time(self): + # return self.opt.mode_fit_time + + # def get_iter_time(self): + # return self.opt.cum_iteration_time + + +class randomWrapper(Abstract_Optimizer_Wrapper): + r""" + A wrapper for Random Search Methods + """ + + libpath = pathlib.Path("") + def __init__(self, func, dim, ub, lb, total_budget, DoE_size, random_seed): + + self.func = func + self.dim = dim + self.ub = ub + self.lb = lb + self.total_budget = total_budget + self.Doe_size = DoE_size + self.random_seed = random_seed + + def run(self): + import ioh + + def random_search(func:Callable, + search_space, + budget:int): + r""" + Implements random search to minimize a problem of size n. + + Args: + --------------- + - objective_function: The objective function to be minimized. It must accept a vector of size n as input and return a numeric value. + - search_space: A list of tuples, each containing the range of allowable values for each dimension. + - budget: The maximum number of evaluations of the objective function allowed. + + Returns: + --------------- + - best_solution: The best solution found. + - best_score: The minimum value of the objective function associated with the best solution. + """ + best_solution = None + best_score = float('inf') + + for _ in range(budget): + solution = [np.random.uniform(low, high) for (low, high) in search_space] + score = self.func(solution) + + # Update the best solution if necessary + if score < best_score: + best_solution = solution + best_score = score + print(best_score) + return best_solution, best_score + search_space = [(self.lb, self.ub) for _ in range(self.dim)] + budget = self.total_budget + self.opt = random_search + + # Run random search + self.opt(self.func, search_space, budget) + + +class linearPCABOWrapper(Abstract_Bayesian_Optimizer_Wrapper): + + + libpath = pathlib.Path(os.path.join('mylib', 'lib_BO_bayesoptim', 'Bayesian-Optimization')) + + + def __init__(self, func, dim, ub, lb, total_budget, DoE_size, random_seed,sample_zero): + + # Call the super initializer + super().__init__(func=func, + dim=dim, + ub=ub, + lb=lb, + DoE_size=DoE_size, + total_budget=total_budget, + random_seed=random_seed, + sample_zero=sample_zero) + + @staticmethod + def _register_new_library(libpath): + r""" + This is a re-interpretation of this function from the `Abstract_Optimizer_Wrapper` class. + The modification with respect to the 'default' function is the advice on where to get the + 'Bayesian-Optimization' module. + + Args: + ---------- + - libpath: `Union[pathlib.Path,str]`: A composite path to point the location of the library + """ + + # Appends the library path given by parameter + if not isinstance(libpath,pathlib.Path): + # Modify the instance to be an instance of the library `pathlib.Path` + libpath = pathlib.Path(libpath) + + if not libpath.exists(): + raise AttributeError(f'No such module Bayesian-Optimization, please consider cloning this repository: https://github.com/wangronin/Bayesian-Optimization to the folder mylib/lib_BO_bayesoptim/', + name="libpath", + obj=libpath) + else: + # Append the library in case this exists + sys.path.insert(0,str(libpath.absolute())) + + def run(self, **kwargs): + + from bayes_optim.extension import PCABO, RealSpace + + # Extract the kwargs to set up the setup + verbose = bool(kwargs.pop("verbose",False)) + n_point = int((kwargs.pop("n_point",1))) + n_components = float((kwargs.pop("n_components",0.9))) + acquisition_optimizer:str = str(kwargs.pop("acquisition_optimizer","BFGS")) + + space = RealSpace([self.lb, self.ub]) * self.dim + + warm_data = None + # This is to define the case to sample the zero during the DoE Stage + if self.sample_zero: + x_init:np.ndarray = np.zeros((1,self.dim)) + fX_init = self.func(x_init) + warm_data = (x_init,fX_init) + self.Doe_size = self.Doe_size-1 + + + + + self.opt = PCABO( + search_space=space, + obj_fun=self.func, + DoE_size=self.Doe_size, + max_FEs=self.total_budget, + verbose=verbose, + n_point=n_point, + n_components=n_components, + acquisition_optimization={"optimizer": acquisition_optimizer}, + random_seed=self.random_seed, + warm_data = warm_data + ) + + print(self.opt.run()) + + # def get_acq_time(self): + # return self.opt.acq_opt_time + + # def get_mode_time(self): + # return self.opt.mode_fit_time + + # def get_iter_time(self): + # return self.opt.cum_iteration_time + + +class RDUCBWrapper(Abstract_Bayesian_Optimizer_Wrapper): + r""" + Wrapper of RDUCBW + """ + + libpath = pathlib.Path(os.path.join('mylib', 'lib_RDUCB/HEBO/RDUCB')) + + def __init__(self, func, dim, ub, lb, total_budget, DoE_size, random_seed,sample_zero): + # Use the superclass initializer + super().__init__(func, + dim, + ub, + lb, + DoE_size, + total_budget, + random_seed, + sample_zero) + + def run(self): + # import sys + # sys.path.insert(0, "./mylib/lib_linearPCABO/Bayesian-Optimization") + + from hdbo.algorithms import RDUCB + self.opt = RDUCB( algorithm_random_seed=self.random_seed, + eps=-1, + exploration_weight= 'lambda t: 0.5 * np.log(2*t)', + graphSamplingNumIter=100, + learnDependencyStructureRate=1, + lengthscaleNumIter=2, + max_eval=-4, + noise_var= 0.1, + param_n_iter=16, + size_of_random_graph=0.2, + # data_random_seed=self.random_seed, + fn_noise_var=0.15, + grid_size=150, + fn= self.func, + n_iter=self.total_budget-self.Doe_size, + n_rand=self.Doe_size, dim=self.dim,) + self.opt.run() + + + #TODO: This is a correction applied to the method since there is a + # wrapper around this object. + def get_acq_time(self): + return self.opt.mybo.acq_opt_time + + def get_mode_time(self): + return self.opt.mybo.mode_fit_time + + def get_iter_time(self): + return self.opt.mybo.cum_iteration_time + + +class turbo1Wrapper(Abstract_Bayesian_Optimizer_Wrapper): + r""" + Wrapper of turbo 1 algorithm + """ + + libpath = pathlib.Path(os.path.join('mylib', 'lib_turbo1')) + + def __init__(self, func, dim, ub, lb, total_budget, DoE_size, random_seed,sample_zero): + + # Call the Superclass constructor + super().__init__(func=func, + dim=dim, + ub=ub, + lb=lb, + DoE_size=DoE_size, + total_budget=total_budget, + random_seed=random_seed, + sample_zero=sample_zero) + print(sys.path) + + + def run(self, **kwargs): + + # Load the libraries + from turbo import Turbo1 + import torch + import math + import matplotlib + import matplotlib.pyplot as plt + + # Set the specific variables + verbose = bool(kwargs.pop("verbose",True)) + use_ard = bool(kwargs.pop("use_ard",True)) + max_cholesky_size = int(kwargs.pop("max_cholesky_size",2000)) + n_training_steps = int(kwargs.pop("n_training_steps",2000)) + min_cuda = int(kwargs.pop("min_cuda",2000)) + device = str(kwargs.pop("device","cpu")) + dtype = str(kwargs.pop("dtype","float64")) + + + self.opt = Turbo1( + f=self.func, # Handle to objective function + lb=np.ones(self.dim) * self.lb, # Numpy array specifying lower bounds + ub=np.ones(self.dim) * self.ub, # Numpy array specifying upper bounds + n_init=self.Doe_size, # Number of initial bounds from an Latin hypercube design + max_evals=self.total_budget, # Maximum number of evaluations + batch_size=5, # How large batch size TuRBO uses + verbose=verbose, # Print information from each batch + use_ard=use_ard, # Set to true if you want to use ARD for the GP kernel + max_cholesky_size=max_cholesky_size, # When we switch from Cholesky to Lanczos + n_training_steps=n_training_steps, # Number of steps of ADAM to learn the hypers + min_cuda=min_cuda, # Run on the CPU for small datasets + device=device, # "cpu" or "cuda" + dtype=dtype, # float64 or float32 + sample_zero = self.sample_zero # Get to sample zero as part of the function evaluations + ) + self.opt.optimize() + + # def get_acq_time(self): + # return self.opt.acq_opt_time + + # def get_mode_time(self): + # return self.opt.mode_fit_time + + # def get_iter_time(self): + # return self.opt.cum_iteration_time + + +class turbomWrapper(Abstract_Bayesian_Optimizer_Wrapper): + + libpath = pathlib.Path(os.path.join('mylib', 'lib_turbo1')) + + + def __init__(self, func, dim, ub, lb, total_budget, DoE_size, random_seed,sample_zero): + + # Call the Superclass constructor + super().__init__(func=func, + dim=dim, + ub=ub, + lb=lb, + DoE_size=DoE_size, + total_budget=total_budget, + random_seed=random_seed, + sample_zero=sample_zero) + print(sys.path) + + + def run(self,**kwargs) : + from turbo import TurboM + import torch + import math + import matplotlib + import matplotlib.pyplot as plt + #tr = math.floor(self.total_budget / self.Doe_size) - 1 + + # Set the specific variables + verbose = bool(kwargs.pop("verbose",True)) + use_ard = bool(kwargs.pop("use_ard",True)) + max_cholesky_size = int(kwargs.pop("max_cholesky_size",2000)) + n_training_steps = int(kwargs.pop("n_training_steps",2000)) + min_cuda = int(kwargs.pop("n_training_steps",2000)) + batch_size = int(kwargs.pop("batch_size",5)) + device = str(kwargs.pop("device","cpu")) + dtype = str(kwargs.pop("dtype","float64")) + + tr = max(int(self.dim/5),2) + n_init = math.floor(self.Doe_size/tr) + + + self.opt = TurboM( + f=self.func, # Handle to objective function + lb=np.ones(self.dim) * self.lb, # Numpy array specifying lower bounds + ub=np.ones(self.dim) * self.ub, # Numpy array specifying upper bounds + n_init=n_init, # Number of initial bounds from an Symmetric Latin hypercube design + max_evals=self.total_budget, # Maximum number of evaluations + n_trust_regions=tr, # Number of trust regions + batch_size=batch_size, # How large batch size TuRBO uses + verbose=verbose, # Print information from each batch + use_ard=use_ard, # Set to true if you want to use ARD for the GP kernel + max_cholesky_size=max_cholesky_size, # When we switch from Cholesky to Lanczos + n_training_steps=n_training_steps, # Number of steps of ADAM to learn the hypers + min_cuda=min_cuda, # Run on the CPU for small datasets + device=device, # "cpu" or "cuda" + dtype=dtype, # float64 or float32 + sample_zero= self.sample_zero # Switch to sample zero as part of the DoE + ) + self.opt.optimize() + + # def get_acq_time(self): + # return self.opt.acq_opt_time + + # def get_mode_time(self): + # return self.opt.mode_fit_time + + # def get_iter_time(self): + # return self.opt.cum_iteration_time + +class EBOWrapper(Abstract_Bayesian_Optimizer_Wrapper): + + libpath = pathlib.Path(os.path.join('mylib', 'lib_EBO')) + + + def __init__(self, func, dim, ub, lb, total_budget, DoE_size, random_seed, sample_zero): + # import sys + # sys.path.append('./mylib/' + 'lib_' + "EBO") + # print(sys.path) + + # Call the Superclass constructor + super().__init__(func=func, + dim=dim, + ub=ub, + lb=lb, + DoE_size=DoE_size, + total_budget=total_budget, + random_seed=random_seed, + sample_zero=sample_zero) + print(sys.path) + + def run(self, **kwargs): + import numpy.matlib as nm + import functools + from ebo_core.ebo import ebo + from test_functions.simple_functions import sample_z + import time + import logging + + dx = self.dim + z = sample_z(dx) + k = np.array([10] * dx) + x_range = nm.repmat([[self.lb], [self.ub]], 1, self.dim) + x_range = x_range.astype(float) + sigma = 0.01 + n = self.Doe_size + budget = self.total_budget + f = self.func + f = functools.partial(lambda f, x: -f(x), f) + options = {'x_range': x_range, # input domain + 'dx': x_range.shape[1], # input dimension + 'max_value': 0, # target value + 'T': budget, # number of iterations + 'B': 1, # number of candidates to be evaluated + 'dim_limit': 3, # max dimension of the input for each additive function component + 'isplot': 0, # 1 if plotting the result; otherwise 0. + 'z': None, 'k': None, # group assignment and number of cuts in the Gibbs sampling subroutine + 'alpha': 1., # hyperparameter of the Gibbs sampling subroutine + 'beta': np.array([5., 2.]), + 'opt_n': 1000, # points randomly sampled to start continuous optimization of acfun + 'pid': 'test3', # process ID for Azure + 'datadir': 'tmp_data/', # temporary data directory for Azure + 'gibbs_iter': 10, # number of iterations for the Gibbs sampling subroutine + 'useAzure': False, # set to True if use Azure for batch evaluation + 'func_cheap': True, # if func cheap, we do not use Azure to test functions + 'n_add': None, # this should always be None. it makes dim_limit complicated if not None. + 'nlayers': 100, # number of the layers of tiles + 'gp_type': 'l1', # other choices are l1, sk, sf, dk, df + 'gp_sigma': 0.1, # noise standard deviation + 'n_bo': 10, # min number of points selected for each partition + 'n_bo_top_percent': 0.5, # percentage of top in bo selections + 'n_top': 10, # how many points to look ahead when doing choose Xnew + 'min_leaf_size': 10, # min number of samples in each leaf + 'max_n_leaves': 10, # max number of leaves + 'thresAzure': 1, # if batch size > thresAzure, we use Azure + 'save_file_name': 'tmp/tmp.pk', + } + self.opt = ebo(f, options) + start = time.time() + self.opt.run() + + print("elapsed time: ", time.time() - start) + + # def get_acq_time(self): + # return self.opt.acq_opt_time + + # def get_mode_time(self): + # return self.opt.mode_fit_time + + # def get_iter_time(self): + # return self.opt.cum_iteration_time + +class EBO_BWrapper(Abstract_Bayesian_Optimizer_Wrapper): + + libpath = pathlib.Path(os.path.join('mylib', 'lib_EBO')) + + + def __init__(self, func, dim, ub, lb, total_budget, DoE_size, random_seed,sample_zero): + + # Call the super class initializer + super().__init__(func=func, + dim=dim, + ub=ub, + lb=lb, + DoE_size=DoE_size, + total_budget=total_budget, + random_seed=random_seed, + sample_zero=sample_zero) + + + def run(self, **kwargs): + import numpy.matlib as nm + import functools + from ebo_core.ebo import ebo + from test_functions.simple_functions import sample_z + import time + import logging + + dx = self.dim + z = sample_z(dx) + k = np.array([10] * dx) + x_range = nm.repmat([[self.lb], [self.ub]], 1, self.dim) + x_range = x_range.astype(float) + sigma = 0.01 + n = self.Doe_size + budget = self.total_budget + t= int (float(budget)/10) + + f = self.func + f = functools.partial(lambda f, x: -f(x), f) + + options = {'x_range': x_range, # input domain + 'dx': x_range.shape[1], # input dimension + 'max_value': 0, # target value + 'T': t, # number of iterations + 'B': 10, # number of candidates to be evaluated + 'dim_limit': 3, # max dimension of the input for each additive function component + 'isplot': 0, # 1 if plotting the result; otherwise 0. + 'z': None, 'k': None, # group assignment and number of cuts in the Gibbs sampling subroutine + 'alpha': 1., # hyperparameter of the Gibbs sampling subroutine + 'beta': np.array([5., 2.]), + 'opt_n': 1000, # points randomly sampled to start continuous optimization of acfun + 'pid': 'test3', # process ID for Azure + 'datadir': 'tmp_data/', # temporary data directory for Azure + 'gibbs_iter': 10, # number of iterations for the Gibbs sampling subroutine + 'useAzure': False, # set to True if use Azure for batch evaluation + 'func_cheap': True, # if func cheap, we do not use Azure to test functions + 'n_add': None, # this should always be None. it makes dim_limit complicated if not None. + 'nlayers': 100, # number of the layers of tiles + 'gp_type': 'l1', # other choices are l1, sk, sf, dk, df + 'gp_sigma': 0.1, # noise standard deviation + 'n_bo': 10, # min number of points selected for each partition + 'n_bo_top_percent': 0.5, # percentage of top in bo selections + 'n_top': 10, # how many points to look ahead when doing choose Xnew + 'min_leaf_size': 10, # min number of samples in each leaf + 'max_n_leaves': 10, # max number of leaves + 'thresAzure': 1, # if batch size > thresAzure, we use Azure + 'save_file_name': 'tmp/tmp.pk', + } + self.opt = ebo(f, options) + start = time.time() + self.opt.run() + + print("elapsed time: ", time.time() - start) + + # def get_acq_time(self): + # return self.opt.acq_opt_time + + # def get_mode_time(self): + # return self.opt.mode_fit_time + + # def get_iter_time(self): + # return self.opt.cum_iteration_time + +class ALEBOWrapper(Abstract_Bayesian_Optimizer_Wrapper): + + r""" + Wrapper of the ALEBO Method + """ + libpath = pathlib.Path("") + + def __init__(self, func, dim, ub, lb, total_budget, DoE_size, random_seed): + # Call the Super Class + super().__init__(func=func, + dim=dim, + ub=ub, + lb=lb, + DoE_size=DoE_size, + total_budget=total_budget, + random_seed=random_seed, + sample_zero=sample_zero) + + def run(self,**kwargs): + # import pathlib + # my_dir = pathlib.Path(__file__).parent.resolve() + # sys.path.append(os.path.join(my_dir, 'mylib', 'lib_ALEBO')) + # import numpy as np + from ax.utils.measurement.synthetic_functions import branin + print(sys.path) + + def branin_evaluation_function(parameterization): + # Evaluates Branin on the first two parameters of the parameterization. + # Other parameters are unused. + x = np.array([parameterization["x0"], parameterization["x1"]]) + + return {"objective": (branin(x), 0.0)} + + def function(parameterization): + # Evaluates Branin on the first two parameters of the parameterization. + # Other parameters are unused. + x = np.array([parameterization[f'x{i}'] for i in range(self.dim)]) + self.iter+=1 + if self.iter == self.total_budget: + print("Optimization is complete, cannot run another trial.") + exit() + return {"objective": (self.func(x), 0.0)} + + parameters = [ + {"name": "x0", "type": "range", "bounds": [self.lb, self.ub], "value_type": "float"}, + {"name": "x1", "type": "range", "bounds": [self.lb, self.ub], "value_type": "float"}, + ] + parameters.extend([ + {"name": f"x{i}", "type": "range", "bounds": [self.lb, self.ub], "value_type": "float"} + for i in range(2, self.dim) + ]) + from ax.modelbridge.strategies.alebo import ALEBOStrategy + alebo_strategy = ALEBOStrategy(D=self.dim, d=4, init_size=self.Doe_size) + alebo_strategy._steps[0].model_kwargs.update({"seed": self.random_seed}) + from ax.service.managed_loop import optimize + self.opt = optimize + + # Call the optimizer + self.opt(parameters=parameters, + experiment_name="test", + objective_name="objective", + evaluation_function=function, + minimize=True, + total_trials=self.total_budget, + generation_strategy=alebo_strategy, + ) + +# def run(self): +# # import sys +# # sys.path.insert(0, "./mylib/lib_linearPCABO/Bayesian-Optimization") +# parameters = [ +# {"name": "x0", "type": "range", "bounds": [self.lb, self.ub], "value_type": "float"}, +# {"name": "x1", "type": "range", "bounds": [self.lb, self.ub], "value_type": "float"}, +# ] +# parameters.extend([ +# {"name": f"x{i}", "type": "range", "bounds": [self.lb, self.ub], "value_type": "float"} +# for i in range(2, self.dim) +# ]) +# alebo_strategy = ALEBOStrategy(D=self.dim, d=10, init_size=self.Doe_size) +# from ax.service.managed_loop import optimize +# self.opt = optimize( +# parameters=parameters, +# experiment_name="test", +# objective_name="objective", +# evaluation_function=self.func, +# minimize=True, +# total_trials=self.total_budget, +# generation_strategy=alebo_strategy, +# ) +# self.opt() + + # def get_acq_time(self): + # return self.opt.acq_opt_time + + # def get_mode_time(self): + # return self.opt.mode_fit_time + + # def get_iter_time(self): + # return self.opt.cum_iteration_time + +class HEBOWrapper(Abstract_Bayesian_Optimizer_Wrapper): + r""" + Wrapper of the HEBO Method + """ + libpath = pathlib.Path("") + + def __init__(self, func, dim, ub, lb, total_budget, DoE_size, random_seed, sample_zero): + + # Call the Super Class + super().__init__(func=func, + dim=dim, + ub=ub, + lb=lb, + DoE_size=DoE_size, + total_budget=total_budget, + random_seed=random_seed, + sample_zero=sample_zero) + + def run(self,**kwargs): + + import pandas as pd + import numpy as np + from hebo.design_space.design_space import DesignSpace + from hebo.optimizers.hebo import HEBO + # def obj(params: pd.DataFrame) -> np.ndarray: + # return ((params.values - 0.37) ** 2).sum(axis=1).reshape(-1, 1) + def obj(params: pd.DataFrame) -> np.ndarray: + # Imports the desired BBOB function (for example, function #1:sphere) + problem = self.func # parameters: dimensions, index of corresponding BBOB function (1-24) + + # Calcola il valore della funzione obiettivo per ciascuna riga dei parametri + values = [problem(np.squeeze(row.values)) for _, row in params.iterrows()] + + # Restituisci i valori come un array numpy + return np.array(values).reshape(-1, 1) + + dimension_specs = [{"name": f"param{i}", "type": "num", 'lb' : self.lb, 'ub' : self.ub } for i in + range(1, self.dim + 1)] + space = DesignSpace().parse(dimension_specs) + #space = DesignSpace().parse([{'name': 'x', 'type': 'int', 'lb': self.lb, 'ub': self.ub}]) + self.opt:HEBO = HEBO(space, + rand_sample=self.Doe_size, + scramble_seed=self.random_seed ) + + rec = self.opt.suggest(n_suggestions=self.Doe_size) + # Fit initially the model + if self.sample_zero: + # Perform a loop to rewrite the first point from DoE + for idx in range(len(rec.param1)): + rec.param1[idx] = 0.0 + + # Observe the DoE + self.opt.observe(rec, obj(rec)) + + for i in range(self.total_budget-self.Doe_size): + rec = self.opt.suggest(n_suggestions=1) + self.opt.observe(rec, obj(rec)) + print('After %d iterations, best obj is %.2f' % (i, self.opt.y.min())) + self.opt.cum_iteration_time = time.process_time() + + # def get_acq_time(self): + # return self.opt.acq_opt_time + + # def get_mode_time(self): + # return self.opt.mode_fit_time + + # def get_iter_time(self): + # return self.opt.cum_iteration_time + +class BAxUSWrapper(Abstract_Bayesian_Optimizer_Wrapper): + + r""" + Wrapper of the BAxUS Method + """ + libpath = pathlib.Path(os.path.join("mylib","lib_BAxUS","BAxUS")) + def __init__(self, func, + dim:int, ub, lb, + total_budget:int, + DoE_size, + random_seed, + sample_zero=False, + verbose=False,dtype='float64'): + + # Use the superclass constructor + super().__init__(func=func, + dim=dim, + ub=ub, + lb=lb, + total_budget=total_budget, + DoE_size=DoE_size, + random_seed=random_seed, + sample_zero=sample_zero) + + self._verbose:bool = verbose + self._dtype:str = dtype + + def run(self, **kwargs): + + try: + #from mylib.lib_BAxUS.BAxUS.baxus import BAxUS # Import the BAxUS object + from baxus import BAxUS # Import the BAxUS object + #from mylib.lib_BAxUS.BAxUS.baxus.util.behaviors import BaxusBehavior + from baxus.util.behaviors import BaxusBehavior + #from mylib.lib_BAxUS.BAxUS.baxus.util.behaviors.gp_configuration import GPBehaviour + from baxus.util.behaviors.gp_configuration import GPBehaviour + except ModuleNotFoundError as e: + print("The module was not found!, please download it", e.args) + + # import the parser function from the BAxUS library + #from mylib.lib_BAxUS.BAxUS.baxus.util.parsing import parse + from baxus.util.parsing import parse + #from mylib.lib_BAxUS.BAxUS.baxus.util.parsing import (embedding_type_mapper, + # acquisition_function_mapper, + # mle_optimization_mapper) + + from baxus.util.parsing import (embedding_type_mapper, + acquisition_function_mapper, + mle_optimization_mapper, + fun_mapper) + + #from mylib.lib_BAxUS.BAxUS.baxus.benchmark_runner import fun_mapper, info + from baxus.benchmark_runner import fun_mapper, info + from wrapper_helper import IOH_BAxUS_Wrapper + import logging + + + import json + import logging + import os + import sys + from datetime import datetime + from logging import info, warning + from typing import List + from zlib import adler32 + + + from baxus.util.exceptions import ArgumentError + from baxus.util.utils import star_string + + #FORMAT = "%(asctime)s %(levelname)s: %(filename)s: %(message)s" + #DATEFORMAT = '%m/%d/%Y %I:%M:%S %p' + + # Call the default configuration parser + parser_args:str = f"-f ioh_function --algorithm baxus"\ + f" --input-dim {self.dim} --target-dim {self.dim} --n-init {self.Doe_size}"\ + f" --max-evals {self.total_budget}" + + args = parse(parser_args.split()) + + # directory = os.path.join( + # args.results_dir, + # f"{datetime.now().strftime('%d_%m_%Y')}{f'-{args.run_description}' if len(args.run_description) > 0 else ''}", + # ) + # os.makedirs(directory, exist_ok=True) + # logging.basicConfig( + # filename=os.path.join(directory, "logging.log"), + # level=logging.INFO if not args.verbose else logging.DEBUG, + # format=FORMAT, + # force=True, + # datefmt=DATEFORMAT + # ) + + #sysout_handler = logging.StreamHandler(sys.stdout) + #sysout_handler.setFormatter(logging.Formatter(fmt=FORMAT, datefmt=DATEFORMAT)) + #logging.getLogger().addHandler(sysout_handler) + + #repetitions = list(range(args.num_repetitions)) + + #args_dict = vars(args) + # with open(os.path.join(directory, "conf.json"), "w") as f: + # f.write(json.dumps(args_dict)) + + ### NOTE: Rewriting the definition of the function as: + + + ### + bin_sizing_method = embedding_type_mapper[args.embedding_type] + + acquisition_function = acquisition_function_mapper[args.acquisition_function] + + mle_optimization_method = mle_optimization_mapper[args.mle_optimization] + + input_dim = args.input_dim + target_dim = args.target_dim + + n_init = args.n_init + #n_init = self.Doe_size + + max_evals = args.max_evals + noise_std = args.noise_std + + new_bins_on_split = args.new_bins_on_split + + ## +++++++++++++++++++++++++++++++++++++++++++++++++++ + ## NOTE This handler is in case for small dimensions + if input_dim == 3: + new_bins_on_split = 2 + elif input_dim == 2 or input_dim == 1: + new_bins_on_split = 2 + + ## ++++++++++++++++++++++++++++++++++++++++++++++++++++ + + multistart_samples = args.multistart_samples + mle_training_steps = args.mle_training_steps + multistart_after_samples = args.multistart_after_sample + l_init = args.initial_baselength + l_min = args.min_baselength + l_max = args.max_baselength + adjust_initial_target_dim = True # args.adjust_initial_target_dimension + #print(adjust_initial_target_dim) + budget_until_input_dim = args.budget_until_input_dim + + combs = {} + + if n_init is None: + n_init = target_dim + 1 + if args.min_baselength > args.max_baselength: + raise ArgumentError( + "Minimum baselength has to be larger than maximum baselength." + ) + if args.input_dim < args.target_dim: + raise ArgumentError( + "Input dimension has to be larger than target dimension." + ) + if args.noise_std < 0: + raise ArgumentError("Noise standard deviation has to be positive.") + if max_evals < budget_until_input_dim: + raise ArgumentError("budget_until_input_dim has to be <= max_evals.") + if args.multistart_samples < 1: + raise ArgumentError("Number of multistart samples has to be >= 1.") + if args.multistart_after_sample > args.multistart_samples: + raise ArgumentError( + f"Number of multistart samples after sampling {args.multistart_after_sample} has to be smaller or equal to the numbers" + f"of initial multistart samples {args.multistart_samples}." + ) + if args.multistart_after_sample < 1: + raise ArgumentError( + "Number of multistart samples after sampling has to be >= 1." + ) + if args.mle_training_steps < 0: + raise ArgumentError("Number of mle training steps has to be >= 0.") + if new_bins_on_split < 2: + raise ArgumentError("Number of new bins on split has to be greater than one.") + + funs = { + k: v(dim=input_dim, noise_std=noise_std) + for k, v in fun_mapper().items() + if k == args.function + } + + c = { + f"{k}_in_dim_{v.dim}_t_dim{target_dim}_n_init_{n_init}" + f"{f'_noise_{noise_std}' if noise_std > 0 else ''}": { + "input_dim": v.dim, + "target_dim": min(v.dim, target_dim), + "n_init": n_init, + "f": v, + "lb": v.lb_vec, + "ub": v.ub_vec, + } + for k, v in funs.items() + } + + combs.update(c) + + for i, (k, comb) in enumerate(combs.items()): + info(f"running combination {k}") + llb = comb["lb"] + uub = comb["ub"] + input_dim = comb["input_dim"] + target_dim = comb["target_dim"] + n_init = comb["n_init"] + + #f = comb["f"] + f = IOH_BAxUS_Wrapper(self.func, + self.dim, + self.lb, + self.ub, + None) + + #function_dir = os.path.join(directory, k) + #os.makedirs(function_dir, exist_ok=True) + + if "baxus" == args.algorithm: + # *** BAxUS *** + info("*** BAxUS***") + behavior = BaxusBehavior( + n_new_bins=new_bins_on_split, + initial_base_length=l_init, + min_base_length=l_min, + max_base_length=l_max, + acquisition_function=acquisition_function, + embedding_type=bin_sizing_method, + adjust_initial_target_dim=adjust_initial_target_dim, + noise=noise_std, + budget_until_input_dim=budget_until_input_dim + ) + gp_behaviour = GPBehaviour( + mll_estimation=mle_optimization_method, + n_initial_samples=multistart_samples, + n_best_on_lhs_selection=multistart_after_samples, + n_mle_training_steps=mle_training_steps, + ) + # conf_name = ( + # f"baxus_{behavior}_{gp_behaviour}" + # ) + # run_dir = os.path.join( + # function_dir, + # str(adler32(conf_name.encode("utf-8"))), + # ) + self.opt = BAxUS( + f=f, # Handle to objective function + n_init=n_init, # Number of initial bounds from an Latin hypercube design + max_evals=max_evals, # Maximum number of evaluations + target_dim=target_dim, + #run_dir=run_dir, + #conf_name=conf_name, + behavior=behavior, + gp_behaviour=gp_behaviour, + sample_zero = self.sample_zero + ) + self.opt.optimize() + #del baxus + + + # def obj(params: pd.DataFrame) -> np.ndarray: + # return ((params.values - 0.37) ** 2).sum(axis=1).reshape(-1, 1) + """ def obj(params: pd.DataFrame) -> np.ndarray: + # Imposta la funzione BBOB desiderata (ad esempio, la funzione 1) + problem = self.func # Parametri: dimensione, funzione BBOB (1-24) + + # Calcola il valore della funzione obiettivo per ciascuna riga dei parametri + values = [problem(np.squeeze(row.values)) for _, row in params.iterrows()] + + # Restituisci i valori come un array numpy + return np.array(values).reshape(-1, 1) + + dimension_specs = [{"name": f"param{i}", "type": "num", 'lb' : self.lb, 'ub' : self.ub } for i in + range(1, self.dim + 1)] + space = DesignSpace().parse(dimension_specs) + #space = DesignSpace().parse([{'name': 'x', 'type': 'int', 'lb': self.lb, 'ub': self.ub}]) + self.opt = HEBO(space, rand_sample=self.Doe_size, scramble_seed=self.random_seed ) + for i in range(self.total_budget): + rec = self.opt.suggest(n_suggestions=1) + self.opt.observe(rec, obj(rec)) + print('After %d iterations, best obj is %.2f' % (i, self.opt.y.min())) + self.opt.cum_iteration_time = time.process_time() """ + + # Now the requirement is to wrap the function from the IOH workspace + + + # def get_acq_time(self): + # return self.opt.acq_opt_time + + # def get_mode_time(self): + # return self.opt.mode_fit_time + + # def get_iter_time(self): + # return self.opt.cum_iteration_time + + + +class SMACWrapper(Abstract_Bayesian_Optimizer_Wrapper): + + #source_lib = os.path.join(__set_directory__,"mylib","lib_BAxUS","BAxUS") + libpath = pathlib.Path("") + def __init__(self, func, + dim:int, ub, lb, + total_budget:int, + DoE_size:int, + random_seed:int, + sample_zero=False, + verbose=False): + # import sys + # sys.path.append('./mylib/' + 'lib_' + "linearPCABO") + # print(sys.path) + # import pathlib + # my_dir = pathlib.Path(__file__).parent.resolve() + # sys.path.append(os.path.join(my_dir, 'mylib', 'lib_RDUCB/HEBO/RDUCB')) + # print(sys.path) + # sys.path.insert(0, bayes_bo_lib) + # print(sys.path) + + # Use the SuperClass Constructor + super().__init__(func=func, + dim=dim, + ub=ub, + lb=lb, + DoE_size=DoE_size, + total_budget=total_budget, + sample_zero=sample_zero, + random_seed=random_seed) + + self._verbose:bool = verbose + + def run(self): + # import sys + # sys.path.insert(0, "./mylib/lib_linearPCABO/Bayesian-Optimization") + + from ConfigSpace import Configuration, ConfigurationSpace, Float + from typing import Callable, List + + from smac import HyperparameterOptimizationFacade, Scenario + from smac.runhistory.dataclasses import TrialValue, TrialInfo + from smac.initial_design.latin_hypercube_design import LatinHypercubeInitialDesign + + + class IOH_SMAC_Wrapper: + + def __init__(self, + f:Callable, + dim:int, + lb:float, + ub:float, + seed:int = 0): + + # Assign the values + self.f = f + self.dim = dim + self.lb = lb + self.ub = ub + self.seed = seed + + @property + def configspace(self) -> ConfigurationSpace: + + # Initialize the configuration space + cs = ConfigurationSpace(seed=self.seed) + + list_of_variables:List[Float] = [] + + for idx_ in range(self.dim): + list_of_variables.append(Float(f"x{str(idx_)}", (self.lb,self.ub), default= 0)) + + cs.add(list_of_variables) + + return cs + + def train(self, config: Configuration, seed: int = 0) -> float: + r""" + This is to follow the same "lexicon" recommended by the library, which + states that a custom made model should have this train function. + """ + + list_of_values:list = [] + + for idx in range(len(config)): + list_of_values.append(config[f"x{idx}"]) + + # Compute the `cost` + cost = self.f(list_of_values) + return cost + + def return_values_to_zero(config_space:ConfigurationSpace)->dict: + r""" + This function changes all the values of the present configuration to zero + """ + + config_space_names = config_space.get_default_configuration() + + + + + model = IOH_SMAC_Wrapper(f=self.func, + dim=self.dim, + lb=self.lb, + ub=self.ub, + seed=self.random_seed) + + # Scenario object + scenario = Scenario(model.configspace, deterministic=False, n_trials=self.total_budget) + + intensifier = HyperparameterOptimizationFacade.get_intensifier( + scenario, + max_config_calls=1, # We basically use one seed per config only + ) + + # Initialize a LHS initial sampler + lhs_des_obj = LatinHypercubeInitialDesign(scenario=scenario, + n_configs=self.Doe_size, + seed=self.random_seed) + + # Now we use SMAC to find the best hyperparameters + self.opt:HyperparameterOptimizationFacade = HyperparameterOptimizationFacade( + scenario, + model.train, + intensifier=intensifier, + initial_design=lhs_des_obj, + overwrite=True, + ) + + # We can ask SMAC which trials should be evaluated next + # Optimize the loop (PENDING THE DOE) + for i in range(self.total_budget): + info = self.opt.ask() + + if i==0 and self.sample_zero: + + new_config = model.configspace.get_default_configuration() + + + + info = TrialInfo(config=new_config, + instance=info.instance, + seed=info.seed, + budget=info.budget) + + + assert info.seed is not None + + cost = model.train(info.config, seed=info.seed) + value = TrialValue(cost=cost, time=0.5) + + self.opt.tell(info, value) + + # After calling ask+tell, we can still optimize + # Note: SMAC will optimize the next 90 trials because 10 trials already have been evaluated + #incumbent = smac.optimize() + + + # def get_acq_time(self): + # return self.opt.acq_opt_time + + # def get_mode_time(self): + # return self.opt.mode_fit_time + + # def get_iter_time(self): + # return self.opt.cum_iteration_time + +class REMBOWrapper(Abstract_Bayesian_Optimizer_Wrapper): + + libpath = pathlib.Path(os.path.join("mylib","lib_REMBO","HesBO")) + + def __init__(self, func, + dim:int, ub, lb, + total_budget:int, + DoE_size:int, + random_seed:int, + sample_zero:bool = False, + verbose=False): + + # Use the Super Class constructor + super().__init__(func=func, + dim=dim, + ub=ub, + lb=lb, + total_budget=total_budget, + DoE_size=DoE_size, + random_seed=random_seed, + sample_zero=sample_zero) + + self._verbose:bool = verbose + + def run(self,**kwargs): + + + from typing import Callable, Tuple + try: + from mylib.lib_REMBO.HesBO.REMBO import RunRembo2, RemboSetter + + except ModuleNotFoundError as e: + print("The module was not found, importing with different way!") + from REMBO import RunRembo2, RemboSetter + + # Extract the kwargs to set up REMBO parameterization + matrix_type:str = str(kwargs.pop("matrix_type",'simple')) + kern_inp_type:str = str(kwargs.pop("kern_inp_type",'psi')) + ard:bool = bool(kwargs.pop("ARD",True)) + variance:float = float(kwargs.pop("variance",1.0)) + low_dim:int = int(kwargs.pop("low_dim",max(2,int(self.dim/5)))) + hyper_opt_interval:int = int(kwargs.pop("hyper_opt_interval",2)) + box_size:float = float(kwargs.pop("box_size",np.sqrt(self.dim))) + + # Define a wrapper class for the IOH_Instance + class IOH_REMBO_Wrapper: + def __init__(self, + func:Callable, + dim:int, + lb:float, + ub:float, + act_var=None, + noise_var=0): + + self.range=np.array([(lb,ub)*dim]).reshape((-1,2)) + self.__act_var=act_var + self.__var = noise_var + # Include the function + self.func = func + self.__dim = dim + + def scale_domain(self,x)->np.ndarray: + # Scaling the domain + x_copy = np.copy(x) + if len(x_copy.shape) == 1: + x_copy = x_copy.reshape((1, x_copy.shape[0])) + + for i in range(len(self.range)): + x_copy[:, i] = x_copy[:, i] * (self.range[i,1] - self.range[i,0]) / 2 + ( + self.range[i,1] + self.range[i,0]) / 2 + + new_ar = np.unique(x_copy,axis=0) + return new_ar + + def evaluate_true(self,x): + x_scaled = self.scale_domain(x) + + f = [] + + for idx_,val in enumerate(x_scaled): + f.append(self.func(val)) + + return np.multiply(-1,np.array(f).reshape((-1,1))) + + def evaluate(self, x): + + x_org = self.evaluate_true(x) + n = len(x_org) + + return x_org + np.random.normal(0,self.var,(n,1)) + + + @property + def act_var(self)->np.ndarray: + return self.__act_var + + @act_var.setter + def act_var(self,new_act_var:np.ndarray)->None: + self.__act_var = new_act_var + + @property + def var(self)->float: + return self.__var + + @var.setter + def var(self,new_var)->None: + self.__var = new_var + + + f_wrapper:IOH_REMBO_Wrapper = IOH_REMBO_Wrapper(func=self.func, + dim = self.dim, + lb=self.lb, + ub= self.ub, + noise_var=0) + + self.opt:RemboSetter = RemboSetter(self.random_seed, + sample_zero=self.sample_zero) + # Call the runner + self.opt.optimize(func=f_wrapper, + low_dim=low_dim, + high_dim=self.dim, + initial_n=self.Doe_size, + total_itr=self.total_budget-self.Doe_size, + hyper_opt_interval=hyper_opt_interval, + matrix_type=matrix_type, + kern_inp_type=kern_inp_type, + ARD=ard,variance=variance, + box_size=box_size, + noise_var=0) + + + + # def get_acq_time(self): + # return self.opt.acq_opt_time + + # def get_mode_time(self): + # return self.opt.mode_fit_time + + # def get_iter_time(self): + # return self.opt.cum_iteration_time + + +class BO_Torch_VanillaBO_Wrapper(Abstract_Bayesian_Optimizer_Wrapper): + r""" + This is a wrapper to use a basic code for Vanilla BO by using the most basic + BO-Torch implementation. + """ + libpath = pathlib.Path(os.path.join("mylib","lib_BO_torch_repo")) + + + def __init__(self, func, + dim:int, ub, lb, + total_budget:int, + DoE_size:int, + random_seed:int, + sample_zero:bool=False, + verbose=True): + + # Use the general class initializer + super().__init__(func=func, + dim=dim, + ub=ub, + lb=lb, DoE_size=DoE_size, + total_budget=total_budget, + random_seed=random_seed, + sample_zero=sample_zero) + + # Set an additional verbose property + self._verbose = verbose + + + def run(self,**kwargs): + # Call the Algorithm + try: + from mylib.lib_BO_torch_repo.Algorithms import Vanilla_BO + except ModuleNotFoundError: + # Call the normal way + from Algorithms import Vanilla_BO + + + # Extract the kwargs to set up the experiments + acq_func:str = str(kwargs.pop("acquisition_function","EI")) + beta:float = float(kwargs.pop("beta",0.2)) + + + # Set up the algorithm + self.opt = Vanilla_BO(budget=self.total_budget, + n_DoE=self.Doe_size, + random_seed=self.random_seed, + acquisition_function=acq_func, + verbose = self._verbose, + DoE_parameters = {'sample_zero':self.sample_zero, + 'criterion':"center"} + ) + + self.opt(problem = self.func, + dim = self.dim, + bounds = np.asarray([(self.lb,self.ub) for _ in range(self.dim)]), + beta=beta) + + + +def wrapopt(optimizer_name:str, + func:Callable, + ml_dim:int, + ml_total_budget:int, + ml_DoE_size:int, + random_seed:int, + sample_zero:bool=False): + ub = +5 + lb = -5 + if optimizer_name == "saasbo": + return SaasboWrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, DoE_size=ml_DoE_size, + random_seed=random_seed,sample_zero=sample_zero) + if optimizer_name == "BO_sklearn": + return BO_sklearnWrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, DoE_size=ml_DoE_size, + random_seed=random_seed,sample_zero=sample_zero) + if optimizer_name == "BO_bayesoptim": + return BO_bayesoptimWrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, DoE_size=ml_DoE_size, + random_seed=random_seed,sample_zero=sample_zero) + if optimizer_name == "random": + return randomWrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, DoE_size=ml_DoE_size, + random_seed=random_seed) + if optimizer_name == "linearPCABO": + return linearPCABOWrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, DoE_size=ml_DoE_size, + random_seed=random_seed,sample_zero=sample_zero) + if optimizer_name == "turbo1": + return turbo1Wrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, DoE_size=ml_DoE_size, + random_seed=random_seed,sample_zero=sample_zero) + if optimizer_name == "turbom": + return turbomWrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, DoE_size=ml_DoE_size, + random_seed=random_seed,sample_zero=sample_zero) + if optimizer_name == 'BO_dev_Hao': + return BO_development_bayesoptimWrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, DoE_size=ml_DoE_size, + random_seed=random_seed,sample_zero=sample_zero) + if optimizer_name == 'EBO': + return EBOWrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, DoE_size=ml_DoE_size, + random_seed=random_seed,sample_zero=sample_zero) + if optimizer_name == 'EBO_B': + return EBO_BWrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, DoE_size=ml_DoE_size, + random_seed=random_seed,sample_zero=sample_zero) + if optimizer_name == 'KPCABO': + return KPCABOWrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, DoE_size=ml_DoE_size, + random_seed=random_seed,sample_zero=sample_zero) + if optimizer_name == 'pyCMA': + return Py_CMA_ES_Wrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, + random_seed=random_seed) + + if optimizer_name == 'RDUCB': + return RDUCBWrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, DoE_size=ml_DoE_size, + random_seed=random_seed,sample_zero=sample_zero) + if optimizer_name == 'ALEBO': + return ALEBOWrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, DoE_size=ml_DoE_size, + random_seed=random_seed,sample_zero=sample_zero) + if optimizer_name == 'HEBO': + return HEBOWrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, DoE_size=ml_DoE_size, + random_seed=random_seed,sample_zero=sample_zero) + + # TODO: NEW ADDENDA TO COMPLY WITH KUDELA, STRIPINIS, RAMIUZKAS + if optimizer_name == "BAxUS": + return BAxUSWrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, DoE_size=ml_DoE_size, + random_seed=random_seed,sample_zero=sample_zero) + + if optimizer_name== "SMAC": + return SMACWrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, DoE_size=ml_DoE_size, + random_seed=random_seed,sample_zero=sample_zero) + + if optimizer_name=="REMBO": + return REMBOWrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, DoE_size=ml_DoE_size, + random_seed=random_seed,sample_zero=sample_zero) + + + if optimizer_name=="BO_botorch": + return BO_Torch_VanillaBO_Wrapper(func=func, dim=ml_dim, ub=ub, lb=lb, total_budget=ml_total_budget, DoE_size=ml_DoE_size, + random_seed=random_seed,sample_zero=sample_zero) + +if __name__ == "__main__": + dim = 3 + total_budget = 200 + doe_size = dim + seed = 4 + sample_zero = True + + try: + import ioh + except ModuleNotFoundError as e: + print("IOH module not found",e.msg) + + # Algorithm alternatives: + algorithm_name = "REMBO" + #algorithm_name = "turbom" + f = get_problem(1, dimension=dim, instance=1, problem_class=ioh.ProblemClass.BBOB) + + opt = wrapopt(algorithm_name, + f, + dim, + total_budget, + doe_size, + seed, + sample_zero) + opt.run(matrix_type="normal",kern_inp_type="X",ARD=False) diff --git a/wrapper_helper.py b/wrapper_helper.py new file mode 100644 index 0000000..05452cc --- /dev/null +++ b/wrapper_helper.py @@ -0,0 +1,95 @@ +import sys, os + + +try: + from mylib.lib_BAxUS.BAxUS.baxus.benchmarks.benchmark_function import SyntheticBenchmark +except ModuleNotFoundError as e: + print("The benchmark module could not be found! , trying to use another way!!!") + __set_directory__:str= os.path.abspath(os.path.dirname(__file__)) + + sys.path.append(os.path.join(__set_directory__,"mylib","lib_BAxUS","BAxUS")) + from baxus.benchmarks.benchmark_function import SyntheticBenchmark + +import ioh +from typing import List,Tuple,Optional,Union, Callable + +import numpy as np + + + +# This is a helper class to wrap the IOH-BBOB problem instances to run with the BAxUS framework +class IOH_BAxUS_Wrapper(SyntheticBenchmark): + + r""" + This is a wrapper which extends the IOH Single Objective defined instances + to work with BAxUS. + """ + + def __init__(self, + f:Callable, + dim:int, + lb:int, + ub:int, + noise_std: Optional[float] = None, + )->None: + + r""" + Args: + -------- + - f: A IOH Real Single Objective instance + - noise_std: Standard deviation of the observation noise. + - negate: If True, negate the function. + """ + self.__dim = dim + + self.__bounds = [(lb, ub) for _ in range(self.__dim)] + + self.__f:ioh.problem.RealSingleObjective = f + + # Convert the bounds definition + lb_:np.ndarray = np.ravel(np.array(self.__bounds)[:,0]) + ub_:np.ndarray = np.ravel(np.array(self.__bounds)[:,1]) + + # Use the constructor from `SyntheticBenchmark` + super().__init__(dim= self.__dim,lb=lb_,ub=ub_, + noise_std=noise_std) + + def __call__(self, x: Union[np.ndarray, List[float], List[List[float]]])->np.ndarray: + + r""" + This is the implementation of the `__call__` function for this wrapper class. + + Args: + --------- + - x: A list or array with possible points to evaluate. + """ + # Call the __call__ function from the polymorphic class + + + #x =super().__call__(x) + x:np.ndarray = np.array(x) + if x.ndim == 0: + x = np.expand_dims(x, 0) + if x.ndim == 1: + x = np.expand_dims(x, 0) + assert x.ndim == 2 + + result = self.__f(x.ravel()) + + return result + + + @property + def dim(self)->int: + return self.__dim + + @property + def bounds(self)->Union[float,List[float]]: + return self.__bounds + + @property + def IOH_instance(self)->ioh.problem.RealSingleObjective: + return self.__f + + + From c8ebd3278f894d31e9f9f9a44a1bdf95d4c0cf9f Mon Sep 17 00:00:00 2001 From: Ivan Olarte Rodriguez <126246479+olarterodriguezivan@users.noreply.github.com> Date: Mon, 10 Mar 2025 14:09:28 +0100 Subject: [PATCH 2/6] BAxUS --- mylib/lib_BAxUS/BAxUS/CONTRIBUTORS.md | 7 + mylib/lib_BAxUS/BAxUS/Dockerfile | 8 + mylib/lib_BAxUS/BAxUS/LICENSE.md | 41 + mylib/lib_BAxUS/BAxUS/README.md | 273 +++++++ mylib/lib_BAxUS/BAxUS/baxus/__init__.py | 2 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 275 bytes .../baxus/__pycache__/baxus.cpython-310.pyc | Bin 0 -> 17735 bytes .../benchmark_runner.cpython-310.pyc | Bin 0 -> 6755 bytes .../__pycache__/embeddedturbo.cpython-310.pyc | Bin 0 -> 20463 bytes .../baxus/__pycache__/gp.cpython-310.pyc | Bin 0 -> 4972 bytes mylib/lib_BAxUS/BAxUS/baxus/baxus.py | 629 +++++++++++++++ .../lib_BAxUS/BAxUS/baxus/benchmark_runner.py | 339 ++++++++ .../BAxUS/baxus/benchmarks/__init__.py | 12 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 1294 bytes .../benchmark_function.cpython-310.pyc | Bin 0 -> 11014 bytes .../benchmark_utils.cpython-310.pyc | Bin 0 -> 1961 bytes .../__pycache__/other_methods.cpython-310.pyc | Bin 0 -> 5026 bytes .../real_world_benchmarks.cpython-310.pyc | Bin 0 -> 17723 bytes ...thetic_benchmark_functions.cpython-310.pyc | Bin 0 -> 9218 bytes .../baxus/benchmarks/benchmark_function.py | 343 ++++++++ .../BAxUS/baxus/benchmarks/benchmark_utils.py | 63 ++ .../BAxUS/baxus/benchmarks/other_methods.py | 149 ++++ .../baxus/benchmarks/real_world_benchmarks.py | 732 +++++++++++++++++ .../synthetic_benchmark_functions.py | 283 +++++++ mylib/lib_BAxUS/BAxUS/baxus/embeddedturbo.py | 760 ++++++++++++++++++ mylib/lib_BAxUS/BAxUS/baxus/gp.py | 230 ++++++ mylib/lib_BAxUS/BAxUS/baxus/util/__init__.py | 0 .../util/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 194 bytes ...acquisition_function_types.cpython-310.pyc | Bin 0 -> 486 bytes .../acquisition_functions.cpython-310.pyc | Bin 0 -> 2231 bytes .../__pycache__/data_utils.cpython-310.pyc | Bin 0 -> 1968 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 1204 bytes .../util/__pycache__/gp_utils.cpython-310.pyc | Bin 0 -> 4475 bytes .../util/__pycache__/parsing.cpython-310.pyc | Bin 0 -> 7677 bytes .../__pycache__/projections.cpython-310.pyc | Bin 0 -> 7742 bytes .../util/__pycache__/utils.cpython-310.pyc | Bin 0 -> 6907 bytes .../baxus/util/acquisition_function_types.py | 12 + .../BAxUS/baxus/util/acquisition_functions.py | 50 ++ .../BAxUS/baxus/util/behaviors/__init__.py | 6 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 377 bytes .../baxus_configuration.cpython-310.pyc | Bin 0 -> 1541 bytes ...bedded_turbo_configuration.cpython-310.pyc | Bin 0 -> 2377 bytes .../embedding_configuration.cpython-310.pyc | Bin 0 -> 456 bytes .../gp_configuration.cpython-310.pyc | Bin 0 -> 1132 bytes .../util/behaviors/baxus_configuration.py | 53 ++ .../behaviors/embedded_turbo_configuration.py | 99 +++ .../util/behaviors/embedding_configuration.py | 12 + .../baxus/util/behaviors/gp_configuration.py | 39 + .../BAxUS/baxus/util/console_entry_point.py | 7 + .../lib_BAxUS/BAxUS/baxus/util/data_utils.py | 43 + .../lib_BAxUS/BAxUS/baxus/util/exceptions.py | 30 + mylib/lib_BAxUS/BAxUS/baxus/util/gp_utils.py | 127 +++ mylib/lib_BAxUS/BAxUS/baxus/util/parsing.py | 375 +++++++++ .../lib_BAxUS/BAxUS/baxus/util/projections.py | 199 +++++ .../baxus/util/space_learning/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 209 bytes .../__pycache__/trust_region.cpython-310.pyc | Bin 0 -> 1513 bytes .../baxus/util/space_learning/trust_region.py | 47 ++ mylib/lib_BAxUS/BAxUS/baxus/util/utils.py | 232 ++++++ mylib/lib_BAxUS/BAxUS/baxus_figure.png | Bin 0 -> 85473 bytes mylib/lib_BAxUS/BAxUS/benchmark_runner.py | 6 + .../BAxUS/data/rotation_matrix_alebo.json | 1 + .../BAxUS/data/rotation_matrix_alebo.npy | Bin 0 -> 48128 bytes mylib/lib_BAxUS/BAxUS/docs/LICENSE.md | 43 + mylib/lib_BAxUS/BAxUS/docs/Makefile | 20 + .../BAxUS/docs/_templates/layout.html | 12 + mylib/lib_BAxUS/BAxUS/docs/cli_options.rst | 124 +++ mylib/lib_BAxUS/BAxUS/docs/conf.py | 58 ++ .../lib_BAxUS/BAxUS/docs/custom_functions.rst | 75 ++ mylib/lib_BAxUS/BAxUS/docs/getting_started.md | 14 + mylib/lib_BAxUS/BAxUS/docs/index.rst | 24 + mylib/lib_BAxUS/BAxUS/docs/installation.md | 93 +++ mylib/lib_BAxUS/BAxUS/docs/make.bat | 35 + mylib/lib_BAxUS/BAxUS/docs/notices.md | 4 + mylib/lib_BAxUS/BAxUS/docs/reproducing.md | 191 +++++ .../lib_BAxUS/BAxUS/docs/troubleshooting.rst | 28 + mylib/lib_BAxUS/BAxUS/requirements.txt | 8 + mylib/lib_BAxUS/BAxUS/setup.py | 29 + mylib/lib_BAxUS/BAxUS/tests/__init__.py | 0 .../tests/data/slice_localization_data.csv.xz | Bin 0 -> 13206892 bytes mylib/lib_BAxUS/BAxUS/tests/test_baxus.py | 19 + .../BAxUS/tests/test_benchmark_function.py | 183 +++++ .../BAxUS/tests/test_benchmark_runner.py | 269 +++++++ .../lib_BAxUS/BAxUS/tests/test_projections.py | 114 +++ .../test_synthetic_benchmark_functions.py | 274 +++++++ 85 files changed, 6826 insertions(+) create mode 100644 mylib/lib_BAxUS/BAxUS/CONTRIBUTORS.md create mode 100644 mylib/lib_BAxUS/BAxUS/Dockerfile create mode 100644 mylib/lib_BAxUS/BAxUS/LICENSE.md create mode 100644 mylib/lib_BAxUS/BAxUS/README.md create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/__init__.py create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/__pycache__/__init__.cpython-310.pyc create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/__pycache__/baxus.cpython-310.pyc create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/__pycache__/benchmark_runner.cpython-310.pyc create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/__pycache__/embeddedturbo.cpython-310.pyc create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/__pycache__/gp.cpython-310.pyc create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/baxus.py create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/benchmark_runner.py create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/benchmarks/__init__.py create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/benchmarks/__pycache__/__init__.cpython-310.pyc create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/benchmarks/__pycache__/benchmark_function.cpython-310.pyc create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/benchmarks/__pycache__/benchmark_utils.cpython-310.pyc create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/benchmarks/__pycache__/other_methods.cpython-310.pyc create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/benchmarks/__pycache__/real_world_benchmarks.cpython-310.pyc create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/benchmarks/__pycache__/synthetic_benchmark_functions.cpython-310.pyc create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/benchmarks/benchmark_function.py create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/benchmarks/benchmark_utils.py create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/benchmarks/other_methods.py create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/benchmarks/real_world_benchmarks.py create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/benchmarks/synthetic_benchmark_functions.py create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/embeddedturbo.py create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/gp.py create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/util/__init__.py create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/util/__pycache__/__init__.cpython-310.pyc create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/util/__pycache__/acquisition_function_types.cpython-310.pyc create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/util/__pycache__/acquisition_functions.cpython-310.pyc create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/util/__pycache__/data_utils.cpython-310.pyc create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/util/__pycache__/exceptions.cpython-310.pyc create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/util/__pycache__/gp_utils.cpython-310.pyc create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/util/__pycache__/parsing.cpython-310.pyc create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/util/__pycache__/projections.cpython-310.pyc create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/util/__pycache__/utils.cpython-310.pyc create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/util/acquisition_function_types.py create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/util/acquisition_functions.py create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/util/behaviors/__init__.py create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/util/behaviors/__pycache__/__init__.cpython-310.pyc create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/util/behaviors/__pycache__/baxus_configuration.cpython-310.pyc create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/util/behaviors/__pycache__/embedded_turbo_configuration.cpython-310.pyc create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/util/behaviors/__pycache__/embedding_configuration.cpython-310.pyc create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/util/behaviors/__pycache__/gp_configuration.cpython-310.pyc create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/util/behaviors/baxus_configuration.py create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/util/behaviors/embedded_turbo_configuration.py create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/util/behaviors/embedding_configuration.py create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/util/behaviors/gp_configuration.py create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/util/console_entry_point.py create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/util/data_utils.py create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/util/exceptions.py create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/util/gp_utils.py create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/util/parsing.py create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/util/projections.py create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/util/space_learning/__init__.py create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/util/space_learning/__pycache__/__init__.cpython-310.pyc create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/util/space_learning/__pycache__/trust_region.cpython-310.pyc create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/util/space_learning/trust_region.py create mode 100644 mylib/lib_BAxUS/BAxUS/baxus/util/utils.py create mode 100644 mylib/lib_BAxUS/BAxUS/baxus_figure.png create mode 100644 mylib/lib_BAxUS/BAxUS/benchmark_runner.py create mode 100644 mylib/lib_BAxUS/BAxUS/data/rotation_matrix_alebo.json create mode 100644 mylib/lib_BAxUS/BAxUS/data/rotation_matrix_alebo.npy create mode 100644 mylib/lib_BAxUS/BAxUS/docs/LICENSE.md create mode 100644 mylib/lib_BAxUS/BAxUS/docs/Makefile create mode 100644 mylib/lib_BAxUS/BAxUS/docs/_templates/layout.html create mode 100644 mylib/lib_BAxUS/BAxUS/docs/cli_options.rst create mode 100644 mylib/lib_BAxUS/BAxUS/docs/conf.py create mode 100644 mylib/lib_BAxUS/BAxUS/docs/custom_functions.rst create mode 100644 mylib/lib_BAxUS/BAxUS/docs/getting_started.md create mode 100644 mylib/lib_BAxUS/BAxUS/docs/index.rst create mode 100644 mylib/lib_BAxUS/BAxUS/docs/installation.md create mode 100644 mylib/lib_BAxUS/BAxUS/docs/make.bat create mode 100644 mylib/lib_BAxUS/BAxUS/docs/notices.md create mode 100644 mylib/lib_BAxUS/BAxUS/docs/reproducing.md create mode 100644 mylib/lib_BAxUS/BAxUS/docs/troubleshooting.rst create mode 100644 mylib/lib_BAxUS/BAxUS/requirements.txt create mode 100644 mylib/lib_BAxUS/BAxUS/setup.py create mode 100644 mylib/lib_BAxUS/BAxUS/tests/__init__.py create mode 100644 mylib/lib_BAxUS/BAxUS/tests/data/slice_localization_data.csv.xz create mode 100644 mylib/lib_BAxUS/BAxUS/tests/test_baxus.py create mode 100644 mylib/lib_BAxUS/BAxUS/tests/test_benchmark_function.py create mode 100644 mylib/lib_BAxUS/BAxUS/tests/test_benchmark_runner.py create mode 100644 mylib/lib_BAxUS/BAxUS/tests/test_projections.py create mode 100644 mylib/lib_BAxUS/BAxUS/tests/test_synthetic_benchmark_functions.py diff --git a/mylib/lib_BAxUS/BAxUS/CONTRIBUTORS.md b/mylib/lib_BAxUS/BAxUS/CONTRIBUTORS.md new file mode 100644 index 0000000..8021e15 --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/CONTRIBUTORS.md @@ -0,0 +1,7 @@ +Original TuRBO implementation written by: + +- David Eriksson + +BAxUS code written by: + +- Leonard Papenmeier diff --git a/mylib/lib_BAxUS/BAxUS/Dockerfile b/mylib/lib_BAxUS/BAxUS/Dockerfile new file mode 100644 index 0000000..1641c7c --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/Dockerfile @@ -0,0 +1,8 @@ +FROM python:3.10-buster +WORKDIR /app +COPY . . +RUN apt-get update && \ + apt-get -y upgrade &&\ + apt-get -y install libsuitesparse-dev libatlas-base-dev swig libopenblas-dev libsdl2-mixer-2.0-0 libsdl2-image-2.0-0 libsdl2-2.0-0 libsdl2-ttf-2.0-0 libsdl2-dev &&\ + pip install --no-cache-dir -r requirements.txt + diff --git a/mylib/lib_BAxUS/BAxUS/LICENSE.md b/mylib/lib_BAxUS/BAxUS/LICENSE.md new file mode 100644 index 0000000..063c3cb --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/LICENSE.md @@ -0,0 +1,41 @@ +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by the text below. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under this License. + +This License governs use of the accompanying Work, and your use of the Work constitutes acceptance of this License. + +You may use this Work for any non-commercial purpose, subject to the restrictions in this License. Some purposes which can be non-commercial are teaching, academic research, and personal experimentation. You may also distribute this Work with books or other teaching materials, or publish the Work on websites, that are intended to teach the use of the Work. + +You may not use or distribute this Work, or any derivative works, outputs, or results from the Work, in any form for commercial purposes. Non-exhaustive examples of commercial purposes would be running business operations, licensing, leasing, or selling the Work, or distributing the Work for use with commercial products. + +You may modify this Work and distribute the modified Work for non-commercial purposes, however, you may not grant rights to the Work or derivative works that are broader than or in conflict with those provided by this License. For example, you may not distribute modifications of the Work under terms that would permit commercial use, or under terms that purport to require the Work or derivative works to be sublicensed to others. + +In return, we require that you agree: + +1. Not to remove any copyright or other notices from the Work. + +2. That if you distribute the Work in Source or Object form, you will include a verbatim copy of this License. + +3. That if you distribute derivative works of the Work in Source form, you do so only under a license that includes all of the provisions of this License and is not in conflict with this License, and if you distribute derivative works of the Work solely in Object form you do so only under a license that complies with this License. + +4. That if you have modified the Work or created derivative works from the Work, and distribute such modifications or derivative works, you will cause the modified files to carry prominent notices so that recipients know that they are not receiving the original Work. Such notices must state: (i) that you have changed the Work; and (ii) the date of any changes. + +5. If you publicly use the Work or any output or result of the Work, you will provide a notice with such use that provides any person who uses, views, accesses, interacts with, or is otherwise exposed to the Work (i) with information of the nature of the Work, (ii) with a link to the Work, and (iii) a notice that the Work is available under this License. + +6. THAT THE WORK COMES "AS IS", WITH NO WARRANTIES. THIS MEANS NO EXPRESS, IMPLIED OR STATUTORY WARRANTY, INCLUDING WITHOUT LIMITATION, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE OR ANY WARRANTY OF TITLE OR NON-INFRINGEMENT. ALSO, YOU MUST PASS THIS DISCLAIMER ON WHENEVER YOU DISTRIBUTE THE WORK OR DERIVATIVE WORKS. + +7. THAT NEITHER UBER TECHNOLOGIES, INC. NOR ANY OF ITS AFFILIATES, SUPPLIERS, SUCCESSORS, NOR ASSIGNS WILL BE LIABLE FOR ANY DAMAGES RELATED TO THE WORK OR THIS LICENSE, INCLUDING DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL OR INCIDENTAL DAMAGES, TO THE MAXIMUM EXTENT THE LAW PERMITS, NO MATTER WHAT LEGAL THEORY IT IS BASED ON. ALSO, YOU MUST PASS THIS LIMITATION OF LIABILITY ON WHENEVER YOU DISTRIBUTE THE WORK OR DERIVATIVE WORKS. + +8. That if you sue anyone over patents that you think may apply to the Work or anyone's use of the Work, your license to the Work ends automatically. + +9. That your rights under the License end automatically if you breach it in any way. + +10. Uber Technologies, Inc. reserves all rights not expressly granted to you in this License. diff --git a/mylib/lib_BAxUS/BAxUS/README.md b/mylib/lib_BAxUS/BAxUS/README.md new file mode 100644 index 0000000..4b8e1fe --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/README.md @@ -0,0 +1,273 @@ +# Increasing the Scope as You Learn: BAxUS + +> 💡 **_NOTE:_** If you're interested in BAxUS, please consider using [Bounce](https://github.com/LeoIV/bounce), which comes with an improved trust region management policy, an easier setup, and batch parallelism. + +![figure of splitting method](baxus_figure.png) + +This is the code for [our paper](https://openreview.net/pdf?id=e4Wf6112DI): +`Increasing the Scope as You Learn: Adaptive Bayesian Optimization in Nested Subspaces` (Leonard Papenmeier, Luigi Nardi, and Matthias +Poloczek) + +Please see the full [online documentation](https://baxus.papenmeier.io). + +## Installation + +You have four options for installing `BAxUS`: `PyPi`, `Docker`, `setup.py`, or `requirements.txt`. +Please make sure to install the following packages before running the non-Docker `BAxUS` installation. +We assume that you have a Debian Buster or Bullseye based Linux distribution (e.g., Ubuntu 18.04 or Ubuntu 20.04). +Please use a Docker image if you are working with a different distribution: + +### Installation from PyPi + +```bash +pip install baxus +``` + +### Installation from source + +First install required software: + +```bash +apt-get update && apt-get -y upgrade && apt-get -y install libsuitesparse-dev libatlas-base-dev swig libopenblas-dev libsdl2-mixer-2.0-0 libsdl2-image-2.0-0 libsdl2-2.0-0 libsdl2-ttf-2.0-0 libsdl2-dev +``` + +Then install with the `setup.py`: + +```bash +cd baxus +pip install . +``` + +or with the requirements.txt: + +```bash +cd baxus +pip install -r requirements.txt +``` + +### Docker image + +Alternatively, use the Docker installation. +We do not share the Docker image to ensure anonymity. +However, you can build the Docker image yourself with the provided `Dockerfile`: + +First, [install Docker](https://docs.docker.com/engine/install/). +Next, build the Docker image + +```bash +cd baxus +sudo docker build -t baxus +``` + +By default, BAxUS stores all results in a directory called `results`. +To get the results on the host machine, first create this directory and mount it into the Docker container: + +```bash +mkdir results +sudo docker run -v "$(pwd)/results":/app/results baxus /bin/bash -c "python benchmark_runner.py -id 100 -td 1 -f branin2 --adjust-initial-target-dimension" +``` + +After the run completed, the results can be obtained in the `./results` directory. + +## Getting started + +The main file is `benchmark_runner.py` in the project root. +It can be configured with command line arguments (see [Command Line Options](README.html)) + +For example, to run `BAxUS` for 1,000 function evaluations on a Branin2 function with input dimensionality 100 for one +repetition run (for installation from source) + +```python +python3 +benchmark_runner.py - id +100 - td +1 - n +10 - r +1 - m +1000 - f +branin2 - a +baxus - -adjust - initial - target - dimension +``` + +or, for PyPi installations, + +```bash +benchmark_runner.py -id 100 -td 1 -n 10 -r 1 -m 1000 -f branin2 -a baxus --adjust-initial-target-dimension +``` + +For Docker, follow the instructions above. + +Note that we need to pass an initial target dimensionality with `-td 1` even though this is adjusted later by passing +the option `--adjust-initial-target-dimension`- + +## Command line options + +| **Name** | **Shortcut** | **Full argument** | **Default** | **Description** | +|--------------------------------------|--------------|-------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| Algorithm | `-a` | `--algorithms` | `baxus` | The algorithm to run. Has tobe from `baxus`, `embedded_turbo_target_dim`, `embedded_turbo_effective_dim`, `embedded_turbo_2_effective_dim`, `random_search` | +| Function | `-f` | `--functions` | None | One ore several test functions. Has to be from `lunarlander`,`mnist`,`robotpushing`,`roverplanning`,`hartmann6`,`branin2`,`rosenbrock5`,`rosenbrock10`,`ackley`,`rosenbrock`,`levy`,`dixonprice`,`griewank`,`michalewicz`,`rastrigin`,`bipedalnncontroller`,`acrobotnncontroller`,`svm`,`lasso10`,`mopta08`,`hartmann6in1000_rotated`,`rosenbrock5in1000_rotated`. | +| Input dimensionality | `-id` | `--input-dim` | `100` | Input dimensionality of the function. This is overriden when the function has a fixed dimensionality. | +| Target dimensionality | `-td` | `--target-dim` | `10` | (Initial) targetdimensionality of the function. Whether initial or not depends on the algorithm. Initial for `BAxUS` as it adapts the target dimensionality. | | +| Acquisition function | None | `--acquisition-function` | `ts` | Either `ts` (Thompson sampling) or `ei` (Expected improvement) | +| Embedding type | None | `--embedding-type` | `baxus` | Either `baxus` (for the BAxUS embedding) or `hesbo` (for the HeSBO embedding) | +| Adjust initial target dimensionality | None | `--adjust-initial-target-dimension` | not set | Whether to adjust initial target dimensionality as described in the BAxUS paper. | +| Number of initial samples | `-n` | `--n-init` | None (set to target dimensionality + 1 if not set) | Number of samples. | +| Number of repetitions | `-r` | `--num-repetitions` | `1` | Number repetitions of the run. | +| Number of evaluations | `-m` | `--max-evals` | `300` | Number evaluations. Cma-ES might use a few more. | +| Initial baselength | `-l` | `--initial-baselength` | `0.8` | The base length of the trust region (default value is as in the TuRBO paper). | +| Minimum baselength | `-lmin` | `--min-baselength` | `0.5^7` | The base length a trust region is allowed to obtain (default value is as in the TuRBO paper). | +| Maximum baselength | `-l_max` | `--max-baselength` | 1.6 | The maximum base length a trust region is allowed obtain (default value is as in the TuRBO paper). | +| Noise standard deviation | None | `--noise-std` | `0` | The deviation of the noise. Whether this is used or not depends on the benchmark. It is generally only recognized synthetic benchmarks like `Branin2` but also for the synthetic `Lasso` versions. | +| Results directory | None | `--results-dir` | `results` | The directory which the results are written. Relative to the path from which the run was started. | +| Run description | None | `--run-description` | None | Short description that will be added to the run directory | +| MLE multistart samples | None | `--multistart-samples` | `100` | Number of multistart samples for the MLE GD optimization. Samples will be drawn from latin hypercube | +| Multistarts after sampling | None | `--multistart-after-sample` | `10` | Only recognized for `--mle-optimization sample-and-choose-best`. Number of multi-start gradient descent optimization of the `--multistart-samples` best ones. | | +| MLE optimization method | None | `--mle-optimization` | `sample-and-choose-best` Either `multistart-gd` or `sample-and-choose-best`. | | +| Number of MLE gradient updates | None | `--mle-training-steps` | `50` | Number of GD steps in MLE maximization. | | +| Budget until input dimensionality | None | `--budget-until-input-dim` | `0` | The budget after which BAxUS will roughly reach the input dimensionality (see paper for details). If `0`: this is ignored | | | | | +| Verbose mode | `-v` | `--verbose` | not set | Whether to print verbose messages | + +## Optimizing custom functions + +### Custom benchmark class + +For practical use cases, you want to optimize your own functions instead of running benchmark functions. Let's see how +we implement benchmark functions. As an example, +[MoptaSoftConstraints](source/baxus.benchmarks.html#baxus.benchmarks.real_world_benchmarks.MoptaSoftConstraints) +implements +[SyntheticBenchmark](source/baxus.benchmarks.html#baxus.benchmarks.benchmark_function.SyntheticBenchmark), which means +in particular that it has its +own `__call__` function. + +Let's look at the `__call__` function +of [MoptaSoftConstraints](source/baxus.benchmarks.html#baxus.benchmarks.real_world_benchmarks.MoptaSoftConstraints): + +```python +def __call__(self, x): + super(MoptaSoftConstraints, self).__call__(x) + x = np.array(x) + if x.ndim == 0: + x = np.expand_dims(x, 0) + if x.ndim == 1: + x = np.expand_dims(x, 0) + assert x.ndim == 2 + + vals = np.array([self._call(y) for y in x]).squeeze() + return vals +``` + +which consists of some checks that ensure that we use the internal `self._call` function correctly. + +If you want to use BAxUS with a custom function, you can just use this implementation and replace +`self._call` in the line +`vals = np.array([self._call(y) for y in x]).squeeze()` +with a call to your own function expecting a 1D numpy array. + +### Example for a custom benchmark function + +A custom benchmark function could look as follows: + +```python3 +from typing import Union, List + +import numpy as np +from baxus.benchmarks.benchmark_function import Benchmark + + +class Parabula(Benchmark): + + def __init__(self): + super().__init__(dim=100, ub=10 * np.ones(100), lb=-10 * np.ones(100), noise_std=0) + + def __call__(self, x: Union[np.ndarray, List[float], List[List[float]]]): + x = np.array(x) + if x.ndim == 0: + x = np.expand_dims(x, 0) + if x.ndim == 1: + x = np.expand_dims(x, 0) + assert x.ndim == 2 + y = np.sum(x ** 2, axis=1) + return y +``` + +To run `BAxUS` on it, either register it for the benchmark runner (see explanation below), +or call `BAxUS` directly: + +```python3 +from baxus import BAxUS + +baxus = BAxUS( + run_dir="results", + max_evals=100, + n_init=10, + f=Parabula(), + target_dim=2, + verbose=True, +) + +baxus.optimize() + +``` + +The results of the optimization can afterwards be obtained by + +```python3 +x_raw, y_raw = baxus.optimization_results_raw() # get the points in the search space and their function values +x_inc, y_inc = baxus.optimization_results_incumbent() # get the points in the search space and the best function value at each time step +``` + +### How do I register my new function? + +For this we need to look at the [parsing.parse](source/baxus.util.html#baxus.util.parsing.parse) function. +The first thing to do is to append your benchmark to the list of existing benchmarks, +currently consisting of + +```python +required_named.add_argument( + "-f", + "--functions", + nargs="+", + choices=[ + "hartmann6", + "branin2", + ..., + "MY_NEW_NAME" # <---------------- ADD THIS LINE + ], + required=True, +) +``` + +Next, we have to register the new name in the [parsing.fun_mapper](source/baxus.util.html#baxus.util.parsing.fun_mapper) +function: + +```python +def fun_mapper(): + return { + **{ + "hartmann6": Hartmann6, + "branin2": Branin2, + "rosenbrock2": functools.partial(RosenbrockEffectiveDim, effective_dim=2), + ..., + "MY_NEW_NAME": MyBenchmarkImplementation # <--------- ADD THIS LINE + }, + ** _fun_mapper, + } +``` + +and that's it. + +## Citation + +Please cite [our paper](https://openreview.net/pdf?id=e4Wf6112DI) if you use the code: + +``` +@inproceedings{ +papenmeier2022increasing, +title={Increasing the Scope as You Learn: Adaptive Bayesian Optimization in Nested Subspaces}, +author={Leonard Papenmeier and Luigi Nardi and Matthias Poloczek}, +booktitle={Advances in Neural Information Processing Systems}, +editor={Alice H. Oh and Alekh Agarwal and Danielle Belgrave and Kyunghyun Cho}, +year={2022}, +url={https://openreview.net/forum?id=e4Wf6112DI} +} +``` diff --git a/mylib/lib_BAxUS/BAxUS/baxus/__init__.py b/mylib/lib_BAxUS/BAxUS/baxus/__init__.py new file mode 100644 index 0000000..b776a2b --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/baxus/__init__.py @@ -0,0 +1,2 @@ +from .embeddedturbo import EmbeddedTuRBO +from .baxus import BAxUS diff --git a/mylib/lib_BAxUS/BAxUS/baxus/__pycache__/__init__.cpython-310.pyc b/mylib/lib_BAxUS/BAxUS/baxus/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d539b3e7f9d96b8630d4326c9e2ed7a8b181d566 GIT binary patch literal 275 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 E0cvKEYXATM literal 0 HcmV?d00001 diff --git a/mylib/lib_BAxUS/BAxUS/baxus/__pycache__/gp.cpython-310.pyc b/mylib/lib_BAxUS/BAxUS/baxus/__pycache__/gp.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..23e02ae0b2558bcfb5d756a689f3ac096ceb8db1 GIT binary patch literal 4972 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 + +import base64 +import math +import pickle +from copy import deepcopy +from logging import info, debug, warning +from typing import Dict, Optional + +import numpy as np + +from baxus import EmbeddedTuRBO +from baxus.benchmarks.benchmark_function import Benchmark +from baxus.util.behaviors import BaxusBehavior +from baxus.util.behaviors.gp_configuration import GPBehaviour +from baxus.util.data_utils import join_data +from baxus.util.projections import AxUS, ProjectionModel +from baxus.util.utils import ( + one_around_origin_latin_hypercube, + from_1_around_origin, + star_string, +) + + +class BAxUS(EmbeddedTuRBO): + """ + BAxUS main class. + + Args: + f: the function to optimize + target_dim: the latent dimensionality + n_init: number of initial samples + max_evals: max number of function evaluations + behavior: behavior configuration + gp_behaviour: the behavior of the associated Gaussian Process + verbose: verbose logging model + use_ard: whether the GP should use an ARD kernel (yes this should be part of the gp_behavior) + max_cholesky_size: + dtype: the datatype (float32, float64) + run_dir: the directory to which to write the run results + conf_name: the name of the configuration of the optimization run + sample_zero: Sample Zero vector from initial LHS + """ + + def __init__( + self, + f: Benchmark, + target_dim: int, + n_init: int, + max_evals: int, + behavior: BaxusBehavior = BaxusBehavior(), + gp_behaviour: GPBehaviour = GPBehaviour(), + verbose=True, + use_ard=True, + max_cholesky_size=2000, + dtype="float64", + run_dir=".", + conf_name: Optional[str] = None, + sample_zero:Optional[bool] = False + ): + self.behavior = behavior + # need to set this here, so we can adjust the initial target dim before initializing super() + self._input_dim = f.dim + self._init_target_dim = target_dim + self.sample_zero = sample_zero + + if self.behavior.adjust_initial_target_dim: + target_dim = self._adjust_init_target_dim() + self._init_target_dim = target_dim + + super().__init__( + f=f, + target_dim=target_dim, + n_init=n_init, + max_evals=max_evals, + verbose=verbose, + use_ard=use_ard, + max_cholesky_size=max_cholesky_size, + gp_behaviour=gp_behaviour, + dtype=dtype, + run_dir=run_dir, + behavior=behavior, + conf_name=conf_name, + ) + self._target_dim_after_reset = self.target_dim + assert ( + self.length_init > 2 * self.length_min + ), f"Initial length {self.length_init} has to be larger than two times the minimum length {self.length_min}." + + self._axus_change_iterations = [] + self._split_points = [] + self._trust_region_restarts = [] + self._dim_in_iterations = {} + + self._data_dims = [] + + @property + def target_dim_increases(self) -> int: + """ + Returns the number of times the target dimensionality was increased. + This is not the current target dimensionality minus the initial target dimensionality. + + Returns: The number of times the target dimensionality was increased. + + """ + base = self.behavior.n_new_bins + 1 + return round(math.log(self.target_dim / self._init_target_dim, base)) + + @EmbeddedTuRBO.target_dim.setter + def target_dim(self, target_dim: int) -> None: + """ + Setter for target dimensionality. + + Args: + target_dim: the new target dimensionality + + Returns: None + + """ + self._dim_in_iterations[self.n_evals] = target_dim + self._target_dim = target_dim + + @property + def splits(self) -> int: + """ + The number of splits in the current trust region. + + Returns: The number of splits in the current trust region. + + """ + base = self.behavior.n_new_bins + 1 + return round(math.log(self.target_dim / self._target_dim_after_reset, base)) + + @property + def length_min(self) -> float: + """ + The minimum base length of the trust region. + + Returns: The minimum base length of the trust region. + + """ + return self._length_min + + @property + def length_max(self) -> float: + """ + The maximum base length of the trust region. + + Returns: The maximum base length of the trust region. + + """ + return self._length_max + + @property + def length_init(self) -> float: + """ + The initial base length of the trust region. + + Returns: The initial base length of the trust region. + + """ + return self._length_init + + @property + def evaluations_since_last_split(self) -> int: + """ + The number of function evaluations since the last split. + + Returns: The number of function evaluations since the last split. Total number of evaluations if there was no split yet. + + """ + return ( + self.n_evals - self._axus_change_iterations[-1] + if len(self._axus_change_iterations) > 0 + else self.n_evals + ) + + @property + def sample_zero(self)->bool: + """ + The indication to sample the zero vector during the first stage of the optimization. + + Returns: A boolean indicating to sample the zero + + """ + + return self.__sample_zero + + @sample_zero.setter + def sample_zero(self,new_sample:bool)->None: + """ + Setter to sample zero handle + + Returns: A boolean indicating to sample the zero + + """ + + new_sample = bool(new_sample) + + self.__sample_zero = new_sample + + + @property + def _evaluations_in_last_splits_in_tr(self) -> int: + """ + The evaluations spent in previous splits in the current trust region + + Returns: the evaluations spent in previous splits in the current trust region + + """ + split_points = np.array(self._split_points) + if len(self._trust_region_restarts) > 0: + split_points = split_points[split_points >= self._trust_region_restarts[-1]] + if len(split_points) == 0: + return 0 + else: + if len(self._trust_region_restarts) == 0: + return split_points[-1] + else: + return split_points[-1] - self._trust_region_restarts[-1] + + @property + def _dimension_importances(self) -> np.ndarray: + """ + The (inverse) dimension importances. This just returns the lengthscales of the GP ARD kernel. + + Returns: The (inverse) dimension importances. This just returns the lengthscales of the GP ARD kernel. + + """ + return np.array(self.lengthscales) + + @property + def _split_in_trust_region(self) -> int: + """ + The number of this split in the current trust region, i.e., if we just reset the trust region and haven't + split yet, this is 1. Then, after the first split, 2, etc. + + Returns: the number of this split + + """ + if len(self._trust_region_restarts) == 0: + # if the trust region was not yet restarted, just return the number of splits + return len(self._split_points) + 1 + else: + iteration_of_restart = self._trust_region_restarts[-1] + sp = np.array(self._split_points) + return len(sp[sp >= iteration_of_restart]) + 1 + + @property + def _init_dim_in_tr(self) -> int: + """ + The dim with which the current trust region started. + + Returns: The dim with which the current trust region started. + + """ + dim_in_iterations = self._dim_in_iterations + if len(dim_in_iterations) == 0: + # target dim was not yet adjusted + return self._init_target_dim + else: + eval_when_tr_started = 0 if len(self._trust_region_restarts) == 0 else self._trust_region_restarts[-1] + tr_adjust_iters = np.array(list(dim_in_iterations.keys())) + min_iter = min(tr_adjust_iters[tr_adjust_iters >= eval_when_tr_started]) + return self._dim_in_iterations[min_iter] + + @property + def _budget_lost_in_previous_trs(self) -> int: + """ + The number of function evaluations used in previous trust regions. + + Returns: The number of function evaluations used in previous trust regions. + + """ + return self.n_init if len(self._trust_region_restarts) == 0 else self._trust_region_restarts[-1] + + def _adjust_init_target_dim(self) -> int: + """ + Adjust the initial target dimension such that the final target dimension + is as close to the ambient dimensionality as possible given a fixed b. + + Returns: int: the adjusted initial target dimension. + + """ + + def ndiff(b, d0): + psi = 1 + desired_final_dim = self.input_dim + initial_target_dim = d0 + + base = psi * b + 1 + n = round(math.log(desired_final_dim / initial_target_dim, base)) + df_br = round(base ** n * initial_target_dim) + res = np.abs(df_br - desired_final_dim) + return res, n + + i_b, i_d0 = self.behavior.n_new_bins, self._init_target_dim + + def _fmin(d0): + return ndiff(b=i_b, d0=d0)[0] + + bounds = (2, i_b + 1) + + x_best = 1 + y_best = _fmin(x_best) + for j_d0 in range(bounds[0], bounds[1]): + if _fmin(j_d0) < y_best: + x_best = j_d0 + y_best = _fmin(j_d0) + + info(star_string( + f"Can reach a difference of {y_best} with init target dim of {x_best} after {ndiff(i_b, x_best)[1]} splits. Adjusting...")) + return x_best + + def _restart(self, length: float = None) -> None: + """ + Reset TR observations, reset counter, reset base length + + Args: + length: new base length after resetting, if not set, length_init will be used. + + """ + self._X = np.empty((0, self.target_dim)) + self._fX = np.empty((0, 1)) + + self.failcount = 0 + self.succcount = 0 + if length is None: + self.length = self.length_init + else: + self.length = length + + @property + def failtol(self) -> float: + """ + The fail tolerance for the BAxUS algorithm. + Is computed dynamically depending on the split we are in as the fail tolerance is dependent on the + current target dimensionality. + + Returns: the fail tolerance for the BAxUS algorithm + + """ + ft_max = np.max([4.0, self.target_dim]) + if self.target_dim == self.input_dim: + return ft_max + + desired_final_dim = self.input_dim + evaluation_budget = self.max_evals if self.behavior.budget_until_input_dim == 0 else self.behavior.budget_until_input_dim + evaluation_budget = evaluation_budget - self._budget_lost_in_previous_trs + + psi = 1 + new_bins_on_split = self.behavior.n_new_bins + _log_base = psi * new_bins_on_split + 1 + n = round(math.log(desired_final_dim / self._init_dim_in_tr, _log_base)) # splits + + def _budget(dim): + + return (evaluation_budget * dim * (1 - _log_base)) / (self._init_dim_in_tr * (1 - _log_base ** (n + 1))) + + budget = _budget(self.target_dim) + + del ( + psi, + new_bins_on_split, + evaluation_budget, + ) + + length_init = self.behavior.initial_base_length + + gamma = 2 * math.log(self.length_min / length_init, 0.5) + if gamma == 0: + return ft_max + ft = math.ceil(budget / gamma) + failtol = max(1, min(ft, ft_max)) + + return failtol + + def _adjust_length(self, fX_next) -> None: + """ + Adjust the base length of the current trust region depending on the outcome of the next evaluation. + If the next evaluation is better than the current, increase success count and potentially increase TR base length. + Otherwise, increase fail count and potentially decrease TR base length. + + Args: + fX_next: the function value of the next point + + """ + debug( + f"eval {self.n_evals}: length = {self.length}, failcount = {self.failcount} (failtol = {self.failtol}), " + f"succcount = {self.succcount} (succtol = {self.succtol})" + ) + prev_data = self._fX + + if np.min(fX_next) < np.min( + prev_data + ) - self.behavior.success_decision_factor * math.fabs(np.min(prev_data)): + debug(f"eval {self.n_evals}: increase success count") + self.succcount += 1 + self.failcount = 0 + else: + debug(f"eval {self.n_evals}: increase failure count") + self.succcount = 0 + self.failcount += 1 + if self.succcount == self.succtol: # Expand trust region + debug(f"eval {self.n_evals}: expanding trust region") + self.length = min([2.0 * self.length, self.length_max]) + self.succcount = 0 + elif self.failcount == self.failtol: # Shrink trust region + debug(f"eval {self.n_evals}: shrinking trust region") + self.length /= 2.0 + self.failcount = 0 + + self._log_property("length_history", f"{self.n_evals}:{self.length}") + + def _choose_splitting_dim( + self, + projector: AxUS, + ) -> Dict[int, int]: + """ + Choose a new splitting dim based on our defined behavior + + Args: + projector: the projection model used + + Returns: the new splitting dim or -1 if none could be found + + + """ + + n_dims_to_split = self.target_dim + + n_new_bins = self.behavior.n_new_bins + n_new_bins = (n_new_bins + 1) * n_dims_to_split + assert n_new_bins >= 2 * n_dims_to_split, ( + "Number of new bins has " + "to be at least 2 times" + "the number of dimensions" + "to split" + ) + weights = self._dimension_importances + indices_with_lengthscales = {i: weights[i] for i in range(self.target_dim)} + indices_sorted_by_lengthscales = sorted( + [i for i in indices_with_lengthscales.keys()], + key=lambda i: indices_with_lengthscales[i], + ) + splittable_idxs = np.array( + [ + i + for i in indices_sorted_by_lengthscales + if len(projector.contributing_dimensions(i)) > 1 + ] + ) + n_dims_to_split = min(len(splittable_idxs), n_dims_to_split) + if n_dims_to_split == 0: + return {} + n_bins_per_dim = n_new_bins // n_dims_to_split + bins_per_dim = np.array( + [ + min(n_bins_per_dim, len(projector.contributing_dimensions(i))) + for i in splittable_idxs + ] + ) + cum_sum = np.cumsum(bins_per_dim) + dims_to_split = np.sum(cum_sum <= n_new_bins) + dims_and_bins = { + splittable_idxs[i]: bins_per_dim[i] for i in range(dims_to_split) + } + + return dims_and_bins + + def _resample_and_restart(self, n_points: int, length: float = None) -> None: + """ + Resample new initial points and reset algorithm. + + Args: + n_points: number of new initial points + length: new base length after resetting + + Returns: None + + """ + # Initialize parameters + self._restart(length=length) + + # Generate and evaluate initial design points + n_pts = min(self.max_evals - self.n_evals, n_points) + X_init = one_around_origin_latin_hypercube(n_pts, self.target_dim, self.sample_zero) + + if isinstance(self.projector,AxUS): + X_init_up = from_1_around_origin( + self.projector.project_up(X_init.T).T, self.lb, self.ub + ) + else: + # This is an addition in case the Projector is not set + X_init_up = X_init.copy() + + + fX_init = np.array([[self.f(x)] for x in X_init_up]) + # Update budget and set as initial data for this TR + self.n_evals += n_pts + self._X = deepcopy(X_init) + self._fX = deepcopy(fX_init) + + # Append data to the global history + self.X = np.vstack((self.X, deepcopy(X_init_up))) + self.fX = np.vstack((self.fX, deepcopy(fX_init))) + + self._data_dims.extend([self.target_dim] * n_pts) + + @staticmethod + def _projector_as_base64(projector: ProjectionModel) -> str: + """ + Return the current projection model as a Base64 string. + Args: + projector: the projector to return as base64. + + Returns: the current projection model as a Base64 string. + + """ + if isinstance(projector, AxUS): + return base64.b64encode(pickle.dumps(projector)).decode("utf-8") + return "" + + def optimize(self) -> None: + """ + Run the optimization + + Returns: None + + """ + self._log_property( + "projectors", f"{self.n_evals}:{self._projector_as_base64(self.projector)}" + ) + + while self.n_evals < self.max_evals and not self._optimum_reached(): + n_pts = min(self.max_evals - self.n_evals, self.n_init) + # only executed if we already gathered data, i.e., not in the first run + if len(self._fX) > 1: + # target dim increase + n_evals, fbest = self.n_evals, self._fX.min() + info(f"{n_evals}) Restarting with fbest = {fbest:.4}") + + # Split target dimension, will be used if we made progress and if not -1 + dims_and_bins = self._choose_splitting_dim(self.projector) + # first_split = self.target_dim == self._init_target_dim # TODO remove + + if dims_and_bins: # if we have a remaining-splitting dim + splitting_dims = list(dims_and_bins.keys()) + n_new_bins = sum(list(dims_and_bins.values())) + self._log_property( + "splitting_dims", + f"{self.target_dim_increases}:{','.join([str(x) for x in splitting_dims])}", + ) + self._log_property("split_points", f"{self.n_evals}") + self._split_points.append(self.n_evals) + for splitting_dim, n_bins in dims_and_bins.items(): + info( + f"eval {self.n_evals}: splitting dimension {splitting_dim + 1} into {n_bins} new " + f"bins with lengthscale: {self.lengthscales[splitting_dim]:.4} and contributing input " + f"dimensions {sorted(self.projector.contributing_dimensions(splitting_dim))}" + ) + self.projector.increase_target_dimensionality(dims_and_bins) + # self.projector.merge_dims(*np.argsort(-dim_ent)[:2]) + self._log_property( + "projectors", + f"{self.n_evals}:{self._projector_as_base64(self.projector)}", + ) + self.target_dim += n_new_bins - len(dims_and_bins) + self._dim_in_iterations[self.n_evals] = self.target_dim + info( + f"eval {self.n_evals}: new target dim = {self.target_dim}" + ) + self._axus_change_iterations.append(self.n_evals) + self.length = self.behavior.initial_base_length + + self._X = join_data(self._X, dims_and_bins) + + else: + warning( + f"eval {self.n_evals}: cannot increase further. " + f"Re-starting with new HeSBO embedding and new TR." + ) + self._log_property("tr_die_outs", f"{self.n_evals}") + self.projector = AxUS( + input_dim=self._input_dim, + target_dim=self.target_dim, + bin_sizing=self.behavior.embedding_type, + ) + self._log_property( + "projectors", + f"{self.n_evals}:{self._projector_as_base64(self.projector)}", + ) + self._resample_and_restart( + n_points=self.n_init, length=self.length_init + ) + self._axus_change_iterations.append(self.n_evals) + self._trust_region_restarts.append(self.n_evals) + self._dim_in_iterations[self.n_evals] = self.target_dim + + self.failcount = 0 + self.succcount = 0 + else: + self._resample_and_restart(self.n_init, self.length_init) + fbest = self._fX.min() + info(f"eval {self.n_evals}: starting from fbest = {fbest:.4}") + + # Thompson sample to get next suggestions + + while ( + self.n_evals < self.max_evals + and self.length >= self.length_min + and not self._optimum_reached() + ): + X_next, X_next_up, fX_next = self._inner_optimization_step() + self._data_dims.extend([self.target_dim] * len(X_next)) + self._optimized = True + self._log_property("final_target_dim", self.target_dim) diff --git a/mylib/lib_BAxUS/BAxUS/baxus/benchmark_runner.py b/mylib/lib_BAxUS/BAxUS/baxus/benchmark_runner.py new file mode 100644 index 0000000..40c5698 --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/baxus/benchmark_runner.py @@ -0,0 +1,339 @@ +import json +import logging +import os +import sys +from datetime import datetime +from logging import info, warning +from typing import List +from zlib import adler32 + +from baxus import EmbeddedTuRBO, BAxUS +from baxus.benchmarks import run_and_plot, EffectiveDimBenchmark, EffectiveDimBoTorchBenchmark, RandomSearch +from baxus.util.behaviors import BaxusBehavior, EmbeddedTuRBOBehavior +from baxus.util.behaviors.gp_configuration import GPBehaviour +from baxus.util.exceptions import ArgumentError +from baxus.util.parsing import parse, embedding_type_mapper, acquisition_function_mapper, mle_optimization_mapper, \ + fun_mapper +from baxus.util.utils import star_string + +FORMAT = "%(asctime)s %(levelname)s: %(filename)s: %(message)s" +DATEFORMAT = '%m/%d/%Y %I:%M:%S %p' + + +def main(argstring: List[str]) -> None: + """ + Parse the argstring and run algorithms based on the definition. + + .. note:: + This function should not be called directly but is called by benchmark_runner.py in the project root. + + Args: + argstring: the argument string + + Returns: Nothing + + """ + args = parse(argstring) + directory = os.path.join( + args.results_dir, + f"{datetime.now().strftime('%d_%m_%Y')}{f'-{args.run_description}' if len(args.run_description) > 0 else ''}", + ) + os.makedirs(directory, exist_ok=True) + logging.basicConfig( + filename=os.path.join(directory, "logging.log"), + level=logging.INFO if not args.verbose else logging.DEBUG, + format=FORMAT, + force=True, + datefmt=DATEFORMAT + ) + + sysout_handler = logging.StreamHandler(sys.stdout) + sysout_handler.setFormatter(logging.Formatter(fmt=FORMAT, datefmt=DATEFORMAT)) + logging.getLogger().addHandler(sysout_handler) + + repetitions = list(range(args.num_repetitions)) + + args_dict = vars(args) + with open(os.path.join(directory, "conf.json"), "w") as f: + f.write(json.dumps(args_dict)) + + bin_sizing_method = embedding_type_mapper[args.embedding_type] + + acquisition_function = acquisition_function_mapper[args.acquisition_function] + + mle_optimization_method = mle_optimization_mapper[args.mle_optimization] + + input_dim = args.input_dim + target_dim = args.target_dim + n_init = args.n_init + max_evals = args.max_evals + noise_std = args.noise_std + new_bins_on_split = args.new_bins_on_split + multistart_samples = args.multistart_samples + mle_training_steps = args.mle_training_steps + multistart_after_samples = args.multistart_after_sample + l_init = args.initial_baselength + l_min = args.min_baselength + l_max = args.max_baselength + adjust_initial_target_dim = args.adjust_initial_target_dimension + budget_until_input_dim = args.budget_until_input_dim + + combs = {} + + if n_init is None: + n_init = target_dim + 1 + if args.min_baselength > args.max_baselength: + raise ArgumentError( + "Minimum baselength has to be larger than maximum baselength." + ) + if args.input_dim < args.target_dim: + raise ArgumentError( + "Input dimension has to be larger than target dimension." + ) + if args.noise_std < 0: + raise ArgumentError("Noise standard deviation has to be positive.") + if max_evals < budget_until_input_dim: + raise ArgumentError("budget_until_input_dim has to be <= max_evals.") + if args.multistart_samples < 1: + raise ArgumentError("Number of multistart samples has to be >= 1.") + if args.multistart_after_sample > args.multistart_samples: + raise ArgumentError( + f"Number of multistart samples after sampling {args.multistart_after_sample} has to be smaller or equal to the numbers" + f"of initial multistart samples {args.multistart_samples}." + ) + if args.multistart_after_sample < 1: + raise ArgumentError( + "Number of multistart samples after sampling has to be >= 1." + ) + if args.mle_training_steps < 0: + raise ArgumentError("Number of mle training steps has to be >= 0.") + if new_bins_on_split < 2: + raise ArgumentError("Number of new bins on split has to be greater than one.") + + funs = { + k: v(dim=input_dim, noise_std=noise_std) + for k, v in fun_mapper().items() + if k == args.function + } + + c = { + f"{k}_in_dim_{v.dim}_t_dim{target_dim}_n_init_{n_init}" + f"{f'_noise_{noise_std}' if noise_std > 0 else ''}": { + "input_dim": v.dim, + "target_dim": min(v.dim, target_dim), + "n_init": n_init, + "f": v, + "lb": v.lb_vec, + "ub": v.ub_vec, + } + for k, v in funs.items() + } + + combs.update(c) + + for i, (k, comb) in enumerate(combs.items()): + info(f"running combination {k}") + llb = comb["lb"] + uub = comb["ub"] + input_dim = comb["input_dim"] + target_dim = comb["target_dim"] + n_init = comb["n_init"] + + f = comb["f"] + + function_dir = os.path.join(directory, k) + os.makedirs(function_dir, exist_ok=True) + + if "baxus" == args.algorithm: + # *** BAxUS *** + info("*** BAxUS***") + behavior = BaxusBehavior( + n_new_bins=new_bins_on_split, + initial_base_length=l_init, + min_base_length=l_min, + max_base_length=l_max, + acquisition_function=acquisition_function, + embedding_type=bin_sizing_method, + adjust_initial_target_dim=adjust_initial_target_dim, + noise=noise_std, + budget_until_input_dim=budget_until_input_dim + ) + gp_behaviour = GPBehaviour( + mll_estimation=mle_optimization_method, + n_initial_samples=multistart_samples, + n_best_on_lhs_selection=multistart_after_samples, + n_mle_training_steps=mle_training_steps, + ) + conf_name = ( + f"baxus_{behavior}_{gp_behaviour}" + ) + run_dir = os.path.join( + function_dir, + str(adler32(conf_name.encode("utf-8"))), + ) + baxus = BAxUS( + f=f, # Handle to objective function + n_init=n_init, # Number of initial bounds from an Latin hypercube design + max_evals=max_evals, # Maximum number of evaluations + target_dim=target_dim, + run_dir=run_dir, + conf_name=conf_name, + behavior=behavior, + gp_behaviour=gp_behaviour, + ) + run_and_plot(m=baxus, repetitions=repetitions, directory=run_dir) + del baxus + + if "embedded_turbo_target_dim" == args.algorithm: + # *** Embedded TuRBO - Target dim *** + info("*** Embedded TuRBO - Target Dim ***") + behavior = EmbeddedTuRBOBehavior( + initial_base_length=l_init, + min_base_length=l_min, + max_base_length=l_max, + acquisition_function=acquisition_function, + embedding_type=bin_sizing_method, + noise=noise_std, + ) + gp_behaviour = GPBehaviour( + mll_estimation=mle_optimization_method, + n_initial_samples=multistart_samples, + n_best_on_lhs_selection=multistart_after_samples, + n_mle_training_steps=mle_training_steps, + ) + conf_name = ( + f"embedded_turbo_target_dim_{behavior}" + f"_{gp_behaviour}" + ) + run_dir = os.path.join( + function_dir, + str(adler32(conf_name.encode("utf-8"))), + ) + embedded_turbo = EmbeddedTuRBO( + f=f, # Handle to objective function + target_dim=target_dim, + n_init=n_init, # Number of initial bounds from an Latin hypercube design + max_evals=max_evals, # Maximum number of evaluations + run_dir=run_dir, + conf_name=conf_name, + behavior=behavior, + gp_behaviour=gp_behaviour, + ) + + run_and_plot( + m=embedded_turbo, + repetitions=repetitions, + directory=run_dir, + ) + del embedded_turbo + + if "embedded_turbo_effective_dim" == args.algorithm: + if issubclass(type(f), EffectiveDimBenchmark) or issubclass( + type(f), EffectiveDimBoTorchBenchmark + ): + effective_dim = f.effective_dim + else: + warning("Benchmark with unknown effective dim. Choosing input dim.") + effective_dim = f.dim + + info("*** Embedded TuRBO - Effective Dim ***") + behavior = EmbeddedTuRBOBehavior( + initial_base_length=l_init, + min_base_length=l_min, + max_base_length=l_max, + acquisition_function=acquisition_function, + embedding_type=bin_sizing_method, + noise=noise_std, + ) + gp_behaviour = GPBehaviour( + mll_estimation=mle_optimization_method, + n_initial_samples=multistart_samples, + n_best_on_lhs_selection=multistart_after_samples, + n_mle_training_steps=mle_training_steps, + ) + conf_name = ( + f"embedded_turbo_effective_dim_{behavior}" + f"_{gp_behaviour}" + ) + run_dir = os.path.join( + function_dir, + str(adler32(conf_name.encode("utf-8"))), + ) + embedded_turbo = EmbeddedTuRBO( + f=f, + target_dim=effective_dim, + n_init=n_init, + max_evals=max_evals, + run_dir=run_dir, + conf_name=conf_name, + behavior=behavior, + gp_behaviour=gp_behaviour, + ) + run_and_plot( + m=embedded_turbo, + repetitions=repetitions, + directory=run_dir, + ) + del embedded_turbo + + if "embedded_turbo_2_effective_dim" == args.algorithm and ( + issubclass(type(f), EffectiveDimBenchmark) + or issubclass(type(f), EffectiveDimBoTorchBenchmark) + ): + info( + f"*** Embedded TuRBO- 2 * Effective Dim ***" + ) + behavior = EmbeddedTuRBOBehavior( + initial_base_length=l_init, + min_base_length=l_min, + max_base_length=l_max, + acquisition_function=acquisition_function, + embedding_type=bin_sizing_method, + noise=noise_std, + ) + gp_behaviour = GPBehaviour( + mll_estimation=mle_optimization_method, + n_initial_samples=multistart_samples, + n_best_on_lhs_selection=multistart_after_samples, + n_mle_training_steps=mle_training_steps, + ) + conf_name = ( + f"embedded_turbo_2_times_effective_dim_{behavior}" + f"_{gp_behaviour}" + ) + run_dir = os.path.join( + function_dir, + str(adler32(conf_name.encode("utf-8"))), + ) + embedded_turbo = EmbeddedTuRBO( + f=f, + target_dim=2 * f.effective_dim, + n_init=n_init, + max_evals=max_evals, + run_dir=run_dir, + conf_name=conf_name, + behavior=behavior, + gp_behaviour=gp_behaviour, + ) + run_and_plot( + m=embedded_turbo, + repetitions=repetitions, + directory=run_dir, + ) + del embedded_turbo + + if "random_search" == args.algorithm: + info(star_string("Random Search")) + rs = RandomSearch( + function=f, + lower_bounds=llb, + upper_bounds=uub, + run_dir=os.path.join(function_dir, "random_search"), + max_evals=max_evals, + input_dim=input_dim + ) + run_and_plot( + m=rs, + repetitions=repetitions, + directory=os.path.join(function_dir, "random_search") + ) diff --git a/mylib/lib_BAxUS/BAxUS/baxus/benchmarks/__init__.py b/mylib/lib_BAxUS/BAxUS/baxus/benchmarks/__init__.py new file mode 100644 index 0000000..1af17f6 --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/baxus/benchmarks/__init__.py @@ -0,0 +1,12 @@ +from .benchmark_function import Benchmark, BoTorchFunctionBenchmark, EffectiveDimBoTorchBenchmark, SyntheticBenchmark, \ + EffectiveDimBenchmark, SyntheticTestFunction +from .benchmark_utils import run_and_plot +from .other_methods import OptimizationMethod, RandomSearch + +from .real_world_benchmarks import SVMBenchmark, LassoHighBenchmark, LassoHardBenchmark, LassoDiabetesBenchmark, \ + LassoLeukemiaBenchmark, LassoMediumBenchmark, LassoSimpleBenchmark, LassoDNABenchmark, LassoRCV1Benchmark, \ + LassoBreastCancerBenchmark, MoptaSoftConstraints + +from .synthetic_benchmark_functions import BraninEffectiveDim, RosenbrockEffectiveDim, MichalewiczEffectiveDim, \ + HartmannEffectiveDim, LevyEffectiveDim, AckleyEffectiveDim, GriewankEffectiveDim, RastriginEffectiveDim, \ + DixonPriceEffectiveDim, RotatedHartmann6, ShiftedAckley10 diff --git a/mylib/lib_BAxUS/BAxUS/baxus/benchmarks/__pycache__/__init__.cpython-310.pyc b/mylib/lib_BAxUS/BAxUS/baxus/benchmarks/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d310ff0c8819f74ca99bf1ff09253d5abaaa9023 GIT binary patch literal 1294 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 literal 0 HcmV?d00001 diff --git a/mylib/lib_BAxUS/BAxUS/baxus/benchmarks/__pycache__/benchmark_utils.cpython-310.pyc b/mylib/lib_BAxUS/BAxUS/baxus/benchmarks/__pycache__/benchmark_utils.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c9363b17be6b772e764f961002ee1a058f7f0983 GIT binary patch literal 1961 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 bWc=tVo}D^+OS1rK8sr$UXoD{4M}Gc4@@Dk{ literal 0 HcmV?d00001 diff --git a/mylib/lib_BAxUS/BAxUS/baxus/benchmarks/__pycache__/real_world_benchmarks.cpython-310.pyc b/mylib/lib_BAxUS/BAxUS/baxus/benchmarks/__pycache__/real_world_benchmarks.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f42d7c58ea5b47af41398f82b29cb59dd87a6f79 GIT binary patch literal 17723 zcmeHOX^{}Stg-PC+@5iOBi06tAp#p?8!$e8mUp$)ptg?)vN(7hmTn%D+&g|7RfbATIyys-ifG zqgIr>ysLSY<62(hyPntiZsZNV$MP}UwTfAd=i}8xKB3ZkdL>y+bVNO#kBl%H&e=I+ad#o~1oy<>io>|#boyt$~bG)**I-Q@c?#u5}l}8mP;Uq68 zPSTxT*Yo=kPdP(~54rmgKY)1J$snHL_(8;noe{)GIDQE6QD+SCF^(TbeB7Bpe1hXQ zAU^5rL3|I#EySmsy@>DS_^S|~cJ?8@kK;EYzTY{3_yLaJg!n<{5aNfpe>Wq3*tr4m z8#sQ8qs}W?>oSe|nXDEXUaeFQSv`zBRrBh#(0G&Q2VvsP zjQ}ybf->pTUhTBKGGDYSu0UL$fBG!y8lPXS1xs$=6(4eI#ign(&V_p(E|uJ3;GK6* zdDSSnNX_^E5}k;D9uKZU(~YTC^LkRlUw6hF!!_L4K1@>QZsKn4Q%dH0l#=Sioy3Jq zKF-fcCv^cNfC)*KQzeb3!^jW0X=fPkAPsM6&WJO5!B|)GnfEA$k{`yPjE9q_>y5yk zua|<8^_m|D+p7h>{b5jJ%EFIxXYa8Vx?g84d%=?Bqr6q@yw`$C6iZed{$|$*R=@%Wt?vujIK78s|pp!bV-aT9>^_1>;~9 zg=+`+O1l}|p7dE>a?Oin=4q-ELjmJmorW$!=Bxi{I$B z-1J?C+c_gJKT4SBjzu`s*J_xo)ji)W_<>U-@zVX7c!=W~!sUMk6$Hw&ixQQ^9kht&|gvc}^2| z<0r zsU7<;gwjX#byZb@iSp#e9%oN~sShh3)wsNd{PYI(D;4Z5Pj4b#)7!`^q}t$UjNg}o zeH;6Eqz<6ef$~A*9deX;yodgcwlU)V-vx)AskVwX_jcM$Z`?pRm<6?4K0AHpavPJE zRmBKy6&(Tn4CV5JxLvjogr?-2R^|-Rv}7*VX^mBh&1df^AbY8l1G$7I@!H*Y_Ojec z>Fzr@%OGYP$hhM;XTx;&%xm>Pwuq%_em0ZJaxV5V5xgzJ)XIf*ALSEPU*!|Ylp<6Ad4hcbRxGPu? za@I-WeN>A2vQ`+w__`uY6bfF=3kro$t2IKSUUU60)^bJN4|RXlr{!hE_gZc~ju;J! zAhrx+mHIN?9xrfz3iPRg{MImiwpk0js{61IbrEW)$RI%w8s$1o+@c#4mz~h$PWfSC z!S>ynU3G=V6wnlvinkEPh5KC7#WFU81mOn4bI-eB42x9V2@OB6gD^f{c>FC-&7YN$ zgydm3{v_lpi@sA`d79rB3BdxDDM(4*fUFG-YBwD272tjlWrnfpIV5LIv<1o%8Kj9} z3W#_^^BmUSMPIxIkxOcrEEI|r+xH8FOUjEYGfVZVJ5#UNBET>@!dq;*EpO)WH$Qgt z2~np$h@+34dg#qZPu8mqTX=rGcJv|7_GhZA`0^QCg@;b8JT*TfL#DKu9-+-(7AuA2 zx~MpXUTUtfD)yr{hj96CKw!la>ZF=hQ|h>y*d|P9raG#cSBH&Zx}%h#8s8t)wdYNp z$`7k)Z4~#E+B(Dpy=9fnb?K%^^Va>**pZl~yZ-?MffA_iRo1l)O$vlS-!SNDO>L{? zn4>}%P9x2PxKTH?PO65~o32UKA$E_vL4jyQ9jrJQPV7RWt)5cWQR7B@Q(4p6TA-H` z8%dN&wKXgY`o<95->a0EMkUj-~!#Dw4f z4B|f3Kc%#e?J%-bTcMDTh}Z^Y{ZR7A>U64yzp_qzx{ zE3hsw|8bswEcRuhBLx(sZEB9buDx#$<{p&rj?@|!Fwm2Z<;eIbW?ogE+w%<6Pyn|#l{e-LU(`3% zNrkC%r1h~#Cwmyf-h|S&jXF!q3TDk}K(Yo>-?Z=>)Hx|-Wsb{9EfT742|`I=F{syi zZ=H3q*46wuYR=tWQ|=WObC{M^k}J#wD?v+JzAaQ!WTBYQ-Jqm~I>dY{CDm0b5~|`F z9;3Bno@RLx0rQwiGGIg5RJL#!)MT%5NfWO}K|vHFxr-Q365@k+TEWGs=AqiTPQeAIk9Cj55kn+Txf`T(e<%% zKf$G6McKv^k3aEnXe`@a5E@uC94z^biWji35D!ri-EUSyqge48*@P5XG_v_b04s$T zRIRWQ#u`*-Xv&!kV@x06P@e&{^&9U)C2z;&A3-pjn${9nUbL$RuNnpx8T`$c6R}Ah zcU60NI5vp|Dy<&YTKjjNGDt2a&w**8A*YpwgYVX-=A9X&ofdpnHBs%v3I_hHUhoyufg*0O8Wprr`d zS#}>cE}~=jd0)T*$ucfMcHq=pF) z8nnh>Rd^K5bQGVWOY2o18So;(>jN!Ryoy?QNGOJ?4QZ;T8s9TD?fa&#y=)r8-%HPq zj%YU>R(V+~qTs-fI!M1O#83Tu4G_J$++8SXkwTEkn~v$m-9$O*rf3HOA>Xl!pz}@w z?LAi<&zDsc&^~sft@$2 zr2?q*+vp;G-+h28f?%mg3hyR==`yKUmtvt#nv2$42(`*Wm~p#1QKZE1_g_kg^C+3m zoP`b?O;e~97Q$4mPy*Y*TJxobMB1<$i- zBpgW<-bg@EhI)f`lN%|d4p9l*({#t%87Rs|c~~mSmtto~!F7UF@I47!UiroA@N{XU zC(l9?Yd)-3UbDn0Dt7@vm~cs!L3@F1-@r2Bh=(cf5egoq;4umwr+{bX4S4EK6|F_# z5GE9RNzh9nq3)*?tOS(OCv74{^b^Rxau5M2qFprgrL+Zy@9Il=DL{2 zA$F7jx6!Cvf9CgKv63?{Qo^Og>cfQAYzR#X~ z`dDwm*X4xYYu$Sn>8zCb|76k)Q9OTa=UFFZU>CFgU^MFot{t6Mc-ns|n)dD6+SR;& z1mE@AXx=Gy-FctnFPrzOjfxx1yd6g+Jo$GMv-@4ouEm8dpG*HJq+sQ^*2pc4b)@Rn ze0D8E-=DMYy2YxOIu6RgypDA}ux`L1(edxW>?v9ITeEYVv}(a}rds9BQ^{L_eLa8X z?CtUeI6M8QL>*2>v5acCXFr<3w1JTxFqp7$fL)#O0A>^WvJC0Vf+3~BYsk6S7$jqg zG;Fqsvi=9!EpT#i#Tn%0ZYTE(S0d?`8W8FKc*-@4tv`ZZzk z&YyK`HfKEvZ>_sx7lY0g1}3ssW7l)ru}*XOA)=~+Bqi8+DYo+#$XX6#{Mw5*l$tew z2QZ6~@z$dkf6m&X&oM*8j5v?U5IO}Z3dnL0FHpey+VBe6wM92?E*ApPgu^DPn|HT6 zj-#N?Cc-{?jcvc5rKcw;*hx*SfMxufQ6jA+VBDot@Gu2Csk#?1ZdayIVtX^I zwbMxLN+5m=^)ArFLv+u`bj1d?ND9Vdv)f6=Di{BWWF*UW2$%Rx z1lfMcBQ_{`6G2A;$RQKIMadthV9-jF%k(EGV<*o02vHDop1Nz!+cK}amBoqNn%T#978ZK5h( zKLgVHZbXO_+mR4`+VAZ8d6H_95TUvYPY=+f2JZ0blq3KIu6m$I;Y#o311Cz}omf5& zxNm~6qwWyjPqM5y5}~F=jtd2F{M*Fg^eD>4@m1?i~)1Bco8NR~&3ij!?gK z1l=F)_|ioyr~f?!tmMJr;t=u;Pz3Df1E^3Su!4bo{TRRsDnJEh01IJV1NIR6@Eb{j z65yVqJKl*gf{}LS;mmwH*&Ku*%upSE8!ZsX03}fmp39?nb1WcyV48q1!GvRWW9vK~ z1ZO}B(6df*zXCu4TO#NogAv$fnUrY+Q6PWJpq zab%TYG_7bjtpR6Q4_a$4_@Cbg7=abI{Ry+%9lwRHYjdETfgM|F*pjs0df!t%)!co% zYoTLA`x&MCkp#b{;(!go)8o@j*gt44a*qK+h&pfQ0o&0G#o%-;P>(DRAd=n%Mib9d zKn&@P-l`~%z_kd_V54Hgfk57=?6kBVbpYl?2?@X%15j9y=oe|Qu1cemZN}fH>ez53 z44pVgZ=^6^HZW9>0HOL8c0aM}ico@VhL!Iy&iNaf8sA4d}I6V=H zF;Q5JlJJD2tSSAGpQU%{E7&Osc)zm(z~qt*(Ba*bI_TK2Ad1;yO^lhaS53IIQe>%K z9oJ1bxsKqP)%+Nee zA+I6QrEe10-*Zu1hp!UlksBi~x8!P#)z;x3 z!0Wk{R_nfbk_8g_+mQt!EOw{RF_*=Kyh<#%DGFJHy4ukWkWclPdPC%58_UX3;dxJ+TlEAP07 zEJcq{a2tY9YdB#70@Eo#q5+dzFVvbF9^X`9bjUgR4NU`4F_IGF(bV$=c5QO2NO;BXZ5 zizHH#&@Xi87X+dlX(t_}oszo5+K^0Xr--LXyI6xh1K?wS8PaZ$(pP4`a{AL`fweMEeY>i7!;SxW+8cwsw1 zslfqln-T-LHD*|5VKPM1Y zT^l$-V2y3zia(*U?1=wUdipX2@1vlE05Hk=qWC;TX{RweCOQ6%lx0HCt_xqX_uo>H zzoFpk2=W=AD;I;Mf)AU+_4B%aUWl(y?w?U^ytD4+O}Xsm#$XW1oKOv57)SZPUmXW@Uaqy{5HR!~CA70T3Bde8tj8p9QmXd+uzJl3 zEKQ}XCh6mndIoszGWGu)1r-WtMHV#*o}z#?5|U~H#PCC6O=#wCpf8%lLqgGX2*8&m z?r!+y$(xVw6;z^#Yv7ma#QcB7L)Q-Dvwcd-bO5)m;27sKN^Qze+}P?(s*=YxRV(Gj z9atEu@{ICU$e6tOHnRq6hwjVjvVt>#6F3WqvsNx}d9dW-j@~&7NXIiXd4Q(fw3{gp zyCam3knhrBbK;a!G61bk1G_isjv)nl0Ld;s6*$f*X(0XhEz%JB&J0d)u2G&W??LLA zGtTc!vE{cH{5lzCa6F?x&Wi$_N3s6_+{h|2IY`a|Z-Y}DI2agtH~1W3)vm3|Mcjhg z2UMx`8mNU49&mYiIp>#}xuQMuPTy~evR$js2&yZ$6jUo&Y3e+4;_R8n&pbK@R}2*0 zsDUM%N%U~AkRhJUs$~bPB-gng%`+1S|(P!b%+t=DR-8Z>l^xA*}NH!cL?WSo)rJQNq_BalW z0uRo8^Xf~Mgv!!+&}SQ713pcejjU%SQjit(C9uW7CIE4!iHns1+PvUnZ%~^Z?E zWt9wP<(-&C{cuUzB~+D$Q9ZEKt047C1_49T!tW@c(Tgx}=d8y|)|2q!!LQ2+19Z_VUjze2KZr0M+j-pm zQ3MRfH`ZXP$WsDYHLG2I3F@r)AaYqJ1lXF63WRDuEcsr_eGtK?NGejbqe|<@0P9C) z(sqXg`j+*qAt~ZrRORy&5N%`=;Y4AeKA^0DX^pW5Go0F*w@`1^9AE0lD0AMe$n}{m zQWE{y4s4Zis? zNSJhwleqk+5x@e3Pa33&kZ`KNp^lPO2;H=MV2k#+0Bye}l@4s(Na)lyqggj%n?&NU z{6MZo>q`-Ju`q)?BMHGU1>g&Cz>mDh9l7yr_n_0WkqGG>sazJc-ykeLg16%)O_vLf zM$I0jQ!ytj@)|=T;=m^kPf4eGqwf129oyt{HRxE~>cUui6uJcr3wwS$^=fSEjF-f} zVN^S(s^meI_akAe9Ye~<7icnx+*6qznspd>>JvHL z;t=k)aNF(>0#o%j(DD^rimA2621y6hykj%s+f-?%0a6~eYalcw(f>W_7yp4mt;xX_ zWcKbF`S+a~NmHF&ITl7u?H_EazmV+r^j39@P`{y$6(F2A%?BxPH2D$Y+K2ggtBOOZ z4S~~FC{qh|4G(TmznP~mQ~gk+>!7!4I6(qg%Hv2Ji|x1 zOu-BVWaNi&DCZ2wz260 zsG+l(v-jNpx%WHgo_mfnFpw4SJo4k8*5A5c5Z)yw{wQFk@VeJULC^(Vw1iUdFP22` zk|j0ek}L*!N-4qXBuh#B%T}tHE@gO`f^@dj$I}U<`%42nokV)DG{n;>q;sV`Je@{* zxU`q2Gf0n=_VIKU>Cw`Dp6)|>tTfKk{nmlz!O}rdI4|e}`rs>qK4=`gEte+159vAZ zInEyfzegViKg{{V;P>hy;72%r1pGdI6#OXXRq*@uG4NxYKMH|&GaXyAkWQYh z-mr{$N=-A(Hf^M`=gc|BzRb+3LAB2_)0oxl8H^rz70vaSSr2-;;<$!gVNR7=Pdr(x8CB1`X`C~g)6O-ARU6ZWU2QZqcB4wOi$94D za|e(S41thPl60{o>uEhiUlbop^8u`^is!6a z2?tbbZ5xwuY<1T38Y;eOUbUR6W~oinHk+DyziSw3!}D71=|W+4c6QROwI{1u;hV18 zW;2@Y6g0kelMSzF<+Hs1=g(d#UM!wJtzK)GZg+%+=BlRWsty*u*>0+ur+N)Tb@)0> z29=v;z2T{Ktd6Q-3a({nx@p(dmceQc!}O|#iiA3ScJ3=z`C#a@+Y7$JvQ*8Q)#hD% zq{<8p+fuO%)nv@5YfQHc7c;2wHb%2z=+ymWFz>Uh?w;nI(kkg@lfD2GX;w_b_9(-! zU5**kn-4n)7cgpPJEm)tT~7~MyPjt27+BSfo2JH>x-&el7&S9OSd^oIqpaNwz4i+r zq_{>(#vh1UQfF0CE#X7y3|<-Uorgg@!4nsS+tQ4*C@#v2k|)n7i?S~2(raN_=IMm4 zyp|*t0DvWm@BMS-uWvtFnOa?u{Dj-kT85vkVe!j1HLGoerBf?OU&a*J9*pE?qNVXA ztKv)Tia!`3u}lk@PolFnHk%DngLJtJ6nf>dFWD_$skJT3ADDJLl9>SDD~hkUhE-$Z zsLu`%p`lhFg5`46(p5^R-xfEje=uAat-F_fLz;HFbfwiT{wA}IheS?PF^@S zed**APP3&k({=2V)28MYn)8-fDc~)0$Q1%w(dOE2A)32eaOZ8H&@-#$D3gB>?YBGG znrBBatD|`DH5AY}y_l+aKtxN7cY4mDve&7La=>Me2pG`3Mqsk|1e85hwb2 z-X^US0?M64#f@5t>mx-^ypky?k#0(F&`m>E8)nTj^x&HxdQdy|-%?B;YXJ{XP$j_) zA4-S9>|O@r2}@!fw!`DP*P;N6xHr zNVC0|I3wJ#{Y1t<@@b~x&rfKKY4d){snuM=bJ=04aEb`Y6C;6Q$3XHjyNA+UEx=LD zLC&E~)gQ&{4uj;xtP%*|us9qD;8+hPBk8M3Xb?V>ChXI?yQFMry%(|8w?t36EiB1U zp~8%^EM0{LD&`aXBN%B}K64UX9IYgNk038E@k#sQ9P63wXHj|%uS936fBXxAQkGCcIonay`#Ylij-4iVU6 zC;7Rum9et3Rl>;TiW?<&f$Rt3(#1HPblV>8?t>`xgxkUl5XujBX-19?_8=V`?8=6N zJs5<L8IrAOJZRN)9xYa!DxtJ)Kj!yVdMC74`s~T3yBK z(%F`jdrrk8-PUoSM6$^~g;pz>ErCy8&q!YVM9p%v;1Jwi2u`EsMZ9j ztS9kG;^;b~8rup4`#eek?UC?m5T7sm0ty2uU89pVrlq#rL6SqRVMuY%j@^*lO*Cwvm^ica~tT;XeT*Ei}*MB71@c`XWd^*|R~u;@F1kCl+7`x&BaRqr!=AyG=9b zi)+t*8Ee9SX)zsW&qHDB_-9Ak1mzqUFnmsDXkuIGp=lI+oeIwqA+Cyd!xQSCaJh$r z+gg0ot}#KTdr;oJg78a@*I>BQ{D-%k3cnZLWeR1D1Y{>TMh3=XsQmBX2*X0EOB|9i zObnT)dz8xs^idD?bY!)Yn4AjE{7ssK@E_Ux!B%by&zDiR2cBK)dNWKSa7NZO&5Uge z&hsdpqZ%BX#BBm+0-5x%0T5ilbL1M>0L??;0Y}iJ(jH)bl-sw3ZtgNvGQJgCs>TqD zjLf)|MA7^Qj;O$Pq!T2-QAgo@i86YQrM`}~qs8AAO5dS|d60$i-Ytw^!=9!}pC)o5 zBK&Z>pI93E+jzS-sSMBC5j3M+uhRzT9F9XLu#Qx29qB4>fmG2PvTe)7_74@$w^T&hc`jTRXmcyG0GnEJcbuSc(0t4*d;^^2>y_9{7i5 zVF;dW!T)n=%)x&stQ&{oZlO9D>}ZNj$4Oc7U{~@i#VmJ zc@1A`nf`F+kdAHLw($EMdg7PIu1j?=xRa={=5cuJ7Lhc^w`rbS856f7BKJj6pZI{< zZ{v83s`Q}oqu73of=qEpexi#%4!XGhjgdFbzq2s1$_>|$>s*35#_RKhydIsL3wTtsD+4r(_oy$fm5JL{23)$V#a)63P|Aj4B*ukKkdlG|0|-}B zuu_OQ1aVWk;&>VY0-+b-(S_G}SnN52QMfIPw6UO;8dd9x5Q2cZ;Z~W6fSzjFQNXfd zdXv_C;gnu_>bdJTw~F#bA*tO*>x$eDw!twhnAzSd22%Bs1sAh&5N7 zNxLAnPCkJ2I)tIRm2?GN>I7<$kTP?O}1Sq-t!t-N(< zC^POUJ|-zrznEQL81LP^2wfYNh+NrpMScRWdlRJVJ6{xM5YxUPu^jT?L)XP+=@ym_ zxe{_G;<)VD0$g1-#@ z=gy(D#!n_X|MLAz#UFRm`-+WdrQc`FwGg$X;Hm42*H{_l{!mY7&rcx`jdjxf1P@61 zNe|&+hxrM+-E1Lf;l9*1j0GdF1hI+Fp_7t4S7yG<3^#Ud int: + """ + The benchmark dimensionality + + Returns: the benchmark dimensionality + + """ + return self._dim + + @property + def lb_vec(self) -> np.ndarray: + """ + The lower bound of the search space of this benchmark (length = benchmark dim) + + Returns: The lower bound of the search space of this benchmark (length = benchmark dim) + + """ + return self._lb_vec + + @property + def ub_vec(self) -> np.ndarray: + """ + The upper bound of the search space of this benchmark (length = benchmark dim) + + Returns: The upper bound of the search space of this benchmark (length = benchmark dim) + + """ + return self._ub_vec + + @property + def fun_name(self) -> str: + """ + The name of the benchmark function + + Returns: The name of the benchmark function + + """ + return self.__class__.__name__ + + def __call__(self, x: Union[np.ndarray, List[float], List[List[float]]]): + raise NotImplementedError() + + +class SyntheticBenchmark(Benchmark): + """ + Abstract class for synthetic benchmarks + + Args: + dim: the benchmark dimensionality + ub: np.ndarray: the upper bound of the search space of this benchmark (length = benchmark dim) + lb: np.ndarray: the lower bound of the search space of this benchmark (length = benchmark dim) + """ + + @abstractmethod + def __init__(self, dim: int, ub: np.ndarray, lb: np.ndarray, noise_std: float): + super().__init__(dim, ub, lb, noise_std=noise_std) + + @abstractmethod + def __call__( + self, x: Union[np.ndarray, List[float], List[List[float]]] + ) -> np.ndarray: + """ + Call the benchmark function for one or multiple points. + + Args: + x: Union[np.ndarray, List[float], List[List[float]]]: the x-value(s) to evaluate. numpy array can be 1 or 2-dimensional + + Returns: + np.ndarray: The function values. + + + """ + x = np.array(x) + if x.ndim == 0: + x = np.expand_dims(x, 0) + if x.ndim == 1: + x = np.expand_dims(x, 0) + # for y in x: + # if not np.sum(y < self._lb_vec) == 0: + # raise OutOfBoundsException() + # if not np.sum(y > self._ub_vec) == 0: + # raise OutOfBoundsException + + @property + def optimal_value(self) -> Optional[np.ndarray]: + """ + + Returns: + Optional[Union[float, np.ndarray]]: the optimal value if known + + """ + return None + + +class EffectiveDimBenchmark(SyntheticBenchmark): + """ + A benchmark with a known effective dimensionality. + + .. note:: + This is an abstract class that needs an implementation. + + + Args: + dim: the overall dimensionality of the problem + effective_dim: the effective dimensionality of the problem + ub: the upper bounds of the search space + lb: the lower bounds of the search space + noise_std: the noise std for this benchmark + """ + + def __init__( + self, + dim: int, + effective_dim: int, + ub: np.ndarray, + lb: np.ndarray, + noise_std: float, + ): + super().__init__(dim, ub, lb, noise_std=noise_std) + self.effective_dim: int = effective_dim + + @abstractmethod + def __call__(self, x: Union[np.ndarray, List[float], List[List[float]]]): + raise NotImplementedError() + + +class BoTorchFunctionBenchmark(SyntheticBenchmark): + """ + A benchmark function that calls a BoTorch benchmark function + + Args: + dim: dimensionality of the problem + noise_std: noise std of the function + ub: the upper bound of the search space + lb: the lower bound of the search space + benchmark_func: the BoTorch benchmark function + """ + + def __init__( + self, + dim: int, + noise_std: Optional[float], + ub: np.ndarray, + lb: np.ndarray, + benchmark_func: Type[SyntheticTestFunction], + ): + super().__init__(dim, ub=ub, lb=lb, noise_std=noise_std) + try: + self._benchmark_func = benchmark_func(dim=dim, noise_std=noise_std) + except: + self._benchmark_func = benchmark_func(noise_std=noise_std) + + @property + def effective_dim(self) -> int: + """ + The effective dimensionality of the benchmark. + + Returns: The effective dimensionality of the benchmark. + + """ + return self._dim + + @property + def optimal_value(self) -> np.ndarray: + """ + The optimal value of the benchmark function. + + Returns: The optimal value of the benchmark function. + + """ + return self._benchmark_func.optimal_value + + def __call__(self, x: np.ndarray) -> np.ndarray: + """ + Call the function + + Args: + x: points at which to evaluate the function + + Returns: function value(s) + + """ + super(BoTorchFunctionBenchmark, self).__call__(x) + x = np.array(x) + if x.ndim == 0: + x = np.expand_dims(x, 0) + if x.ndim == 1: + x = np.expand_dims(x, 0) + assert x.ndim == 2 + res = ( + self._benchmark_func.forward( + torch.tensor(np.clip(x, self._lb_vec, self._ub_vec)) + ) + .numpy() + .squeeze() + ) + return res + + +class EffectiveDimBoTorchBenchmark(BoTorchFunctionBenchmark): + """ + A benchmark class for synthetic benchmarks with a known effective dimensionality that are based on a BoTorch + implementation. + + Args: + dim: int: the ambient dimensionality of the benchmark + noise_std: float: standard deviation of the noise of the benchmark function + effective_dim: int: the desired effective dimensionality of the benchmark function + ub: np.ndarray: the upper bound of the benchmark search space. length = dim + lb: np.ndarray: the lower bound of the benchmark search space. length = dim + benchmark_func: Type[SyntheticTestFunction]: the BoTorch benchmark function to use + seed: int: random seed + """ + + def __init__( + self, + dim: int, + noise_std: Optional[float], + effective_dim: int, + ub: np.ndarray, + lb: np.ndarray, + benchmark_func: Type[SyntheticTestFunction], + seed: int = 123, + ): + super().__init__( + effective_dim, noise_std, ub=ub, lb=lb, benchmark_func=benchmark_func + ) + if effective_dim > dim: + raise EffectiveDimTooLargeException() + state = np.random.get_state() + np.random.seed(seed) + self._fake_dim = dim + self._effective_dim = effective_dim + self.effective_dims = np.arange(dim)[:effective_dim] + info(f"effective dims: {list(self.effective_dims)}") + np.random.set_state(state) + + def __call__(self, x, offset: np.ndarray = None) -> np.ndarray: + """ + Call the function + + Args: + x: points at which to evaluate the function + offset: offset to add to the x values (we used this for our ablation study with ShiftedAckley10) + + Returns: the function value(s) + + """ + if offset is None: + res = super(EffectiveDimBoTorchBenchmark, self).__call__( + x.squeeze().T[self.effective_dims].T + ) + else: + res = super(EffectiveDimBoTorchBenchmark, self).__call__( + x.squeeze().T[self.effective_dims].T + offset + ) + return res + + @property + def dim(self): + """ + The dimensionality of the problem. + + Returns: The dimensionality of the problem. + + """ + return self._fake_dim + + @property + def effective_dim(self) -> int: + """ + the effective dimensionality of the benchmark + + Returns: the effective dimensionality of the benchmark + + """ + return self._effective_dim + + @property + def lb_vec(self) -> np.ndarray: + """ + The lower bounds of the search space. + + Returns: The lower bounds of the search space. + + """ + return np.full( + shape=self._fake_dim, fill_value=np.min(self._lb_vec), dtype=np.float32 + ) + + @property + def ub_vec(self) -> np.ndarray: + """ + The upper bounds of the search space. + + Returns: The upper bounds of the search space. + + """ + return np.full( + shape=self._fake_dim, fill_value=np.max(self._ub_vec), dtype=np.float32 + ) diff --git a/mylib/lib_BAxUS/BAxUS/baxus/benchmarks/benchmark_utils.py b/mylib/lib_BAxUS/BAxUS/baxus/benchmarks/benchmark_utils.py new file mode 100644 index 0000000..66829fc --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/baxus/benchmarks/benchmark_utils.py @@ -0,0 +1,63 @@ +import os +from copy import deepcopy, copy +from logging import warning, info +from typing import List + +import numpy as np +import pandas as pd + + +MAX_RETRIES = 1 + + +def run_and_plot( + m: "baxus.benchmarks.OptimizationMethod", + repetitions: List[int], + directory: str, +) -> None: + """ + Run an experiment for a certain number of repetitions and save the results + + Args: + m: the experiment to runm_x + repetitions: the repetitions to run + directory: the directory to save the results + + Returns: + None + """ + os.makedirs(directory, exist_ok=True) + + base_run_dir = copy(m.run_dir) + + for rep in repetitions: + out_path = os.path.join(directory, f"repet_{rep}.csv.xz") + rep_run_dir = os.path.join(base_run_dir, f"repetition_{rep}") + os.makedirs(rep_run_dir, exist_ok=True) + m.run_dir = rep_run_dir + + if os.path.exists(out_path): + continue + info(f"starting repetition {rep}") + for mr in range(MAX_RETRIES): + try: + _m = deepcopy(m) + _m.reset() + _m.optimize() + break + except Exception as e: + if mr == MAX_RETRIES - 1: + raise e + warning(f"Optimization failed. Retrying... ({mr + 1}/{MAX_RETRIES})") + m_x, m_y_raw = _m.optimization_results_raw() + _, m_y = _m.optimization_results_incumbent() + m_y_raw = np.expand_dims(m_y_raw, axis=1) + if m_x is not None: + columns = [f"x{i}" for i in range(m_x.shape[1])] + ["y_raw"] + r_df = pd.DataFrame(np.concatenate((m_x, m_y_raw), axis=1), columns=columns) + else: + columns = [["y_raw"]] + r_df = pd.DataFrame(m_y_raw, columns=columns) + r_df.to_csv(out_path) + del r_df + del m_y_raw diff --git a/mylib/lib_BAxUS/BAxUS/baxus/benchmarks/other_methods.py b/mylib/lib_BAxUS/BAxUS/baxus/benchmarks/other_methods.py new file mode 100644 index 0000000..117c591 --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/baxus/benchmarks/other_methods.py @@ -0,0 +1,149 @@ +import json +import os +from abc import ABC, abstractmethod +from logging import warning +from typing import Tuple, Optional, Dict, Any + +import numpy as np + +from baxus.benchmarks import Benchmark + + +class OptimizationMethod(ABC): + def __init__( + self, + run_dir: str, + conf_name: Optional[str] = None, + ): + """ + Abstract base class for a generic optimization method. + + Args: + run_dir: the directory to store results in + conf_name: the algorithm configuration to save to disk + """ + if not os.path.exists(run_dir): + os.makedirs(run_dir, exist_ok=True) + if conf_name is not None: + with open(os.path.join(run_dir, "conf_name.txt"), "w+") as f: + f.write(conf_name) + with open(os.path.join(run_dir, "conf_dict.json"), "w+") as f: + json.dump(self.conf_dict, f) + + self._optimized = False + self.run_dir = run_dir + + @abstractmethod + def optimize(self) -> None: + """ + Start the optimization. + + Returns: None + + """ + raise NotImplementedError() + + @abstractmethod + def optimization_results_raw( + self, + ) -> Tuple[Optional[np.ndarray], np.ndarray]: + """ + Get the raw optimization results, i.e., the x-values, the true function values, and the additional + run information. + + Returns: + tuple[X's, y's, additional_run_information] + """ + raise NotImplementedError() + + def reset(self) -> None: + warning("No reset implemented.") + pass + + @property + def conf_dict(self) -> Dict[str, Any]: + return {} + + def optimization_results_incumbent(self) -> Tuple[np.ndarray, np.ndarray]: + """ + Get the incumbent optimization results, i.e., optimization results such that y_2 is always less or equal to + y_1. + + Returns: + np.ndarray: the x-values + np.ndarray: the incumbent y-values + + """ + assert self._optimized, "Model hasn't been optimized yet" + ( + Xs, + ys, + ) = self.optimization_results_raw() + assert ys.ndim == 1 + ys_incumbent = np.minimum.accumulate(ys) + return Xs, ys_incumbent + + +class RandomSearch(OptimizationMethod): + def __init__( + self, + function: Benchmark, + input_dim: int, + max_evals: int, + run_dir: str, + lower_bounds: np.ndarray, + upper_bounds: np.ndarray): + """ + Simple random search implementation, samples points uniformly at random in the search space. + + Args: + function: the function to optimize + input_dim: the dimensionality of the problem + max_evals: maximum number of function evaluations + run_dir: the directory to save results to + lower_bounds: the lower bound of the search space + upper_bounds: the upper_bound of the search space + """ + super().__init__(run_dir) + + self.run_dir = run_dir + + lower_bounds = np.array(lower_bounds, dtype=np.float32) + upper_bounds = np.array(upper_bounds, dtype=np.float32) + + assert type(max_evals) == int + assert type(input_dim) == int + assert len(lower_bounds) == len(upper_bounds) + assert len(lower_bounds) == input_dim + + self.function = function + self.max_evals = max_evals + self.input_dim = input_dim + self.lower_bounds = lower_bounds + self.upper_bounds = upper_bounds + + def optimize(self) -> None: + """ + Run the optimization. + + Returns: None + + """ + assert not self._optimized + + points = np.random.uniform(self.lower_bounds, self.upper_bounds, (self.max_evals, self.input_dim)) + try: + ys = np.array(self.function(points)) + except: + warning("Could not run function on all points at once even though" + " the function should support this.") + ys = np.array([self.function(y) for y in points]) + + self.ys = ys + self._optimized = True + + def optimization_results_raw( + self, + ) -> Tuple[Optional[np.ndarray], np.ndarray]: + assert self._optimized, "Model hasn't been optimized yet" + return None, self.ys diff --git a/mylib/lib_BAxUS/BAxUS/baxus/benchmarks/real_world_benchmarks.py b/mylib/lib_BAxUS/BAxUS/baxus/benchmarks/real_world_benchmarks.py new file mode 100644 index 0000000..7286729 --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/baxus/benchmarks/real_world_benchmarks.py @@ -0,0 +1,732 @@ +import os +import stat +import subprocess +import sys +import tempfile +import urllib +from logging import info, warning +from platform import machine +from typing import Union, List, Optional + +import numpy as np +import pandas as pd +from sklearn.preprocessing import MinMaxScaler +from sklearn.svm import SVR + +from baxus.benchmarks import SyntheticBenchmark, EffectiveDimBenchmark + + +class MoptaSoftConstraints(SyntheticBenchmark): + """ + Mopta08 benchmark with soft constraints as described in https://arxiv.org/pdf/2103.00349.pdf + Supports i386, x86_84, armv7l + + Args: + temp_dir: Optional[str]: directory to which to write the input and output files (if not specified, a temporary directory will be created automatically) + binary_path: Optional[str]: path to the binary, if not specified, the default path will be used + """ + + def __init__( + self, + temp_dir: Optional[str] = None, + binary_path: Optional[str] = None, + noise_std: Optional[float] = 0, + **kwargs, + ): + super().__init__(124, np.ones(124), np.zeros(124), noise_std=noise_std) + if binary_path is None: + self.sysarch = 64 if sys.maxsize > 2 ** 32 else 32 + self.machine = machine().lower() + if self.machine == "armv7l": + assert self.sysarch == 32, "Not supported" + self._mopta_exectutable = "mopta08_armhf.bin" + elif self.machine == "x86_64": + assert self.sysarch == 64, "Not supported" + self._mopta_exectutable = "mopta08_elf64.bin" + elif self.machine == "i386": + assert self.sysarch == 32, "Not supported" + self._mopta_exectutable = "mopta08_elf32.bin" + elif self.machine == "amd64": + assert self.sysarch == 64, "Not supported" + self._mopta_exectutable = "mopta08_amd64.exe" + else: + raise RuntimeError("Machine with this architecture is not supported") + self._mopta_exectutable = os.path.join( + os.getcwd(), "baxus", "benchmarks", "mopta08", self._mopta_exectutable + ) + + if not os.path.exists(self._mopta_exectutable): + basename = os.path.basename(self._mopta_exectutable) + info(f"Mopta08 executable for this architecture not locally available. Downloading '{basename}'...") + urllib.request.urlretrieve( + f"https://mopta.papenmeier.io/{os.path.basename(self._mopta_exectutable)}", + self._mopta_exectutable) + os.chmod(self._mopta_exectutable, stat.S_IXUSR) + + else: + self._mopta_exectutable = binary_path + if temp_dir is None: + self.directory_file_descriptor = tempfile.TemporaryDirectory() + self.directory_name = self.directory_file_descriptor.name + else: + if not os.path.exists(temp_dir): + warning(f"Given directory '{temp_dir}' does not exist. Creating...") + os.mkdir(temp_dir) + self.directory_name = temp_dir + + def __call__(self, x): + super(MoptaSoftConstraints, self).__call__(x) + x = np.array(x) + if x.ndim == 0: + x = np.expand_dims(x, 0) + if x.ndim == 1: + x = np.expand_dims(x, 0) + assert x.ndim == 2 + # create tmp dir for mopta binary + + vals = np.array([self._call(y) for y in x]).squeeze() + return vals + np.random.normal( + np.zeros_like(vals), np.ones_like(vals) * self.noise_std, vals.shape + ) + + def _call(self, x: np.ndarray): + """ + Evaluate Mopta08 benchmark for one point + + Args: + x: one input configuration + + Returns:value with soft constraints + + """ + assert x.ndim == 1 + # write input to file in dir + with open(os.path.join(self.directory_name, "input.txt"), "w+") as tmp_file: + for _x in x: + tmp_file.write(f"{_x}\n") + # pass directory as working directory to process + popen = subprocess.Popen( + self._mopta_exectutable, + stdout=subprocess.PIPE, + cwd=self.directory_name, + ) + popen.wait() + # read and parse output file + output = ( + open(os.path.join(self.directory_name, "output.txt"), "r") + .read() + .split("\n") + ) + output = [x.strip() for x in output] + output = np.array([float(x) for x in output if len(x) > 0]) + value = output[0] + constraints = output[1:] + # see https://arxiv.org/pdf/2103.00349.pdf E.7 + return value + 10 * np.sum(np.clip(constraints, a_min=0, a_max=None)) + + @property + def optimal_value(self) -> Optional[np.ndarray]: + """ + Return the "optimal" value. + + Returns: + np.ndarray: -200, some guessed optimal value we never beat + + """ + return np.array(-200.0) + + +class LassoLeukemiaBenchmark(EffectiveDimBenchmark): + """ + 7129-D Leukemia benchmark from https://github.com/ksehic/LassoBench + + Args: + noise_std: ignored + **kwargs: + """ + + def __init__(self, noise_std: Optional[float] = 0, **kwargs): + + from LassoBench import LassoBench + + self._b: LassoBench.RealBenchmark = LassoBench.RealBenchmark( + pick_data="leukemia", mf_opt="discrete_fidelity" + ) + dim = self._b.n_features + + super().__init__( + dim=dim, + ub=np.full(dim, fill_value=1.0), + lb=np.full(dim, fill_value=-1.0), + effective_dim=22, + noise_std=noise_std, + ) + + def __call__(self, x: Union[np.ndarray, List[float], List[List[float]]]): + x = np.array(x, dtype=np.double) + if x.ndim == 0: + x = np.expand_dims(x, 0) + if x.ndim == 1: + x = np.expand_dims(x, 0) + assert x.ndim == 2 + result_list = [] + for y in x: + result = self._b.evaluate(y) + result_list.append(result) + result = np.array(result_list).squeeze() + return result + np.random.normal( + np.zeros_like(result), np.ones_like(result) * self.noise_std, result.shape + ) + + +class LassoBreastCancerBenchmark(EffectiveDimBenchmark): + """ + 10-D breast cancer benchmark from https://github.com/ksehic/LassoBench + + Args: + noise_std: ignored + **kwargs: + """ + + def __init__(self, noise_std: Optional[float] = 0, **kwargs): + + from LassoBench import LassoBench + + self._b: LassoBench.RealBenchmark = LassoBench.RealBenchmark( + pick_data="breast_cancer", mf_opt="discrete_fidelity" + ) + dim = self._b.n_features + + super().__init__( + dim=dim, + ub=np.full(dim, fill_value=1.0), + lb=np.full(dim, fill_value=-1.0), + effective_dim=3, + noise_std=noise_std, + ) + + def __call__(self, x: Union[np.ndarray, List[float], List[List[float]]]): + x = np.array(x, dtype=np.double) + if x.ndim == 0: + x = np.expand_dims(x, 0) + if x.ndim == 1: + x = np.expand_dims(x, 0) + assert x.ndim == 2 + result_list = [] + for y in x: + result = self._b.evaluate(y) + result_list.append(result) + result = np.array(result_list).squeeze() + return result + np.random.normal( + np.zeros_like(result), np.ones_like(result) * self.noise_std, result.shape + ) + + +class LassoDiabetesBenchmark(EffectiveDimBenchmark): + """ + 8-D diabetes benchmark from https://github.com/ksehic/LassoBench + + Args: + noise_std: ignored + **kwargs: + """ + + def __init__(self, noise_std: Optional[float] = 0, **kwargs): + + from LassoBench import LassoBench + + self._b: LassoBench.RealBenchmark = LassoBench.RealBenchmark( + pick_data="diabetes", mf_opt="discrete_fidelity" + ) + dim = self._b.n_features + + super().__init__( + dim=dim, + ub=np.full(dim, fill_value=1.0), + lb=np.full(dim, fill_value=-1.0), + effective_dim=5, + noise_std=noise_std, + ) + + def __call__(self, x: Union[np.ndarray, List[float], List[List[float]]]): + x = np.array(x, dtype=np.double) + if x.ndim == 0: + x = np.expand_dims(x, 0) + if x.ndim == 1: + x = np.expand_dims(x, 0) + assert x.ndim == 2 + result_list = [] + for y in x: + result = self._b.evaluate(y) + result_list.append(result) + result = np.array(result_list).squeeze() + return result + np.random.normal( + np.zeros_like(result), np.ones_like(result) * self.noise_std, result.shape + ) + + +class LassoDNABenchmark(EffectiveDimBenchmark): + """ + 180-D DNA benchmark from https://github.com/ksehic/LassoBench + + Args: + noise_std: ignored + **kwargs: + """ + + def __init__(self, noise_std: Optional[float] = 0, **kwargs): + + from LassoBench import LassoBench + + self._b: LassoBench.RealBenchmark = LassoBench.RealBenchmark( + pick_data="dna", mf_opt="discrete_fidelity" + ) + dim = self._b.n_features + + super().__init__( + dim=dim, + ub=np.full(dim, fill_value=1.0), + lb=np.full(dim, fill_value=-1.0), + effective_dim=43, + noise_std=noise_std, + ) + + def __call__(self, x: Union[np.ndarray, List[float], List[List[float]]]): + x = np.array(x, dtype=np.double) + if x.ndim == 0: + x = np.expand_dims(x, 0) + if x.ndim == 1: + x = np.expand_dims(x, 0) + assert x.ndim == 2 + result_list = [] + for y in x: + result = self._b.evaluate(y) + result_list.append(result) + result = np.array(result_list).squeeze() + return result + np.random.normal( + np.zeros_like(result), np.ones_like(result) * self.noise_std, result.shape + ) + + +class LassoRCV1Benchmark(EffectiveDimBenchmark): + """ + 19 959-D RCV1 benchmark from https://github.com/ksehic/LassoBench + + Args: + noise_std: ignored + **kwargs: + """ + + def __init__(self, noise_std: Optional[float] = 0, **kwargs): + + from LassoBench import LassoBench + + self._b: LassoBench.RealBenchmark = LassoBench.RealBenchmark( + pick_data="rcv1", mf_opt="discrete_fidelity" + ) + dim = self._b.n_features + + super().__init__( + dim=dim, + ub=np.full(dim, fill_value=1.0), + lb=np.full(dim, fill_value=-1.0), + effective_dim=75, + noise_std=noise_std, + ) + + def __call__(self, x: Union[np.ndarray, List[float], List[List[float]]]): + x = np.array(x, dtype=np.double) + if x.ndim == 0: + x = np.expand_dims(x, 0) + if x.ndim == 1: + x = np.expand_dims(x, 0) + assert x.ndim == 2 + result_list = [] + for y in x: + result = self._b.evaluate(y) + result_list.append(result) + result = np.array(result_list).squeeze() + return result + np.random.normal( + np.zeros_like(result), np.ones_like(result) * self.noise_std, result.shape + ) + + +class LassoSimpleBenchmark(EffectiveDimBenchmark): + """ + 60-D synthetic Lasso simple benchmark from https://github.com/ksehic/LassoBench . + Effective dimensionality: 5% of input dimensionality. + + Args: + noise_std: if > 0: noisy version with fixed SNR, noiseless version otherwise + **kwargs: + """ + + def __init__(self, noise_std: Optional[float] = 0, **kwargs): + + from LassoBench import LassoBench + + if noise_std > 0: + warning( + f"LassoBenchmark with noise_std {noise_std} chosen. Will use noisy version with snr ratio 10. The exact value of noise_std will be ignored." + ) + self._b: LassoBench.SyntheticBenchmark = LassoBench.SyntheticBenchmark( + pick_bench="synt_simple", noise=noise_std > 0 + ) + dim = self._b.n_features + + self.effective_dims = np.arange(dim)[self._b.w_true != 0] + info(f"function effective dimensions: {self.effective_dims.tolist()}") + + super().__init__( + dim=dim, + ub=np.full(dim, fill_value=1.0), + lb=np.full(dim, fill_value=-1.0), + effective_dim=len(self.effective_dims), + noise_std=noise_std, + ) + + def __call__(self, x: Union[np.ndarray, List[float], List[List[float]]]): + x = np.array(x, dtype=np.double) + if x.ndim == 0: + x = np.expand_dims(x, 0) + if x.ndim == 1: + x = np.expand_dims(x, 0) + assert x.ndim == 2 + result_list = [] + for y in x: + result = self._b.evaluate(y) + result_list.append(result) + return np.array(result_list).squeeze() + + +class LassoMediumBenchmark(EffectiveDimBenchmark): + """ + 100-D synthetic Lasso medium benchmark from https://github.com/ksehic/LassoBench . + Effective dimensionality: 5% of input dimensionality. + + Args: + noise_std: if > 0: noisy version with fixed SNR, noiseless version otherwise + **kwargs: + """ + + def __init__(self, noise_std: Optional[float] = 0, **kwargs): + from LassoBench import LassoBench + + if noise_std > 0: + warning( + f"LassoBenchmark with noise_std {noise_std} chosen. Will use noisy version with snr ratio 10. The exact value of noise_std will be ignored." + ) + self._b: LassoBench.SyntheticBenchmark = LassoBench.SyntheticBenchmark( + pick_bench="synt_medium", noise=noise_std > 0 + ) + dim = self._b.n_features + + self.effective_dims = np.arange(dim)[self._b.w_true != 0] + info(f"function effective dimensions: {self.effective_dims.tolist()}") + + super().__init__( + dim=dim, + ub=np.full(dim, fill_value=1.0), + lb=np.full(dim, fill_value=-1.0), + effective_dim=len(self.effective_dims), + noise_std=noise_std, + ) + + def __call__(self, x: Union[np.ndarray, List[float], List[List[float]]]): + x = np.array(x, dtype=np.double) + if x.ndim == 0: + x = np.expand_dims(x, 0) + if x.ndim == 1: + x = np.expand_dims(x, 0) + assert x.ndim == 2 + result_list = [] + for y in x: + result = self._b.evaluate(y) + result_list.append(result) + return np.array(result_list).squeeze() + + +class LassoHighBenchmark(EffectiveDimBenchmark): + """ + 300-D synthetic Lasso high benchmark from https://github.com/ksehic/LassoBench . + Effective dimensionality: 5% of input dimensionality. + + Args: + noise_std: if > 0: noisy version with fixed SNR, noiseless version otherwise + **kwargs: + """ + + def __init__(self, noise_std: Optional[float] = 0, **kwargs): + from LassoBench import LassoBench + + if noise_std > 0: + warning( + f"LassoBenchmark with noise_std {noise_std} chosen. Will use noisy version with snr ratio 10. The exact value of noise_std will be ignored." + ) + self._b: LassoBench.SyntheticBenchmark = LassoBench.SyntheticBenchmark( + pick_bench="synt_high", noise=noise_std > 0 + ) + dim = self._b.n_features + + self.effective_dims = np.arange(dim)[self._b.w_true != 0] + info(f"function effective dimensions: {self.effective_dims.tolist()}") + + super().__init__( + dim=dim, + ub=np.full(dim, fill_value=1.0), + lb=np.full(dim, fill_value=-1.0), + effective_dim=len(self.effective_dims), + noise_std=noise_std, + ) + + def __call__(self, x: Union[np.ndarray, List[float], List[List[float]]]): + x = np.array(x, dtype=np.double) + if x.ndim == 0: + x = np.expand_dims(x, 0) + if x.ndim == 1: + x = np.expand_dims(x, 0) + assert x.ndim == 2 + result_list = [] + for y in x: + result = self._b.evaluate(y) + result_list.append(result) + return np.array(result_list).squeeze() + + +class LassoHardBenchmark(EffectiveDimBenchmark): + """ + 1000-D synthetic Lasso hard benchmark from https://github.com/ksehic/LassoBench . + Effective dimensionality: 5% of input dimensionality. + + Args: + noise_std: if > 0: noisy version with fixed SNR, noiseless version otherwise + **kwargs: + """ + + def __init__(self, noise_std: Optional[float] = 0, **kwargs): + from LassoBench import LassoBench + + if noise_std > 0: + warning( + f"LassoBenchmark with noise_std {noise_std} chosen. Will use noisy version with snr ratio 10. The exact value of noise_std will be ignored." + ) + self._b: LassoBench.SyntheticBenchmark = LassoBench.SyntheticBenchmark( + pick_bench="synt_hard", noise=noise_std > 0 + ) + dim = self._b.n_features + + self.effective_dims = np.arange(dim)[self._b.w_true != 0] + info(f"function effective dimensions: {self.effective_dims.tolist()}") + + super().__init__( + dim=dim, + ub=np.full(dim, fill_value=1.0), + lb=np.full(dim, fill_value=-1.0), + effective_dim=len(self.effective_dims), + noise_std=noise_std, + ) + + def __call__(self, x: Union[np.ndarray, List[float], List[List[float]]]): + x = np.array(x, dtype=np.double) + if x.ndim == 0: + x = np.expand_dims(x, 0) + if x.ndim == 1: + x = np.expand_dims(x, 0) + assert x.ndim == 2 + result_list = [] + for y in x: + result = self._b.evaluate(y) + result_list.append(result) + return np.array(result_list).squeeze() + + +class SVMBenchmark(SyntheticBenchmark): + def __init__( + self, + data_folder: Optional[str] = None, + noise_std: Optional[float] = 0, + **kwargs, + ): + """ + SVM Benchmark from https://arxiv.org/abs/2103.00349 + + Support also a noisy version where the model is trained on random subset of 250 points + which is used whenever noise_std is greater than 0. + + Args: + data_folder: the folder where the slice_localization_data.csv is located + noise_std: noise standard deviation. Anything greater than 0 will lead to a noisy benchmark + **kwargs: + """ + self.value = np.inf + self.best_config = None + self.noisy = noise_std > 0 + if self.noisy: + warning("Using a noisy version of SVMBenchmark where training happens on a random subset of 250 points." + "However, the exact value of noise_std is ignored.") + super(SVMBenchmark, self).__init__( + 388, lb=np.zeros(388), ub=np.ones(388), noise_std=noise_std + ) + self.X, self.y = self._load_data(data_folder) + if not self.noisy: + np.random.seed(388) + idxs = np.random.choice(np.arange(len(self.X)), min(10000, len(self.X)), replace=False) + half = len(idxs) // 2 + self._X_train = self.X[idxs[:half]] + self._X_test = self.X[idxs[half:]] + self._y_train = self.y[idxs[:half]] + self._y_test = self.y[idxs[half:]] + + def _load_data(self, data_folder: Optional[str] = None): + if data_folder is None: + data_folder = os.path.join(os.getcwd(), "data") + if not os.path.exists(os.path.join(data_folder, "CT_slice_X.npy")): + sld_dir = os.path.join(data_folder, "slice_localization_data.csv.xz") + sld_bn = os.path.basename(sld_dir) + info(f"Slice localization data not locally available. Downloading '{sld_bn}'...") + urllib.request.urlretrieve( + f"http://mopta-executables.s3-website.eu-north-1.amazonaws.com/{sld_bn}", + sld_dir) + data = pd.read_csv( + os.path.join(data_folder, "slice_localization_data.csv.xz") + ).to_numpy() + X = data[:, :385] + y = data[:, -1] + np.save(os.path.join(data_folder, "CT_slice_X.npy"), X) + np.save(os.path.join(data_folder, "CT_slice_y.npy"), y) + X = np.load(os.path.join(data_folder, "CT_slice_X.npy")) + y = np.load(os.path.join(data_folder, "CT_slice_y.npy")) + X = MinMaxScaler().fit_transform(X) + y = MinMaxScaler().fit_transform(y.reshape(-1, 1)).squeeze() + return X, y + + def __call__(self, x: Union[np.ndarray, List[float], List[List[float]]]): + super(SVMBenchmark, self).__call__(x) + x = np.array(x) + if x.ndim == 0: + x = np.expand_dims(x, 0) + if x.ndim == 1: + x = np.expand_dims(x, 0) + assert x.ndim == 2 + x = x ** 2 + + errors = [] + for y in x: + C = 0.01 * (500 ** y[387]) + gamma = 0.1 * (30 ** y[386]) + epsilon = 0.01 * (100 ** y[385]) + length_scales = np.exp(4 * y[:385] - 2) + + svr = SVR(gamma=gamma, epsilon=epsilon, C=C, cache_size=1500, tol=0.001) + if self.noisy: + np.random.seed(None) + idxs = np.random.choice(np.arange(len(self.X)), min(500, len(self.X)), replace=False) + half = len(idxs) // 2 + X_train = self.X[idxs[:half]] + X_test = self.X[idxs[half:]] + y_train = self.y[idxs[:half]] + y_test = self.y[idxs[half:]] + svr.fit(X_train / length_scales, y_train) + pred = svr.predict(X_test / length_scales) + error = np.sqrt(np.mean(np.square(pred - y_test))) + else: + svr.fit(self._X_train / length_scales, self._y_train) + pred = svr.predict(self._X_test / length_scales) + error = np.sqrt(np.mean(np.square(pred - self._y_test))) + + errors.append(error) + if errors[-1] < self.value: + self.best_config = np.log(y) + self.value = errors[-1] + return np.array(errors).squeeze() + + + +class IOH_func_base(SyntheticBenchmark): + """ + The Rastrigin function with many local minima (see https://www.sfu.ca/~ssurjano/rastr.html) + + WARNING: This function has its optimum at the origin. This might give a misleading performance for BAxUS + as the origin will always be reachable irregardless of the embedding. + + Args: + dim: The ambient dimensionality of the function + noise_std: The standard deviation of the noise + effective_dim: The effective dimensionality of the function + """ + + r""" + This is a wrapper which extends the IOH Single Objective defined instances + to work with BAxUS. + """ + + try: + import ioh + except ModuleNotFoundError as e: + print("Install the ioh module as `pip install ioh`") + + def __init__(self, + #f:object, + dim:int, + #lb:int, + #ub:int, + noise_std: Optional[float] = None, + )->None: + + r""" + Args: + -------- + - f: A IOH Real Single Objective instance + - noise_std: Standard deviation of the observation noise. + - negate: If True, negate the function. + """ + self.__dim = dim + + self.__bounds = [(-5, 5) for _ in range(self.__dim)] + + #self.__f:object = f + + # Convert the bounds definition + lb_:np.ndarray = np.ravel(np.array(self.__bounds)[:,0]) + ub_:np.ndarray = np.ravel(np.array(self.__bounds)[:,1]) + + # Use the constructor from `SyntheticBenchmark` + super().__init__(dim= self.__dim,lb=lb_,ub=ub_, + noise_std=noise_std) + + def __call__(self, x: Union[np.ndarray, List[float], List[List[float]]])->np.ndarray: + + r""" + This is the implementation of the `__call__` function for this wrapper class. + + Args: + --------- + - x: A list or array with possible points to evaluate. + """ + # Call the __call__ function from the polymorphic class + + + #x =super().__call__(x) + x:np.ndarray = np.array(x) + if x.ndim == 0: + x = np.expand_dims(x, 0) + if x.ndim == 1: + x = np.expand_dims(x, 0) + assert x.ndim == 2 + + result = self.__f(x.ravel()) + + return result + + + @property + def dim(self)->int: + return self.__dim + + @property + def bounds(self)->Union[float,List[float]]: + return self.__bounds + + @property + def IOH_instance(self)->ioh.problem.RealSingleObjective: + return self.__f \ No newline at end of file diff --git a/mylib/lib_BAxUS/BAxUS/baxus/benchmarks/synthetic_benchmark_functions.py b/mylib/lib_BAxUS/BAxUS/baxus/benchmarks/synthetic_benchmark_functions.py new file mode 100644 index 0000000..ae17fa4 --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/baxus/benchmarks/synthetic_benchmark_functions.py @@ -0,0 +1,283 @@ +import math +import os +from typing import Optional + +import numpy as np +import torch +from botorch.test_functions import Ackley as BotorchAckley +from botorch.test_functions import Branin as BotorchBranin +from botorch.test_functions import DixonPrice as BotorchDixonPrice +from botorch.test_functions import Griewank as BotorchGriewank +from botorch.test_functions import Hartmann as BotorchHartmann +from botorch.test_functions import Levy as BotorchLevy +from botorch.test_functions import Michalewicz as BotorchMichalewicz +from botorch.test_functions import Rastrigin as BotorchRastrigin +from botorch.test_functions import Rosenbrock as BotorchRosenbrock + +from baxus.benchmarks import EffectiveDimBoTorchBenchmark + + +class AckleyEffectiveDim(EffectiveDimBoTorchBenchmark): + """ + A benchmark function with many local minima (see https://www.sfu.ca/~ssurjano/ackley.html) + + WARNING: This function has its optimum at the origin. This might give a misleading performance for BAxUS + as the origin will always be reachable irregardless of the embedding. + + Args: + dim: The ambient dimensionality of the function + noise_std: The standard deviation of the noise + effective_dim: The effective dimensionality of the function + """ + + def __init__(self, dim=200, noise_std=None, effective_dim: int = 10): + super(AckleyEffectiveDim, self).__init__( + dim=dim, + effective_dim=effective_dim, + noise_std=noise_std, + lb=np.full(shape=effective_dim, fill_value=-32.768), + ub=np.full(shape=effective_dim, fill_value=32.768), + benchmark_func=BotorchAckley, + ) + + +class ShiftedAckley10(EffectiveDimBoTorchBenchmark): + """ + A benchmark function with many local minima (see https://www.sfu.ca/~ssurjano/ackley.html) + + Args: + dim: The ambient dimensionality of the function + noise_std: The standard deviation of the noise + effective_dim: The effective dimensionality of the function + """ + + def __init__(self, dim=200, noise_std=None, ): + self.offsets = np.array([-14.15468831, -17.35934204, 4.93227439, 30.68108305, + -20.94097318, -9.68946759, 11.23919487, 4.93101114, + 2.87604112, -31.0805155]) + + super(ShiftedAckley10, self).__init__( + dim=dim, + effective_dim=10, + noise_std=noise_std, + lb=np.full(shape=10, fill_value=-32.768) - self.offsets, + ub=np.full(shape=10, fill_value=32.768) - self.offsets, + benchmark_func=BotorchAckley, + ) + + def __call__(self, x): + x = np.array(x) + return super().__call__(x, self.offsets) + + +class RosenbrockEffectiveDim(EffectiveDimBoTorchBenchmark): + """ + A valley-shape benchmark function (see https://www.sfu.ca/~ssurjano/rosen.html) + + Args: + dim: The ambient dimensionality of the function + noise_std: The standard deviation of the noise + effective_dim: The effective dimensionality of the function + """ + + def __init__( + self, dim: int = 200, noise_std: Optional[float] = None, effective_dim: int = 10 + ): + super().__init__( + dim=dim, + effective_dim=effective_dim, + noise_std=noise_std, + ub=np.full(shape=effective_dim, fill_value=10), + lb=np.full(shape=effective_dim, fill_value=-5), + benchmark_func=BotorchRosenbrock, + ) + + +class HartmannEffectiveDim(EffectiveDimBoTorchBenchmark): + """ + A valley-shape benchmark function (see https://www.sfu.ca/~ssurjano/rosen.html) + + Args: + dim: The ambient dimensionality of the function + noise_std: The standard deviation of the noise + effective_dim: The effective dimensionality of the function + """ + + def __init__( + self, dim: int = 200, noise_std: Optional[float] = None, effective_dim: int = 6 + ): + assert effective_dim == 6 + super().__init__( + dim=dim, + effective_dim=effective_dim, + noise_std=noise_std, + ub=np.ones(effective_dim), + lb=np.zeros(effective_dim), + benchmark_func=BotorchHartmann, + ) + + +class BraninEffectiveDim(EffectiveDimBoTorchBenchmark): + """ + The Branin function with three local minima (see https://www.sfu.ca/~ssurjano/branin.html) + + Args: + dim: The ambient dimensionality of the function + noise_std: The standard deviation of the noise + effective_dim: The effective dimensionality of the function + """ + + def __init__( + self, dim: int = 200, noise_std: Optional[float] = None, effective_dim: int = 2 + ): + assert effective_dim == 2 + super().__init__( + dim=dim, + effective_dim=effective_dim, + noise_std=noise_std, + lb=np.array([-5.0, -5.0]), + ub=np.array([15.0, 15.0]), + benchmark_func=BotorchBranin, + ) + + +class LevyEffectiveDim(EffectiveDimBoTorchBenchmark): + """ + The Levy function with many local minima (see https://www.sfu.ca/~ssurjano/levy.html) + + Args: + dim: The ambient dimensionality of the function + noise_std: The standard deviation of the noise + effective_dim: The effective dimensionality of the function + """ + + def __init__(self, dim=200, noise_std=None, effective_dim: int = 2): + super(LevyEffectiveDim, self).__init__( + dim=dim, + effective_dim=effective_dim, + noise_std=noise_std, + lb=np.full(shape=effective_dim, fill_value=-10), + ub=np.full(shape=effective_dim, fill_value=10), + benchmark_func=BotorchLevy, + ) + + +class DixonPriceEffectiveDim(EffectiveDimBoTorchBenchmark): + """ + The valley shaped Dixon-Price function (see https://www.sfu.ca/~ssurjano/dixonpr.html) + + Args: + dim: The ambient dimensionality of the function + noise_std: The standard deviation of the noise + effective_dim: The effective dimensionality of the function + """ + + def __init__(self, dim=200, noise_std=None, effective_dim: int = 2): + super(DixonPriceEffectiveDim, self).__init__( + dim=dim, + effective_dim=effective_dim, + noise_std=noise_std, + lb=np.full(shape=effective_dim, fill_value=-10), + ub=np.full(shape=effective_dim, fill_value=10), + benchmark_func=BotorchDixonPrice, + ) + + +class GriewankEffectiveDim(EffectiveDimBoTorchBenchmark): + """ + The Griewank function with many local minima (see https://www.sfu.ca/~ssurjano/griewank.html) + + WARNING: This function has its optimum at the origin. This might give a misleading performance for BAxUS + as the origin will always be reachable irregardless of the embedding. + + Args: + dim: The ambient dimensionality of the function + noise_std: The standard deviation of the noise + effective_dim: The effective dimensionality of the function + """ + + def __init__(self, dim=200, noise_std=None, effective_dim: int = 2): + super(GriewankEffectiveDim, self).__init__( + dim=dim, + effective_dim=effective_dim, + noise_std=noise_std, + lb=np.full(shape=effective_dim, fill_value=-600), + ub=np.full(shape=effective_dim, fill_value=600), + benchmark_func=BotorchGriewank, + ) + + +class MichalewiczEffectiveDim(EffectiveDimBoTorchBenchmark): + """ + The Michalewicz function with steep drops (see https://www.sfu.ca/~ssurjano/michal.html) + + Args: + dim: The ambient dimensionality of the function + noise_std: The standard deviation of the noise + effective_dim: The effective dimensionality of the function + """ + + def __init__(self, dim=200, noise_std=None, effective_dim: int = 2): + super(MichalewiczEffectiveDim, self).__init__( + dim=dim, + effective_dim=effective_dim, + noise_std=noise_std, + lb=np.full(shape=effective_dim, fill_value=0), + ub=np.full(shape=effective_dim, fill_value=math.pi), + benchmark_func=BotorchMichalewicz, + ) + + +class RastriginEffectiveDim(EffectiveDimBoTorchBenchmark): + """ + The Rastrigin function with many local minima (see https://www.sfu.ca/~ssurjano/rastr.html) + + WARNING: This function has its optimum at the origin. This might give a misleading performance for BAxUS + as the origin will always be reachable irregardless of the embedding. + + Args: + dim: The ambient dimensionality of the function + noise_std: The standard deviation of the noise + effective_dim: The effective dimensionality of the function + """ + + def __init__(self, dim=200, noise_std=None, effective_dim: int = 2): + super(RastriginEffectiveDim, self).__init__( + dim=dim, + effective_dim=effective_dim, + noise_std=noise_std, + lb=np.full(shape=effective_dim, fill_value=-5.12), + ub=np.full(shape=effective_dim, fill_value=5.12), + benchmark_func=BotorchRastrigin, + ) + + + +class RotatedHartmann6(EffectiveDimBoTorchBenchmark): + """ + Version of the rotated Hartmann6 function as described in https://bit.ly/3dZFVXv + + Args: + noise_std: The standard deviation of the noise + """ + + def __init__(self, noise_std: Optional[float] = None, **kwargs): + # bounds taken from https://bit.ly/3e0YgDw + super().__init__(1000, noise_std, 6, np.ones(6), np.zeros(6), BotorchHartmann) + # this is the same matrix as in rotation_matrix_alebo.json + self.rotation_matrix = np.load( + os.path.join("data", "rotation_matrix_alebo.npy") + ) + + def __call__(self, x): + x = np.array(x) + if x.ndim == 0: + x = np.expand_dims(x, 0) + if x.ndim == 1: + x = np.expand_dims(x, 0) + else: + assert x.ndim == 2 + x = x.T + x_r = self.rotation_matrix @ x + res = self._benchmark_func.forward(torch.tensor(x_r.T)).numpy().squeeze() + return res diff --git a/mylib/lib_BAxUS/BAxUS/baxus/embeddedturbo.py b/mylib/lib_BAxUS/BAxUS/baxus/embeddedturbo.py new file mode 100644 index 0000000..38ba5a4 --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/baxus/embeddedturbo.py @@ -0,0 +1,760 @@ +############################################################################### +# Copyright (c) 2019 Uber Technologies, Inc. # +# # +# Licensed under the Uber Non-Commercial License (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at the root directory of this project. # +# # +# See the License for the specific language governing permissions and # +# limitations under the License. # +############################################################################### + +# Derived from the TuRBO implementation (https://github.com/uber-research/TuRBO) +# Author: anonymous + +import lzma +import math +import os +import sys +import time +from copy import deepcopy +from logging import info, debug, warning +from typing import Tuple, Optional, Any, Union, Dict +from zipfile import ZipFile, ZIP_LZMA + +import gpytorch +import numpy as np +import torch + +from baxus.benchmarks.benchmark_function import Benchmark +from baxus.benchmarks.other_methods import OptimizationMethod +from baxus.gp import train_gp +from baxus.util.acquisition_function_types import AcquisitionFunctionType +from baxus.util.acquisition_functions import ExpectedImprovement +from baxus.util.behaviors import EmbeddedTuRBOBehavior +from baxus.util.behaviors.gp_configuration import GPBehaviour +from baxus.util.projections import AxUS +from baxus.util.space_learning.trust_region import create_Xcand +from baxus.util.utils import ( + one_around_origin_latin_hypercube, + from_1_around_origin, +) + + +class EmbeddedTuRBO(OptimizationMethod): + """ + Embedded TuRBO is the base class for BAxUS. It is the implementation used for our ablation studies and runs + TuRBO in an embedded space. + + Args: + f: the benchmark function + target_dim: the target dimensionality + n_init: the number of initial samples + max_evals: the maximum number of evaluations + behavior: the behavior configuration of the algorithm + gp_behaviour: the behavior of the GP + verbose: whether to print verbose log messages + use_ard: whether to use an ARD kernel + max_cholesky_size: If the size of a LazyTensor is less than max_cholesky_size, then root_decomposition and inv_matmul of LazyTensor will use Cholesky rather than Lanczos/CG. + dtype: the data type to use + run_dir: the directory to write run information to + conf_name: the name of the current configuration + """ + + def __init__( + self, + f: Benchmark, + target_dim: int, + n_init: int, + max_evals: int, + behavior: EmbeddedTuRBOBehavior = EmbeddedTuRBOBehavior(), + gp_behaviour: GPBehaviour = GPBehaviour(), + verbose=True, + use_ard=True, + max_cholesky_size=2000, + dtype="float64", + run_dir: str = ".", + conf_name: Optional[str] = None, + ): + + self.behavior = behavior + super().__init__(conf_name=conf_name, run_dir=run_dir) + # Very basic input checks + + assert max_evals > 0 and isinstance(max_evals, int) + assert n_init > 0 and isinstance(n_init, int) + assert isinstance(verbose, bool) and isinstance(use_ard, bool) + assert max_cholesky_size >= 0 + + assert gp_behaviour.n_mle_training_steps >= 30 and isinstance( + gp_behaviour.n_mle_training_steps, int + ) + assert max_evals > n_init + assert dtype == "float32" or dtype == "float64" + if target_dim > f.dim: + warning( + f"Target dimension {target_dim} is larger than the input dimension {f.dim}. Setting target dimension to input dimension for function {type(f).__name__}." + ) + target_dim = f.dim + + # Save function information + self._target_dim = target_dim + self._input_dim = f.dim + self.f = f + self.lb = f.lb_vec + self.ub = f.ub_vec + + # Settings + + self.n_init = n_init + self.max_evals = max_evals + self.verbose = verbose + self.use_ard = use_ard + self.max_cholesky_size = max_cholesky_size + self.gp_behaviour = gp_behaviour + self.n_evals = 0 + if self._input_dim != self._target_dim: + info(f"eval {self.n_evals}: creating HeSBO embedding for TuRBO instance...") + self.projector = AxUS( + self._input_dim, + self._target_dim, + bin_sizing=self.behavior.embedding_type, + ) + try: + eff_dims = self.f.effective_dims + info( + f"important target dims: {sorted(list(set([self.projector.input_to_target_dim[d] for d in eff_dims])))}" + ) + except: + pass + else: + self.projector = False + + # Hyperparameters + self.mean = np.zeros((0, 1)) + self.signal_var = np.zeros((0, 1)) + self.noise_var = np.zeros((0, 1)) + self.lengthscales = ( + np.zeros((0, self._target_dim)) if self.use_ard else np.zeros((0, 1)) + ) + + # Tolerances and counters + self.succtol = self.behavior.success_tolerance + + # Trust region sizes + self._length_min = self.behavior.min_base_length + self._length_max = self.behavior.max_base_length + self._length_init = self.behavior.initial_base_length + + # Save the full history + self.X = np.zeros((0, self._input_dim)) + self.fX = np.zeros((0, 1)) + + # Device and dtype for GPyTorch + self.dtype = torch.float32 if dtype == "float32" else torch.float64 + + # Initialize parameters + self._restart() + + # History + self._fds = {} + self._model_history_archive = "model_history.zip" + + info(f"Running with the following behavior\n\n{self.behavior.pretty_print()}") + + @property + def failtol(self) -> float: + """ + The fail tolerance of the current trust region. + + Returns: the fail tolerance (=max(4, current target dimensionality)) + + """ + failtol = np.ceil( + np.max( + [ + 4.0, + self._target_dim + ] + ) + ) + return failtol + + @property + def conf_dict(self) -> Dict[str, Any]: + """ + The current behavior configuration as a dictionary + + Returns: the current behavior configuration as a dictionary + + """ + return {**super().conf_dict, **self.behavior.conf_dict} + + @property + def n_cand(self) -> int: + """ + The number of candidates for the discrete Thompson sampling + + Returns: the number of candidates for the discrete Thompson sampling + + """ + return min(100 * self._target_dim, 5000) + + @property + def target_dim(self) -> int: + """ + The target dimensionality. + + Returns: the target dimensionality + + """ + return self._target_dim + + @target_dim.setter + def target_dim(self, target_dim: int) -> None: + """ + Setter for the target dimensionality + + Args: + target_dim: the new target dimensionality + + Returns: + + """ + self._target_dim = target_dim + + @property + def input_dim(self) -> int: + """ + The input dimensionality + + Returns: the input dimensionality + + """ + return self._input_dim + + @input_dim.setter + def input_dim(self, input_dim: int): + """ + Setter for the input dimensionality. + + .. warning:: + Should not be called, throws an error when called. + + Args: + input_dim: the new input dimensionality + + Returns: + + """ + raise AttributeError("Cannot change input dim") + + @property + def length_min(self) -> float: + """ + The minimum base length of the trust region. + + Returns: The minimum base length of the trust region. + + """ + return self._length_min + + @property + def length_max(self) -> float: + """ + The maximum base length of the trust region. + + Returns: The maximum base length of the trust region. + + """ + return self._length_max + + @property + def length_init(self) -> float: + """ + The initial base length of the trust region. + + Returns: The initial base length of the trust region. + + """ + return self._length_init + + def reset(self) -> None: + """ + Reset the state of the current instance (re-initiate the projector, reset global observations, reset local + observations, reset fail- and success counts). Does not reset the target dimensionality + + Returns: None + + """ + self.projector = AxUS( + self._input_dim, self._target_dim, bin_sizing=self.behavior.embedding_type + ) + self.X = np.zeros((0, self._input_dim)) + self.fX = np.zeros((0, 1)) + self.length = self.length_init + if hasattr(self.f, "effective_dims") and isinstance(self.f.effective_dims, np.ndarray): + self._log_property("function_effective_dims", self.f.effective_dims) + self._restart() + + def _resample_and_restart(self, n_points: int, length: float = None) -> None: + """ + Resample new initial points and reset algorithm + + Args: + n_points: number of new points to sample + length: new trust region base length after reset + + Returns: None + + """ + # Initialize parameters + self._restart(length=length) + + # Generate and evaluate initial design points + n_pts = min(self.max_evals - self.n_evals, n_points) + X_init = one_around_origin_latin_hypercube(n_pts, self._target_dim) + + X_init_up = from_1_around_origin( + self.projector.project_up(X_init.T).T, self.lb, self.ub + ) + fX_init = np.array([[self.f(x)] for x in X_init_up]) + # Update budget and set as initial data for this TR + self.n_evals += n_pts + self._X = deepcopy(X_init) + self._fX = deepcopy(fX_init) + + # Append data to the global history + self.X = np.vstack((self.X, deepcopy(X_init_up))) + self.fX = np.vstack((self.fX, deepcopy(fX_init))) + + def _restart(self, length: Optional[float] = None) -> None: + """ + Reset observations, reset counters, reset trust region base length + + Args: + length: new trust region base length after resetting + + Returns: None + + """ + self._X = [] + self._fX = [] + self.failcount = 0 + self.succcount = 0 + if length is None: + self.length = self.length_init + else: + self.length = length + + def _adjust_length(self, fX_next: np.ndarray) -> None: + """ + Adjust the base length of the current trust region depending on the outcome of the next evaluation. + If the next evaluation is better than the current, increase success count and potentially increase TR base length. + Otherwise, increase fail count and potentially decrease TR base length. + + Args: + fX_next: the function value of the next point + + """ + debug( + f"eval {self.n_evals}: failcount = {self.failcount} (failtol = {self.failtol}), " + f"succcount = {self.succcount} (succtol = {self.succtol})" + ) + if np.min(fX_next) < np.min( + self._fX + ) - self.behavior.success_decision_factor * math.fabs(np.min(self._fX)): + debug(f"eval {self.n_evals}: increase success count") + self.succcount += 1 + self.failcount = 0 + else: + debug(f"eval {self.n_evals}: increase failure count") + self.succcount = 0 + self.failcount += 1 + + if self.succcount == self.succtol: # Expand trust region + debug(f"eval {self.n_evals}: expanding trust region") + self.length = min([2.0 * self.length, self.length_max]) + self.succcount = 0 + elif self.failcount == self.failtol: # Shrink trust region + debug(f"eval {self.n_evals}: shrinking trust region") + self.length /= 2.0 + self.failcount = 0 + self._log_property("length_history", f"{self.n_evals}:{self.length}") + + def _create_candidates( + self, + X: np.ndarray, + fX: np.ndarray, + length: float, + gp_behaviour: GPBehaviour, + hypers, + tr_idx: Optional[int] = None, + multiple_lengthscales: bool = False, + ) -> Optional[ + Union[ + Tuple[ + Tuple, + Dict[str, Any], + np.ndarray, + np.ndarray, + ], + Tuple[ + Dict[str, Tuple[np.ndarray, np.ndarray]], Dict[str, Any] + ], + ] + ]: + """ + Generate candidates assuming X has been scaled to [-1,1]^d. + + Args: + X: the local TR data x-values + fX: the local TR data y-values + global_X: the global x-values (used for fitting a PLS if required) + global_y: the global y-values (used for fitting a PLS if required) + length: the current base length + gp_behaviour: the behavior definition of the GP + hypers: the pre-computed GP hyperparameters. If empty, the GP will be trained anew + tr_idx: the trust region index (for TuRBO-m) + multiple_lengthscales: whether to use multiple lengthscales + use_pls: whether to use a PLS kernel + n_pls_components: number of PLS components for PLS kernel + kernel_type: the kernel type of the PLS kernel (only recognized if use_pls is true) + pls: pre-computed PLS. If not given, a new PLS is computed + turbo_1_return_format: whether to use the TuRBO-1 return format (supports multiple acquisition functions) + Returns: + either a tuple (X_candidates, y_candidates, dict of GP hyperparams, PLSContainer, lb of TR, ub of TR) <- TheSBO-1 return format or (dict of best per acquisition function, dict of GP hyperparameters, PLSContainer) + """ + # Pick the center as the point with the smallest function values + # NOTE: This may not be robust to noise, in which case the posterior mean of the GP can be used instead + target_dim = self._target_dim if tr_idx is None else self.target_dims[tr_idx] + + fX = fX.copy() * (-1) + # Standardize local function values. + mu, sigma = np.median(fX), fX.std() + sigma = 1.0 if sigma < 1e-6 else sigma + fX = (deepcopy(fX) - mu) / sigma + + # Figure out what device we are running on + device, dtype = torch.device("cpu"), self.dtype + len_hypers = len(hypers) # save here as overwritten later + # We use CG + Lanczos for training if we have enough data + + with gpytorch.settings.max_cholesky_size(self.max_cholesky_size): + X_torch = torch.tensor(X).to(device=device, dtype=dtype) + y_torch = torch.tensor(fX).to(device=device, dtype=dtype) + + # pass stored pls unless we want to retrain + # Possibly get PLSContainer from GP. If we passed a PLSContainer to train_gp, this is the same one we passed. + # Otherwise, if we passed None and the kernel requires a PLS, it will be a newly trained PLS. + gp, hyper = train_gp( + train_x=X_torch, + train_y=y_torch, + use_ard=self.use_ard, + gp_behaviour=gp_behaviour, + hypers=hypers, + ) + if self.n_evals % 10 == 0 and len_hypers == 0: + # save model + full_arch_path = os.path.join(self.run_dir, self._model_history_archive) + with ZipFile( + full_arch_path, + "a" if os.path.exists(full_arch_path) else "w", + compression=ZIP_LZMA, + ) as zip_archive: + model_path = ( + f"gp_iter_{self.n_evals}.pth" + if tr_idx is None + else f"gp_iter_{self.n_evals}_tr_{tr_idx}.pth" + ) + with zip_archive.open(model_path, "w") as comp_f: + torch.save(gp, comp_f) + + # Create the trust region boundaries + x_center = X[fX.argmax().item(), :][None, :] + # x_center = gp_X[gp_y.argmin().item(), :][None, :] + self._log_property( + "tr_centers" if not multiple_lengthscales else f"tr_{tr_idx}_centers", + f"{self.n_evals}:{x_center.tolist()}", + ) + weights = gp.lengthscales + weights = weights / weights.mean() # This will make the next line more stable + weights = weights / np.prod( + np.power(weights, 1.0 / len(weights)) + ) + + if not multiple_lengthscales: + self.lengthscales = weights + else: + self.lengthscales[tr_idx] = weights + self._log_property( + "lengthscales" + if not multiple_lengthscales + else f"lengthscales_tr_{tr_idx}", + f"{self.n_evals}:{weights.tolist()}", + ) + X_cand, lb, ub = create_Xcand( + x_center=x_center, + weights=weights, + length=length, + dim=target_dim, + n_cand=self.n_cand, + dtype=dtype, + device=device, + ) + + if X_cand.size == 0: + return None + + # Figure out what device we are running on + device, dtype = torch.device("cpu"), self.dtype + + # We may have to move the GP to a new device + gp = gp.to(dtype=dtype, device=device) + + best_per_acq = None + + # We use Lanczos for sampling if we have enough data + with torch.no_grad() if AcquisitionFunctionType.EXPECTED_IMPROVEMENT != self.behavior.acquisition_function else gpytorch.settings.max_cholesky_size( + self.max_cholesky_size): + + if self.behavior.acquisition_function == AcquisitionFunctionType.THOMPSON_SAMPLING: + X_cand_torch = torch.tensor(X_cand).to(device=device, dtype=dtype) + y_cand = ( + gp.likelihood(gp(X_cand_torch)) + .sample(torch.Size([1])) + .t() + .cpu() + .detach() + .numpy() + ) + best_per_acq = (X_cand, (mu + sigma * y_cand) * (-1)) + del X_cand_torch + elif self.behavior.acquisition_function == AcquisitionFunctionType.EXPECTED_IMPROVEMENT: + EI = ExpectedImprovement(gp, best_f=fX.max(), lb=lb, ub=ub) + start = time.time() + X_cand, y_cand = EI.optimize() + end = time.time() + debug( + f"Optimizing EI took {end - start:.2f}s in {self.target_dim} dims with {len(self._X)} datapoints.") + del EI + # y_cand = torch.unsqueeze(y_cand, 1) + + best_per_acq = ( + X_cand, + (mu + sigma * y_cand) * (-1), + ) + + # Remove the torch variables + del X_torch, y_torch, gp + return best_per_acq, hypers, lb, ub + + def _log_property(self, property_name: str, value: Any) -> None: + """ + Log a property to a file. If the file descriptor does not already exist, it is created, otherwise an + already opened file descriptor is used. + + Args: + property_name: the property to log. This will determine the file name + value: the value to log. This is just appended to the file if it already exists. + + Returns: None + + """ + path = os.path.join(self.run_dir, f"{property_name}.txt.xz") + if property_name not in self._fds: + self._fds[property_name] = lzma.open(path, "wt") + self._fds[property_name].write(f"{value}\n") + + def _select_candidates(self, best_per_acq: Tuple[np.ndarray, np.ndarray]) -> Tuple[np.ndarray, np.ndarray]: + """ + Choose the next evaluation point. + + Args: + best_per_acq: Tuple of x-values and acquisition function values of the candidates. + + Returns: The next point according to the acquisition function selected. + + """ + """Select candidates.""" + X_next = np.ones((1, self._target_dim)) + indbests = [] + X_cand, y_cand = best_per_acq + # Pick the best point and make sure we never pick it again + if self.behavior.acquisition_function == AcquisitionFunctionType.THOMPSON_SAMPLING: + indbest = np.argmin(y_cand[:, 0]) + elif self.behavior.acquisition_function == AcquisitionFunctionType.EXPECTED_IMPROVEMENT: + if y_cand.size > 1: + indbest = np.argmax(y_cand[:, 0]) + else: + indbest = 0 + else: + raise RuntimeError("unknown acquisition function type") + indbests.append(indbest) + X_next[0, :] = deepcopy(X_cand[indbest, :]) + del X_cand, y_cand + + return X_next, np.array(indbests).squeeze() + + def _inner_optimization_step(self) -> Tuple[np.ndarray, np.ndarray, np.ndarray]: + """ + Create candidates, select candidate, project up point, evaluate point + + Returns: next point in target space, next point in input space, function value of the next point + + """ + # Warp inputs + X = self._X + fX = deepcopy(self._fX).ravel() + + # Create th next batch + is_cands = self._create_candidates( + X, + fX, + length=self.length, + gp_behaviour=self.gp_behaviour, + hypers={}, + ) + best_per_acq, hypers, lb, ub = is_cands + + # select next batch + X_next, _ = self._select_candidates(best_per_acq) + + # Undo the warping + X_next_up = from_1_around_origin( + self.projector.project_up(X_next.T).T if self.projector else X_next, + self.lb, + self.ub, + ) + + # Evaluate batch + fX_next = np.array([[self.f(x)] for x in X_next_up]) + + # Update trust region + self._adjust_length(fX_next) + + # Update budget and append data + self.n_evals += 1 + self._X = np.vstack((self._X, X_next)) + self._fX = np.vstack((self._fX, fX_next)) + + debug( + f"eval {self.n_evals} on {self.f.fun_name}: new point: {fX_next.min():.4} (current global / local best: {self.fX.min():.4}/{self._fX.min():.4})" + ) + if fX_next.min() < self.fX.min(): + n_evals, fbest = self.n_evals, fX_next.min() + info(f"eval {self.n_evals} on {self.f.fun_name}: new best: {fbest:.4}") + + # Append data to the global history + self.X = np.vstack((self.X, deepcopy(X_next_up))) + self.fX = np.vstack((self.fX, deepcopy(fX_next))) + + return X_next, X_next_up, fX_next + + def _optimum_reached(self, tolerance: float = 1e-3) -> bool: + """ + Whether the optimum was reached according to some absolute tolerance value + + Args: + tolerance: the absolute tolerance. If the difference of the best function value to the optimal function value is less than this, return true. False otherwise. + + Returns: True, if the difference of the best function value to the optimal function value is less than the tolerance. False otherwise. + + """ + try: + optimum = np.array(self.f.optimal_value).squeeze() + current_best = np.min(self.fX) + optimum_reached = math.isclose(optimum, current_best, abs_tol=tolerance) + if optimum_reached: + info( + f"Optimum reached within a tolerance of {tolerance}. Stopping early..." + ) + return optimum_reached + except: + return False + + def optimize(self) -> None: + """ + Run the optimization until the maximal number of evaluations or the optimum are reached. + + Returns: None + + """ + + while self.n_evals < self.max_evals and not (self.behavior.noise > 0 or self._optimum_reached()): + if len(self._fX) > 0 and self.verbose: + n_evals, fbest = self.n_evals, self._fX.min() + info(f"eval {self.n_evals}: restarting with fbest = {fbest:.4}") + sys.stdout.flush() + + # Initialize parameters + self._restart() + + # Generate and evaluate initial design points + n_pts = min(self.max_evals - self.n_evals, self.n_init) + X_init = one_around_origin_latin_hypercube(n_pts, self._target_dim) + X_init_up = from_1_around_origin( + self.projector.project_up(X_init.T).T if self.projector else X_init, + self.lb, + self.ub, + ) + fX_init = np.array([[self.f(x)] for x in X_init_up]) + + ####### + print(fX_init) + # Update budget and set as initial data for this TR + self.n_evals += n_pts + self._X = deepcopy(X_init) + self._fX = deepcopy(fX_init) + + # Append data to the global history + self.X = np.vstack((self.X, deepcopy(X_init_up))) + self.fX = np.vstack((self.fX, deepcopy(fX_init))) + + fbest = self._fX.min() + info(f"eval {self.n_evals}: starting from fbest = {fbest:.4}") + + # Thompson sample to get next suggestions + while ( + self.n_evals < self.max_evals + and self.length >= self.length_min + and not self._optimum_reached() + ): + self._inner_optimization_step() + + self._optimized = True + self._log_property("final_target_dim", self.target_dim) + + def _close_fds(self) -> None: + """ + Close any open file handles. + + Returns: None + + """ + for k, v in self._fds.items(): + info(f"Closing file descriptor for '{k}' logger") + v.close() + del self._fds + self._fds = {} + + def __del__(self): + """ + Close any open file handles. + + Returns: None + + """ + self._close_fds() + + def optimization_results_raw( + self, + ) -> Tuple[Optional[np.ndarray], np.ndarray]: + """ + The observations in the input space and their function values. + + Returns: The observations in the input space and their function values. + + """ + assert self._optimized, "Model hasn't been optimized yet" + return self.X, self.fX.squeeze() diff --git a/mylib/lib_BAxUS/BAxUS/baxus/gp.py b/mylib/lib_BAxUS/BAxUS/baxus/gp.py new file mode 100644 index 0000000..d8f0f78 --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/baxus/gp.py @@ -0,0 +1,230 @@ +############################################################################### +# Copyright (c) 2019 Uber Technologies, Inc. # +# # +# Licensed under the Uber Non-Commercial License (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at the root directory of this project. # +# # +# See the License for the specific language governing permissions and # +# limitations under the License. # +############################################################################### + +# Derived from the TuRBO implementation (https://github.com/uber-research/TuRBO) +# Author: Leonard Papenmeier + +import math +from typing import Tuple, Dict, Any, List, Callable + +import numpy as np +import torch +from botorch.models import SingleTaskGP +from gpytorch.constraints.constraints import Interval +from gpytorch.distributions import MultivariateNormal +from gpytorch.kernels import ( + MaternKernel, + ScaleKernel, +) +from gpytorch.likelihoods import GaussianLikelihood +from gpytorch.means import ConstantMean +from torch import Tensor + +from baxus.util.behaviors.gp_configuration import MLLEstimation, GPBehaviour +from baxus.util.gp_utils import ( + initializer_factory, + mle_optimization, + latin_hypercube_hp_grid, + pick_best_from_configurations, +) + + +class GP(SingleTaskGP): + """ + Extension of a single class GP for our purposes. + + Args: + train_x: the x-values of the training points + train_y: the function values of the training points + likelihood: the likelihood to use + ard_dims: the number of ARD dimensions + lengthscale_constraint: the constraints for the lengthscales + outputscale_constraint: the constraints for the signal variances + """ + + def __init__( + self, + train_x, + train_y, + likelihood, + ard_dims, + lengthscale_constraint=None, + outputscale_constraint=None, + ): + super(GP, self).__init__( + train_x, + torch.unsqueeze(train_y, 1) if train_y.ndim == 1 else train_y, + likelihood, + ) + self.likelihood = likelihood + self.mean_module = ConstantMean() + + base_kernel = MaternKernel( + lengthscale_constraint=lengthscale_constraint, + ard_num_dims=ard_dims, + nu=2.5, + ) + self.covar_module = ScaleKernel( + base_kernel, outputscale_constraint=outputscale_constraint + ) + + def forward(self, x: Tensor) -> MultivariateNormal: + """ + Call the GP + + Args: + x: points + + Returns: MultivariateNormal distribution + + """ + mean_x = self.mean_module(x) + covar_x = self.covar_module(x) + return MultivariateNormal(mean_x, covar_x) + + @property + def lengthscales(self) -> np.ndarray: + """ + return the lengthscales of the base kernel depending on the kernel type + """ + weights = ( + self.covar_module.base_kernel.lengthscale.cpu().detach().numpy().ravel() + ) + weights = weights / weights.mean() # This will make the next line more stable + weights = weights / np.prod( + np.power(weights, 1.0 / len(weights)) + ) # We now have weights.prod() = 1 + return weights + + +def train_gp( + train_x: Tensor, + train_y: Tensor, + use_ard: bool, + gp_behaviour: GPBehaviour = GPBehaviour(), + hypers=None, +) -> Tuple[GP, Dict[str, Any]]: + """ + Fit a GP where train_x is in [-1, 1]^D + + Args: + train_x: training data + train_y: training data + use_ard: whether to use automatic relevance detection kernel + gp_behaviour: the configuration of the GP + hypers: hyperparameters for the GP, if passed, the GP won't be re-trained + + Returns: + + """ + if hypers is None: + res_hypers = {} + else: + res_hypers = hypers + assert train_x.ndim == 2 + assert train_y.ndim == 1 + assert train_x.shape[0] == train_y.shape[0] + + # Create hyper parameter bounds + noise_constraint = Interval(5e-4, 0.2) + if use_ard: + lengthscale_constraint = Interval(0.005, 10.0) + else: + lengthscale_constraint = Interval( + 0.005, math.sqrt(train_x.shape[1]) + ) # [0.005, sqrt(dim)] + outputscale_constraint = Interval(0.05, 20.0) # TODO + # Create models + likelihood = GaussianLikelihood(noise_constraint=noise_constraint).to( + device=train_x.device, dtype=train_x.dtype + ) + ard_dims = ( + (train_x.shape[1]) if use_ard else None + ) + model = GP( + train_x=train_x, + train_y=train_y, + lengthscale_constraint=lengthscale_constraint, + outputscale_constraint=outputscale_constraint, + likelihood=likelihood, + ard_dims=ard_dims, + ).to(device=train_x.device, dtype=train_x.dtype) + + # Set model to training mode + model.train() + likelihood.train() + + # Initialize an empty hyperparamter "grid" for multistart GD + hyperparameter_grid = {} + # Initialize an empty list of model initializers, used later in multi-start GD + model_initializers: List[Callable[[GP], None]] = [] + + # If we passed an existing hyperparameter configuration for this model, use it + if res_hypers: + hyperparameter_config = lambda m: m.load_state_dict(res_hypers) + model_initializers.append(hyperparameter_config) + model.load_state_dict(res_hypers) + else: + # Otherwise add bounds and default values to hyperparameter grid + hyperparameter_grid["covar_module.outputscale"] = (0.05, 20.0, 1.0) + + hyperparameter_grid["covar_module.base_kernel.lengthscale"] = ( + 0.005, + 10.0, + 0.5, + ) + hyperparameter_grid["likelihood.noise"] = (5e-4, 0.2, 0.005) + samples = latin_hypercube_hp_grid( + hyperparameter_grid, gp_behaviour.n_initial_samples + ) + + # convert hyperparameter priors to initializers + for i in range(gp_behaviour.n_initial_samples): + hyperparameter_config = {} + for k, v in samples.items(): + hyperparameter_config[k] = v[i] + + initializer = initializer_factory(hyperparameter_config) + model_initializers.append(initializer) + if gp_behaviour.mll_estimation == MLLEstimation.LHS_PICK_BEST_START_GD: + model_initializers = pick_best_from_configurations( + initializers=model_initializers, + model=model, + train_x=train_x, + train_y=train_y, + n_best=gp_behaviour.n_best_on_lhs_selection, + ) + + # save the state dicts for multi-start gradient descent + best_loss = np.inf + best_state_dict = None + for i, initializer in enumerate(model_initializers): + state_dict, loss = mle_optimization( + initializer=initializer, + model=model, + num_steps=gp_behaviour.n_mle_training_steps, + train_x=train_x, + train_y=train_y, + ) + if loss < best_loss: + best_state_dict = state_dict + best_loss = loss + else: + del state_dict + + model.load_state_dict(best_state_dict) + res_hypers = best_state_dict + + # Switch to eval mode + model.eval() + likelihood.eval() + + return model, res_hypers diff --git a/mylib/lib_BAxUS/BAxUS/baxus/util/__init__.py b/mylib/lib_BAxUS/BAxUS/baxus/util/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/mylib/lib_BAxUS/BAxUS/baxus/util/__pycache__/__init__.cpython-310.pyc b/mylib/lib_BAxUS/BAxUS/baxus/util/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e17f2f8fc2a2587eec8bea2d26d4e564f7c67101 GIT binary patch literal 194 zcmd1j<>g`k0+UU<(?RrO5P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;x_&enx(7s(yY> zVo^zIQGQBMW_oFARi?hDzlUx>QGQxxPHK^^hl`WHu5*5FL1Iy6aekhzQ)XhZer{z> zW|BS-$2&Pzga+$F$fU%I(qjG6lFS_a`1s7c%#!$cy@JYH95%W6DWy57b|CAEnScZf F0|5WPG3@{V literal 0 HcmV?d00001 diff --git a/mylib/lib_BAxUS/BAxUS/baxus/util/__pycache__/acquisition_function_types.cpython-310.pyc b/mylib/lib_BAxUS/BAxUS/baxus/util/__pycache__/acquisition_function_types.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..01bbb1aeaa18f95929ec4904fdb9481320f4ac1b GIT binary patch literal 486 zcmYjO%}xR_5N>Hn5aD1#^y-xZ?#Y`m{H;PFyBk4c_R=i0V3XY~v}_cw`Z8X<`X+nz z#4G52 zO_olq9j)eKZQIuc0Iy!mON^yaA{fidj3tU^vGpsAEwU)yRch{2;C4oCm-Pq1z5nPA zTyK=0jC%ec82TO?wg$mn-@E-p`WVJ;;P=IOR*7&_9Obeys6qTm#(&_xVE=4c3K71$Ui5+cqsq? literal 0 HcmV?d00001 diff --git a/mylib/lib_BAxUS/BAxUS/baxus/util/__pycache__/acquisition_functions.cpython-310.pyc b/mylib/lib_BAxUS/BAxUS/baxus/util/__pycache__/acquisition_functions.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3848a4357030869424262cd28fd68d35d558e724 GIT binary patch literal 2231 zcma)7OOF&c5VqZq>3J=%5CUOOuK5!=`hi1n)#vJ>-|rA8-~9f^__<5S zU-)slSnzQhni_)OgwvD+*t3*oEMT;;S%GE7?7%U-8@SM0X)E)BwwYt6ova&ljqaqq ztRM6#c|f?!TStVq4q4!Fx=noV7|tP&eX5;jc~az{oWH+cintQ|QC7<0rN~5Hfw^Cl zRgxtKB8=j_5g6Emr!g)*UApjb8=CqKgdhRsBw%gI&u}IzZV6jB!kx56>@wjtYTSHt zS9qfiZ*lL)3EI5f%;6p0J+gxi@A3W-3A%g@96l=%qGJw1vvH~2p-@#g(kvZnHXZ6u z#LFn1Mity897a{V8!GTQ2CV-rsN2x)LQ`LZsO_4Bq_#lP+5yRG2GXi2NV@{d1ZGSu zPT!&(Fb7B2W1nd!E4WCd2b=h=#L&t%3dF%!WeYTIh4&x%uC|p(N5;~OnW<(G&i{?b zGtj-0gWVz%gCdP&C1k;6GMnC*B#|0q zvoskFpoMq7-G8<{Xyh>3pQ^#MO40#DZknjXfHRurF)C`SoM|r%lRT-ya1A_AJrFK) zX;UxKgN=_+Vr#WT)18>XidAty!CPaTR1M-a9Z^m>JMw-eHJt!aUod&0rWKtqpe^}{ zAs^BR`w_n)uMnxAk%y1TNV|_y>tt(_nmu${n6WGt;?vYosd*qPLEtu`q){@Tc z+TJE_;1sYL-ETdPDfqA|s3Yv>p_$lMWC2m;xG|~N!g@m%HulgU?n`id$r`zEmt@ge zHnBg(jeJkDywqK>Uq(3(d6FsZRE3Opb$gnty{QlfLiS;%b}NyqLTZ-->?>aZrL{%}c@77fqQMmO5 za&Z0sx%hsu-_~{xs7Z83w{r0++E0|WQju#%m1$CGJBzAaZO0->&7;!YxX9xO(1hkY z4Q_~`W;?J_z;ag#HBBqyug@Ca4ZH?fV0weur|3Bz++!Vko%ZMkTc;grTi%KNpNwyo zet;{|92sS@$v!9*na~9T-q2sJQUdga?14mvzP0c;unDwwqm7YU7Pq;RKyH5P{=nvR z&Yr`gu%RAWl;qx*M1Ap!QiAn+Xf<7QfQj8Dso6>!LF|C)$)E7>j!&Q%5**|83=<&v z^x*M_t49xMvzX>wX}YI-K*bO+t03Pf-IdX+P(@jp3Z+|^^C3m}J?)LlSwn44iKO^ff#~QKoUj{}qDhj-ZTT4p-!dW8?hb?{=h~f_ zz9Ad(uz3&O>gRI}ObWMNqm0^g17uTs?>0^@wLhMzR*T^`*PsE{3Bx?fL>TH$7(x=C zrl|MAaBmu=&4|QACXw6P8Kp&3t!T<4DWjRTlDv}VaE_1S1`6Zxdx4BI|0~P^3Q6b@ z#;%?)+BrGf?wvDZ{+j$8Mj%DZN`TdzD8Is$2#`6{fEk=07A68)r_#9D!2llgSHtGI pCKB2+$$x8HHkWzt*(qpmHrKy}8BO6+@*v}Q%%dJW3aD(|`Wu{D8x;Tm literal 0 HcmV?d00001 diff --git a/mylib/lib_BAxUS/BAxUS/baxus/util/__pycache__/data_utils.cpython-310.pyc b/mylib/lib_BAxUS/BAxUS/baxus/util/__pycache__/data_utils.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0dc14662337b701c137e5ba9a6f6c19611826b04 GIT binary patch literal 1968 zcmaJ>OK)5?6t?ecCTRjyC~1p8vXENkR!s&ZU=c+XO|vL0(umTk8mLCj*mvfp_Z8c> zlPNb6kh0`IG)uN@`6u48>R(_3=lISHO_8wV zEWU)UD-ePRnvtCLDaE;$dAZ;B^PnHNwV#FkNCYxE>WEPKvMalZcb$j`calhSME7OT zUxL-LSV}yxEZtqWaYw`7_n|zl zWigcdmOinoBF*)H7h-Uj7TQKinpzb@51-Fk2;&m;d(ib`5Qa45jGmH)zM|)3k341H zd#B#1-$0at{^B(rdVd-i?-lHU44RL#@p`2$>wvO)l#!VnUqRi)W3LnAzf?(Gx{AEy^WTi&NMB&+C~>N zgY2@R&JQ7^GGUnKEw(G!gsVadu)__TNXE6Ua~KL%Dj^k|2vEK-%qHV>ICdAoIi6+Z z1Rs}Rm_e|h`(SFuWx<|HrPC5@w1I!)3aa0VkzY)3dv*UcWMS#Iai|a{3aCJ=4`Ev$0tNU%y#}hB{6^FjIQnbU z8<)B4l^Iu1;!>z|RLd7>@2dy*HxE>qfNr&Ue{c7}=DjknxJq?dZ0@F9_ws3$9`>LQ zcJH1%df02_AwQ{guLhrb&J@n{RyDOtM`c}3=#ggt?`O2}6R)9-C;VT1U_pR; zz>=%LlJGQYqN7j*&pdteYa+rk`ZH~S4^1c{cpaSqe-dwp9A9q&;6#T%nsefS3xE=v zyNXcybdT-V`N5Pq9BV`aazt~$5tL3KI|IJ_f#HEq}q1>B_3jut73z>YT1T{NQu?_HkWA0{r8_rJ#^W~t8ECxaV zOOOc+@CB)X1zHDI)D@egX6%-2F&PlUIh~HirZqoAu+JNU9qX;JUjy+IRQ74-l)_&J z)qPATIraqpQglD2>Rq@2AF8+YiKW^ByA|)lzFpcG$wHn~>dsBn7J%@6TqiGX0M^H5 z06AF1vbB?yL!Rk7TZ=cbZ^M>Zp-Zp{0>#8b&NIalqHg#Sk>ZlnzgAZOfBS5fUpDA0iIV2UBL{Z*`y6oa;|mZsK+%)cGu z+J9sD0MzIe5Nj*ffM#oS9f@`WHsVzq;0NA*DG}faFrYBq3X@|)a1KtL)1BF;Y<>7p v9ZhW~$x3d%_{@fG;#9uj4}L4kCBD0pm!i((9ZZE|{0g~DyWYqCt@r)`$q*s3 literal 0 HcmV?d00001 diff --git a/mylib/lib_BAxUS/BAxUS/baxus/util/__pycache__/exceptions.cpython-310.pyc b/mylib/lib_BAxUS/BAxUS/baxus/util/__pycache__/exceptions.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..96902fb7168c486420781e23c98000da550527d9 GIT binary patch literal 1204 zcmah}O-~y!5OuN%`GB+>P#1W02uPrKH6uUoc=pZncy+JWMKIp|{*$G3g#LQ)a5Mnyf!PyqpAbW= z_6v-opV6cSxXvQLQNVS;4b}wQ3^)S3##(?|0XG1*SqE?@;3n%HqyBmVnIDZBpgpjg zO>i7dY79;4tTu^Q9pa;TZ{K89!Ic{sqs`U(E{3tMFrOy8bV4hfYJ;i5LQ0-diG?aF zhpEYmux%%7IJ$1k+k_}ua6;x?LJG|)>E|1SoL5xdzG)G{bVA5AGHu`!+`lZ&b-`mT zsd3zBW<*x;D-nMl9}d15oeIg#;P7BL9(>eANsX{t4Tgf+xR^;ch>`pl|a3;v>akB=ljT*H^6xN;<&G={#X?v8WJaOWJABf^a>n~6~AKfW* zbsjYMo^yp=&N06W#!P^+7DS{{xEU4}JFPL)nQ{Eq>&mCJC?&_2es5SekOI{9c@|1P z&e6Zs+eE-@so`SQ@oVd$HkkNc3}|I}TjR=&)1j^uv&*U$tq`iBxYR;9oKh(*)|In@ z@xak?YLXn=k|um5wGCkO(z6QGJX%TZ^@7z`VGHV#e93P3So4QG@L8w?Gp*h@oYRY2 zs?eNRa+SG!CDR^odv(v$qi2~~U&r!d!KJFtw@%d$r7zWx!`Fp2;cgxEBjf)7rsvp&{0sqrgE{k3`LzWUI$;cSiny72@<*i#wj?GKCFxa+&wdhIvSX3IZY Ft^Wvg5y=1m literal 0 HcmV?d00001 diff --git a/mylib/lib_BAxUS/BAxUS/baxus/util/__pycache__/gp_utils.cpython-310.pyc b/mylib/lib_BAxUS/BAxUS/baxus/util/__pycache__/gp_utils.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8a702621f7c1faa95df36d8940d5b958fd45c988 GIT binary patch literal 4475 zcmbVP&668P6`ya7M%rE3yZ*Le$Ol-|dY2riP>XTm4=N6|vA3{uKoC^3>XtOS^C9<) zyw=v}f=$6CoVdVAOL569#f?f8e@I`s#Q#D94!_qU?MlW;QAjmC-P5mMzj^(BzxO6x zTJkjfe)zY~ddX=``zH-Y#g*;on#MGyM_R16be;M}WW;96jIEXx+buhGT25SP zRbsd0s(CZ2wmit0QLR$I*_UG^M8cI*twZKU5lM(7a((!nO(t(i_CnWHNX9weBIQg%Qzo&(!r?dNb646$)$Tch@xOO;?jON z9N=bchZ!ER;ipp$jGb|%sL-6Q75cd}_-Dz{##Y~9azo{^sZ2(}CY5yU*lc^&IeC$*&vhm;x}&rOf7oMk~C z_<8E{$3Zj^o>e2tXy7c0fpA6$&F33sW=ujBeLG)(aQ~Up1g;(}U zr}*7r(ji=ArR?GQ%^WX|lL#_D4w6y169xy|?+1_hf}ig-m!%o;L>P!rS>>>g3%Ent z%3IPqafYaph}jtorNek0bo$bU_y8~n1_PcjX(R(_2SNlRSpgOSHb5g!DJ+^bv5e(n zg&HDOaf%wyt|px*%`%=zJ(RV%7?5ThMbb%!`Cyn!i-bPW#CNgc3%=P;W4@V2fxzjf zOoY85KMXhDzkm1Ij!3&<#KpC{cW&Lkb~}v`C1I8(*KUPDwi%D2aCZ||`_|1TA3oSD zTLt#bVID@Cy+NDq*#_S0$^alx2yZLK=%h&(JHbEX?j=}~okz2_>Kc~O&|UmJy^i)g zT3;7eF)3a{Bdc&!JInbX`+AP}6oOy~#RrADE9~o2>>Cr+%S~Y4P}sL~YtPUpp3ma@VPV+>;F80@)#pDxf|qUs>b`+)y^^lhl% z-cm50e_mp&Ts9XF^U`Ya6*!+NJ9hUm;(8)rAy0Cj@vK94bsF<3_qj-T)Xu>yrQ-5| zPY(#NM1~8TGTm!|R@8v_k@#g^dnq-gkFS+N#LvI{3HVA?Wt!Q7?Zj9N*-sHFSq5N> zpar05``0m)RkaPJ+m_n_ zJjimXx5XPI`zAGn^|JXMEoj6MZ%-E~2>t+1Gup&monh~yVVQ<*={z1@SHmP6D68W&tgEKg<>t%tzEWy-OKHixRKWGz+MXD!BMM(9sPO7$8v&`KY}C*W-#l3++Fg`*sTgfsk5ZVM-9Se<@J6ZS$H)3qPesh?E7t#FroZlr zpP(;S7u|%w4jBl$odq#!&#XhX%zniA6m%(0d06BJfV zzo7N>BT#2yUe_Ku1>$Aj5SI$jCP*BlI<`^vIgqxPd8C7Y?Wvx%V?8zq*J98`Wm?xz zQqIIFAg>6zQaI4#=I$N}KxThT)Lz~5Xs`1cb1?SuTHzHH=s>B*DpZIcj|>_;HOIBQ zPI~YLXRvd9Y{I4`vKz9sa%E9hB|I#czE6+dqv-~p0URnS?}*^QpZcsU2qSrUQc8iMEorw`Q0m68)deP6itZQ>7QBs&d!zl`{Wo)(#O+%#y@h`B_FHW z(9i0q=}^g8$R0GJs;-XS8|t!ju>--TUV845wCMY_bcus{0ZcAT+M4)L&{v^ws3GbQ zE;SdaQO;aPPrALqNG0Dg5!bR#I2dhEGR>4L1$|A*M)^@n_34HxQk5sA878@^HKm#5 zLfYLZ4RV$6N`k9QBSYCd=MCi-#gp!J)KkNV-vF4k?AK`Onhy`qJFCB8xYm~q-T2Bd vj2FnT|F$gSUyf~j*>JosjMwYa8DlzQVdgZ=G(F7J4ey0fTO%1YT7K~#LTUBw literal 0 HcmV?d00001 diff --git a/mylib/lib_BAxUS/BAxUS/baxus/util/__pycache__/parsing.cpython-310.pyc b/mylib/lib_BAxUS/BAxUS/baxus/util/__pycache__/parsing.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..50243d408f2d86789b20e5db53a01f22349896f8 GIT binary patch literal 7677 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 literal 0 HcmV?d00001 diff --git a/mylib/lib_BAxUS/BAxUS/baxus/util/__pycache__/projections.cpython-310.pyc b/mylib/lib_BAxUS/BAxUS/baxus/util/__pycache__/projections.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5d2310b9df1d7423428cb0b7a81d61915a5b1259 GIT binary patch literal 7742 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 LJ~K9Us66y98cEp? literal 0 HcmV?d00001 diff --git a/mylib/lib_BAxUS/BAxUS/baxus/util/acquisition_function_types.py b/mylib/lib_BAxUS/BAxUS/baxus/util/acquisition_function_types.py new file mode 100644 index 0000000..17c9756 --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/baxus/util/acquisition_function_types.py @@ -0,0 +1,12 @@ +from enum import Enum + + +class AcquisitionFunctionType(Enum): + EXPECTED_IMPROVEMENT = 1 + """ + Expected improvement acquisition function. + """ + THOMPSON_SAMPLING = 2 + """ + Thompson sampling acquisition function. + """ diff --git a/mylib/lib_BAxUS/BAxUS/baxus/util/acquisition_functions.py b/mylib/lib_BAxUS/BAxUS/baxus/util/acquisition_functions.py new file mode 100644 index 0000000..cfe393f --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/baxus/util/acquisition_functions.py @@ -0,0 +1,50 @@ +import math +from typing import Union + +import gpytorch +import numpy as np +import torch +from botorch.acquisition import ExpectedImprovement as _EI +from botorch.optim import optimize_acqf + +from baxus.gp import GP + + +class ExpectedImprovement: + def __init__(self, gp: GP, best_f: Union[float, np.ndarray], lb: np.ndarray, ub: np.ndarray, + evaluation_batch_size: int = 100, ): + self.ub = ub + self.lb = lb + self.evaluation_batch_size = evaluation_batch_size + self.best_f = best_f + self.gp = gp + self._EI = _EI(model=self.gp, best_f=self.best_f) + + def __call__(self, X: np.ndarray): + + def _ei(X): + X = np.expand_dims(X, 1) + return torch.unsqueeze(self._EI(torch.unsqueeze(torch.tensor(X), 1)), 1).detach().numpy() + + if X.ndim == 1: + X = X[np.newaxis, :] + if len(X) > 100: + # batched version + Xs = np.split(X, math.ceil(len(X) / self.evaluation_batch_size)) + eis = [_ei(_X) for _X in Xs] + result = np.concatenate(eis) + else: + result = _ei(X) + return result + + def optimize(self): + with gpytorch.settings.max_cholesky_size(2000): + X_cand, y_cand = optimize_acqf( + acq_function=self._EI, + bounds=torch.tensor([self.lb.reshape(-1), self.ub.reshape(-1)]), + q=1, + num_restarts=20, + raw_samples=100, + options={}, + ) + return X_cand.detach().numpy(), y_cand.detach().numpy() diff --git a/mylib/lib_BAxUS/BAxUS/baxus/util/behaviors/__init__.py b/mylib/lib_BAxUS/BAxUS/baxus/util/behaviors/__init__.py new file mode 100644 index 0000000..bd5aee3 --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/baxus/util/behaviors/__init__.py @@ -0,0 +1,6 @@ +from baxus.util.behaviors.baxus_configuration import ( + BaxusBehavior, +) +from baxus.util.behaviors.embedded_turbo_configuration import ( + EmbeddedTuRBOBehavior, +) # noqa diff --git a/mylib/lib_BAxUS/BAxUS/baxus/util/behaviors/__pycache__/__init__.cpython-310.pyc b/mylib/lib_BAxUS/BAxUS/baxus/util/behaviors/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9a5bb00fdcfa7b96c3e54b31c73e625ec5396ee2 GIT binary patch literal 377 zcmZusyH3L}6m=d0LPTO=;{(W$SWGMkfdQ#3q@u87u^jBSmh9ZhiBZcRv9d7mCtaEN z1tzXTK?rfB`##4$7qV=dpdCHG&R#ITh32=#*qoww`xqpVks&s!qbSs|iEUCRSSJ&b zr|*a$d9==$So)5sxp>gvaIkl28zrTZxBiAz-;3)!tq+<2Eq$*|*=z`1ISlzdv{OCv zPV^dD7j)Ez|H9Sgb>4f|z#m?MyeHyPOhfnpItQyL7~y*5Ksx+GJ!*PYjf$~@sW!?L zqYG9Q=U^AY=?>b0Y0*);GPX*%BlYXQYp_)Hf%Uy$O&kw&yONMiik4wX4x6aWqoGvGQQ}vflty% zR#C&0^MkpmTXVtt~g<4dzH;_(BeKIM1gZ^6Q^R^aw zTQOyXYPpiY^eE1^yvJ)E4LeBIVdrlfA0lZj+HuUC~UbEwp7mv3z8 z^v*lbCBK$f=l&y|w#^K7SIo$^8825Vg}ClP)kk1b65{ZENW#CvAbdyOukY-oZoIvg zjg>H+YWDPWI)+g9^jzQks!6v^#Tj+a{DYtQM5o0i|`zyUO)bN`L5BwVeS_c{|;L zY6ICAdq^p3n$~ziG)y^iJ;OFE+qUw=*kq|%P|d8A%ef5zcjYqgL$$*#-BVFju!Fyd zH~wD!O7L|0-%lSyXMjSIMg;F_NRp4Saz2koi9Oi8eL^b&A8l+_OWB-nj`R_H=J_5w v=*K(g$71_5Qoyxr_vu&eMf7Lf2ymylP3~_r`_erW+Wo^RI>IR-!7=^^ggBSZ literal 0 HcmV?d00001 diff --git a/mylib/lib_BAxUS/BAxUS/baxus/util/behaviors/__pycache__/embedded_turbo_configuration.cpython-310.pyc b/mylib/lib_BAxUS/BAxUS/baxus/util/behaviors/__pycache__/embedded_turbo_configuration.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..423cfc49eb55a1ba3dfece161861b77df150e61e GIT binary patch literal 2377 zcmb7G&2Jnv6t`zQv$LDc_h&01Mo1hMHCYKERjMl5q@_&}O`;~1U<9&e$KK6^`PkaC zRdhSpSYHBtku4pQ;1XMg0IjIS!6P}_>pj@m-r)P; z<2V=P)tV1uZ=d_E;gX-X{Q`7ug2I_^4)|fx$wgf3r!{k;^WC?4yttv};|zitCbShw zP7|JWiv6MWYmdBE-se!)$A}s*L&g+xkf4$$@xuKRvH!>ap{&_~*VN~QI!lNsIYk3CdEtql> z2*Zcy06l}W1df5*z%AeexDDI^P7WN9T##Jg72p-K;(_EnL(gX*^3|=NLK7V$8n`sk z;V>K?AJpm4H+U=!910JmszS|!Xh0~3GY*xkO;4)A1Fu9?6J28h$_t4}Ac|yR%Egq{ zr!~>Aj@@AfdqTnKDBJT8f88`23Z?5i$yd6WZS2u5OY_HzR z({3nYnP;mTaVVQQY`JT;aYN5BoJ#trZS>M{Ji2UuCmYY{T&?Zr{8_@}iJERL%c zSYJ08N*vlqbA--ilJ1Kx)qFnnYR@dx}Px{bb?{?aYm!lPjb-IlKZy$p~g~`wY^~dsvQqxM5(@yfRP}7u#S(XjSPX8I; zQdn?{av{|r69zwTym{YrvNhew*2dM2`Itx(fZ)oxy{BDoZP4}fcjrQ42^|sR%DC4l Z@A?3wkM);F>SkU?Gq`Tmv1Kpde*m+cg1rC$ literal 0 HcmV?d00001 diff --git a/mylib/lib_BAxUS/BAxUS/baxus/util/behaviors/__pycache__/embedding_configuration.cpython-310.pyc b/mylib/lib_BAxUS/BAxUS/baxus/util/behaviors/__pycache__/embedding_configuration.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aa17a8bb94b052d1a6879fd59498b7c9d2a8828e GIT binary patch literal 456 zcmYjNu};G<5Ix6^)K=|=m{~IvPlyE}8mK5sixeuMES6Kdt))0FPJ<`|3;YZ#D}R!e zslUL4-GJyxe!8>o-aS9l>vh1z>Br~d1Oa^cVn2v0F5D@P90(972aQsM;2K0A@EZs$ z(JM{^K@y0W?!M5G(4!&RL(r8Id z&h1)SBdl6f@>$WF$*6y8&0OWu_D5IoqQoYGlM%`iY;AxuB1~dLt zm9$!`oMv*#AC<8sm4E8l%oKCC!Sb~-#qnxmu~Xs=ExqS0ASgft6STV@N4O@^xn={e Z*SG#FZ!$ksx6YbxpLoUAX3#y*PPMv%m#f_RRg9xGv8j|+zRcvd^^_q#d`B0mk1cxgUbItYVC zE-M1Wek1|1GC-7wMQHX_fKLlQT%CAtj?enz9*o8Zr(-xgJ?QkhgE4fvqc-YnyMHu- zVXyrWTHVq3DXR0Gs0!Aw@cWBLSLm)B|-(Wg}e#e-pNsOsFL#_l&X2uX`M9N zNi_FWpp&@S3ViKG*I_VmQJ{5jbvANWIPtF*+FhhU=uYH?|2asMc4u>#Ch<9@R`y4C z=GV$JCWoR;|B8fDhjPZL_5X953}g09@DSnYHqVG;m)y%qCi8;s5__`+SwxFji+d$& z+X?vzQb~LM`N;jEPsnb7j Dict[str, Any]: + """ + The configuration as a dictionary. + + Returns: The configuration as a dictionary. + + """ + base_class_dict = super().conf_dict + this_dict = { + "number of new bins per dimension": self.n_new_bins, + "adjust initial target dimension": self.adjust_initial_target_dim, + "budget until input dimension": self.budget_until_input_dim, + } + return {**base_class_dict, **this_dict} diff --git a/mylib/lib_BAxUS/BAxUS/baxus/util/behaviors/embedded_turbo_configuration.py b/mylib/lib_BAxUS/BAxUS/baxus/util/behaviors/embedded_turbo_configuration.py new file mode 100644 index 0000000..0017f2b --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/baxus/util/behaviors/embedded_turbo_configuration.py @@ -0,0 +1,99 @@ +from dataclasses import dataclass +from typing import Any, Dict + +from baxus.util.acquisition_function_types import AcquisitionFunctionType +from baxus.util.behaviors.embedding_configuration import EmbeddingType + + +@dataclass +class EmbeddedTuRBOBehavior: + """ + The behavior of the embedded TuRBO algorithm + + """ + + initial_base_length: float = 0.8 + """ + The initial base side length (see TuRBO paper) + + """ + max_base_length: float = 1.6 + """ + The maximum base side length (see TuRBO paper) + + """ + min_base_length: float = 0.5 ** 7 + """ + The minimum base side length (see TuRBO paper). If you get lower than this, the trust region dies out. + + """ + success_tolerance: int = 3 + """ + The number of times we consecutively have to find a better point in order to expand the trust region, initial value + + """ + acquisition_function: AcquisitionFunctionType = AcquisitionFunctionType.THOMPSON_SAMPLING + """ + The different acquisition functions to use in a multi-batch setting (default: only Thompson sampling) + + """ + noise: float = 0. + """ + The noise of the problem. + """ + + embedding_type: EmbeddingType = EmbeddingType.BAXUS + """ + Uniform bin sizing means that all target bins have approx. equally many contributing input dimensions. + Random bin sizing means that a random target dimension is chosen for each input dimension (standard HeSBO + behavior). + """ + + success_decision_factor: float = 0.001 + """ + The difference wrt to the current incumbent solution required for a next point to be considered a success. + + """ + + def __str__(self): + return ( + f"_linit_{self.initial_base_length}" + f"_lmax_{self.max_base_length}" + f"_lmin_{self.min_base_length}" + f"_successtol_{self.success_tolerance}" + f"_acq_{self.acquisition_function.name}" + f"_noise_{self.noise}" + f"_et_{self.embedding_type.name}" + f"_sdf_{self.success_decision_factor}" + ) + + @property + def conf_dict(self) -> Dict[str, Any]: + """ + The configuration as a dictionary. + + Returns: The configuration as a dictionary. + + """ + return { + "initial base length": self.initial_base_length, + "maximum base length": self.max_base_length, + "minimum base length": self.min_base_length, + "success tolerance": self.success_tolerance, + "acquisition_functions": self.acquisition_function.name, + "observation noise": self.noise, + "embedding type": self.embedding_type.name, + "success decision factor": self.success_decision_factor, + } + + def pretty_print(self) -> str: + """ + A nice string of the configuration. + + Returns: A nice string of the configuration. + + """ + pstring = "" + for k, v in self.conf_dict.items(): + pstring += f"\t-{k}: {v}\n" + return pstring diff --git a/mylib/lib_BAxUS/BAxUS/baxus/util/behaviors/embedding_configuration.py b/mylib/lib_BAxUS/BAxUS/baxus/util/behaviors/embedding_configuration.py new file mode 100644 index 0000000..54387e1 --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/baxus/util/behaviors/embedding_configuration.py @@ -0,0 +1,12 @@ +from enum import Enum + + +class EmbeddingType(Enum): + BAXUS = 0 + """ + BAxUS embedding where each target bin has approx. the same number of contributing input dimensions. + """ + HESBO = 1 + """ + HeSBO embedding where a target dimension is sampled for each input dimension. + """ diff --git a/mylib/lib_BAxUS/BAxUS/baxus/util/behaviors/gp_configuration.py b/mylib/lib_BAxUS/BAxUS/baxus/util/behaviors/gp_configuration.py new file mode 100644 index 0000000..17d9bbf --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/baxus/util/behaviors/gp_configuration.py @@ -0,0 +1,39 @@ +from dataclasses import dataclass +from enum import Enum + + +class MLLEstimation(Enum): + MULTI_START_GRADIENT_DESCENT = 1 + """ + Sample a number of points and start gradient-based optimization on every point. + """ + LHS_PICK_BEST_START_GD = 2 + """ + Sample a number of points and start gradient-based optimization on the best initial points. + """ + + +@dataclass +class GPBehaviour: + mll_estimation: MLLEstimation = MLLEstimation.LHS_PICK_BEST_START_GD + """ + The maximum-likelihood-estimation method. + """ + n_initial_samples: int = 50 + """ + The initial samples. + """ + n_best_on_lhs_selection: int = 5 + """ + The number of best samples on which to start the gradient-based optimizer. + """ + n_mle_training_steps: int = 50 + """ + The number of gradient updates. + """ + + def __str__(self): + return ( + f"mle_{self.mll_estimation.name}_n_init_mle_{self.n_initial_samples}_" + f"n_best_lhs_{self.n_best_on_lhs_selection}_mle_steps_{self.n_mle_training_steps}" + ) diff --git a/mylib/lib_BAxUS/BAxUS/baxus/util/console_entry_point.py b/mylib/lib_BAxUS/BAxUS/baxus/util/console_entry_point.py new file mode 100644 index 0000000..fff7390 --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/baxus/util/console_entry_point.py @@ -0,0 +1,7 @@ +import sys + +from baxus.benchmark_runner import main + + +def bench(): + main(sys.argv[1:]) diff --git a/mylib/lib_BAxUS/BAxUS/baxus/util/data_utils.py b/mylib/lib_BAxUS/BAxUS/baxus/util/data_utils.py new file mode 100644 index 0000000..ddeed16 --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/baxus/util/data_utils.py @@ -0,0 +1,43 @@ +from copy import deepcopy +from typing import Dict, Sequence + +import numpy as np + + +def join_data(X: np.ndarray, dims_and_bins: Dict[int, int]) -> np.ndarray: + """ + After splitting, copy the data from the splitting dim(s) into the new dim(s) + + Args: + X (np.ndarray): the x-values before the splitting + dims_and_bins (Dict[int, int]): the splitting: dims and number of bins. Be warned that we assume an ordered dict + which we are allowed to in newer Python versions. + + Returns: the x-values after splitting + + """ + X = deepcopy(X) + for dim, bin in dims_and_bins.items(): + data_row = X[:, dim] + X = np.hstack((X, np.tile(data_row, bin - 1).reshape(-1, (len(data_row))).T)) + return X + + +def right_pad_sequence(sequence: Sequence[np.ndarray], dtype=np.float64, fill_value: float = 0.0) -> np.ndarray: + """ + Pads a sequence of 1D NumPy arrays to the same length. + + Args: + sequence: sequence of 1D NumPy arrays + dtype: the dtype of the result matrix + fill_value: the value for the padding + + Returns: a matrix of shape (len(sequence), max_sequence_length) where all rows are filled up with fill_value on the right + + """ + max_len = max(len(s) for s in sequence) + padded_matrix = np.full(shape=(len(sequence), max_len), dtype=dtype, fill_value=fill_value) + for i, seq in enumerate(sequence): + assert seq.ndim == 1, "Only 1D arrays are supported" + padded_matrix[i, 0:len(seq)] = seq + return padded_matrix diff --git a/mylib/lib_BAxUS/BAxUS/baxus/util/exceptions.py b/mylib/lib_BAxUS/BAxUS/baxus/util/exceptions.py new file mode 100644 index 0000000..c08caef --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/baxus/util/exceptions.py @@ -0,0 +1,30 @@ +class ArgumentError(Exception): + """ + An exception for an illegal input argmument. + """ + pass + + +class EffectiveDimTooLargeException(Exception): + """ + When the effective dimensionality is too large (for example when larger than the input dimensionality). + """ + pass + + +class OutOfBoundsException(Exception): + """ + When a point falls outside the search space. + """ + pass + + +class BoundsMismatchException(Exception): + """ + When the search space bounds don't have the same length. + """ + pass + + +class UnknownBehaviorError(Exception): + pass diff --git a/mylib/lib_BAxUS/BAxUS/baxus/util/gp_utils.py b/mylib/lib_BAxUS/BAxUS/baxus/util/gp_utils.py new file mode 100644 index 0000000..1ce3e85 --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/baxus/util/gp_utils.py @@ -0,0 +1,127 @@ +from copy import deepcopy +from typing import Dict, Callable, Tuple, List, Optional, OrderedDict + +import numpy as np +import torch +from gpytorch import ExactMarginalLogLikelihood +from scipy.stats import qmc +from torch import Tensor + +from baxus.util.utils import from_unit_cube + + +def pick_best_from_configurations( + initializers: List[Callable[["baxus.gp.GP"], None]], + model: "baxus.gp.GP", + train_x: torch.Tensor, + train_y: torch.Tensor, + n_best: Optional[int] = 1, +) -> List[Callable[["baxus.gp.GP"], None]]: + """ + Pick the n_best best performing initializers from a list of initializers based on a GP and a MLL + Args: + initializers: list of initializers, sets GP hyperparameters + model: the GP model + train_x: the data to evaluate the model likelihood on + train_y: the data to evaluate the model likelihood on + n_best: number of best performing initializers to choose + + Returns: list of initializer functions + + """ + assert n_best <= len(initializers), "At most as many best as we have initializers" + # avoid side effects + model = deepcopy(model) + + losses = [] + for i, initializer in enumerate(initializers): + initializer(model) + model.train() + model.likelihood.train() + mll = ExactMarginalLogLikelihood(model.likelihood, model) + output = model(train_x) + loss = -mll(output, train_y).cpu().detach().numpy() + losses.append(loss) + return np.array(initializers)[np.argsort(losses)[:n_best]].tolist() + + +def mle_optimization( + initializer: Callable[["baxus.gp.GP"], None], + model: "baxus.gp.GP", + num_steps: int, + train_x: torch.Tensor, + train_y: torch.Tensor, +) -> Tuple[OrderedDict[str, Tensor], float]: + """ + Optimize likelihood of a model with an initializer. + :param initializer: the model initializer + :param model: the GP model + :param num_steps: number gradient descent steps + :param kernel_type: the kernel type of the GP model + :param train_x: the training data + :param train_y: the training data + :param mll: the model likelihood + :return: state dict and the average loss + """ + # avoid side effects + model = deepcopy(model) + initializer(model) + model.train() + model.likelihood.train() + mll = ExactMarginalLogLikelihood(model.likelihood, model) # TODO + + optimizer = torch.optim.Adam([{"params": model.parameters()}], lr=0.1) + + # only use half of the optimizer steps if kplsk kernel + cum_loss = 0 + for _ in range( + num_steps + ): + optimizer.zero_grad() + output = model(train_x) + loss = -mll(output, train_y) + cum_loss += loss + loss.backward() + optimizer.step() + return deepcopy(model.state_dict()), cum_loss / num_steps if num_steps > 0 else 0 + + +def initializer_factory( + hyperparameter_configuration: Dict[str, float] +) -> Callable[["turbo.gp.GP"], None]: + """ + Take a hyperparameter configuration and return a lambda initializing a model with this configuration + :param hyperparameter_configuration: the hyperparameter configuration + :return: callabe, defined in GPyTorch model + """ + return lambda m: m.initialize(**hyperparameter_configuration) + + +def latin_hypercube_hp_grid( + hyperparameter_grid: Dict[str, Tuple[float, float, float]], n_samples: int +) -> Dict[str, np.ndarray]: + """ + Draw samples from latin hypercube from hyperparameter grid. Default configuration will always be the first configuration. + :param hyperparameter_grid: dictionary, key: hyperparameter name, value: Tuple[lower_bound, upper_bound, default value] + :param n_samples: number of samples to return, if 1 return default values + :return: dictionary, key: hyperparameter name, value: np.ndarray of sample values (shape: (n_samples, 1)) + """ + return_configs = {} + for k, v in hyperparameter_grid.items(): + return_configs[k] = np.array([v[2]]) + # if only one sample, return the default value + if n_samples == 1: + return return_configs + hp_grid = deepcopy(hyperparameter_grid) + keys = [] + bounds = np.empty((0, 2)) + for k, v in hp_grid.items(): + bounds = np.vstack((bounds, v[:2])) + keys.append(k) + d = len(keys) + sampler = qmc.LatinHypercube(d=d) + sample = sampler.random(n=n_samples - 1) + samples = from_unit_cube(sample, bounds[:, 0], bounds[:, 1]) + for i, k in enumerate(keys): + return_configs[k] = np.hstack((return_configs[k], samples[:, i])) + return return_configs diff --git a/mylib/lib_BAxUS/BAxUS/baxus/util/parsing.py b/mylib/lib_BAxUS/BAxUS/baxus/util/parsing.py new file mode 100644 index 0000000..61b92a3 --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/baxus/util/parsing.py @@ -0,0 +1,375 @@ +import functools +from argparse import ArgumentParser, Namespace + +from baxus.benchmarks.synthetic_benchmark_functions import ( + RosenbrockEffectiveDim, + BraninEffectiveDim, + HartmannEffectiveDim, + RotatedHartmann6, + AckleyEffectiveDim, + LevyEffectiveDim, + GriewankEffectiveDim, + DixonPriceEffectiveDim, + MichalewiczEffectiveDim, + RastriginEffectiveDim, + ShiftedAckley10, +) +from baxus.util.acquisition_function_types import AcquisitionFunctionType +from baxus.util.behaviors.gp_configuration import MLLEstimation +from baxus.util.behaviors.embedding_configuration import EmbeddingType + + +def parse(args): + """ + Define a CLI parser and parse command line arguments + + Args: + args: command line arguments + + Returns: + Namespace: parsed command line arguments + + """ + parser = ArgumentParser() + required_named = parser.add_argument_group("required named arguments") + parser.add_argument( + "-id", + "--input-dim", + type=int, + default=100, + help="Input dimensionality", + ) + + parser.add_argument( + "-a", + "--algorithm", + type=str, + default="baxus", + choices=["baxus", "embedded_turbo_target_dim", "embedded_turbo_effective_dim", + "embedded_turbo_2_effective_dim", "random_search"], + help="The algorithm" + ) + + parser.add_argument( + "-l", + "--initial-baselength", + type=float, + default=0.8, + help="The initial base length.", + ) + parser.add_argument( + "-lmin", + "--min-baselength", + type=float, + default=0.5 ** 7, + help="The minimum base length.", + ) + parser.add_argument( + "-lmax", + "--max-baselength", + type=float, + default=1.6, + help="The maximum base length.", + ) + + parser.add_argument( + "-td", + "--target-dim", + type=int, + default=10, + help="Target dimensionality", + ) + + parser.add_argument( + "-n", "--n-init", type=int, help="Number of initial sampling points. Default: target dimensionality + 1." + ) + + parser.add_argument( + "-r", + "--num-repetitions", + default=1, + type=int, + help="Number of independent repetitions of each run.", + ) + + parser.add_argument( + "-m", + "--max-evals", + type=int, + default=300, + help="Max number of evaluations of each algorithm.", + ) + parser.add_argument( + "--noise-std", + default=0.0, + type=float, + help="Standard deviation of the noise of the objective function.", + ) + + required_named.add_argument( + "-f", + "--function", + choices=[ + "hartmann6", + "branin2", + "rosenbrock2", + "rosenbrock5", + "rosenbrock10", + "rosenbrock15", + "ackley2", + "shiftedackley10", + "ackley1", + "rosenbrock-domain-fixed", + "levy2", + "levy1", + "levy43", + "dixonprice2", + "griewank2", + "griewank1", + "michalewicz2", + "michalewicz15", + "michalewicz1", + "rastrigin2", + "rastrigin1", + "svm", + "lasso-leukemia", + "lasso-breastcancer", + "lasso-dna", + "lasso-rcv1", + "lasso-diabetes", + "lasso-simple", + "lasso-medium", + "lasso-high", + "lasso-hard", + "mopta08", + "hartmann6in1000_rotated", + "rosenbrock5in1000_rotated", + "ioh_function" + ], + required=True, + ) + + parser.add_argument( + "--results-dir", + type=str, + default="results", + help="Base directory to store results in", + ) + parser.add_argument( + "--run-description", + type=str, + default="", + help="Short description that will be added to the run directory", + ) + parser.add_argument( + "-bins", "--new-bins-on-split", type=int, default=3 + ) + + parser.add_argument( + "--multistart-samples", + help="Number of multistart samples for the MLE GD optimization. Samples will be drawn from " + "latin hypercube (if more than 1, otherwise the default value will be used", + type=int, + default=100, + ) + + parser.add_argument( + "--multistart-after-sample", + type=int, + default=10, + help="Only recognized for '--mle-optimization sample-and-choose-best'. Number of multi-start " + "gradient descent optimization out of the '--multistart-samples best ones.", + ) + + parser.add_argument( + "--mle-optimization", + choices=["multistart-gd", "sample-and-choose-best"], + type=str, + default="sample-and-choose-best", + help="'multistart-gd': sample --multistart-samples different starting points for the hyperparameters and start " + "gradient descent for each of them. 'sample-and-choose-best': evaluate -mss many " + "initial configurations and start ", + ) + parser.add_argument( + "--mle-training-steps", + type=int, + default=50, + help="Number of GD steps in MLE maximization.", + ) + + parser.add_argument( + "--acquisition-function", + type=str, + default="ts", + choices=["ts", "ei"], + help="The acquisition functions to use. Either 'ei' or 'ts'" + ) + + parser.add_argument( + "--embedding-type", + type=str, + choices=["hesbo", "baxus"], + default="baxus", + help="How to choose the bin sizes for the HeSBO embedding. 'hesbo': original HeSBO choice, pick " + "one target dimension for each input dimension at random. 'baxus': ensure (almost) uniform" + " bin sizes.", + ) + + parser.add_argument( + "--budget-until-input-dim", + type=int, + default=0, + help="The evaluation budget after which we reach the input dimension under the assumption that " \ + "we always fail in making progress." + ) + + parser.add_argument( + "-v", "--verbose", action="store_true", help="Whether to print debug messages" + ) + + parser.add_argument( + "--adjust-initial-target-dimension", action="store_true", help="Whether to adjust the initial target dimension" + " such that the final split is as close " + "as possible to the " + "ambient dimension for BAxUS." + ) + + pars = parser.parse_args(args) + + # load required benchmarks + benchmark_loader(pars.function, pars) + return pars + + +acquisition_function_mapper = { + "ts": AcquisitionFunctionType.THOMPSON_SAMPLING, + "ei": AcquisitionFunctionType.EXPECTED_IMPROVEMENT, +} + +mle_optimization_mapper = { + "multistart-gd": MLLEstimation.MULTI_START_GRADIENT_DESCENT, + "sample-and-choose-best": MLLEstimation.LHS_PICK_BEST_START_GD, +} + +embedding_type_mapper = { + "baxus": EmbeddingType.BAXUS, + "hesbo": EmbeddingType.HESBO, +} +_fun_mapper = {} + + +def benchmark_loader(bench: str, args: Namespace): + """ + Import the required implementation of a benchmark. We use this class to avoid imports of benchmarks that require + optional dependencies. + + Args: + bench: the benchmark name + args: the parsed command line arguments + + Returns: + None. Just import the benchmark implementation. + + """ + + if bench == "lasso-leukemia": + from baxus.benchmarks.real_world_benchmarks import LassoLeukemiaBenchmark + + _fun_mapper[bench] = LassoLeukemiaBenchmark + + if bench == "lasso-breastcancer": + from baxus.benchmarks.real_world_benchmarks import LassoBreastCancerBenchmark + + _fun_mapper[bench] = LassoBreastCancerBenchmark + + if bench == "lasso-dna": + from baxus.benchmarks.real_world_benchmarks import LassoDNABenchmark + + _fun_mapper[bench] = LassoDNABenchmark + + if bench == "lasso-diabetes": + from baxus.benchmarks.real_world_benchmarks import LassoDiabetesBenchmark + + _fun_mapper[bench] = LassoDiabetesBenchmark + + if bench == "lasso-rcv1": + from baxus.benchmarks.real_world_benchmarks import LassoRCV1Benchmark + + _fun_mapper[bench] = LassoRCV1Benchmark + if bench == "lasso-simple": + from baxus.benchmarks.real_world_benchmarks import LassoSimpleBenchmark + + _fun_mapper[bench] = LassoSimpleBenchmark + if bench == "lasso-medium": + from baxus.benchmarks.real_world_benchmarks import LassoMediumBenchmark + + _fun_mapper[bench] = LassoMediumBenchmark + if bench == "lasso-high": + from baxus.benchmarks.real_world_benchmarks import LassoHighBenchmark + + _fun_mapper[bench] = LassoHighBenchmark + if bench == "lasso-hard": + from baxus.benchmarks.real_world_benchmarks import LassoHardBenchmark + + _fun_mapper[bench] = LassoHardBenchmark + + if bench == "mopta08": + from baxus.benchmarks.real_world_benchmarks import MoptaSoftConstraints + + _fun_mapper[bench] = MoptaSoftConstraints + + if bench == "svm": + from baxus.benchmarks.real_world_benchmarks import SVMBenchmark + + _fun_mapper[bench] = SVMBenchmark + + if bench == "ioh_function": + from baxus.benchmarks.real_world_benchmarks import IOH_func_base + + _fun_mapper[bench] = IOH_func_base + + +def fun_mapper(): + """ + Map benchmark names to their implementation. + + Returns: + dict: a mapping of benchmark names to their (partially initialized) classes + + """ + return { + **{ + "hartmann6": functools.partial(HartmannEffectiveDim, effective_dim=6), + "branin2": functools.partial(BraninEffectiveDim, effective_dim=2), + "rosenbrock2": functools.partial( + RosenbrockEffectiveDim, effective_dim=2 + ), + "rosenbrock5": functools.partial( + RosenbrockEffectiveDim, effective_dim=5 + ), + "rosenbrock10": functools.partial( + RosenbrockEffectiveDim, effective_dim=10 + ), + "rosenbrock15": functools.partial( + RosenbrockEffectiveDim, effective_dim=15 + ), + "ackley2": functools.partial(AckleyEffectiveDim, effective_dim=2), + "shiftedackley10": ShiftedAckley10, + "ackley1": functools.partial(AckleyEffectiveDim, effective_dim=1), + "levy2": functools.partial(LevyEffectiveDim, effective_dim=2), + "levy43": functools.partial(LevyEffectiveDim, effective_dim=43), + "levy1": functools.partial(LevyEffectiveDim, effective_dim=1), + "dixonprice2": functools.partial(DixonPriceEffectiveDim, effective_dim=2), + "griewank2": functools.partial(GriewankEffectiveDim, effective_dim=2), + "griewank1": functools.partial(GriewankEffectiveDim, effective_dim=1), + "michalewicz2": functools.partial(MichalewiczEffectiveDim, effective_dim=2), + "michalewicz1": functools.partial(MichalewiczEffectiveDim, effective_dim=1), + "michalewicz15": functools.partial( + MichalewiczEffectiveDim, effective_dim=15 + ), + "rastrigin2": functools.partial(RastriginEffectiveDim, effective_dim=2), + "rastrigin1": functools.partial(RastriginEffectiveDim, effective_dim=1), + "hartmann6in1000_rotated": RotatedHartmann6, + }, + **_fun_mapper, + } diff --git a/mylib/lib_BAxUS/BAxUS/baxus/util/projections.py b/mylib/lib_BAxUS/BAxUS/baxus/util/projections.py new file mode 100644 index 0000000..5baf20a --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/baxus/util/projections.py @@ -0,0 +1,199 @@ +from abc import ABC +from logging import warning, info, debug +from typing import Optional, Dict, List + +import numpy as np +from numpy.random import RandomState + +from baxus.util.behaviors.embedding_configuration import EmbeddingType +from baxus.util.data_utils import right_pad_sequence +from baxus.util.exceptions import OutOfBoundsException, UnknownBehaviorError + + +class ProjectionModel(ABC): + def project_up(self, Y: np.ndarray) -> np.ndarray: + raise NotImplementedError() + + def project_down(self, X: np.ndarray) -> np.ndarray: + raise NotImplementedError() + + +class IdentityProjector(ProjectionModel): + def __init__(self, lb, ub): + self.lb = lb + self.ub = ub + + def project_up(self, Y: np.ndarray) -> np.ndarray: + return Y + + def project_down(self, X: np.ndarray) -> np.ndarray: + return X + + +class AxUS(ProjectionModel): + """ + AxUS embedding. Also support HeSBO embedding by choosing RANDOM bin sizing + """ + + def __init__( + self, + input_dim: int, + target_dim: int, + seed: Optional[int] = None, + bin_sizing=EmbeddingType.BAXUS, + ): + self.seed = seed + self.target_dim: int = target_dim + self.input_dim: int = input_dim + self.bin_sizing = bin_sizing + self._reset() + + def _reset(self): + """ + Reset the AxUS embedding. Sample a new AxUS embedding. + :return: + """ + + if self.target_dim > self.input_dim: + warning( + "HeSBO: Got a target dim larger than the input dim. Setting target dim to input dim." + ) + self.target_dim = self.input_dim + if self.target_dim == self.input_dim: + info("HeSBO: Target dim = input dim. Using identity mapping.") + self.S = np.eye(self.target_dim) + else: + if self.bin_sizing == EmbeddingType.BAXUS: + debug("Creating BAxUS embedding.") + input_dim_permutation = np.random.permutation(list(range(self.input_dim))) + + input_dim_bins = np.array_split(input_dim_permutation + 1, self.target_dim) + input_dim_bins = right_pad_sequence(input_dim_bins, dtype=int) + + mtrx = np.zeros((self.target_dim, self.input_dim + 1)) + np.put_along_axis(arr=mtrx, indices=input_dim_bins, + values=np.random.choice(np.array([-1, +1]), size=input_dim_bins.shape), axis=1) + self.S = mtrx[:, 1:] + + elif self.bin_sizing == EmbeddingType.HESBO: + debug("Creating HeSBO embedding.") + target_dims = np.random.choice(np.arange(self.target_dim), size=self.input_dim) + mtrx = np.zeros((self.target_dim, self.input_dim)) + np.put_along_axis(arr=mtrx, indices=target_dims.reshape((1, self.input_dim)), + values=np.random.choice(np.array([-1, +1]), size=self.input_dim), axis=0) + self.S = mtrx + else: + raise UnknownBehaviorError( + f"No such HeSBO bin-sizing behavior: {self.bin_sizing}" + ) + + @property + def S_prime(self) -> np.ndarray: + return self.S.T + + @property + def input_to_target_dim(self) -> Dict[int, int]: + """ + Return the target dimension each input dimension is mapped to. + + Returns: the target dimension each input dimension is mapped to. + + """ + return { + D: int(np.nonzero(self.S[:, D])[0]) for D in range(self.input_dim) + } + + @property + def target_to_input_dim(self) -> Dict[int, List[int]]: + """ + Return a list of input dimensions the target dimension maps to. + + Returns: A list of input dimensions the target dimension maps to. + + """ + return { + d: np.nonzero(self.S[d])[0].tolist() for d in range(self.target_dim) + } + + def project_down(self, X: np.ndarray) -> np.ndarray: + """ + Project one or multiple points from the ambient into the target space. + + Args: + X: Points in the ambient space. Shape: [num_points, input_dim] + + Returns: numpy array, shape: [num_points, target_dim] + + """ + X = np.array(X) + assert len(X.shape) <= 2 + assert X.shape[0] == self.input_dim + if not -1 <= X.min() <= X.max() <= 1: + raise OutOfBoundsException() + return self.S @ X + + def project_up(self, Y: np.ndarray) -> np.ndarray: + """ + Project one or multiple points from the target into the ambient space. + + Args: + Y: Points in the target space. Shape: [num_points, target_dim] + + Returns: numpy array, shape: [num_points, input_dim] + + """ + Y = np.array(Y) + assert len(Y.shape) <= 2 + assert Y.shape[0] == self.target_dim + if not -1 <= Y.min() <= Y.max() <= 1: + raise OutOfBoundsException() + return self.S_prime @ Y + + def contributing_dimensions(self, target_dimension: int) -> np.ndarray: + """ + Returns the dimensions in the ambient space that contribute to a target dimension. + + Args: + target_dimension: the target dimension for which to return the contributing input dimensions + + Returns: the input dimensions contributing to the target dimension + + """ + + return np.nonzero(self.S[target_dimension])[0] + + def increase_target_dimensionality(self, dims_and_bins: Dict[int, int]): + """ + Split up one target dimension. The contributing input dimensions will be randomly assigned to two bins. + One bin is the current target dimension, the other bin will be assigned to a new target dimension. + Therefore, the target dimensionality will be increased by one. The projection matrix will change by this! + The affected target dimension and the new dimension will only have half the number of contributing input + dimensions than the target dimension prior to the splitting. + + Args: + dims_and_bins: the dimensions and the number of bins to split them into + + Returns: Nothing, S_prime gets updated + + """ + + for splitting_target_dim, n_new_bins in dims_and_bins.items(): + contributing_input_dims = np.random.permutation(self.contributing_dimensions(splitting_target_dim)) + non_zero_elements = self.S[splitting_target_dim, contributing_input_dims].squeeze() + + assert len(contributing_input_dims) >= dims_and_bins[splitting_target_dim], ( + f"Only {len(contributing_input_dims)} contributing input dimensions but want to split " + f"into {dims_and_bins[splitting_target_dim]} new bins" + ) + self.target_dim += n_new_bins - 1 # one bin is in the current dim + new_bins = np.array_split(contributing_input_dims + 1, n_new_bins)[1:] + elements_to_move = np.array_split(non_zero_elements, n_new_bins)[1:] + + new_bins_padded = right_pad_sequence(new_bins, dtype=int) + elements_to_move_padded = right_pad_sequence(elements_to_move) + + S_stack = np.zeros((n_new_bins - 1, self.S.shape[1] + 1)) + np.put_along_axis(arr=S_stack, indices=new_bins_padded, values=elements_to_move_padded, axis=1) + self.S[splitting_target_dim, np.hstack(new_bins) - 1] = 0 + + self.S = np.vstack((self.S, S_stack[:, 1:])) diff --git a/mylib/lib_BAxUS/BAxUS/baxus/util/space_learning/__init__.py b/mylib/lib_BAxUS/BAxUS/baxus/util/space_learning/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/mylib/lib_BAxUS/BAxUS/baxus/util/space_learning/__pycache__/__init__.cpython-310.pyc b/mylib/lib_BAxUS/BAxUS/baxus/util/space_learning/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ec741cb297a119df7a4b2964f75c5dab51b199db GIT binary patch literal 209 zcmYk$u?oU45C-5>I*8B*ai}-BiD-4GixrAk9gTuDJS))jD$HMX43 Tn&CNKXj67dF8w!lUE6rT^tl4aTPrXicKIf%WPCh?_E2ur)0ZDD)qmL`S87bAJbvJ!o`qfzt0 z7z){I{(@4lkG=L?;yVbTHn(< zxS+&KqL9Lh?4UiwD6>{{;cRLjueGkk7j$V!o7s1Gg%@qvQk1n+n>qJ%;VEzFC~Ji; zTxF{kbMMKry+TV5sIx+gj&hW%oIRvEJLoaU(r0Z&pFlD1$ilC4ca^2+iYWgQFS>As z9%#2zmwBvnPnds6R+#zwXwhSy>MCQU7Z&s36y6?^ebu|etb0$VN+{L7$e!KTYYGa8Qv zAtVxO+p#J79SmAY2inUNC zw|wxPAYjuZpKEK9CUcl`xP6gn$9$7qY6>7M<76=rUTGo=O(*lp>>|U-OxsYo`HiMo zl55LEY5Qu%1=qB!GEJc&kh%a5tH^md=nMEqAki}57%(qLv<-9(^Z+zTBTcGE_(rfx z^Io+z=R#_KE{bSu*h)m&%EI!}91$L9Q`jGncprlPxE{`mj1P-66!5qUCX%?~x5@Cc z*RPJg5XCe}xj1_D$?5B(mqi9snUqC-bee?aFuO^UXb3bueR2KO*|5PVyspY&C6jbm z&cg{Gr#uunv}`CvRm!p8aZ=>Ra818%CLg~sb7U@89su-rcJVIm(;g0RANS}sKEO}$ zF7>g8#Su6ReC?z~3_qo~=}8MF%m@^W;)#K6fYBpah{^2u>nbdhrdLgOoScP1gg4rr zrbQ^lu8A;->w0X!A?URGEGt-*@{i0klurSC Tuple[np.ndarray, np.ndarray, np.ndarray]: + """ + + :param x_center: the TR center + :param weights: the weights of the dims + :param length: baselength + :param dim: the target dim + :param n_cand: number of candidates + :param dtype: the data type + :param device: the device + :return: triple, X_cand, lb, ub + """ + debug(f"creating {n_cand} candidates") + lb = np.clip(x_center - weights * length, -1.0, 1.0) + ub = np.clip(x_center + weights * length, -1.0, 1.0) + + # Draw a Sobolev sequence in [lb, ub] + seed = np.random.randint(int(1e6)) + sobol = SobolEngine(dim, scramble=True, seed=seed) + pert = sobol.draw(n_cand).to(dtype=dtype, device=device).cpu().detach().numpy() + pert = lb + (ub - lb) * pert + + # Create a perturbation mask + prob_perturb = min(20.0 / dim, 1.0) + mask = np.random.rand(n_cand, dim) <= prob_perturb + ind = np.where(np.sum(mask, axis=1) == 0)[0] + mask[ind, np.random.randint(0, dim - 1, size=len(ind))] = 1 + + # Create candidate points + X_cand = x_center.copy() * np.ones((n_cand, dim)) + X_cand[mask] = pert[mask] + return X_cand, lb, ub diff --git a/mylib/lib_BAxUS/BAxUS/baxus/util/utils.py b/mylib/lib_BAxUS/BAxUS/baxus/util/utils.py new file mode 100644 index 0000000..50ef1ed --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/baxus/util/utils.py @@ -0,0 +1,232 @@ +############################################################################### +# Copyright (c) 2019 Uber Technologies, Inc. # +# # +# Licensed under the Uber Non-Commercial License (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at the root directory of this project. # +# # +# See the License for the specific language governing permissions and # +# limitations under the License. # +############################################################################### + +# Derived from the TuRBO implementation (https://github.com/uber-research/TuRBO) +# Author: anonymous + +import argparse +from logging import warning + +try: + from collections.abc import Iterator +except ImportError as e: + warning("Failed to import Iterator from collections.abc. Python < 3.10 won't be supported in the future.") + from collections import Iterator + +try: + from reprlib import repr +except ImportError: + pass +import functools + +import numpy as np +import seaborn as sns + + +def to_unit_cube(x: np.ndarray, lower_bounds: np.ndarray, upper_bounds: np.ndarray) -> np.ndarray: + """ + Project to [0, 1]^d from hypercube with bounds lb and ub + + Args: + x: the points to scale + lower_bounds: the lower bounds in the unscaled space + upper_bounds: the upper bounds un the unscaled space + + Returns: scaled points + + """ + assert lower_bounds.ndim == 1 and upper_bounds.ndim == 1 and x.ndim == 2 + xx = (x - lower_bounds) / (upper_bounds - lower_bounds) + return xx + + +def to_1_around_origin(x: np.ndarray, lower_bounds: np.ndarray, upper_bounds: np.ndarray) -> np.ndarray: + """ + Project to [-1, 1]^d from hypercube with bounds lb and ub + + Args: + x: the points to scale + lower_bounds: the lower bounds in the unscaled space + upper_bounds: the upper bounds un the unscaled space + + Returns: the scaled points. + + """ + assert lower_bounds.ndim == 1 and upper_bounds.ndim == 1 and x.ndim == 2 + x = to_unit_cube(x, lower_bounds, upper_bounds) + xx = x * 2 - 1 + return xx + + +def from_unit_cube(x: np.ndarray, lower_bounds: np.ndarray, upper_bounds: np.ndarray) -> np.ndarray: + """ + Project points that were scaled to unit cube back to full space. + + Args: + x: the points + lower_bounds: the lower bounds of the full space + upper_bounds: the upper bounds of the full space + + Returns: scaled points + + """ + assert lower_bounds.ndim == 1 and upper_bounds.ndim == 1 and x.ndim == 2 + xx = x * (upper_bounds - lower_bounds) + lower_bounds + return xx + + +def from_1_around_origin(x: np.ndarray, lower_bounds: np.ndarray, upper_bounds: np.ndarray) -> np.ndarray: + """ + Project points that were scaled to one-around-origin cube back to full space. + + Args: + x: the points + lower_bounds: the lower bounds of the full space + upper_bounds: the upper bounds of the full space + sample_zero: A switch to include to sample the zero vector from LHS + + Returns: scaled points + + """ + xx = (x + 1) / 2 + return from_unit_cube(xx, lower_bounds, upper_bounds) + + +def one_around_origin_latin_hypercube(n_pts: int, dim: int, sample_zero: bool) -> np.ndarray: + """ + Basic Latin hypercube implementation with center perturbation in a one-around-origin cube. + + Args: + n_pts: number of points to sample + dim: dimensionality of the space + sample_zero: sample the zero from the initial/repair LHS + + Returns: the LHS points + + """ + X = latin_hypercube(n_pts=n_pts, dim=dim) + if sample_zero: + X[0,:] = np.ones_like(X[0,:])*0.5 + + return X * 2 - 1 + + +def latin_hypercube(n_pts: int, dim: int) -> np.ndarray: + """ + Basic Latin hypercube implementation with center perturbation. + + Args: + n_pts: number of points to sample + dim: dimensionality of the space + + Returns: the LHS points + + """ + X = np.zeros((n_pts, dim)) + centers = (1.0 + 2.0 * np.arange(0.0, n_pts)) / float(2 * n_pts) + for i in range(dim): # Shuffle the center locations for each dimension. + X[:, i] = centers[np.random.permutation(n_pts)] + + # Add some perturbations within each box + pert = np.random.uniform(-1.0, 1.0, (n_pts, dim)) / float(2 * n_pts) + X += pert + return X + + +def str2bool(value: str) -> bool: + """ + Parse string to boolean or throw error if string has no boolean type. + + Args: + value: the string to parse + + Returns: True, if string is truthy, false if string is falsy + + """ + if isinstance(value, bool): + return value + if value.lower() in ("yes", "true", "t", "y", "1"): + return True + elif value.lower() in ("no", "false", "f", "n", "0"): + return False + else: + raise argparse.ArgumentTypeError("Boolean value expected.") + + +class ColorIterator(Iterator): + """ + A color iterator + """ + colors = sns.color_palette("husl", 23) + + def __init__(self): + self.cc = 0 + + def __iter__(self): + return self + + def __next__(self): + c = self.colors[self.cc % 23] + self.cc += 1 + return c + + +def in_range(x: np.ndarray, incumbent: np.ndarray, lb: np.ndarray, ub: np.ndarray): + """ + Whether the point x is within the range of the next slower trust region around incumbent + given the current bounds lb, ub + + Args: + x: the point to test + incumbent: the point to center the next smallest TR around + lb: lower bound of the current trust region + ub: upper bound of the current trust region + + Returns: true if point would fall in the next smaller trust region, false otherwise + + """ + offsets = [(ub.squeeze()[i] - lb.squeeze()[i]) / 4 for i in range(len(incumbent))] + return all( + incumbent[i] - offsets[i] < x[i] < incumbent[i] + offsets[i] + for i in range(len(incumbent)) + ) + + +def star_string(wrap_string: str) -> str: + """ + Wrap string in stars. + + Args: + wrap_string: string to wrap + + Returns: wrapped string + + """ + return f"{''.join(['*'] * (len(wrap_string) + 4))}\n* {wrap_string} *\n{''.join(['*'] * (len(wrap_string) + 4))}" + + +def partialclass(cls, *args, **kwargs): + """ + A partially initialized class + + Args: + cls: the base class + *args: + **kwargs: + + Returns: + + """ + + class PartialClass(cls): + __init__ = functools.partial(cls.__init__, *args, **kwargs) + + return PartialClass \ No newline at end of file diff --git a/mylib/lib_BAxUS/BAxUS/baxus_figure.png b/mylib/lib_BAxUS/BAxUS/baxus_figure.png new file mode 100644 index 0000000000000000000000000000000000000000..a8a2768fb10369b5277e024469e285e4326482d2 GIT binary patch literal 85473 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

iYc4u7 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 literal 0 HcmV?d00001 diff --git a/mylib/lib_BAxUS/BAxUS/benchmark_runner.py b/mylib/lib_BAxUS/BAxUS/benchmark_runner.py new file mode 100644 index 0000000..d8c7c5f --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/benchmark_runner.py @@ -0,0 +1,6 @@ +import sys + +from baxus.benchmark_runner import main + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/mylib/lib_BAxUS/BAxUS/data/rotation_matrix_alebo.json b/mylib/lib_BAxUS/BAxUS/data/rotation_matrix_alebo.json new file mode 100644 index 0000000..c5add6f --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/data/rotation_matrix_alebo.json @@ -0,0 +1 @@ +[[0.02544996682934575, 0.009574537166452495, -0.058103127520602524, 0.028667861413367236, -0.0355217681935252, -0.016604316880075937, 0.02457914631200122, 0.06831660262365145, -0.0006238226399938474, 0.072518165501472, 0.033466069225168434, -0.011527200257611864, -0.07530578702380952, 0.014178398798682984, -0.03430446276541374, -0.01066757306503117, 0.015042973622327243, -0.03339916565020489, 0.015429404051627184, 0.06137910415120743, -0.04230220270576482, -0.03366326546736503, 0.04999726697382792, 0.017515610672236056, -0.022652699147739003, -0.021162346694844004, 0.009161717920765429, -0.02540990178301067, 0.05279104071502312, -0.005285776582363403, -0.022936330489805628, -0.03753685138706834, -0.02254932230652342, -0.02835962369410157, 0.005944892422419754, -0.00454828556040731, 0.0010128135789340496, -0.030193983491232878, -0.0475732145557355, 0.03513030705165126, 0.01196908634958705, 0.0037014232400676417, -0.0018846905221955104, 0.07039962184403559, 0.015784259629399982, -0.0299971700219201, -0.020147575294624083, -0.035339057808230635, -0.015846595326207503, -0.008777004211869693, 0.040223553196324605, 0.02134320770717852, -0.062358816207578494, -0.028417670799849977, -0.011618130605545536, 0.04415317894754264, -0.01503640406653814, -0.04750027828703065, 0.002525308429364371, 0.002707392955910534, 0.08835118201131428, -0.05350560321514318, -0.05201324888656311, -0.012597445999067577, 0.0015193374813761134, -0.01650155133683012, -0.04615551725099004, 0.02977370162101278, -0.024511188949340006, -0.010678093087685442, -0.06616397557007656, -0.013393626036625344, -0.0008307585586323427, 0.01557292061261327, -0.009816662877438796, -0.00634982811736922, -0.025058932308207396, 0.05603748249887647, -0.019045407339781634, -0.054888250154415126, 0.01082673978074529, 0.04827299447840366, 0.009142120877155113, 0.01995227818361848, -0.019427482229898627, -0.001694072556671922, -0.04917739056654921, 0.004234280853664795, 0.02353096722022128, -0.006172457189858234, -0.024173171174897434, 0.05719802031829663, 0.011933469552045321, -0.01787475683227195, 0.024780160135971424, -0.04038254494374412, -0.02943950962551391, 0.055596242119447616, 0.007771656392393609, -0.020640000032250395, 0.02870037952221334, 0.023188234118250106, -0.0018237229609560125, -0.03584176319237006, 0.02775773097259729, -0.023483423692803457, -0.04817392437547226, -0.02158683929701966, 0.01202962730612544, 0.021205374851379105, -0.03953364350013944, 0.028101255233948342, -0.03354659134837273, 0.014868316812619964, 0.0010892902825457224, 0.029379020788161007, -0.006634779658266286, 0.015682274611741764, -0.015557194317197473, 0.014326205387608634, 0.01866742929003277, -0.06465472117789456, 0.014447520982604649, -0.011027284458509002, -0.004491357023586313, 0.03072477574554824, -0.008721285706118775, -0.02752104393937565, -0.03489636319850242, -0.044653993364481726, 0.03715964440756241, -0.032132194177338716, -0.0275649172427052, -0.013237485929765416, 0.02389424674186741, -0.02724701967488443, 0.023462161339039802, -0.012944720783336555, -0.03724425241442513, 0.03600266067419821, -0.018284301389487292, 0.026370900690282847, -0.000678983412101499, -0.10088129981329742, 0.0029239317525212895, 0.05016344034231465, -0.025566293606524543, -0.04426334135712184, -0.0009406722312208958, 0.04730130417010296, 0.03232615436942289, -0.0010074828127931944, 0.01348258434837365, 0.03374678451431559, 0.01957404735368179, 0.00022063026719628537, -0.00017645017989813445, -0.0014518072560848333, 0.042224557661487805, 0.012436097314277608, -0.013239357060148223, 0.021296077180036434, -0.00013392607468563217, 0.03226112271715656, -0.005862978154962229, 0.03459561409791674, -0.027189191789299353, -0.02195864265200352, -0.0004201371467906479, 0.035355509315858666, 0.06425048035092656, -0.06159708405212547, 0.048343019244404754, 0.04152675753985215, -0.0299744350469573, 0.034268429146775095, -0.014461358927494457, 0.046132565047468155, -0.06271149944514903, 0.0015754014218372654, 0.005664662764855548, -0.056377326888553396, -0.03847415326317977, 0.02697118142363545, 0.0063030233374681, 0.021993158288957083, -0.01449765710719618, -0.010403532833918969, 0.014721839168428442, 0.026517664515774073, -0.018903895648546703, 0.0012540756428439121, 0.031008647016355514, 0.024607870808221143, 0.008391016612096385, -0.03382925773124992, 0.020826417353134914, 0.04264555083920006, -0.0012150351114579754, 0.04027894654242726, -0.07227608224195892, 0.0222614153187953, -0.02070962666529088, -0.005348786028611981, 0.09047184562504831, -0.0399443145431695, 0.036681395956834534, 0.011611599095065839, -0.0026783628929257456, 0.030220592720757576, 0.007949211995958182, 0.030430202915896494, -0.008453846438350036, 0.001987430890492973, -0.01538253321443193, -0.01833173437456127, 0.0002709212406512944, 0.008489964098265624, 0.021235817816013122, 0.00084143897059623, 0.04632868692808529, -0.030082103857458804, 0.04301715996079379, -0.03216669622100307, -0.015661427920926334, 0.005267183543879863, -0.00815101747591674, -0.014615278781262286, 0.012143694693683468, -0.003901152581143365, 0.0630926825716529, 0.028437257524049974, 0.07429036517795731, -0.05152679559109312, 0.06166610428840731, 0.05190292889222631, 0.030764217361379444, -0.0662338637230066, -0.014473956709209677, 0.06054230329625967, 0.003484125337583866, -0.004077818397687257, -0.004014036972957696, 0.014225221680064891, -0.00043126791438360284, -0.09193359127072778, -0.06796480988779202, 0.011311941247418612, 0.0011584298417835152, -0.033989266783988004, -0.006726496323191289, 0.009598275678863276, -0.01682852974742208, -0.00788184955680023, 0.02608286935132159, 0.03136064307209446, 0.03453603159271619, 0.027579334442363854, -0.05589683987791795, -0.025393545006302087, -0.006028774824671259, 0.035157512944897266, 0.00045756454743067364, 0.005523585630424437, 0.00619140524968758, 0.011235583093780954, 0.0004101799604958375, -0.03685080678170204, 0.016307923375214476, 0.0223772298877034, -0.032820078945766655, -0.007606992382938688, -0.03993573175679455, -0.0031454071655047365, 0.015319877861119368, -0.004860899027247003, -0.03786681075906258, -0.03961846988667918, 0.044415042760445715, -0.06025592480924845, 0.05294636632228032, 0.03685573720186807, -0.012644689117056367, -0.037169482564545664, 0.0058716735311822345, -0.01911201800170213, -0.024604709302551736, 0.05568268972436768, -0.061167483619462844, 0.019949070036128363, 0.05863735101769346, -0.016618711118862657, -0.020180135332158337, 0.07978078101974595, 0.0007141436572412401, 0.0037684128991120995, 0.06779251866785406, 0.004288760608178283, -0.02147327302527603, 0.033927791040706784, 0.008573640581554806, -0.027845202384482425, -0.00943393554290449, -0.026105872760025142, 0.007266785167767473, 0.019220751009638565, 0.034249577148739545, 0.01926074993529251, -0.05411880937933463, 0.0028521203267845435, 0.009446840593227243, 0.017635374599867085, -0.04685975913371206, -0.01512077743554284, -0.028315271322213686, 0.0561508089476226, -0.007221160958910436, -0.02948273274685288, 0.0256538410702407, 0.00953646555345523, 0.01530153075507037, -0.003875189669917652, 0.01779558523244992, 0.04051790192266688, -0.0010349754387499067, -0.058761116749689334, 0.0037370013252884253, -0.005723644012324471, -0.06841204116902681, -0.006081952754233316, -0.019651950517148315, -0.02050202592409786, 0.022141818878607954, -0.02735175751011535, -0.024472634934950582, 0.0020688799545815553, -0.03457952612209436, 0.02244266819688071, -0.011169218153425312, -0.025072130421874145, -0.012397192133443341, 0.03357151195505463, -0.006230195604090403, 0.03015190355085056, 0.0008594269159238315, 0.0015361596778206252, 0.10406526915939543, -0.018660699169951913, -0.05318852466012751, -0.021213013122363913, 0.02119468447835584, -0.013516077684948415, 0.012680191334203799, -0.018490005275249938, -0.004409654875366219, -0.01004919966517205, -0.02264029111370543, -0.02962879441855739, -0.04797354099546257, -0.01613220765851406, 0.011391106271089446, 0.0002985882660491209, -0.00717246491925436, -0.008597963373209993, -0.01721532312499551, 0.009678078199187385, -0.03444314400399684, -0.0006110870081299184, 0.030095401285819307, -0.03242552577159918, -0.01996966410454913, -0.023110393835922085, 0.05977582250907947, -0.03200349116009199, -0.0432301821818922, 0.02509733022365558, 0.012685983760961849, 0.0033298739159166313, -0.018162974018985794, 0.012223009496134545, -0.006376756070253344, 0.024613355935691767, 0.009618426960158603, -0.02253354781745811, 0.019726377739358973, 0.029198265910964687, 0.003081121937156081, -0.020998893754629072, -0.017515017172647692, -0.02841567529937914, -0.04210410519210633, 0.005365385102786315, 0.017844878567949484, 0.0028280731509617713, -0.009539481290206889, 0.015682459552584346, -0.0279800756304544, 0.0034367055271386764, -0.0015662483504134544, -0.07635430569220523, -0.015828498468888088, -0.03707116307115235, 0.027489394760517854, 0.07760900715881079, 0.05960165570909173, -0.00012393858597745154, 0.03533043593943542, -0.010513470852040924, 0.05433849155697967, -0.013160155217196021, -0.044175546354151586, 0.026667907802597122, -0.00624258018338364, 0.04396661073197066, 0.043204805856817574, 0.004500639309502591, -0.015718736468537775, 0.021112306975209508, 0.04665864145156651, -0.03738537408123857, -0.011149390048931505, 0.06470137398090567, 0.0008447778802526712, 0.024318258129175117, 0.022167521064307222, 0.014691686904840693, 0.034460186236710114, -0.009550929369839938, 0.012141062580959372, -0.028190884152881727, 0.015643067224705123, 0.007653572411026542, -0.0055859378535763875, 0.03337823835523605, 0.05468522234744894, -0.017562407720009103, 0.06467042526395275, 0.012674141170101922, 0.03225720035256546, -0.015676009708682503, -0.005036417801341434, 0.0682021244027462, 0.06031095261426205, -0.0018923092377590729, 0.00017149838088330836, -0.013912141829860577, 0.052123498161137344, -0.02219699933405572, -0.0673808656854221, -0.005455667235310066, -0.01350980778434929, -0.004079998193585963, 0.010104195775541907, 0.04858984919127531, -0.011555670550317598, -0.05683992369931614, 0.04219093882017361, -0.011768017064248518, -0.014830933335194914, 0.06335728663991559, 0.03026019936293646, -0.03225621143316863, -0.008941308126161174, -0.025749856735587218, -0.006423390521150042, -0.04240160749535543, -0.02534452817047598, -0.0923626333954701, -0.06332636638363964, -0.004340713859562943, -0.028358347662619125, -0.021329461684091958, 0.001338488829787546, -0.012095086399903632, 0.0524100829458531, -0.05618674875785418, -0.02933754752513129, -0.02082479880704903, 0.0061017450584318, 0.04758180371689842, -0.02562768229923555, 0.04254254618215783, 0.005598302215425604, 0.001597504765323405, 0.011499204708492935, -0.010038670470154162, -0.011364971907213684, 0.05371746009331105, -0.012674742722117823, -0.003478943756488481, -0.016420953557072297, -0.008789669107980534, 0.008579086033650332, 0.0008804650281343512, -0.02752188304205001, -0.01267994501219349, 0.0036103785243878136, 0.004685290762301383, 0.008670226785288775, -0.00699971720382852, -0.025543894708458754, 0.02070346897282023, -0.05155037733109825, -0.03463072193702552, -0.028377802594538523, 0.003062088388507453, -0.007377151397203944, -0.048199015353242364, 0.03058795120377042, -0.008937922369892578, -0.039467696391554216, 0.008602301969437828, 0.029752008811578263, -0.0063994793183276425, -0.011005349644175183, -0.0015634208593509006, -0.02078278956498697, -0.011300471062667457, 0.0299582083977062, 0.007959610884624232, 0.0005730264526975677, 0.001763169752962604, -0.049507934074479384, -0.003693872202712282, 0.006372525798574993, -0.0022043018152753885, -0.04527486918657121, -0.03132478786798592, 0.0010491703350776582, 0.008713200007881316, 0.036618894058383686, 0.014456866928522435, 0.06315198817283738, -0.012368409358895063, 0.009981281893570861, 0.037575330447387936, 0.03129548350121423, 0.005928451862367609, 0.032474460769431904, 0.0015358371867804934, -0.03451977335105108, -0.01999708647682553, 0.028680358754644766, -0.002322045886485012, -0.08311719561226522, -0.041398332583280156, -0.0066884821572702775, -0.015006733786730495, 0.005293511442263052, -0.037354230788483975, 0.017908849882217106, 0.022608150083536647, 0.027551274535621208, 0.04964016890391346, 0.027959060166013714, -0.04179108383433412, 0.006338596753257193, -0.04935974055515581, -0.006982584317027455, 0.00021566627433725755, -0.018535727367743223, -0.013786677865804842, -0.035745211059006424, -0.054118826242401996, 0.00856375003388984, 0.0376616411709326, -0.030823276372279683, 0.05632439095220414, 0.005983443118483419, -0.06606315329217609, -0.018217016790740413, 0.024985453920891906, 0.06156258773854721, -0.05010149660959409, -0.011693923261393187, -0.062434486720972696, 0.030931985852038713, 0.03858420708156836, 0.005466507280807955, -0.008618499897791246, -0.03940561919713775, 0.018848903515659193, -0.04795199380877849, -0.03616219010325521, -0.025393486311775734, -0.0005316629419990955, -0.023936926861690445, 0.006236724817455975, -0.041402753010796864, 0.02589610307094204, 0.0037782679479585954, -0.07645008422587357, -0.001939292934583975, 0.05315644227581925, 0.00032512489809113747, 0.011060716018612193, -0.03420672543470896, 0.04774112817478683, -0.03720715487521094, 0.047321660923205236, -0.03051656088228274, 0.043359171410497, -0.040995780454288186, -0.03193136855243585, -0.004159204540012843, 0.01407008835128247, 0.027705775432171537, 0.037209257569873595, 0.02551170378367514, 0.013465296308026797, -1.5429144449680045e-05, 0.02194544883402673, 0.010588526981456101, 0.046857993823547384, 0.017829278524572424, -0.015469866331317318, 0.01151855579071382, -0.05297917872170339, 0.004964981704141709, -0.020661179599578146, -0.002451777532827503, -0.042536495852133205, -0.007755170828492804, 0.021210681255928177, -0.014197223408240313, 0.024837588926117482, 0.0278280153233007, 0.0011475715809504614, 0.043037339224761786, -0.00780499205192544, -0.02518458988341412, -0.014135788940900939, -0.04444124318276995, -0.054016536546300634, -0.034099302115737404, 0.02917150435139308, -0.05308183612782863, -0.05165618291529786, -0.03432716693225907, 0.029137017354082716, 0.02449058881720085, 0.031346566795035884, 0.007216395252047302, 0.027140348246400516, 0.010233502033607057, 0.0038677386392154084, 0.023920011603450315, 0.059812861148561575, 0.0022147667516118213, 0.06417614431102979, -0.006144109984115213, 0.051890734226751584, -0.019381656792883124, -0.014444442099476491, 0.0341760628179983, -0.01184829316834197, 0.007969839819992735, 0.024203640602674742, 0.01350193564907138, 0.06774842139795823, 0.016760076063503132, -0.01455876574563842, -0.044597409774678, -0.005965278289559568, -0.0106110116371154, 0.018816205394308567, -0.02389466202680981, -0.09304042695575718, -0.026195693071275693, -0.003328650993743347, 0.05027908367279303, -0.025586400794513225, -0.0716993971399754, -0.015137443374897669, 0.005799374499022873, 0.013483326076409738, -0.05036831912654175, -0.026879964569960342, -0.07200206289503315, -0.009291529746272661, -0.00032708447431179996, 0.002634613806198758, -0.026720160060376287, 0.014831866725950004, -0.04131301331143406, -0.05673920131505779, -0.02472208405983444, 0.05879355672863055, -0.0004385526490997744, 0.01230359156432597, -0.025328946432114977, 0.0063052028630976135, -0.03333120108391044, 0.018684341891596942, 0.030630289738284928, 0.013827144282346854, 0.014515895816816199, -0.006650750373944518, -0.011870937567686268, -0.02165599507640621, -0.010455976354767915, 0.02791836088136045, -0.023224491423490375, 0.05122649891946596, -0.002841847674184444, -0.016234032164947138, -0.002319513173250188, -0.044956921980588885, -0.05131697543813063, 0.010006293278361614, 0.012330385780861947, -0.047490007381838256, 0.03292022103860924, -0.013223841949178153, -0.02136605352847755, -0.0008463221482648744, 0.03479692709916324, 0.04789200848863673, 0.026512841346147967, 0.041402601196805215, 0.03666013572400877, -0.05837997042035416, -0.00035195279929901846, 0.0007421086213932693, 0.009220069320096098, 0.032177415320047795, -0.01690356468468221, 0.0020962195563653755, 0.016133931230476888, 0.0024057915870467845, 0.021500539026504624, -0.0013263427694096123, 0.04520738383059099, 0.0023522286467021446, -0.02962642315572629, -0.07493722114085444, 0.009274243584691762, 0.024096086578617972, -0.014573256289723112, -0.021745561499129287, -0.003837211555728911, -0.003848021424247923, 0.0007196459777235415, -0.027785682264963828, -0.011227855970143199, -0.039486757574886164, -0.021845032500412052, 0.00480013304768488, 0.03297220905726019, -0.015305160724260528, -0.053260203698048715, 0.022744549438974842, 0.019785798190122196, 0.028792996902911372, 0.036559137569331365, 0.015179871751199496, 0.01244257204242631, -0.06564713790555489, -0.01820256439805181, 0.0019438561183134336, 0.01215695536543661, 0.029135685325929646, 0.00012708136607335937, -0.0035887848715945862, 0.00761934485659318, -0.04824257716557489, 0.017190189461099938, 0.018127441979764923, -0.05851166926743259, 0.045925720198745974, 0.0061697016184177845, -0.012038352426429014, 0.02416751240236374, -0.007544980428605972, -0.048898624894895514, -0.007762699026868499, -0.00188917259505334, 0.02334593100770175, -0.06912329269585844, -0.026326385211886343, 0.01942927856610177, 0.032765377860532435, -0.025351448034941514, 0.03548060523713817, 0.07996828152402138, 0.05378759513588525, 0.015304460739872674, 0.004841721580535618, 0.0651579851373533, -0.010845625531765633, 0.017926903143797548, -0.024865194973974606, -0.010018490342399072, -0.051210381794430604, -0.0063228283523982095, 0.03848644502936834, -0.02495817278763482, -0.03554932506689068, 0.0003035828535880386, 0.044720863864625766, -0.07283358592762915, -0.025763557408852732, 0.01804350178126259, -0.04525916878418612, -0.03087292862959327, 0.016890642719804335, 0.006644945960631868, 0.05103176357904997, -0.028690571715064117, -0.02349157602683207, -0.03666406952647047, 0.03933402415437864, 0.03310781725260428, -0.029177198044979293, 0.02702743858169564, -0.0016247041849735265, 0.02749128144548188, 0.021479501506346355, 0.04100449126850208, -0.016177981849709748, 0.04068128498410257, -0.03045361843064771, 0.012518377290962099, 0.004502476966229918, -0.03237062421520531, 0.007777584982420256, -0.04572875890295289, 0.0297716078035051, -0.0041862633160941, 0.011284694612290471, 0.03526365025227816, -0.005625952472555742, 0.0047736537646365625, 0.028902440515400796, -0.05173846797726007, -0.02293324547272178, -0.025028241597442893, 0.020359798820343136, 0.018950718038348482, 0.010330481780502799, -0.03676943227620284, -0.009652119319950282, -0.010900381043634944, 0.022593431362578797, -0.018145042998678248, 0.061008771968577256, 0.011758170604351968, -0.029292554489137704, 0.01857733786897081, -0.06483116510515574, 0.028261527375664997, -0.007756430393117088, 0.07320287853479808, -0.0050863048214077455, -0.014081475283452976, 0.02227221555278466, 0.05377276467938246, -0.010039319983905228, 0.024467567746195563, -0.000910921488631018, 0.029232531123948975, -0.020322391402546054, 0.0022959135299324266, -0.006602513525015889, -0.03164254040445227, -0.004822164978820946, -0.007560440493548586, -0.019632439151389607, -0.017903110751186172, 0.014384773155777039, -0.0017743778638947025, -0.013361952121339846, -0.08835207573184659, 0.03940216953637207, -0.008385204723116458, -0.09198794622850377, 0.013596144095023787, -0.020331473766418473, -0.036927223221769626, -0.05930635360532665, -0.02779553133179956, -0.0048192480147144015, 0.068973613478601, -0.032453960085565815, -0.008494110253831138, -0.005981967974233847, 0.05777071002535412, -0.035864174641367194, -0.005483612481219899, -0.0193362129264717, -0.0220803761616696, -0.05342978690575192, 0.004553319238985557, 0.02808219567791317, -0.041349466305242784, 0.009868719338874269, 0.025389821698599886, -0.06198236426971348, 0.014051366268106432, -0.05176941177575887, 0.007520646706317931, -0.022666063550873028, 0.0016471056408659407, -0.022511699642230664, 0.008249153130504285, -0.052261798131774194, -0.0019015238575151952, -0.025383377793598533, -0.0005627063073191417, 0.014250855939723705, -0.002106474248949486, 0.00485566667247458, -0.006997836505382873, 0.01787223673626606, 0.031821525626735264, 0.04392393790759886, 0.01828106875943795, 0.055158666594602036, -0.03155733652814337, 0.021396514592139784, 0.03044927671945577, 0.0437150510251324, 0.03644146741905808, 0.02246549862547271, -0.018897570111653137, -0.017135325176711628, 0.018269457857250784, -0.044794081906037564, -0.0006053316156140833, 0.01419766660930227, -0.03730115300374363, -0.022944296793010962, -0.026994214633824634, 0.02009700622350624, -0.030452249091681254, 0.012803918968967534, 0.012464433476752055, -0.026807914257007195, -0.024705813653216963, 0.08103160257912372, 0.04325008996287298, 0.008220236017197891, 0.06756035601989532, 0.015982696921125937, -0.02706291725605258, -0.03315890754229484, 0.008180541681448493, -0.058748865277956516, 0.0033132050719494838, -0.018553758990914614, -0.03798794951826333, 0.0005694433107625862, 0.013191295369500488, 0.00936781527736304, 0.028783515201507126, -0.020486772281918822, -0.014910762751660167, -0.02034652202567177, 0.024119387935737244, 0.008475764122883984, 0.00198140262235459, -0.0007643555024034075, -0.04111751291202958, -0.002014509498715809, 0.016146874499167057, -0.0022402919964668202, -0.005154094326828428, 0.022760110203592004, -0.012342958014092416, -0.016736413088264856, -0.0004060514966732276, 0.00029221223678524785, -0.011417054347676578, -0.021808787631605694, 0.031020219993909106, 0.01519779777927508, 0.02213232886408425, -0.02573193140394706, -0.008896541936164416, -0.010508281828083338, -0.03179688736214475, -0.01711000233142099, -0.033199437191908994, 0.009588430258660852, 0.01369707618716735, 0.012986528888189392, 0.018199056524192563, -0.014790595112319333, -0.012491711299531435, -0.004973522996312428, -0.02610381812083688, 0.017878693494987333, 0.022981200865093063, -0.0656841576274024, -0.006330636956291156, -0.03071085635551733, -0.0029391384725188205, -0.007427561513204247, -0.0206718590735725, -0.003123990914104894], [-0.01015303986811999, 0.001030841163751943, -0.027896268238050227, -0.0011696489802250163, -0.0020101945605100445, 0.11856931599098472, 0.022139948623062, 0.02010318930290502, -0.07440098355457364, -0.024334610310945675, -0.01504521988721073, 0.0024305891980669816, 0.005406700083055913, -0.03490746875227754, 0.03472999107678702, 0.0189056541107092, 0.050226018420700506, -0.007528573697391188, 0.014537326896943011, -0.04360058268358098, -0.017213792837196602, -0.01072437051600063, -0.02595787160601739, 0.029576801982920713, 0.020457348401371686, 0.00821186754818479, 0.038779717984996735, 0.009421067322287495, -0.06387534123003841, -0.03722260910894021, -0.01414308697758453, 0.0033720089016298985, 0.015931488033158428, 0.07611052555826757, 0.019082747690929047, -0.01660748196285279, -0.014246525079155262, -0.038513413513461006, -0.03094962770161998, -0.01570520766679024, 0.04489522558640853, 0.0002567895852848413, -0.04174574471840873, 0.06879259625923206, 0.061979001989023404, -0.004849863429026936, -0.01234069149504951, -0.07207391972286795, 0.0034770331712498863, 0.01685530742344266, -0.005134639533506115, -0.023779700000676668, 0.006508402231971401, 0.025607084496068955, 0.0396943832799847, 0.007181697647595088, -0.0007539302310683709, -0.030684398585970524, 0.024726894970491638, 0.05250006381913063, 0.010873496742065614, 0.028953204337900447, -0.018502998633203777, -0.015242660774777076, 0.015247296667607742, -0.010450410598708089, 0.016938347960562865, -0.02569227917706604, -0.007629801890255635, -0.012246135126781224, -0.023498317056226653, -0.026364527594153354, 0.020274173129264716, -0.0034009558857580995, -0.005779235719694523, 0.015160621095489882, -0.013882447226564485, -0.0015927457765849834, 0.03639079159009473, -0.050186904881289685, 0.050355428385891174, -0.010570407234994753, 0.04352567388295576, -0.024643680349360358, -0.012388351983918359, -0.030915305284279212, -0.02654541129387408, -0.010940836334525446, -0.039294264608197016, 0.007691994464038799, 0.02834384329259591, 0.0014505805429562272, 0.024970048225222558, 0.025930407601876787, -0.019779302648881614, 0.006259058738724194, -0.01834301400882257, 0.0030892487288715163, 0.08790852966328686, -0.009494969425186357, 0.03701191438854383, 0.01072055250410467, -0.05387462366025633, -0.02159032557471155, -0.008349815443371688, -0.04090170120125939, 0.051378239226484684, 0.0032491222167340406, -0.02393396130357987, -0.03295694784334419, 0.012281223572794018, 0.00014793828713114202, -0.030208981941263393, -0.017060281574859615, -0.030350878380982316, 0.05738389409759073, 0.03177894772941044, 0.0004082413570973475, -0.013297060457557255, 0.01667702391895596, -0.008367475530735783, 0.009864886776324995, -0.04603567689435302, -0.0008771886533245482, 0.01711053408672908, 0.019368122972228022, 0.01864882327228601, 0.02217572614229736, -0.005411242092449385, -0.0250094744278004, -0.08186124140065852, -0.0420830714697686, -0.060041196206686145, 0.025775521819437795, -0.04103673914682439, 0.004199677006784073, -0.0007699309685163178, -0.021409026024850706, 0.006039382839497312, -0.049684765633317154, 0.0023539936748808443, -0.03760909191396803, -0.028906824164143592, 0.012203641272825923, -0.020506909252057816, 0.009623301470259494, -0.05670506068012822, -0.016108375413587644, -0.04011232295166115, -0.04135667312443743, -0.028768780888598015, 0.02533396853500854, -0.018410725825082987, 0.008460965301370225, 0.06652560795281785, -0.040959934283271555, 0.03394875839002846, -0.006840288626741815, -0.02032339316312763, 0.01970024800324472, -0.0482674270102825, -0.015345294154594456, -0.01200026384138556, -0.0010104617029862394, 0.0046098342301606355, -0.013115875854833738, 0.02231543613213669, 0.012322021747504004, 0.010945991076882775, -0.033551280618276585, 0.00922267530746998, -0.013529248107285435, 0.028167271695776774, -0.03258354852861697, -0.008916674580936411, -0.03319966916181142, -0.012841301642614386, -0.05478832677240397, -0.0042816361271833265, -0.0042754408009425815, -0.018092786421494846, 0.01463542932219392, 0.030788643518782327, -0.016444223762838085, 0.05106940275117795, -0.0271423084934017, -0.012326789061520222, -0.009392655772957134, -0.03865452087076049, 0.021784880401347052, 0.03573001357777589, -0.017813897703711647, 0.02050748892525574, 0.021342604938274383, 0.0032139406621484057, 0.026062365162938472, 0.01664329544076443, -0.016660359601583796, -0.02774321562653661, -0.04101555032436639, 0.039143637877529794, -0.01542282908661605, -0.01662961062159951, -0.05223123918944684, 0.050489092278077435, 0.05359134137128009, -0.0004109275142334546, -0.04395294695428482, 0.015153006890299754, 0.012772555827629569, -0.013967625138660797, 0.026960979886601878, 0.009892612853825512, 0.015947209351902962, 0.004284250659819385, 0.02486826696067346, 0.048796208074554495, 0.05188242094115905, 0.017690472915675912, 0.03554061933465908, -0.044018787209512744, 0.04927736618760717, -0.014917542776583637, 0.010212679580718503, -0.012921330731530845, -0.05045675640197096, 0.005666534725409853, 0.018276787728401613, -0.019581064356578838, 0.0038088368313944666, -0.01587930451559898, -0.04257858105215481, 0.045706034705188414, 0.0323828191513969, -0.002831858845031593, -0.011127040589427756, -0.004110248819159652, -0.06621398382493941, 0.03265892788286002, 0.024556710627969866, 0.016779142706693867, -6.325327385600654e-05, -0.001614099161738474, -0.010117097926408459, 0.1000946071370491, -0.0038411404785507614, -0.02995254698766416, -0.026732268803495787, 0.05167069029807976, -0.021901973298227524, 0.0017803397680634997, -0.013926670731323382, 0.017014259558018326, 0.011809219628670558, -0.06312106317276073, 0.019113411491298367, -0.030457708649848536, 0.01674304877502875, -0.027724717356263535, -0.01202416282116246, 0.03693359929394971, 0.016947080948314444, -0.0225061671018998, -0.008650955622006035, 0.07152007062300192, -0.04393996774311808, 0.01137628474889444, -0.030080163450784292, 3.876641081563626e-05, 0.005504166382827479, -0.03339489669513328, -0.028065109630249864, 0.06117417489761348, 0.03467801510749316, 0.023076026603347004, 0.0008944909678732897, 0.01245468968384475, -0.0019048722690804178, -0.024011992395192312, 0.009762260086930949, -0.008078214601423746, 0.016943144010121616, 0.02718770287853543, 0.009884104351438043, -0.004629974109525276, -0.042943669401976206, 0.054660156191598426, -0.0235049545255522, -0.054454273119515104, 0.07165803220232919, -0.06168281602210213, 0.07346780972684466, -0.006497694518980802, 0.07267241179913564, 0.03244599762099451, -0.02488779431635504, 0.01498243036861498, -0.004627919955770931, -0.016832521233928175, -0.011616428542766156, 0.009734886266631083, -0.044055916726552805, 0.02486251400626638, -0.018742611785652022, 0.01013933031642858, 0.03247559013218589, 0.09459083512993467, -0.0061814596352802505, -0.014654585762934658, 0.0068743989763212845, 0.04296309871796011, -0.008786282849572044, -0.014964814583092335, 0.03715757802916117, 0.029389127468180277, -0.07018910235282234, -0.0022671280623205413, 0.01702884724788028, -0.017284172941825722, 0.0012175066668610995, 0.04875852927184998, 0.04766466836378955, -0.02208446443692416, -0.0055837626816742855, -0.006097394104905557, 0.013027960294989534, 0.024429734394069317, 0.024883868782869533, -0.007717257254975246, -0.03598320922495605, -0.016888323782649102, 0.05484118304136722, -0.007366200362350739, -0.014946114625513662, 0.004642456665663159, -0.010155210627039318, 0.04932915397928191, -0.04401419432867196, 0.03180959620265615, -0.03293197760678114, -0.022434178409792553, -0.028743584627940275, 0.04710926832974503, -0.038305187644416726, 0.004451628705445715, -0.02339983274538951, 0.03305215056312805, -0.015179774895651785, 0.058123001658862, -0.04471535309543776, 0.008274630497605334, 0.04139155060610064, 0.02658140669499307, -0.006459641351841069, -0.03463665666542799, 0.05661594041155597, 0.01988236681056074, -0.0042501222710711675, 0.02970648665182408, -0.05734162638460729, -0.02675330551477144, -0.03563321082571466, -0.0002707623407053085, 0.04510284739174235, -0.013937688461664812, -0.05008320801695838, -0.010644801499488123, 0.05083001174157156, -0.03976794940675296, 0.018139829221634006, -0.061355916446978145, 0.02055241640030546, -0.004017452826107479, -0.01145350088096255, -0.03550841329530561, 0.003463327781951752, 0.015623547385026039, -0.020466679941858332, -0.01164813680138252, -0.025110281479065223, 0.02432365597470158, -0.015583979035415994, 0.03913690220467336, -0.04257360008820674, -0.0293608263563574, -0.0017663957614694203, -0.04741354278251331, 0.00528997822625279, 0.053516330894750094, 0.04895061821796999, -0.053420440027008256, 0.049001916875010904, -0.004338618286564839, -0.03372035456416778, 0.03325273876058476, -0.02069657246263677, -0.042988807817081226, -0.03648131152217954, -0.0007117611085157328, 0.017628690009600986, -0.0729281083858234, 0.015534189076880709, -0.016398893153474668, 0.04389801401914385, -0.015886121428085515, -0.0004887718385654747, 0.04350479550677641, 0.002088198842677633, 0.028648466127904785, -0.0403452478650482, -0.026325241544903948, -0.019143607736920174, -0.020065194518331657, 0.029406939206013498, -0.05528488769844319, 0.030329163523453263, 0.02481229431576762, -0.04371418209139283, 0.02426866658848317, 0.02039807394896405, 0.018030373666631634, -0.03275778986270153, -0.01553093876937561, -0.0424557899079492, -0.020600943828969886, 0.02841623122694168, 0.028430461630210534, 0.09329358273477556, 0.0017256635673308894, 0.011417923896669194, 0.03286048049594423, 0.019733760833816564, 0.005115354932786326, 0.0015268059095245139, 0.049085226841407294, 0.058275065674785645, 0.021670676575033944, 0.009290098318585781, -0.009728897246884862, -0.007065134664984379, -0.02043263288474092, 0.0700185213023341, 0.03947875599110101, 0.008009399880434795, 0.055266781514151014, 0.009168461281182224, 0.0017677618999300294, -0.005287649182379124, -0.0030378090991815335, 0.03103683754569402, -0.005159326014286588, -0.0065902036265972005, 0.03712861378585721, 0.02613132376640102, -0.05259115250311066, -0.0056828958855907295, -0.0027900745978634203, -0.0022220822241819232, -0.025350409644898375, -0.021815447169482943, 0.03550327811407822, -0.0024678312109125376, -0.024924483760002825, 0.021781982477757054, -0.02973801694315856, -0.013752351075943766, -0.0076854537598554686, -0.03681880771639984, -0.03589204439776908, 0.0010585516409445783, 0.00840784262945558, -0.08402636641160798, 0.016737225291732456, -0.017795249565654703, -0.052740612578901815, -0.053811746029679745, 0.06765916976728854, -0.014079490631870889, 0.009072545151075787, -0.02253194195337572, -0.013944168967239979, 0.01437332335301171, -0.007216878213415799, 0.0008646543238635188, -0.05041576029579501, 0.06969475184966888, -0.0013431314133204187, -0.042799521063519, 0.002808481239870063, -0.05021936765999202, 0.02716968766290912, -0.0015481668251448102, 0.01533423481757028, -0.06072601253104493, 0.018588933841098262, 0.021952207080363228, -0.02171093174679372, -0.04394316386979369, -0.04636451536693348, -0.05803398931487645, 0.05026496782934799, -0.002687812274459688, 0.009765400016845845, 0.029750169807261875, -0.0252729543692774, 0.024124517182822, 0.0037470186555374364, -0.0855823155125592, -0.03596915974718685, 0.007490168606309891, -0.007186342771062757, 0.008445203794189041, 0.07930379321199899, -0.024229628304623854, 0.03333107657742417, 0.03626942171201965, -0.020680971735459366, 0.041701822172982905, 0.01696440424561776, 0.003958914362789216, 0.023411283825373212, 0.030675056359005328, -0.011045864230569663, -0.06762270458547572, 0.02993501706823505, -0.02210799295243436, 0.017756388980225964, 0.0560352608229367, 0.020763605403481683, -0.028210719294663872, -0.020917047379858382, 0.006839017604636636, -0.03375211212934924, 0.016395310569139954, 0.004127255297244804, -0.0463385379286631, -0.020969994218131362, 0.002630550572732159, 0.026729187980745722, -0.004258123065917387, 0.0014228444572740116, 0.04198370514255661, 0.012408725397309417, 0.034086908539952755, 0.026252450305474635, 0.06324317605749297, 0.025758858277202996, 0.010444861247085675, -0.001066360805031575, -0.03660862695508929, -0.0374631831701558, 0.016593777650845964, 0.017538901928272965, 0.0004229874799809748, -0.0129756297049408, 0.030616368708697883, 0.05249241257465889, 0.012344331787684681, 0.022122535987706155, -0.042492566613534025, 0.020626292402831765, 0.018520932675914113, 0.02599014821206337, 0.039239525724734714, -0.054013369661217864, -0.010531655318856345, 0.04164449618117891, 0.012390698072273698, 0.038337775692589116, -0.012214683589736541, 0.05496496949568891, -0.027400854330441957, 0.10015628566328927, -0.01511329331597217, -0.01326265514473395, 0.04338421911043217, -0.0014541225353393375, 0.002969301923075897, -0.026966032086696116, -0.04416161008506396, -0.0027882425832497955, -0.04060158016436306, -0.038360516660103275, -0.048623561482371506, 0.01385639058945707, 0.023791716391607563, -0.035042952986419004, -0.03974507175663447, -0.017269880161187818, 0.028605023989592998, -0.024361787609453626, 0.02118327420627269, -0.041393365501887616, 0.01501808672566414, 0.01655171414107287, -0.03216574897231152, 0.013478440508926243, -0.0402974335719754, -0.028938165756713485, -0.0022461311271102773, 0.03098402126599095, 0.009204925916611945, -0.014132774145570346, 0.009641047583226868, 0.0037102996219085032, 0.045187015245371734, -0.021466029304243343, 0.03629091598781914, -0.04037007995348967, 0.02630068972002036, 0.007709915104736113, 0.018394968208106224, 0.052144811271388015, 0.0008574029327243892, 0.01918764888264248, 0.018203787460614254, -0.05632179546594161, -0.00018593777576297182, -0.03158729626208494, -0.05245389029127688, -0.022500339079148543, 0.0024219774287067546, 0.010501549744664206, -0.017228450802697196, 0.024442940971235047, -0.010582183854567582, 0.050680966435229735, -0.0472391170640831, -0.02380055244490008, -0.013989959549435552, -0.005305700709999072, 0.028845678708233388, 0.04605309575037641, 0.04177317059757487, 0.00886976290821489, 0.031243627229238985, 0.019712750970535067, 0.06505690497814556, -0.006824106761560578, 0.005536754706552405, 0.010211911069640712, 0.013089567263331915, 0.0017610583322624851, 0.054005606275472115, -0.02768405514010655, 0.020376304465766253, 0.06960485840610407, -0.03721858939839902, 0.032018493344214395, -0.05261709644632544, 0.06776499898015363, -0.049525981204812324, 0.04146784694378618, -0.05288595941300466, 0.00266548622136532, 0.05605853772606208, -0.009179389880902517, -0.004198121088030984, 0.009135689832664606, 0.03885323727095904, 0.059391754545477196, -0.0003625440136304772, 0.006803256331490927, 0.004767451166010097, -0.023850071254632295, 0.009725547490181048, 0.0224022617808219, 0.01972406894682954, 0.007921367368592776, 0.00047137452904760964, 0.02226833734651263, 0.00018724877171945125, 0.06517580565218764, 0.01063605246148822, 0.0745751073667017, -0.053869292648454255, 0.007003887056237059, 0.025665773023541685, -0.03869435400162277, -0.007176017639508744, 0.007945416780121745, -0.06053080482044869, -0.014744972780694079, 0.016646864955235777, -0.06344058731272965, 0.06858724481504037, 0.04256708450446997, 0.04268714611637644, 0.03827902721665556, 0.041191641440769866, 0.039573645269911625, 0.03633382301200207, 0.0003766394517877164, -0.025530550321495322, 0.02923890285721633, 0.012347023317954928, -0.044093608526162675, -0.018011320581198254, 0.0022513189078672254, -0.0030204845696608675, 0.02341655873716331, 0.0027505918085683257, -0.027321935263040317, -0.000501970784010276, -0.00017806742754677106, -0.03746169251568095, 0.038388400986998084, 0.005718052006654355, 0.011073068808792386, 0.04410563448347062, -0.0046574814216608865, 0.015674359403776313, 0.01104784356799879, 0.05993759188595399, -0.014744930877363803, 0.01376350722071402, 0.03572282064451309, 0.008779254412660073, -0.03268576647658075, 0.004970474245815747, -0.016066464658841, 0.0006208023690643084, -0.022024535672333548, -0.03697914358716115, 0.010221668543292792, -0.02497625096519947, -0.020861905384386564, 0.005148659273672385, 0.045050233122352956, -0.02417622272454254, 0.020820832432003892, 0.03637898750380775, 0.006562573136838671, -0.0163932967813544, -0.007178670776047737, 0.02015261221753389, 0.0017950649340300086, 0.031026116923085455, -0.01759086868898034, -0.025595781451275283, 0.03817522804567382, -0.002112147125116982, -0.05651316946305708, -0.036575599123547645, 0.04463583117057854, 0.0248115393228615, -0.025048624011437055, -0.027279334489460013, -0.036562048024610536, -0.03130290866105127, -0.015056650190672385, -0.0016393688538951855, 0.054363010196031264, -0.00929746201310205, -0.01524593161137663, 0.06080675063083209, -0.020744039591753652, 0.005899208741933529, 0.025528001978533204, -0.057916975315925594, 0.02641106277150012, -0.03604377922165894, 0.012250205113206444, 0.009928299209913111, 0.004913066499356737, -0.03262867380396605, -0.021589434243820305, -0.01417259288638303, -0.019135697728212657, -0.05165121204260358, -0.08337338490536396, -0.014767697539757187, -0.04100163327699655, -0.002851158158039386, 0.018922558781055473, 0.10839775592029938, 0.004160639945101454, 0.011878910054102276, -0.003646318994462567, 0.010722425291487665, 0.001167123370420643, 0.04712942620403465, 0.0404593918612136, 0.0163842779285022, 0.05018796530899244, 0.01772126476435421, -0.06651392503474839, 0.0628180398762673, 0.053468093657555796, 0.005998329219366668, 0.035533451402980545, -0.020083862543616087, -0.010509671392208875, -0.014958354837725715, -0.06051233170764324, 0.09065779813041598, 0.010689956278195866, 0.0016135327834780665, -0.005429051000611621, 0.01538259621133793, -0.0015386483252059575, 0.008786469947630495, 0.06869917919314943, -0.015383126070342831, -0.007731482494523022, -0.027063305868062545, -0.04785135250685925, -0.041215153974000454, -0.04966505766469876, 0.018039929160023865, 0.0369269086034058, -0.002388612995377176, 0.012281396164136073, 0.023331529865730657, -0.11469678864162994, 0.01924867890074813, -0.02008919409395083, 0.01637346980053507, 0.01830050509961667, 0.01853866795644264, 0.0049959073964135695, 0.03009628613453847, 0.017336287016862652, -0.023800322100489286, -0.0576885596822325, 0.020457517056611113, 0.003061675828534065, 0.027336826084969814, 0.0025168088383118984, -0.020371851639325856, 0.014448946801106742, -0.033772126433957425, -0.022418066124611984, -0.01832915150277681, 0.004026440368662286, 0.03375609171432216, -0.03115264283692697, 0.0177695630082554, 0.006262575589226443, 0.04039196379916408, 0.009233148536663856, -0.04031948988037164, 0.025954433371656226, -0.00866639280286472, 0.047751343917679115, -0.01466945454009921, -0.019107564977168617, 0.016963521747445004, 0.00798826339698559, -0.011942135529303562, 0.008925874540781555, -0.004417229243507315, 0.014540059323402446, -0.05262232972185011, -0.005758445890360345, 0.025022086925323175, -0.0088246004890455, 0.0013021820207053077, -0.05450140177306701, -0.00354518727425241, 0.003918840110059738, -0.012525827156963291, 0.019889649567411856, 0.005324125461427035, -0.013781634889515896, 0.020068008044571303, -0.03726099607035369, -0.0037410293285305065, -0.02544982175520219, 0.005108144484653938, -0.062112963233675086, -0.05059086986600131, 0.00987961418227097, -0.016185688504441346, -0.015174897808725808, -0.02088885160166976, 0.01927010177251419, 0.03162119149464245, 0.010549017471333634, -0.01417119133662854, -0.012151296027075926, -0.0005469990843245198, 0.010030862534548865, 0.00896730142841334, -0.021909221470815737, 0.02809550853296408, -8.306524023809517e-05, -0.0012091052352073194, -0.0444450163843177, -0.05453754979707345, -0.01396925846954064, 0.0002773326816046058, -0.05610502253120422, -0.028635943021830985, 0.010661834066600226, -0.029037620839389655, 0.015139170719009491, 0.020463718107632624, -0.03106101718516608, -0.01040879568588795, -0.012873555237942038, 0.0014055119433325958, -0.0045527274824216785, -0.022860969530141516, 0.002557105439993138, 0.003035510149338197, -0.017100826914623134, 0.005358947256140371, -0.036688935258127615, 0.02612888817547883, 0.03081797637125553, 0.020681861390870034, -0.01826099220852966, -0.01701548456380598, -0.028778953184336566, 0.010674484239163765, -0.022379960811327235, -0.0022520726705501344, 0.00921664688797936, 0.021966089212811773, -0.0047284781186080855, -0.009616910679466378, -0.007615549399986542, -0.014047909623827976, 0.007451523080037449, 0.0673346345294699, -0.01420608998559701, -0.015550991520781189, -0.014961904123833431, -0.0005994323709865315, 0.01878486223357407, 0.012254508185530257, -0.054613282170860936, -0.028281566794656453, 0.01753982090334112, 0.0004272477634314466, -0.01851548659773727, -0.022577952652179167, 0.042951380188779045, 0.03554185523750142, -0.033794383403844136, -0.03850664577890465, 0.014135597229028796, -0.03792152271610988, 0.025513111273484226, -0.020871279469287372, 0.001769972231329449, -0.01512370977573126, -0.011843668006869649, -0.007520168739482192, 0.05081296479927913, 0.04231105664296747, -0.05816133738826793, -0.004749846573762342, -0.003161656491905871, 0.004405377934719539, 0.04977669490252759, 0.02202325726057793, 0.028469307252778762, -0.017930223382979196, -0.008636834774127765, -0.0522799836087357, -0.03299430780226192, -0.031841068814027734, -0.005762578972660625, -0.00041879564895088307, -0.037155770965868785, -0.0005414922405594326, -0.03480819481726788, -0.03104906273114779, 0.003817002082406703, -0.015785992350571827, 0.05385493220247522, -0.01540570424995071, 0.02863404732803712, 0.008425817746456348, -0.01735657976968747, -0.007334340161946817, -0.0015524118941669422, 0.004122949983302951, -0.047244935066274654, 0.021196527095712212, -0.008900075047781328, -0.04574030624224767, -0.005357595645667853, 0.0013265105021830921, -0.0006437604748843151, -0.010853721968342559, -0.014242577048827657, -0.03377980818618994, -0.03582916907117142, 0.032533423338327615, -0.018310079234247423, -0.02017964877194674, 0.027333929904271765, 0.08121200796776311, -0.025536463047281518, -0.030039842573846648, 0.009741776583344998, 0.0073789637378839186], [0.0008061803326397336, 0.03368893042906682, 0.03144395163767602, 0.042609031946589174, 0.037509946516911245, 0.06696443761020585, 0.029238240402168474, 0.016034588576769777, -0.006304769207010571, -0.0017730331485263581, 0.027634940002136316, -0.04037108484303681, 0.00802073586112471, 0.02696961651895689, -0.009880372234719189, -0.007874417603524945, -0.062326567477609195, 0.03691675453161641, -0.014390921948308577, 0.05334335920844405, 0.029668248368733167, -0.006749080009662629, 0.05006212249292442, 0.019392614763768367, -0.04031657165083216, -0.018792276116038127, 0.04971576953957292, -0.0206319973228801, -0.004403378361001062, -0.04287764419545627, -0.0653501205444166, 0.05817111752071228, -0.005202707923822555, 0.06323051200774693, -0.021079247469249652, 0.024525515192294123, -0.0021001668882423084, 0.03295122225017152, -0.042102919354183095, -0.0009227219603966941, -0.0362632049071422, -0.00339486002087892, 0.032509527093606036, -0.017905647542333026, 0.07389713256203854, -0.04615480748504136, -0.03695576144660844, 0.03292393532467507, -0.0017881691919908113, -0.030713546989910943, -0.036924240177451925, -0.00874806654939446, -0.04903303379532313, 0.006548844747258021, 0.019152616568209956, -0.01107273231986307, 0.06097165555678093, -0.05758243479822744, 0.027492901718970574, 0.011626141651148895, -0.05068143521847249, -0.00560806263577767, 0.009623904611933623, 0.03761976907803831, 0.017054375021152143, 0.00019811835124720347, -0.01689653319487896, 0.06192588126857526, -0.005204005039379188, -0.01460983121935413, -0.023636315887199888, -0.0933378820455942, 0.03852687964899336, 0.005264528306587949, 0.0017296400404098388, 0.006097786404450871, 0.04997531338097292, 0.010094110605581708, 0.04926141257409599, -0.021084819686162458, 0.026756100854401842, -0.04109361696600307, 0.03666427235827209, -0.009501895630286484, 0.013167667567927754, 0.004881798368439289, 0.022244096602708263, -0.02484073315493445, -0.009485907466153503, 0.021613802860622845, 0.029288916630979822, -0.0048837580986363475, -0.031538657091396166, -0.0036569313282508523, 0.03473006894189807, 0.036488558667524464, -0.004978319755382758, 0.05921099765441641, 0.0059452082545494115, -0.009382215308063536, -0.04379433556991019, 0.006882998990701191, 0.02880668194509809, 0.017421996159136498, -0.013051294864077159, -0.011464034099096604, -0.007046660189744192, 0.017201040810081985, 0.06132907540196288, -0.04800841593495927, 0.011071483090810248, 0.01799580093223345, -0.000681994165685762, 0.02440569304970274, 0.0020478413514306787, -0.002044499461807554, -0.0064382301875132155, 0.019291673977772643, -0.005863674076224676, 0.06883215002048394, -0.042861184881599956, -0.09219024757142302, 0.029842606122716418, -0.036576194361024626, -0.030219256079510207, -0.02618527872489306, 0.08329149579495, 0.06385445338791645, -0.010337593029704986, -5.163200431347603e-05, 0.021216041080845523, -0.0019090027136704586, -0.027444165170136856, 0.03713467737020694, -0.037603781624133456, 0.024769563827877435, 0.013093697395830734, 0.00871330520890204, 0.011570397430947767, -0.034656371706784546, 0.014622241969952755, 0.04184513343803564, -0.050178779501062365, -0.015201364796290697, -0.007400097819600447, -0.05499165791653846, 0.02647468786398554, 0.020628678278590145, -0.036581722483133086, 0.03395693244983607, -0.028542179003687256, 0.025332915430586505, -0.007645411221179592, -0.04157608891590476, 0.03598539906940333, 0.028930190676736973, -0.007368401912727064, 0.04026806173108013, -0.008065033813915235, -0.022403188884776902, 0.0372431405972216, 0.007834087126379109, 0.013764307191638108, 0.02952390433377197, 0.0022290558463524054, -0.006992535461629826, 0.0179978496914082, 0.024214924441350705, 0.0036440508923308735, -0.032732509251153286, 0.0020838584149707393, -0.043239904179216, -0.003985134030929585, -0.0088768890623465, 0.004753274971394814, -0.04673277345793616, 0.03468060720725573, -0.013602735791517103, 0.0031655108779341298, 0.055242945179653155, 0.00040297920874899154, -0.010021133042771486, 0.006742925934400627, -0.029871011708563176, -0.028351549235141285, 0.00624635606202998, 0.05336196213368213, -0.01248239061385966, 0.0576868055048393, -0.004757086606831782, -0.04834421263999078, -0.003451019018446607, 0.006258210124865372, 0.003793438827345983, 0.0139046384463683, 0.023010378457920394, -0.004905449849666871, -0.010804044678387024, 0.04383905613594763, 0.030298866486007915, 0.06187004581161721, 0.0022137786187429766, -0.0067788525218131016, 0.025024690539887175, 0.01767881620041627, -0.01623166044089664, -0.011528246350153948, -0.0541922713227693, 0.024450967664704108, -0.0049302910140126745, -0.024184308806321258, -0.010057920264444804, -0.030106660834626684, 0.028181360851795373, 0.020525580823499746, 0.009050056402082023, -0.005628445896131611, -0.009100497027372551, 0.05766161365052026, 0.010741179225142493, 0.0430409243336327, -0.04419771600171032, 0.014889126470653564, -0.00955446605251382, 0.004396857140004434, -0.0028689312663475568, -0.04646734565879336, 0.07284711360909046, 0.0293855029077692, 0.02301267449718264, 0.04346282271875344, 0.03488007671971673, 0.0023955211532144492, -0.05439784175089145, 0.05730829634860319, 0.02172363753897287, 0.011327056357710238, -0.005385739752538598, 0.0024549137082356502, 0.04259117359569025, -0.029223811855393772, 0.00757796050274771, -0.04388676169461083, 0.0490444815464166, 0.020332013128705004, 0.018852532422245, -0.038928156411799086, 0.010934197424811987, -0.005332069620341771, 0.01573642706338989, -0.03883553618362448, -0.008436220624947994, 0.0007095453887960117, 0.002253576487781978, -0.024342441963048942, 0.0026988026815864905, -0.030870446927778558, 0.040254978139998635, -0.01999185885275797, -0.04210871414274424, -0.010540097705808963, 0.017799133632633697, 0.007088467211846089, 0.06331325682873593, -0.02993899289796756, 0.04991378241066906, -0.014096053216545279, -0.02793248323080406, -0.005734568893785541, -0.04411980442509814, -0.019685947087129847, -0.03584978228505609, -0.026191200058144855, 0.0455214340286847, 0.019779298201290124, -0.02811052482969426, 0.03494465997556524, -0.005137840153836969, 0.013852394716497194, 0.03652840360183261, 0.0011797474183047364, 0.019399430070685945, -0.05245151489903019, 0.061843906526768314, -0.012423832035865017, 0.01634555063819021, -0.02634459513046193, 0.02922055022205893, -0.04880699625981898, -0.011675618720714105, -0.01836769968723189, -0.0612455237935144, 0.008620635373667904, 0.01660432486822779, 0.03267657624126177, 0.030731657629082997, 0.0567736281914762, -0.013983662062877465, 0.027877259153433077, -0.025269988671324992, -0.007133886134097829, 0.004424622520385221, 0.032088567047091746, -0.009798853494717786, -0.040893221091909335, 0.019130952566665797, -0.03013631460343858, 0.02127625527235876, -0.013458335697556065, -0.01098537184848967, -0.04942154185695195, -0.023587827489208735, 0.013116882412882568, 0.017204808629664264, 0.007919767524558636, 0.007985174053546089, 0.01097984924114652, -0.019901164576731446, -0.028351806235432188, 0.02440223380896711, -0.036579225868440715, -0.0193606866965369, -0.007855781924921864, -0.02362772677103098, 0.014870610015860623, 0.020384709546084283, -0.0001675224025293829, 0.024261246075738572, 0.04269421030986308, -0.0017830880084522861, 0.03015774851406247, -0.007214430592746748, 0.03958747891859166, 0.03174511197204021, 0.004090640522965934, -0.011739326936732275, 0.08340284834533963, 0.0052891881266376225, -0.010954581768877586, 0.005852621296008302, -0.01658717592403661, -0.06885896391306227, 0.017870708826724098, 0.02820638438735018, -0.010622216083516154, -0.03570407526843364, -0.0499964656802078, 0.06910437139642424, 0.011928310018703652, -0.021235813193022375, -0.010244131042474423, -0.04777102651041598, -0.021639385673213354, -0.03143886181064253, -0.015763299042919215, -0.03422371640485643, -0.03416113812733597, -0.04116530975743989, 0.025807003144682372, 0.049637875137877915, 0.05524906463021666, 0.04094569883306731, 0.06403242303200693, 0.005018568141920254, 0.0769740669211952, -0.006889921831696042, -0.01410786998284963, -0.018416546665787504, -0.01517619046856766, 0.04693252972537107, -0.010727048376657779, 0.08442922083398535, 0.062112902850625144, 0.018451166532083417, -0.012915986702221032, -0.06221709039606051, 0.014631249837568756, 0.00678035842456646, 0.008677709300344522, -0.009738145634239345, 0.00033323072147556365, -0.012896341275116257, -0.017018306327412726, -0.029343934387139878, -0.02526588890703315, 0.01060001706243348, -0.0007644274880697116, -0.023684216017554386, 0.008118369086233163, -0.05452888797781802, 0.009163515533223079, 0.04625729296113877, -0.04294209326438773, 0.07072254076190762, 0.000937480869952427, -0.0004045281441374688, -0.02842585185382883, 0.03169034578799068, 0.024990773434298487, 0.01517774733982203, -0.03802650342389969, -0.01307264497671036, -0.0062091098693206215, 0.03906291476754867, -0.018744709800276652, 0.0002486019721847036, 0.06891433564100326, 0.030866050612081686, -0.005421807461275888, 0.059716075055711124, -0.06302101720008713, -0.016030798277143196, 0.016441212151031864, -0.021493081137448425, -0.00601361979615698, 0.015859516862086073, -0.033213096508195504, 0.014622728240686873, 0.02857279243164525, 0.009901510061738693, 0.002396380672884467, -0.006968464488298354, 0.039233186562602086, 0.016615198207881456, 0.039348993914879074, 0.01486947827838154, -0.03996526709243051, -0.03501845081240181, -0.019926443901962795, 0.013336129529761646, 0.007430393655340416, 0.05586165268170602, 0.028051481575270786, -0.03662693591290608, -0.03300907842139468, 0.048741301186328016, 0.01807919418233161, -0.0011575223272295952, -0.058562241158029354, -0.021076132496507773, 0.0156816566070968, -0.02683462820189762, -0.010163095118314255, -0.023694594643910428, 0.006661278187541271, -0.012871243465831775, 0.026473548783776384, -0.0058478152040326034, 0.020742671356139965, -0.04398184349901983, 0.06406266510877534, -0.052699776422536676, -0.028372101696891923, 0.03597914860929579, 0.03148889121865643, -0.06672618798327962, -0.06915351059840438, -0.01946226350761449, 0.019934409003821957, 0.047746546554579605, -0.016765792496055587, 0.05615754987696718, -0.01999841125761987, 0.012724572210456088, 0.014730017175171514, -0.02285419169970852, 0.019613059868680168, 0.011368564044131476, 0.017617594787091524, 0.014420100423924873, -0.017239575143701863, -0.05220171722618091, 0.03669263403315713, -0.011754774811686592, -0.005794827090147857, 0.041161264172277466, -0.014437175303900762, 0.01910949150427941, 0.05688410380853065, -0.0022686422626577198, 0.008863038104754254, 0.004614961048337363, -0.0005303435283878638, 0.023961456463258694, -0.04958488512970541, -0.04858657336051309, -0.041266589711218465, 0.013658166959436351, -0.011744542490451928, -0.05983236319114707, 0.006608334204254759, 0.006156440486893331, 0.020328116505070125, -0.0739672868984494, 0.05376833977410342, -0.03464830343538412, 0.005496057624819183, -0.0021901848905186046, -0.014961144338196484, 0.018071949704563658, -0.06393842873010482, 0.010967295663140047, -0.0018137763809576365, -0.015563925121151997, -0.0005700100492111518, 0.029127226424351924, 0.015861054779522644, -0.0292921518086303, -0.06009086638761335, -0.022062854874930076, -0.022083094946809934, 0.03528089659868153, 0.0212455501352831, 0.058096832120707015, 0.04577359398532814, -0.020265692244300814, 0.035133502260198436, -0.04087039789860145, 0.06201848093375825, 0.006179909013338272, -0.03368574312140691, -0.020408085069426454, -0.019776982934099983, 0.0031463149262728456, 0.006060916707220379, -0.037789761072358645, 0.029396749350854665, -0.003695907513169225, 0.034899907644961696, -0.020643361103041408, -0.012562285265997218, -0.007475534146543615, 0.035708912651482995, -0.035317428948256055, 0.007094261203813931, 0.048772575662319156, -0.027509331747750325, 0.0036893226828428887, 0.014721598614583982, -0.06001831435284283, 0.015081073632437146, 0.0550872387849865, 0.037598392571103166, -0.024184292499053205, 0.02084015046077603, -0.010265574579954119, 0.0023259348398000264, 0.006396160799651104, -0.029358367934705074, -0.00356015719098804, -0.02868990119425304, 0.023500355633258932, -0.0017599114784240342, -0.012213881472141808, -0.008508854692710696, 0.03216534000091617, -0.029892812999193944, 0.025209906658893586, 0.04591892379003326, -0.001958781812918064, -0.027182781227588774, 0.031041583880031025, 0.024449165972358414, -0.051819658286311646, 0.016125296682808647, 0.00263924597221994, -0.012967864440876114, 0.03534977219608054, -0.04336533242979807, 0.0017721339984314785, -0.0084058499823166, 0.01796174384105251, -0.0123238148104574, -0.005033256759488562, -0.03596960640813341, 0.009433825811501158, 0.02160132837133233, 0.03794694665043989, -0.008483507499160214, -0.03644404798761198, 0.022152048718646823, -0.00929645380747648, 0.034551280538862146, 0.011106599073380831, 0.025822376482570734, -0.0271316258852647, 0.04550044654525831, -0.07951223770582515, -0.009723583051464823, -0.006017384850979322, 0.01203134388854832, 0.07679005706788203, 0.08872468106018964, -0.045731842178484555, 0.024097554023554908, 0.0051049523669478205, -0.048264463285461155, 0.046008363024496984, -0.03318454713253173, -0.013045570179972977, 0.03252770117442812, 0.008506673518283476, -0.03836593179500658, 0.014046401837606602, 0.02909552827202313, 0.01591641371771013, -0.07373609960307906, -0.023791675646977914, 0.02865026817689601, -0.004263625769000556, -0.0031292979010331384, -0.011049213962980713, 0.0035588254876105525, 0.0427696539443395, -0.027226308566212193, 0.008760358354132636, 0.008528813587412101, 0.04655331407719315, 0.020214494277642846, 0.037511678113394537, -0.004510871159766099, 0.033064882496138995, 0.042471736687084906, -0.021573554890802354, -0.06667427439218743, -0.0049917138276098765, 0.021244471930740607, 0.02823502889005211, -0.018136900323984476, 0.004797880184113961, 0.043853879481639366, -0.015480401907983419, 0.006691992013057455, -0.0614128612178576, 0.037197501808447615, 0.05214102088624345, 0.03454776966925125, -0.038283954317992856, 0.018853843225446282, 0.07119288175575433, 0.0371542680165463, 0.06979105190838987, 0.00255848877275827, -0.009965561437690318, -0.026517461565047324, -0.07335598276029956, 0.0441943274001797, -0.0020897238154267512, -0.002797490034322697, -0.003906794496005079, 0.012638848202309622, -0.008600663456340175, 0.032145761426459155, -0.02422174465711871, 0.042350177223286566, 0.01717987027015588, 0.04446320132505356, -0.007506991720839648, 0.024452435813324618, -0.004450632662468097, 0.06410215732038874, -0.02567262182261784, -0.011157219538025091, 0.006266586065165034, -0.01546300857689423, -0.03976774580620598, -0.0628893731989039, -0.037317985121660596, 0.010027709049933754, -0.017486977874811516, 0.025119302177690348, -0.005416756490620263, -0.03859828878324348, -0.05899653938634266, 0.06693543401230945, 0.009479492382484286, 0.04098727557991081, -0.038685627070320285, 0.007799288210200059, 0.045306114048927114, 0.04929779568940164, 0.0033870328627491446, 0.01036078411468602, 0.01134800064811772, -0.004148480590659808, 0.003399667894269579, 0.014666444539568838, -0.037844257850859146, 0.007755974020236719, -0.024159406878389446, -0.004406834467638411, -0.018267399133914314, -0.03794938781321395, -0.0010367842482668296, -0.004124557243127117, -0.037261453391359764, 0.0017278269147197748, 0.013485441036331758, -0.0356780897923719, 0.019511047726220827, 0.0027506475321865936, -0.007134476454540074, -0.04889988899598907, -0.04319677555640734, 0.017084694548574614, -0.007304728275055985, -0.0576731657537455, -0.017945240073469877, -0.008120631901873857, -0.009802913554059677, -0.0006692656630651328, -0.0028716472730558416, 0.03255528371269187, -0.0567186296194245, -0.011497525842484957, 0.008509631897147998, 0.005285236374557814, -0.011404524779761102, 0.024211047771929617, 0.04169096584304746, -0.007757987091402028, -0.0444655388268826, -0.016169698320512266, 0.01655253434815356, 0.03255915447606781, -0.0073131945115094965, 0.011307647898088025, -0.048472900775265844, 0.027699493525264445, 0.0244856277157574, -0.046583200478696685, -0.022775348740844713, 0.016109531513712607, -0.028639831163250567, -0.0016006554229182788, 0.047383086453472695, 0.0033289775222431605, -0.062139048984499574, 0.016303682944174544, 0.03140569549392105, -0.025877600650436858, 0.028461825068231278, -0.0022264165778686173, 0.021962988556885332, -0.009787338415780474, 0.041049547057233106, -0.014115201909780665, 0.0020649512187065526, -0.00924479918494631, -0.020974120090590423, -0.015537670341998995, -0.007303271750573541, -0.007142778729644329, 0.008065825861234648, 0.05105851254824938, -0.0438266955978521, -0.04274939655435858, -0.05085965603153736, 0.0022312825840828335, 0.07705389193878957, 0.028804224339424, -0.003895197057743312, 0.0050004494387678785, 0.03689393185948743, 0.0001605923031295282, -0.019238861808459365, -0.04563201216854111, -0.009871665344647389, -0.04251262457540526, -0.025347485850635645, 0.004918459722949839, -0.022036312602444923, -0.002181793659696218, -0.011654875789191787, -0.029809794575253235, -0.004145217642421838, 0.028258888435619155, -0.021070511305553957, 0.020629303149070955, -0.014475017817694957, -0.0028137467019246102, 0.023131091767325484, -0.04937954207926386, -0.00985061820277223, -0.021867870225957355, -0.008044764297973782, 0.04840091949464256, 0.022215005739424417, -0.04375679095717922, -0.012187844269360348, 0.008865627723393141, 0.019139532124859727, 0.003259817901812018, -0.01397345615768775, -0.037081716540184544, 0.016105489896183395, 0.006257253442356252, -0.00911394747582055, 0.023621710909294446, -0.029404037353614812, 0.014292753689859666, 0.045240458110601185, 0.006271892097252821, 0.029633569998042956, 0.01618750946917451, 0.012084963678761374, 0.02451643879836517, -0.01232383636098913, -0.02838142118960854, -0.06014806213291811, -0.006879772326267718, -0.05721024582861812, -0.017990004417427194, 0.017315949594886977, 0.0033869947804564815, 0.017454588121854058, -0.02143587474966386, -0.0038148599035567965, -0.02379439881089452, 0.027370650310643833, -0.03291514044144255, -0.012529199532756746, 0.005082206607425862, 0.04571352867062613, -0.03173205598192889, -0.005914150168883038, -0.058433912121838585, 0.021177532067206524, -0.038032086073658294, -0.03149104094349897, 0.008218043531321682, 0.040152050398768256, -0.018405234095923453, -0.02331270854260809, -0.08014461171667954, 0.04828435663317823, 0.04553692940374903, 0.02197931886996738, -0.00027422683592119503, -0.03712673651182566, -0.011907163956753761, 0.04135090117916689, -0.03105652509307669, -0.02979884590335608, 0.029419876108549795, 0.03415111023640047, -0.02423409041891717, -0.0008802497503564645, 0.002626414461351476, -0.04584024208849956, 0.0331159176680011, -0.029717933523118616, 0.03237244387250651, 0.012825983218363193, -0.025652199511605935, 0.01998199280326697, 0.025324956467355435, -0.01873652396456426, -0.07854544020604481, 0.02261824608418532, -0.016939849567509806, -0.03436667031360999, -0.02777396677371066, -1.6291878195517056e-05, 0.09321870870712343, -0.011038404415254948, -0.001757667221330913, 0.028850353258124288, -0.021857177043484107, -0.012246069125483861, 0.002518772743601274, 0.018990744489162794, 0.053631340805044905, -0.006536987738318133, -0.0062236277136904754, 0.03013412516483607, -0.0008007312576133247, 0.030110395625143838, -0.005036667804136405, -0.016718787685965457, -0.04011173158465617, 0.0638290704505462, -0.016290091520590244, 0.016294103841038396, -0.026620046381419522, 0.014431633592455041, -0.03430597741425483, 0.02493867361468891, -0.008106177989558889, 0.053896161923800645, -0.016215471794179027, 0.007682163264155905, 0.03868663949824896, -0.05023406446102921, -0.010907058925538123, -0.023983687507123697, -6.304629611038761e-05, 0.02062160957267279, -0.04622108669710117, -0.015382199967336944, 0.0032703495803395656, 0.017631076373073748, 0.006950148337591659, 0.019406818312962343, -0.032580478513951724, -0.01260420374647255, 0.02858352468171502, -0.022533246597418323, -0.03751103588299303, -0.050158709546023306, 0.01989233102113289, -0.05909648945691884, -0.0391440047362617, 0.0383187337737889, -0.08983790296578723, 0.05458067490692015, -0.010291845420905714, -0.012850324682761347, -0.008389714909270625, -0.026887229101251475, -0.019257677632641714, -0.01199223293272209, 0.05108609214261842, -0.03866788322022069, -0.01853187731941721, 0.047606542827077665, 0.01985790346983669, 0.0012658151011049137, -0.016084618819035012, -0.09156911149690194, -0.071957107727413, -0.05944888800305774, -0.0038639796482589452, -0.008332206847234744, -0.027163936332850587, 0.011727525232955864, 0.062305435494221156, 0.020395934349746837, 0.036518268558839856, -0.006978676005509901, -0.0133511413273834, -0.0601073041960399, -0.02477883607717524, -0.021387827006178455, 0.004629901220662155, 0.007897220006326894, 0.01368106822155331, 0.0335223461704032, 0.005437737705509218, 0.046575755711368474, 0.07741454628743226, -0.02093349275039195, 0.03229164314606853, 0.03853956690494557, -0.04157614414060258, 0.01172427935814777, 0.007664173144045712, -0.01494579065846186, -0.008675959861764546, 0.011492732246895539, 0.01834637003509682, -0.0027797137939854374, 0.014023189280569703, 0.014612843820832052, 0.02735620509896124, -0.008832747250959696, 0.012635651967317914, 0.03741954017595958, 0.034066692069348314, 0.010662181413421956, -0.030801612891100907, 0.027004726349252144, 0.007714647841730436, -0.006390996504618239, -0.036208361894789105, 0.011044465373388474, -0.007346082997836091, 0.03672613672274027, 0.025450021527291963, 0.0005059003658910815, -0.038866675112587075, -0.008078282639481417, -0.009297336898531551, 0.025889576843261142, 0.009137341089649415, 0.0034705036429404086, -0.007199004928143189, -0.03687130824012799, -0.045068799237560214, -0.021022525430036035, 0.05633834464052225, -0.014081828092830479, 0.03373643250707098, -0.008680754260742706, 0.0018578398375719662, 0.0052407469777503105, -0.025872594521325974, -0.01146526080238372, 0.04817154532339191, 0.05216566698787369], [-0.020383927903994768, -0.03914049799327216, -0.013303130029856253, 0.03240347402385443, -0.07931592848120189, 0.02571702656777039, 0.0643416981551486, -0.006548705854986522, 0.012017130090487667, -0.005778872419741559, 0.037501843941435124, -0.007140909010821223, -0.026854840892549917, 0.004185920531168331, 0.035233053121337614, -0.02564305592764872, 0.02182288696181532, -0.01864460207184237, -0.009737470963951715, 0.028619824389206204, -0.017899974038513643, -0.025500917180436095, -0.008933963220031477, -0.02203067909244308, -0.010660471756294719, -0.017042525559594072, -0.004526758742851919, -0.008642692933350519, 0.04154407090539697, -0.03611499392571479, -0.024382446372725936, 0.009345661419501994, -0.04953042854864899, 0.010008660374918325, 0.05630168314827396, -0.057657207748953915, -0.003359326110058321, 0.0007347218389702123, -0.02253285992845542, 0.05561581519813078, -0.05292577872518468, 0.015744095814342815, 0.03072212734296715, -0.025159225530925297, -0.015829437674758008, -0.027896311749981098, 0.010132557935711602, -0.015982553579191237, 0.03683760303134778, -0.030714284943941607, -0.0026681492130579943, -0.067197408424196, -0.036851105473729245, -0.025333917526987534, -0.010064828418289064, -5.494408543779174e-05, 0.05012818280487011, -0.002484449786762875, -0.04673907089055903, -0.04882944995481066, -0.007891495306852396, -0.021680323823137723, -0.022383695831977725, 0.056553782862118124, 0.01853942493956038, -0.0182452571612903, 0.023589442518471906, 0.00045776104747902776, 0.03778419776920881, 0.007691635375169462, -0.013197028498778502, 0.017011157386055808, -0.007914660500909595, -0.024811812166667398, -0.019282718508707948, -0.01896693277369537, -0.04259957063585087, -0.08266892177090965, 0.02936780114280875, -0.008470939781518687, 0.012206060966956457, 0.046178540804887175, -0.025648023415437236, 0.00116748700482511, 0.06155981335769697, 0.06359576739155774, 0.0008933475248086506, 0.009702432643170415, 0.08824501220348385, -0.0057863681878242736, -0.022529470356801286, 0.024260812629041874, 0.02569027098470111, 0.06197468888598211, 0.0037193793970223717, 0.028271459063924326, 0.01652003542133973, 0.007400736250126817, -0.012828622395371247, -0.03455710594582853, -0.04114417188687289, 0.0030127701370539738, -0.03267840952617286, 0.0164459654596609, -0.016769958437696457, -0.002345755578308596, 0.0004336156157556028, 0.024585235287930003, 0.019455891553624673, -0.0055623492275337005, -0.007721154557692022, -0.0056153816153458325, 0.01074374616292391, 0.027778953894911185, -0.02100617039542154, -0.026125460347442425, 0.0026288896851459093, 0.024508440295408055, 0.010321642672801463, 0.010399505013161966, 0.012482842245635537, 0.04711202123988664, -0.017483675493826657, -0.05559581889141205, -0.025696072747430285, -0.033653825833109996, -0.01194762392750671, -0.005705562732865309, -0.046343642289605524, -0.04237678001258772, -0.008596472433471938, 0.030382342988947257, 0.002436621349838573, -0.02081377182440089, 0.033909097320585856, 0.010359134249108967, -0.04200496041862781, 0.0046485469160677416, 0.013140663342481852, 0.016506180152021776, 0.025276029628242266, 0.019211397370047647, 0.01773443715840681, -0.0085520459411775, 0.039112421873333546, 0.00115755917860622, -0.08783116177606601, 0.04904435974246961, -0.03136375379655827, 0.01227644975477302, 0.05162797203122105, -0.010387015461516044, 0.04118631279242062, -0.028379095079822506, -0.020026862960327418, 0.028937057655822187, -0.021095258844336065, 0.02008273740185102, 0.02590640863588237, 0.02215778146079922, -0.02325522786776671, 0.007696734975007988, -0.011445125744149472, 0.0644849192844939, 0.006252165942680908, -0.014078716115210055, 0.012563539806949837, -0.04529562186113342, -0.002562738869620322, 0.024982194163909656, -0.012096075585976059, 0.0027545192251701156, 0.04302953441416275, 0.01280639225269576, 0.038898884308170546, 0.04585284591506293, -0.03187165288886183, -0.06562075920899933, -0.015224915621653507, 0.020669103170586324, -0.01139160221548719, -0.03575099255258808, -0.05721623816493934, -0.0464880018870039, -0.035553081570228864, -0.01366059233429537, -0.03336872636406655, 0.015799040889108704, -0.04332721421093192, 0.03245121675955372, -0.02956698980498422, 0.005151903385991835, -0.026323635850459555, 0.04729383260739232, 0.05319203797302895, -0.022500063723659664, 0.05862115220694229, 0.017186003473764765, 0.020840447298763047, -0.006590755728514263, 0.003696873102996618, 0.02819903325249033, -0.006616404821742728, -0.01757807850212672, -0.032759262638336076, 0.007274016770144631, 0.0842988790615144, -0.061654152070471556, -0.03564595436657792, -0.02195399273079173, -0.0135229026670551, 0.006902934555169115, 0.06179600564186666, 0.012902268430201244, -0.03094538721259594, -0.07308904585903553, 0.019882312588394777, -0.048295511955170796, -0.01968123059275747, -0.024261256179497044, -0.009399125827896721, 0.02093635651863246, -0.06121666615059948, 0.02544591685700288, -0.023565954791035626, 0.006577879866869685, -0.010098320692543487, 0.011354071809009051, 0.0631477760917091, -0.012736340040056443, 0.04324916311792595, -0.018523181790668655, -0.05166475534614414, 0.01898041521244732, 0.03591526122309054, -0.030718310694076295, -0.04348434031182097, 0.019041086187768036, 0.017572193333732763, 0.01657393982384416, 0.0514670341196543, 0.017796315483232548, -0.008580015115779882, -0.015296358587495, 0.014623276631035914, 0.04127666564239568, -0.04242426994152844, -0.01143439309628577, -0.0010821750086099772, -0.008701981244769716, 0.020792588172837953, 0.05469863510125442, -0.012472583289013555, -0.06488998492208273, 0.01719034935958531, 0.03246584789655385, 0.035552960952272034, 0.00907887116381961, -0.005243834988241083, -0.01233645502107288, 0.0013183621456291927, -0.022658722852188673, -0.021133231664209134, -0.060204258804911266, 0.010137084935360776, 0.019892236290390556, -0.020946446161251162, 0.03480885627571291, 0.009236424901949127, 0.0033727864005723496, -0.0362509769334298, -0.021022061859959876, 0.032988020117747714, 0.04073940144786776, -0.006735928528663622, -0.010485321575737248, 0.0459235293806628, 0.0019484114037910255, -0.02864010151117101, 0.06120960238282802, -0.006135766554555536, 0.016846254936039105, -0.02921740623737107, -0.004398903679715669, 0.025666351342930167, -0.04997347682359245, 0.04081193051377301, -0.0028034030270211382, -0.034121277727554425, -0.028079022254652343, 0.007081956790452034, 0.0337895879748621, 0.05575109271881148, 0.0016563366066729285, -0.03110274675743512, 0.01011399546368116, 0.01111332984392769, -0.007762845902125209, -0.03073506072751446, 0.009176786474923735, 0.0036019634206247327, -0.04523513937872489, -0.03913227925646766, -0.024012962230806633, 0.03790920107322763, -0.01952192394471933, -0.03576035308041978, 0.05519482081955862, 0.006118916693830825, -0.05741330746944833, 0.05794921681403581, 0.02270008982062903, 0.02805025198552973, 0.02006495405422955, -0.04047263432584372, -0.03674196729649809, -0.019234967543348955, 0.0039757923584057275, 0.026674152575373523, 0.006331533452550251, -0.014469347085025265, -0.02110366646119535, -0.025040932513478234, -0.01871886873849417, 0.041236476525100804, -0.0200965968579984, 0.008352215512452906, -0.0745659370215269, -0.009318303079281482, 0.00969071033658819, 0.02953374883028487, -0.012792449162825318, -0.001373590373613169, -0.007007095923081637, -0.03944685827428085, -0.0005091156492173926, 0.05337152376109779, 0.039697081957408425, 0.018449838856499364, -0.04508781313689339, -0.013858832574870462, 0.005415728496452266, 0.02632592062055515, -0.029114246757322947, -0.010401563385573897, -0.0029195529075451004, 0.00028161002616035324, -0.027098994499639574, 0.03172762603586378, -0.003527779247911915, 0.019471299958149915, -0.024816232727499346, 0.0018712220648589017, 0.007158004971196884, 0.015227484491882902, -0.025886488842682197, -0.040668612865486675, 0.00042411322967178186, 0.0777159989716213, 0.024965915543950157, -0.03938097594170346, -0.027732538755718576, -0.047854057682998566, 0.00717345075369542, -0.009047805695755074, 0.02564486216409404, 0.035514604609403304, 0.02084798447879104, -0.002883616069738876, 0.06157781253438292, 0.025946636161611848, 0.0014373931904601335, -0.02825449410411661, 0.0006166909844726454, 0.0016093687726943537, 0.004254275264727225, -0.007880745424497312, -0.02004199445329053, 0.04950041318436611, 0.039114090675156886, 0.013454242222424844, -0.05513748483729037, 0.014126757404679946, -0.05664813472409724, -0.009968913231268355, 0.04620432192309212, 0.02468453575187692, -0.02780209085473702, -0.0018213507613078182, -0.0020059425154266564, 0.03801608834051508, 0.0004980013917431254, 0.001082008438579851, -0.008097358516223119, -0.06202995321030391, 0.022317726731082295, -0.08200789782712227, -0.01742148200200496, -0.04012884421922213, 0.017507948518929676, 0.002978493598888278, -0.06487237985138677, -0.010874031902363456, 0.03376502105364521, 0.021371053290932036, 0.005209376366107334, -0.044228234524755244, -0.004306534863846593, -0.057066111595728636, 0.021162476753615815, 0.01035263692904454, 0.043618647212459484, 0.015069798280653692, 0.01507055026057439, -0.060905961836013975, 0.01713438920293154, 0.05384725702444808, 0.08271013284380033, 0.021125491180049014, -0.02752442100389405, 0.031143239776270877, 0.0101126414749767, 0.03972619194243236, -0.025228617873733917, 0.0013458194052212366, 0.008263415714493148, 0.01175901609465494, -0.004089912206372601, -0.0034714820301167543, 0.014833175217607717, 0.006071435392688734, -0.0008935500481268122, -0.01150136661604785, -0.007742907694588099, 0.025672965135282798, -0.033838600769833076, 0.004549887375096905, 0.03934807670102093, 0.07299078399986256, -0.011843391782548143, -0.03526982058555699, -0.03409943247214581, -0.007207405110112896, 0.026651195097805253, 0.03227696887809625, 0.01833927164912518, -0.04045781706358581, 0.005568755881518875, 0.04924580610013282, 0.02796857008365239, 0.0059997740686171565, -0.00019322826844753171, -0.020446258968851196, 0.01633664896085149, -0.00015362628268627589, -0.025338370690279322, 0.01473679971289809, 0.06338015339975658, -0.003167668005836551, -0.06165138138646526, -0.026982732554275253, -0.004761265051749085, -0.026526326283721403, -0.04438894872461808, -0.03845189832541838, 0.02725200992234195, 0.00551498166885037, 0.03988326092741837, 0.013916487061636732, 0.028569531526918834, 0.03520122879195398, 0.010192908876976, -0.040672597611205875, 0.00468134051095484, 0.008253244632121832, -0.004545306542404155, -0.03898345422109324, -0.05035631441915185, 0.012060343776629361, 0.03430739274680141, 0.005791866761915628, 0.022969118631771507, -0.0009864942561430817, -0.02178858646816409, -0.012010068628441544, -0.06163260797546066, -0.01619804969744479, -0.0020918073574738363, 0.016433701078956624, 0.011717078976504522, 0.02832276624912025, 0.0006988807240361876, -0.015831833864884882, -0.00876214121895862, -0.03711761359377108, -0.018400215029760053, 0.005599645930305067, -0.0723911043948699, -0.02746306162516265, -0.058778177230337056, 0.0033918412219894525, 0.0005330619964023647, 0.047232029288959095, -0.05065305992465067, 0.005946897085424348, -0.012928521252954916, 0.017338627044350997, 0.03938320981198716, -0.011365928210874334, -0.009726529368587034, -0.0674736792891647, -0.0032329718201954266, 0.029374409831782446, 0.023629587200754497, -0.01874730057962099, -0.025182880594402147, -0.012372303760571992, 0.06442902784967194, 0.006346493767277462, 0.04683617586033295, -0.03202461654940631, -0.017113878264088694, -0.03671650576706122, 0.01202237376956167, -0.04939602478383949, -0.019308206988568402, 0.014404476435417604, -0.02663586091190031, -0.01149267544294115, 0.04649025247567275, -0.0018085959668595357, 0.022236661296801803, 0.021078835571271787, 0.09049438008321092, -0.007074706786437601, 0.03351425996686522, 0.03394685564639234, 0.007826626617548843, -0.022468709780363028, 0.018141710429147386, 0.009644904994500538, -0.022522836348968782, -0.029448905838120456, 0.004199907382985077, -0.031076224392019534, 0.0646783145997076, 0.028061121117208744, 0.0609583649819273, 0.0021254818442207725, 0.0037767992560647718, -0.027591541211479713, 0.06443495584520582, -0.024841198636762853, 0.05011472848299668, -0.0019229044768410215, 0.016171320761877387, -0.006716049609741739, -0.007482831567552859, 0.036260644986981456, 0.053850744606221405, 9.923799352532306e-06, 0.01605812543005963, -0.07016591799616181, 0.01980702504690493, -0.03154119919426457, 0.016701396030864138, 0.0016448319682060564, -0.003205943402456602, 0.016459196093437628, 0.04569859496367523, -0.001356228987568893, 0.009442616536815017, 0.041784038615530546, 0.00836756982826261, 0.021579931394124507, 0.0588355838510787, -0.022666081732441945, -0.009454672117146056, -0.012354170237541859, -0.019812793414293248, 0.021185816351940237, -0.019448125706493333, -0.0796301717309504, 0.034031017734838326, 0.006394871316948821, 0.017521037600375673, 0.029649856210110206, 0.03270804211807661, 0.015994687303658658, -0.023620672945554633, -0.011290906125520677, 0.009744194126478851, -0.01386543251747596, -0.0202568366891771, 0.007856085565997381, -0.024698493876247368, -0.025161950204079665, -0.0032278974960433743, 0.02438350670526175, 0.003874899368595818, 0.04330139324048336, 0.00617168272028034, 0.016267914481378383, 0.027717717764083515, -0.011132833226512933, 0.10254867007557639, 0.010248821610287291, -0.03564335792151485, 0.06284792057780302, -0.047097488953666014, 0.04282155442714592, -0.021880501418374228, -0.010474045748704693, 0.06732446908994924, -0.004800841108526192, 0.007285258058433858, 0.010677004557880534, 0.001166366280948919, 0.04691242635145941, -0.020502758638433122, -0.0027788273077255995, -0.01349021770647987, 0.00973216420387726, -0.005969109182157355, 0.02923057999040641, -0.016101756052658654, -0.004028265439850392, 0.02410790449727518, 0.01762981503524611, -0.013886590783579629, 0.02449022866425071, 0.010494999606798672, 0.023985772760006217, -0.009231387600158007, -0.03402133784189351, 0.016869613525958994, -0.026512159214197212, 0.009493703539623005, -0.013066266666071354, 0.006695119084088219, -0.06467070250469777, 0.0643661423779862, -0.04352782222637966, -0.05013779925478491, -0.02322885963918539, 0.03713396420659827, 0.0120754069519472, -0.002016721386123753, -0.02353230227029201, -0.03208160231179749, -0.00712704225325953, -0.030480930554216877, -0.012522343168459113, -0.030169491256530068, -0.015642484275566106, 0.025014700891328952, 0.007738604017552043, 0.021833036578273783, 0.028135381374366494, 0.06860587709342059, -0.006408941970067285, 0.06401030163112889, -0.0004870800605521874, -0.03165900351361182, 0.0027502327086944382, -0.040528239896052455, 0.041496890483408516, 0.036883555270465926, -0.020790353209543224, -0.021432515421583566, -0.01174287968297208, -0.022690217650162704, -0.006741327186429287, 0.04610077882937877, 0.03088921821003649, -0.01913864463665068, 0.02095229748637737, 0.006565294341770528, -0.006228354637671243, -0.006214538086622364, -0.024942615171306207, 0.051289684902533286, 0.03816502753718478, 0.05760440094987877, 0.018286309601458446, 0.018529519378360358, 0.01009397135347637, 0.046834061978960145, -0.019527547828133113, 0.02243628619623911, 0.02673842309757534, -0.005873869278150073, 0.00837360040894633, -0.08967316386683977, -0.013779836049590016, -0.022980775508147772, -0.009562860262367193, -0.11398416373013992, 0.00891114927376425, 0.0850063687434161, -0.04328043835311, 0.0623750393565303, -0.0040127227309493885, 0.018360176991068386, -0.05470455804132451, 0.044444331570237805, -0.01683650776534467, -0.00394809325015525, 0.0479213292456449, -0.048729587656214636, -0.002358139162004308, 0.02561712268467415, -0.026402131332487647, -0.00970011834838882, -0.023128320571032864, -0.013557870435727813, -0.03391973862735238, 0.02787356030997788, -0.032485277504591854, -0.013600369460600493, -0.014883077524253479, -0.014910066435794525, 0.06309213494405908, -0.010604617947245895, 0.03764340046710219, -0.02199703686013975, 0.015350868103338331, 0.0070637689797234966, -0.02343649999333841, -0.028173925057086074, 0.017010061101204146, 0.0018724017542062548, -0.02631381652080277, -0.004630779957576244, 0.032645120214720734, 0.013797146140973137, 0.02184585872818723, -0.021834614767993536, 0.016049032354946834, 0.004108807769577618, 0.0386766686444467, 0.002540046307033317, 0.023019338049390745, -0.03209650851429079, -0.058875230743756814, 0.02758204624336399, 0.0069245023798619925, -0.016690581712776424, -0.037503195830709726, 0.009066995005289402, -0.005831146931833118, -0.018614282000637444, 0.04740640998502062, 0.008279296649783573, 0.01045814414631888, -0.03137859977982655, 0.003652968087527508, 0.005464551358274354, 0.01038102575891178, 0.07052769123729213, -0.005119387396310706, 0.005205183208813703, 0.05114450092685202, 0.04434904254958737, 0.06312532350987357, 0.0003392857455160119, -0.010853438981438457, 0.008148675580773637, 0.04566490350558478, -0.03116038334398271, -0.06206994345722143, -0.008668031516889031, 0.010895088157816216, -0.015677404604811013, 0.022835616137928342, -0.0164000328372747, -0.03475561190607761, -0.00126564875001798, 0.02704653708768901, 5.733652616033034e-05, -0.029961064707973988, 0.04926354956163881, 0.012835273047583567, -0.028960530559075007, -0.017218808481188334, -0.03543126601385842, 0.025058521588242098, -0.006413351509198644, -0.023349866296733607, -0.04907317382993923, 0.0009760537234187374, 0.035163306157192965, 0.035436379738240716, -0.018891726730971555, -0.0015474372959675485, 0.0654865541274599, -0.023237367990458474, -0.01345510781358812, 0.056682738712721226, 0.03553206666521696, 0.044105876553650704, 0.0016925650044570895, 0.0018198296323202652, 0.025425500133249228, 0.019860769087826302, 0.015058994258508112, -0.014576573134526373, 0.015409068327189432, -0.014699398906499486, -0.016368221738489945, -0.03142883421093819, -0.03447022820029815, 0.07610453108499644, -0.022354808487134406, 0.006551517023279894, -0.005322201937107529, -0.024767228595379585, 0.03525209925216456, 0.030080966244978222, 0.02110768961242903, -0.002913393323251666, -0.02187975431978027, 0.062421859969548604, 0.02989766037390752, -0.0008405992104526686, -0.0033026881206361693, -0.006830326128608681, 0.001506177188703051, 0.022753602822516112, 0.007887739656073594, 0.02129491990363846, 0.026455811765955208, 0.024866090387367954, 0.0288739400579612, 0.03825307862749006, -0.019871926937157693, 0.030494110536742045, 0.005630616975042619, 0.032872314007896704, 0.00647203647303641, -0.015255486362334356, 0.046843004846996994, 0.013172084063438106, -0.02864149708185552, 0.011462898364200322, -0.007219882191603838, 0.04911548665386575, 0.008811744213747487, 0.013275055084206447, -0.03352403957222776, 0.008327456228500256, 0.006078235303314944, -0.01794831231105358, -0.00576333132963151, 0.02407129657767421, 0.031503489410409674, 0.02301052106722657, -0.021524502839987553, -0.0040525409667676055, 0.037323678445229796, -0.029474407744472426, 0.029150477613180684, -0.004601845092082548, 0.003492817856088592, 0.00942974439979133, 0.07026094567011501, 0.02849979882484293, -0.012336055979594534, 0.03763100215339384, -0.03894890970290488, 0.021456622889720802, -0.014465117326142595, -0.020587470707836213, -0.022110729355314968, -0.017280487313636805, 0.03902512413792471, 0.04354325969827687, -0.032581237257741126, -0.00047085088718993456, -0.008785956253302916, -0.050788259181437825, -0.03411679210397071, -0.011012214844076282, 0.001667146925729357, -0.02833101369553903, -0.03326047312048769, -0.019733727393844692, 0.018753216194611483, 0.025535956761829064, -0.021715563007980665, -0.02477857970788373, -0.0344970442495224, 0.02803237371350426, 0.03468041179065526, -0.0017807499198769952, -0.024971599562676902, 0.044925024806041866, -0.02442207161344736, 0.0025871362934163124, -0.0044871027548730276, -0.008490544047918947, -0.03044229347573858, 0.00047750773232669615, -0.037085713338368936, -0.011953386107292931, -0.031146027479113807, 0.005455267604579723, -0.04842273263146466, -0.011953926630393023, 0.06795189768379975, 0.01779214369259306, 0.0438832783886707, 0.0036041243220441208, 0.026535326525877864, 0.000982616802440336, -0.012237107073265077, 0.03587693727303116, -0.06270120413957096, 0.03895886253121002, -0.01685089235611038, 0.044476782889987895, 0.05431760596465513, -0.0011023769328763892, 0.017733627286447628, -7.512555827803639e-05, -0.0013523254118227006, -0.01014922923576144, 0.028254068698131775, 0.02235474222961226, -0.04349474690529843, -0.04836719215161379, 0.018250865564333578, 0.002451972581571338, -0.04974244692433341, -0.012578042255332067, 0.023384880181463164, -0.03207188767035513, -0.003174633666433401, -0.015110688798414295, -0.020492712329304, -0.016268135066718637, 0.014343281311475945, 0.015224317995135631, 0.09706377369873137, 0.02457404732161115, -0.017449021391997048, 0.003378747326359498, 0.060577751272601475, -0.018858242312410595, 0.036451866647877, -0.019030083622912478, -0.040669867239935376, 0.041886480127070864, -0.009765692840861168, -0.04593823860608827, 0.001331122326259888, -0.0461150077434467, -0.012452447951312479, -0.04956592184459106, 0.02276553190001352, -0.019843545451940926, -0.03479858908176015, 0.023694389137555696, -0.013120152553588236, -0.00022661931308102213, -0.030741939560518978, -0.07356639276867055, -0.017558996816046356, 0.0026831602488744753, 0.019790199099168834, 0.0043621229108062485, -0.017844499747346476, -0.0028603617638003126, 0.09173449527894775, 0.06697344037606953, 0.012182622252153302, -0.020249490360862803, 0.023938943235694534, -0.11588665465559768, -0.06152823597614375, -0.0002737529528623809, -0.00917911399296281, -0.0057674446443327625, -0.03558833505523352, 0.002427940885969546, -0.044726213040868094, -0.015347516153680817, -0.024836672225574626, 0.02633109827367052, -0.04413455435843159, -0.022537118389416775, 0.0029306775147442815, 0.03881528265429225, -0.09192108249016713, -0.01381431604977845, -0.025334045316670044, 0.012810005713568006, 0.05888291528219179, 0.05591395904331806, 0.02769419474264673], [0.009516049882591866, 0.011270882165492168, 0.005755224802814282, 0.038086882500329405, 0.04360978118644228, 0.037026560739504194, 0.041537025461763584, -0.02901454679368567, 0.02742130769106688, 0.06858064246423332, -0.014032892121022551, 0.018720906333509667, 0.04505991025330945, -0.07544036638201924, 0.0546903459243911, 0.019836719537092123, 0.029092720523592165, 0.00904456008929253, -0.020049954330791504, 0.02337262534067734, 0.04456006178164656, -0.01204829244816553, -0.04443353929332178, 0.03875950802846993, 0.008747558371410369, -0.04734069687827737, -0.05169447908301435, -0.05063897426030002, 0.021302119496367185, 0.007304907483649113, -0.00010175717411886869, 0.022365588412505917, -0.01563230716390086, 0.06222605297325308, -0.027329548003989956, -0.029388366643094868, -0.0356724123243132, 0.016305614698551397, 0.011765490986733637, -0.019396988998819985, -0.03424650781735915, -0.030810253779451725, 0.008480278339378932, 0.05595468245963176, -0.02881158796041299, -0.022963300620275677, -0.015041521757487518, -0.04507074448886113, 0.020727750981744834, 0.001007217068685241, 0.03545137384220444, 0.025638056461212255, -0.05317428089178335, -0.016178296902127756, 0.007736021898684868, 0.011730435322119911, -0.0171430065517955, -0.045637376743902905, 0.006948209144496117, -0.0024729324828220074, -0.022733375361120012, -0.0413154616026171, -0.03905158172128443, 0.010309691030651918, 0.031655109892503336, -0.023759051222843712, 0.07038769469951515, -0.010889605306121012, -0.0077306619217291025, 0.019714939638394793, 0.03193738298250954, -0.0013061626294413858, 0.010218240413605055, -0.013751972317327069, -0.02290906902391359, -0.04775307854067788, -0.013601924067154932, -0.022100739035443344, 0.005670178097587903, -0.1002602775757074, 0.03206271057920747, -0.0021390134095314347, -0.00033092546384027753, 0.06281625482591686, 0.028411765855806008, 0.06845219721791189, 0.0012289194483043357, 0.025236801374242293, 0.06566917622450169, 0.041987420793791475, -0.0025611930629433205, 0.026246415797216816, -0.012343183545824817, 0.057204712566301635, 0.06244445312036536, -0.0051762653456335714, 0.06703116343404497, -0.02708915637898738, 0.0022203617400105534, 0.01916208246233176, -0.0027421983932087676, -0.01875905366571392, 0.005262016693130449, -0.010792900939413024, -0.018240985315421964, -0.05422533213085735, -0.016666183827612466, -0.023928461446388872, -0.06431218226120225, 0.04766035833438348, 0.047962386561957476, 0.011465233398842596, 0.036878401902691565, 0.04337175450322936, 0.006954230268367565, -0.03902655206560989, 0.000294608468338436, -0.001994881894261849, -0.05241521884707044, -0.012833340936559377, 0.01556514060715666, 0.047518034016842535, -0.005104158125421622, -0.0070068168237494635, 0.06149760880873547, -0.08890782147902879, -0.05877219431524335, -0.002831197309533663, -0.03818744807408743, 0.01605846554249961, -0.003507144228102669, -0.03317496980108166, -0.021694773282553363, 0.014349703271624277, -0.027575874030695224, 0.0467300203205016, 0.01923775003866318, -0.0023805347236419173, -0.05026183168808286, -0.012183791556951573, 0.004470507010191367, 0.00673329228429396, 0.04877481630813481, 0.010337444961826217, -0.0305352691437624, 0.03802914749967627, 0.0675337734609758, -0.04845506320876044, 0.02610533883495148, 0.014326312560393106, 0.02723669902470397, -0.004297086896410819, 0.045607942344888186, 0.006142934238864934, 0.010938986160357782, -0.0351481626222275, 0.009899966900868442, 0.04660042549347737, 0.02251326666281402, 0.04084672435664158, -0.015754799733090727, 0.013152218169783597, 0.029476371043431766, 0.0031416899138384663, 0.048850595976872815, 0.019749068954397535, -0.004743089845778345, -0.03374902187248212, 0.03839570157955862, 0.020282895405046675, 0.0011711710507039685, 0.006569074617460771, -0.0748429584834151, 0.01966313423325928, -0.05042736282549319, -0.009889536279218805, -0.0060050338968840496, -0.056161783921548594, 0.0400220016004065, -0.009425625205867028, 0.01405186447914036, -0.024590168176902107, 0.02938179183732718, 0.029218272535295808, 0.053747918351938644, -0.03204127614702221, 0.00787831801944418, -0.04752651968580702, -0.009595717945931191, 0.0350419436645203, -0.011257820394421518, 0.0244039301771298, 0.02763160186684281, -0.028609726637397803, 0.004890929623028499, -0.021121249035766787, 0.029863291234325115, -0.017355343519603987, -0.01300668429145254, -0.017886094520557748, -0.02289592434656055, -0.010165290716454754, -0.019058809007976907, 0.02109963677944117, -0.031035385263621162, -0.059471893218604244, -0.012835279504272278, -0.017222096449743894, 0.00625463670252021, 0.051563279042557454, 0.00358787262706934, -0.002461087829834275, -0.02645606229648048, 0.024695244066576482, -0.022313831135526985, -0.041820876677098315, -0.05255692189808385, -0.015323759543567034, 0.01429029050770461, -0.040379336091247456, -0.021354894394121998, -0.06968426588018017, 0.012916249691129686, -0.006360629249475997, 0.001311526187860233, 0.002910418884770446, -0.004903327516983965, -0.036438185038934714, -0.03687608034592106, -0.05271179799698297, -0.03795652860141478, -0.03322237977268928, -0.016944560112978124, 0.0183132334672385, -0.0033549279738928454, -0.033812625612531566, 0.006468246583653525, -0.004055745074087102, 0.0326761702423984, 0.00641545863409829, 0.013640092937713531, 0.028638188554953675, -0.030997822268992774, 0.030945689142153628, 0.019671544574857557, 0.032544700442784215, 0.06566426668538822, -0.019545214732948395, 0.004630904253885263, -0.03731110137521118, 0.0026790464895055655, -0.009849735029195738, 0.0007571074911268821, -0.012208957514111038, -0.0030919053199095292, 0.007454770908970091, -0.03461819150462167, 0.03270874704658492, 0.06533930721738766, 0.07027517117422014, -0.008296841793133902, -0.04991829284977507, -0.032556839279790376, 0.003462827929536576, -0.03449107886224746, 0.0053409720232195975, 0.0483803698420458, -0.01407850457642464, -0.03828494115327271, -0.03243097475700491, -0.022435953629379765, -0.01583104581718727, -0.02702462978284103, 0.00126228156515046, 0.035338573830283805, 0.009071948210610458, 0.0017185555917216258, 0.049366304990397104, 0.03692089537200344, 0.022904348665814575, 0.007525767881665222, -0.010976555327616294, 0.0449760516351867, 0.008485317100843858, 0.034935030215658816, -0.0059590413717917155, -0.06539071289586901, 0.002277403732802488, -0.025550347138756646, 0.00362115742358278, -0.0396348454945908, -0.02701737088271578, 0.03732605178767663, -0.08172470454931646, -0.0461817787159893, -0.047500333293744146, -0.03060053828668111, -0.06556791029522213, -0.008549973717428171, -0.015009493223086453, -0.04241736666719109, -0.011045419957848619, -0.025457350797823717, 0.005932910025058697, 0.06115410919304114, -0.031225433101685303, -0.05098561666925154, -0.0073034876196750205, 0.017857437507746203, 0.022308483951288614, 0.017307919397921437, -0.059650200144421246, 0.042773323995486695, -0.019308423725924194, 0.03152726281766622, -0.012439638403179572, 0.0007381371368083722, -0.0003458019123511111, 0.0539661512035533, -0.0022152790407308533, -0.03230638887976283, -0.05921915133042524, 0.026719867552056957, 0.016542706239852108, 0.015678804218799178, 0.0672674387532612, -0.05755895469068846, 0.003358217990099616, 0.034362782966452385, 0.0355071383134917, 0.04493934314611052, 0.007936677930715575, 0.009061743357316104, -0.033555062403889196, 0.04144285982383377, -0.03513182725683788, -0.03544443072273143, 0.006958405064348437, -0.02307103806494013, 0.030360438305277994, 0.04768057892396886, -0.01091501281651765, 0.016208857813825486, 0.01790556745393261, 0.04401849837816101, 0.0027365630375850956, 0.0237978355142796, 0.028423212996301413, -0.05415020903805167, -0.03534140182778365, -0.02144611800968118, -0.028873958259107223, 0.025500144428714573, -0.07259792713174756, 0.0017205447392073178, 0.050735037028034495, 0.03732375889226554, 0.013283132290602575, 0.018873063589000285, 0.004814453427625012, -0.020474236000742364, 0.02311145010741729, 0.019047909532409542, -0.008195878978782675, -0.03718993174567291, -0.023119291694193658, 0.03250832371270079, 0.07119164601943147, -0.014333631375893503, -0.018842065662307034, -0.031166501463924717, -0.011430653617236889, 0.010573005669156874, 0.03772291458710397, -0.003004602476583367, 0.0034416543960523946, -0.001568580629356014, -0.047112740198009824, 0.012565005946894013, 0.00886425922844861, -0.0007440052464325886, -0.0475257881880785, -0.042895356692472714, -0.009236863784022154, -0.04596132199334461, -0.02582087237145114, 0.008532140750535978, -0.02390104247811871, 0.029782529467781975, -0.021804297487257766, -0.041494276910578116, 0.0284512835696943, 0.008513540643207881, 0.00345912339570904, -0.038129955265496104, 0.021622694180949063, -0.020616777304124714, 0.060377749804009936, -0.009241967726873872, 0.018759938923309474, 0.00877367525598461, 0.008100905628905582, -0.044842693471081094, 0.0015986906063471366, 0.028216448992338973, 0.014647344957640172, 0.016837377754324902, 0.032908844911606346, 0.010509791686395523, 0.02301562693633532, -0.008325302158881314, -0.02303893165750994, 0.06112316185060589, -0.019375999987049773, 0.02444621869717235, 0.002119339492748739, 0.0025483516918766887, 0.01351243173290235, 0.0025385324898173985, -0.022026729859527767, 0.029893817866870846, 0.033455574594871945, -0.004822376841021362, -0.03406554227369611, 0.002049751605095483, -0.031852800871107714, 0.02632690899256264, 0.06800731725955711, 0.020204645901294414, -0.014224128255572463, -0.08949207536391135, 0.006582380388858755, -0.08188775182270247, 0.015071677135975351, -0.006611578960136543, 0.03609584185809034, -0.007529754163971843, -0.003994883596204817, 0.006775153322926781, 0.09264514665043687, -0.0020274588891776423, -0.0559702653074889, 0.025477922824638843, -0.011019127198717907, 0.02827791622483865, -0.000168242729744833, -0.033465026018008076, 0.03548113078703895, -0.026352782045897027, -0.038841624728063615, 0.030800602843641677, 0.05552793829678691, 0.035124500019102486, 0.01899323350216279, 0.02042257788669296, -0.017907829099844057, 0.025154441658912587, 0.014001932733061849, 0.026616666553835298, 0.026873865566616514, -0.03152991047767887, -0.05065974501507032, 0.034586618570019545, 0.055277211060307724, -0.05295561822011517, -0.0060415620986245325, -0.019447824880427747, -0.004362020445569032, 0.02844050762630935, 0.001964978781183154, 0.005193780817318553, -0.002766318864537414, -0.060986302096787535, -0.024380477282433283, 0.06609016661250756, 0.01024011799593915, -0.01897706440653322, -0.001860526927925014, -0.0156719361897453, 0.00046521008853636636, 0.027646252434194822, -0.021094114643289072, -0.011581347131455703, 0.04384521615053609, -0.017491360208885698, -0.04470045355032693, -0.08049985901980344, -0.01299465408963094, -0.0239971965538942, 0.023561521877691855, 0.009624284506800963, 0.014614393561455882, 0.008945543737091385, -0.03874558797110843, 0.037942999169733004, 0.03657522999306445, 0.030807949265342256, 0.02420625179217579, 0.004342551006841608, 0.00348714481803368, -0.027281886066179126, 0.031287945219300485, -0.044491965307265326, 0.04045050364756625, 0.006865174781231446, -0.0077261961637190985, -0.054357863056181906, 0.01040281310609207, 0.030021305834997642, 0.04097239496314419, 0.009999860578879983, -0.01937395473190954, 0.03884768247320243, 0.007622188392080214, 0.008303034200425486, -0.014895555836582102, 0.006995044277560439, -0.02775017841811886, 0.0029468063992949475, 0.021947386577700966, -0.04671642039525364, 0.03582361460594961, -0.011680743629269446, 0.04896958844251106, -0.006577935406504403, 0.04182038415933406, 0.008349263238979027, 0.013625194376729216, -0.014793537431832754, 0.010531214961052467, -0.05405378525968018, 0.009390361241981282, -0.026531929746959573, -0.04799978789940294, -0.020756168909876516, -0.0025347284413171425, -0.013019113473728791, 0.015834227103941, -0.0262962018222829, 0.03734388910120512, -0.02463124674027526, -0.046966857771609964, -0.002184153715272138, 0.01869970946916851, -0.006528368239807866, -0.029780171456889604, 0.05420209237873458, -0.01898654289436391, -0.027130632471517785, 0.018196798738856594, 0.01366091667931339, 0.02880812939224304, -0.0014270967427545203, -0.001679539856873448, -0.02461009554990062, 0.024735236933347733, -0.03624104197012949, -0.00025183050481937183, -0.04207747501826864, -0.03441747261707521, 0.01576111413252653, -0.01920997523970805, -0.0044733672938141525, 0.013306321951204843, -0.06851056307615812, -0.02683108029576584, 0.038789592431656736, 0.01582679664047952, -0.00997093824715558, 0.024159252344848205, -0.03717371605130737, 0.021677342771823867, 0.018114562598336336, 0.03812644985503967, -0.05617450116882642, -0.02928311241830864, -0.01150718291513602, 0.0010142262505906546, 0.03523274197821232, 0.015959175807267276, -0.029711666858490714, 0.01129613960867348, -0.007406711740157532, 0.036586867136381325, -0.020114011331918938, 0.0004079574388599072, 0.004073769677464872, -0.0019173693047724732, 0.027707739633925563, 0.012649438253834015, 0.020864275805071726, 0.0239474502400684, 0.010613497346631938, 0.009344690455557685, -0.000523540461158812, 0.03360515338512904, -0.006655612235262082, -0.012799597037101583, -0.049136959139625944, 0.053601968419029235, -0.050120996782071534, 0.04821101417454661, 0.0360324995863493, 0.022063041831051827, 0.04816567436788465, 0.01015388824926463, 0.004253323450471247, 0.0617711172797525, 0.02861993052008087, 0.018200516708531542, -0.03942680688307368, -0.07130536598981708, 0.04727384034635568, 0.02668914256816046, -0.0053651692855075615, -0.010047457066019921, 0.019739823993145566, 0.05816662615749614, -0.036385644763250305, -0.013285728347845674, 0.05218894276377892, -0.0011164015814513276, 0.019903986710914492, -0.034694998340364325, -0.06210132630543276, 0.013816357164018503, 0.008334510929570294, 0.001748802509812089, 0.028846335228029228, -0.05029633499809182, -0.04810656133998551, -0.0010317577870101874, -0.0017075612462518937, 0.014861720670416434, 0.02810017566575656, 0.0012457667208948184, -0.007332599225773206, 0.02739440365436982, -0.018341008319856918, 0.014083481692745927, 0.015875353709619303, -0.007481185841994569, 0.018128349793970662, -0.027726787693975595, -0.01054967318029083, -0.07068219264400566, 0.021648974145375352, 0.008507417721293167, 0.0014295702467999362, 0.04204188510335237, -0.04230825954899063, -0.01835439368063128, 0.008455172667196743, -0.0380749869685971, -0.01712216787239499, -0.009813621948649766, -0.019409745276690593, -0.055459423215736645, -0.014843167563047665, 0.04520304081380705, 0.02197607252015994, 0.0011231174155678023, -0.010340458518241407, -0.0434493986853458, -0.01304053041365056, -0.01471649496401508, -0.033147991520015505, -0.04281483129442174, 0.019705712502441866, 0.004406636000933235, -0.0169762284698102, 0.0053178367179047056, -0.015863145780902952, 0.0286879055326748, -0.03738908914739223, 0.020181137328069712, -0.012776354184951341, -0.025982685274757816, -0.05914919675780559, 0.00023097761197138703, -0.0038091319572657175, 0.006262176394882784, 0.008862874077917918, 0.004868766408947785, -0.003557216503538907, -0.003715148214592956, 0.02566437198744319, -0.024235881378884345, -0.012917676655380636, -0.0036281196774270424, 0.007999271276358758, 0.02698948536167617, 0.05424465926713866, -0.011284102580579781, -0.003641951883713617, -0.004629355367941155, -0.009653117278233621, -0.024514340307839506, 0.01834854666697951, 0.02043310674849112, -0.02513065585221953, 0.04372206260427646, 0.049624966551558236, -0.005199897580929235, -0.017890420552126175, -0.019206574168093408, 0.0030648529471394327, 0.02058065835129867, -0.030724912647133434, 0.03092862558707986, 0.024342780689482858, 0.047299730230894746, 0.01831510251107875, -0.013711705795225576, -0.007541512635956576, 0.008586886538932297, 0.026750497512704446, 0.023968699862481076, 0.006805162278230605, 0.00934427598238642, -0.016998743997306415, -0.03290140586482559, -0.04742060821610957, 0.023361117341453942, -0.0012595776184091945, 0.01119487449454285, 0.008193699920037007, -0.032843426788169566, -0.047605507900628605, -0.021498532291985974, 0.024511928056186898, 0.03224016096024176, -0.006227985107538546, 0.007058516546317327, 0.03680486938388352, 0.014044605702258066, 0.03807287855856642, 0.003956823287422684, 0.065703488168308, -0.04487500625250487, 0.039682822993847566, -0.04354450624926689, -0.03256699588588159, -0.03879041487437371, 0.05371372831486175, 0.022526442564747597, 0.03569412788535292, 0.06220008283790959, 0.014997707351172599, 0.03494961403770499, -0.01516648318192175, -0.002338864768328699, -0.008781301875543887, -0.03758427336036445, 0.003715915538663574, 0.010886511969338366, 0.040696491029115975, 0.001687543615528113, 0.03507884570942956, 0.03223690049573516, 0.0073287815323526285, 0.04849223882388844, 0.018455283003082936, 0.015962791406517428, 0.0028160630101366434, 0.03142912691771227, 0.04720391253544792, 0.0025100922465844614, -0.027319156716268563, -0.04171902416242494, -0.01685308583504785, -0.015696129384114722, -0.06826652724066973, -0.015354651267776532, -0.025692113214828532, 0.022174311509144336, -0.007166841827231246, 0.012642867305735772, -0.020208257767634796, -0.005402040593051592, 0.055112681712298744, 0.008395037376849329, 0.01432150545577309, -0.06752393297163321, 0.002842468550584146, 0.01153918712388551, -0.01869216672910948, 0.06350906552378599, 0.00709422567766733, 0.011497921503486339, 0.0504130905805533, -0.04751715295110935, 0.07702783322003247, -0.007067765433785956, -0.024453338185230766, 0.021345815377540645, -0.0018307302223449238, 0.04336413741747337, -0.01272947110142811, -0.04453606671723965, 0.031220943627811665, 0.012339166749982363, -0.03305348629443473, 0.0012493725590923353, 0.04074988418766244, 0.02826432074335499, -0.004126757324368526, -0.007469153444673955, -0.0094296910640517, 0.024628191876478616, -0.014999053282355502, -0.0028645915135510685, -0.0644280145951182, 0.04904834827571126, -0.010643444595253305, 0.006330692622061935, -0.019573151830719098, 0.054242449206256156, -0.023042719440413535, 0.02783495598653413, 0.031538750777522634, 0.011656567812988742, 0.0019142457513541397, 0.01735221650785583, 0.016608040411316194, 0.02311838770208547, 0.040185989495019094, 0.0023849449807477052, -0.0365772740389157, -0.0029118359995356485, 0.01202980160932982, 0.021938671287615934, -0.01249715134303568, -0.03698268206543328, -0.021061900938741565, -0.005919675961174133, 0.0663165271817281, 0.03396181417452065, -0.045994670520614976, 0.014605797267453577, 0.011199659835821241, -0.06847108590996862, -0.015828974291595244, 0.0620689419567265, 0.013556318509441409, -0.015797176541286973, -0.002014999731059139, -0.07621272531588183, 0.012723692523384535, -0.034597659278167124, 0.013067906589302484, 0.07571770308145567, 0.013092448241405551, -0.05899354771871011, 0.010775335801328789, -0.051589302538926636, -0.03445031958562818, -0.03785607119706137, 0.03829250473380152, -0.011263760984792972, -0.016789113959259597, 0.00042935685994050074, -0.061731723309633224, 0.05050919671670721, -0.011720835008833148, 0.04489576826471014, -0.0012128147860225257, 0.01435636097560281, 0.009910018797270954, 0.01755978647764057, 0.014710611519000348, -0.019712839272029836, -0.03334894497568854, 0.01210975659843381, 0.04946923930933337, -0.028551090438595574, -0.02333792934785377, -0.004124709206791784, -0.0015746785357535777, 0.0025611494217395274, -0.002380494283521806, 0.06039225240879398, 0.03436894203934964, 0.009354021670408852, -0.03291689520637641, 0.028739736284164374, 0.012185235806221398, -0.030564253005467303, -0.009843919502862552, 0.05787936890642864, -0.007180413418476864, 0.02595258261992725, -0.016230663609899523, 0.01951350250249308, -0.004529743796974468, 0.01176688496008915, 0.000342476353409396, 0.02313561140453899, -0.016505234060146524, -0.04684446654579654, 0.026384734132651955, 0.010468773100253763, 0.03507640643871155, 0.04546445099978065, -0.006146487335865402, -0.027376008702462436, -0.027257501555374368, -0.03377601428492627, -0.02553669895991286, 0.02298904788868921, -0.002443145044382015, 0.0406945589783195, 0.010007409400019103, 0.03065369757805901, -0.04925260727724372, 0.018872323253271758, 0.0358632195962372, 0.030621000249239985, 0.019965283568230505, -0.029399732933085405, -0.002574394392626541, 0.025389389612337956, -0.044138224943386505, 0.02210105327677041, 0.003787556585600839, -0.03597911089660618, -0.0633396571900045, -0.03717975247523193, -0.005133990853988239, 0.029283277780705837, 0.004657298776905185, -0.0459559349329163, -0.06554142970927097, -0.019211972371373245, -0.03674630972771923, -0.002545559910904994, -0.021066151633128503, 0.03711382874514626, 0.044867446018608585, 0.02708872650365533, -0.014368843189114864, -0.019435925427903622, -0.004413108517564103, -0.04802632464862949, 0.0031976683984852447, 0.015898070292449513, 0.02930395910582276, -0.029131307942325615, 0.03535107806313236, 0.010678055638148689, 0.0349026133686988, 0.029527790418742792, -0.00039695428219191516, 0.02096372745296973, 0.030978679006286963, -0.029184958813852836, -0.023999975712299445, -0.003332092592378715, 0.00953179541236387, -0.017149254005119956, -0.004361511009550898, -0.0022212479827114257, 0.045232644125661865, -0.030689439136230828, -0.005851839977546687, -0.005281274229771301, -0.020747285733446304, 0.04380477794498794, 0.04566712313294495, 0.036469581165512126, -0.0036727686618696865, 0.0174012067660681, -0.041982758043238894, 0.032380389924196465, 0.0012495768483914754, -0.033510896676256605, -0.00269154200717851, -0.010395777823857992, 0.0035676432418514964, 0.033870894067223385, -0.003781973205081309, 0.05479745141467656, 0.0400063074193703, -0.029796240104578913, -0.03246720634783999, 0.04419522744962531, 0.04448458065993023, 0.04421474432671862, 0.04325829299780613, 0.08972806095590945, 0.006775541595311193, 0.06927678892213267, -0.026104054942017316, -0.05800996881744175, 0.03584202437869626, -0.01274740009332542, 0.02056992125472633, -0.06653961238029434, -0.015140955063536105, -0.060740601694889776], [-0.012321477003911115, -0.04413031116132265, 0.06425330864025, -0.004742012307094805, 0.008284475890231156, 0.022504887864775093, 0.0016305602413191848, -0.010226654633116151, -0.026052298646134113, -0.007847865673673047, 0.0009142245479507767, -0.04503031990515897, -0.01136395487557833, 0.039131808304570546, 0.046193401055741753, -0.010246086299225854, 0.02238735464104269, -0.005800463375319592, 0.018251924969607047, 0.050279156538862814, -0.07341446866137422, -0.036697551216881175, -0.00654075367532516, -0.02517193772919945, -0.03990218262090159, 0.016274702162342766, 0.018907027839446297, -0.05734161923330265, -0.027595629547145735, -0.028563076021767348, -0.00879611033995293, -0.036175417628283094, 0.017767510286370875, 0.01751599610914197, -0.01683083229400944, -0.022485051875875354, -0.016278594292674607, 0.02180981882989987, -0.041769997667236346, 0.038023409454162105, 0.021040879250135, 0.006847551412868615, 0.023081450328091765, -0.01267118479543175, 0.03999559846709981, -0.009080718591910942, 0.03305907869602319, 0.018926233309054137, -0.01678862199168888, -0.003091040048724839, -0.029673404310946686, -0.013213418719197428, -0.026992053387202647, 0.012923497805616453, -0.007797610260936467, -0.0029156373309935984, -0.0038889184241222233, 0.025883829121842016, -0.005498694001112862, 0.04079673198190572, -0.0474225508464432, -0.028642658257140418, 0.03963961392739989, 0.034965553865050784, 0.004714858841763397, 0.03389577799981075, 0.038679312177106705, -0.018662915719066094, 0.05897945407813551, -0.019958854786490517, -0.03372417795300406, -0.039724421617840996, -0.008219642490505889, -0.018437859123937653, -0.01673957457907053, -0.012140217264781202, 0.0037777447449021395, -0.03653368051324232, -0.03220366587756552, -0.006202506350692489, -0.006811642785994486, -0.007234676625900025, 0.0402577834024294, 0.022574537589497963, -0.03729056005560544, 0.051700294226874235, -0.022317950997425375, -0.00527751695049275, 0.008465394797993232, -0.012850961544189205, 0.008006793151859853, 0.005279495377824427, -0.004958258847528446, 0.015959221649083866, 0.038594030426199494, 0.022656444176778444, 0.04111414699751315, 0.032742918015643295, 0.011154603831996273, -0.025495162395221264, -0.017619134355473073, -0.020796087445721916, 0.08004487563915176, 0.03784563705964048, 0.028489309628428328, 0.031165297983410046, -0.02918698333398946, 0.003977716476896369, 0.017841276395704243, -0.0310573752595941, -0.019564027615840803, -0.02706394720134822, -0.019523679556548726, -0.013624092901740114, 0.024148867652371987, 0.0267636124854728, 0.024964687824102716, -0.0132126626775016, -0.00971956257471343, -0.0075994791498099346, -0.002398806361213357, 0.0267229809368301, -0.022854428823208827, -0.01003919585039542, -0.019657312736036693, 0.026428299990431944, -0.011343509786799835, 0.0022569792840749447, -0.01970092998964399, 0.012524042540579837, -0.01433006339982441, -0.0007965200943410612, 0.016609657685707706, 0.0178958990901852, 0.048600057386237336, 0.040226917171949025, -0.00493019667724242, 0.0011284049537454831, 0.020693194754120167, 0.002063198048146395, 0.018563498351741595, 0.041033549892723876, 0.04363194273498563, -0.004560652398214657, 0.026497164489500204, 0.009481758308118633, 0.02295403727620638, -0.007183725355473189, -0.0391609467679882, -0.004744803678595538, -0.03711833785320388, -0.012430824379161905, 0.07258757180515651, 0.03916481242650281, -0.0030677836217066715, 0.0409494250082881, -0.010281683456200105, 0.015649732406313028, -0.034066368008525416, 0.013895221041605947, 0.03050887225911681, -0.06701256993335489, 0.031102337222372073, 0.04245722036458319, -0.0057521940570249026, 0.015641678854414368, -0.03274739776173814, 0.0016298537260670577, -0.005332780786204098, -0.025314436471027966, 0.03108994074615467, 0.014682074855797308, 0.04134019858911943, -0.011168537980629877, 0.01913861998777367, -0.03669372538003931, -0.01429519756258439, -0.020764889883989526, -0.003966481880319041, -0.024674683301266202, -0.00957952246702886, 0.03367514267405009, 0.011470386066201578, 0.013517207824223523, 0.056246598572749704, -0.08702500162936062, 0.029048669817164783, -0.10388103756316021, -0.007049703916847991, -0.05142953514835232, -0.006985958330995074, -0.008723475801863993, 0.03759382067671664, -0.017786901483601767, -0.0032523073017440597, 0.029091399581202125, 0.023525974251075603, -0.04633659977659325, 0.05657901217447688, 0.010069470532687431, -0.007023523313581978, -0.0016599263203662118, 0.04595661876549673, -0.018503447835479095, 0.0033362527911527766, -0.014966773241310377, -0.04122605754853287, 0.03933796358767222, -0.033206532410736705, -0.041959280817113385, -0.021329413415370226, -0.017521513290647807, 0.01434095762521693, -0.032006079492094934, -0.017042240517744656, 0.0712059044316805, 0.028495065162213562, -0.005838373771562422, -0.00765692854294284, -0.026752656985854394, -0.04758278069014494, 0.0098583638439878, -0.06105928191524046, 0.022867318209341903, 0.0049652011614257485, -0.027380743660640004, -0.002734112760854941, -0.007159311032794028, 0.008804483439356796, -0.005547039529220903, 0.03901482969728284, -0.016097737909970437, -0.02016467934464273, 0.028218104169974476, 0.04893811764941958, 0.009524993527700906, 0.007342438364066129, -0.01666461758309446, -0.04919169808501488, -0.004793072293575767, -0.01972147700206757, 0.016819780175582923, -0.05791833444226621, 0.04852395178080907, -0.0009605536573555583, -0.009928477651240261, 0.009546000931356772, -0.02342129746093428, -0.047070502922816226, 0.0221658829555601, -0.021787010709776622, -0.035179812449081485, -0.00567804353580296, 0.04435183884436027, -0.08306092802711214, 0.010773084778549737, 0.0016082319995565971, -0.026845182949416048, 0.008288815225746572, -0.004672081721995294, 0.020453466837101378, -0.018929208764488545, 0.02778512988235147, -0.0005637456498233575, -0.014800087721236088, -0.0023141431528348657, -0.00028686347061224887, 0.005366846854952232, 0.03410999204779357, 0.006763585737004249, 0.02296752217412526, 0.04875108287743138, 0.005980248541738774, -0.009876625905656605, -0.059440143929157, -0.010210857533219465, -0.0038531684755911608, 0.006969665897826806, 0.02102268231382935, 0.0020531040062701884, 0.018409705737417473, -0.01654244288246044, 0.08276783620046513, -0.023617327831305615, 0.039131321078239314, 0.016219501202462856, -0.030625991989478605, 0.04687916038301372, -0.00884754247196973, -0.028053988671785324, -0.013362726890714575, -0.015472481042947834, -0.0021146596002102266, -0.03188998700952021, -0.027833029384542518, 0.0006823500993225649, 0.0038123850569078003, 0.013611592794068319, -0.003131132235165474, 0.03435658079257172, -0.03590666271784018, 0.043749013154003286, -0.0006360473927657668, -0.008361523411017105, -0.03021492133463236, 0.03699718916604012, 0.0017924688004619157, -0.05066961004057925, 0.033790069496250526, -0.011047266734017364, -0.013130071895965626, 0.001105012915359558, -0.0199030729010365, -0.013299584936067529, 0.01764221093871615, -0.004421411680688084, -0.05693246568586324, -0.04830797452533235, 0.019331989179532546, -0.01192916288113866, -0.015005205716658365, 0.021382579677842833, 0.009242701662906496, -0.041402445108580266, 0.008428926978108691, 0.0838120102077084, -0.005705817774011744, 0.0073850086653852245, -0.0113377545823778, 0.00017138278885849706, 0.019381212339976667, -0.032921537277033786, -0.026406365147128175, 0.025532083454973466, 0.019697988318798536, -0.03281262444529575, 0.048882800340803896, 0.017616873281344515, 0.003174444478866726, 0.03579550431586741, -0.008735512744024057, -0.01473931485038947, 0.01956290194664728, -0.028139129777953888, 0.008092171707496331, 0.011584670612964348, -0.024221649348240518, -0.008343961130266274, 0.0538674813937436, -0.08256882636526683, 0.015540966666820775, 0.021208621382791615, 0.026801900882296486, -0.009414446555088503, -0.00014580212483212077, 0.008444334286986054, 0.010665806910410736, -0.016170570692296674, -0.002929868598067757, 0.03808910279191046, -0.013777195688774606, 0.026791556770119157, 0.03320966339524997, 0.06016953556645488, 0.05493441822159227, -0.03167025750099588, 0.01419430131268081, -0.00041983615526883754, 0.03271477184733205, 0.024305068267058687, -0.039747846923149074, -0.02510966749670125, 0.04805649388184676, 0.012314843025875585, 0.01953990966351668, 0.02609900994617039, -0.030090694311863998, 0.0005014090300462719, 0.01204098482972313, -0.010319606585425628, 0.00445672171984407, 0.046976031867509246, 0.07309933184375793, 0.04901896075489735, -0.00973472021254686, 0.0074054961854960865, -0.02671300269122857, -0.01949889860736243, 0.005920583850026362, -0.03773450231270169, -0.018174465808880436, 0.0005011329001242074, -0.0005635755203653899, 0.014871638874087743, -0.04847272608237441, 0.01931584208427971, 0.01886363687354125, 0.01134412797973743, -0.05964351215201022, -0.02396213858496561, -0.024755937069684337, -0.008076024895602125, -0.05198735691340931, 0.017405993654117706, -0.060238051649287194, 0.018937763697810188, 0.014347192862776637, -0.04313269101957638, 0.06295729944979903, -0.023571534430259132, 0.01767615260319929, -0.007966523930216672, -0.02447258515416725, -0.020262485670629854, 0.08265696174057971, 0.013591876469971245, -0.02689071704228508, -0.008734687738425681, 0.050824042734125566, 0.032214102490172675, -0.0017945372426729032, 0.049589605458748506, -0.036818011521921636, 0.047734113670432496, -0.008900021081364673, 0.008666979173477592, -0.028012244376312414, -0.03180450860442914, -0.031622045964708786, 0.017365905455995305, -0.01199881628744751, -0.01177781759482354, -0.0014227934941301048, 0.018989405961061058, -0.016305364235450905, -0.07158208740058086, 0.031071873112562133, -0.025225402272725097, 0.07571395144308771, 0.014704073055642785, -0.039300424550332294, 0.0651230597448005, -0.023176132806488982, 0.001547516248737106, -0.002137275302003373, 0.08116740469755046, 0.033328145481795204, 0.04207188272906986, -0.034498292573474795, 0.04688976726403298, 0.0334611127604035, 0.003828659698939564, -0.0389146075010309, -0.025739861694708075, -0.016425652450336226, 0.050409898341778586, -0.014305864163346236, 0.03726212555834494, -0.005752978325284017, -0.0338189548876473, 0.020160283185658753, -0.019762342307739537, 0.037767340403386127, 0.024707348480998537, -0.04077464171052149, -0.08187558830965055, 0.03211218126110826, 0.04243398265848522, -0.006645973404453028, 0.009859997848047442, -0.021470101922649677, 0.039803145603061134, -0.024254350048571044, -0.03428033473019948, 0.01646532592872607, 0.0027846774183492217, -0.03887113844100982, -0.057032959200178854, -0.015950065528669906, 0.05205769815918965, -0.01292028454929062, 0.03780495453129945, 0.018796827282899643, -0.046039273074785704, 0.07375245002112715, 0.023010590847766542, 0.039081480890558906, 0.008699554281772763, -0.00299738048031083, 0.03973909586232062, -0.015611947838909119, 0.0005798469577145936, 0.018986849908879402, 0.024801109152343178, 0.01143492267518738, 0.013049837914523327, -0.010511513758325985, 0.025837741875458085, -0.007396520096636935, 0.038351750661789474, 0.021685200244584445, 0.054072269779258386, -0.01084720976270739, -0.01745166616160291, 0.00013423233275875954, -0.015084131974661385, 0.005132741081039125, 0.035796323310656214, -0.05262893884210083, 0.002211716335067224, -0.0038784754862870707, 0.0076664399555346, -0.01188297518697283, -0.014637416093190893, 0.019749589517702327, -0.010394695967961613, 0.010098196489055232, -0.008286478594841426, 0.023325185633040528, -0.0010844850061213617, -0.007253680352688958, -0.04267886465925943, 0.0078942730557537, 0.011294233736272766, 0.03922822704743732, 0.06337289310895457, 0.04002610050251712, 0.00989737938396906, 0.046814930011096344, 0.034488886050149846, -0.07813384387700655, -0.05323882437881623, 0.014130409010893515, 0.04746671018468859, 0.05195413487434938, 0.00822891353848469, -0.004113471383196066, 0.016407243803448816, 0.00766110191586571, 0.008004494307516267, -0.03560658986655711, -0.09079545082491955, -0.0077662580144861595, -0.00799465531492629, 0.012459542145440445, 0.010960568463029719, -0.01743558536932137, 0.03610046988339767, 0.004647270876536987, -0.03362555327620463, 0.016856591327821562, -0.03713352415516035, 0.07091956178761925, -0.010357294309542995, 0.021346612702439278, 0.016802930089689493, 0.016903522774512396, 0.032340673841323414, 0.007857870121654027, -0.017329509717866006, 0.04173632021466345, 0.012554695216177997, -0.06429847415266628, -0.00968944399985983, 0.012790894057246467, 0.052856231460059855, -0.02573782741879896, 0.019596945277049655, 0.0355210081409275, -0.011006288511253664, -0.009977055765767354, 0.019689063270884453, 0.012754475666217461, -0.01323126640251889, -0.00015030655247344135, -0.016018183903431828, -0.01952300017862112, -0.008958742421593033, -0.019383875085308543, -0.005635806867470939, -0.004597106224700637, 0.0025128668876894886, 0.025588850632059477, -0.0044013364721494095, 0.03343207161791574, 0.0499405350193516, -0.02022545856849576, -0.024693466248392366, 0.026018299430672433, 0.01717794457561357, 0.002348500440097088, 0.011404743475596625, -0.00921023880646681, -0.014131631618073234, -0.03549418824754468, 0.0014697685060345023, -0.003434394176875632, 0.0269289883170863, 0.023722909764586776, 0.009799338881367069, 0.05677702553961919, -0.031710540205265814, -0.07131976256822051, 0.03665449792904214, -0.002036793375967747, 0.05488680087524837, 0.023105622496254467, 0.09337779602577143, -0.00231971296154267, 0.010063535207180656, -0.01293823980746531, 0.017230608644703504, 0.02211285957107628, 0.008808177836584729, 0.031119567185125402, 0.03614945180504829, 0.015001717847314138, 0.01989154147222031, 0.0056178452480054085, -0.029791676072872784, 0.009448787153938343, 0.005767406636169137, -0.05863738402255414, 0.055811317646283956, -0.031044400937302895, 0.02500077471252984, -0.009042780476959264, 0.02811060120322967, 0.01596904593284234, -0.04293944415193668, 0.002836197418776539, -0.0020548601069883634, -0.02460027461070501, -0.0068094524150701, -0.00045493334739379193, 0.026010954312754735, -0.025722378177255027, -0.042864642425750846, 0.002530937754411716, -0.014079771445272431, -0.004911560169256569, 0.001648235862752711, 0.006831663151671753, -0.008880501901344748, 0.007357444469122321, 0.07841255135327242, 0.006534356159113161, 0.028034752960465564, 0.05217272101670474, -0.05510115555386593, 0.020581096535239162, -0.04747272254965116, -0.04245412248134138, -0.01986433228740111, -0.03230453770647274, 0.01962893934133994, 0.007015381388215813, -0.0004897232211922963, -0.020053935256816816, 0.028509085748873952, 0.06613713020773605, -0.0012495674924857259, -0.006755904219497998, -0.04540875857803117, -0.006255164333823541, 0.013990610563723152, -0.009265525420146524, -0.0576244201266161, 0.06454888062376665, 0.010071429630338195, 0.03941182176055469, -0.005701946139743362, 0.0164039954849659, -0.018309394798076667, -0.015329378117752184, 0.004481582830511625, -0.0001690483708885436, -0.013992690455661946, 0.004026913814879813, 0.0508103981787264, 0.06220570036358217, 0.06821925307183034, -0.02972636929712813, 0.018231307429267228, 0.008951625455569007, -0.011740316502239983, -0.006584744171986618, 0.005261954542281731, -0.031358160495692164, 0.02767942425257792, 0.05490896841757481, -0.012598706799115154, 0.04577388590003046, 0.01893709066216749, -0.013272610249020062, -0.03693189198538399, 0.052827669481864535, -0.03049476102239384, -0.026124013170066542, -0.0306425080943504, -0.021626888859015484, 0.01708927179215175, 0.024843603488345616, 0.04183953942174791, -0.018790369015512683, 0.04256110222927197, -0.01362417359746416, -0.06675999898056721, 0.003159391306509437, -0.07180096502910532, -0.03429202926505494, 0.010887869183378595, 0.029130631681559944, 0.02807114453105118, -0.007671204837380239, -0.021951983072519454, 0.022523210118289214, 0.04929679471539422, 0.04063870830049249, -0.045134661769959526, -0.017872007829769387, 0.005151397143689807, 0.06643596901741355, 0.007714516338663477, 0.002367221652810992, 0.017549822363216925, -0.0014344311111475997, -0.009989827102712064, -0.007652306983313501, 0.03276296384634109, 0.0048848457359636464, 0.009394608186412962, -0.020213722410803978, -0.04599183901001949, 0.03352203961206253, -0.042289964757670134, -0.02733410274528964, -0.03137365066599839, -0.014411792366674815, 0.010413616464115509, -0.010629713338168938, 0.07035218086336895, -0.0015968038028671893, 0.032848148710265035, -0.0084954907170146, -0.0330708111199992, -0.06224630020681689, -0.011150112350875499, 0.006136842734697253, -0.04494543464919096, 0.05617104869121611, -0.04195801558504906, 0.01854640012761996, 0.021188728772055583, -0.040707372302230246, 0.0036581853177999925, 0.0060156785053483985, 0.05773386357909731, 0.005060981187025026, -0.024652857916427913, 0.025022428183817252, -0.0827557355798232, -0.01795603706358487, -0.03238560835209652, 0.04641215439839316, 0.018119351336777622, -0.026488481679164427, 0.0016041278418103123, -0.01156208316621753, -0.026106280347108983, 0.07370615018395252, 0.034604356982606554, -0.051736851438125814, -0.008538823013307661, 0.011309581040408332, 0.056640517197135164, 0.03809484225470203, -0.002785677822111406, 0.014504016846877847, 0.050153814937364025, 0.03157086024024256, -0.03061695759190082, 0.03795247940289864, 0.003510619550545268, -0.0007831549868709473, -0.013062128851371521, -0.024021417550752724, 0.04866706390722239, 0.015725697584973376, -0.009595576902406979, -0.02794730852035047, 0.053271568865340534, -0.061542394483827055, -0.02592196546464463, -0.0621192752977582, -0.09651446803258067, -0.02469585115841286, -0.03094958084904083, 0.010862674921726405, -0.011441153519666018, -0.01750491692162886, 0.04993968234593367, -0.01898728525508128, 0.03120948868674752, -0.058011467192842565, -0.012739013603438468, -0.04933540173135603, -0.006672409721605748, 0.038437994569110866, 0.047016334850680484, -0.00803647121392723, -0.035576584397718894, 0.052096823348137145, 0.009878337296399737, 0.0064239674190188145, 0.0037310568722971537, 0.04610381551055631, 0.04331424822162683, -0.02662408394113811, 0.05073922763949365, 0.051566103909037105, 0.016015987735817708, 0.004852296024491176, 0.06056453015289304, -0.01873146433126438, -0.009019711112035133, -0.027067208099370153, -0.03914782128358444, 0.0059970406757684615, -0.0014704817757061307, 0.026062236494523425, 0.016911816894543293, -0.026013866111590945, -0.052882065954201134, 0.0019864590349063533, -0.030050610444361973, 0.0321807910102508, -0.044109996722129875, -0.007291476981409495, 0.050425732631383106, 0.04931942752621962, -0.01135305602413783, -0.022993107095841386, -0.004407793075950539, 0.022424917063607937, 0.0329958455379907, -0.07865659258567813, 0.0280798444909868, -0.04695397623162482, -0.023787078954573344, 0.004195475805261176, -0.006859669071422325, 0.016246903719593503, 0.012078208133641102, 0.0007732042267012298, 0.00536556380369155, -0.005175859386346448, 0.02823433659398111, 0.016909634929848618, 0.011420059656529776, 0.005465219731084866, -0.044073543306247805, 0.024901564871252935, -0.00783586832517539, 0.015513991146492824, 0.08761389959144254, 0.00028138689100188225, 0.04792286622619287, 0.03893456668029716, 0.010171615083485934, 0.008917543908271373, -0.04180401203109425, -0.004023703466385451, 0.020020534725593217, -0.005722672177397898, 0.009889954215505217, -0.003110271966792498, -0.022511104922804528, -0.1173011735375188, 0.03184304427250888, 0.002887899564912, 0.013675399192313194, -0.03278602942728742, -0.019532284570779636, -0.02246688329455633, -0.011622723975369283, -0.019080110834736094, 0.01721879089371022, -0.03733272395148291, -0.009910184958279809, -0.01763091231428701, 0.002749344693478309, 0.030490014306820766, 0.034938746140507855, 0.04624608567589026, 0.029231699837640006, 0.048962492329843454, 0.009627888904601306, 0.02690167345180243, -0.059077614820964124, -0.035674629981507694, 0.03867948670760955, -0.007137691763128465, -0.004375585395942654, 0.07479916886840011, 0.010115390354800892, -0.02457160440155629, 0.047049232190647, 0.030292676151464394, -0.017711135548590908, -0.005316888177266782, 0.03322862419875073, -0.04568279407158567, 0.05357001397414723, 0.022993103484735464, 0.001160387849005977, -0.01295160570189318, 0.030443797877143484, -0.047277050189414194, 0.02355950726327705, 0.027730443278708845, 0.043858108607521935, -0.028688304947057635, 0.035449985348394226, 0.025628097370710742, 0.025280364988772015, -0.029571790069432502, 0.023411132951084664, 0.023333624963097193, 0.05696862903985612, 0.005561445062402175, -0.031248988593948472, 0.05367288941822468, -0.06285953602603903, -0.0005597888053650648, 0.039490327781412746, 0.0232399347124437, -0.03025477057232343, 0.008536068626276939, 0.015718616289656404, -0.040939149485824396, 0.0033950160137695903, 0.045239612383741905, 0.005499864968872756, 0.007148549221157738, 0.040163743232817864, -0.035377654906124385, 0.004860808880546464, -0.03729688371983781, -0.028242007484452603, 0.014473144386231422, 0.020103928686625697, -0.03149993774734404, -0.00046404415135873353, 0.08987178490476, -0.005797951693868368, -0.006907992297814797, 0.049685624578974984, 0.05256857562682219, -0.02230340301295956, 0.01730942434876947, 0.00261268213383308, -0.013369154979770686, 0.05418813628014863, -0.027357375458538336, -0.026676018115363666, 0.017204038886792183, 0.058057872485282734, -0.03569172921992621, 0.009538559983844555, 0.014372053892039613, 0.007891497012824576, -0.027593571424743536, -0.033648286403450495, -0.07637311823913895, -0.02426039458926108, -0.05066105914961183, -0.004141268122904401, 0.010960056243137213, 0.015868281638289607, 0.04872352278360219, -0.03510274659237816, -0.0035320545107919363, -0.027487206850467325, -0.06501804993776698, 0.01244680732326278, -0.046441136475458694, 0.011199147770654175, 0.02987218865630449, 0.01766489107194864, -0.022371279215409705, 0.01150049328504933, -0.009493757906234553, 0.03372236235792888, 0.014110999234335052, -0.017446216041406417, 0.02511014699304057, -0.021838600341250652, 0.05238948929174141, 0.007762338366032931]] \ No newline at end of file diff --git a/mylib/lib_BAxUS/BAxUS/data/rotation_matrix_alebo.npy b/mylib/lib_BAxUS/BAxUS/data/rotation_matrix_alebo.npy new file mode 100644 index 0000000000000000000000000000000000000000..59d421805e7553709fba04dc00ac1ee86b361472 GIT binary patch literal 48128 zcmbT7_dnJD`^PCOiAq@w^cKoUw#bF7%Bsjn_AJTX*?aH3&awB-Di?{Oh>Ao-k)%RG zM);o3zwkZ3o!1Yq+wGj&>vdg^aepRh=%{PylaslTdGlCUI-5K3T;Sl5v6AHB=isrr z@8sfSYHxhs$-?q~*Og7}oGnS$oo!4VEJ@#a#rZkT3keCG;pce3@&EhK$_0NkjAh6K z@kW~bp{yY2IJVu@FqnUV8j~Fc!i_3~B0F2^gSf9_ySD2S;5tHjdn@0nr1xX2jAWw22Mw z)RZBh_JgBeFJ_bhe4%=jy_f(x1C(=$!f7Z#GqyjaA_Xl}pRAd52g1^&?7{<-nK;hT zXLgUe0)lzIj71c?;tL6rqj^4QIASQ;MlD%@RDW%)`Iyu2?LmG{4cZ*M0wHr1`W~=8 z)OAdX;Dn`>4Qh1hTJUB$WP$HTE}GrDeLnbBDY{?k@yqx}fTx3=Ne~nca{V42PS@=r z-*I!_-zg)Ui}omMqO1pL$BcG76A!|(AIXxNb8%1G;&ePA86Tvd*t^C|#D4YWJO_>w#G9-r%eM84SiEGMIAnH6<+PVy?YkWW$8&%{Au)(N2}Y{A&_I+a{yj~8mQ zEql?GWgtuL?XSOUD`8!wq`1I839p@~r`KYu#JNh@JKFrAkjBONU8cDdW?S9s*jfYO zEbYlwBl~2?c&vKqAHo{qQ*AQ1j_K`X3p`yx{k2WOa{qv^*x(^1dk#!-gLRUqR<;7f7{hiG!f{3q&(7@p;8xo(^R{pGE5(r0iM&;e!FB(1kpV^bthXBF*<==XoD;ZJXmh_wt_NdOnKhA^`;e7 z8JOpO{jr9Zvd&0ZQwF^Is(;W4W}-13QK=~_#&iOs%))C8?A=+kn35=kCqE1EKukV3 zjDE1M4bZ}S439>;vZH|FXvH}N6#_WyUpgYWKN-lp9pl-5@PphaZ9okN4|X<<@?G!K z#e;hu(7EOo!9vcyHWrTvkiCL-GAE+Y;KR}Ag25CZ6L=yy6vK(ZvgE~K!TBKX_*4AZ zUJsnVt0WlwkN~FTyuIG26893U#qfi8aDeJ1ab-9?hvs6ilB0%u7^N;6qVsNbJ8bxhx2^5Nn z7=JiWi!_$@mJeU)!@4+=&RY?8kmz$1eDJXnJ*@W{eyK0O^2BsKo!l&#qRIL#JnRV{ zzv+E44oQXeb?%Ji+8AU(+AN1yqg?~~`x=uVe^$aMqkFMzZkLpE=VE0YT80 z>|BVALVIn#JtM+_z9pyE&%&TFmy&aF$r48?vx-hH=K_C&Eq|4YKkRY3sn2pI4>X0| zFvw{IVEFHvk>4sNu%=g2I^`dSmqI;0#q=a%XNSfo^{(@<8O>LB&O88)^Ri^W>qvok z@{{)diC5taol~zxO9|}xOE>&(AQyL1ERFQ2ih=)9vLug3KH5jj6QlRVqao#Rt}5}*1G>$m(T0^;tk11V2`P-h8@#tO ztahs*tLjYj<48OB;u1vrt-%2+@0*TMIy#`IDbM2ZQ!x-M5R>Y8Nd^xae{Wt5Z$>+D zyvk)&hmHH|4>X?*0~;B+#KFz$kj@zk`4IWR>1Sg#0rtI`9q7844Nf-B4+C>6(Le0QYByOX z9uL&~kzeP5%py4^XUT}rSaIuV>A#B*QhVXTY@QpmOi|SF8hQd_QPBPBJz-$du|K%# z^95KOnx8)QiHL-UAWqc~4;TCRyy)jsf&GQku@?jRICY%aBaqh*1F9-txHysK;qIXv z%cr)euk@b?wMiU^JLeWres{+C?))1n<^@=PeobytwGjPc#lsUG7lW_%jP}R()o5Rl z27SjW0PlXg(e;T4wqb*gu3sZiPKj=6in;)U3HgR!={#U7^7t@oViJxGaWHS5&p@8U z0xHMAO7MK)#HV+y2ItPi-wV5!45gFP~l7hBnkX<84 zQii;#uu_4shipoVpX^~VG_CEuK^<(;yt83WaDWDL6wp)3s$p081U&IQqB% z=%qKBbq>nL^;sHA*6Tso81u)?uRRlK`BeLRyB~ngLiGp4Lo)xf&lZp%5==F zNpSUd_nd1}1)4NXJ80jw2EE;L-XHaXfOD0&Le7u~$1+wj$aYH5MRqOE}4tGC^6{`0;pH5XAHv*V){R14Y5d z*&jOYqb@-&kX$MevQJ(=*WFPF&trA(kgaOrbdUYl#iP|oZlk2hkYf)YhNHJD9o_Mg zjAxp2P#to-9(ZE@-2+eSurL;~C*v5cS%vpbGX9ButEpF+3iCfVj9K?&qm5usn*l=x z#r!xv+G!5G>EAfpF&f%t=0d*tDqiqbzI#X1=`Z{l}7!iG8X) zRJsCZh8)B{wxnS3R=Y4mV+sfgQ(U}O9fh_B8axiKM?mg5#0VP}o{hoAlhvIgENGh`>w& z@64ph1AKpl?D(s!06cjIp3USZ;2rt5<*cuRApXREr^1N@9O@0c#Yd%xdd8gRwTE*- z6CSW0$;?N?g*A^~PRU4pZAMwHJPp5zNAxUaRs-+XXMdlV_G#aWH=&7uz^=P?K_|ViDU9cqtY`*ke)?eh zralN}Z+E?*VNAnnjeP^$BFUgZ-s!?Un*%0maUIDQZGk53;kS1G6x?Nc{>^1E0WYxL zt=(nGL6zbXor>5ZEaT}+-@EAwm&UBZekmow)TEgB>{)AguA~-lKOzVhd(!tGB4Q{&fW`bDuu- z@J}Qb`QmMX++yr2aov5Zkp<*RH50=Lp7_rCZgGELF{pMLwJe=1hN*QFEM-=fOD+D42`hH+kX40$j*$q=e6yN?~B7o=N6G;ub6=0uuPWtm!0$yJXt-Bao z3$#Op_OmMyPG2`cvFM^V_VBr~&8TKz1lp`(2zXatY$I@qp*P4MCZz4tHGs?t( zJwDyGnqJ7lxHVqZRD@?A`}xlQ$-qJF!S{?s&FGMmM)J9}m`lzaknqeAbLCI^t?$c0 z7bm~p=I>IFerxwW^@0v;p1(+;*%OXzy6*A5BjvDe^3);lX(gJ-mHCv>=Hkrr%V{h( zQcyB1t(j}b12z-tEej1xp<=|mh)XsTpROL+IQ6^;_=)3#vI}mYRVY<`m)`(>Xi0H? zjShp3r}L3KaltrFxY87?9EOD^#UIA~E5Jy7h)-fQ0;g<_G)?;1VORCPh?1drjFy_Y zbB!zz!-Hb(e@_U2C2cObsrPEoz-p*bPtx7KkN&g${Wk(%rc#RsCEbIi)W|bmgq-0x z?c#s+T>-E`7p?NB!UqGRBD(~5Gts3iOZAFK3Jk})6JA-Aq8Fs;o(l=K|8eVzdtoh;9o0reD9+V9xb2pskF{##R!3D+@Z`?vmWP|?xOat6JE)f%ouys%qRzh>|w_@D^9Q!Vag{E;B~~J~I+etiPEE8@9g`)40>XYr^=E zm3TIsmZ7Y?f2R!2eBphnM#zRpyYeH2mPNSmmi@T@nkVcT7^AOND#Q7|VWK@5K1kNo zC={p255`_LS=3vJI5lFQEF=?+M57HkVRa&^O6GdHk@mhIP0r!ThybWOb$QcFwE(zh zzcTz6pNC8h;>*#amEaR8sLB%P0o_+W^ap*fMed8{>fR-ZILYzxUSCQEq*85{afZ|Y zh3lxox8gE<+S~PNYdH+rCM6!*{;k1I#z=c&WgeWhKEb2eRRFIzz8lk7xIyWMY|o_P z04!Z_<=fyd#H)g3{v7H_Fq3LLeBI)~zw&BftH&6REnc~B zU7`Y}kzT-1RYgCRptXdDSIFfxlFFdz-*ghawvf*C&ruI84_^<4_X<9KQ5MJ=-O4 z#jiepR6Y@?E!s89tK%>@ThE*}Eex(4UIiwO3S2OK$Z_VT3p|l%x+2P(g6Xshw4FyS zP%@lrRrgsDK02&3{H5CuIeJxE z=1RZ{wbI~IlQ}TvYxp5jpaL8Ff~KmR%5hAtDpfm)fW@q_r&vaFz{&VzI>V6+@Y{8k zEv3r`C;CGDrPv41e8GFEsy_=hINSA*eiz?6|p&3zDNzcA?In+{z4R4M&=)xc2` zI@Z8t2CoKpY2M$fh1|Ilf8)=3qR-W(<8}$<@Y+CW{rOlD2G7`t(51xS=9Yv>s2>4} zIE=UFFNNdxPP!KluKUASmiC*`=cN0x-sbpL90g>d3bU)ab>Q(!wLIob0zBp0a{V_H zgQsT~J3U5<@p)09Fx`C*bbVPdDb*f=^(Eqbv5HB+O*x$R&OIGvS+{Qb4L74QBe&@O zH<`H9df;n~;$39A#=;`lQ3l==kyoyZWMav}gwl*bJ;sy&ls6@dL!$%hkB)Y^!`Ba5 z7N>Kfz*T$j=2Tx9ngwlrxf_~=Maw2<+U)DG<;}^x4%9)|soirj;l3C?uecF>F2xec zt87!l470Ge7vTj3*2*7rRd_OqZL>ow14ky?tc2LA!KRDxa@}JY z%s%+vv3%hOIMk^0`t4!{zO-~F_j%(9Pj>}F`VJECQMS+OKh7jbN$6RQx}68Ldw)z@ zUyBAIOUKy2wisx!$`BjA=#AXx_bByih9jf0+l6iZRP2meF#l~Ef)DoedJ|H!;S_|( zoOzyxa(7r54KI{K^kqeZJ{4;`E&S7^BrhKKq_FT9lbPdT1EsAriV~Eg^<0xsE=S@T z;~xRvU^vTfbGuS50}mt7^aD)_xTq z4L)c8Hbel9EK4r+kWx_mOj$0-odqQ)C7-qk7eR9$8O_NaA}qhKz|H9@B>OGj-FHv| zRa;MUDqK?q_nySA_0NHDQg>-4)-xa0YpAIBG!sbvmr;Y6-xQ?N)?V0##KZE)PKaic zIXp4`fHD-R(B`Grc(h#y6Hf^;*_|$d^`x->wiM05JX|!>{AMnyrX5&5daeP3<2k<> z?*zg#eZ}3v%5<3gtg4?f7K0M9)4$vmQ*m9}Ls8=XeY_Om)AJ?dKI*+Wzy2m!1ws$` zC%$*iMtPltYlNLp91I?A$&x5UDvK(uD5F%gf35aSz04WRM|rUQb3PCq&dzG;#o-Aj z_AfsaD^R+5&y?PkG>G)fa%fXXhABodt?%ABVE@IH<#RI;{ylp8HIFF{-ZheSKJbo! z%f_bSa)Y&Kwaa(6t{@Rto{QwLzc+?`;!VFgzJ`OawogaLNDfRr)Xn26<$!>df1($x z?x8_vj;5QKAKd?7r7YJ_ie6blOd6R9V5K*{k1ReBEaax%TwJX}d5R2|q@WV;emqic zrQ``>JDr;GCE=*1lB8~g>7=>4?~>0qUo0^9Nx8VM3@>|~D|z<9581k(=Xd`x!nUuq zb35PCAV(p@_F#P-emX%tsJ@zsCg0hH6u%~cokC+_UT;1q2Y#GtTg||kP^H+QvqWI~ z^?`H1qY<{Lj)>AlR)BZ$m*wBOaWK0-`0@9*&d|RhlXkwk7G66xNl1%_qP5o-Hv3zN zP$xG1Pr)q%Ye&fUCItthR`GsikSxb@YM(U!e)Yr`Y~BODjRn9f6rV?o%|Icg6Sg5D zM9g#wx~KeA1ish!o-6rU44ZV>1CmAcI8E3+)NPuHN`g{zJDwyzV-nRM#$ST_mj(HF za`F)WGaP$%H37Oq4OrVHydm|B!n+ZUa?qmqT*+XXgT-8jw)pAOQSHkyYGMx&C4RP! zrv6t5Gqg2ifq(L0GcX}1e<}w*s*5)qsmg+j&!3L?=Nh2Rk;U>#lHa*~kz%=JCk5UG zZP-Tc6vC(B(XG|^cr1IyX)Exy5E!k8A4#9fLl&z*UYUXjP|rE#D&*({`Rh${pA+*@ zdPgDAe8LYNvHuBsVq1dYXWX7Sk@EYqg>n8lryVhC-r=zQ@i4e&%hkn5PlPkF^d~Rw zcgOAHZ+=F^IKxG5o2-qF`t@?^y3}GG-F~BjcDOq92># z9_!oHXviiQZts?j&-ab&(|_!YxBRD-gnH7;wt(ICJ@DHak? zjwzpvFRTyv!jef#Z;x0S_Ea-UxcxJLg7CFejRR>&Fu0z!FyjwbA7%fce^QQT#aHVR zc#N@y?{^XFP6nQMxtey}K>@kHW(CBYi-B*+S31+>O>yGgB1^=yGpw;L+IN@vplTdX z0IPZ;H0pFpe7}+prqacI!Vik!Mg7|@rItka`t(9u*TqWMEU)xe<;_QGtm*qZmjdC1 zeMT&Tc@RIh-8gJo4CH^}AG?$i;q`h1voLuYNX^>1ebGQ%h~i^Zs&u@|RDF5$@*&e(Fs7-%{bNcJCV0mjML)iwF1;fm_1BgTbUsQGJ7UNf1L zlPq<iFo$+pU?*VAq*c#|Ka|I1*ATDPLF%?9@#$?+4xl1TG<}$bo}vpHqMP~1e)voCYNtQM1~U(8 zAE`!n#s)vNY4gh#}p?6JuJn&q1&yqGU!>=?#Wv<6vkwxzNfA=)f zfa~mm=a*C>kny5>h5mmD=xujs);9YBUaDs&3*;67kEhpI-k64=U0UKAtxhWbosMbk z?#_b-G52XojyUMOlIJv0mI{3=#x)-LnMm!WQKT;!i2qq>KD-?gg3O^6zSS!ExKYzT ztQwMlzh&3ugLm`M{}kN~)`B2lN*8t#KM)On+2*XO(<6aC`_`UbVj|@9-aZ_DB^F=E zQXZF2i9lJ+ci&GKyWswJ!O5#_nRuwp?p41=B7AR%Q8f!s18%Y@wW^_7>}aFC%d_B# zd{)iX6$n zEyxr&FgY5Zjio1}s6U>$fgTGL|Ek?ha5Ve@Rh&TwY*!r}7_UeLt43?#g_L9nmf|)3 zy}tpka`qkI|B;Rlz4l5|55=P0mxcnZ@8(eGl|**)v>QY}G`MUrNx;#+ZS0)S31Haa zx=v=81e)LILZq6@Ksock3Dr?w9PYw@9X&Cy`O2;sM)YTgmwM1SsX8bGdFbQ46X)&Vrr)4DT7)} z|C}1|j=lid_9~Jc_#2HwFC%<&^6rAmFRg=mTBPU0m8Wgfy8*O}$U^Q#CPDCWI>eAC zAdQFd1yz9<%S#P}cB{My_*V?;soy_|zZC+3llh&b zN)qRO{s$J>b-?-bjM&5W8VGPcs_y*J8MEKeB{3>T;BpOH%YEm1tZ|oJ|LAQ8pXJlS zgB22B)p=c=fyNbW7@?$5KOLLepZzt8LIg)k^{S2gy|16X?a z;+M_MoNKDx(o-4`$omOf|=jB9n zot0CIl8D1$uWP{@QgI*=u*ZnXIs~hSd9Ga6O8`A`^$JGKO#El-r+-h*4|VD{?EQ~K zAkE65+rJso@qqDJKlNRbKC0$#>wJ<7dJ-L%uYb6U!B%O#e=FSaiOJ2A;dF5z+?5?_ zWgm@l@rGTlEC%QwAE-M-Ai@}@1`}(285U2RdwK488JH3G?O!Si!87OEF72uogS29f z#d(T^S3#Fz(aVtsvyPc6ofbDTDqnF5Mek$M5J^j1SlwMEnQM7u+(+0RPV7= zOgc-i(8L;mmSU6!hkh4gvVjc|G|EA)j8E)a&K-z4Cbz;x$`ho*Zj`rA=A+Zwmp{L9 zM}U80pV&Y1|KM-$f-Bo%E}C@LpOEuNz=6A>>uN{xQ1sEl`d!m1nE!1VsjWoni`5UQ z@N`{(xpXtx2hvg4W~jmWoG}5KtoFtJJr#g;Y~{7IqQQ{)0hjibc z{+$8Tv+`dR#uM>%C`;tljQ}Xv_V;~FT?ef%%(NTU3vsrOPNUtF07p*q?8Z^}pxyNR zn-Y?adL5H`Nu56#jw}6U34BtVK1AY$rtpM`_o=|#Y}0*NCITo!k`IjE2?c(x?K4CY2jRex8+vm(5JtsSe@iw+ z;h$e*S)bo!!`2AVt-m@SGb$erd{YR-CYL1IXwn`yUD2T(sTPS2YNqET4picoS?T56 z2uI96R65HZF6uCNF%eUw zs4vg&CIfx(m-P`6uQTJqA4&^$t(8i!?xBK zg28Ajh|OI)9?V>#pBY9wLRXr^=|k=rz}8T|e|W1DES7Jb)rl_$&jjB{=M$v8NOZhv zDomO)-)|m6a?O1PLDBAlS3!WQsz@(XjnpS^mao^yr-inrdhz=K6u{fOp zEe~2mV+0d`Y~6BwJozBjb_qPAbTYtA&lg{nT7r>xf_Lm?UMoxu1g5#T-$%>d4Xe); zq(0!-zVnU7SxEbBt1Q{29QMSYiuSmdirIoJN|*U=L%(S`TWUx&GMw=soU==S2#=n8 z`*Yz?Nkj3lfwvYDGmhxECnkYhEnLtL%0p9y`Yoo@2_Vd%clncfHa4Fm46)~jqXkiL zd3BBmg`6GwNd^fJJW{AJu|EwXc?Yx7ngei2U#Idv&3aJ2K3%HjSB!715}BRV!eEK_ zWQGojSCIQ!(f;2J3ZP@Jw~dH$gF%C9{ijHroWbFv`K*t#v5}s+PV#yUynPbGdaa89 z8avtx7YS)#vX`MPTvHu{Mz*=f0wQ2+|8=SyF=KqKEgYVanvVO4?nW{@LEz|pE?YCo zADQ2mo{rK_fUU`oy?P6(WJ$&H4 zN!gv94`C;Xndf{m@D6iI_pzE-a7ukN(7NJ;Qfnh7Q8EemmdwA%pg#;(X3t#vvKRzx z28S>C#TH{{xcK2X*9izyGA=i;g5cy$mK*{fmRGHk-hq7Z)#b;#w?_Os} zjge53e;JJ4r_Xd$$d`f3DeEiLr1zA{@Y#ai<$O3r$RBY1kdLyJ+86$9Ec=5DztOtV`69^RMsi-sEb!^i=&^J4!t$|;x?f4Xl=$jy zOZUG@kf@rZ+i#c*ydvR&Nj8pXE}oufayJ+L{G@ICe5(rW9&as4SZ3je_N&~%vP6{Q zUbighIFGXj_S|b>E`f<#yHkcy(U`eJnGsM}hJ*M05C47{f-d!Z{1#N@P~>nZhs00MN>Y{baB9|)8!u*T*7dhqq2ZkkcjEeKL2Jn zwgZ*;Fq(_Ialpz?Qz)^Tj1ITgT{g$VF!SA(Tj0YCjC$MhLv1b{qD##ceCOj(OZRYS z=e|OSj$m6CCCx8|rp1QtgCu^?0LcfI3{h@E*)LVO6xp~-ntzwO0+aFfQD3VHAg;9u z(H|^>E8gSD*M(5#ZKwcX#jeDVQyB zlbW!n81*yuM$d{>(AI}8_S9x-EjY@n>^`a?@K97|9`hBsm zA?ZV#x#&jIV*Hk;Q1s<}IwX73B}z{xgM$6SOpIG1ti-F)5PI@)r?6G4W-t!-+8WMx zKPti-&U8z*EGfulBDl-NnggS+i?$|@=Ro$;o>ZnU&9Eftb$V6F5NOh045*le!K3r+ zPnh21LmdZEiAgLOv|p+bNB_7$t#XUu^j>}FQ6rnH=PU!S$_H&1MytSpxz=Y?C>2;A z7fjbs1%W)Vl&vk)D^WH9dz-F4aP+Nm^=AA5B{<5rCH{5 z#j)xEE$tmI6bbwu6|$!QZs~t_=6jL}m-0@^UHDawk8Wk+va&n!zZsnoo3O(C^t+n- zMa|G*!1cTB2Xydkxll|Ali(27tBp zW53S8CQSLbS0Mhs1ekIrZp}+3;>ClOYQtm|Si@eGC>~RR9|!CLj$f~XgR<_jO(W6h zy1&&jKRFOiIZ9IJ98SZ`3!YU^Vxuwr_VmD$`!P_Y?z`g{_Wp19Ys+{m*u0ff9rP7-;N$}_OQdNOhD&!6*{WX_PMF%mPZ_T9rIj3r| z$@I7cb3fgPCOoV{Va=b8+KCxsPSK*7N0-5{_?e!%+HEf=(ySLJy=XJF#y zjo&Pd>0lvMdi_wnJ>(pa-D#O?!i2Wi*62G#yaQL>?5XyJ8Lvs$`|_LA#1_3^zkL#}7O)6@ms7BC8v(yA42+LD6Cm&>`N^N3GoiEogI%Lg zEr>COH;0*ILjT>zQ70@yV94NUKOh%RG7B zyqW-VQH2&UEz;m__B!HkVkDZZskeUB&x7E`G^Wc_BtPgGbM~J~1g!dBR=84<3Y&5h ziz!`2xaYF;0S5LI5U-Euu*~nXHTkx)+ z6$(TpW}5%RVpi0sgY%gv>>KcY>mptZ97-#KG;efKBK7@S#v3+ZBwqGxD?1BkE01;P zXBU%nNBK>ocUCx__ItIhuMjh1sr0uC3Q*Ut``@{*rRehA)EbVkZRF?vq;-a4d&y&ta zgjIVDbj3pL;=}fZWs=S}?7dG-;#-Ga`Ie<*M#0~aEZ>iWLgYBeVgHwqgEFxm?p{`A z$o!GZL%A&vt{gZoOEVq_yI1H(3x7xBWO|H$O-B&WtFrxOu(XF$v9}4Gr%E9Ax!yaW ztrQIR%RSthOoS2%Wj6DQLagZ?wMkgWgciQ4B>QAPcpK(=mvb}`wz*G*w$_(}1N-r3 zcUaVbJH7MTuOd=DM03G!Z($<%((z7+jaDKV^|tmtV_uxqdHY<9KOYxr>wRS=%JF66 z#(8bpH2i0DN?QJ%IY`;ooE{Abfq*cYZk@seR4cnhmPnle*S};|9y&N>$y_gE(qMmZ=8;&y1%A8EsjRvtARrH?XD=p-`>^|kpp=b;5sl8Xt ziy$ZUyPf9QKp5*IXlw7}fr`|^_2hHO@Fi6N6H02KQF}}*{f{@w{RQQwDmPGJO!MFR z9t_&e!J7?(k-+uSd12O$<64%CG6#6k4O2qv-@`mf6{6|E- z7Aa3VS{`?+%_1LCnZG{IUn)oAIeRKP{W_Sm<>B+VRfeJTKj@UDi@@0Ay!I!?3S{Ab zLa{Jn34!m;EgBmtAu_yXyznK7r^7n zR6@1a6A27-5RqvA=ncnD`u?H`a|S1hb3#0J>DU|&)Bom!z-4RrX6{ldOq!^Eh!ReQ zTq*ShMk#;bsBArFFe3}~^Rcf32U4M>ETw@eiWi>1(*(nsTBz3mwR);qIZ zjazg7I~Kjb{jTm;Jg_l0&93gL-A_Y1vDB9L8b;aIDdgg}ax3)NhiXjRJ>JFt`k*V*3Q zvAj(3MKWi%?)P-%@j9X3e5f2<^MGY!zPjrU`A#DLc~ymi z2(>}b-V~DVQWWKGWpu{41Xh5$YzF9||_Rv+w__t%k~LBJ63T-)||+SwSll z4PnC1RurxfLC?G4P<+sL38R+rczUQ@J3TAc+G(2H)g)!!-t=9)jU{kN> zU2#`B9-8pBrN2(%ATj${FlKuS)F&W|y ze7#C%dmEIisoXSs^5EsfoVYHj>?7~q8G0s0;+q|onH!@DV2`JZfv>tL){85vUtO%k zwtJ^s_O%i5(T@09z<4oyq<$?SOwy5GUAh|diZk$4*2?J82Liya4TB1yTWU|^y|2vrQJS7~0H-qWe{-Y%Kn2+Z%j#rw|zu>^^JWvc~&@K6dv_lA!Q>LHr7~!@~pfDoE=H zH*UmUTfY$wyqK5y<^H!}*O^0~vlIr^TD~(k7s3@A9~IhX z@zAWPSs_zj2A?JFEr*;=1opO0AA0IKv^wzV^}8drV799q#Ai|gm%C&yHYRw0fuQL# zhx0_Z>nJAjF+LeNnv5h^LPIe9ZGn{!F%~btcEN=Q@%`mI?r7&kE1Tx-f z5R2{`z`W_=vmO~YUBS(1Hitsnt`Oo69e^5~0+Ttvc1s1zw+TPK+aQ)+KwG!ZJHa=LW^3l8=-2!tF4V zaf65|9IN`!Hbm+{B11dsULLW9u+sf{=XSEdGyjbXXRZZ2J}C0~)`w)2@_6>jCM^bb z9D=0(?r~nlf6al>j1*KbKYL61jxy$^zfR^!x^=ubLWH; zp?5k^r?1!(9``a@%U6^5fLk<@Z|4F*d0{-ctB~YlXAVWaOv;2m+iEd27=VGJ3z8q5 zN+GvCtbsFQ0Z4jn@S*L=Ey9+ zWOl-%hsD|ip2dJ;rMa2bZ&IH4(~^!a)g7%}nckY`Wq^%4`CG!_KwRwBR6`vdxXf#v zob{~&W2Z-czM#E_X%Bh{A_p8G4p$hsN+Qr{Urpbi+sTk1)3?8K&=vMvVQP(%ipCGp z+mcPu$)Nt2F>aEv0Qu!!zX>R^$MBlK{9uMm@|*SB{%>XY z?U|QRw{$Sb_VV&=CB~!60S^s|BXMY2_k(rXoaBF{atb2bli=1?>B$nId!Xapk5Sk4o_z^N6~C9MaX;nJWAaKeLsT&2`Y*qBx*Z4;t^I38_fye^MZWA% zPd0ciP_Ehb9>oj+?GFa8ZXjzwwTfR?F>a;C2k8B*z*;@AQ}d+!H2cZ9m!J5BfzkZU znU}4VD14JK>+$s*ynE)r>B*50l3%%x`yS=sBj3HOm&xPc%7bH54lBt(j9W``9n3@Z z3%+xr*Fuos@lMD2b|k)|L}oPbomKnmQW)NKrL2Y3!NP>_0+PfP>O@ z?YBGRac-qU)buq0nR>~!Z@kDu57{j95k(Sbi6MJM&&H$fUB#0uDd-a3yeCJt3U zsGG}P&w)#18Yg1q1E9X=r~c2L1mq?=wVX}si-&dvlP}-b$J$;IS~!jpb~g5d7>4_|93UlI1jX+)=pNSF);UWAky48H|2$%Fh7f%6wPpnbRL(dWnC5~i@uAVr zLT?OpI1R&;VI?&nyzSvf~%9~YGL3lg~7{|6x8yo zbdxxd0dM1Ef{a8>@z(Zu)YhkbAb6QY1(D9*kVR-;H;~al;S!K#P9S0in@f7ctGj45 zs^831luz0__T>{KZizuLkLTxnJ(O}<>t_;5P`5QN<>L<`vdjHhww}l*orCG3<50Ve zm$Tf!*f|ep2e!Voez9h1z`P@^*tAfG!@wYp@;^ck)^IKg$H5orT#e{!1&xDHg z55L9fiZS7y&8sq!M}2(Z%}A?j5K{dYV_UKs39MhN9xiM+14Xo*@yO#85YpaeI%c1a zKlNIc^=}3t=j-N`vcq}JT#(yu&1^=q23lWUs-rR>=d`^VxqnU(eyE0i`zhNJG+o;C zTmQHZ(Cv3@^z+MxOGg%sc80-!&eGF5_2O-CQUC8pmwp{&Zh8Zg z0wGAH^7hC)Gd;>P8e5m$O@?C+RJJcF8DmwA4_@TVLZ^VH|Fkw00+#?Kd_cAk3%bs$ z9XCve3Zq`liJ?f)GSk?qLiiDv@JJW&hA`NsbY#NoK|V?@I_y$dj)C^C618`2i$S09 zxg%|TIlixxDxNwRhkdF)@+lW?A>+%;(YJh6IMFR4DYQ2e_Kci8T1)Cm+;L{#hROfq zjd@+tfN4Jb@dy;-mn7$aWM08{i|LTNJ;td|(+|J=GGTC2CA`OiVqUdv0R)<>pP9_f zhO)cQwRMDUAxnw%;-;J;h;e=tWD)F-TQu}z#}`vjiS6FaaOOhrYTjg`Meh%%roU}- zBlkW_O}Uz&GdbWe)-F>iZwgETe;iL1`5=9j8f>*ofWk8uscC19BiBIKK+XyFt4 zO!s}*m4;LQ4V{GaU@UKG8dQFngFP1GdlTPe!9GFH8)Y=fpt>YNJschg7ptE+yk>OA zie2w%RSE-f=i%1+=ONW_H*T@g<6j6o*gM$mx~&96=@aDG@=LH+bw{hntym~=czRbY zJ_wbnmo7U{JHe>S%LmE+me}h0?s|ML$=&aZ>)cb)08}yKcg}F+042cQv4DIYe?2bg zbjp^%#a$`<18?%d!%!>lVeWO1VMwW=eO-xPicaYU=~aVIH&`zXMgTYg3M zLm@_f@iC-U4nPyR+g!V4m7%PQp@PHB6rNm)%9EH&!d-pS)>ye47XwpU(8ozOKL%(QADFRn$UxhjL(r zV+6JvHtBwBqd?nl`qwOL8E90YG5_~lHpu+(-*)D28PZ6F(Omx$hBfxXu73s-u-C$& zE8$8lj%xk4tD!UibeH#EyGs>M>M)&14_((Cs>|hEBbOX4`M=1U)wMTO@>b>RHSc<{$-MclG1X4 za%8=rswxoqw4MeAy#>5MWPLrL(pjhaA`v%wvqkIK{jsBjZszUrG+gir_Vsp&1(_{Z z8e88bf$Y+{7uOG7+~)ASd~qZV_CKRp+caJbOmyV}L#GT;e9IM?s`uo5IiRvS8SRUg z%My&9Dincnj*IBDY#z{#%C6{lIKcNzQh1~b$FWP>GCp3u4JCJN^7fH_t)X2Y%N6@j z%=x&%^zD~BYt+H{PuU zrHPyHhM{_ne==07K=VO=#jBr1u*Gn&_oi7L_)AykU5<5u=^f0`2~CZ_Q?unlrnnFK zUyYPYnIg{#LuBZaHzZH2Fgs9B?%V6X6HOwwmO=ht%?_qtAvjKZL5VN>Hq00f9y>cw z3vQB{FUF@5!0poO>kZD4_~Oog2fw|p#UdN)y?=kkz}G&S%$A4V5E*#}}8SXm3DrUOlJR#zY! z$xV45yDR2Vh&_&iw_iSt#OLQvOW(Eg#FIWRzA{o3K|q(h&=AR)P1v&-*bQBPc_cGJbvL%QZk-D zwwwR;b_)DCu-7`mD-&-?D@9x%3P#_m%R1&~(~xc00p6&1gX_`?qx98CytQ?y=lz~c z=xCZ)oc!*Nd}FqI~i|5V`4ro5m;#%v55keq&F zQvepmOK&dh&jX*HW0k9{^(5zIYf9f#j~!!d=3nO$@w4D^WbKV4*!650q)6SYU0_U= zQ6L^`6xHf#+N+@9gnGFf;eZ2vZwTn^h=i6fb%%#XV?q7D+av6jsrWQxw$l?*@iEA0bXvh7o^US5>H5CxuZHmcYjkzVrud=PcDUzo zAo#Oc96L1Q1pZIiw~w00VeCo2{RRI?7qXUSz|$z%xeg$#eatN`$tH z@IB)BqaP)^Yj96Z;(_AS6g+Uk(E2;!Q>G*iI$dHafXG#*HnWao=-2%wI`NtUU=8k6Jd<{LKf!x`y?ivqjjZcjwcG_F5PctE%VJ^n`PvyVm3&A5&+Z zSiYG~!b{%eZ>(jLP%6Lkr^cfjpn0%-QRjsRJe_#6DtNgNrLJ);)4<)0g1pRfnR>BKhduLsdL+%CaTU8uX2#+3;t8jp=0Iv&nNWa_e z3+tKBceea0gZYgvDl3634EPdFyHmmrPWyHQUm?Dw@cAsKmev~dtkrUO@gWvQb!e!~ zPgcP_$?r|OWDDWZnuB>aIcHLRs(a3*mkdpHUAwrpgy82-5}m`0*TKh4QE&W&7tAgs zv~ZDpk-SUju*lJym~zgh`h!U}cE`pFcrm5Hk=V4jj8|7NPiVv@byEcPg){PU+zde5 z_O|BV?s?!SGSMQQm4gwMktgzo(t+yalx1yTDfCAiMXxDtv&hSYt z9Oq{05GChfrz`TJd%`PlUXP-8IEVsS5hiAza?Ihn&b4#Xv5^>F{9l;i?gEIIIJoIK!ReH0G^O+D=8g;EmFM+?b$AvAEDozN%9nCiuDzA z7lVMRJtwn_D+LY*)=T%?ECiEN`#1-T15o0Ww@zPK0k)3uyx3Bk0*n%gpJ_;c=irV{ zsZDjHPV_?S)^-eq*yO*Lg&Z@$MZq=ItS1whw%jXxrCtik^hxVq44N=>tXSg5mmt(v zR(7f__CUE&iK35%BsbmCWgJx22xrax50y7JLsbjgUw-RSOt63KxwSeCE=k&)p8xCu zf86euaFKko88Z1=#g@WO3*CIm-#lFFk?AeC6Nwe4f+IXi^I+B3!))0m07Q6d7#fQT zvFg)do~zx_@W?M_>~vo?_`5|rnrTo#&0fdDXtDvX2C8U}UQI*mRKxGLNdD^ZmQn3C zH%F9e&!NdKxPdpy7R`R;g(A&`%n#;#Hz77?#&Kr47)B?;3QxVy#K{-i&A%@OK+m%C zpBVQ5NbCAZJ^ZQ^hJ!EQp2j3-;kD<2aqAyv%%Jb`yS3&~LVm;qdi8C~7 z7|_tTl)&>R*NsJ*;&95@b#BKEZ?NC~t17^;7CTOb(8tghg4NF7mn2EwU+hrl6B+XN zy3-M)w~}6nR*8~Sw&Wh+pgU&JAkhG|<}6n~Y%TS1gT({|k zRWKI&K5jAN%fyTi-;TOIZa@>yrkKLK61X%WHSf-K4co0Mwsd{9z@*LI{0USJxX2pd zYyKeubgB*qN@NFMuNYIem1`dKaO89+52T@Y$9bOFnqqi2Ih>fD8V?uQxZU4(mB8?) zuMbM_7TP`W7ui9V4l1{9XTFehLP>S?`~R%!K>tmM&#Y<&UZ{{ROB)MCvsSH-e=9uU zc^un&=E^uc)2hGUf#eX++~-RV-d%?blNx<`dkV4XwW+pML@;PFYl`pr9FM9$EML8A zNe6DVBER>-Zm95G5C_#GeKWj_#5(U`qTihtBj{^4=b<)F_@Yr7w9U`L<(46S$w#C}tFn;Cw2vIf8M6UyPJy=$+hRePH#hO3Ng-Y;2iw+eKWH7fcUk6s8V(j#=X_#tBDra2 z%etln+%3MJkJGLYOX zysndp@{M?^dLy(hg;k?G!(x?`NdnStgmp#d`{S`=KYOBCf{{x0JhRxmBJp^9|EL^l zi9YA7{A2Fm+QZ`BReV*kSvMPKSE z(DikXk`*gC=a~PxR_2#Mazs|Ri#HoYJzX@orA={Yi^eH;-xOG)Rn<174@TX4vQkbo z#n4%uuVeQ)8js3*$OL~ifdU)(rG@!G?4GtXmi9_Up1l62r=G{52Ms^lwy(aphw1?n z%K75(WzFY9!T#WOi|@J~PX&xu#ZNjrl;G7dXn~KUzIV4~LW!;dT^i-?Tv9d#(OsXP z4BTym&>g!Uy}p$VZ+{B?d-mBLxA;%aUiNl@z^7OZretU$wGzym%E*P&D5Z_kZ!5_X9Fy6RYb28r(Ucc(Ts9O<;o8~VHtBIt+iv8&*j=ec} zC`fNESTP1Vwy{li@RvfDG4tuzI!{<~A_7tU9H=(jW$caO*2>P6t5svw)4~d9 zvaj=Saek)$b6EtgZ`^faedYqa46?pmmZij7XRuEg@^CO?Da~HO19uLx-edSyje);n zxG1&Bpm6XZ{SvufnW!)RP2Hb|wmS+A=DzfYuJtmRr?EvalgDiEd^7>;McJ>bzDva= zRwcJ9!A;n7SDnALr3^Tfb`NB0mO_UAA{Pdvz_P&uwXR>sF-cA~R*AY0pR3B>>Mzx#ICESFKSf;lnfoxi~rX z>cFHyE8=nu1&cA=ZY^`&sT&&ude=EqVu-(atmxwQ(1>(6+V-LM zSGqqk+1Kt?POAh%b)l&z85A7LZ2qU??gx5UHU;eg}^;6IFtRa89nJ7qW&#a z!nnu!o+*|PT;`!SRn&^aB|PhyClr9%n`$hy!wD~TGI&CzB@r9NXyi@f!g1;&)8Gmp z@sFLUdZW}|h>s>%r8ci6AhY1MfDguH@ZI3OUcPP;@J_~OpSrIDg|~$Ld^{+)_(Qa7 zr{f*GZ)3Um*rovw+XYp!In*x2W7NoN_tyg|Xg7Is*ogocm-OaaRsY>?2D;H*8kLX3AdVZ9%>7yEybGQ_lYn+bW zIlCU!eM&~vBND{}Kb=7Hmh7DMF@N~7QakmGCK{5i{Z<*_&xfas?dk6o-9Sx@d+X!T zQus$3NpX1A2=r_;-%{+8@w3RS2VvoPP(1ln$@N|#tQmHEawmO|?>QQWK2e9mnaZ6* z?q+^)NV%2iQ)Vpg+Om|>*d2h+HXpj-9}x!6lut66JxPF%bp2l54=wP;x2_D4mS~XK z=GSm(E(Qd{e~q5qlm+t~*$Ol4fyni!$**NH0HNOPOElfoSz`WK=9J1vUQK zY8-hLg8x0L4oh>6CwW1x=#oe$3_Q4=Dc=}?pB1_q&ngzfp6;wY6}|;%h0My$tK{BH zCF}U?P!J?6M42;QEk|mP=~5fNU{HTl{x9K06$JBKd?OQ5jS8C=J!nE~u-TKstxga)dSi~%&tmPz zMC-9Fto#e_1bGhlX>W2brQ`Wm0+th5&`;-Tcgl9InK%0hHwZc z*xKX7{4wycbeMuwIzE5yt2_1}5$EgQU0}9N#6#Uy=2=gRarl|Vm0tea$U67>Vd_q@ zpLXV|ow^)=IvhF=egB1nnI-e>=Au%NSmV6oc{T$XR2B334rqe_jdVhHa4q4@_Rc+3 zu7h@(6wxKcbMTaw&wXMd2#&2f})!68G{@JY96hsSyfrDGH7A9E->1@}33D)7Q~N zIPl}RwG^1PbDny4EFDe{<71iGM9_P3sXeO44f`{xicjbH5#OD1C?AzOmNUzWKBEc+ z#)3cF*qyS#LfZLEQD8Fe+Rn3@-=2ZN6AD$oC~r7D1|*JY(o4d|TVnpswhx(jU7D$jPk9exgWx6u*Ay7_%3{K~CCN zR>WgjxaGy>*?=S*8Q8^Kou3Uf0+-)xq$lHYo=tr`B?-PLnU#u#WdM`sOk`MH3WRrN z&7K}gMTeQ~l&nxcps_mgDAIxCApCCFum#qE%t;2CcbT5xU#z5dj_^w(JP*3Rv_^pK zMUJ=YBBi)^=In~|h8aqpuc(|)N{9HF8$B}eDWDA(diS>0L!!D-U(q$DFD zyZ-ZP%-2Fta#s-D;#CS8KBZ#bT6tL7bH5~{zYhQE*e6R1#bGObF0IPZWC*gpv+AW2 zhTLL#utL0!8Z-9BPU_XzToK}@G*F689%o!Poh(4d+1LuUwJ3ae??YJ=8}WK_->%IS zq=4@J15E2eC0KFVoYyIvaL;9%c0X0h!90og;ryJgkWhO?BY7nQUkx|bO`j@*^V3wh z>t`w<#MSbS9N{JgwT`-{ZmNNxC1SxL9S`Fs{5cYH0% zIeWDW%NF2vH=&?C-YIBPldU*iABE9B6HH~5e2A|taN=%ZEr>^F^99&OLIW3n4{sgu zSTU8~{&~9rvzYa7Y`vNU&%}B>L|V&m`1a2&T6{^^DP^g*G?IpNIl7u-KyoltLY#UI z$*>-F%&k|i78`pe5^inJ0RQL!m#Twlgp=|XvRd+j3yt5)Zq@{2;JfaY0ogE!+r!eUd@=Brit}CYp+62W|>{ zFHFW8it4vHUew^c%kjYW&R{rB4cGF?x%h7Ix0CBmBuD9*Z{hwtA6^QvuSR_hgy$ax zzsTgcI}rzBj}de&{(pcd9ose5a?=@eDx| z&g>=Cpi*c*6*(k1YYc4@Ce<%V9fWCq!r|?uTBsPMQh#>P6GOA+8OPbo*e&RX7c(?#G=c|4MT)dH>QCOPyy@{vyUuqw6_ z&ou96jbH!y!jg2F-GoLy2ylJ`t0$-1oGvV7SU%gN6 z3?Dz#t(DpsVY6pKQ%Cv$d@3tZ=^cc;4 zO*r~u+tS;wtO`MOZ|b4gzvTRrx~wa7p#Vjs%EoWWS3wq^+3~|no?z+u?wgW%HU47f z*d9_@4Yr2K()BW_z!+T@b&~Yok}F;*evTsdl0Ug}FI$T6SL>URk*5XdBfAVZRsW`yjN5d>0nwh|JyN`L-f+w*0otWY*h{00+J#3;`$>hHJB3!2^9jAFkY3KwJ zF|>s*dU^~XM}y$_8*ANN zGKBMGz34V~A`&NSr|skdE@96%#lIenq<@@gKWlQL2>oGq_`@1mbp9lCG)TJ=Sf>NF z32GO?4*AWkL8MQ-LjB+evX!Di_m$0?O{4K-flc&)kQ-cmWtAuNBLi66YqlI1%Et6h zQ75g>h2VkR;akwNJMAIDP+fmBmCb zo1GTEc_SUE%CgNo%Z$M3@GhNZEnk>@$zz-%90x&a-`}hUWZ*7vI~n}EhleJUkSr{D8j*|116}@Xb66pF6nT)%Gt#4R_(t&)0k*<8I(= zX;>gyM~KH4%V)sM(^Au4LPSyHw=4G8wl=K(I?j7Ly~nc z(o6|I<|r$L;x0D68Krbc+BtXcutyd;oMrXZ7%@cIBzlo#JqAEM;RtR~f_M;J6 zve550)vVa61(R>tnJy>$W4rwG(d(VH*kE;6)%7*urmqW~_Sk5`VZkSF7lz|e_|~q( z?x-TXrXUrOF&7V-zI=%W7FIC3dveY*vkpCr1>Wpe48`LDmpMyR^MQL{e2@BvWGGwu zr*-p^E4*B)Rb?wK!T6Z#C9Q>y_;P;B&+gOJC=)03D7%vEmz&R7b%}<+?XOYuLb@d& z7b(R4bvzc5-fg0}@HQ5dj@Yj-3D@F>F-G(1sCaO5>fb*RUkN`;v$}kb-G=dp-nz`1eu~2*z}M2z!-|CYR47KVrB9wr_sF zx0>~bml9sKd)dOF?$sTq?fR*= z3rVPN$+!~JN&(q0wU!ZX9yE09Q#`kvj%^yjkF@ z&eX?~Pi(+nzxG?PyBx&pN`LJWDuc~}g{3DJ%CYD1m#vSkctA;V8!C83V()!t%IOYr zP8&Hdwe4sT+)F9gv00hay>)b}{J#a^=d&MuR}|~Xyr_gQS|4ltYNep0&6)#;_xx!$ zIFSa+&jRUhok+xUovMM6Psn}qKMDVmOA(ku6L!buRvoNV_ANi&@PwfaLFF%NrBJSX z>sgq29(ueQoYM%6M<N;0&TmQ>D23?y$%6y=hR97Nz$*4I1*Q!vZr3Fz1H-$y&cdUF zCu_9jFF9v>m~Sd~my?`!$s%kY8DYO6ogg?FZGqb74NjFuDc6Q9SK_2W{v z+k+qn5B!v1O2w^$U$S5G<)BD!1LG|5XDMYq+2`~;7lm|J89QU^;OoinKN#DHKeTqM z=7Lx)yyj9jalLU3mQPBShb-EG-NE$r71=Cw-Nth4Dfv9Cx3A>k&YD7H)roM`&o}YA0@x5sSrL=n0AZ6VZwv#p}Hf$84vyo^^>#92JpFif9K`1 z*7#Yg^LzDc!mS;vH6JuD1)X?@C-&l(P~&ZLM9HNfkg#v4xnoug4B{-OXbuGcRo~?r zhTSRP?Ef>ZVSf$Ob+P<=B$kTlQyN*nt_ERR*1mF{a}hYZvSr7hY7)9cdNa4xCxg#Q zV6NELL>ySVl3HZigsht!J%ViWVST**MBs5RV3S*#qg{#z<*ZEt;a77YQsU;LJ(vf= z+k@4=m{5T6fJ_*TNE)*5zR_K~KMYrY^rm&K1OdJ+8}l-cMjW=#5PLxK8jD3MW9;Pp zU3v93PA#3}C%;WGcBkVBi-(G4j@H-|>uCRXH4V~Swsy)su!k*q)urhICE%gVAgk3}?p9*SpftWt02T zKifRC=+GLLIqr)}f?>I4r-)bo(Pn4O;s~TrxK-Pya*%^B{&F%61&wX~9&yP|hm#}i z4M7clu>He16^kn=u&~#~JLG8=)UDsl;iJ^U5w&djv$9^eb8>IlnrR(O9+sLP{RTKk zYxh1=EDuMMRF_J_EWnp~n3=1+2>0&YlFACjq^_@y79R>=b?oLklUg#;u}XGXE+^v< zOPYf}tQ#lRyKCiTfd#P9CC zz$A1ZA3n_xqm~T>AB!fjwa(ih{hJc{`bY^%{gI)`U8sd8!B@5y+dJU;vrjqH0|~$p z?`kYXU4<>y$Ie-Glt4}N?B^8ecsyb+cWP3=0r?K~{NafxgNL5w1#I8Tu>EBGMH8*- z*zh`)%H&K2#K(Hj@o&q-f!8UcrEh}}4!qI&UXzNsP5&s8-BHNdCrp_$%*QMG&sIM~ zX2G?xRoXB4dDuE^To?E{3fY-Q$7sA`u_wAmT7Y5Sr%Sz@f!y|#u)C{HDBx!1KHi)M&j0cS#lte}04DB%umj(XgQ4+I(RxnzqE?ns+;S1Wf% zBCe@z;xAP!gXr%arfnOL{GL@vH0zsSvl?ks#1V!4%82A)mf{EbPE=|d{RH%pYR_8 zPXU&vzWlmamJXYD3@?08Aai|oIZ|!?l8VwjHlADu%CYX*z8m-cT!4LDb6vA!o?OJw z18H}73PAY%w3dN>A{Kt7K zvGD%F$*_yBW6&n}G*54A9MtSho4vzH{K!kv-7h;S*mwU}jRQv>jud9iv6kfHLo@ax zDa325BkedKIF*8Z4Hd3kue^XNTD0k2zblUAY9%IJO~=59!J`z00@!Ux;~6zT=B8R{ z?Uc(-hF(jHgD>A&;-1;RF2!U&Vi<$%oj+>fW5K~Kx3Y5}A!*kR*C=(QeYqqgz1;>k zhupfoZ_OL2S-BhytM%bW){1?LMk<``nZD)3=MS~^k{@)*oXXW2b&>{KF+!f-m-G zJe8~9Er-%A?W$Asf#97Tbnm-x6bu^+?_oNcj|;LYa_fu%U{V_L)_2+iqF*JB(On~) ztgob}TBbY3i>Mp%mZZUKs7t-XK{6M?qIZs&a4kKhbPK_BDJZ{DTVtN?fINeVFWL7N z!e)Ez&5=Smc(8)rA$Kern*Gq!bj%4)9C~{GSC%d0i@8jEx)20vFNb&JuGfQ5chY`F z;cV!t{%%=J>R(sr4$c@U6oLrbK5ZS*G-A&04qVfWz-;xE6~l_5obzR|L7Ea}fC2DIEwE6+#fBF&EArYz8SI1`*t zIIZ*I-4*`{8lsfeKs8@NI>xr;)!m>f1tpgd@7>ht*uz>To^#wB)DM|>GG8Ne>`K_f zeXj@L$KMI}&K}Ff{2}^Xvg!b{gYW1+k(|nQE_rPl?{K77s1JECm5WIu(r{Ma4XRg} z)!z1&A$N-JI}P&h);+Qn>gM&ZN0BFnQ#=6*qv^aS+{yf5vHyb1LvMl~k4Fy6F;bUG z|I=Z%TNCabvANy7BLXE%B4pi+3gE>i(PCl7Ix_#|o4@sPA#^>yAahkN9&d?%6fS>Q z0#AhPtb?Cc0xtYI-L&H(ie6hx>LPuHhxfhCrq;8dN5E|ZrX$1~<{{|I^&}W8E*y3# zn9l;OMBXd>Q)K<$y(w%-p#<{}|0zrEDnq-`kFO2th)+HzrsD{^86;JP#*Da^;~YPW zTySRuo~yKYaB?{ne#hzjCg=yIg+BDC`_CF#e5~Yc&thRv{xA?a)(9}Xp z$?ECE3yCQ8Q@-X|c>x4;i>l}PBqHUdi+T;IOUV@{G4MJS6Ys$WT zwL0gT4?fj}u6~Ir)2vdgTP{|t^pC*#1BC`nCZyk~vixWCLMl{@Q1`vnNgo%#MmBtF#1WnpU)#Od36i-x>%F}QBaS$Nfep&I9O*4Kz<^J+%j z#+o@C<12am{%jIx2Yqy=nQ(->Q<{5TDkk9IX``*#c9xi7c*yaK_Z_Gy**7V`OXhxG z6@M@KJsjvI9o1FZl2GsLaaHG_G&nx>#2zc|V@`e=b-q90s&719d%AcWFT}tLKjJCc z__d=TBi9`}UR^aR5HCR1BG=*0kJrJtD89r6OToYW&eB-WpPO`^nvrR|SsuUM;`9k_A(6Htn!)5R_~(Jt4vt2E$Ry zX1xjSVB6?>d%u4nsD=Er->g#t3d-M3@%|`)@^|CvdJ4qjcIL9u-`m-EFms)F`m^BE z!w^}2;wS3f|6*F{el%|BA0iuUB5dE+U(d0V^hKMkF7D85#2eqv-7==C0+lzl%`BQp z@b&zFt#@xWd^fy!ekCLjHtR;0{SHgQW1ok0H|A5}P8Am=ai|1BUTQczstPCGE%9R; zSb|(vdz4g13!#yV>W1`J;sG$adz?wgsdYW8ECW4snL|53gvt!JXyZP!nKIC5}h zAS1l=YysXk@=>;Fpn#%0i$}n&aCjj^nI0G?ec~ZLuFi0BUs-lJcsDv1L(R6Da)s+Y<#l&meLzsaDR`f}8Qx4C+OSqm#dDhnM>Y70G5>gDQT#?Bx(&OZ zhkYTSQ0aAMH|fnybT2Ka>7-$w+oRYyng$Sl2yANSLeV3Vty8$d4@(t(i1LXf!DZ_4 z2fGZ&9HQjgj*b?(xL|O6)491|=-D>mwZR{av1fmzdAg?J#NjhHIh@ISq$beUCS2`c ziJxy`KFM+2e>;*T;SRi!O1fngck%V@J9MGe#D}}$&N>`&4O=X2=&9?(Fxj4a@-FfB z*xA+T{N~7pKcBB_u!YtGLv6d58@CReym4k{^$4l+UXWg?e_98N$Iov!@hgVOd9m%M z{+OZ2!V<6EWCrk@JEiQ6@12eT*R-~}&lk%~?kd=8J@wEMFQT17Q83z2?BBb?FA z_Nj$l+pN3goy{0U_b=@_M-6I*t9v^iw?sA0;|I^j6k`87&1?CjeiPnh+Op}MEgB5f zC|p=4^9e(LrSP3jK_0c82`1NLpia*_X-p~$^+dO+{hKWX3hj=V9gT?)PPKnb&!5cA zYO6Z+?Or)LACi1N^gSGD`Fv6;E;zy0Rv%NNB*MqNeJ;1@cNz2us+jZ(gg~VJb%{cS zT>P1l5gR1R!;itWiqeyZm@wazbEkXc~1yhl75!xO8(+TKAA^AVX{{W2CGNQgVf`tgu@bO zzr&ac(Iz1U<6nw^;jDf07H$eU^eT=-FOYdA2~m$2g>&G5#ME4R+YR_|N1SSzx*Q%j z@Fee+NPd&Rr-1a6X-wAKpFenxyxf!rLcvcY(gT5wZang=F4bm^4psKOxHzhPaz zMPQ(`mFmH{Ak0}~)0TJ~4Ur#wWseG_BR$WNDtUI|57t{`F(>@2p6%{;qrsIB{Z{{Z zvt=Ge#Lq1SaQnl-NFQT!-7;iQVR8Fb5`;^ew+GWKk+~T~`Yd|e!%)AShE|{W4*F}X zZ@8*w!2#GTH=&-59&S#vfwaUY`^A3i)4XKtKlwD;JBggSpx zS$ytkCZO6Bm*-ZeR6KFlSt9aTFj92lHuD81B8_QdDNklHY;u@!y8k#A{jHy-?RKs~ zi=1LcQ&sZy^{hIT1@Sn#Y9!~D;|Z^JYe)K9Q~-r%yR)Vl;rWHz+?DvvkT%6cRf8iF zwI{+J-BwM9$<ITW>>~kx>|G9#A^zMl;na1G-UIuMRg&2^xoT^Q) zDneSOgH78fl5tXv>d%W|;3cRimSFO% z%#H|}B2;7FD>kE>j9Uw@D7SW}fKFZOna94iI4y1NGO1dGK?9UqE&)DZv0c9JUY-*& zS?|*PLHf&|RP~d%F8aV=W5p${xmXx+WxAqqEg!^wCzpKcB>Pu=g)P#Jg;4I}Ow%Wj z2Hz`q=bNiYhT`}4^c&>+u6~oEP!(+&@=6PQe*4=6{^(pEa^fyQsx2@0t}mJc{d5+~ zE|TvKI{xP;`?E`+qw*t~hB_Kw@LMv7Ygi*M_tsaRq5|O6PF(-Hr-38og6&dvP|LM5Jv<;jF9I7)cb|`vyh*H|q1%p}60G_-GdGY!L7qR?4O~|<(8KCT5G~m& z@LsWz(5cNu#&bC#X7w8I{&nxe&pV4@RE+wf8sY5zS)!vmAY=fV2{Y<37plN(SiM&H zOEKgx`=w(0A)Rt!5Cs<*$af_RsAwk}_-MC;NH1Jo=;#uSr(Ed7lb@nd~Uc}Os_ zdWmsd?o7aWdzrG^?Pd5TV@7nnAObtC`h49jb&QbLTq1L{`n-iHxZ)xO*MS5)}j+`;o`cX=O z&T#?;CH*fti+RT-y?Er}mMPR!PDPzNY#}@|g;@NyO8=)-B!uvIpy0{6})Sob^SptRz2>}7AlktyMS z7V1s>21TcCsRkB+@w89z`)e7vTATCfu51~ZPmNsF=2UV^)hIXcS;WPm_EM{p8PI?{im?0WsR9;#mM`s(^U1l^A09DRBs73dVzdw%>5 zCVq~k11B^I`UCr(QF`I%%`T~*As zAEm&Fq%s4ch;WFI`k88#oC#VXv;yy#gOPrmHYzML6Q^|b)}oXffL@$a_sW}8y#Gk< zw>@JvWZBPkq#77Q<*~fa7st)uzzEBvWo<05Ub}a;@v#~F>WF@RC?NyStr!UT*&(WulpH3v-!FV^!^}7}E zoLvlf9nnbg?yqkgj^T?(DSJ};p1z5K-!?ApTlN8=z)e9}%dHsFA#{FiswDg&b<3ptQ4Wc)bXe9xkdclfK39)c~r>uf+F4 zr^4!>m4aW8i<+}18<=nEWpAmA16{R{a~9`_KZE~E#*46A(z|YwX%wKKvG=|ew)rYN zYJ5RktE~v+YaMNsuaG}qWT0__rv`;S@9^1-UMT-v-;s~(=?-s1E>6F9#^RY+p^&}# z@ZjmirFUFL@ZkvaEZYTl&^dFH&#cMpZ)p@a}rW%weI=hCkq9tkabx#4+gvTvNdO?BmV=F zUCZr}Sbpb=`hSG8bM)XDwR2ySk@b_b#@Yn&&E&iYFUf61@n_2Z$`k`O1vHtBS z2L3h)AKth^c;S0$TSR{roavaX4Cr@;aV_%#wq!dHZf-MvL^!Yy>z1Tf=}0DX@?Bwh zUpX=k#MXXqD+T#?)#{bJe$Y4=`8TL65UVOAr5?Yk!L(QT^QP5w0$z)St=0p!un0bsDq)O)vPKpI04lj z22Q;$_X8<)mZcaQlBbEyDVf@D1*y}TVn*H>;Hi?lB>AlZ4QZS%D?NXc(_IY2%7QaLT+li$SXTx+b z6}1to56^q&`gN@& zxi=ixcF#ws3J*NHmDBEA15;94(%h@6$e#0t_?`xGuVgM}dFxUPq89G8O_>>h>J}rS zq%SgCT=gvRaTo+W`11URtuwIY?!M7~al4+o>$;VAcc!naS zIi>rHNdM7s+l9Cju{b96KqKTm`{C>s&lo~&%dT}c`M=z9| z{?nI&|NT^$8GI859Q^A`lygaNNXkAcvorwNT-JZdB&C2>p7$whvpf{Mqbkzt$LJ)~pPx z-=BcJdbA9^D-_(iVxsf%TN%C*TUonvn0Qj01a+F2UBF6D*XpE6GWJRo&K`W^4%x2_ zn(SqhFkwux+rTIvIyapzuM#N1PcJVXH>^$r(U6^|{Y7GM%YD`WiQF8lE56$Djz{4M9o=VTN&^+q6WV%}n{;`by)_%(#t!^Ksn>7xCBa7ep#@XXC?Yx4p}xPZoP} zIn8D^4QTV2AB^6~#=XHCt9MPxNzU5gOf zNPlgqW#d1NIGo)kU@|%xfIL|rEvPaGpJB^*psyM6X-piDIvY!J9_;UjZ-4ZKi|79N z?&H1#41UVithV>#K!z)BNHKuSkx!0RF`RG${lJ;Lh3CX`a5+Nf-74`{ z*e#^1TrGu{)!~OcmCKPkJdC-pmV(T3$y!=tCFt;IrqnQ~2AI5^S43IK9xwXsk)R93 z@bkqn*T#_s(0tG;!P}ky?|iadWsFuD8F6AZ>HogdX|#u`$pM zJ)#Q${?PWw)t8l^eE``PKBs`>%%Q}rN4TU)e{yk39Y>T zp<9y7;DusNO8jar-rPMXByLcKdqw{_&yl@UOlhcf8Cw#LQ+-vK@ovI{-<7Q7ToQ@r zW@i+mY7WlLuDl&<&4BOmC*9Wc{Bd8y$ZXIj;uCS4kn(OyLuc19Y1e%oct~v5o!cjC zfwunL8=GUnu$w7xHd7-W^nIS?f?^X&Cw!>qRJ4R#g9M*iZncuFcR65dZ#7j!+Vg6lk^?4lZ#I5(7-#dWI%g59nRb1sp5wgo>b zGiBrZv1hh*@6v%Tq&c_bpCQt$ZKZm7yd08iavP^vV=$PW)6U^ZIj+=P+h(#-2m!_? zzF$y?2I?r4Una8@tTfn6N@W`0aO=rQ(f6g`uzArl?~Drac^I=Ct!jSzVr38#Fn>3?Ro)?xX=>i`JVKFDv~Hm(u3i6 z@tUE5&76?KGUW#U!U%nJ{K^5E_(r4J(qC=k-2&TR29 z5@e)8I=&m+fLZ0r=)MQZ;B>yGqnVoY*n>Uq>eOa}=FEkya;c?2wMjN3Gujk{F2q%w zBYZi(tM1H6Z!OXE#!LwZ;lJFuH=wf9lXxh9`pfOkipF;-Ym;Vkq}MR|N%m|q>9rOG z&Pan71~WRe@UAsNMX-s9vuP1LzNEJ$Kdu737$3}*evJqFl?R_k<_HJTy;WR2vWeWE z%Y3~^U+{`<&d#8|2H0}@q=L=;SnzLgOW{A9gok}Eb@c=rA(18M)rGVWuiRno|5#!m zS5M~YqnkyT$Y6g*=Y9-u$9u@hn6yCeh-jrG;hR4Fb@q=1;e!a$Epr;PMnK0?x2~_& z)!6*+>ld$*B1{nt`2E4S1m~9Nfjzeb)(`qvxv@rK8gsOv$gyPPR9mUB-Y)|>M|{6t z&TYUGN;|Ez$Etv?Tz_OIbrfcqM(^7)-XO zs~=lW2IeOEcUk)qfL3K5a*m|o{i?0gJnTjIi`R~h>PZy*YFt0Xs8Izw>mSPo%H-pf zTT3&rTQ-L?=-{sEb)?Cn&t@X7J>llFY6s5FdMX zchFf9vj5sS{LW6q5~gFt+?!Te zlmRCdwSRFiI6}>>i$!m3i_z_#C=bKQM(k*r_CB?_1Xmij9yVrhN0Ytr!H$3OK@OLA zqu5=6o%g76bYuk{u;TAf?`uQ}o!zBZYE!Xng(cp4s2FLQ53h~+<@UFb6>Of~Mn6Fa&tnK4*TwZ;g=F9*2*t-XP*j?}uz5SNyj7sFC zJ|nns%m&Q=O*y7tOoFeUX{_E+7m)mT?t0cM!hNf{suN8(Q$IYZuN!>`hpnpL4et?N z*XH{TUQsdyz$5azvY%EO`{d8gg?gsL7ReVsKi(>Y+iQsqRTKGmWSh`#*VHVGZF-RL zMcEeLKaHKW3@2WrbJjmo5|gpBUr*eK+_M!G4>%}`n;@T)NBte43aA-wG~a4Z=9&kO zYwlX{M922zbI*(1F>vffZ?7zwr(ZR6PO~R@yP$TXdXm3-cKjKKKy5MHv^!m;$LWA- z!4oG7pC?0{a(edtfHG7U49yfyBlG2f@>y(YU8m>bgCX1j6|`pp=#YsmcM+J}Mi zy?2{nvlYAdraL*9W$`lJx1|m1U|iK*GH2IRF6E~k=-#>@bV2q63UWk!XPFD{MXrEV)@VCRZ1H@Tx+e+R*u zdzgFpmQ0wgBp`rxJLlQJ-iq-*PI>7 zj-^1G`lIZdbIHI`#=4nXCK-zwUMQ;5XQE`P%Zg@A524<9?>~kd{f*VF(M(Ilt<|Ie=biU6m28W}EZ*ZxPfK#~ zO^`)sv1bgtIy1Z7bUqLh9(aF@ny^F(2VJp>caC^XL;1Q=a1O|S@^csr_rTOUN}{Th z@;d3sh_Ujcvu4J`t zFUecV$(OO+;7P^7v?m-1;`P9xJ6hj`lcDla~!dG&S z`fmJ}f;A%^uMZ0(W7n%iqm{8JJS%@nK6udq#v*8^Vp@xl`f*76h93oAZT(mZyp3X>W^`$&>d2DMtJk6x}jR*37LE{ z4`^+odYIKy0?RFYr_UbG1nTzC(XY&9aGG&9UHyH+<=rEnerhBFj%oIqSnkfjXFUcx zyO~n(y286B$;#=N&9_7Jg?}sfYs|e3GAe<6Y>5(A4&}pNSI4f$Ukl-9OT6;2$$VT1 z{LDYE+BEzXtjS~~`LWFK?sDSOam#%8llEUKPEF@LUYv?W zAIb@K-`iO*qhMC_%`z99vNpfbCOtQPgRZ1A_N;+2_`P1Zita}zA z?Qa6o?(~elhthD6fjU~EJQ^(iNyc;N#^XMouJNW_N+>3GT5c~5@g7%RcE55h1uO#h zsPCSrg!+p*`h{7gAeHw%vw?88Z_R$l{OG3+hkkw>$U2%17w2N=-b@(*>-~$0sx+za zcd5c%m!=Ft51eHAu2l|`SB#$?t#`rS$Ley~_;X>W%3YR2wxKX_z1;A8aOVH-BboJf z{^)e(^0hC_rAWVnCPvZG70Zg$yAF~5&hueIYEAcO40^nAeOG!jh)HhUY`wJMGxLft$ z>fb}oF9|>U>+j9%471rN%knFSX}Az%^Sf>rvnD`F-qe3FB4w~z|9c?vV+8i3bZ=oN z+^N{uC7$qp!ZFblogcgqj|V$nikh8I$4aBiH-x|mKipRMeN~=(zg?~Dv@Zz7X!*rU zAI^|_)1stMzkejCn5xW9*T+Krq5IW(gSD`u?FT4ayosxs_NV8%2*;C;CU-IOHqOha z`U#HvVU63SH!B*|C~ZmoRVCjKc@9f*=f5X>J;A!mflva%Ds|nrB~$QG|F5{&MY`Er>yAEQGvOy-{sH#u7!#zYWFLJVKDG=slNGvA5s+-s>z7! zqw)LmXDE>sKpuO;(4!-DRkwdz^l^Kq-W|I%>L5 z72zFLeBIz%h6fFy)#yz+iin?iE3}Y|;Y*7+a6KL>giW6BGNs@Zk7kQ-!Wr?L9~zF6 zCcI$1ao1;u30F-dC1UNXCw_u)?vDn6xZgtCmYH~ov)x}GerQmMd;D$03y+3@(YJ|k z;qwjHNV=$zHkpvn-LlzC%MEmS&gL|4&O?u`h`dpA3#{&5{>E|5AN|;z@9$s?f!as^ z?FhI<_z@i^UAtFHpefJw%d9WS70O)fU@lL?jt;pQiO+f9L|ffy!%_uY8OeW#gUNe} zs?Gp6djQZ#awJ5OT+I!pP5u=}s<8IkO6*jTE57QX`S$)8;cEBrYD=6-hP%emLtYhi z=zeLTgm0u0#=Ghj+Pqb9MauuCv1S;WT=qzK8y5=7nSs^a>%{l`%1-rS7e=R!`}Vyxa@Eirb^69r}4dM>pQPg|`kpYQoLtUqV9EWVu_`F!7g zS?lV-ZHm&JEB?8dmKeR*u^I%SEE1-S`(07sbHQx)LK?^vXfz)-NyXb`B|)vOq#t4& zo5bWThuyDc4}_>D;2{y713bS>Fz8nJsfUB&Xm%oNJ$Bt4+6M})-g^{5=iOE*{#IXz z%6Cv749kSDA&JjZzbc`5PfS-=fEPHmvMY&8lOAlUzx=#IJxbiv+vV^z437#8v(+a# zV&&g(=TmWh5NpD$u@aFE8TEgk*E}}@x2a1`|3*okRl7AVXr6eI6-wVL9BqSEwgM)B zBUvaNo_KZ>dGF}an!G%cOWsfIXrgQl3UOe=COej@5_*iInX7n1a9^O8>XF-dIJaZ; z&5U6zdh*7c-Q1XnPIQ*i_tlND{7AgT#5D>!3A|XB3(CW+>J#<9^)Ep20k=}Y(~c0# zbar{iB(KXg%PNFY?tl) zWDF)PT}|)dR)?kX!8|YHH2i1zlx;{R79GX5+#TFb&YJ?hsv|sv1IcF@cUG_td!IX( zy|`0}s$HV5?>|lj+T_^%R~@2oA6I$-^PL1d9aCSV_BkEIoR@5dzlT7huR~;ucp2V& z(`bL>d@%f}cq`uO)&{ameUH}(x8xDWVbLxK0E%RK~PWRN0IGm;8I zx5j;UzN6sx^KV5Im~!#9LHC{=2Xf%LTyQ~~Xd1v&@9NMX1xJ5mXNxdY0e70Eo)F|`)Xm8|QQ9ZA5%@GJW+Gp50SLo{RXP##`*-aJJ~ z2?EXw+M=x;kP8~rgvN!K2A6OW+t|COondJ;P;WoYczS;u)|ytzEWAvFq_5xo zZnmexJ1wTYznpV{P9&7_-^EZ2T9Is5;n|OZO9KYym4o5-f22tCCLBHu?Jc59B%H6o z@28BZtjNz%e!_<2OUDXTznnZ7hm0R$=Vcv9-}i*6**mHt=r&)>hdM71(N$@?O*AZ;_=ZDIo+Gt zc-&h=e=MgGZuwiEjgX2a{-=rk3N&f3ys2%vxg!VS|NcLN6Ejd{ySceiLqi^Z|<4Suc31dV65*D&err?znd?F9nBMZnQnMJqwhF z6O#F!a>yq9JZ+OZ@z)B(4%iT`rs0z#Qc-<`?`Hkt%wIL)f6Fo7k$E~2@>owD%8IVX zSK@M0kSGy>1^#Jf?=#V4Kgnmi;7>khJt6%QxtpqigQD@( zFn~hd7sQ)hTNvU^N6jtIOsineWS_^g(PGSSmSM|vB7Ab?m$`?CkL!WUo3sBg7=Am< zeLmBWhupEHQuUWee<(6&;QmqK!=3tf~%^M`c-p(`^_7L^qlqoQB<|j zW?jkSmvbseQzv=pH78-IjiG?VwPuVFHQKH6yb!*03+-%tm5py>E?@m?+yX7V{1-*{ zB!C`Vvpcev^!a<9mwc&d1Zj__3%++qzFNrUTeqGr@cinZKN@0;R{C`urhToTKH2lv zWP1_xaXj7U5>o~a)17%eq^A(c@H%*ox)N-A{}c_8oPZkjDf&x>j_}8McYOYA368ei z9*@({!SSd1;}g%5P$NAy_!^mGhQIGiH@h5wqu2zIR z32$0Hmy+Dz<9zKjnKWcE@2fbYRRTeN{hSk*v!O>uWx;y96a_u_90q^2Vqskg6^%0m z=vqRLOm~#QgwegJr&7LnSp0g3&#^F=`DrdF_a_~HpH*C7H!g)J$+dC5;VgVKv{(38 zd=c)WkG!flmIPwS{3@TGS-@yw$I8r930@H3jkh~aeBvP2C#ji)QAy$fDizg0^Q&8C z$vp-~tm}G3^~t`~_;H6fq(YsrQKfrI1!jo9dF1q8GjMw3<#Cdp3uAZgCqJ4}$dh8S zW_unC(=0d4mgB9^+H(xPL#sm_B$PWg95@_U_Ic`N5(o(;mS zM%u@0BSCG#FY9AR3>dj(1Z;~8M|u&5;1ljS;CH!Ac1Sq@g{*2%yeTG}B1MOTWfB?W zo>6w$prHm-4ttGmI~jpWf1CYBNnau8u*omZEIv4HA~b9NDFK<>RhwAp-9f`>cikxPl!g)N)XDzhqi=?Opub#nkF4vte1v=j5qx;ReoX{ z_1iM6|G;sXZj#Bt=OPqd0n<0 zH+q+7LZ1bad+oAU&<&Ccw7KGB8Ws(=Iqzi!xI{o)_Q18`x5+5JxcPn$$*3sIGl=i23z3iv$6urPeS*yGBQA}` z^-Cl}{WDrgAyvXhR{AynGl2p&fg#@gJ4p}h$!gonu4L>!aWBl{dKomX%v4{v84d0{ zHKy;~8<9r#fzY;*P}IiDojl?(@F--{%av^;_g2PlKu4a#6ZG8y5l>mgY|Q+g8x~WV103y@ zI$VU;Z6e&BB7DXaA|I^YyRIJzxem?Oo{xp#hXXwRTZp$jQOWt5@}Xi3iY%I`;Lw4M zX&+4&emhJJj~!A-%>`*A+lc2%S+H6vKvl;Y2J%fe-;A@?0b}495knaYnymM4qm^sM zx3M?h89gWl4qirH&jur$3iq|&%Uugy(NpYHRheMn!0nd%r5%JM2CN6DOi_!{`|4<3 z7`W`ZEoc}RgQlB(Ql?6i;Td=PM0aTh(04EAZ(<4ouiPt7p1v=Hse3W%Vj;y)^6847 zR7V0Z85?xFTu%dq@|UA`X*^-qnbzpG-~#-$zhFT3ZC>-jaN4<(K|X0=#Z`G?4qzacX_2{7aV~w(bjAd#C&7 zkA$G59OLpZe*ky~SE`P%wZi_aZQ~E_liZh+r=37s9xw?LJkZT*Q0^35J1JROuMgFO*;)oO=qp8NM2LuE%%GuU1?BG&&@4-*AJW~ zw&Za!pG8(dts%PTG)&6ArSEqvANT~6zZv{!1S+?0oJZEh^sjW)pJnkj+j9!)?+|K?+cQvpgIY}AmhA@AXW zg|DPFNq*}6ja-#2QMl$c|0HLH`1m;Pi6oL9#t;4U^M?svZ^;JR|7qs|V}TSf?5Ty6 z7_%q3Pognf@JnYc@oBV5Tq%_$?>|bP@-u71VsXSQwDRtBG47TLbe3i&=YqfRLptd~ z!r^`~a+YulydK+q*63AIQM@zTy1Qz+|u${Y#zWMCM5}|JMH6mVq2&?$t+U zQc<5vEiZYX3>2u9D1XTuD%Iu6tk_PHH+Sh(>iEwZn3)PM#~C-{;;eO2M?w)^D2mu_ zd^rO6wWG6bU*&^=-(*337va~?8C-v38;GIPp=D`48CaX+xaHdROc1(ue9@k8?xTz( zdb6IEf@!|v{N(Nmq!LIGV7iimZ#@o`7VRRrILQ+^i_}fvxNS0U4dI1AH`YkUydK+viLu zjLCH_erYCt>Eba)S+e(AbFbVO6fPp;FcD;^Aai{V`*g3rxv0v;&v0TpnM=~~GyDjR zCw_F%g*(^6!FvAGD#OEYEUu-wn@!UUWB>6n_zLSGW9#IK*K-P-7SZw8VG)c8BX*Z6 ze^4-G>^k6w24uV;h#y`@;KZJo!;AdhQ0p-g$w^y*2Dhb(U3*BcO3TkUoXk6Pp3{%K z{F?$aH9ld1&E(vm^S_t%rWB)$8WbP?wuf%tU6!9qyg>5GT{$GzjhA+t7!^mx_dT_q*3sYR)UY_{R(IitKRWndrDB|64Quvr!9oYvmq`1ed_|-ZZnn&n-~qnZVIYt??i>Gy1Tn zt_rTO`&?oXp+IZh8QHCRgva-~b~4zZ1Ojhv55Ll52i+nkBGalAk?YRbxvSkVC_l!( zg)KV^$84}+a;6fV$ZNHjb0`uRs2Hf3Q zTcH@6gC$SfHn^TP;D+M>`=Pd5s7s|3_JN#3n&%WHp{Wq(LKNdfAp+!dl8W3NBJru_ z0OzyWWc11ST-!v>FKw4M0+u80WvdIKd45~Mat73vuDyNri2|y}9+nRCx1!beZJx{B zgx9cEMWx3?e3D^pBPIG-C_=U2e&L8S1Z9YtPjLC6)$zEq3?)fW&t+fXem4s8DwZ5} zYbnBH$9mH7HFwe@YCLp_^xz5u#Ljtq%>(W8Tg-aYl0lSe(cQu{5*pr#bT^xLfHB>f zn@^L<@ywRrw;u;)0|#A<^I7H~IAoDVu!-MeXa~$SpGcZ{GBTlkYJiqFs!r$S(|G# zqttOA^;|Veqo0B{Rs;45R3w*Ay-J%%orwjHXL2f@M55|Zp`^Rf%CIQnWjAp^=`DCKZ4aCmD9et&Fv>~XjS^cJ2t)hks93s2Y{`I8=rebmnV$#oUr zkRl^GL%27$cv1`USgXKafAB_sdnn=1-|6Cs%Z1->grC_$JzkFEUtBm(dgh}aBnHV| zXsCR9thJ0k?yYzs$3N?gy8SFen+01yqL<^QQF|C{4v=%dES!y}cI`bs%t?9=OQAcq zY$}9I(U(U)@TcH~*Opg=``nRwt81P%EtzZ4u$;JST7f6c`OG5iYrs2ziiLcB;9|<* z-*mLsVCAKNDp<^?|jf%*&JBB;*iQUnGKDB??XqX2REZg_m}(7vPur#=H8y!LVz0o^K3S60DABPOttd#iO)8wcnHf(RON` zz%t^AFiq|2p^x-{5``(&!HfQ&_eU#JJE;^_-K+L&+Ea|@W*@nHpLT`*m=a9oD#7t& zb|&v{d6>7~JAtb-9*Ua34eiZHgM`tku%3Msw6c+MyKXIuRu49GhN;`(7HjO&O!UOH zII8Ul%6@o%K>4egQxzysq?_eus-fl+FH`F<;VY>xKS}IJ20My0(=khP7&cPLRWy!8 zV^&rExGuuSGR-ngp(XPSyA*|AYPop)XGri|elnQS9G~mysDl_^@0KGMit)}<*U_b@ zP&kkrW6R|j4{Vp31_}2Xm;%gC`=850yDF{yy3$2B=AbQ&}UbeiJx;(?1&I2U~vf^;KZ;J{{3ClIsbZ(kmOvC;)c42M@bAQ-D|A zf4f=S>%gAH|)td>8UvA`>4}t`#u?0nWLP%Z)Stl bY5J;n1{rve@mj*;7uAset7q8aaUlE;`SZlj literal 0 HcmV?d00001 diff --git a/mylib/lib_BAxUS/BAxUS/docs/LICENSE.md b/mylib/lib_BAxUS/BAxUS/docs/LICENSE.md new file mode 100644 index 0000000..0527150 --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/docs/LICENSE.md @@ -0,0 +1,43 @@ +## License + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by the text below. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under this License. + +This License governs use of the accompanying Work, and your use of the Work constitutes acceptance of this License. + +You may use this Work for any non-commercial purpose, subject to the restrictions in this License. Some purposes which can be non-commercial are teaching, academic research, and personal experimentation. You may also distribute this Work with books or other teaching materials, or publish the Work on websites, that are intended to teach the use of the Work. + +You may not use or distribute this Work, or any derivative works, outputs, or results from the Work, in any form for commercial purposes. Non-exhaustive examples of commercial purposes would be running business operations, licensing, leasing, or selling the Work, or distributing the Work for use with commercial products. + +You may modify this Work and distribute the modified Work for non-commercial purposes, however, you may not grant rights to the Work or derivative works that are broader than or in conflict with those provided by this License. For example, you may not distribute modifications of the Work under terms that would permit commercial use, or under terms that purport to require the Work or derivative works to be sublicensed to others. + +In return, we require that you agree: + +1. Not to remove any copyright or other notices from the Work. + +2. That if you distribute the Work in Source or Object form, you will include a verbatim copy of this License. + +3. That if you distribute derivative works of the Work in Source form, you do so only under a license that includes all of the provisions of this License and is not in conflict with this License, and if you distribute derivative works of the Work solely in Object form you do so only under a license that complies with this License. + +4. That if you have modified the Work or created derivative works from the Work, and distribute such modifications or derivative works, you will cause the modified files to carry prominent notices so that recipients know that they are not receiving the original Work. Such notices must state: (i) that you have changed the Work; and (ii) the date of any changes. + +5. If you publicly use the Work or any output or result of the Work, you will provide a notice with such use that provides any person who uses, views, accesses, interacts with, or is otherwise exposed to the Work (i) with information of the nature of the Work, (ii) with a link to the Work, and (iii) a notice that the Work is available under this License. + +6. THAT THE WORK COMES "AS IS", WITH NO WARRANTIES. THIS MEANS NO EXPRESS, IMPLIED OR STATUTORY WARRANTY, INCLUDING WITHOUT LIMITATION, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE OR ANY WARRANTY OF TITLE OR NON-INFRINGEMENT. ALSO, YOU MUST PASS THIS DISCLAIMER ON WHENEVER YOU DISTRIBUTE THE WORK OR DERIVATIVE WORKS. + +7. THAT NEITHER UBER TECHNOLOGIES, INC. NOR ANY OF ITS AFFILIATES, SUPPLIERS, SUCCESSORS, NOR ASSIGNS WILL BE LIABLE FOR ANY DAMAGES RELATED TO THE WORK OR THIS LICENSE, INCLUDING DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL OR INCIDENTAL DAMAGES, TO THE MAXIMUM EXTENT THE LAW PERMITS, NO MATTER WHAT LEGAL THEORY IT IS BASED ON. ALSO, YOU MUST PASS THIS LIMITATION OF LIABILITY ON WHENEVER YOU DISTRIBUTE THE WORK OR DERIVATIVE WORKS. + +8. That if you sue anyone over patents that you think may apply to the Work or anyone's use of the Work, your license to the Work ends automatically. + +9. That your rights under the License end automatically if you breach it in any way. + +10. Uber Technologies, Inc. reserves all rights not expressly granted to you in this License. diff --git a/mylib/lib_BAxUS/BAxUS/docs/Makefile b/mylib/lib_BAxUS/BAxUS/docs/Makefile new file mode 100644 index 0000000..73a28c7 --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/mylib/lib_BAxUS/BAxUS/docs/_templates/layout.html b/mylib/lib_BAxUS/BAxUS/docs/_templates/layout.html new file mode 100644 index 0000000..1ce785c --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/docs/_templates/layout.html @@ -0,0 +1,12 @@ +{% extends "!layout.html" %} + +{% block menu %} +{{ super() }} +

+ Indices +

+
+{% endblock %} \ No newline at end of file diff --git a/mylib/lib_BAxUS/BAxUS/docs/cli_options.rst b/mylib/lib_BAxUS/BAxUS/docs/cli_options.rst new file mode 100644 index 0000000..3c46619 --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/docs/cli_options.rst @@ -0,0 +1,124 @@ + +Command line options +-------------------- + +.. list-table:: + :widths: 15 10 25 10 40 + :class: longtable + :header-rows: 1 + + * - **Name** + - **Shortcut** + - **Full argument** + - **Default** + - **Description** + * - Algorithm + - -a + - --algorithms + - baxus + - The algorithm to run. Has to be from baxus, embedded_turbo_target_dim, embedded_turbo_effective_dim, embedded_turbo_2_effective_dim, random_search + * - Function + - -f + - --functions + - None + - One ore several test functions. Has to be from hartmann6, branin2, rosenbrock5, rosenbrock10, ackley, rosenbrock, levy, dixonprice, griewank, michalewicz, rastrigin, svm, lasso-high, lasso-dna, lasso-high, lasso-medium, lasso-leukemia, lasso-rcv1, lasso-breastcancer, lasso-diabetes, lasso-simple, lasso-hard, mopta08, hartmann6in1000_rotated, shiftedackley10. + * - Input dimensionality + - -id + - --input-dim + - 100 + - Input dimensionality of the function. This is overriden when the function has a fixed dimensionality. + * - Target dimensionality + - -td + - --target-dim + - 10 + - (Initial) target dimensionality of the function. Whether initial or not depends on the algorithm. Initial for ``BAxUS`` as it adapts the target dimensionality. + * - Acquisition function + - None + - --acquisition-function + - ts + - Either ``ts`` (Thompson sampling) or ``ei`` (Expected improvement) + * - Embedding type + - None + - --embedding-type + - baxus + - Either ``baxus`` (for the BAxUS embedding) or ``hesbo`` (for the HeSBO embedding) + * - Adjust initial target dimensionality + - None + - --adjust-initial-target-dimension + - not set + - Whether to adjust the initial target dimensionality as described in the BAxUS paper. + * - Number of initial samples + - -n + - --n-init + - None (set to target dimensionality + 1 if not set) + - Number of DOE samples. + * - Number of repetitions + - -r + - --num-repetitions + - 1 + - Number of repetitions of the run. + * - Number of evaluations + - -m + - --max-evals + - 300 + - Number of evaluations. Cma-ES might use a few more. + * - Initial baselength + - -l + - --initial-baselength + - 0.8 + - The initial base length of the trust region (default value is as in the TuRBO paper). + * - Minimum baselength + - -lmin + - --min-baselength + - 0.5^7 + - The minimum base length a trust region is allowed to obtain (default value is as in the TuRBO paper). + * - Maximum baselength + - -l_max + - --max-baselength + - 1.6 + - The maximum base length a trust region is allowed to obtain (default value is as in the TuRBO paper). + * - Noise standard deviation + - None + - --noise-std + - 0 + - The standard deviation of the noise. Whether this is used or not depends on the benchmark. It is generally only recognized for synthetic benchmarks like ``Branin2`` but also for the synthetic ``Lasso`` versions. + * - Results directory + - None + - --results-dir + - results + - The directory to which the results are written. Relative to the path from which the run was started. + * - Run description + - None + - --run-description + - None + - Short description that will be added to the run directory + * - MLE multistart samples + - None + - --multistart-samples + - 100 + - Number of multistart samples for the MLE GD optimization. Samples will be drawn from latin hypercube + * - Multistarts after sampling + - None + - --multistart-after-sample + - 10 + - Only recognized for '--mle-optimization sample-and-choose-best'. Number of multi-start gradient descent optimization out of the ``--multistart-samples`` best ones. + * - MLE optimization method + - None + - --mle-optimization + - sample-and-choose-best + - Either ``multistart-gd`` or ``sample-and-choose-best``. + * - Number of MLE gradient updates + - None + - --mle-training-steps + - 50 + - Number of GD steps in MLE maximization. + * - Budget until input dimensionality + - None + - --budget-until-input-dim + - 0 + - The budget after which BAxUS will roughly reach the input dimensionality (see paper for details). If ``0``\ : this setting is ignored + * - Verbose mode + - -v + - --verbose + - not set + - Whether to print verbose messages \ No newline at end of file diff --git a/mylib/lib_BAxUS/BAxUS/docs/conf.py b/mylib/lib_BAxUS/BAxUS/docs/conf.py new file mode 100644 index 0000000..740e220 --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/docs/conf.py @@ -0,0 +1,58 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +import sys + +sys.path.insert(0, os.path.abspath('../')) + +# -- Project information ----------------------------------------------------- + +project = 'BAxUS' +copyright = '2022, anonymous' +author = 'anonymous' + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.coverage', 'sphinx.ext.napoleon', "m2r2", + "sphinx_rtd_theme"] +pdf_stylesheets = ['twocolumn'] +source_suffix = ['.rst', '.md'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +latex_elements = { + 'extraclassoptions': 'openany,oneside', + 'preamble': r'''\usepackage{makeidx} \usepackage[columns=1]{idxlayout} \makeindex +''' +} + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = "sphinx_rtd_theme" + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] diff --git a/mylib/lib_BAxUS/BAxUS/docs/custom_functions.rst b/mylib/lib_BAxUS/BAxUS/docs/custom_functions.rst new file mode 100644 index 0000000..c071f2a --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/docs/custom_functions.rst @@ -0,0 +1,75 @@ + +Optimizing custom functions +--------------------------- + +Custom benchmark class +^^^^^^^^^^^^^^^^^^^^^^ + +For practical use cases, you want to optimize your own functions instead of running benchmark functions. Let's see how +we implement benchmark functions. As an example, :class:`baxus.benchmarks.real_world_benchmarks.MoptaSoftConstraints` implements +:class:`baxus.benchmarks.benchmark_function.SyntheticBenchmark`, which means in particular that it has its +own ``__call__`` function. + +Let's look at the ``__call__`` function +of :class:`baxus.benchmarks.real_world_benchmarks.MoptaSoftConstraints` : + +.. code-block:: python + + def __call__(self, x): + super(MoptaSoftConstraints, self).__call__(x) + x = np.array(x) + if x.ndim == 0: + x = np.expand_dims(x, 0) + if x.ndim == 1: + x = np.expand_dims(x, 0) + assert x.ndim == 2 + + vals = np.array([self._call(y) for y in x]).squeeze() + return vals + +which consists of some checks that ensure that we use the internal ``self._call`` function correctly. + +If you want to use BAxUS with a custom function, you can just use this implementation and replace +``self._call`` in the line +``vals = np.array([self._call(y) for y in x]).squeeze()`` +with a call to your own function expecting a 1D numpy array. + +How do I register my new function? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +For this we need to look at the :class:`baxus.util.parsing.parse` function. +The first thing to do is to append your benchmark to the list of existing benchmarks, +currently consisting of + +.. code-block:: python + + required_named.add_argument( + "-f", + "--functions", + nargs="+", + choices=[ + "hartmann6", + "branin2", + ..., + "MY_NEW_NAME" # <---------------- ADD THIS LINE + ], + required=True, + ) + +Next, we have to register the new name in the :class:`baxus.util.parsing.fun_mapper>` function: + +.. code-block:: python + + def fun_mapper(): + return { + **{ + "hartmann6": Hartmann6, + "branin2": Branin2, + "rosenbrock2": functools.partial(RosenbrockEffectiveDim, effective_dim=2), + ..., + "MY_NEW_NAME": MyBenchmarkImplementation # <--------- ADD THIS LINE + }, + **_fun_mapper, + } + +and that's it. diff --git a/mylib/lib_BAxUS/BAxUS/docs/getting_started.md b/mylib/lib_BAxUS/BAxUS/docs/getting_started.md new file mode 100644 index 0000000..90e5593 --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/docs/getting_started.md @@ -0,0 +1,14 @@ +## Getting started + +The main file is `benchmark_runner.py` in the project root. +It can be configured with command line arguments (see [Command Line Options](cli_options.html)) + +For example, to run `BAxUS` for 1,000 function evaluations on a Branin2 function with input dimensionality 100 for one +repetition run + +``` +python3 benchmark_runner.py -id 100 -td 1 -n 10 -r 1 -m 1000 -f branin2 -a baxus --adjust-initial-target-dimension +``` + +Note that we need to pass an initial target dimensionality with `-td 1` even though this is adjusted later by passing +the option `--adjust-initial-target-dimension`- \ No newline at end of file diff --git a/mylib/lib_BAxUS/BAxUS/docs/index.rst b/mylib/lib_BAxUS/BAxUS/docs/index.rst new file mode 100644 index 0000000..8e91fc7 --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/docs/index.rst @@ -0,0 +1,24 @@ +Welcome to BAxUS's documentation! +================================= + +.. mdinclude:: notices.md + +.. toctree:: + installation.md + getting_started.md + reproducing.md + custom_functions + cli_options + troubleshooting + baxus + LICENSE.md + :maxdepth: 2 + :caption: Contents: + +* :ref:`genindex` + +Indices and tables +================== +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` \ No newline at end of file diff --git a/mylib/lib_BAxUS/BAxUS/docs/installation.md b/mylib/lib_BAxUS/BAxUS/docs/installation.md new file mode 100644 index 0000000..fa8be8c --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/docs/installation.md @@ -0,0 +1,93 @@ +# Installation +We explain how to install BAxUS and how to build the docs. + +## Installation + +You have 3 options for installing `BAxUS`. +Please make sure to install the following packages before running the `BAxUS` installation. +We assume that you have a Debian Buster based Linux distribution. Please use a Docker image +if you are working with a different distribution: +``` +apt-get update && apt-get -y upgrade && apt-get -y install libsuitesparse-dev libatlas-base-dev swig libopenblas-dev libsdl2-mixer-2.0-0 libsdl2-image-2.0-0 libsdl2-2.0-0 libsdl2-ttf-2.0-0 libsdl2-dev +``` + +### `pip` installation + +`` +python3 -m pip install baxus +`` + +### Installation from source + +First install required software: + +```bash +apt-get update && apt-get -y upgrade && apt-get -y install libsuitesparse-dev libatlas-base-dev swig libopenblas-dev libsdl2-mixer-2.0-0 libsdl2-image-2.0-0 libsdl2-2.0-0 libsdl2-ttf-2.0-0 libsdl2-dev +``` + +Then install with the `setup.py`: + +```bash +cd baxus +pip install . +``` + +or with the requirements.txt: + +```bash +cd baxus +pip install -r requirements.txt +``` + +### Docker image + +Alternatively, use the Docker installation. +We do not share the Docker image to ensure anonymity. +However, you can build the Docker image yourself with the provided `Dockerfile`: + +First, [install Docker](https://docs.docker.com/engine/install/). +Next, build the Docker image + +```bash +cd baxus +sudo docker build -t baxus +``` + +By default, BAxUS stores all results in a directory called `results`. +To get the results on the host machine, first create this directory and mount it into the Docker container: + +```bash +mkdir results +sudo docker run -v "$(pwd)/results":/app/results baxus /bin/bash -c "python benchmark_runner.py -id 100 -td 1 -f branin2 --adjust-initial-target-dimension" +``` + +After the run completed, the results can be obtained in the `./results` directory. + +## Building the docs + +To build the docs, you need to install additional packages: +```bash +pip install sphinx m2r2 sphinx_rtd_theme +``` +If you want to build the PDF documentation, you further need to install +```bash +sudo apt-get install texlive texlive-latex-extra latexmk +``` + +The docs are located in the docs directory. +To build the API doc, run +```bash +cd docs +sphinx-apidoc -o . ../baxus +``` + +To build the HTML version, run +```bash +make html +``` +and for the PDF version, +```bash +make latexpdf +``` + +The docs are located in `docs/_build/html` or `docs/_build/pdf`. \ No newline at end of file diff --git a/mylib/lib_BAxUS/BAxUS/docs/make.bat b/mylib/lib_BAxUS/BAxUS/docs/make.bat new file mode 100644 index 0000000..32bb245 --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "" goto help + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/mylib/lib_BAxUS/BAxUS/docs/notices.md b/mylib/lib_BAxUS/BAxUS/docs/notices.md new file mode 100644 index 0000000..36a34df --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/docs/notices.md @@ -0,0 +1,4 @@ +* `BAxUS` is tested under Python 3.8, 3.9, and 3.10. +* We support only Linux which is due to a dependency to the Lasso benchmarks. +* We tested under Debian Buster and Debian Bullseye (Ubuntu distributions based on these Debian versions work as well, + e.g., Ubuntu 18.04 and Ubuntu 20.04) \ No newline at end of file diff --git a/mylib/lib_BAxUS/BAxUS/docs/reproducing.md b/mylib/lib_BAxUS/BAxUS/docs/reproducing.md new file mode 100644 index 0000000..f337fa2 --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/docs/reproducing.md @@ -0,0 +1,191 @@ +# Reproducing the results from the paper + +We explain here how to reproduce the `BAxUS` and the `EmbeddedTuRBO` results from our paper. +Please increase the number of repetitions `-r` if too low. + +## Main paper results + +### Figure 2 + +For Figure 2, we used the following code: + +```python +import math +import numpy as np +from matplotlib import pyplot as plt +``` + +Define the HeSBO success probability: +```python +def succ_hesbo(D,d,de): + """ + HeSBO success probability (independent of D) + """ + if d 0], axis=0) + print(mean.shape) + sortkeys = np.array([i+1 for i in range(len(mean)) if mean[i]>0]) + hist_bins_format = [f"{f'{hb:.2f}'.replace('0.','.')}" for hb in mean] + print("sc",sortkeys) + + color = "#5D3A9B" if bs == EmbeddingType.HESBO else "#E66100" + label = "HeSBO" if bs == EmbeddingType.HESBO else "BAxUS" + ax.grid(which='major', color='#CCCCCC', linestyle='--') + ax.grid(which='minor', color='#CCCCCC', linestyle=':') + bar = ax.bar(sortkeys+group, mean[mean > 0], yerr=stderr, width=bar_width, label=label, color=color) + ax.bar_label(bar, fmt='%.2f') +ax.set_xlabel("\# target dims. containing an important input dim.", size=14) +ax.set_ylabel("empirical probability", size=14) +ax.legend(loc="upper left") +fig.tight_layout() +``` + +### Figure 7 + +To reproduce the results from Figure 7, run +```bash +python benchmark_runner.py -a baxus -f lasso-hard -m 1000 -r 20 -id 500 -td 1 --adjust-initial-target-dimension --n-init 10 +``` +for the BAxUS result and +```bash +python benchmark_runner.py -a embedded_turbo_target_dim -f lasso-hard -m 1000 -r 20 -id 500 -td TARGET_DIMENSION --n-init 10 +``` +where you replace `TARGET_DIMENSION` with 2, 10, 20, 30, 40, 50, 60, 70, 80, 90, and 100. + +### Figure 8 +To reproduce the results from Figure 8, run +```bash +python benchmark_runner.py -a ALGORITHM -f lasso-dna -m 1000 -r 20 -id 500 -td 1 --adjust-initial-target-dimension --n-init 10 +``` +where you replace `ALGORITHM` with `baxus` or `random_search`. \ No newline at end of file diff --git a/mylib/lib_BAxUS/BAxUS/docs/troubleshooting.rst b/mylib/lib_BAxUS/BAxUS/docs/troubleshooting.rst new file mode 100644 index 0000000..6205355 --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/docs/troubleshooting.rst @@ -0,0 +1,28 @@ + +Troubleshooting +--------------- + +Mopta08 Executables +^^^^^^^^^^^^^^^^^^^ + +The executables for the :class:`baxus.benchmarks.real_world_benchmarks.MoptaSoftConstraints` +benchmark are not contained in the repository but downloaded when necessary. +We support four different architectures/operating systems: ARM (32 bit), Windows (64 bit), Linux (64 bit), Linux (32 bit). + +The files are automatically downloaded and made executable. +However, this might cause problems if there are no sufficient permissions for writing or making the file executable. +In that case, please download the correct file and move it to ``baxus/benchmarks/mopta08/``. +The files can be downloaded at + +* 64bit Windows: ``_ +* 32bit ARM: ``_ +* 32bit Linux: ``_ +* 64bit Linux: ``_ + +Slice Locatization Data +^^^^^^^^^^^^^^^^^^^ + +Similarly, it can happen that there are no sufficient permissions to download the slice localization data +for the :class:`baxus.benchmarks.real_world_benchmarks.SVMBenchmark` benchmark. +Please download it from ``_ +and move it to ``baxus/data/``. \ No newline at end of file diff --git a/mylib/lib_BAxUS/BAxUS/requirements.txt b/mylib/lib_BAxUS/BAxUS/requirements.txt new file mode 100644 index 0000000..ea9af99 --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/requirements.txt @@ -0,0 +1,8 @@ +numpy>=1.21 +pandas>=1.4 +torch>=1.3 +lasso-bench-fork-leoiv==0.0.6 +botorch>=0.6 +gpytorch>=1.6,<=1.8.1 +scikit-learn>=1.1 +parameterized>=0.8 \ No newline at end of file diff --git a/mylib/lib_BAxUS/BAxUS/setup.py b/mylib/lib_BAxUS/BAxUS/setup.py new file mode 100644 index 0000000..80666c7 --- /dev/null +++ b/mylib/lib_BAxUS/BAxUS/setup.py @@ -0,0 +1,29 @@ +from pathlib import Path + +from setuptools import setup, find_packages + +this_directory = Path(__file__).parent +long_description = (this_directory / "README.md").read_text() +setup( + name="BAxUS", + version="0.0.8", + author="Leonard Papenmeier", + author_email="leonard.papenmeier@cs.lth.se", + packages=find_packages(), + install_requires=[ + "numpy>=1.21", + "pandas>=1.4", + "torch>=1.3", + "lasso-bench-fork-leoiv==0.0.6", + "botorch>=0.6", + "gpytorch<=1.8.1", + "scikit-learn>=1.1", + "parameterized>=0.8", + ], + exclude_package_data={'': ["results/*", "tests/*"]}, + long_description=long_description, + long_description_content_type='text/markdown', + entry_points={ + 'console_scripts': ['benchmark-runner=baxus.util.console_entry_point:bench'], + } +) diff --git a/mylib/lib_BAxUS/BAxUS/tests/__init__.py b/mylib/lib_BAxUS/BAxUS/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/mylib/lib_BAxUS/BAxUS/tests/data/slice_localization_data.csv.xz b/mylib/lib_BAxUS/BAxUS/tests/data/slice_localization_data.csv.xz new file mode 100644 index 0000000000000000000000000000000000000000..47dfe21fcabdf11f4f9c2bfc0b112b5444b1f8db GIT binary patch literal 13206892 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

S&^sp* zlUz^EFhO=osZPz7TlRlH&AuD2m@KhnddTmP%@ZRhn)VuSl)J+b2F;xX!&~Py?V5q1 z`ZSdyLj?4qC+#61vZcG$p|$UIDAPgL!yf5X$||!~=hvI7 zH)+bz2O|g*Vr8e1)%&a6<^fu^5WNpoeO;_!#LJlTY&eYAERAeR*i}ZLkT$R`8)Cse$UeFgn-%U zoTy<K(j~Z;rpmIG`hw8I;iuVBI>lGU0-HmN(bj)6cTCC zm{$7Jwsuo&BOKgjK0`e(mwE@Hr=1n-WN6BMym_h{=skmHb22H=kd~pvHLY-4fz z7HbvC{r_lV5ItCVQ{?8-NsQ`hr6#XMj?F(wodc1#3yskerU1s)TU?v>AU7g{f$QtlxcpZ5JHy(U990q%B0T2v+j-uu^S(bsBn zGnXcI5ipv|_XY(Ja+K|p>9%3MqXcTxw5Vah*Dt=0AYGMv`rmb~pb^NPnoQ4|+BBGo zJ=>JLBLirbgy;f>V1mO%2V*Q3+6nQa8j@q+Pd0fW-NbRIqe(gc&%o?eAw997WDJ{U zx933@n|Sh0oCe+Ve2>FKs^r~QfB+Vf+Lz-FRW4)=bc{Affk`fLsnMT zw=>odPhG;*+C+foGj?Q}p(5)1z_Ip0eK3}t{&VZYC-S#V2owF4Vlva5odiAH$ZDMx zOI>eSx{FcfDx1yAzbh;|1aU_TOvBQc`2R=cg=#6}jl18?mdA-3rAAW^Oyz^f_5N40 zY*~F&aV5;yMgxcUPz=Sxw-5>4i!-0>ODEERV#u|W|Ck(_J=ePSpP3rkJi1d8{B7VL zU+l+vSxgP34Mpijqs+ae{nTmcyq65=JTH9sDRo1M!E{H`*E8)qlS60$)XSioJy1h0?qq_yGl5ci;70JuMjfz1l%mDjO$3c7ZpZ51NYPRq*U{#%$^IL zdaej0eTp8}lDTqi3rY4sblR*o2AT&OWw(cO+-X2Bud*hZlSJfb-u{s>zaGZNmubAD z7SC?YVK%mP-=)4Q1gItvZ(}AzhP|TzeKBO4@x)6@}tYxc~P2m zA%ISJZCQQJWw>0dMRN5}R8+Hxkh%{Eqq1CaXBos!AgAI}mDI5Q_N_xIN`{Ra(Ec>q z+AkdsA6GQC0_$jqgM@IqyzcBv$fV?>-7>^rECU9$Y68C*f#D)YOEmk#6(HM9k^f_9 zc6*_+CF;aC?0-6Jk!5-pp1YL@PiHFI44qXM@j8<4;6**2jjzQ*hSaP!s$y%rvktl> zPU4SmqM4@RA+?vUAS9T}ImDqoP%!APKeq@}!L& zN&hKA(Ei&qjyTiu+_$WaH6O@3S#|3{%F|oVZhok&K*{efKN%&=jOr54_3!L6z8luZ z`G}3+rCi7h&T-&Ueidi9o5P66IxHZ;D&(9?R{0IbZRy$LTV%+_K<2ZlRsSP1y3hT4 z@CntwwGtef(>3p5^t{FeYF3edj|=A{s+?!!*mZLL34UNpXQnjYO#Ps5`kXFTZBz8u zCWs(cmU@uE)Uv`V7SPRRH8(m^LF?390z3+Je5PHK}+H-w?CkMIFQ+FmIZggdNDqOGxCB!C!da zmHC(ob*u{2cqnrJrTP;HYmkhSu!|y9gt!?7{JW{P>u)vKBN?$V4Kw~c!})Rn?Q2F^ zs8`(qtJEN5s=-gi;ooa&GDG){kH6KM2Iz$^8$$aw-lp>N%)d*ZP;gE>8XfbV2jB}A z8ev5IN0?+DwCi+!_1T~mqz^%{Q?U!kqL?f^5wX;60AxQWd-QNB&-;=il;>f39RGPX zP*eGP#RaY}lYFYW(tc&!@aZQ2zrdt>6brx=WCyKPE=VE2(V~$WO@5D}P(irq%%L=Q z;nXEWqO`<k1B(-fzsBT+egtAW1F>6t<1Jw zg!Ap#?ONg@mGoKnAtQ)e5N$jck`2Fci&n@7X_S}ER6M|)dGH6;;DJR}|DlQ|3Z zn}f=l1KM0hNHZE*63&hT(Pm@37UAKtZ;@U+Z=GEq$53ZUo||l?y@5|*kz-LCGsjLO zQH8L}mqt0KFXM1CzkMd!Os*7Kss-$82OHc>`pPrm9Gtd+*gYT?VX?o_uW&3E-d4dE zkE+-JI91HRagVz^cq$RzFy>DKO?G6BmZ)YeD#+hr$s10`3N)=H2XquF432*Lu*PcX zYI+Cj*pcbSB5xDG?%Gw))H>4P!f$YV^oHTrOv5INWp;q&f|^qZ^oiV9nv9G_O;_r@ zZy^wR@6^1R8T1&P|H+%1I)WtdWN<8+ZwNJh`xVPf=uaqG(Nca28FUZGwbPLdnF;S4 ziVIV6SqyJ)?tdUj)Za21d!6aTZos|#^b#?-p`qX{&Odfq@iQwTD|}U7>lG~78FSng zQyUzBRsI>+Wkn?1yam<*(niyMO^w!^i1vW^Ydv|)p9yt*+h@J#&Iv%Ig%e+-()&A7 zw}?ybE}ifwWK^&i?E43#_MU^@R`DcsFQo$3UcaBYb7#V=LxcD0!`iepzI{mJ!0}$) zIww*pmx3=6qCVZd%^fnGw;rk2n;6b#DIxc}9<;MGO$ay<2yHR<5dlSz7C(E^FXu9G5+=bC1P7WY}Yjj9QIl%ljH)A>SEL9)4h{(SRB zUP4k$0ONqnN-i8`XHuPNJ73Zkhi=_64jrxl0zZuUCYjmj%hct_8Fwwe!9QGg2Q^1A z`SR$)#xyOg@r8&lzc7Ql6+E@Op(|zm`HaR~LS$659L{$i0$}dckCy&8iWgysUebf@ z7J4QQ=H?KthSrK~TVKlhN`yRC|gL7u_wVbB^t+i?K_Hd-+FNmyFIlL2@9`4 z_batg4A14PM_qxAh$z-TsgTK*oz#Tvm*z9ruynX#`@|b)6{m!w7c(0I`BYVqMC2vJ zw1k5*ClSgkx}zLHvs}tLbxm~Wg7%HcO3*Tpiap-x`8Cqw+($ruD?Jj-qK(%liqtY) z7VUwk$NhV<$?~}d+@Zs50yh2$yR${7@Zp*kzhM;$(f7M*g&^`hI<*!aV>VtmziB_B z=+`j$9mp0Y{Lub?;ST0Vgd+AvsO?S)luK&OoN-?kn6tAS&8xDjBIWY&FI)H>N?ac1 zi5if%T~LrcfP-3pyv<_Z<7e;INfQX&)2Fy%%u6&`5A!G~(0ckV-l%n9rTG;$p5BZA zyc^mzc6N8N>j8ewk6+U}aoRP%$HC%W5Q0xj^Z0E>?13|6WI}`i;+;dU#K&lC0z$s@Mt4Exy$UeD8kcskrHqb z+l2(p+f#;D*Jrlllv=lWy&%6&?P$Rf`@|(;%Xm)3`E-4K>%%Lyf`ArOF*xTsEc=*L zS<6?><}Arid?pbv9G{S*YK>KAxUH~Xy0=@~=Ig4hxH>x^7*Pv(siP=6yFlM76?sx_ zzf=tR+A#g%T+sh)?#su{2x*!JIS+XoL28@Qf?>$7Sb*dcJJWPSXgzF=l!{d=-fzM( zxYJuj#~FH%r;L7b>Xc(sYfCpRg2Xos)W2MEm$UpE_we)+H-meLJ!s^NM7*ZY?Q1)t^^^WKL|S=(5}*e&!?Ynx4IsaE=H8FI~g!)*oCUw@^vPfSE}UTlI-&NvZ#3j`&P0pox!rL zH{tWWq=zhM%12UqJSnYHlak#U>}VBf1ap{pi^TKXwsk@baCQ?ShMo2Rh3FKEO%C`_ z&97_01XIuJ6$^u)nqO0aX@M-S^Pxzfo90BX3OvAFB8$S1gmw3#WPsyl0tF@;aBaHw z>=}E7N|YFiF(|ODKq#A)eF)?AjiW1563nPl>sYXB)@2Vkt$NfsZw}bSz?~=6D=6Ub z0dyF;o#~D28`b$WiZ$!kbkQf(x*yJfpbE^Cg0e_F280NKG2S8Gl7s8H5_r0<3(}(% zq^~ApbyhZ?&1 zOaw6Et%&J-XG;;9iuH6Zf}HSpETM37Yq;IX{KpmYks5z}?s-;F>D==rARRd@2xTLS3<1$jo+Km+W!ck{0eVup! zaK;b~bx0UYRW#baL?=xB7Ec6S!X5I=AU~wIAsgYJzy+Ysdsc^}d&}gdHKt8+}tmv>`_T;`? zUm4R?(f-B*eAwKR={gZwyTvEg$zG|`@q?HQ+2}K~Ab$sC%{|h%*FuH?c$22I{tx{q zVS+WWUt;Z=%+1-cOylrBQ`{2T7)LvE_JwvN#}(HA#caM#(k6%`StXsP7yKGyhy!&CX_u6_Gs$=>7Cw z_WN@lM3THCi97~S`w=Z_g<@sUpbXo{e7_0XmJ|8Kj<$ZbfIumBA5zD29k-4kM8{@l zz?fnq4u1;vGh@sBllN#WwGuGqv*2HxIk!C7wxmtz1z%9J@zS@4%;e|dT@$PlA_(5= zJrhn!vB?Fz?9aWdrg{^;yJj#J^V`p%ovyZ!NWR@*=@zF3=!315#}eY^H{eiVBuj72 zbcL-0bNq?2fjb~B`BYPn+Cn?vX>QP(2z@&~xp5sBo>MzYY#kHj?2}e=Wo%arbiw7u zmfAlrU!+0MQeAe73$%;n0V^}$rg>4lu!BM=pMp{uCl}bT-d$T%T80NW_0~%=LD;)= zxF3>ZuY zbJ%$|%PZy#BbJ62FjL0gqe?s##XrHxW`WJ0Q@nTanczqts5#A40%;YgNV0<%x^9`& zPG`PMouw4M$XkQ$usG?KOE}Nv$RO(%lB=xEw&GAQtf>~0K=Z`|pD1tBj)F0Y$zlNYq~Nk;a^OXa0fQ>+rf zJ%0aC^!niV9w2vNi61nq^4?=#lg7K%B;6y7O6%eqMM`z`^%}&Ump69ssf=l|T!dHY z!sSd}bEjEYv>mI;kdvkC@0{a*3QgumFYbtZ7R(i0k&P8j&$Wkt~DCSF=GF|QD@d*xd@7(%bIB(a!;HSN097ck%aowHObV7+kBHw<}@+csk9=IW!$HB z8`~>=N^W=4>fi2qR*ZNLC{A+iKbc^w-2K%NHHi#U2NW=y!{~w}bBgeuo3jU+sfvpD zMYL=-O!wuH{Z=%eM9lGsApff@28Dgo6V||sft|e2m&p}@Iou^O zb31mN^cj4d$omIuhZ=L$&|myJwsO8qDf^}E;A9#VT5T6zgW#MKtpp2cD80bs4Z4V! zJ+NmJ>sU@oWVT!>qdO4m5B3Ld4VWieTbV}Wqj)!f89|jKVp`O&(UrUbi?7SE&?ed7 z3mlCs!ll>lsD~G(AO}aw1r)Gt659L&yz}N!W&!J$Umx}mLZiNHiUbGRX@e7SoB4Sf^QNhU4KkQ-MQM z0+!gY+A=rSQeUK|-+8TM`|IZVB4~s;UPEEYkmywiF%Gkn6j(%9=Juk?t#f6=@R(O7 zEiD`N!UO-y0vK4rZOl%rv$8eML|edmaYKT139VjoI;ou^T3)d|x8QNnhB)!wU#7x> zw!J*jgi;>{*eEd?47=y~X%(pzjz}U_kmq_4<|q;IFPYpgQl_XMd#JKyNN+{B;{>H6 z7k4O0+rw$`^a$*VXG#rBU>KYHU#~OJUqluqX6DkgCfV8psP`ez<(T9z*Y7!P^dA30 z5pTDdK9W5-L8DpAOAJT*?=$Zb>*CFO7t4!qkwI7Qd?aTJfE)JH-VF(%7s4P6maAsQ zx5djM#A|Hs!&xSWPxe~S(wX%WrEUml18hJM<@jZ70Wpg&G!@hiYagS+qMgl0`=Jg{raZtfaslWXbs;tII%4^yTOEFlN zcMby~qLM4Vz^PLaBZ2lzV#J=f#w%>e5KN&;m9Izf{r7}j9^xhor(QK=>nEzgGH)lR|gixq2k5OoV~S6$(kJteb$ zcU-4OhYjii0;t|B@_%U)1_nEn6C9XYHa;9_RT9hvO`!^bAS+5`Lt`bWO+ft3hFoH` zLUYtHSSGdrD!n6xcU?T zbR}*)!zX(7I5idr^`i{z%w{N7bolbb5u;cU)CK}=pST($H6Ou`h`wSv8AvJ>+_%F; zL%acDmq+>ryjgvZ;(3G(EYqi3fTesEIqL!wkeRO|Ers zZ$iAdS?2CI9HEAzAO5K3IOkmychT>P7|>x}#x}I_7mnmHV%*?1a3{ zRV8eEPFCaSop4)a@}=YjDuyG0lMXg@tmbr-vRJUpZdJ&~GsJBgTeh|=b|!) zY_HiGXS%+&H?`ezTiD+ z&faON5Esp4dtt zURiY`q!S>gv-mITjd?6#^6c-9rQ?Xd=NlC5+^^9V>mpS-fuBaQ zPZR<(ChEnM%pbELDnbr2L)zoLsBnKcMN|j04+x&A60pE0IPE$Xtq=U7-O0Gp%k2&R znHgBHSq)Pbm&$J+#A9kF|2fy0b4AfyMzc-iP^Jn17~A_>Pxk367v-a2G83+};f^^G zLogrdU;Hp_kaaeUg6Zkt(uQ~(X5Z027rMuO9m1Bb&f%&k6{D)Y?6q_mCX-2mhN6}I zp!1jCe|c(iYRXjC$O9!c&gMF!{YWFzGq7?dXPa;Ey}lTA3InDuY3r zVAAtQ>1`sf^bCjpkX5Q-W2Tj{S4+I(H+e0_qvnHQfUu6U+<&t|CU`9q|g}HmQUD^lWV? z00f$g5SQB9(G&lyjp5S&szSLy9EpT{-pRXwNQKv{z)8I3L3Ocu8bb!nMq7f5D=E!$ zla5F)+GOs|Uq;Uz)<6$Xl|5u}a-D!`Pp+CKpjoZjS~IkVBI7a8U$Vz;7EKFBi5d^R z@gz?2RbgU-)0|BtMVwJ=Yt8r5A{-|*DEHFCCnIo;xje+)=7hp2^umR>eeSDxEP(%nvrAVSaj1RJx}v8>Movm`ysN6okc z^FSI8wZLTrcf^>Bw>)`l_DZRaZR@msi2L^|6t&2rZgClId6lkcKoqF{B1HKN-N8pk z*W2iH-hRIh=OIm}+=@_+&S`M@%-R(vEt5^YhcY)^{%GnPpQ4(f5rp0a(}_85*;`J( zi@^734~L=@U~%+Tfzb=L$1^Fg7-}B4jef2lsxEfQR-lkHu5Ra|mXdb`qJ);T2~4Z> zQN=MKwl>6(Q+(t@mElk8_8p1I=;S89lv|QtakhJ^&UOJN6ht^=pO~$Caz%sc{V13G z4>${c!~o=QY{M2u=lNgvcaWXpk)FjA)HlSC2u2j|OM(i6!@BId#f)GbVv1x{BZDps zlrVgBNa;ZKD|?}U zILCu+|G+czNzQl88&^3KxCFjCW2Ddfu!lL|3Fz2nJ11}dEPY4@`GgF{%;rjdsZ|WU zVel+sA4K&GbInW$ncMEU;#PDTBW5a_foF%ug85NDB|fBXX>~Jb+Ivp%zSs)HgL+EfNResZ(>kkwUut=Eb7_EkLlRS{<3=iI~ny8 zTsEGf^$qyvTJd&<0fFv z8b4cQ!zLMxI@z*)A8L)yXUe;&?*LRk;u2>oWzloWkI!oknFRr+L3QpX!d$|8@@^MX z(t&fSP?1J7-koq%g=(pz5(&C;Ect51!wCUgXCYYDaD#Yg8SqdnfZDDN%<&bbl9vCE z9ynPL2apnH$C9YRy)wj!!n(OX4&O%;9DdbtSy}ISmu^x|Qupv(;=(<)<#9|(XYfcF z>`;D#m|eC8VVf5j#+%6KoK-C$N06?7TeGyrQBd5eu*N11Q4d+v4rO77)*zulGoZ}P zj>vg4Cm_Jj5YD&SPM`mzh4L0yHay*V%+b?%3DTv%^eJa`1VS^uOqN6D$mW3$Jq~YE zk`kmT{P^jme-BI@+|j!spQl9im`P+wO?L{KNm>R`dKN~rV9vkJ)+`k$*scriOZDWv z1$i@6v|4|V`6(3d*=~geJV4IuB{+x)Ta%VPWTFveXq!%1#nYsh2({rl+}6%_&Gjs# z@I%h0`9P5z@FX|XtE*DjU;zvg&`emi}e3dCqd@26b}5(XyI0`Pc;fTvGYnX%C7bGpel zJJ$x;S)}!DEQ2%@gd$Y|j8AT?;7SKf+-`&-QoE~UfptedL$22$Zpq6ElH5-={`Sr@7F)w)(n`9j!U%xikn!?K~!0KtJFd`)G+%bdNM zV#BBC_cYp(0XtRNbmA{RqqiY$x3nI*(&76_w`oqJSQHM1CyKdgZPecf2^I9vjyQn5 zk&2i9r?#sJQ-Tqj!2S^lkWEWb6hje}YsW8I{Z|EsGM1rcPz@%FUj`E(FTGHrbaB07zo_c_6Z>3PbGsOH}UEh44F_d@}j2tNz$G9EJe4lN&yWGxvm`W z@bTA42VfHw7D1U(KdP?dI@sF6>DCD#;fZ@F8 zY{-_`lKCFRaZW16<-7N*;Qs8&;I%Vz%oojzdEZN0O0$akmiXwJ6s$FZ9;XTiRIO%| zEQ$>;@d=d2YT%)({Tl-O0T#wz?!P(>?MxcBhkA==HtR^pr#c%n>wi4M#tD5rey*0y zPXhpKlt{|}f~Xc5>M>c1@!TT|FLT*I>#Dv;5hU&Oy$O};`rXq3@@|D+2nCo@A(c=c+3ppGZm1AY=L1yzqkECIgUkK?tag z=ofV`ZbW)wCV90m#EAKkTx90=k!eOvOw#W|D8;1!GpE7bSvIUWOr`lNe9-0Tk2Znj zHR2@;RuWkd_oB}ga~t-VV~4^Jk+Z}Ri0tE)1dP6*%hKIdEt)yM;qsr3ivK1V0Qgn- zH~B1S{$^f1QI}cGom!V&;b$i76Xi`97rY<@;jLsL5Z8wF@-DE=NH0+G*e*NU&sIdT zqw}uCladhE-vQHQrVe8z{?;PN{qm_`O-VInc+v$f%>fP2o%6LrAZK$_QXQ&&56@ zj=>Ri#cCM~-R3I`$`V8VzCf^iLuWaJMdZ*KI5ze&UQJC6_R1v=ri#Yu(+SpV-7g5b zw`7@BL>MJ~Eq1KIJEfB(z-TG4fuo;>OV*_9YPoD0y@+QP{pQVnT&#BgXQFAbh?8EI z2kwGAPqyyJTrQVNW9b3fsB{FeEGza>io$+_r6LaMVXWlh8_?EhBo(>B6%)>^E{uxk)> zfK$V~6@}Dis4KCXA`(TrT%iU5h;rQHHK- z$alr@XGB>flprGhtprSObmcn|8_CtS7}eS5OhmCiYrvy7 z*I8`sItQp?1wymxu!xEJAVK`z=OZ<`T&=8LLNA7Vz zc)8bJeFXk-@XYt;)~FD=&L%Y@b8SJ91ibIlomvE5n-6DbvAYu2|)---lF zkkf7_3!;ft=Kco)1e4nhJQVcfL2}Ps7jE8B^QOw}I-Pp3XX~-14L!JfH}a zOimjdhJpNi6Sn%Vw3zGhGF07eF>if(dqNuXL40)eb(7xJwm`dU(gl#6y2+B}?RJX% z-r#SLCzQt2L!kXGZ{U+T<3wTB254tgh|toj8s&_G-<4s@-#bNM(ZhlSTKTocFVLzz z8G7E&Cj`ebB_s3SsxEX@NfLN$NopI~Ai;KukPZZjTV>mWg0}nxHNT zpSK!nD?O$ej3tWRHD>e&-cw5CxvCT1lfvBM3R82s=j|Q@wVYib!0Zo|HCwFFe+CVy z%FJzMFkN^&mL}r;C(0USS@!c2_F)R_A9#S%lE>Qc3c&L&)p3L}9I652)liry57Yi zb)CLZg|tM?VFn|CL#d>5>%3eVUVz*zHp1@)rf$r5+gnUwFdYx_F~lCbf2G8!$)-f$+4z91GzO(|(2D+!T&zHLwdUQ|N1RFN zj^?b7h}^+qHL*p5jGWw4Io(WgZ-WG>k35`EcSfy<*f*p|Aix;uu6forX90-sGrJE; ze%#zt%8+gP&O2C0zN`WPw9@K^WHh_>;A)R2-3Af9>BY@Ner|*VR%!^vsyRi44redR z#Hs~ecHOfoqL`s)qpSOH??2@a1ni?L{lGvSHBU?3{oN*lQb<^6OXY+>-JuZDw}GR#UbuWa$$vY8C@p_~#2fk`=C z*<2f(Yi4m-o|CI{{iwHP;NviF@Giwtk4yEYn99qeGegDN`fqHo%{6={#VyhM1x?UE zMOqvb*o&jupJzXuScg1HCKI0bB_Pf`rr`gVQex-TiCogBATX9Q`4DU*xyyb&<1&0mC9;TK z>AEMiS7kFzRG;$2JNVQ$3fEyPhHv>k=U~hv01~<423f35kI-4v|5P|wx?uI!C|b(S zo!p^j8wlw6%A#B1NHaCDr6YL{{I=!+`zi@nXt0tn9bGQc=IVy5$PM&uP~=f7Z9nP_F-CPz=lrTA=7D25FiAv!JBy$v!Hk(8>_VNcBNBdoI~`qF?eHMjFTM^&}nQ z3AA0dn9b2*95?g^!T>QPTP6{GUWM6DC~6`;l>-i9kpc5W4qx@kQlL+un;_@pL>*_t z&6(k#j==Bq5_L7I{C*zbhi9T?cazulKq|Fzm~gtMIp#Xtclg*sD-p@HN#(Q=5rS)} zx=xdIHstHtc8}Tp=bSXd(C@6{1^FT*`({EMs21R7&vi|0I;Y-6x z+rp#+1suc{AwyD~$Bw7zpFS*kv`yQHd}4PypJYB1dy~rV2#CF*n|TI16W3Dt@nIK1 ze2v(a*jvPrWgDJYs^sN>ZmZ=?S%x`f79= zp(DJHb#tN+#WkP)HL{4ueuj?Y5GG)7fI+U!qEZjhOL*J|UX(%p%*06yLgQtdkjmkz5wz*ki3b8kI0FzcsR!&c#oQI1IhU)&txvwTDWj-+j_OcG@ zB5D=l_TNiZ&1Hm%r!f?S6-my_Z*%%?f!M_)HG)H`fOdl zJKw4{t;*9SWkPCFwfapPUDGyZgr0F+Qz*WJ#f~=tggtR2fy=Qaj``+XjMo=~@DQ4p z^i-cL+>A6y&Sw~rm0lo`4m=&cjy!ei)DLDL2SX2z;V^9$T-JhXR+5{a;gaiYI>AQ4 zGe&fuYN*m9fS*sO_zb&$V4lIASxSeRnd2UW2qnwMhcoHN?+nxP4H1cZ3bXAsNa68v z(uow)%GP#@ZAj0J1`C=Vl=Z7c3j!^O&h)Ac1Ea`lx<7}c+@~!+rx2?>s>vW+DqiQqet02|LlfT+M9Io z=_%JR*GuNT^Pr%E!`fZ#RG+WB9tMP8HK!*45Tm%mw4Cy}%Z|}F`dfbKbn06hof`>g z+*Ix*EyrcVbHwey4ESAR`RKjI#&x5nO^~}VMN4Q!Q+4fGD*>EX$}&0urUV4NR_C6I zq@rVuZbN&=?47f{y+1Z%y#AQ~!`n0CK_EM4PSR>#xkwb#0+bV0GuC()Z)o~gi&H?s zd<)B+{RsFwHYtJYD*U8L{J)q8(fOhXm9@KSq;F!7yoK^=Bt#~147f-YyzKb> z{Oh$!(M=AZNv9pUw0V7)G^||jjBoUjoJpI%DX{snSThp%8#7i0_`ko{6r$? z+UX5&XSTzSqP$gsyblAvoE$!eKU^b`&y#~pH`N2n&~(dE-D!KLq&nyOUEUt)U?djT znIX9El_*wZT4*SGCn3Q#v-5&@kjg|^fz^9)oa9=OIV>^c)p7P-I+hO89Z0eIr$3uJ zH<$&J!KK&*Z*(4N@tsyj`0E;g$~OuRH#K_|Y`OH{?F?!!b18<2>NF^3fa{@>YqW0_ zA7x?WLR(eqfH^i0H93BK-D`raXq@3^>V6{N!@uGMdZ`+`$7?lpEqSpFM>wCw#GeI} zlc6(g3=O);y`H%RpbNSQ$D%`21j&7n4JvbjG^R9puYW^EJEsQb$TJWVo_jZZ0$gAd z;T_~+X329otkB>+LkRrH!gau4ji*Q&JQpkJ7S_J5)HbM)C4PXn%HaL^4~QE zzFJ6q>+ASigN+gZZ5*dWyV(~#0RPV9iC4Q67g}a!+55DMk8LI=4;9@GlwZ)QZnh z#EC0<=ZWStx&XfE9^8>~lk4#vx9OorSOO0QjcQ^QO!k^b38?FUrcy{5Bm$)i*AIq{ z`irlj_!y23XK?Zyw6Lp_aeF$EzNo{}yz6Xfz-sCB`FL!Lpeq`rb5c3Bv!W1S40?sh z$?WM4Vg)d6B(~Zg{=O@Si5@V>Q^cxoAdq0XCjMKwGa7U-XJ!m69yh^Oi{-U@HFLl` zWF5U?%>+~6r~rfuMl8XGlM#kWaf;*>d`bzHTL@h}JV5|&BUHC9z<=96>OZA8|D`nkX7*&1& z@1qhl*mo#99E7%wegKepQQJ(i`TRjgw|Yo0OInkA$u^8Hhg4UH{;r`w>e1gt?tYsv zH-@diZiov1u({pp(DQ;==KSO409rTxr5cgndGbH|sSB4Lr;z?R65=tC7RL4(2p&a8 z?QJv8?a{5RN@skw#1;T*ixm(@QAPe}dT#S|@)UU7-pCJ;}s!o`oy>)pZiE zkQe{uOwS=3|Fw)6YvDobTNK0yEm#x}EaUp_2gjx}HhpEdH6M*|jfFk@C; zf3`mP%U2*iQ*u|&GecEPxY2b50(>}_U~_dQSH*aD!T1uYc4zwUUUDw{-|1ZMl!ygB z;cT!ybdm zo(wmV#xkwv0xFIj1?F!!MhW$I=`9KfKc>iyHqy##>-F2OnPo)M7S&OsrpqNU^xg#r zzaM>fjGi+aLg(I0>)vDX0d%xycdVm94M__nj+%|P_-BWMp92`U;KufEmW%a=ZHAn~ zM5XnuPG}#HjL3v$Jc0|2uRGd}n-bu|5YGP7qkXZG);d&5bTtSy3XRicxdmwe0BE2z zjEsD*XzR44P0$0$fIF_R8TjsIRG!#Z9#W>ob*b~*_q}PLY21W$3lq}!53r*RDL%du zSdqElw~jY;jChnq`fAW6!}gPn%b)-S?gV=V6qigE{HPRW!XFtcqk;2WW!t1VR8 zD}u%gk2x|-dN&(4qE+pEW}K?B;KblhQ<+6DhO)5cu+8+ z3~gBD?h4+eIaW2bPduh19{HAPGGXU8!0E15Ln`B?Zdr2BH=`sXp%lnTA2M}t?t1*) z^ERMqr=$yyT<5D|Q6q4Xj6eoetRq@iKVq+M4-bOk=&ax07qV+h@$Xb%azP&CwLZ-kGZ`JI<{6U_@}2qXrxO zWnyG=uTaqe0M)MT`WIufO}mkdX)KYpKyuLybFNMu_4DG71>Cwq+mfxu!-jf}qG6ce z{$OL-(f==)8fzNA`D6H_6_A$D`HdUqcD07dl(#-%Q{Kj24wM!5d3;7WPWNg|Tu(l@ z)Fjm3_sd4DIe#1iCft1 zTBW z{-VwBfr(j-zd=M(Vs4M19aBYI--8gu(!MgMchTFSUWFZ@-UGbK%pk_iRF8-2zvO@h z-^V=m9AHvMHNqK#%rYG4idBTv!w*R_>*t;B0!UQyX3TjTQKw|oZ%%r1dv8CNzGEgu zI{<(pgX$4*PMDga&o$Zy;&mu}H;(u>jXzsWrFh?3j1@uS?S#7Biw3XJ`7g2!ThScR zATB|1a!ydr_;f?Vm5CM`wuMa`?8;%y%w$^+m&>pg2=po7)>@*{I10(KSp70^*Xg1C zNu^*8tmgZG-SJ#2#6;X`oLDT`pi+UNx%I^**HOY5mG_@q`7eD5v4#BUb{`@(#&hEK^snq7YkHK(<2(-M1_p)Ac~oZy(*2tHAG z!86OZjRz!7 z<((o7kIvodaV!s2^XrD>yj>eCcQ>ozye5Kq1O|%?aF~5M`SOC1AqB@tMl%jzIgvOW z*eUHrbb=CfPDau*VlZ16^y!qizFk!udcYQcCq_+Ht@b+Togx+^N&ZU2vij1z2j%x> z^4~Fk{YJgKx7{x3hc%<*x_IonhCxu}GXxAfVjt5j-4aJ&&cDBd58oo*N*E0>Ugku` zS+s)%w+&ssbDZ<{DpeeCI~m(X_y``XH%dorpj$xJ_y!H$1G;yxPUMgR(>+qVC+lqb zv0UCE!2%zN#sZI4fIQINqBHI|3SubkNB&WWu>w@wIV_jX0eA;}b`AAh%R`d&$ng|amk(RIZ(=u=}oXzhJbc9fgtk9#$mkm@uuRw4L9s2%z9d*b0y~l%uCMIwc(2&PTLK1gbx+y&@RDVes$@!6A$dRi)_Omy6)3Je75d%HCZ3TPe;c z&@tg$hj3`hxAIZ^rHeUqD`u)3(u!91V~NDj{j9v78&53!pmQ>jE5LoPhDePI!}8=Dj@LJ@A^-{WTyDXKChv?sI(gSq+Qx)MN-d)Cz*h|GRZ z_Dn*#0M zluR}p54k+636sdn7e84y*pK}jC`NzR49`Se1}Zw`;+nC6GC02b(PmB>G0nra2g={n zikjcfhTxSpjkbar{!I7en9wSd&=xyxXwX&Nj+tr3TV zlFaP7LC6(jCvqgP%}Mm)A#dS#AME|!ZtY<0`Ho!maOcw_u0q4u;dIW{nS2CNJ(_;7!ccDi zqG&+;old66hwQ+~;>94j}`gXMgfJy_U8b9>Pl(Sn4 zI4T4am~T?koQmX1s>3tb`^B&p32Q{(mA8(rLE$r*-jfjP zlELvG<*v8msO-CeX0U$FO&~+Z0AR|N2O-9Wrsy{;&4amH)>gRaLh(0_5Quodt0dYs z61_flJyhx242}!$fASfqWtR z!4h*9M8xZk>Yzc5C33QTm7-zB2kaaFv2;F;*x|i(6v}$s&9lrztLz2=_(hCObsJ?N zAzr6sd#zLyNI`aaoy{vY_axUKL{i#N4v*djr&55yfs5s@&`p~oLVRYNo6Sagfz5&H zyP1Y!*o{cix;~Uf=69rZxhW>!ZjmMgNS{8$HjEz~aA@xUZw6mf!Rrv&_g1w$i>HFK zdQf9^-ONla9&HhJj3;AGzjb2$itmI5!26ns#Gc&A6^1`VzlHmih)|jEq|k_^e5!n5 zb75h+ZH7|wZgRPywJ3pI* zgK-t>Y9l^L78!Jvj5hUqOPa=VLcE4uZAydzP!$9CJm!8@`NVWpZ4YaAarBX|TCkfg z7q#i1Lz>Qpe7lh^E8N##8#Z+|+B;2wmtIdY?5SuBQk?BR?IYfnfUJiToFe3{NiYo6SoCV9~bZe;k+kO8`jQvA<# z?pJ!=7i@~wPyx_liZe7;4oUw6bVaITPZeYZd8x;4q)tDpVS^#Jg8B_9VQ2*emQJkm z09APySo`*>kX_-91%`BCapO=nls!^mU2n1*0#Lvq1P4;jjt!-Pb8w0I;K>@Q2+7H{ zw938mevNd)GR0uLQ)NU5SupE!rE=m_22y5&X@>-0JXXtbWxVFz61XO(X23Yi8MbFtr)fa-a(#wLH}HB6v_VDCOQ%RE@?pb8YjVZ`lK)EcPoVFA z2p-_fAUpv*aACR3dp4EmKzU)zTJX&C117-iq0xUZ$E8s*8k9tq_AZt1p@?Mq(GHyJ zU_GCTSZ?jmE(xH&&dQQJ>t90oQV@_ES)F1oD`A;an`x}X-gpqn%WF(>8(^z9^;Qth zln)DJL729^-|>U@XH&>jXJ4N#+g@T4ry7?G7^(jkh3!&>JPBm-WS3tl2!FRo+-G7c zFYu3cN30HA4nXxbL%{S=;^7nR_6}1IieC4_nA>vols}aPXpmwPVe@QUwrK`JApp&+ zHOH^8ZQKs>7uP&D2alB3fr0xqFsk$rD6L&cPb|gf<5FUExcz7d4wB<1H9!e!L^kRp z$ahb>{`XFTen$Sj@fw=rR?BzldQjWg=ThtvbeUECO~Z;-kIUpIFyh1TXfY;o>*lps z(jOf&r}mgdVCn5yCY1dCwF#D3w2lymP(`Lv!Us0KV-Bk}l)OE&@{%kz9X=(lJq zdG)vXdOAPW3_V=%s0TII>pc>o*QyrqoKRX?R4ibXC9uPxn=-IYr=fl39)v_(?B>K- z9KbN&KzgJRu4KPs*X*-UWcAI>uzzvA-wTYa`R_rn0dK^zy$!;6QH21!H{n0zuRts9V>`k0!^Zl)}x#BspNq}FE zN|1LL0vzQN_AJ8P6OF_(-IryuO`U8Z^$~zEq2~4-mo@-yYRF3r&2{F%`gyvk9<06= z`a!(tNsoj5w@UvkPynEx5}=o0LzC?ot0Qx!6F;gWwKeI+n>Bgs&IBll6T1T~+PO?H zP1mLe;bgTuJkLJOjqaQ(RTHAscyCFcM+J;&>TU9Pz(|;|zDJxAS&cHRYC*(oecVV< zpu(D`n;g-JsgDe8O2D*|!v3(o2~z@^y<*^IgPKU14vcv#|1T*~Z88v2G`#ahh9vjF z)1=(HwU|q^#@u2J*p3;yFT;ITD*GuxO+ev3!A{h!Q5_&JM2@O0z}N`(r7z(`SCT@8Vp}LBFQn=$O&@nit?x=(MGX5w_Ws3rIF&H1%w~#@5n`mR?+l^M{ zG=nGWVI3+A9CmK$zHckk&K*1lzk-qRyX&wcje|?_dk>sMXnOStI@I2s^a!ffC_BA= z$%QiLCESFV?tq(EmPa?!kW-#gR4eL43bWjYlBh!QfDOK1^eg!;R)Zoagl+r$n!R~u zxztAbJyy6}udQxmgA3uKd2YGojvejpi+ogX|4^kk>Jt9}eK+&iQ-D*wWh0@EM$*2l z67Ocbl34b7mdvmr_C=2Ij6WCKqi)V6Iacem3wqa>efji2Xx@L4R26z^L9I1zAtzdQfrJ?FEeP6i_T^c(AQ&)oN1<#xO= zk)Yw-JGb5p(~w-I-x_R8WG3c$f$HSb4R zwjLw{7JP#J_#E#!7uo6!USRxc%p#Yv+{`fZLowHJ(jd&NSZD(QDez(ZSkp)4p;eZO zJn30ZQ1o%8Gg*~;2cGd(az(yjx}C)ezFQombeDuxI1|&U(%qkWrjL38BB6vJ?;?E_pV}ziwfcOChcf*nWx?H|iS7JSH zkTkx|C(;t_N{@6$>y3N)>&7{P*Qq`O8wKD1`!KO5Km#2AzGcXbl7X{aALlNwWAZ^& zhdN9DD|+#-kUJqBNuWg~jjc z61!}^8q`h=nejf!{<*E3w5|}|UX=2{HPDe*m!2XRCMii1o*+n`3$1PVQEUpw&i5Y> zmzq?z2JW|idB137M`1?e$c%*g-(J@@CX&b7vWF3X9cs^-+J$&l6=MX2owO?N#cxXB_AS2INhk4{3^j zqtWqcp7#r7?k1v|m_*W5SkV)SfW;rfaiWFEq9w5@iIIl6oOdJ*|52w+WC$Uqql7Zv z^VhC$*qS=qwVhRxscbq^t$Yui$p*BKFoh3{q0BqgJvHDi2@`rHf}vqF3tkXOkxDYt zRix9QIr1f?@keIihx{S7#{O^KR`%D8^aex2ki0_Aa`Cdjf0G|x967z!ot!}<0>ZK? zAgHgxO4Xfkc0LM+&a%WsqC zQa`v?5?H+@vpM%^66b@7u|X~FT50nfE{7%Fnhe1C0mlU4CuqbMl1lTREfzqS9Sf7( zQHqb#U4K2C>+(Ie*=7Nu3j`|02xE7tuG^YX6-H?*M<7PR@NEw_VqQasnY;=$hNJ;v ze_`~Q4*?&qa3OlYAVNOrji|)H3j`te^%pIS_~VdmLN4jl{Kjs^*d1bRp&mlcs|H)a zU&0W~4PX%tT30qtqsuOA2oIErEV+noI|osp(P&}n2fB;7Tt)kseH7KW|HrtxxHFJj zo-zy{Z4X09E2V;J^6hw3GgVZ=XGZz@9NPmEG-|ojZR9U4X z-$<6 zUcmI{#8HpQ<5=sVEnyXMk@|-F9f1TWqQz0NmTZq6Soux;+)^WpL0g5@zTch}!|-G7 zOo#d-8cxVPr0RZGBBzkiFVW6%6y_<7l%VmFZ3dH=q6A=*iAb0q=>H1CUIg% zHey{+>#e{=A{Z=?zNRX|DN+zRc{zM7G8XhfbriUp#Qb#?O`HK2;sMCRqfv`^jD!Bw zN)}-RvryjE$N6R6n`I*JBRRC&$Hms8Y{yx5!&)IJ?xiJ;}}N}x|}Y8>nkd2hyw z`eeVHZM0%tfYNB|laPUxuD1|M`xKi?F3Y{poDdinS`f1$GwM^r?gEp~&~THm2b2Q@ z=|H)uDj}BAq@{fm;QCKLb=|CvJ&~9>BrX3T;5cT#t#l2!DFF+GMo;0XE)^+degwq2 z*%s`Y#yN;M5QNB;#c=~(sY`c$YlCExI6I2L8~i`mXyw2ZbbgMgQLb;k_VksLE=uM} zxrj4e+pd}TP~QiiVG%Ru+_*n;5rMZ>ZeR)U>fH_l$~t}RU}0fzTP=|;uBe2xF!nvWD zp=koQ!rJ?$6zB`e%I5+_m+!ZRQ;kJb?-{s_s4?t+r-k;zhZW4t9!Js7$-SxG--?}} z`h*>nSnJsEnGc<$XZX09`gB{e5g7C2U`{x2@*`v-%dqAFx^SZr=y$_3p?)P;;A&VE zm)VpIZnmg}jKG+S(-pE?tkP&7v=!&wk{Dh94K8=SH@M9+Y-*xP+pXseLL{2Szef~g z@H=E25g%n^Mdi%)0Fp{;9l}z@i*RG^>gP0P1vgkTq~x{IU<6;=2;eu4>nz-2aaDPQ zmC_P&hJTZN%+e^j2h_xHCCk5`+ue*b?)u9cO^5U{Z z9akGAZg>D*sz$6YSv_S-iZ~40S)Wi!f7h5DamMTf54kW^Js0Gcm_US_+U zY&GFyytR2pQe|d*B(~VT#Nk%0$n9bZ;J;^r9<0|OJyV{OCACv&f@!^B7k(*kC7^vB z4m&C(l^dYA(1II+s0w|?&6A76iKW4*d<9=>oSyL%;5s+hrmJB}0De*Ssyl+FbrM;5~V} zk7Z0|U`07C5n|+yQH6+g#*YT*pizo(Zg~l7QIKnh8IA9}u2>XU(8eavUC}LML1=`0Jbit8NZxeHF(-=_l>y;1seu^3S3fh_x(4R$ftY+8shrh!H4?at&#>? zsK&@iiEA1VzJykZ^n)`$DJpV$T0delF?`vFhr|TBbI7r>Nh6~bybVDXK2h&#IR2jk zCLMOdO;JC%NSqEg&S65YQu^9`B7aXM9HfZS6y2ccHx6uo*|@JG5_pvsQd``})qAWK)9{-zsyEYm5Bwy_UD+7Z+jKTx^5-mWCP$f)x8xolrNm1~3MrH)zh~CpUtlibRyCdG%*na(8)hnZ zv%fDGE96uKp4?xKhN+oMUa5%T-4fl8RrjhAj&v+2X>+ zcR$jt6tI=2B(^)Dt$B^*!Vx4sLV($A64Y>e9mtcZsP;9G;u0XZnHz7L1u4|@W5z}3L(J)^vyH3Q@6b2=!SXd)5S9~zZ5uS_0L9N zHhIW6pacs?Se~gsV_yn-mp{F-rhr&cUM`<^l5&Y{!)wf)o;I*&ZyCswXS>Sspt>Pp zwq-V0!?H6OZ*i^)Z7MaVYXNh$oFL}ks`C#qnH~Eh-bzeoRsSR9^2{Kh9g>3Un)bh9(TkzdEo}!k{_M^kq%8TtfhrX za+lFpfdXzyP}#Wyt@QQ91frmf{Xahb+CjUI!XWfC>Cc|6jg4BnsA6yGyT^pz`CTLl zyPZbEk2TlUM zlspSETEw}|W|%%4=o?81m797=#6nOJP!cJj9YRN8A(;r6C=)&8TMMFo9cpBp7ca=m zb5}!aS$)t{`beChh7&VQ|DyOHFi;Y2)FE+)&As}*2Qg;Gqn+;(tbh+GNZZxKz? zRF=F5_6Mj|8t^MI;k&0V^_YCAlcimv?{{KG!8w(V`hoS#5wHG}^#h>6*qkesfHH;! z->G92mbqZ>Nd-%Yy|~x4)AA4rh2nCy4ym8tkPhgc(@8!3UxTRhpg4UU7c5_cNkRL% zF^3#x#@(MsuA2e%N5Al-#G|i6&P;>7Hxiq43&WIF%I<2u`VdaPdhIjRvGHSK7a@Ic zHh6|hmf}MJ+jxaprn#t z@{FM?O|=>I(eYpUkevCWDrWj{%u75K{1xj;=~6Uu_F!5QBepq+8&&!X58yQ)bmq3e zeSZLP=o~rge>iqPvVYn9{3ywy|ki&YbHETk~CiWBO^Um%!99TgxDm zM~yY;4K>zC2X6P1OXHOwmZHr#{lrexn?i-A6bBC=jK&jIG}s(}$tSm|Uc}irximcU zq#F_FtD3nyiW9CNtCLD#VGWQy^)tP9Xskp&C?e-MQmFgPzHT7KZxC5j>6kJ)?9tVp zZTtV0bS~|sQ-~>pe;N9B0iZu8XUC+Hh;H|J+9R}tU!&X_B4Q8u1Ijyl!BugV?T^Wz z6{dCwXGhx=IM*XG#FdlUJG3+l=@UYEr^QX$!O}p&Z;N@;COsh!KqbM)S-Mh-nVtZe zgiwN1#Nf;ru+Q4nN&Jt$k(Y+M@vKKg$)RR~g77t;47Mk&6B)#l9~4ldbaQ48pK1k8 zS)0&O0XHGu$BVmowm`Y}FeV2hFE!-O)Iv~0N&|qKqSp#tz;X7cf+x!OPafH2X?c2H zhM;!U@KBZbEWTob)cZ^3oMl>&fLyB6^G~NVzyO7$QH_=;7>6%{mGp}+51v1vH?Zdo z*W>xo0{9dusHjFT_qOH~=?AF_fd-Px{!XIvskgVEm z*5$pI{a1~-iKuz(b6o=Az7>0&Jk6>EB7>(H%N9RRzdMOAGgsBXqwT1pGW@xPQ2jBGgN2zQ7~?zC{o-(y-(`Wy^6qEs99s&dD=&kfEj_JUCt7j6CC=ehpdXx;;Q>>k4^vm+kl zJAaRC8>7TCaWU8|<`_ZcV1*P$s)<+FMR2der#4JjZ=rIGGg6(C%@R*Sqz0tvb|8nj zcc>NjOp}vTxZBfS|C>;T^di;wug9|l7uv0ML0|}}A`#$sFX8hJ`9aL)Q)cghRpsU* zJ|9Ez&@MeJ{|F%3yN>-lw&kQDz^YVqS_-g@jGlcL+nSJZF9Cyxi~lnVq8r=ug{p`K zWl+AN>9>>-_1uI~G(+yyya5*!gZ&?G z%o|Fj*6cdYeFAe^@cN)HtPh&Iw5Ew{TM}k!b#`ujcHar?dLtg#Lz#4q}|TESRDHSd1B;!wfxIFMc^#by&FfRgdD z1Q!3JEnet+65Vnj&u2}n87>FKH}N-xFCh>5DkBr;hs&f{G3YSA7RR!~X8w=*41&XD z@*n13v{`Kd9*8}V?##t3kZtoAmi#H}yb(^wI@r7~XM86@QuE zR>lv|yhW(nvZ1+`b1N`cob|v8>2aNQ(;8|-4;~vExr@o{d>FD0 zab_@`l=&lypIwkb>P5!fJk7pTgwfbmG*0jB=QdVZQ#-%aTswaH@)-TK0=>PIobz4~ zDxiN@6I4_nQIx^EN*ZcLTNh;}Y<$w-l$7oFm0a&@M$BkDx8f@)E3Vkpzv&=~K^W;m zK9dotBUchGUAd1jGPlS9&*tH~kkylia8hR5LEE|%TPC*qY^~FZ0V1EGQjbKi33C}Q z&mBJ9MU;yb3FV5V+Gh&at+7UjN4;}mgkoj7^N3z<>exo2n&yYoe$^8C=oP8B#Fic$ zKz$Kd7jtvf7xMinB(!n8Vmw!j!E&%3M&*qeglXbK@k*VEW#i40P0{9n!wQK9nWp%8 z%0Eo4A&nvHy;QXo-*r&7cl(@G$ds=wCo>orkk$Awc2-lBGBbPvn+M*yqDVZ@w zJ3a?0s&MN#gD3ioclh$m{WR-Q#{jZ$0BgAevT6w)Qa=NPEa9TNT(?O!OTYHi*VicK zoAZ7TEt);#F+?(&o^;XV>3Sx4HO_Q-b2?r}5G8b$_g#7 zhEpqqPVDtaUnLtiGQ}v%y>YM9)5D_Qz?9|-I@V-Miyj59NGaFV7`X4i*vUM#Hn+!+ z9W#j^sfJfFBD8NbR7-xnli8tw;(gH)WuMiPW?}dSN?lB;)J`;BdL@dWPAE$0sRv%W z>_|3>GWz3YRnPmwIt6FB?WWF?)|l6!mVS}PNbL+z~B|rMODev0un1~n9yOPv6 z1;N zIxbOz0EeDQaNJ>RCV#NareQp~29jOO_JOs|xP zoy!XLo0J|PL|&?O3-)%N>wm({UhJ6*TjL(`69rqv7@fX`!Fspqa#XAbykuGRrY0aPB zb{Tz=RgcvbFyLFABhOXIi@jpp1ksdxTQ#RL_6uBS5J*Veiivqq3fFh;$n_9S_J zQj^9hF=w3M;sfK2aUVs8T-P&!vsUWpGXgvMx1`^tL~gC6UhRkTUvA2P4vb?IAd}zq zpqjXk^u-I8Oq0gIR1BZ`QCmiK^+dFbsnJ3vd2Ad+ZN4af^-!4FCRe~Tz}80~sz(%@ zsJQ==*|~gEu7te;Mz;BD)Zr$sRmil-9w`42Ic5QJpc>7y1D^N%;AopHTUK+s+T$X_QNc zZRO5iEI;NitNt#ba~s%s(taJPfmn=EUf@v;#3_kaWcMxL-NHG71E4p@yMb?~J3n)H zG(hTX8OgL`6&rJBwaL!TYgE!7Vlnk{Tm_i!bR#MPZ@q_$lk?3JSryW|Rs(6v1Z58< z9hzTPEe{M^i73SjJ=IJxMzM>P+w`S_?CYWmxu$5GE~~%slC37ADW*dMVQ0V@-Qdzg z@uPg#*4^0SvXnx%k6uaog8XxJgd6&%O?9Et?1C5|Y+xt=8b-P6YuI1dmpn-Y;ouD? z!8TZLp9byvR2xBS za)}7#OUtiud)|9EVN&D=Is*^!WFDT`6d)tp85D0OKp*lRa}}H4q`Xq3Q%DJ&`lIxm z{%Ai2$wABPXw0FIu;$O}6HqcCHM0qtzrTb}*VLec{t1n>5`~67II}^9?^d)0V6C&TO8_$y& z5?Ifi+HoC_Pr0L1?Rn10!tdWwF`?%|5WF}SBEC%8o<MUGz>l8T{ZQAEEm4SnNj^#J)R6*>3EI zVOY~pdyliP*1K|B1qC6~tP?0ZXw`n@2X&xaZh%Ef7`sJw2(S|JT;8fj2w9WN|APFZ-wdFII;i@4j%R_&KSOE70@fLtGF86tC%eo zLMoG$hBf{}#E<0E@h|be_}h?3GX4JB@U~zZHMwJPy=5pC3(xq-$~C$Q(FUmxV82rw zwyyn>)`&L;rFoAh(tT>niiwO8r{im`xJ`CqL&Jb3swNmHuZCU0o=~vgs#nhFP78{c zrO5x`REf|-R!5Np`C=g!eDeU%7s>GGru9kiTnEWrI^gU&NKwf^FBDnKGAbLNJYcGj zZnDb~J=^6oXXs18uFp-Uj&EdS&jP2m`4&0YPc9jLyjm3etA2M51G~AW44J|%VCEa( zXfIpPgP>u-x%W#eR3?r* zBkY#nzWQ?jQwm>WD>7pp08meJqw>GmC7Dv=Yg7OWaLnzrx|Qe{FJefJXspjczVgZf zyr=j3cuKtWp_x4834FF;&oBo^_6W(JIh6{1%bA`JO#=8j-qwoc#o^`mM2xJeKB>dm zNY*_4&G(h>wx;84(Tyo=iZe0;bw99Wn3#Q zeG)k+^F@($XD#l0*$~%W-^K4%P4DzSfYQ@QqiS6=`}q$EFa4SlgVDn@X-!^_2ZP05_Op60b9_BLp>?_0ZxRr!Hs zIy|o2d8Z*MBq6wEJc``miEI^z0bH273OdS%RUNri-$m`7QkS9mnLpJc_~Wg>Bu0Ya zxBYm=sflvjedEj`Z_DlvNQWMq;E{gcdB`9v6X|nU_sIZ)UT_4Sv%Sde9HII~6xx_s zv|*g1K42KW*4vNUdHObWx`h%2IH}^I+-a2!?>mJMlDPG0Wn#Jx)XJo2&na_GX91$l zV4;1~fpPKOQ>fE#l$HMAEpr~d_`JXr>$QR6E^YujpX*wl`dbX9U9D9q({}Z(!P^1c zgvJN+kLm@kEsWFc3!<+i^S(p^!sLAQUuW^20N$KvE?$;c`puX9+hq2KV-ST(O|r{` zAH+{{fDxySRn86wwPev4nGycbh3$j%)DRp-FH9t5`!Zp4NdsS)y6}%V9IjTCaa9Ef z&3I7wj!~J)k<&O*qspxzqLeAXK@|y@?~ggB#>L)Z@oewaL#hgr50L1L;u$b(W0jN( zmD5~GVVH0t!_0>13RJM+1(?02k;w~gB%?n>AD};G<^@lYK+{|10U9yigc3hcvJ zgXF2JFsaDO7cM?D7qPL%F*`HA4V#MJtyUS^)34O2DEh0+UbKVjx2#eA&Bb7~bO)7@ zdJqOab^>KIr#VyTmjH^(@Ks%M{E$=lvmdJFG0)mza`i%V5p>ZX=EdKdO-hQxjh#5d z|Ci^8*;Oh=dWUwF@alc|IC@Ldqhwy&8by5#F1!#no$WJi)Ze7X-pH||$_gpgpSfj_mT@N)80BuB6M`U`rP2&mhmr%1v1Fl6C0 z=-+7Tz*%k+`~N!K4h?#lax@DnGpX;|CsrU6W%pa^U&-V7EjxDzKt!?v$5Xi)l zQ!0%!sRSSwY0)s;n3|jo7o+W3?4uXT_|4k&o%;CKlpy|CTlpynpf}ynofI_zZjp{A z(=3g7u<_e4#;|5EU+|U^(k5(M72)mur85XSZp5cMBPtQ}qrhnagttu5_EColv4*~~ z#yS>=|Idmz-E*2#4O*(>aS{OQDJTr!=^*yd4+ouox}r+V$p31mt!#`UR&u^NL49sJ znJe5AAjOJ-%It)bsRVl3b|`Mk(65GmOTcOf2d>~`Tzqp}($0HHdr0TGt5PV^Xgg*d zDp#F4F+}RA@%UW6m3{Kmn{x02eq0B&3~D<^9^h|JcBG$DKpM3GY5CKlmU(DshAph2G zSUcA@${^4bN#j8uDYXl@;Q#VnsPYkE4wbQS2)sBPRKNw3_7i@)*->d}Di+{7o|(?; zzLiBFk+NInH2VfpEn>^lK&rb3Y5&wQY|XFDs4=WBJ=Z=|1{N*E3!gCJkBuT1=g$5X z+2zNUrAuxMTmo$=vXO<$>M6Yp-qrmuZ!5^7fm9;e&Pe{@b-!#`+Ofm&5ZWHC?FUK$ zFI02Q$QpF|i{LTWSjKKqZ(4K}f~bV~Wmnd0(D83oqthwDyBoEUT4At!ckjnC=I=JZo=TPe|ph^+#n^E}l0 zn78|=*{)_ri#YB3b^rtR)|DFl&X5luk)vGqv9Cb*w@-;Q>6$8|w~dA2i1+Zf}8>{*YoP}p4^w}_i8M)isxY~cl7 z@Bxc=*BB9#5yN9vkRMru@Vx7G`%_b8AWA`Cj8`0^T61ZGfCuGFLk1}&>n%|Lso_9s zGBB86%=Lx+tUd8ZZhhB{&lx`CmvZCtvT^Chh7%>f9KeZ5^1M*u2ad;=mVGnJX*+aN_NQAk{ z>9c%|oRdQsoG!fN$ph_U@EBl(jEN>EN70xAZsv^CJ-%8gur>RTXX#CJhVpcsA8JdC zLtawV)?SwehnH`404fqMdI4}HqGdt7gY^EmCMT(J+cYgUMw%}fkVjv_gi=B@Q^BNV7F)H7-ixQ1-nFdI-ajGX&>e0;$f z#0u&4Tnw*u*VH&xgxB4Bt`9Rd_pK zJfR8LxfJqq3Xt}tQH5uKm#-M;xsA$FkOJLc-+nS=GQ9$X(RMS`_l2+4%sFarNPW4b z#&1+G8vend->~RvdW8O%u1W^-!%_0J`$e^wS6H!9_4n$|M$8dH8UzQ> z{jD6>AbBOOks_B+$RQTy$Fkw{Oi00%As1nZA>?fV&zbUs9cq;4H?uq){P&f}!^!k- zATNgpFb!yuiPj})g!5#oLTQq-llp(mmg_-;^O4vF#v-D-^=}GP2r~++7B0?<9I)j* zmjopMJe|a~nqgfM%4=iEoXe{tN6#FwLox`#q!+&8lx(nQ*Nr1QN74~{2!H0~QT;-H zhg%hqeh#%hiz#%67UJ~#_BoH2UUwgz=Egg-6^7BR6~Ohri}cAu2LetVFEk&Q%Ip)K zCuxxqBqm&vQ+uPoufg)SFR_Qi9+^dBgnTEqP63OF{bCRPacsg=zNpn)$3Egxm9N#u*RHFx0I>>L{Gc*L{mT`I(4L_1L# zXC=DI=0KE#8bxa^z9G8Ra5j3*7F3=Xv*jY~GZjkNGUl4ZWAYyI!D6?CuCQ!`<$_MV zgPvo5*LBrD4R+ujf#r*rXWZLBy}T-FyV}3hcOrr$8dvbRDJ@>t3ZHN8Govw+1g`~Z ziE9WRH5sM&hl|Yr3CanD0j=`&;6u*@ru0_eANTq~wP1#q3+ida^GdUaH7+c+NKC=e zi_jYhu?9t0?5vZiNyVtv*`8T8%GUTZRZa2GB6GYr@yW2d{!M{&=^>7odjmwG!T} z_nSK!)MNw?qWBKOv{x;ftJMV6?5A+^62O8ozaJ1JLkvhTa3aHRP>}j@A`>HY(8m=K zdq}w+zfq@I`L&zA>tGuC0m^^8%cK5k==guqBKydl>~bWiHJWmU@nw~@(6q-F)cw(w zT)Gb|*HnB!+y&1>RHY?Ym)%E`Q$k=Qi(S6A@FUPG&;gdaYNH&hzC@FA z8)*3bWehaFYC|7noxRX+bcd(|*`{YLV+rsk#C}f<=<>vA8;f8x#I|l>I53{)C?lc< zB*fP#nrDq6zb28o%C^!jYCrPYY#f+^w)BQNu=z>m&)`=$e;-H-gFiA<@F|-mPtdq- zVQs?~k>z84G_{IjkRW{3X41a0O3qZzF}{YJJ7ZYx4zJTzgVPBS{~lV4LU7xp3$z@f zJ?1R!VMMo}I11zr8`|WW(BJh6PlUIJ1;y+{dj>c9ChQG&)x0?k##1PHoZK1y+R_*u z(!th1Xk~yi!n>3f5g~^gEMk`DvbnZRcH#gXkkKVRv>u82Yw7rjO4@7TuH+Lx;kN7! zwrIh%$e#qW)1fX2e|)E3JPUCZ?cA|qF26nKS|GT(K@Lz1N*!H$z2RLuamhYT>y<(T zF=WZ8ZV(2ALgX`3zQokE6nRFrl+iHFe5;4`@-ZQ*c$ctcOP9*mSMF<%<&^TCvcN4< zvC!{}QhB%pV)Ivgy2R<@5Ld{!^l$k#)i;)q>;+dFl$0koU?=^!scs4j#b+2J}y-%5iOCB zF)+pWBE@3g;h{PY7uc@0>SjM=&J+i;sDlJ)Z^{0Azea*pEm#57oKD2QJ9~|D|6M^(3%+FGbq}q^!D3IsfQhj;&D+5jk4KY{pGSghBdt=&es*n zTc{=5 z8nKY_EZRg*GQO_|4pmTT+?)FItnblb-!gy(RhpMG)k6@}26fwVQ%q%s zlU$bklk|WTBLD<^&^(rTJ;%P~?2r-Gidk;XZ=o--l*Ba%whK~0Wx6IsaG3w;xGg{; zZg3$)oxpc{NfZlV#v{p$-+?C85ohb#8C-oktc^*Y`~8qh%jg3I@2=prsnmwgpHQon z{ecSrT*+yv&uotn=7Olrb=Sd5DgJoLDjGY|1yl+kry>9#BVUrwTd?WV3Q9GW@0d}a zQ~-WeFqMu*wMd}f5j?P^5#sw2EVcU_^SS&V+e{ev34w~<>H>9KeH&tpCaz$%dffS*1$g?0P|0qX2wqujw!{A72XHEz zQ|zGX|JEyvE#Yr&&QAwmz6p1)5<6{lq-X9>re8udxTR~1J+JZ$WKBMPb~W8{&E92K zDTQq-Ri{sXyh2vAfv%}ENgMPuVMt+f{H4{RABa6`7xKodkMljJ}nMp`Wc|9$kEdlF8~nhIy*y4EKbj9Ab|6{6s6KZXWp&H zZ0#ZWGEXzN>D5xic*?~`f|W=ShJRsb@-Zg+v`>XNb8D@dM3-yj`P%eW_jOa-0QzIu zXORorr+1lb)d}?+DF|Xr3X%)jR2+=LL~U_65%;(YDP}QeW$irs$Z6PVhfc>k(WY}R zV};Fm1(Lf#)*zR6O)Bree7{zyYP$ER)8!iw(llE8n;?__Q*c(hIa}m(?1^{h#O#4} zu+b-n6J)UM-h55>{@~q^XJ~88`J4;)!GRq>(dBRBD?^N*b+D_!EjRXN^=B>;!4YP@ z>$9bGKL!DxnJkUSYOVJ4NN+^R6QD@j#4%RnPMon;#3`nQAFQA=b?$Jn z+wBBLcXpe&w_D9X+1F>SXIa2J!Cor@s@V`Sb+k#v7#{JDT6P9xH@Z5v0}G?Z6-xXwozk<>X$OAt{ z2uSS<*Oi{51B$m2J&2XBCC_l&0+#aB|3D7cU7M9w5<*yfZ)NriWf zdPBTbsR&GyOLg`Vg3JA?;9*Ff@bA%1c4j_c*x%dYHH(eY8tY=Ym=)d7lc`VD;V&BX z6VYrMJ73$jh!kAen5Rfo6=;_cdp%q+xtLv0Rgk> zyQ+lq&iO?O&1X(-7wHl0yi#)uY?E*~L$HL?2xbh4QM1MO>;{-#6`&}U^IP3GNL50^ zPTqrGmkl*FTdrPOaO{j^D-X}%AESGP>l-rb0?o39F~Peh5CgnJKvr!1*qa=Q_y&MM zq&Z`f1P5+YtYk{W;MfsF5^WE+d%s&esqC`OpSB%mg;Lk{n{q3oDtUzn3`?4Bu7j15 zbGQ$97R8$p-{gTw$Qaw0n{Cw4qTk@#mQ8G=P}c2BGmRvqM73rd@L)=ZH{q6O_i$hpJaCG|fVXqlaFfOkK0Jt+RA&ClAl33`ZO%>DKEsGh-K&`6% zt!c1(S-W%h6~{&DWz9*Zs5%nw-t#KZf9$L(*FQ`WQ9J}zdbXIVzq-jbs7%&#UcgcL zkEuST>$GV2Ml5Ak#yW?Ncn8}(=ogHZtwKmVzH&z!Ca=gLK5<6{T&PkC6N@Z`t(+ic z7`jWU0E_4caa~u`7PxAF@W385(RONy&fHdlaALS9Trwb^jYQFaLJ%iF;nH-Vm7aKx za*FakygzYnZgTb{IRNJgq1-p%Y03VUnW{*D>3lMPZ5@}bWbB@k-TcbaUV9d@ZO3Zf z6ZQVUn14sMk>j#ec^D|${j<}I$!i>Kx3+ee2e;pJfl|{mGTIeYcXxITkvPW0uw^R| zKq-Oe{M(^@?KBi|vS^WhDxXXZm7DGSS09#?uelRXn5-*qmyuHdr@`4-nUrQ{^&NNi zq&L7K>ExrHIqt#HgM;rUwQBI~*-$oTVT}Lfw%zkkY zNAja0JHNq(*FUStKfIs3q?<9HWy+WM}hI(*<|cmaU70E`?zhbx+Cz*Fi{p0(7#HK-coW+FN_RY zr1Vq&wJsz+CZyg44yIH&|0*FQi++(wXQbB>^y(Xyoj$?-*$3<#1F6oJchCT%w3+zj zXLUL6!)jS{<%O)nMb&3{cb)7s0{}uP|7y$#KMWAvfszlS?}0>q`>q}DGhmYmXYO6b z=tc^9W+b=P8Z&=)9+xPc`4c8fvv_DPBnN@uiJb?cP?g&)wkheUZUNpWgeZwO^ax-y z1$2pW6WA836-bkSS}`=3;r%ug)h=5YprhropKy)M#T$V?y|{&D69bpE5+ECf>j5MY zG4phOv^LA&!t=U&4W%0i;TCdgiUaCCVYPw{B-w}aaeE}nYp?Rza)SXYrGlDLaV-AL zh9N|7<+pYKf!GS4A#*Vo$BUd%ciAA!UPK|kP>H+iv631__BsdzM%Utt&RZ@tTv<(=2IA4ecEa}L%2kf;AZ0y?P} zk>+kjqy7t5n*hk+lpH-gmfi#MMf&?Zmv^zNu8-yU+?MnWx=scc@rRH{@mwivIai-t zN{ueu1SF77vYrU03l__M+RIZO=~M};)f4X-VxP*y9P=ZYM8!i87;g1DPt~D9exN^+ z#Sp(4Dz4j0TUaHvGJ!e%R4oai>nC}|I z4su1U1;s6n6!)4u5kQe8R`pZVz{9X2AuxyWK)GX-r(Sm#L#pkVEtH^<3%IV>O}Ihip~ptbvGic%D04~@3zD`L;YEd91#&b)?yY8!TZM#YQ9mG=PBqZHSsTM%ZjHbit7M+p4c&`$^$jq!w}o zTwhlKHQmz_M6-lfRFzc0Yw`O-{dtK!PFvH~7bE+O-BwG#OrY@wc~)$ck8PJ$7Nxn) zxv{piH%Y8Ni^Jpjlp{rhnVGLofeR3y8u;>6O;H*_8npb>b>{_Qi} zTl1efye`heSF*tg)8?XRd=M)eRez3}7!Extad5&(;omd1@YLtC!#Fj<`M;X#FYj|^ zaXz!Nxs}m=T3ATVs^_0(BZta--UjcS1_G!oe6_-~Id&-uLy@c3I>x!sr>|LZ6X3Q7ANeZ5jMPfH<$wtW}cN24;|E92wv@1@~)14#Z;1V-a-p31!vOUCm z<^7)9p0lB?8X2B3RzZAyGP=aDYHnMLmXg|^kX>$=`U5)wxi-I~p~=Z0Tr6ShMBqMZv`Y@wCp38apq<`6Yak_E!~k_5~6u38rP%ia?{5+45fl=4_tr)}3;8{`P-io6UdxBMl9-mZKLv8VDO zFS^y|QdX3+q6X>^wfqimMDk9X-$UL>g4ia0D4T-DDhKbubcssNI8YmMl4wFw3;5BK zWlc=YzyEr5ryyJBfmT(U)$|bYW7VH25x~arsB~;G;)sIj`&5;MS(r6x)>}i>dYP^r z@}5R)P+^?8vB2dKBw<{F8Ck{Zt-;uc-(9oKu24sSFjydWyV4xk`p>Mbm4wYLBA-a% z8$ZVsxN`xI95yoCQn_E&yiZVHFEmCfW~~87{5P>-quFWyQ2>r>VB-r64a^4*&&uiz zf!X;?286o<0MZBevuO){D5tO|4Qo)R)Ki+5X32YIfV?@$ zeg!;2){o%3w<07BG$lt{(9Th^qq}C#Fz8)sx=ZXBCEINAZnJitJS0-PjR~0*puvq< zqskR+$;NQx$N0>X^LC5ip;Wrm5(?Z19Ya4u)lCz%&Zpy>+iAN2>HMi>XJpLyxu*sr zD`D2I^5VWZ%gACizJEZt?3Q{0$!=HGm5}ayW|fE}NUziMk~{2^y%sRgL z&P~Hwybmx0&x-7p=#(2nfR!=-jkU*A_2WsRT%oDd?$9k(Tj=-HM`09mXcSE@o48dq0P>QlA&37a7WobKo`5%~9%8&G?|2{3W%QgR=ud~1`?aDr$fY597!f~QF1l25 z(`iMUUaQ+WKDGgXCG5R8|9Pq?S?gG57E(8>7n%|KKL|C@6Rvq75ISs*EgnQ-y35{W zCj>Tyn5ZTe7ZnWw2-J6;+MX_)_80-dhW(sR8S4e* z-RaTVB0Twu2sGhz)G+zDjGY3+*ZqSN>MmBs)@BJvTNPDS zKv;O$Cd3y}A*6YOGp$v%85SolW=?C4D6jP2pdd9`7*VS8iiuM1a*Nz2viHlZI!HFU zdI{J{ffx|=0ZFhGxvwDfJnY*ZF>vYn7*5TBT}F8puq^jgquw`WI0W7#pCL!K0h%lJ zELqvzTI|*F&_uxLvP5tYqVi+QfMn2FJg8x?tot6toega@p1Q)g|A@fwL=v#SCxKYJ z67MT*C=!`l3eY+XQ+><>p0y~SKkVli23|5J3pw|xxtU?&Ix+!55y?59RsNUlq}OW~ z2etALy0Zo+^Y-*ZHRpU}s$Ks|!6K?gv;7A=eMK31!uRgtRIis3tH}p#W{K9t-M?MX zTrILp5`C#*-)$-^1vpH`ONDx6h7#TQMtxr5t1F<#e-|!}b?P^3w9TVOeHq(+&g5UfXd?Y84CsAjZ}Gpj zhzBin7T)6Jyhe%l={aX2M>d@)8UApPSFf7n%IHVJV52mF+rJaTt{t27fp<`2Ytw-C zJD{8csqYAiLQaTAXxs)ADODfNsK0Zx&FX}aW>aKagudxgK0LF5z`RO<%bPwZv!s_7 zfHfd7pB&|+;dMQmZ9N&EBAhHY4V%Ew3;1k!ty{s-FK9@qe%|7|4fB1pLdqwHY@_%@ zS4yv#GF+3ZluToRGkEd^3nPEz6~pTCj+tNsGOnz{J3vfPfuFCX(W;%8Xk!lAD@S#| z8*x@?xJdnipfU z^xHj_kfr0i)+EdF2u!>1xsyjgnWc#hbv|-{0$&Hq|k}d-@JIY};P-mvg~h zyRC$2xO2XM)j`v_HnZj9j~3f0y0Q zsblLc`KU=&F#CJJfl`3D73d^RJs$I*fr0fTDAYs7c&^F_zGAA-m67rItygR<5K(Ky zYJ#Y>-Qb!UrS-v2ZZ9S({Te;OInN;R5avqYQ1$^Q#M@qgDifI~KlIOhFE+omINZcg9^C_HSQ zCykAASIF)*l#d#;n(vg$o?p-^*=tItlV!$)qx)P3+DiA|eNrH4!pg=YsFGVs&}S>R z^D*fUJK>R4S%@Bkk55k)T*>fbybc0BKz5Cu$kQ$oPa_KJk$OVLgW7+2X$k8( z;SK)B0nB1U8L%3~h>dI7@=eLmQE%C8PBDZKj;)3(#Un@zEnL3jtM&$&IhHXOb$d43 z+#hK88h=@4Cw&X3;$(uZ@w7I+=3Y)?KZRc2dyrpF_ahG1gJ{C#aRJ{RwF!=1B!WLl zkD%99ur(Z6JcT?F#HM$zzZ){cr5nV57bI44?X}RNNm6Z5Y`5+occ7?1_`fUxHc(jk$cKV!&YWK_HHseOp z_G+>Vn27vz`2(PYNv%EHJ2Tnv6tp$8J9-?wObeXh+-v&=fr>b^f^BcM%PV6^pd30Y zlgYJ8y{g*6q2;J8v;NZ{q7uG3%_-KD{Cp}17}Ag}`ZsBX<6RrP1&@B3Kmw+Kuw{R+ z{9LX9Am`zlzWzAsrUU8NXX&Bq-?zYU}Ou z;2!xX@g1<~4eS$M?zZEd(!DZ&;r2fadOHb6&~Y zj6^*pB>@9KF_*5-Md;cTcCs-R6BJ1ahr4GAk1V7(ST{MM%gW~dr3pL(XMQ~B*3pSn5L5vOE z!S{@)OFXmFNIep1f+kujtA~m2OIB)q;&{dE!?IdS^}~bW2b@$N%+H<4X^n9NlH);e z4Fm^w;*itdi3?jZy z5f8B5OU_^B=7zy9u0kZYc*x7L`yVw)jz#b>tiFqZ;1Dd1F}36+#wy5E*fp>MWEhzI zz7K@ETyzaX9;-LAX6=`+d~*zAH4=<9PtY;?y2ON<%aH9xr4n&Na21T+IBUF2wL%Qz zA(}h22*NF97bbrg(H~-}3xWvnc4;cF_TomNGSg|Xoth#}(#k;&(LI>I#n=x?w*P5b z+P=_=hsaidEX14fVT-0>$b=bGOMGUD9khWiWww1|bi}o;X56!c9wD6&k2e+8Pn^s4 zdRIv?yu3v$xZ0O-QJMSkrkmlgb9|{cyn;EvSvIn?%Nw|(eew=1gmHi@r|?miF?yV} z!jCqNpW)QY4iu)bZp?2Kho?Exj4-dO95c!2dhu<1W^@9Cs;B?!s|cByVWCen5SZUF z9^KP5pNmEwX9+f`Q){=ON*bLqTg?LiSO1aw-qb0id<(0pTexxY&00*oBhJ_;+`};7 zSNKe6ES@c&j!JP7v$&~(s@Y!^?j|1mIa1Eybbl3nlJ{$L;MgJ75|n)V1>*q*l)h6Q z3O=N-0OAHp^?D%{A!=iRUh;{5b@)jgoDF z<8&)EhBKItE$SraD)c=mf=%O?$;RK$_PRwA0?!jrmkcG1a)166cuxKMEH!*);}>fx z1^~^wHc8!Kph1o!xM{Sv7`rWH0mMpFdyE{QNp$lz8$_(-vS4JlmM(=bL*1BK{s(;e zrb&aeFLX4uOaRF7(SM0hmUB4OOC#j<1C+A8NMq{9+rz1PgaP4}(2If4X9ApLP)hJ} zsj8Che;H031yg^8iQ|Ghy_zxuy{&MvKpMS7n z$vJgRC?#R6UW4X@rF@1~ycaR#2N=E5Ow_q(_k3u~+)p1wK!+K4@H2>rv2eiJFdnYlSH=4Zl(8Fn%}s7>!0C{Df06P>00 zM14K~rV0D7U@+=4!9y&SANh4K@{=oE`}h!MNf>m!*|{w6%?pR1pM8RYe#) zBl1JxLp)v9p2<{@ZZ4a0F_%8vC9QIpx~*OAE>ux2JFU{rnMYHs(B@+YEztfQ_U271 z&e$1b3$nIT3lV~T|w)%?p- zIbUnbAPP`;iB$-Hsd^z3-C^*$m4E&4su|KZ@y*=7z%_6Ai($m^&q5Lwpad37vu}9@ zS^`zoc;wqGjJcER9;L)BL)2F@(UiwTX6=BS-?IYz4-ZD&_f6qU@0s9kv- z&s)J81|R+HY!B4l@C-Hd3_)-SC`Vd_zhJden^sZwfC!Nwn(mP6(T+#b3!lZD1ocK_ z`4OiFhGZxG;TgN`8kJ^a8CyE#(>AS!gph8;#823G|M;kPMoa})9${V|TOaF8i?}3O;3>D|TWCf-^(@ z^MHSctT9n9Dx>7UW?UgI#Wa$bC~r+s*+>7V9WxiGcfd*t>a;c8T)Dmn0b6m95fj3f zYS~}j^nErQvey}rMk74$cpx{-0?_d2uvk_-=;mL3pz_RT0=1#l_6~$Q)1;U+R-bLa zh2WSmjud7dRdx>-tBOQ{DLfpRT9rHL@b$l!3yNh93R*AC#mr^5=}=m2&CsdNs@>A^)= zLu+NPU-Bk+ql9`0nlNZ}Q}MmX(v*^@ZW64$a*R3X^d^O0p3i&fK9a8g>XB}4!K=y^ zlUZ`=XwbezBN*r0sKCwC$F%gHB}0TJ4tGTU>p3h~4~2kqUiyhI{+;EKxeaiHa~Qfc zK@_rKi7CpO;8Yk6f(34f&I|`lBH#x4bIf$}YD9yVjJB1Fi>;UqB&0s^6n=;ua}_)C zA&!$>ijvb~i+Wxh8q!cR6Lo2)tLl1DbW-Xe2w%73r52sGGUQLJAhk!DsF&rS<~yBx z->TEgQ*25Ior^lW$Em^j0me42m;~8}+B_S|c1CjmEQbsCCK`%t59Zb)kc~k95|jhO z%KC;n+?*Hb0>{^N00=d$)QM!{%=$VNqG|10ryruR0n&Z>hW0UwOczw_-v^l-d$v^I zKu1}+&{o<4O>=6;-p!<%B7I3SQOF!{*RryTZ5s?X1%BwCvy%a*{o^^$UC>Lud{Ga9 zwc;zp{+N6{(-S?QSW-d1*d&$KMC*7Pq@H_-mShMC{_Wca%qDNx^t`;nFzbFs((qL> zkK@8lrNJ~o6ASkZ$;;il*zkFyA|!B}enIGe zrdfXc5{vHBegp2GvkTx56jEgn@RUjL`Fi)~C+mG0+DCYkrU36Y6Aqr7GTNWsWYGJV`w) z%7gyr)o0*Sn$Clkn2I(cGaAjT;*gNTmZw>;)H#>K>E0B&*@H5^3|^wCU6LJ1pISZ- zGlhgl<&sWNrdE0b2_`Eqji2AJ;8eFC!1@LuMgATM^kv#OI}XIHHV#T3TQ0KW%5hSd zyUkuhdPF-MBq@lo`*fo+IF+zO-d7z#G&&`feeb5Yy!dk=$)7$( zngdr2to9R0L$7G`K~;*H&Y-`_6hXk`x|;Ya^EZh;Pl6_m3-&7-i(N3|y8)f7m`l@3 za(vJ@LTw#{1MhX*8m@h*@&q-3@U@l%DX$Wa*%ff$P>V5o03{Ov_4Sn2N5K@87gOLg zD~|cnmR6kUs72f~UkDcPN#{}Y|7_hzuEHLDbQoVwOgJ?~EkB%%Ukcr??Y;Fn&oR>Q50b+gWTe?lH;&lv&O1QM?ni?4wUqy34~S64&^Rs_#w^k<}sS zsS^usJ)bDDoJ?@r`(_awvu6+{iF^}J{g~CPy_{L~yAF|a^D|f-bB77^!Ih6+0&fAV zv_3EX#Q}25*jac$q%vPv-XdyAVv8wBL($!xCvIhBZtXBAifo`45{X;=lngtm8if&3 z$vFz`C%3VD4F;slXX~bamSIPc5H+wp!)Ma(rZpd3CfCgpC{z?QzrtLA!iWnmq4HlYcF{;g<3Rw7;KVe#!k$% zuNMkW`J(AQ?0v($NWv>4UPbmJUd(MlpQ;d8nUyRUrkUDsn$qLOI(^Fh5uFPq*Og0m zkVrwYBAm?j=B320^HFx6uKe}Wu3)t2Gc|$`&|AH`Bj){5>NbR|>bqQJz0+WEyRV-x zsc&vwVyw1h9gei{ek1>)<&ommkpj6W$^~Y)PneOxB{2L0)tB?susP$snB#u+iF+%3 za#XmlXHox)QObH8%8H**ZG8J57fgW+lq7-18o$d^3~?}oF+AvNA5N@&#*L?4yD8W% zhQ%IL>ckG{3_A)u^Uu$Nn(u=<^Ekoq)yE?IZF1?~U^v;-Vypxdw1w&7GVmTWUH%%^ z^udw)$om#lvI_GOP$k=sR;a?N!qH2*#q;|b$RwU8;%3G~NnVeV)(8Qnmn7cwuS=951#K6hH_Pi!4!oV7D1<%>!q z@n3IMRb`CkNjOiucLpHm@Ur4zuY64E^v0)__jCGEI=hh=^SD7ah>S>Rla3jNz65p# zdn!k}7cW%z91Fs}N%`KCMQfk*O9mk!(C24(A990v3^g383Y~!%a#}~)QFAUwYOa*) zV%JucWY>&~G}z$JIrhL{;B9e!LN-G}D+SmVjtZ;-ktQV>7hYC2f9?A`fpCpO1p zt$&^O0WUph{%ny|l!!@}%;)t~GQJ?7rD@Pr((_r_(lB?9i@o3;_yrwmAS$>vVTlbU z0s%DzdVk~%inB>m={<@`2c4KERvf>A@la;ZXG|iuFdtyE{KgAK#0F&BAbDm^(XKSy za=KAJW7%8%r@-WIK-`o7NX{duXu7Dq$gN4g4M5ts2kWhC84JRmLaqqi(I&&Xi915r z%^r7Y(J}1AZCX^pB?`wc;Hd!;5GDfD8PHr@uLc(HRrZmCFuQJ8i2QX(oZzpb28#{r z&~lsD8GC4UjqR38qALnL!ajSr;bqd6JApVwsEdAIQ=T$GpQh{*=7qF`!1nbL2}feu zFlsfgj{FyjszU_)=C`@9_g|^1uF0ToC?3|VwjQQ9dxb##;m~(zq-GJzuWz<5^p;qN zw{{dXa9ssY1^A=Tf(!=v2^?Uzm{~etLQXEGQdtQ4PQwU07&T;-pwR$5m(w$yj{Z7_ zg}iTAh;yVIMZGDv3$auy)g+$8ryb+#Yn{T_2xwT#1K$LK+v#j1SCTmjH2ZAsk`c_#=Sfx%?~7H&hMcCSIlQIKv3FMOPdh-OuWa$vi@2Kq0q< zCYlI1Ykc3EbHTT|YS$9}MopBBij0*{NQScyqkpZt=HI)w76t-G>5uZ}+{+jpBI}>T zY4ho%EE*E9>PjbiZh%^P3I$r0EAj`|^~(1Byc}li$dW@vte#D#4);-<0IB-Z=8JX0 zKWtp1*#)b;q$!c6tNnRNK&jqi*;fil6~fc zKrTd4codG|YTA==QH!q|MZ@GZzW%c5v7=OBathX&-z=Dh{SDs&M;==fH^Cd<(U~mC)2Ce>s)PBzrRTef=HApLw~~;gA#%x?f4V}A`K}0YmRY?eY|4jvAbM$t?$`bi zMYSl%*2_(YcGtSipw&3aB!E$d&nl5Z6IewLxfM-uwK#S1S;K*FAfG7{S1X8AHcVX! z9B}@otv@r~e`eZiPu`=GiwS{PEYvQ}v0;)q7W$so%n~Rl3Zj?d@XR>nm7`vA09eC| zXQ=1^3)brF@U8R>7RN(i5y-g(P?pKmPkTQ*vm6u#n<0g#fT}wzXgm%VO8WHo2sjV{Tr}`bWRyp1!dcruqMoo2S-@zlhiWIll z#?3;Zy&UK{T%%;zuk-W`05!-JgP?RI_D>Qu$((AP!#p)C5@T6Th;&pn?TV;yb=u1~SD%@dde5k*W`zUJ++2UOpA_a{INqxD>t z;(Rh^7IH99zLp?C3T(q4N=Jf;X*-E?LXqeZ^@PWxNvE5wC)#oPtc%CbPXG$~BNCfx zEC-@Hzs7jjwj>#tHqex&P?*ITfIYiTPo@YVVlW){W|g5F+L0`%0u#(JliXt6ML~C(o@hsd~F58d(o7^#0m zWX>Fflrjp;!OZI{o90~W#-;yuGv{d?kA9IB##vacD|e;y`2oGWmY2H> zoWXn*#5ml`_sCUW)tTn+ZJJPe35(y!LrE7*C zcmfZB@sT@nZ_m0rV&(6SWCqIXjEzt^iUV#Tm3yZ7IwwZLZD1T&PV_=gbQRYsbE$1} zYj?Ozp3m%_F?SBzukZmHi)=^vd`IR?5HVCP7_7sk&i(2}gWna@T2JM<4`742+)B{3ESqG#CeztH~@xx-mO8*@&0kYug3R_1KMbCc7d|d=9z^1KJ{eEQ``w|CvQG1!Z zlzU3iTCSodZ>J%96B@j2V3BDE<2_wIg~LY)(b&?rH%Q(8cLaoytWiX?FaE?g(0X-Z zk*Q4T&?dQAjvPI`-*_I!Nepx;J^&#I095xv9#M3Ynez+|hm#TlT#t&xvi%ne=2 zV8o&S#klgSV{sYP37#h@#SyZ9lZ;;~JjOOoNX2t(i`Oo)ipSw@U@i0#wF z3JmY_Rp=>3_A84_=>@_Kkc9+ag!Mc6`Qxd&6(Js$JNai_dhxM_*GL(AKh0l)mIlf6 z>w5|i!`A(~~G>XKp!1vhYJ@k>;#K`*{ ztuZJ6ytfNxIU&2Tq7^g2Dz4xf>P3PWiYU+d5_zqW{MX^S&}DA$$Mwtj zmkOjRUc2Ayiod#04RPCkwXH|H?+G;`V#FIarKnj~W*yaZ?`_0k-9NfXNVkXP+7*!C z6F(zvvplZXfYo7AJBJ97VN7rY?R*P0lsfC9zqaPS~W z9$>kWGxHyRnRS4BfXlD2wt?3ao@e1cyw92ByayZ6$ zw_0q$@&NUtPhR-{D(PBJxrxt(<{rAwa-F>C3}YcH7BiC@57VP!)mv~iVuew?hHfDc zS?nCXkEwaR3hP`mAQrA69FGThlU1F_&|HzQc}@wmGxfwa(_%i0oYd3A_#f#p7%!W( zKmytwwt1g(<_8iM2WB9FD}-MX1OEg)=u|tRBPCp9fm#8o@LHT{ghR{*oT(ZQ%mdQcNea!eMj6ZBx!T+oo#jFH1d@5k zUwTSsjX?3~n}+$;Cz#<3HA}RA^>gW4;2IQ+YT(2A#W2a*3#0lJ5vMKGW1HqckM&Mx z#7yHvJ3;A6s=Ro$qk#W>5bZVH9f1ELj!X z0^3uC#Gz^T5(6em-zEpN>d3|$9KkU%w>zgdKGn?kF4fzo${xJ!b7^HR5@5HbAiX4# zce+Ie2dk%Z_Iqh4?&vB%_`AcaHp%1mG{;{yp~F%+ZF`{WAUi`DY;nZ{)ENgt5G;^k zVB2Lz2{>luopi?fRAjEwYbkS%e+Erm$pokkL)0LIoaz!*1+=0n=L`i{-S$vB1}KgD zpb}*mqC?}j`Jnbw*G98M7{n~(H`v9Cv$~3~_=nYCK2GX=lTULSSvgEn+ls&qxcKr`O7l7$R?V1<}XQl=dMCtU?MIA;&hm2u?fXmLavnJjlE+ zIcOHbBfERc-!QtL)IKgkBPqai-N61?&+sCMF9l~-@MJLZpU2b*HaN=;3U8$uOs=XW z%K}T_>^*S@TVeG@N6*W*oqeZ?)>x!`W|61;UU>W^n#?1kwJx&7t)!h+SiiUmJE{V2 zyrgA`peg>WA5?B=Jpe7?ESu!CtqPY>ZSlxnsN!9`RASaY@vtw-Sz71-!{A0{;m=*3;)F-4vqbVlcJu_>m zh+VVC3+`7M1;|fMZb*3GCY}srVkp;Y>1=T2Do2=?3RE26He4I{(DAMu`ys}ovsM&s z9f^UGh%dbebFQi1=7oT|UG8>?L7h`nl~P0!*w+VspTu$sixF*S2%7>a^on4z4 zr6rxQnL&-?x+Y@Q@KzSN2rV@}o@zHv2uj(A5s}|#wQW+7kqD4t^=*fwdY3d06KLBY zKxc@j9tD1uPp%@inopUwZ3DCsAoG}|d20011=7zz2eA7LnXk&UfK_$GFu-R}p1PDQ# zucbRnr{2M`(UR{7R2hQndUdiU+*F)wY>&w?Vi)bHcxJQau?7Z*HQO4r-^xS0#cI6V zK{~$*mwU3LK5Nf@;v`ovsb;i-09zv5TBjQ47T=!%9pPtDwNj-hYI3IQ>Tz1GMZ7Ya zFtNt^K6W}AD0@QA2(9~ZTE41oq&@2-35t2xby;BI4vx%9n=$NEy7d7Un3RCjeGdJd zNcvKBE9FrOQd9bgI2G@DXML-w4F@3qg74T7-|#6pqcWg6Q!Bj%k9IW?4tKS?nDVi* z*^HbPP3FMAkgqILN}hp^39una(3L^nsh^AuvyU%<;5SLIc1o1CYB=$`wFj><)xVI_ zcu+7UZaFT9b;hP;qP8T_E+Qs_*P*2G0~xIBr;U-F`+HK6mZvX^NR>pWED`C>>Pov{ zQ#`$=B92}=fQP>^;ox9;0}hhb^X-99O15f@JP`H!pGIhY5M@HQvE{BrjM&`M!9p9h zE=vEO*!9!oeHFarwNZrRIZe&vINy5(d_aFS(O_ty+i+eZ;1%z{C)7q0E=u>?;HO7Q zjR^$~LyfE6^Xp8UpbXCOEcYv4a?@^|_ISSU`2QF6**-7uz1{VPa=iQvD&-U@;hK|i z_U^8{5;m11VP=rYN7k1e_gSU0>~%;^p| zry0%tJP&;g(9N--)Qo_c)+Gp9TUgA(zp;OrM;< zR7JZ9hZf8t7RK9!;}S^`gAt^gj9PrAZ?0191?>PkN;)JRHFIpE`*d)TgZ+G=o&Y3P zT<9v?7==WYWKe4XL(-&+cDFzC<(Ga<2xur!niGs&8#Iarptr75a6@G4_MYX|>uP2? z7oXKPw)1`NQd=N_K+<}*WKZyyVeWz$PC6}$>-}Wah}WbU@NTBMerQ65_}66N!Q2ZP zh?#R`A7Q$A^qbbT zXFd@NH#=Mw2PAx-4%?iW#ypH4%EfCcvckg~Vzzt0^P8oD?vjxaE%A$k%%;7-2H&Sc z!>E_QDds!S8Kyb=^$zkAA$CMs?6<9=5R!u0WfMk1thv<6WAKV?pd{fem+;jP-atl7 zg+lz`j}6a_Q{M{e04+e$zm@pr);(@@thu8ua@*Fm#aQ`7)3I}|^5S?gkKIL`xgf?P zDZ}aMU2CG624|3MXr4BnII(xWC!vSeJ|dVtmfxX4wo38vNelShn#HHXCpIRk{T)v$ za1N<}QB`DxhZCm+zjJ%nma8NX&ZNEHsYU7i^3lsLLI|C@lswc(qMRufFaBI%H))EA z<3mIi!v=FbG`94bPiiYiyk`ng2|BbX_DMF^vm>e=?3wDx=t?=i4g79&!N$cOk&+zJ z{yjv%k=wo*0;!rh95kobTX0{fqi;^<)jaS3QAdUFz@aRvxlTd^bo{DIN`rFle6~EH z>6H}D#;vP!_iF+rgA}tA6#b$vQ!C*bgBZU%h0x@{R<0itlIJOs0Ox;rRuI60ViJ@z zKm7he25sh;MNyCV6c2`GEgt>=xNyY2UYtUdLJi>0J>IOV+zehBOr%8~Gtf>-wnu;u zi9eC&80l1vXk)qnguPZ4ls}LIvTI#I&pXvwm_$*IU-oD>6}OKxBA9A9Gu;u}v;a74A%IZ6HED%Z(uy8+BIx*RsJP|hgr ziWli*Y9V~KQL6KW3!aR`&J0Qt^w%IiMgAjYPNBAlsW!!Q*4m$GDP(@&l7b%;DPWF5 z__UB6yt~B;SCnUasHawiHag=km8_XXmEe_QCmCA@xdyY@0l96GfM|Yau-zu5mT}h9$3Rfu^iHaO_4FUf4e7>D$C{zy|p@? zAQFMel6g~jY#gQOSA8DH6cL1!@-5Tyc&;~ofrQG^2FF5qbdg`ceN3;C*?1vVnP>u$ zKH`aJ9$qVwD-K>2YkOo0qThu0*pt88r4st&SQFEf7V`wbOjdZucpceD`O5p-DNW>6 zEpDPto3MuU$O;~fGhy0RJj@te#e#Z+TTP|EL~nPn-=sLIfFHlHkFu@bL8Ye;S2-5^pjWkHC8f zMd!N}Y``i>b;MCan>3>dPMr2*tlS8cY^Ah53}t7u_gq%vD)65UZ{9}dS+AwDsasn zp*;-Yb$!$?l9z6>MfP=ho@G3mCL!xVDZewHwX#kWDzvavxn+3hPaw)f8g3Nab=QLx zL5t2;g2J5S#Yt`3C2AeJfD2=6d)|0pK6`1Tb$SU8S*axR!pBN>36pzDxh!<>&DCE% zleLlRtxvgkNz{(FNuF;kr4XrFz%B~eRlU&em(`??pvw8RHw#T-uw6+-F^1ZwpS>pkM`%ivE-=Srtt(h3kqX_;z zHV-M9!iO{c@eilNH8gwAOW)Y|BPNAkUty$Vfo!AIe!*|dVS&1cQC0Dub|JCB99|+_ zNirigTZ5HQ4t_jkI?7;Gz#8@zSWEpTyklUimie49*0?^sGb=LQ&2pi!sN_G7o0pNJ zc!ykNx=Hy&%Q%Gl4L}sK0QMV7(crj7^h2a1f|Hp7VX*JktZ-yj>`_v3_)HfAayUb1 zT_y9rseR~5o4`VvF;onf7@{BWe@;;-ZfQ3CZD&yP=IFvtYv6;M!HUq)x2s)CLp$ryb6XTn)Jlxo%*-xlfEqFO87W5|BgU|5O8~pjN@>p zYyD5>^!6=PW~XIXzW;{;0*%o$7YUk)lkEUd?b02cO89NU#F#fM&=2@?P$oF8{g#`Z zBF%{g*v_X%NXRnfLqBAw)(VaL)8P9ZmCK3=Fd|xCcnBHY3?#Sg>KJ;&=3IM{4Ilv) z-(}3YEcnM{q%fTgN=7M2w=E;zoOPq)vEQ0`#w*?ZsO16Uf8e#`WTA!&byzfooBNX; znR>evpWx!~1Mqm*SRHb~0Zs#8!(!Fm!KV*qJDgG1(_JF{O#K_4B1);oz?D3nDWRay zFfV6T*D0%QxUu%jQtz7St_L(o4VD6|kN{B&mv*s(PfU!lf`p4V9%jvx(&J4*l6-_E zhbF+)DM7JTY69D{-}(R4Qw+kcu+K3k8GQGCA0wBKF}TY9(2Rpzh&aJJ$4}4Ema=C% z&N(afTCVRotQDspMWcB_({;sPow~X`dHE&IxjfWG^V)y%!_qkTX)JYZ+!IN-n27(Cz1F(T@$nrv@pcrkQY+M1RV8-uYOAQ3p3EX# zN{TvU5YrJ81)2f38b>z*$tLuSPep2e6-tMX{t^#%^me2m@Nzk?2{)`R3vA%2XFvfE` z1C{vUtURkn9HA>pZW$jSHZlTS%E)^Cs%3&*lb+hRV(T?7W* zRXWi;`y=>f2aba`99Pr}1xP1LF(D-o?*pK!Omq+X8P1{JjG<)%{^^mcUJMm04!6u@ zf8+p%C`dUWv0I5RvR6M7kq0!$2`D4tUK-JhEx|@6yshs zS!VwLZGiloDw=_fCFDxe5y{^Ept1ayI$Z$gmUsBvD&-7m z-!A2EvKf60CCHf%f2k^_d?FuC)iIUS0^?l=mhep}U|@td5?{U1&=m)ZG2ZZOS=~5x zN@iIO?*Z9B-Zq8^^;;P%N-aYe>stp_rw;+oTh`Qh-z!dY6n+VB9}qFJC8tx_K7Te1GQ z?5g)R=FQCZus!a4-6mI8y?$LG)U>mNCDn%F~miPxWc>QSYzp&R=pXv!k@P z_?NIIkCX^ZgvO^8?YFl(_`NX&pW0#0CEh^qR3ACC$Nb<=y!1qa5L?|4kMoJ`0-6_ zzS+op2C!F*CkBltJyC=cOVs7w8>H-$hjBeM=O9<}5Q2Ns1R{VAHu_hVLP2&CPi)vO zQZx>W*Y(!AVEILGsOZ+cHLAEExA3+5x2&Ej^iFqga$M_lBS!VzAMdP%y)XfLQ)xM- zXCo{(p;6}!^2wA62H6KBut<+yqe;9{3*1?QM!;_w>wElW7Sk^OyCcRbPH*K9gyY^h z41_BIZFWU<5P`!L@qplmi>Grq77z#0h_c!w#We3w2Ajh(brIh^K@YPLJrpmfilJ;m zGakK&rUP@tRPWvGUOdkW%g50byHKJF^8||#)8HdpC9Es%fb{7@)uJ5D0UKZ2 zZ3e@RXj|*fwYDZz3jj16ZBiKw#YG?4(|1QZrbOjzt8ew#@^T3>5f%_m9q}?C)Q-qs zb7mnOf8(GQz0E&@Ndolg+VR+Lnn^5P6prC6fFdwI=};;>qdG%e3LxVNsGJ z8qk83FI3_N)Fc}4K}gwB?Pa+NMPB$`sn`2wmsN=kX4h!-HHSAhdK4hf9TipWv~NVY zK&;)A3`wBpX*j3jM0=ysNfLREUaTDwa+$%}rO|Nma+$RHDT?7^2{q>O$an87PbDM) zQE=)UU2{0@Z%2Zv87 zB)~v-*omNe(r=h7ekkx76ciPv`^vN` z9GObzh;xG-NR;<(kerSm_LY|@o0CKhM9&8o6PcN-^rqZ$g2WKlh3(bhlwgxPYhY-0 zcYQE(pwt`P=lN?)fEQ)qot5U_D6*CZ@Wz+5Hj?zG5J^{#&?B&h`POAIs2h`It8ks! zTz|eac?7P6#XK?Ve1p4)Nx86b@=>u5ItH4$R}yBrM4}m9~`EDbnlU% zJ~3$?uoeHWC&&`jJDb3k6Qt~90o<5?*a+V!Cj5_>I_(?yuX88M>BoZHMU7dW!i$Dl zMqQfy%!8la%zc%`ktoF2*cXMJWiWocLI zumuBArAl?j>8DoiJOP;#JXC_QX2+V91MVJR;`YAluY?2NX7$?WSBxZ+AEG14JltPY z@0z(&lfqacq&t@<%=9#$B$YEu5@kSNnY&Q)1T!^iX}ptI5sjo}yuzC*mYLSN5hM&{ML%TU;4?ESDHJ7@NiwR^Dwimtbskx8 zaUqjPkQ)*BY_=Ig)xo7$L(F0*7Fg5QTW>FwVqSnuzV&wgvEX7>sb}Z6=N+l4wU9`* zgqHWLSgZkcHWCdW=`rs)qKbjL_mUYcvSR#sGBOYi9vGI*=s|UuiB>X6BI@D>HE*Ep8W}A$c9^;quArnQF^_CWFnvF*Gpv%Itui3#24N zv9BHN-w6aXUw}cnW^1a4z25Z}i|93iX9V^MP&vV-fV-eMg!)g`~^-nTgZ1 zquk85Ij{Q6vn6#y?x=p~#;(nrcqyoneT|k9h@kcTaGY7Wo-KxA;uMYo22W@C zl>(`a2r{|44yxLPX{7t(v_hClq*4k@k*q5zhp!*0Rxi9LGi*(v>9*nb1XC|3JtN@H zDV;lA;>urVmL5waDEUzlCh39TB$;4sS7^!(m8_?`~}7zfSN z@`mxKmi(h|oxAxHp?nGdc|&3fz|cjy4&oHth=C#b`H=@qOvG-11oNq?hl#3{avU>Q z#!>21mPbyocKRA?l~+|IBiVUPd`6S*C!;jF=xFI7C@xmN_@d0dZ(_*R+RIMrBo{>ya8!+Bv9Uu8ePr%_1)8=;@9o!&#{9&c5_^_|2;Dzw$w6Xemr;O34mya3%O zv@&@k)ZNNSxJNdOqyYuK**PDHaE;U@Z&lq(M-ZsGKPqoFb@0@Jz&&^8(cj1>PwjyW zas!P?KPb5fPv8@!10omP)1ST8w{Kt*wzJ>^-J0`wa&}O>gorC<61I);d#;Tu2!Rot zyrj<>9+0N2K-CY;A0r8!;kXyf6cM6FfP$XaX^r8#=(!;QwCg+*$h@il8lf9VnSG-) z$7Zij?=or0v<)Dd937AzN?LC*)1JX=nj;7~D(GkY5P^NrG{<{;PY>W*CGF*h>11{y znyp!*9Z{R05}~_zKjn+EKtT?sE+RYy@kaZVp+^Ybko{}0=)x!O^G}tInlC7|pqs?r zN{tQ8Z>M@~9qK!010th!F{wJ9^Kxi%9!rmsfu0WZjHnry57QKKlW;HxwKJEVQL%qi z0B8Lf8jF`=1O$qcwOeONYA0fgMtaBzfGQk`Es)2TEu8Te02pfFhdw2L901WYytn4s zW1;*ck6*pX2LD(&e*ZE{nZNR_p)%K)Q&9go82T!|S5~e5(Xy}scbBy$bd8w0Y8s04 zVTb-QCmN=5*xVU<)K1Md`)To!q#?FNWKH|M2)5ZhccoMCC2Me#_wo%n zr~3Su(L|0x2!ge^hjWEz`_%uMYf&Fa_*boK#E4&mnqWn{o{}86sWu&W)%IHMmM+oR z$tXG9?&Qv0LGS&EGIn3xz>?V_vY0%DlVve;;IXOh~_XCC`ZZHsm(@^W>isNSO@meo8Z->9c4kQ+A@_wlm-g$o zmfFG*Cq#mJ`$LaJKW5oNxMFsMg=6nH2F&$l!Y0h5w(6{G05p3`E#Bm0;WXWVrHkD` zshLW;n~ylK(*Cd5>!8aI+x9fMzAZFK7MIom9&AdmQq3Llxd9TLGFDy+rFG32a&jYw zgCU>qAIOg{ja&wstW%!uaU`7k675G;{owrDa2u4<%a4-7^VXr1J)99dt}L}}9&Ch}ur&|*a6XV&)>-5W`5Z?GLtx{jRFQhdLMFYEyF+;%%&w)Kr8Lr5**AZaEc|i~zmg;uVYlEKkR* zYTiP+CRq5g6NGkEp6^~(vbmZGuKy9#?=yvZ7HNmzy*LkS3=O?&iCYt~%jc{@_x!K0kZ5&M$K4B09r$i~iIGCI<8E)8 zZzu|E)L0xY#z$k=t)N)@SwKCY3R`J z7p{zJY3up=RBrHmP9@oOZ(<4YUX6BHtNV_puQRfyWOuD@rbLs!dcBcFk&rvxyj_PQ?iF94I;UR-=1O{t zVNkLOo9xVp9Sdr5e;!pcI=X&?(sYzwgVBus+I=-LOuXC0{ek#P{;(*fN4@30EDS;A z(JiHeKtvz~SK8mHG(^uns#DyS1L7$&%dN@*XeU{6_ejA&ae4qSnIbFZ1|baE;2IS)tiZ4@(H-P z8!?#(7bD#hlT07DD0RG`N$;%K3nry^EQ*w_zO<%!AfVzdsge@cx&Up9gF-J>NE$eF z0P_U^O-0g4FABGev11~EE))h~MZa1vTExzk2)x-RxOcHhCBEwLcF45`cu1KQJ~Xy2 zwkI19zg|X#y3(beg%QWhq+_m1v%UgB^RaF}+Is5#!B&-UhD=M$cig8nOtYID$jm$)||7hg$xoTwsHqwxs{5bux?ZdlXX zU>9Rz;-IJeaz8<-(q@Yo2LGG?vM`SOgu|ja=BFuyY4pQZIoY_fKg9%z3){+{`dX46 z$JHl#j=!)NkKigKu9Lo{`cb1SnLwDKT`|FO?AD_ZRotpi5f7)u^v(-P^#lxbDbEi| zqP~n0qLcpzIQ|bFktPP5QbAGsPtf38R}vp;vGkpKTi>VTe=-bz2S6%yN0cnJIn7mb zrv9?sJmbVr=U8!@WU(khSs$l@>vxrTaa84f0Xh0FPtSB^9oa<0y1ysw`CYtD40j$n z1x%_&gWK0$xT(>$d>bKG4??MKijv9?DX&&r!U*luRxX;mB~#wGUgeOP)s|$0k>=J67-o%mA#y&g zXzDLwdrvqErSv}sX{r1k0Ps3c>P9d$k?-}e$Sj#~f7^5pUf78u|0)f@a>R|^IMg5? zrqR*NUN53ZU8hUfKB|F3(cc;6hI1LuURZJ!76YV9z2c#%b=}hWLyu5fL=t~o3}Php z?$RnUjTk{h&SS2zX8EwTa`ZlS7FG2v^U08ljToAg3*~$U)e2L#nB^#xpG7#X2rxho z^`M}fl9qi}!y~l1mB-Ie^4s+y*BG=M--k^+YstL>xa(cItLLUt@?!nv8Bw%TGBgVD zOo8S3LuZIE;+@`bhpd=eMf`FF4Ol5Mb7y3*E0eQ!a|rK~L16BZNVAEts z)Ke2|e>Ou~3L5PDH_ZGx7qx&C0ZWFZoLrSb1OR8^E_@I?&1$gvn;PGz>8YvEj>Vb4 zg&=tzaPO-;dnnceFU)@>%GWVALCE+KnL@ay^C%$jf}=3o2vPB>JE)Dv$wpA`a~5VT zVj%YIu7s{&oQW^F1^PXfO7sw2Y7RS31`G)d$x=_4(AqpOQRIj{O+)Ab<*w%Pow5%g zA%k{ZuF^W3w>q?b+T-^3{U!>;&%#>=;f}1|F=tPkb>w#&LY0H`eME#{g?MjO4nI?a z=>%MGR=pb4N}D<}NhYe)$~jLIe^OM#Lm)n{dqmC`nEjrfk68C!|ANI2%I8=01`L+Q zcnM%iC2c`mufl{+A3>1_35=pX=Ubrse7}%Fzp33Z^|vT{a&y?Om^*Js(~jGSDS`lw zY9eW!JZ7>MF|KeyVHE@)IB!nWEIR?{KeC_H#lKYB8G#4tMFL`fMu6aJX8(HRwUhSt z6F;+!|Eyb&$Mt`?TRo?ydJp);v(JB~2<^*=aNr0}4MsT@7u<@pE4Z@6atdWrFnsy! zbF{XyrcD+87c)RqHbsMfgEpudD=vrND7mmu<9k*@vbyll3{|JmJdM4*`!96MS-e$w zYQ5-%cwLxwU2lI5aJii`mO%rJDp#*wMDVUZge(v4R}AKXY;0XIwj6y(Nj9d;{&0>y zI`k;9Sai09qt3|w1+Xehf;196OuVTJ2M=$>Zj^XwngUBWHgTZMolNf{g1syKmgoc3 zzG9#zY`|y13Qbl;|LLM2cOt-&eU$;Tl}+5zWk102+NG?<=*y;Mg|ZqM@Avl??NQE= z39HI%H22EEgb{3{U#Xk_S1-?kVAq70tKRhPgLS86RS^WBZ;-)_k0Xk^dXNWXspfvO zF0h|ueI>DoDu98C!SRrFsFc*}k5xAaX&Q7K1gQHJE;Ia@z5RC>bKKQm;8vP-vE8Tt zrE+Wfu|lb>yov{5s}wGd*x|XQ*3SpNQxV?OWm2uo%ax1zsVC~KlWJ&?3*wg=+m3G?*O{zaix%-n@-?W!Q1$J7qKwx@Ag6L7vrpqpQ}ciEMg5||*f2ntIFuIUUM zG`dpU-ur#hufUm21ReHfk$@>Rz|N1bc3xJbWJPaB&g( zgzJEHX20Ku+c(sLdS5PI&5^-Zu{KB{mO32l<`#%tpGzQyXUE<8o1vT2UZ0WeeX5;) zg7D~a-~Wi|v!^_`s{;7>pL(85>G`W8V~x)re0QCsa%B-3gM$?!P$!9eb;{OR80t8K zq>SOju=FK&t+gi&wiByR54VSh*<9-VUWq@-=*p%QV|AsGmcS-o6zY5j1FAI;&aV6w z83)?fI*<|eofWsf7>IQ3er~-WThn-7>OBey7*Seg^uRtSmYxEQ_SfxvNB~x8{dXa z+|TF}Ujd%CPCWR6nc2_4KDE`W;DfpM--P4eox7iKq{Aq%Hf}0|4gF=Z8 z5+}n*88J7QkuFtwve=Ul+4uwB868_tR5b-5j)sny{|m7JzKHHo@tk6#Ywaii$8f}- z89xRtq{dxE*VsH+-9`(EO4CKvHW*atgUt|vcD7D|@z0^vJ4Y5T%h){3`1TexQenK6 zb9gR|<02-{Z)$*vJ;*+gSlaAPjD?S{=k#sA^HPESJ(?8Z6nD;uozR{cj$VYZ$0zVi z{EN_F4$V-zez04Nl_v+_W)n*LpmVblB@JuONn)3OWa=%XFSupv9s)DzdZk1zfxQ-&(`C<~PVbeYTy>atP#{H*7+^i z);CYxO%!_nai}z2^J}{uCFLSxtc$l(!6*mqjxbtj>0z3KimKsiSl(n;WGs0~(O1oZ z>{CLGYHSdHNT;S)!$9Zm#zoDFS9420=8c_#C^P00?zdl^_{0Rr^+US@EfxpqUm4T7 z+N_YCR0SfD;Wn6K>v`M1U%j7hUm^XLqE_Oq7Md3!0A2=~gWK_ZXV0GMcdIr}Q+SHR z_4k;gy4&BIVE&7VPPxG(16W}v6-h4HB3WG*2n_-9j!6?A2Ir%pJi$ZqsPvq0_P5~3 zK$|B+$tB|OhO&y)hfa3FsG})C7DxTc>$s68jDaqoZ{CMOJTd)vty*qn+wAfH zi&N$XmniNa%9(5bNIC))x5&)I=kt3z?pAGX)ekg4AwH5_B*meJ zfuf{EE~)U$!=aTDk>Y^u`LnG+jAIJNTv_?4YQaeKuM@Xq5cbE#Q0`Mtxv|A{=yGf= zv)>!J4hls_I?xmX?2jCQnogZJmV=C~hXLEYRdw15^-LdFnPgzZA_D@tX8M?|WDWn7 zikMn*va^S+8@_u;n#^1zKGtgU3!Ct&<$&uss=R@d?yhgq3Tw^N3JGgXB)Kh)8CpaC zXKI;edHC-q@d^TZ3$HGS@J+D`jeNQAFeGo-p$D#x&|8ScqQ$Ccsz!+8rzEDPsk0!VmCJJ9s|os}_ehuOYk z$zwEA@+vanw|H>(JQAyP%-90pvaR6Z%Wg|JnJ7CV1?1Nk?ZJ{|%AYn{jV+iyyAD%u z7RR3e4+Qsd@z1ww5g%XUnkhYCfF>fKV4qm(eJI=jcxAvT4amvBGNL8xcJGzQ=gJ_8 z`R_Ql$Yrfrjr2+*y9KH=BwF?qBdhXV9YtPwGJ&^C^`XE^xA^?0itrssJ4-=}QCmU; zZx5fgd~s^`fn{?V7b+%lm?xi8hwNUVH#Vui1F00)nfb#BAjo6gRx_Qd80M&E-cJJ5 zFq#WA(Uxxc7=uql=>OXA6V@wbjUROr^V8X^bI5Eo9vY27Qc2ryeO<6PR}4l=5OP;u zjcW{oLWR@cVbnb|6zcDmw`A6L9Au=W@(P=Hn~r2HxG05JBR;1&VNUt$JMwvDTpnVb~FQ0;9Hg z1J|dd@p5MQF|VU9aT~RSJF6eF^@w|ATbTTUy%Kr(<+Gy?NtM)A5Lpx><75Fd@IAoJ zarB@J%T9Lhfw%PbFqGj$74HN;6Gm2nIV4ru*IrR}bhp#j8VUUqwO{c===d&KW{G3~9Cj+?$< zL?xZdQs5E8z9O9Pk|#VCR=UU6U^bo7Qn;yEfPwxbECp}RFuN;QGtiT>8d-{z3iz*V zN|bpHhDiW_j?>`R41!M_-PyI-G^op|>c|tvv&znbjSG15DH= zN86F}oZSc?na0_+Pjz`wX$2P7&T6WRVQyQlIwxKzx@l7i1ej93r1SeXZ4vP10ylGY z^wB;Zk=do5WmfY-B${@hNMy8cgtZ-AOg9q<;=DjT)PeJrqXe_b{JeB&B0H{{b#)i} ztF+W`I7=+uXQvE;h|GB(3p?Tov7H%7BDY9YOUhIq3ivCM8LffXp@}I z*SA|f|E6}eRnCCros_rCtuv8$wPSK@}AKHSf zn2MUtgpO`wWHt+vcGHLP`YAKwRV-7gOkW4*M4&P$b z6Y;Y)PMW~iWd5tDKg57w2gYAahS+u*J*o-H9Uj)vYFR^+i;E4pk+(PxUsoYpxxQ-v z9?kBXfQ1IO6}x~L>dAv%qWK%9jk$Z_m%I?=!iMKjvoK9Mb;|KOz3+PL0SR~nRYP`1Qqk+C+4UQt zeQlHBK+8~ORYm3}p|en0MTRi8{O=sTRHl%8Wn z;XdwV%)Hl7%S~J#lN8biFAa9Yk%XUS_`-EnkM(OrZEm{eSYbHMctgVyPqQ5*qeE@g8Y{E8Z^w^gc+WuTKS?$)6OX z4Z>jO7lCv1_onEJK2jkEPC<^G90|gA+P6>bt+PvEr-k$P(rnWN>9I>7Kj_W1P4fpX z^UKPdA3xGUeas{{o1?3&ahnhRV(SuF!;HyC_xp!1=kR|Lm_!hFr50c?1~ zkQ6B2(iwUG3Ug$Y?Pj=rEwI$9Q2s{v@4r`vL zyEqJzx3z;;xZe6xd0&);nYWZRfZ(PNVn9X}F8$k{aA`A6Ig_Jtpl(KeLdSHV@Xq1L zjOc6#eZx)U9sl8a&Kk5jNpFw4Ngr5n%X)drT8IBusO`roWJ&!;-)Z+2u^+?b!0h@A zmpRwDXEddYmv2#h{g1Q)nYW#F=0)?@*`R$2B-w6L?Lb@TW43ENw2sRj`GUC_Xt&9! z4?6@^ZF_Cyp3eUiKS}Q7@A8r^BNCTz^PSp~WN|GSHw^LBklLPA2Q70Y%yLtE(Yo~F z+=I?68Rt$}A(aaS^r5MXp$XtjWU-WNj41R@H#<%j7QZz9o!_R^_R&OrvzkBN61c>@ zC+7gZ!SN=8m*y9?8a3C(PExmw8=oGu0IQ5>*npT%;2Z`33or?i!rOQ`X3t+KjdS!m z2EnSz7dL>BGU5&wb@gP0lye&nk7=l zOGpR3E+9X={}JfY1{AnESU=%xv*tLQgjURojbD&-QEcfLTH-9zlM3eCc_8s;&mJ!! z?tgEWKIzb+>&?9Z*+IaC7_MAGzKHm`Zdv?}G<<2ro<&1hp`$y@?4-_q3-VVSE@*FY z81@Os76nKPioPNo0`ML{T#k7DpUG#^WP4=(J8F% z)vFE`{htk0jlR8N7EJQ~8)#|F3WVHM*R&oXo@;*#kUiL3Js0M+KdTY|q7)xigLO#U zPz}61ultXfc&xM2HwhflhvMhgMcp8av{l27O}bZnM(QLo%EB+#Xq8)@a4yY?16F{d6@UEH(QC0ssN(ff_ofknr-;_(QoDM_5L z@r)KSA98DCye`7?V>v<9JkiWKL^V3zURr_`(PFIfpkn44U_RkI#++xi_Q|4UVT-ha zWcOIIFxYY?rBFu@fowVuu?p{rMp~D}hmH^=T`O)r`#76CtQukyMro9=GuKi}Cx5%uu4{2>L7CLxU8}ZTo96406Ho%9cD5R`7FoVxGaI_~mZ^>>E z)GRrKG(a)rDtYNB;iDtw02lJYEjNPtL8jqoc%eg~4vLa;kXFJD@aW_Z0digbwntj7e5Y9Vq1SEr>bW3MyKENw5sDf&0p~Qye{5`+TY=4d@&Ozk{p_CK-%s9KoJ!Af0@bMHX*U%?vt}>Q@O`J+J=$KPVzOq%U`22W3eGyB5V~?S5^!43NO5Yjzc_)39)DXAn1OQ1il6GmMe5>|WYq z>97Rt-AdpH8hL1#!olQe`nils!bA}SgOS-90WMjhaX286a{?3R<1;w8Fb!@l)Cpn) zU@E5q`Dcg^q8l(I%A5pB?e3>ttYkp zEWq5!J` zTR^8DsqqunCzmgf0coe_Aw}J+nlaWYc(|!7;T*vb3*6x9G)o_JLQd2~cyV(bfy}zT z`q|t}ioLb4g7DW#2OrR{cpwgpd9SITX^J;f4uw0`TWPjM=G2>4enrZA>XV2DGiNcS z$OlH!M(B0jhUQbNikCRFaeEh}cE9l|yrn}F01}h|+HY!&GMvNNk^Q=0ZI}VwA8JL(mVyUqf-oB-uz8e!imWt8$Gn z{4Fp>%43Ngy_SC{lBT-pFZ-S}y~1HgKgrD8Yj`$Pws(m%e${QY0xl!LORfZ`SahXd z(UZ&={6W8X@oV%fqX`-F%L4LRd9X2-R?o3|G#3L*zZ1yG>_k;zi-?C^{a4HRj`EQk zK-M_tX;b@3S1-BRc2iNx+FP$a`P!;f(=~r2{s98xobj&w{}n4&`jO6w!OmFKm&{_3 z-5^N<7)OU{SNjwoli_@8x*J*E4HJ6ll%djMkpA5drWpxk1AAe<=XeC*1~2dg9y=jY zf99Y%Di{vB;KDhafU?gHY%UF)&iCDHap884tNB)i1r?V402@#L9Ex+?39?**u*9g2 z;%DgRhu{mY%Bgz*be(OCiX)X8l9zfRiUjx=NEdrS4M{x*=}0Z9<-I#=5my{>UgT9n z{b9J59-}5Tj-pX3dYznrlw8=Qq=b~S82b{xoML|)qdXWOo&qiE@JY@|I)KyO-OOFH z*|BaBm)Y(WDP_T$j@MkL$s6SkvaxiO1u~c0O>eLM9m84-%Aw!r(sq7Lt1^ zVo0$G1mr0U2nat`4J9IE?uE{7+40Sj=;+6dFhbbLSJ*)=iM3Npp2K{>kLriUD>*LL zNehdJ2d$A<0lOHcm;-zLGL-o^Y8}n#2n+b$3c}zxmazCirS#|AXiqH=!b98n89YGi zp#OccOsN|#99eRUAgN;_i*+TO_Ug1+vg5Nn)Rre-g=vs`N@+w?j)LYQUYS$`>s03g`>Aif&c-Cl>b9*Z1A6Oo0#SURqj^1 z=i2y6Ja)}Ibi}G=B1US$e?}<4)cd!re1vlR_pGwTy|Z((t0>-PCmlNLK#f3&C2I__ zj!qBu>JmNn6M?4G8=@O3%ty(}`OD4-=i3!v8_hm%$_LzKGkR$wA${n?u~WkzDm)6n za1g=1jK4^#A`M4}9j9OgyICaBl*BCrI8Z5i#7$tsBD7UEc)wZed zY1zR2QzxlgD(1n&2}$6mQ$2V{`44zLPTQ9^C(QJe2_@iVq+;VpDsT6I0iwWZCf>Wr8>p!;vCC24>@{zO@-B^_?0N z%dHE*NJkBST|yw_#r8grH&Nj7s4@AUUnUE@P2H@9wsoavKzkV)Uj3N5qe4Em-$7WJ z3GWQ;6M)z$GNE*o)D$VpQCjn3L;G9hmLxx~DWIVn&ZSu6qPXbei2XXl?LnMob0 z+xP}i2cKD}|F7Pdn{>I0;4t!!{ zI#P;5X4ma5G(05u5_2xG285Y&f|(@7j61rgwjN9S`b_k?QMLC+MIGK_s{|$JVK?iS z9<9QG17XxxgB}ascBmX;#1!MCx1ZXcTq-BfgdXmcPDHxEpgA+W5r7x-S0x#CG{msX zGym5=v1bA_)V<{`_Eb6;+cpxZ(EZgW-JcMaMv>7oz&|G6bY5LZ3~-PrcE!+cF1lUq zxf!P1zUxxB99xo-8OF&f=^<@H3E2rygd~>se{jK7>=!~S@A=yGjs$DniNDDs6BRgf z;yes7d8NEutOs4UWLA;1+f=#MeN6`5O}8cyxA3Y9bu@W}Z?mlq|8T!}k=}L1@2mKv zN~KcGT${r{Oo4!C#U8%ylA=rHakyneO6Mq@1%>;wWd%!gq8YQwNvG_1=-lA+K>hHh zx8WVT5e6FYOWpr~fg)N_X|vI0cDYd}-~-FyRYtFP%MTvUfPL@5q2fAoJGA(zcVQa& zM4Kd2q+NDZLR)Xah3~Y(Aet!dnwgx|#>nvLd9~I0U=B|9c-$Gy?gvmai4V$0-vx+* z&MXhSHesiDzPFvsRq6mOK+?a$a0Z%kDC!_XD?28*Binb`Y{FUkFuj=ec6(Jd6Oc8r zH#d^iaC`p=#E59#Aehh@GIibw4r~&C8xuAq>=rKy@IWro6|=#F9=#wx7z~;3OYn+^ zIX|szrW))~nnk!ztA~4_^?25`&iRx9i$1vJ2H*yqX=(TjHv|YatrwuD5Z~^#nNM9G zPUtDy<{oui(JtuNv@_aJW8218OW1?hc<;%^DHhGgDI}jj8Wn zu8L4d0vytynBqI;S`nLXEIea>L>!rbeLsm_ku4$QTn|`u{t);Zn~)jCy*Fr+j@ zfg5<^*p~=R#kb!&UKkCEcFSn*10COJR2|?;J#`bz@kcbUWb;s6;H6OB|GeSTdK&g7-o*N86 ztBdgf=?cH^5a`U!72N_7aaW^AGr7^EnWyQ9?q@_wF?04rHbhEH>{u+4--A?Xt(V3c zth!1_Ct?=XrVcM^pmzUiSR6syj=wj&mv@FM91m+pun|xf7;=2&Y8&)-7`4TwP2p~k zJO18T7Hh$Zp%VMaN}usW9`XYoilr0RGf)zKyGC9tN49UwE4@X%O$W_HU{MdEVj!RwwsV z;w+WAP~~;KTXh@s)a1cdT^;ZT4=LA0vcM3ms7powS|^*Si~`~~#J7Q|PbJA`q2YDG z>gM>RTULclq4)+$;PR07i@v@l<=1Uq;vggL-qu!IR3a%7m==7|*%B^HK}|r^%JBbS z%eZQyN^|0!Bo+E@ND54pWGCYY2lzy{ejdf?~^)2`Kn;nQm}%KH=)UK?UT{|8F~m&xjRaK z-(@25E{Q4Qsho@-_ohCnsC@+D-W8apLkKypZDW-TEJE4qLDCL3|H&*nPL1KFa%*6* zRPri2X>&Cid=mgtV4v_aA=qvpk>p_lgdhMb6vwRN$4D;jm|~a910CZqI(=d31@Y88 zKX*ldqAL7mi{zjgLUT3S7I$qJDr~2Irw1~MEkx(dt;wr;_+8wbHS<*q`@gjix5pMf z8RWX1VfRk&T%5lIA^)X(S~4-(_t&n=nrw_YPOtD|nE=+bor9kAIkd(8 zbD_kCGIh(rsIdX=khY;MOEi8IrO&Fdcjgzp_A?rTxbUtsenKlkCKxrQQ6+jMI5s9n zNf|SCA8Hl>FL6fU*e=Ac#PURrUl|tntxa8X;1nzzpE^9zW#S<)v2K81zH@GZI8IEi zLrPtMl`eWS2tkG7^)Jt#qczSxg?#FO3X6Br#gHAMk)U}u?H)d+fVx_vMmlVn`_I9)dp%gzCSnfAOqyFRiXnIVp|tbe&=NYvEGj< z$ikFCV5Fu0Ee-bDvP8kr5Q~o|DXv0g5fbG% z_L7%)HRqXE-}^@T-7MlB1vqRI3^LI)uVdQ4(O2-8eh?%>h)rQWpPLC8 zDmGcK?Kt@griNEjOc=Rl+sE;k zflaRfl4LoFfQG+O5u(5AB}7Yd>&_ooZNd=*ABi0Hnaw!9T3hpp{r+xG>vpE(5N^@K zvmCccpK6}RqVLtm4nC~rz@jyl8FULY(@O^oFu>+4!ZGf`@YC7pmRDG{s>93NXck4F zt`)<>UbGl%M;i*qpZ*7I%M++%biBx9gsKQ^19gm|{P#-)J}sFxBq1CjM&VLo;(M_* zE#Gk1l_ve{O7yH5B{R%D;^~*zz(eS|U``c69w7tg>lpiFu&I+ao|Da)#O&W+s@%Pg zLVZwnjxN|U^0eIj=0cOf8~=rr$BwCGS5Hx>m7%5ZcsJ0b9V7COA^ZM(eoD&lh5zWi zz1G>=ItfNgDy||TU*2`U78&=yNa3Bm(;g#M?rOm`(`c2HG{rN86~5qhJw2Ei$5Zp- za#fo#Fn_U(8wwJO`@(VuCiN`530Zdk$q<6B6|U_LetvOY$52KT=QJz)~#LD668h_H6?ZOCzEpJI*LyFHQS2+k}jWakC!gYA0v zBd{|d*?=8DqNZQ zfDLXBHgF2lVVZ=cqt6@B99f_+e-uYk1J-G-;a{KEG9T;X1s-bZFmWn+hq?@ja_CoR z6cZnA4R2T$NU2z=mh3M@Rq2=hHpn|?TB+mD*M$H3c*Ls9-FYT1?SqQ z4nmj!{&gj)`#4!BwC;{T#cOdxHWj@xm?2N}H9dsnf#roQ(JaS+U3BfE&eKe4v*0tN zx9(&_bt6EaC;#0uq25vpKWJ$5OX?0kR6-%z<329zvavyk`8>%sI>@x~g{qhDnt3pv zW~>VZRLMu_mH@J=r=%mm*V{xq1Czd2#BwiTbS$ZiB%aBr5@hm@qzivvUNtcvSH~s8 zq5+n{qwbK_ZugG5QG!s7Nr7;rFdWO5ks=DERNo_Dh_p-m#8NBqEZ1lBGYFOzJ=&aut2WVC9+4}?u{S$*?J-13yy zeUkd3ZIzkvJWhdd4_lG=x{Vg>F1kF)$#u$^7%Hz2ZjLS9+q=zqcY?!z43eK1vh#~7H!3h+d1!JZNc&*T0ZG6QIjr1(>t%8VEKv>n{AkM1MVgptZKBT|!h zg7re262_A|x-H>!0K87Nn z`tPzP$V#_^UxNtvrrE%G&Q|1RPiWOb3N=mS?+}+xPO^~2oA}^ec&H+YL^p(A5y1;~CrxIg=NNuaqr9v@OdZk(+qZ*oi9CWfn?^rSus46@NUV zDL)t)00K@;c9qJwKDr$+f)t1n-APB>6 z0jhw=?g&Rj~8Cha&3Smks z+ju>Zgil5)Y-8aToM(K+7m}64)!mO+=c|400F^so1=ruEPUhgI+k8o@+e1cw9~VWi z5|?2#jEZ}$yB29~ngy}oMD)v!H^{*O7df7}?cc~5%I|IJamgI4He4LB_sxe|SSPlt z;%#W$3yHIagf>AP$s&db1l8{|kpAOCzdQh62SHU3<=G6pugj^d!P@vua*(Z=p^TS` zGgQ@ir!OclB)C+`fyf&Y2RWmOT5Z$*AzPm%zG|)zV;%C1fLruxK;xV)&*-NFZOq(h zrh!V*3L#6qHOddkCy-i2>y^r2k{g?g3;-B8vrr zj>YX{foRKJ`l4?KL4CQE@@U#579N99OrDtyr^$>1^W6PnC6xWW4P(+I$1o z3w>oQPDc8tYrh%jRvvE6mM_2M5gjS`5P1!t!5W*+>wpsnz>lDCA7vXhE_?U*TdN^C|(_v-arxaP&MPB$1AEd@Va7(+cN~4+J=i=jVQljC;X*PFp(=itsW$I zke913kmmgzT6aQz`mb(`l`s#TOZP&^Kn?!S_FWN#h!cY#cB3=!Wmtn>1PA(rWvWT_TmqBYde-R zSXj00awiFIxMU^}70hN09-!emZkXmOnNvn?;p|?Z>uQb8XEC~fbF)u;V(Ck>PnD|m z+nnt`E_RMXSD;|kTIqiFJ*6GV6m!Sn+d}RTVtkqD5Q)zT1oH`zHGKF&X39N~L(q|L z*R2`?cLJ8q+;zesC=t1e)#N82*96pQ^hj)aLe2-Q%!$Y2sD3gM)|dH#Uj@uFKRn6x z(bW4xgA3-Zu}C{TpUbv#`5+0V2r+r<-(!$*Bg?bJL1tSO`yxLwJsAi$WPIk4aw(9E zBf@$zT#!ei21DH5M4Zu|k&!$a)y4ZmHZEhvj|iI12#X|Un>Pfs`hr_t zqXfj-kJ2utI`u?~nU8NyR1b9xP)7@UlB>yfvc}Y4_rL7+L{;wkt--VSNQ(R2D7Eg$)m_72|BXKJUqSearWE8GVt=NP8Ey)&kJw>0 zNVV=2&i|p%RBxmYPhfP~t(!jm3RQ(80MqLJ_otx|jG53!EX23Pg!@<&U&wHpVDzQu)a-?BjO+uaNlE(Dk2>v7_9FL&}-iU+?g*OhPWSDhV1Tu z##C(Qm(@f22Ou#!7rJ)X^S`kF&NJNo(mJ#sfl^l&;CZ?*`WmUAfYqPF&uJpF{fb z69I0{On0AFbM1x)$opn_6FBMaZO5^s_z2y1uK3`O3~@3Dbet8dz_}+NZ6>Yatuguk zvSaUIc9XroRD4Vr(BizPXLi?S*14}PC`+ygzUj@HDxVh1DXGSqz+P1h{@#?9r%B#k zI;XGpVp0_|Ij(rg!?*a+;B%7VI{%)^{>!IGHY)KTKU5Zg%6e5_HBP^T$HXob7@)8T zaprTcx0G634P<^*t^QtPE2s{;-=N8;B};y9-W7Fe5XVocu^k5)QSgWuA6ew5b=wXvAwwS`+#l)Md(ej0^yrI67WinO^Kn^>c_}OycHE7-c{=0C{PHtETS|` zU(A~pmn0A^+Gq_wzVlY=YIJh0wok{$p~x;4oQ!kO<#2yB-3v|zLzz)v-N`9KONfr( z4jje`zQ0LHo-i_L)-;YBNn=MrjbAF@=k7fL`M^Pzq*(~m3{N52Tv!kEJ;d-UT`e>O zdaHWrdUp8>yS?Ifct{<42u&%AKS3l3-~vK;|1!xSkgycN={wNBST%%_x&x7o8jvta z6f1@^bO6#vwT`K{w;_bL6C#s}M}VB0(K?ipe%#Sz@)as0dd4?))g5%^;GVTyn;#du zm9><)z-~>;jeV!3BQ`eyb6!@MoOd;{=U$(FjOR`g0)4^2w(+2?^}C=ZGL4eF_F6PY ztFaOB8NwL|^_c+r%DJ>*Ntto>2a&Omw5^^$uMJ7B(+~Z4oYAPd-X-8aF3{6O*?Eiv z(Pm6l0j~((Ypo}})dcecmA}M<%n7p7exD;dQI?XBxf6bGI8jD=Vi>vn&gBF!pC~~M zANGBHfGNOXM^ElC2ofbbRLT66&%MMaAa3D`X0epIR4OV@ z*wOcfS7@Of(z5c`qG>SW%8QTo2VZ_k%OikMPZU4tStn`qr zW;M7*9xA$4vY9}dbt!=TKiD`VxD^L~F$4gIK&lM_KxthkF3OQ4VzEAo`@20Vt0$smF$?VW+*vYl&R|KO|E}LG1TRFUsACHy zCCDlIZp}l{2#<9TiD5g*s=dP^?n1#nB2_f@vc$9(o;(da_V1M`7| zklw)sSVc982U+=sw-Ny}kMDPoVK`5Yv4u&sdIx9Dl-RF63Mx(Xs#@}a}FQ~4@N zWgWE5k;g&6;!ctD2Uv(q)Hv(ZFt}kaKK|m0;^SHe?8P#lAj6^B43$hFfv3(sqzdib zo#9v5Y{}vrZ+$>+it`8FE1d2*Ho$`KUAc94ed;} zGAI*uPD3Ljs(BQAeYqYtmg;G}d(N6!C&OyL2ti!lx9dD@TKB|LEMTYuIh%5QX;@Eb zkVvH~qf5Pxp3c5qd~7wZaCu^DzW#@J$b)^Z&rEil>1O;*Y~5VA!HMc`pAxagqSYS#Zls2_sAFTH)$9X{gqXFEBacs1xb*&mO#5&*#=G zt3y~0JXn(X5nF+L1U@YIH97-l{1CZAq*_N3N3#D{jjJly(4{dSq&229N?%JIA z=p89Vae=5Pp^2NJv!hSUUcz2F=;sK+7>xmh_@xg1n#w_M*yB86&EVuUv_MT@i)^t@ zRM)hInMU-jix(U&u(7!yM4i$JBR_{Z2duj1_#IbShfuv;Z%LuOCQa9C*y=v-cM@mt zg{+2p2^1JA4*N`HWeVVNZj+^ZJ6v#&BYO&c6*(bj#s~b{bz?MUrDnv&EoD&n8xh1@m){y9c1(sr(MlC70KeXFphY)H6 zhhSOC7j`^u_wSrFffd^bg;B!4B|ImU+xA++qrsC`2$!&nCxOD$cW;wudUmd|N>EM{ z=gFXx9x7>r@iX&fp0JGPO6Sn_U*9YM&`i+_@TL^>oIT!%f?AaetkUO@V2;MaMMPUv z6%#%;Me>RD!jmaeYH>jAE^&OLO*a|S)#M+H#Q((Al?8*U{{S};?H`YqMn-c`{F}YE zJo@6e?cV%=;h3y7fw4unI>&GLr)@^^F=hZcv7rd zsKBX4Q2t@bZf)50kk#f-_c<(Y@OO-Z!4$|SFuf*sw^A*NNfd=uQH~_gn0ZZx=-o8nbC*J|qf%|H@-KP9 z-!FG4#Z%Dmh>+iFld_Qt0@cIy*5z|(rjMt@)Dscf-_aC|U_p_x2@+W16e;odp11+g zzEN0BE_Mnvf+rO#3q<8964)OLO#;9XwtYlu0>k9XKk%?2*zc#m*Hp^JTRQK`IuMO zxyqYr9)hUvF={8%CHOv@XwR(5^uDM=w)SpxV)_tT=^=LJnb)oNd%9bdFt!NP-ueFj z!W5;AUZBN2&|BL5tdEQoXYAumPSEhe^_j)SHdjJZW*>f;~C_4 ztENK92rRuqX&Xh-atfW`aIA|H+issgxAP`{9Ty>aZ{0Jyr!Zi@}c z^<@~Yg^FMK{P;mC`+Vok9w{}TAR!y)f%SX?=A}Cv56RkvSV_lSk0vOIWJ@onhGc-s z4KC<~&+#r`ib6Lv&xWhX9a*0lJ+f!Do*O9#hLgd9WV)hyCajB-Y38T}FjvA*@hh;k zD(j8I&Rdd%98zTm#DNzfzfHpYu@!5hi&SxfL)ertUbiJ^so!NKl8umuM;W%d?|2we zm$x}2g3lSI=88d2nAvnxHBRn#lhbz30w>h>F>bV0U}{|ArfNZ=Rgi6_hq8}jf_sl% z356>HV|Q5z@zibIeXMJHRlM-pm!r`Xcy9v3ex`Qe7fxg?|& zvIcyoj-SB$13kRzb9G97BQ+Xb)GK(2p~S{8Q*2dA0|vDzy;H-ZC_ni-D0KY5rvoKS zSZS=+f4N5KcF+fCXrNKzb#db6yU43c z;*n&0eCZ?8i$oN<2q;|wi5M{*>Pq>>3A|sKZJG8^0Uu&!dl%{gIAzX?Q-?sPjZ*CD z;?VD03bng&Zs4(+&f)62BK_|rX#FMM`12Mp7X{L~GyX_kaSIwbU7~FvJ1GfFwc(63 zZk{q^it^Xd2T%mufSM~t4b|qJtqb8+sNTIiDxpR^3KQTMtT__RIw047T9xh6FS%bz zVrr}7&4;jDS3T}F#px;4@Rz+rRISuG3{G>h+N+{}0K>fY>d=gk?P-d)N-;Jo$>xsV^Llz5-f%YADtn<5YK2BXzSmfe}5yQHf(_^0f z)S{?-=H$SVKLmL;zqQhSnb}nO;|5rV!{bMl@L!sGit`eP&%jh-xY#bEnjf3j z(doJ#D&Y60&`)Mxy7M6)Y2M{uRQhj{n>lj>L#wzWNQ;6+ zz;1#GH$1_Mu|L<$`r9L*hjKTnfE{dAx}_-$eM5^H(-Z8v{7-Q6mY7Ca4o2N@t9E7O zvD>~p1%-+!0hkb3h#XY#37L7qSEw;6G2u48>NCKNxtREQ^aN|wYO0g#mp$%zYrKrc zk2cf%fR9k8D3Sn-6jX~W+%hxQ6lMQU<#3Ij&~!O!KF z1&~cbAgnxwEIHEOlsC~1Va)|Ci`u6@iNVC%avR{Vq`K@R7!t}6dKflNxi9^@1KN$V z|3p!yh6m2g3$T9yGujOg;KIzwT&c}o;~c!7PH^rwmp8W$)I@~}UchHnc`+H-zlPPu zjzK%Cs|o1(DsJHRT9RaHbO$xDy6V3?6HP8^)Gdf_(!B5gVzvG?f?o@+H(UNE&gTJQ zO13A{xt<3?3pBaQpfbqRB>z9R8uke-2X!c<#J-nKgJ>@D^1R)_q2%s> zRG?td-94WM(GX4+XYZTh-~E;@bHk*m7H9d8({jL#vVvnj!&W+BrF5~+s$J^|NaTo7+gUwWk)|=Cd7m%;C?o{V(jZ z+n`dMCvO9LuZt&`VO|V=I?Pgk8bOEKxCyx^lQi<~GSN&;GYT2P1>hTN!QAr0HRV3*eb49gY2}U4=Nm-FR9WxNoVWhr|OAzPUl?_YDce zIP{{IPGSg<49szg5tg`$JiC~Cw=8wt)NTE?1~R4JxBhC5KjDWCLWZP0A8N z9eV3r)N!9c%UH2>j7lSR%0hjjf1zEs@8(hLQXO|^W>lwTdZ{Nsu(~v&-i2qYf6|QX z2w7&?mzV@*Zdo;oRS_WoI_Mf3r8Z@G$^ml>Ea zZg%W`xnk)Dkv%>@A8+LD;#sch6qI&G__IejQWB|K6382QA)(im&osuaci~L5o5*?O z!|jh6W7106H`S}n)TR$xH8LVT3bdlIs!1VaZ~cno0p=q?Gm)(g;x|tC6?uJ^ADJjU zI46v600BGwo&lg>8VrrlC)J8qFsUnR!27;MCS>ftfW-7jfyNn1w0f(bdZ9*?#Tv^A z!^Bhvao`TYZ!Q@E-Hte!Ylk@<-UY-QYOaW}RuJ*5VJ_Btrg*|+`_QYi57`CtLWVy0_gf|}Yxqe%t^Ii?{dliSVS~UJ^peHr8$f}fL z2m9V=WYoN+bv>P9Aq4rV?>{yfSaFDr5AR5G+x&oVQY}jTwr@(KcTRYxKQ%l*wyBa> z8=@rY#=#xNvmLK4({jO9U;uK$$G_XLjI%riLh4o6IOMF(&}Y%_^?K?_M)_ImD$}v; zqj}1Y`Vo!j%qJGs)Q`^q74#hKfStXo(ep~ zJCP)=dWZM3SrGZk9f|Hm>Bo{pau$+Y`r5lz`;N96rV|zfIZ?xwKBT-#1dNUz5JW>W zk8TX}3+DFk_8*_I6GXuSiIK}`^#LxvKZ6s9cBk=UcLS0*m(TLPjBw(2a7@YH$l|^( z9a3c__i(!gP0xdXO2{1ULC-q}LL@ysk=#*=e|K-%1vPeW^od@90pgVQ^2bR~dESM8 z)C6*oKD>xN7rxATZc=K8sC_YZ9j-Gq)%0&RS2ZOYWaR!VO53W!%l;voXQOQNku;H& zfnfSs6*(92O$*^1dVur>VEBPHrF~>|`mTavr^8b$ns#Qb=2y!05gpFJJF<6bOeVW3 zp2bywtZMONrN{>yy=L$THCzTOIa$+3M;>kOutR!{2Rp+m#|V}lBhayjX)Tvi26{fq zDyy8ZJ^QSgMAHTY7{B8RO0uLFYWWH6*m%^Wx1Sa5)%tqu#?NeXbwNB7SEnQtaS;vZcF? zb{CitAZ)Xr#fr#D5#%ekBQHfOf9LW3jNvE{36D!nwBIjzYc3+(ecBa6tpdb}K|q&d z@^6x$MLkXz`7JGuuW1Au#~-qRm-M7jAp1SW^qRxg#EL)Krc8mKe2iwfHp~9+6JUPS z*C$C;4@Qw7G!qW;&vw9GTQ?w0hX+Csd5m0CCE2U&fLlQb$G^8r?h5p2%Zyq+Jo#-M zlg{seNocz0ZR~*VC$j|~zjAQD9A$_&l}`lAl3ClowxUmy^f`troHpNvCpQV%^Ey0b z_w;I4?`I@_$q^qKj}*cA54^&3aiD@L6)4Vw0bW79Fc?-}*mM8MrLyQu;%m@nJ;PF{ zF+kZePHUL1w&i|Et4rPgJe69Gb!?e1uk=yW5UeDVgy^dX>dIfiIrKa#Zv;qB-_ci* z`|`QaKXK5p0zVEo~|?cH!PLc z5;#OB{|QIaAextH{;5I+0h-Ye_mI3Ol&kL9w;Ef22OQ&szDLugkCQSln7moZU4{}LkaIEE z%@T#IGt~SigFYnEy=Crn|JGCG)u4M}ERij{ACFhLcGeA(wWPJ2+!H~s03}tqvllFp z-{RkiDS}2VQ8~xNH(^!-`(?IIQygv=iG#FIY9~(stN83n3`%h6-OoLgPluQ;$bO6O zC8l1W4r_vf(Q*}+KVUj1X+32S#5xTujMI$>FDX>6v5X$68PH3fEuM@IwyYBkvPikg zcs3Ez6u!1HuU!#BuO}Lo#*HgjuSWvV^Hro#G3ucwYr8<|OE%r&e2q(Eydxqq-2Vl5 z;ERhZoEZT5XZz7VR7p(~cDA9gVAAVuQ~q@=Rp=#jDUWpER(or61z0Htz-C9Zz^eG>3?QOL zOI-aP9A7v1gC23K8=z=x30p`7L*voBWl!u}Pa5#sCXg%naBAE!DV7BRSa#Cu`1{l~{^Jy|bj^RHfS#37e5>RPhB_KfPpkf+fo~=zY2#hy z*qluBhHD7&N#C%tw=TI!EYYx2dYKDLwf13)R)qsy-+V|Y^~PYlD>y+YcUNEMy0=o& zm$j)PDwiABs=qjII6QJewsb2=>Ch&jj4CUs;F&3#`zNt&vU)DZBCK2|XzmBnNg=UD3~9&JC`qi?X4x$K|5bn)hOn}NptycKb?dEF?wsW> zMiZmeeQ6I$kmX=_@fgh_lZ68ifiUBJJ3wW!Zlw{GNByWuDpkZ4%UxjKxNr<*aD8Zy zI}+?hUW!cq9=F$~w%}rRpS&}Gk8nAeg#QIG1%9!0i3!w&YLIyl^aIl&mG%2;ySKW` zsiHpE?P|Eto>PxYN?*M6KhqT5EbqEu3_70o^zQo;2ma>-1`u`LU9X2^I`qVt|D#G` zipsZ3UvO!EJIxReo57Lh=0q+WC9dV%kA@S#Ac<_gYQa zgK>m`7t2A^*MM{kG`B8nyd`DGz|-l68#`@TO!Fz+L73C1rgNJH$d{#;lbWd?2tMq{ z!(3-~2r3DTAd^JeCN+!eWf>2#MyY_9V8j;a<*7kadeA$%G}pKrAJTFQefKXXdH~|e ztG9R2Bf980zxuQ1?%wANQtWA5C3Y*15~P3fo*z>q2slihx>TlS)5Od-JQK)KOeCwf zzq4CY!GTHkl5GmYI+e>)H%<|TrE z(BIsRZve6kieL)2_1D9L2sh_O7w%Y<+ctq@=c7k|p$VYM zXD{^gRrdG=N~^^6eWKw9{ESg}*Cn35XP0{y9HM0={j}_FXP|3O`FbY zA!6dec&oF)lSjm>(CLS!FeZMdcbbJ{CLsbrT1~_X5%W)ynzcE}+*Iz?>}D==7b+0F zzd675s`OvLAI8SGKK7O8b*veKMa5PA!oZADk|oVnL`g%2#)C+rtUIew$%I{D{Y-_f z5JT5>_GIWDbM-Ve@unycT0;HPtSilRIqZ&bd5{z3fL9mhxcUw= zNtI?qyrZm=6mgHjy|DaF>m5rw`nl^&#iM}c25Gm;KqJT!m3me>jV8F58U$ZO<#DvK zDp)j%x7~6cq<_Ol`?Ft~4bxxjJrqk`A0AvYi1Lxi74`2L+e-y2I}OC84*x)xCp##P znjObcj}f8j#&Lqt6-b(P*@nNG24(a#)b=2*auO55)lvp4udLbA!U2B-E2pNw^ZLT+D;NBsWkN%eICPwt;_F=3yvWa+8 zHz&JdUUL$ohYe6aC&!T^CLy3n-#$V{?hn(eusW95mdW}7_h)s>FV}uL)YY3d`_~31 z?lkEMHSi(sJt?et{*I{^v&@K~F%DJp{|ZKWfWQy!rWSBuds%N_313wz?bm)5-8bwl zAreo;a3k?K8X?*gsFneg2KX57)%5h3c{d^AGR`OV1y(mbiAjmFUTgYpCy4l*nuVq6 zW*!o(h7A%$*?`fEf|N-vwI16rZm1M?1$_!C0lmz^LlC~*EF{3Z+T1MNazK?&k1BBH z^q-CN(n*iisV2EO+A(V4vu6N0$eX`{EWJ{=RvdrcOUeyAR>!)AQcQk$XOkCEl=REV*jpH9)xT%Lhiru(Xs`TWscN z>rmKCMXXv4G}S?N?jxT{vD`gdCu_?~`KG>kj40g3TbnQ#9lkMJuz3QXbWG9I!9wPm zj<`EFc|xd(>MRQDT{C4`ZHu!3=MLUng}>|=^v z;{9lG5>ozMa4wr4XlQ8-^1SvA5`Ng{P4J;)Gg$r&cG@wGcBpre{k&_huS{_alZ;-x zk=5$0e|Y{c;p$jk8LK&D9mlvBp{l-hPxMvV0r%GI{6Okv0f9#TDS=bvXb;w|#|?dppd< z+=LBE0tTZipLhEaCWTI3xpy6Jw|vcxqWu`x16w+TZ?^__Y2;;A@CaTM&r?WpOASs~ zHbm0zVi522PG#Phw_ys>VL2Ou$T})S*I>C(yx~G zzn-N}&_Hus=cfw9LJP7-GhUt9sr!a+H$o29Oj3{-w& zRjOG$*mopUy0{%*I3D6uja}s#fhLn*)PcPbdq8y;dBbm~ z{uoqtp`BelaW2yYWab%ZZ9v7eQ}u&dR2x|q4%1ptp2}O)20zX@5;!{FM~0yqU3P{~ ze{GjSr@!W4(l+uz=r=2{D<}??iz407cP>3}auC?5yd*ifjh(jn>Ab}lTNVj*NY;#T zZzdvi|ItM}oWwAblNiTU+Gu5?vMUeNWnQdpBANsyk|=6@n-t1tSV; zlqwq$7)jg+0#szRk<)|UPJg)ADrDo_y^YWRgeqPAN+HbaL%g8AU`z95*w^0@&)mJ0 z#)!8nP?zAk2&f+IX0+UWJ*(<~N9TM3b&^&c!Ahg3*SxE<6?H9Ykiia{2^8F9DN$@J zaT}ue*EJjbVSKmoYs{surfk_5))i>MGsdj2d{DQl(ogjLYOs58PUPbC>YH;JG8!#_ zNzll$f8zIO5R>A_11 zNV&7nv2-sAxlURM`c$3&{&)&~qmNI)i??UrdT$l&6C|=rNK4wS0?-Tz+0!!CiJqgA zl?n}FMpv3GW^AVkMDPM+wODoVM$V`?b38*`YJ&h+p``uKRDt4la-n%jz zCWP`ZPY&=5DY@Q9n$LK$b3k|^A(W1eR!GZvczg3;0RLxgl%oz0*??}=rTz_4J-i1H z4DMFcVZ7-+7p*v=$r7>RHl#Jl19!H_K?nId zB;GD6JG}QiHTc-6q*c%r3~yboR{s>EB`F0O+tFl?0G857MqV2s8LZoxV?%dz@CT)ZLu!u9 zPN?wbvsr$*N2ZE5XAUK&8Dy5`G&E7kK@mZep%!4l8%B;AP^rXFQ2@k_fepr+*r=@q zf-u-greCQ;h;aeFI*V9Yv<5grGdkVei>4rOTVauX{F1C+7;s>wl_Dtx5Qu^6?9^*A zSUR^Fw#T{G69b&L6<%tPB)wha@}{dF6PRwAqp5vYa*HTLY|C{3ly)ZxW6j^~HyVN7 z?1E3?1m3G&Ij`NJ?ii`rXWzCSKaD}BAzyO8jvGC_4en9~z(fig2n@8G9K93`JfAoaYr#yWS1Sp4!bH zwN@-s6uy{-43?YF}V*ZxPIh3H7Uq@dma%Y=*rjgTuxaVK48(G!;IdyAQ#n&Z~WH1Q{Tu8%+eSOrufVH!( zK-K_ZK$zTP-U^UFJgIrgGOoyoweUvx>8`WJMN-DU@<5VIO3v;>vi=Taw;EaprG z*n=wEX+OEY)#H}*DUE9!)2r&Px2U+Q(lIKp+(LHz*mIA5{XH(XOUbcIjDAj~f- zuuhxIiENFIr)gdU6uf`R05?F$zkH{EK~VmN=jmd!I=v-j>Lou&jHwFswy|>KXN+5L zHtjxgOvL#t59A7wQVzDWE~7{^b2l4+@J3!2^3u(P3dnaOG1*UAj$x8gkTN#`U4a*p z(=~R{RZEy^qpP<8w3if@HnjNDs7fN|>gTwURzWo)hET9K`BygVhVuDF7_s>o_Ei$Q z3!BOPJjL{Ic3ji7V~(tbI_+bCuzJ&FV$CI%Ch-cz4EfsCVr!OG6HJ2?Xj=s+!;*LfuM)hJmlIA9!g2b`lFcyU z@L3G-OP|di8Y_05jWgpN29AfL6jJrZVcvp6U!%)#IyBh}WBu6uK{a?}<-LNs2mFud zjn;b0Kty(2*k-;!EI)bDI8w{&vUk9K!6H{w;F1>a7K%-V2-58s(iDlwP>#a_%@O6O6fohdQ>yNrQzrv41G4c|`pSjrAScLTJ}2RuwljVCG&A5g5W#SgqutsgCA zQIK9np`*-HF|SBBhM2`IIQVwD4SE23gY-$)eg%B+aoj-(XFS6-zfxDYk(CRoN>h0(C>q0KVFfX2 z<;ojn^t}<-dg5Sg{-2J{yI$oq6Ke`nKKi;*tVo!8_&^m7XmkxA>a_~oP2Wnn6YX^z z6lYQZ&-5Nmc{WEulvEl+R!it@qzCUmW#mzcBbfkd+!u&iFLe=+EzVe*a2UVqz(w7| zu-_FrFg~X5Bop#iX#rP-5jKm~003k$sO{s8pzYt;pFpEj10Ultl#u*{_*GHmYnk34 zdSooL(b1G_md#-beUHzFJ!!}|;NCfEkK31P6EOaC?c*}l9mK7GsnWn>!_@f|*6`gm z1Xc2-Rm#~<^(RZ!RCA!U+AOU`JZ=$R)&jcEjk*`*x>Hh6**q!4ScUhRw?SL1~Sddu~mgTb&m*K`8wXjDM$LTN?q+wQZbfOWO-sd9H&Zz7&Pj_NM z5+VKWX*O%Mj_vmNgwV01PqgcG$Y#_$vN2Kz^wy^wNLh6kAGp4~ffGvh^-Ekla>>r) zia9Au)1^goelc-x&kxUAw6BVE-~eyz4Z6BXv-|esi{L`oHAU9fAgh=C$xOhpXs!e3 zW!s51Zq74U@KZB`kM1}UZwj~`q64V4MfZ>>l2HXm%|Uq(Hqkb$M2D-O*&f(dnF(F~ zKIIUGJO2@9L*l$v{f&395oAX=x1ueuBDVEj_0Cy;Fnq=}P5ML&BjM%(mP95g&DQ7c zc{Bc`Ia!x;7^+l15J5puIl2})qy1;K*|$>%SajLb%gk+Rew)6_;XIz}ix}k7-3Hmb zN%O+i6t@Y~b;3Ec0o<+{N~QU7BjQ&C(8~e=6$FItb?d@hGu;w>{7RZu8JcTEyO@}J z`cPWZmQ<2QiRBlLvd8>>IX~S5;{xGfq+9~@eNbrRuEs-oL3bp_W2}8bGdLbLso&J` zoD}FJwlm-2+%Rg{GRC=CNJc^H(8<#ag5;{(Zfd~SS)V?33Y3zUjRBi4@Sl3MDnoxy zLCzn{eJYbCl_gJNL#sPq!4PP+V7A-&&1n1kc#9N-N=|~06qvsqS-z|s>#iD2#$4ZY zX7Zj5W3~)nIBCe?A}F%+p%+S$5K(ix*gL}}Fk06c_Y?r<)B?kP7n;&j-cy(Oh3S&!_RwDKEJ{-3>BHr^i44Dq2Xl4L_daZ)xFK z5>d}fru*rxOV4F>0YwlnVJ1#mbtl?hwFEBRbauZ!j2n{?n(ZCxhav>7C^bRGi?#2@ z0T!o`nyITJOzVS^I-DYj95;9$d{reIKGIsto_>ypPHk)FA!YJo2F?Fn!6teKS5##M zD{$Ivl>m4|$lM!(9+c=J!>zg@0EXl4b=42myX|@T9~4l_h7B5K{#hV1lo&n47p(fi2-JEO7 zIQHoHeinsqkW?i$;Z+H~8!FdOa2-D{QEV`1*+YnCMfMSJB!TGjhU5%p^y|CgX`dT+ zcsf}3Fj#*JI~}#$bdI}$TrHWzk9+Y2Zt|_sIPD91x8HdP4Dcw-@h16SVX82t*Q8!x zTv+v=vZ!l4om>hQcV#nb-%+pw@TOrps4QFCTXq@8Yr*>aGlf~7J50STrmWVP#W5qU zQI6>>_ogk6>ysV3i1+2r9+E-a0$HlVU=TY9_`njIBeUVL9L3l zy9l?+B*d^%1XM~KIG(cd?Z^EBA|bz+%)HTwCo>jk_>tT8vzmW)t5c|6zCfdp(0 z<^BGh0H{W2C8oxQ!;fK;SxBE}efO2OlUcKJVgz=B!Va7n|2yTwd!K&52DG;WpE=J4 zYijOt*>$trqKMb2Snbya?mW7ys^Jt%tyli2OC?S`d^0NRc25n=%%Tbat$nzk$TY&` zrgOPnA@nn1l$i{GudBQ(Y&!{kxrq?VB>sX21u8rUCEemn)a&QStvyBmcCf{#P#|`T z`YIl2Cc8ECUj_$U&ER;<&8`K_TeGJ#5%f6}V{P)>0a|hm1B1`tQ8(70$BqEZPrb&i z@G`4p69A%mq4%PvX8oA7k}IKNsEC%sKpnsV-iiQ+s5!)d~)o;xLqE0 zgR$lX-PLUGl)uCERFMd`yo#8LA~PqGi(^zbi)L6b`qZ$9Mwxc;cb1jXs^Ym`C*mPSQF%V1B>ctm?|P7?lvaQ^IZM#FJY=^QImC+BqW1 zbvF0=zZbqZ-DZlI*0;luRLvU@SS3#upu0tI)yndY#V1#we_dl%Uy6s!sr0BS(cjdv zd?i$Q*eRHsSdJGiM~)mA|C2jp?6RB5+F%sQBSrNeDLU#Bb8XXE_aFWjCUVfIXuzi7 zfP3p?G=SIE4^tW3ai;bg0`<_)cvxSj(U1#MCmo{13OpQrk1Rg@#_LVFf}i;oaS&YY zuf3v%x~Jp8)@)=RBOX>8WScr9b6chn^dgi#KJ|2Mma^|*?!8Or#<(1}PJ>@QNV@Ux zbmk$~DJ8S&{#t@#-uCl+uk5aN9o=ZYYCsiq`on9Ug3xns$?RTrM`bYs1BwQu*l)qu zoYFZlD@foSyCySnpKgXpzOb<}veqy#Eke)A%pdCNb)GUgK<6)4@(ogwk$fhGQlFu0 zl+Xac*0jZh^YY++F!g$$mtV~h79z)*+Rt7?=4%aShunbE$eWsy;0glWqVG;xGe0P! z>%WN_MVh=67O#s>M^-}dirjlD(y3LPC^~T>ZSQj)qd|mo8+DjwfSWt9zcD|x1S7Uf z)8&l;$q&yxE1#oY1-rg^!NA=!>%ILy&c#M;h$5GH*8~vQ+g7vC9pXBfa+ZL4U;RrHYJubT>iEfld8g%F`m%Ut(neZak*B15^FNPaPgu^djia8{B0fGyv$r^E zC-W$6J!JeIg=5o=W>I&DgXk`Fnq^qv$~Zf}La!D8nG24)$`yxN^Xjl7vMG}Wq%Coz z5`=A@mjZJhYtY231<&O*)5z7|zbM|Ewq&!^EsqtcD{P9=>fmq$OMsGLgWsV96*&EOL^g=1)6!0_Nuku<+Ctl{{91Wf0=c|7 zNe#WPz1tn>_vAgsTg}-Lv>W_|`wNQKdaD5*zU%laKRktb@^BTdGikx1;H9u{p*#|0 z!Wcxoy*|9})~xP?<763LY2jUNW?FgKn6OAl8m)c5;Ek_8;}aGio2~z2h)%8~?vBve z5>onnJNrhfplZE8)ZCO7@@xrw8i5Gm1vqL&+B?d^Mu_4Haubo*fu~6km>{ ziIU8(3tsYN0X~;-5SX?4mN;x_iWhjOes1|+&?_3R{N@Y85` zsy1%!5>e;p_BoxRh%VufEA2weis8oNQo=NxXat8K7FBXBprHG;cWtN0Ba*3oeqMo~ z`Y$NET^aj~;nB4}r&XRM)TdZbG)YewxZ5p4ba90@^!y4_E-mXTze=@mn2R;O=@Bev z?JI=%&*?D>Df$cduY5OR3hODpbuQXR=WH*U&ONg zMb2$N^X94t0e1nvFM>5U{p*GtL^Z=CGgz7@6S*6u8-MJ2!<#O9HBt6Pn#vktzQB- z@vLKINy$au58Y#F>h-&aZ1VH~qK=HN7i+ak|JW9Ru&;}ANit`O@L~D~WAtxI^u=m7 zJHWPFi7yf@^YkbtIgx=bp+19 z=RG1luVn{M0?bwSgptUZr$bon7!&U}GXJWr7wJugo$O)=>T_wc`z?C-?iJK^Pj;VE z&JQ0T7g%CS5xR!ybEPl4;khvw<&G2-{`91`5^KWy1<_OM`5I|oILh0zl@5Nk1-Kj# zwf|_<&`h%OOmZHl6aT?bFkDdochF)@Oeu)Wbe~JgZl`9s(3(SB zz1MR|Yo!!arMnL6e|&PvE%^IjjITn4^!iC#{d)g^>O1NV_cAqEYbjz}e1sm}aPxsk zJgL8Exz89vtXLiI#JEJbB+AE&OlOHr@Wl?9Sh0BsJfs(}sQgqmGv0Ar8azve&GB^x zld;UP@l0tP7{2o`c>Qj1GKGtbPpD}n$E&ZadW&2t@4PVRQ2IG7w`@ARx{ zxQ+i%$*$12^MogQ8us8gz9atZk3!N%Ila}hl9iWgKHLOXfb!AlIiyMng2yZPrqh^7 z6d@4EsM!L;5hKbq350~O>A@7i-rV9t*t5hx#x_nR)>-9_x42k~x6C##)1?59sH;&# zoDM2hkFo_(?&yv%AQ7$5GxTGqPY|%5Wd@u=N7NUv6a{BF2DRYok&SK;S>*aDId8%0 zPnArH#M>*kIppI$tx0n8zMr@uNM(Ie4f$TB z{A|-7K|#auL0GAv^Cy#S_3tmAv)WOXf689JK2*u|u*HS$)AztNvP1}WNChc^^(Lz? z@X4{6r8KqlQWW{Oo4n5>1wcnhMAFR1k~oQUqxufc6R_pWdAWS*XFJH-C<)$u-ozdj}{Xi2Z$| zWC2%KDUllpT&MT;A{C<8L5kv9DH4mwrx0k7Itz5UA!? zTY{xKvX%Wk?c<~+Nym*NC(m-PYuQjqG6&1uFN*&au= z?|JCM;d8yFTANk4S_m01i+igkJ4KTD|1a^yg9js00FqCzB@1^prvs=ab@ZPr2Y2KC zXtiaY@O7}Q#F;tQ7uxN-UlM^HAyg}Gx->BjUxghZ?C;eX-SaT{rA*dprSeKD($lTtN^KQrOFaym zmIivxO#J)pz#`@8A6-e{u>SE}BlofZ>D5pYk*MMm`Bk+p;}&HPcD_S zir?d6k^PIzj^E9?j05vsmLSvqjztd7p|xd>T(LI&5x7adyV@6FX~5`nU$Dfaq_|UN zk(P&vMTTYs$wO-dngPZU0-bXn&-TuSsS#NWDAtc}yF;2K7^^ZwX7D2CwpHcK5Z{U$ zszLNohYo2pGFz=fEwY?F&tTd$oB`VA_8lHQ4ZgZCfez;GV&IUQ>`uwmPwT`xRRG7X zjMk(m?nF@}nrkc?+O7Tg6WTlBxP~SVTfZdjbQTqfr?u7`Lp`r_F2F@v zxQmaWb@lN5-`)K1K7ToQamtiqq~W>AP)oZ*nJF3-#l+gDJyV-I?;zAZ7T;f0E@9!7 z`Rp57`hTWNb)m<|%J^0cq6OAlcH9!3idzZI!m&_*bEhwF{O%}rKQX}p zIj{p@p;GT>^2Hj!n!&Ay(d2nDm!b3Xtq17O1hLx3+!2r~ZNf689Q9}DAZ3+b&3_PW z*4DTrF~Sd#grmw=^@Fg3kCsI6*r)*v#|2mNnKg7_TaHrYDBRe%7j4{wX_*%FI;eDZ zkFXPQ1&c8PcMjAV?Ybn);GFb;+2&I3Osn_EA;or&95G%8^>ZoT&o^*0tDIUM7W;|x z08je!P6a_yczdmeZ9ayRN|ML?CZ^8s!Pa%hkBEIGjB#P6`?i$knNhyD*Lm?^FnH}g zaV%a2kB8p*UZ-w?6v{i-B(7**+CjQssezoT%%%}tU*O%=Mqj;kF#h{wt>G77AW{b z8+Rp1-g8_-rJX9QPo!D+SC^%_NG77z`ziS33^sNQ@UJV%_nAK@mn2f{I3?jB;yd0! zn0#U+8g)ID+P{q3V$MP%(@9ggui-x1eMG!4D3VR+FNIG4K?~pz#rLOeiHWOveOoG3 z-#{-6Q1mEb1mJc#rPb!AY1Ad?3L_`gl;`z)v9$iP%Rt&0S z@am z_Z!QZA+a`wOrOBd1%chqD zpJ~C9@@ksH*efli{l7#^GE9wCwrqs-ho9hJp0b4nJYtCis zw92^f#aDQY-hjy}7H}2f`YU;O;5?WP|G-IMfZdVwv?4?l#@aulfpc#HYa@mLS8HOduutFlvZrCSF5Z2$o^!`zNCXhL-u z;MTT4rJ~PCfsA{v=U0SaI$x0H?^`s|0qJH$B`jacYRD-ZGv@*bI2(73q5=BbS&b@s zGf7vkIR2xo_=dloUa6X=v6xR~<1sd1%->Cp(Kd9R_e=eMS!hxVtOTSBk5(FfajHr?%dkR0 zS3^rzIx#5&Z`Iz~WKc_+91PNUgP+%O#ZZ0)s}KiLmzCQPfND{(T~k z0zA=?+FYHA8~AZp-4H;HSEFEI`fke0#t(~8Tn-9r>(pcN{(+gakYnm+=69bD7iLQx zQf;Dq=Cm_7ndnJoEal}A+i?!38vrkTb%gch1^n1PX*N}p8y4=y7l-MmqALC|-gbBKmd~OcMU#WqbAROqoy(ncVL74Z|vBnTUl8F?K<9?{b{Ly(hu$ z7iSbEsjd+9;%B!ocho6^RFxm&V>p5saeHWAh_Dt_yg^M!u8{?_v13Q8Z-uIMYd!vx zoH*aqUF&bt_RQ1npJfm+UB-$m%}nqFBnZtu-=n3i{}@50)SG|VIo-u`w1GNjil=81 zVUh$?(^g#;b25e9?Umxxm(p{RF20nI#R*V~MwSp1d&U76W$i{j&RaRrb%UXYIAAYQ zYt3U5EjKpM#V5h(F6HdhWyXHSc3cxUDTd{3*^h`5@hRR1LWmVySuvt}98t%+@c#V} zuq5%cdAm})C9g0MadA3p@PdWtV7D^qd~pDU>ih5h03b$rb>|yyPgR(=3+%FZSq7+E z!y*LaTmKEnACoTy#P9!dH@nmtOpb~WYsLgWEP!xhv*N8FyBUkHQPV#pm%mOz|GfepI&1GERvw$#F}H5O;H48@um))$6O>lODFiV@Aj zxq&JGovIHZ3y0Mo0AoBwQq1w636owe`gyQr;We@2!=$qjw>d`B*DF#m`RO6i3v+NN z$jJlS|6zS6^u~!CyuPVJ@AN}#{LuVb7<`R{gNT;9EWmYXqRQ8Qc1coK-Z-~p2$ZiM z$b%L%5am3~d$a9#%4;-UBIuQ%<}B(!cY0)Riwh>SFme86AVaCb2%~bUStk;;n#T*S zKQ^JNjW1)-IiB68unZS3;50;8erDvwUsHFjnDhQFPqg0$xK$&xJ zpJvLlj!;7p_~VP0>^OE5>DE5Y-VL~w#i0Qsf{UrSF^5yOr(&Tb34eRWm4&(?Vc@O+HkJdqBolYi5yMCQDB zt$%O|p@uN4&B9r3aPAr^f^`jAfeHRnqnh6NlhR?Gk0&8EjXVv{;uYpVk(30gNfAt^fiNFy;9oI+=$8^gVTC@HefZ(UnW7K>IIWWnbr7Zie12$S4se0X!0Wuv zhZ;=LNHO3mX=SyfWOS;AgPb2rrtj<}TlO`#Z&;KcyVD=s!{$CpS>f{OUU%`eQQSt+ zW1CrUR)?ngMHN$P<>vAF9GJmOGaP+J``yWsr1ehc6g5-qoU~j~e3b&A$`kO&ZqR+4i{N6#`08dc{2TBfX-wK>na zCX)%L)TGCTr4zcdikP>z>y#HTmoy| zSLkYcUy9QQb_t`=dTb&yvmYaJlfDgb^E#t%>;Z;TgmZjL$igzOHk8c+#%$N*2IJsxjYz`{>J=i1j#* zg#O%|R$}VOaE%(p{IkEoda+*AY<8vb38oe;bn#kDBT3L4{~T~9bnL@2agsO7EMscd za--ZGu+oeW7a|)?f{M}6Ae%z-RV*huE6=pB^hM_gC04@qa5JN*<(IB-&cVZLR?;Xd zLCVGVnn!)%ciepenW#rZ$wiqm+JKl%GduIcmxJfMwin3*Wwpk;s zsQ3TnxiQ}vP=P#wilvjXRcSZ#W|)~*kqj)Nu=XCfIH>TlD~2mfcB8+16{A)w z6B@S>EO25-yvzf`DfHMt^E{Yk`gh$e`4%KQgMRA$U9F=eOE&Eu}tK`t=q4rMpt%_kVxi?V*A2jPO>w z4J{GWqqEoyIb_nnoJ3?fA1wXnSTLJ3>8Y^Q6X0aMD|wHfVYC&%pwB^?i~GnKyUK3Ld7!U8kJ3{j1SvW*@+C#wA{KCt zPb1Dh_^EjroUeHiZQg_$Hy)*a4X6+*N-Rc2p3TF36!~e@FvPrdR{TT2)p6TcgO`Ko0uTK*r9+iAsH&K z=@1)743->6JBmPS2}YUO&D|2l)%>lehbc)L3V+O0EO zBI%4&1?~QB7X;gu1C0iGF*xkTk>5nxGufouUP+qIz2(^JPkfs!@wm{fwPbMVfWdK` z_?;th-jCT!uHki)&4R`mAi-959nNb2MW;6lb^ck1uNC&M7(w3D(=O5mfWS>;wi3hl z+wuk3IBDJs0731k2!`;ION=7Jj2t>?Tm4Nb2L z>r_M^r*QW2_!`CZ)kOiXTch}Uasw0Ta{MMqbhSwc8e&w0w6P+g}+ z{HD8Xh##F|VqPVxGikF@x=A-er|!_k@$!2xsZdwpGIFA}Gb! zT%T*Xk|uVbT~mY17qE>K5wAXL^s3AJ8Ybt-!vo$rE{7TUh$ zNNy}XSr7+I2}!Q+FI;(@i+&%t#8_VT<39d3u}-s=7ffKxSjOG9#tRE@QRrBj6&*?c z*T{R9g;WsC#=}>r@_b%^tv>0>BI5GuF;Pr>Z^|Px9Iy!{ukE3~`(ZfaZ@+D*9&g^$ zO4F}>F%K}f!OKr}rsC29^4`tMKk-WNBFdO|u;x4`#U5{Hkp5P;KsSQx;2gB*Rn`DI*=Zp+}zcSEjQ=3Ac`Slzn5fF7I%~IMxQ9 zZe|g#vi{-DD6yw329jU-LUSVr-v9@Ctn3J_Tq!4<;6`<$Dnz>s*Kx{bN_@wz>$-^v za;Cp-1}h=AgZswv#T!&NVxtPN;O2a&+Y7$@wu(5oFvkj;HuRO|V^7FbExFNv|6_UL z7zxN=f#3Y&VWO~sEvkGO{f$m{fjSyGJ-)uQC-mxuJ{AAocl#ZV$?8KoqlP>Nyb~;H z6HkyKDqSL=9V(YM3O1#IjFCc?1J}gSy7^Eo>~Yd%a{qKm->xx7_$e6^GbO#ZS-Gz) z6U0!L6i<7CWQ((F;Xr{-@rRG;5Dr?2t71>66WxNL+D(Tx@?ZA#qBDN4{GIl|fXSt? zdP+j0Gu&J3qubR^^PW`ROpDFHj5`U#fVbg}+T8U>jV)m#?p zMV3{E%kQ;Pg~S0E{`<-R>I6~9^06pD<+q~L@QJ&;L9WB_k(&5NJar7f*)a1p$CCe;-IKfj()%c^j1tWbfo$$#y zIBn#pm9mE8(m^6uo}o-)rsCps%D_VDY{oz01FwWg}}W^B{|Fo^fq zF9!C&Tb;h(wDrZhs; zTt9lpBvP0CH`Ps1of<=BbUn@rdgolsIjr(u4`>A;im%h;PAfk11-3uTh6;>|6r`gP zM1c>q=NmXPH*Ifo7c#Zd)>;1xV{zboh)>pft_`l^Msdxtb_G|e*7(%<0jTd`-^aRz zoM5biwz-=63+4|~R|fk0V3lUihXI6c>Wp8qET-XtjUX@vO)Y00e1x-_V)5h>Te-%I z?pp#I@P7TjbE<+%mj)(9ro+d?A4rJ{>W2_mcS>1e$>YUQj1zwLwy;G}xMaaf1jZIv z_kO>gTzf?s{Pjqve{w>MPpiW-s!8bat?Fc8+7oi!_)e12ptFBprN9#3j5}-e`oJzN zn=R}sOdv5?itf+7U3ceMA5&8t{QF2KUN6Io0w0V}qTM-`dotl-vYt~xdH!ZZhdD2H zYvPYjXR?sIVSEUPMn3BqV^JC*OPCQc>V;2~UuUDK;&D5SF4Sg1P}?UA_HNs#WVVe5uIk%!C^>^*`O+Tm@Nba#L8buckq) zlH=#rLm^)DlHuZ5oO;3VblcdKAc+slcg96Z=*Sy1{I-#q>Z}&dw5W@oM#neLtniqtwh|hncdiH>xfMS4`g6cb#q=M9p zY0Pm(5!cmz^f)H5mbz*(7*)M+x=e~BBC941xHAdcP7qk|yv5oA80xxae6Fy*9A zj~<)Bn`(uZL=h?W54h@x=3?t%%k!^VSVx88yh^)7UBdEf*jU(aSiNxG9LK-@%?o7^ zJ~vuBx}77#oh~_$(DCdGCaf|-p`Arma0NSDa^M( z@(9#f^N0=n-AMEZp%8)xDye6Q!~{8v8upuUQb8Xdzu2?}@?vVes8kGzChbZPb51N}_|* z0JRhu>X6u+bj+we9#VeyykaGcPUXXjo~V!nnW}--T|@gTbw|Ld;=-y?1Vi#*<=3Ou z2GjAcpAvutXZ{}@zG;Lc>!3=MUF%d{1Yn4<=JF|@C|I~;-IDR=(KfmMKy`}Cj+Uil zlV~dhS+qB9cjYbNJ)*56VM+zooOiNg9dQbDv(8U;?jdQ`ZfeH29+dlnsTT(tpYEom z*sEsS$S~P~uQjGZ6$JW7!lMyRvRq_>pHr_+&O?SjRbxN3trNIlFdZS(N3{*1QOfoR z)+G2z1dt>ZB5m24ag5+M#brIS{tK!n%!;Xj3BF>!QKi1Rsy5;8Oc3L#Q3>STcS;Vd zd}AvM@{=0#WyhUiz{>1~TLqBNIcbpRMuu_W>0LuqQ9h>5NT|tr^>V9m2J#7#!<8po zHh>%r%Lkth2&y520}%6(muD|BBAXr39hg@PJGy(H=w*-Ot9`n+7FD;$K3CJTl>T;n z6TVtnCLDlGOmJZ?KzKT%#pD-+RWI$%0}IS2UsfHdG-jKl$Ulv5U!lxRmrh7R zac;2|?rML#i z>KmF2O61xs``uz$0~tjiM$R#%QiD>!P<4-&YxXViiF(li8NoW`Tx)9S=#@FMPkS9? ze0yji;uGklyqM1DBkKP`6BtbSlx_xvfwTJZyRL(S;a^(tx zje9L)u9F2OHy2O`?0Q&)-1 zY873#`XsWR@9Oy;!EHCAx^bglp|i}$KHa~ZUFfAZ>EwKWuLG+`P3t375$aGB`mt0& zN2-39fCl(Yy{`TyAoiE>9t@+e`35^+MVYJD6f06oHsJtrt$9M-oZF_`Xz3$X#LMG2 zgKH?V6bJ~^m3{*uxNFJd)id@M?~cfB5HiiX;5)bR`8TB3ePEOM1$y)s8xw$xH9Jvt zPyxn3W5+p6c=RorciN2oM&fw>|8l^lX{FNgpsHdv*h?QJE9dW$eL=b9RZxZqDLJGs z=!zU%39zjmaH91-GR-eq;fXpt};zL18*JIY$)#L_y^?uL90M|B->=e;p z1$5!~Bo=^J?AnDs=&FM6+Z2(HYW-)Ph;tieL2(c&GMiCB*B^@V*96Q>gRBvgw1|(+ z;-3I&HNbs5aAayGq7j+~&vZOD*@lBFD;h74SL8q-rZ?Ww30U=JH?^E<>yNb2>kb;0 zP(<*3z|_|L^6U8_vf(q++AAn{>{mMTp~2Fw))&u+*s_pq=BA0$k<#CgR1-MMC|sky zk1P88)YWMG&!qp~Z=&+dx^ra>BfF=rH=svqE<}FR3FT>oqri7cF+X4pidQrQ&^RTDsBcjG3WsG6V}%{RFuRH^ZhXc=i$ zuRirq?9T?Cd1BE?lVL7LX6f@w-`v0``%cnfF5FBB5Rk~O*6b2=KKQCIBD4ub*0QzEK z0_)F!e5cKbWG$%Kxy6+IRC0*PH%p|h8bGG$;*HMwi~Fr+DQplH)$M?d=K}&bn9RWK zo`sS_Fn4o0>VObGgC4J?R88Dmk2C~h2`P)$HE;qTJ~?W5QM+10ei{avIW>{oUP_@M zhb34QeQ@^1n=%%7AO>u*&sEce#pUCA5Qfm1y(G8Lb}+PB``n5+tH$*=R?_e)t<-A6Lze|tI+ly6b!Dh5##rW4! zP=|~pUy1$*ms2N&K-gu1+f$?3Y8Z++4O_Omp$eZ5&5_9@UjbCP1{4r2<&X-ePz4hC zu8DInWBYtvqmkj|ag-2$9}Q973YhK-1j6~0cHY-1`)RQ5<6oKs{)AjH|Da*186?2{cgcyD%H_FfF{zxp=SNTB@h;T)g=>$@?I6#HqjVL- z7@~l0jdlJ2W*AzH9HXzQVj!A8`6PO^NSeJkzR*$MRv+g1b^Fpv>MYr&Ci76W?SdSq zeWOYB0;193YMaWSg?1A#AZW zIR*eAT;~ROs0@zkio&rQJ|%d$?<-d84rLKVOdX6 za|Iu%#p1G z%D2(I2*%Eo{rpH}Zn6Ob!|cnqdg<8QYvSo>=%MWe#d!x2#!Zdt_V@*c;#K;zUg$M0 zmd-sz(}%%T?jETGqJ@4gY%Y(Fsli4?-5!B1AKBGjn2B<0gA$R%Rz=P>mbf2?+$4dA z0|SDr2qh?8(h+JVgI}?5tiIk8<&KUxUojuu=4|6_z=Y=)V4A8Rl)@AHvfA7Uo(OFi zoacokibJ<_7t7BlcwjhR_ZXnY>79ja6x|mjDJG z{WBXD&MRau2Urd(2EVicUt1}dlg zIu53HA$kVl#NDp2h=WGAcz&UR#92j31!s@idNtXQ(^tCA~R>1Rk_-lu@8#b?H1ge+f_hme-$;kow-yV9hc65 z+BZc6PDBun^BVT9k`k0ihkj&1^blO?Ygpa^sjdI*xOzW_LbS@a0m1z_dT@a$>Cv7< z-TI+N#j67!$75vcNb1li)7qsIKAp-JI)2nj{&0$yII;iIz%^fgW#K5@*7*XSi(kF zlbXBVk96FPLzT5C{W_@?ZEW_#Fi?mNc=yDXP8A{`Lm9jwLJN`%j<>8rU_-2;!N9nm z5p||2sN=(5*h-ZUvhCuRGMe_a)>ca)ifJhr#GxX><<`&TVM+m`+0#+(4pYi_%aVR8 z$ePp$Mc`M!j+1B;l>5#`axpEC5(N<`K~lq@za&GrUox#`EbaU?E!%9FcZx~VJeuI; zv&L?*-d~W$VgC;T_EU|Tfx}!F;a2JoL~m;WqS>HIIWa6ruYZHowBGA6uBt$dudk1_ z5@oGQ-5q~97nP`XR#OB7#`2ZXTlZuUiIFFFI@N6@exx_Apwl;>tF_6I^EY*K>eMkQ zt2`~*+m6qy8^|Xr)1Nk?+fu{LG1=wSO(ThgPR~~_CK$fi(O3GXWkA3cBFHj|>e8UxRyVy^<>qYW`w6=hmr@Cw48LpnM}=LH0|Km6mnvhU zFhIhD{aJVB`KCifA?gg+srI5bd^qy8XVo>{xquz_AVIHPT?@5rJ6ED)x96y?0nG(s zXH|2yySrOMpNF|m7Yx4|yi#DH=-B!PSx3*;Ehajbq)Ja&6e@Iu9*7 zH}ohQB)mU3d<_s z6xICK)lIGQ)ET#!e?w(s%D1T z#ScbHXm(~q_2P2>x>J>->~L{4W$;I`#e1#vSzVbOxhu)3O1s|}_za_+^?YP}ki{SM zs`ROf=tjd}yo)-*Ih5B8bdouE^@Y9o|5SbkXq1D2`zOvX`C#ojFbL4!e2Q%oa1M(k zz$A9bva8sm3&TGH=`B2=bX`W9Q+`He!S3yVh24oQo)Q2t|K4C~-8+T5qRTf+1Av7) z5bap@%tg5&3vV`wwN=M9ja7Kb)Dcji@~Bfhgt-s5^~YfA%G6PDI^|t z1TX%%!_G=aa;ztax?+u|Y;W$y`z%L1^Ar0n<{#bg?{yr4UoQaTWTe_2U_pgH`4u7T zL^Q4c$BakWKw`lbh7|myRauNquNVCl_rbz()nj6v(X0k;CZpJdB=wO`3QL$w`0eHU z0*8v*0J|9x586zIO}ENjqCTZ-cbw}ZNaO(SQJb+G?kFLKDC}Py-eTNZ&b1b$yBw$D zZI6e9j&Davssm_y8r;I;K06I2>dWfb@ZPt7bK`+%Y&T=wPWEYT9x>U5@nhD zYztQklVra*8oR#{+?X>gR#RDd@%n2RCe38xx~>@)?Q<=(pH}6M(7p`VDXs;a{XROl zhl!q-DYj4x;#q>P(1bO&>hJS)t9GYY6K7Lg&;v>CV{8z(!cbuL0;LXBIt*@FQ-&a_ z)T2BCjEEU_;uA?qK<0wS=A>A>M~yiYK1CHQ&>+GoBuc7$RTJwpIF6uHs=nn|G8Qlo z%NdVypTi9?cyXuKw$2jK3yV4r<2_+_s~V_}t_9@71JNg_ zl^Q6`q=l)TE*{SUZfWBYg_1Le(l&(es#q!jaGH0EM3o|W0Nw87KWZw+~TyZ@&_?-OavovZM3)Azj z>k(14w0_dPy^i+dDf6~$Ua>wZ-LXUC0ZbgdN<@^Sw{otnO9+}X;-kQgIL7CL!DC#) z@e{>WExbFg)fsqW9au!(a7~4bsV%{_h%qWwrm}9}UtULS^S$T}Qb=4AAfj;I(W3bQcbGvg zCy1nS`?k(>20lQ5XK~iokdYOOZB+Xw8L{sXKZzT4Q+#bGL4HZVh)9(?*mUM_N&y&3 zyYj{Ao8Smpy~{ZQ3kUbq!mg}J{O+80{zi=GoRBYS7O8IrTbfQHaa9Ma!C_negQr%* zqZ5)S0Fzh%sxmpya}jo8dC^uLSblDv7yN00E;Kx;JHtV$%U|yHN9raNgWk~(eK}RI zwh?6F{(jy3V@x3|fdJMmqjNYPFg=~XNt~yQm*3j<0!R!dh_~g+&y8}t-HOImieq;I zAa~yWg<#_~eO%kIqa{Jlh1NSiQ+VRMZTlPP)RQ{hBe8PIWM(yE?>|TPE*MT1c*tp< zFsy3{9%#s<6{)7TgMh$(ILU{Ob=>>@l&EFi8g9usn|=+6;(FXqIzf}g{*39kr#AGe)rR|x z`=CL=f-xSJ$9HgE2O@_qMlfA{wZubabH3{zug~@Ph;1OkHxHMhPn=KERx6)Z#-FlA zkxDKq{om-podlq1%eg+q0hZ0_{tt##o1x@?uuw{55C^+H&1wAB5ts%_6Bw~9-uXy2 zdm&$e<}D=?LcTC3K=U@GBPYq6yTv!(Pn6JtSDD?Qja4Q9AjmS<|EY@*`{LWpADRff zzS{a^ruR;39klEFDu0$D=)VFK%P5ETV6XU}RL?4+hN<*=t@+N>pDIi@S$tMQ zPYTD&V{v#U9efUyH2*^IA%Q~+**j~>aZZ;}>f*~E*?kJ~>_c8Gt2F1njQ=?=mw*G+5=9h{$*y|vM_s6}lD638u;lNN>S zgneE;DPyXTM6J-^5J9xlz(Cz_j8emlsb@amo;E{F*5|G{i|&Ybce0}${RLld;>2Qg zzkz*s2QLCVTmzkKf3F~qrdX#gEA-gD`Tc?+;gAgkTg%>NP6!i!%+DM1L~F4G4lPxt zqf9m{nve$$}(FWXWl!W2Uq8;dq3>A27c8r-+iP4^pS|J^9UtWM^H#g@M#)NX({}EAS+zTVkqpr z5;|O4l`UnH`ZHxA@H3V%70V6|PDMXPdsht$3&Wfgb2!i$xlFAawwU-Usw)_Y_{-3o zmKkSP$;P1U^CJc{?zO0W!S~YI=15xb4B)s=>KBuA3RsYQ5)3uUg*wxg#YAC27Ls>h zbf7P~#;6*H@Pg8oxt(v0orlQ_CBhhSfRT8~jC1(H#p(wPZq8K%;AozCQ9!UuBmY1$Bn^q63BO?X_vMJb+d zYs;<=9(3IlwAUi`j$_CkU~;)dxGWkmcOyv@$g%-Npgy$nEVG6sw1{;`ddh?HAJ9AURo9*w3``3i5RoPgtJ~%+B*| zU0taf2ci9%L}eIs zza!4<0e4yVd=hR2x?+ewbT|TW@Q#J3fRoCU)yY{p2mr_f8QbgP=5j6CDOJ6$k3gtF zH`P>_hWYbtQYwA#da0w7V@rvxAAuShK|#qi@k|A*Sg5n1eWm zkakY7wno1>p!DK%*H`<<4F0^C0z8+Pyl<&EGAd6|P(R1?1IJz|w*Y%Vja%uKn3Yuw zsz@bYJB2@_Sze(?95EX6A%(O_yMxw^j9*`i?~4Y*Ew^5>nUeJph7oMO`*w4~ofZHl z&VJT*fB4bsXxYu{pm(MH#)6Tj{Rg%GuRpn57+z#pE*JmKQe;2X4)Ur0&+mVGWkJeA z_&{G|E%B_`M(8z?ggYik8b`-Xg>7eY&$a$C*5+RuXKK`vR_V0?}WsMfPesw_BQM3)>tb#X7zgI+TYlO zAaSH-icQ1_MA4FkZoM8C%#FdOA~O?PYN<aD0zhmPw%!S|GZ+=le2 zpEOoHg%`wLMC1MNRZh%p6(8@HK;Y;F@+ls|iRO&q7)g$pOrn@axrKKH9+As?_%R^(B_B)WDxMvPo&6o;(Z zTpj4(K<6vh(+5L76d_8IIW7>~BBjB&yuB zl_2)P+Pw7|TI_Z$?TaRRD9uSQ#9@404!dj4_iZ`CR=NNJy^#RVP?zUFs_nrFy4b}C zr^I*&Ot!G%?If21Mz}BFAdGL?PyO&d;6~u?An8N=Ig#V+Ytc7tg;r%%Cw&w6X;+oU z0fl4Iz2czEcSVAolr=Evx!f^2y3MXa7|0rpP(IfSew?iWIk~Z%o-%&WD~WEZ1D7;l zv=RH=NbMbpCDh?^lra<}_lx5Mn9Z5{*HKZcoEc&w<-p+OFANLLw<*-(q|YxTd+?s& zRKqJTcJfSASs-koO&CBLn0r)gq$Eo1=-h}J__+&GJwJfF9<>_cr<*)EiF|!MuAp5N z8b)kc?MGusmX|eyE4Z{55)MPDQk>B-XImD@&5j%9?k8^Q$Z(r#1GCTLX%a0CIQaVH zkNrLt^=RVe6vujYwqEb}Y*S|PC$pMyIJ_+Kyyk~w_RmA;^2)C`))kbk*OiNh34`Ui zmP&xcX@sfVaea~J!gG=&fj4k6EXYQmHCVyL z%xnlQAjpFjtA_$T3-YsZf0t8To>DQvUPm&|WV8Xh9pmYJJ?kUb#%uu`_m2Sq)r|)K zn}x_If5C~T;t;S2;lG=VO2UP_^l~3e zmo^tVRYarur_xrDmwQL>SBbSHdyOVY;;a8Go(R^kunyv8Fd4!|KbXWeg)kyDNIk6;|GFDY`(u02k;!NV~@g|f!GYG+Wr5pzua z=uL3$NE==2g_UApETU}?GWfw~1!JVNHG%eESaH(Uxf1$c`<0dp_>wbAV?uNsNP|z) zPa$8Oo7l#du~a6^|Dwl@xz+#jD`W>cRin*sH1CmFhn2{Tnrm8zLeNVWl&gB5k$5Rg z^dRk(IC>rg(wbQWrCTv27_7~TpuegxW}a6ZG^<`o`&nuX^InE^S*_I0;!?--FpCFh z15DW4dR|)(wjVI}17tjb9G;4i4X$yw*e@0ZC+~!2iPft8&Vg)> zaoHGnYun9Llu@5twMwk>Ec%qN5wrNeM08Ap{JnIHb7 z^~D{}aS5++qpIg@uMl&#Bvb6J;pp>T;y#7*IKGA|RgJUE*&4SMB*S$CtI%VfR`ND_ zx>EozqVgCjGa@iJ6$&BJ;xB87k?^<`COW96Ia9ms!S?CQJ7W;VRG z%1(wZwwZKaR|ue4lBoTl{$OEM;aa%9d~z-!+U6&1$>_@kk!hx&r1x$vY>&r}UI_yg8G<9*wrz z3Zc22E{38F;H}$Z@9~ga+6GgCMv)#dYmC!DQf2z{)drjzvYpvT=wf>`n z3aTM6TdK>;Wm}!Ei(bJ%Qz*6`FqMzX)CiP#`GV=5>Ojsl)pyUh6pNmRo zihJ9Sfqn7O)mnMvKU+PiRbq|J-_ zj;4AN?6|E8p{#7O20c1mDK)sX9VJPstcg5YHlJpp`YDr{CPpoFsi`3cLF{~8A-XM0 z+sS$Z@rXx7(RyiNwglpX<&+y64}P7|`+Fakbs>&BOT=gO@o>(7KnR#0xc);1=I`3* z`LWT|Li2Ki0KI|KkY&^3y;j*D=z$fC6=>Byg%4J-@xVCWZ5_TWO#sjFa^va1Ki_v- zbi14D*6mTOQ1Sh$(u7)VKH1EIf)w*3I>{WsX z6Jinxn7E|hzt7-*`&ocL`U?H3SYY5mSiiTq0>10jmu;|W>HaZ|aN22a2-9cnux5eS zW7%9S=qv9k-gtko1cEIWYDW$da@#5H9@x9bli5Ha?RMvs`hllleG7mlrt1~CiOsio zHUiDFcRGdm$_R}9k%GMjvq>6Ju6fN~kq-}R*4+l@ZV#j^E1dG9K1&jgT-*o%-QSCd zS(xRnfZVcBuM7h4;=5%@#tKr2F+g9sDrHkhz`zLI^JX~NrKG^4l=d#4K}aJ6>%rW+#Mu2_PPxtlRle}XvZ;z&;H<42B zdJf1IV~*>k^0yp8(MA=+k#M{tGh0Pa(frUNa@^mE6pJI(=Y5_kusCZYETr0V-qm2O zN+``~_Xt5IVsU=w3f;5&R(Q?A#bs%Axl|6UdQ-9k*#DCO@7*hpQ+ApUtm(+PV}*@8S~YE56Bez zJTsW-2=i=Or?xg1x~0NYpcQG)hRQK-KCgBNLcL5@@OpUwaHjy^U=pOSIN4N9Cm2sT z=Vn>dO{G$knB4s{tVn=H+U1G^UL-d^iH6?EYU;Q`blb*-0gWOvdHrI%Ug z^R20L^pZc8rtU8xn@j;3IYvLxNm2AVh#<;zrfQ4juqA87(G@5Rk%7v}rmMu$?Q zAJoV9rL+Y)+0v-8YXQq+G%XDn@xsmKa`@sTUrysMW9=fi)GAT-oEc~W`CT&$_oUhe z7AM*rVia40SSY5M)n&`jPB1FL-c1G!NbZl+Fe!?t;DqF$^ow?P^jObN8}#*xGTRR~ z?IkMN$zFqLCA0-XhYpF>UDc&~&EEPDgcw{oOTm#Gzi=D@9oV}mg-c>`lP%=NK%w6XunSQ}oLKXj$}uD=Y#v0*9G;GPiVc&RHk zwz8j&yI@(Mql%H)Z*^tPChfZ;^!&sQ$Y-f`#KDTs%Nf+==+Uc31yu2nX5UQp-`%q} zdX{bAr*lJpiA@B(=cASwFTTb%Eddq*|Rh68of7<3WX7R#jjFIj?@n%%di_K+kqc%9Api)7(J1E$oLH;@iKUR(J zR}kQJ)v8BZ&E{US*A$`Ye4i_^Wq_grFdG@_M?1tqg&9GJ16&9F<9-^T8-@(}`eNas z-W2i=I~X4r+$8RWSF55*fXJ!pw6E01&*1Zf_DW*`1#4RH8`q($a(}pS4{6yIZ=ZQo zfr8Ky^PjF=s~=cBi&}$31fDmRyhaGifM~>rOhm>u2#0o)(-dZ@t)YW_JKWLHuQBB)YiJGtVbwr5V z^fg!fYM*7s2)9ny>=o+TRFd{t=_(qcwkMPJN7Px z5|79^iIjG>Y-BTg!_Eug9@1#C{E|-<&qWaj;AMa!mQyxt54ycWt7@m-m8+A8%rM>J zs@^Hqf%n!)(5yb|w2PCTX>8i;Yf|V}jK6WqVf?b(V7hgJbBr+!*G_*@*~~rh6-f7O zRT-lCstJl{!lTL>6J?Vx_zNsqX~mco|DSWFm64(-Or68fbkMud4q)B{R=&d0Npl5J zaBX#H9_HOyHr6tC0kgbH;=0$htJyF6`w<8uY2>aV|D!T?X&e*JRsEwdh)O5I@5ik< z!!Q=m`ky=b7+CkaO1Gd>vcsXcE;PH4%H@s=^Q6Jl;x)zI%$@L<^(F+2-a!F0!fc5^ z^mJuC(BogrBun3pVbUiK>9(-ZKW@y{WPxfY9?9pc8C~awyk^lByD8^6b#^s2>82Aa z6*dD=XRmVcdBr$bD$HWXPkY}Gy83JC>*qp;f0=>NEH~BNb?`a@qV;TV4`)zCw}9?C z+ea2-MvRr?E(UfEGQSDcPwj#yhjWCc zV6U9|z!kSdRmqGN!{+g~E4ZxAZF;=|CCIpR>zPZ0a1;dw>SYW(+<71&CrIhM#MlWn z4TaMNnb&gv+n2W`u`!7!Cs&47h+1_w;aexYC%PCt0I%R)q=Sn^r%d!Hhy^ZEcER1z z5*N`ie?!n7EUB%a;YhcP$Z?%eEFv#W`Ae3u!I>KUMW1Nh=6hoM;Dj*T4xcVQ6zLd@H{`G zK)6=R|1Z%8J?QBi%W?Y!pF7shV(bJ;CR~dg4)kCG(IpP(ToQ7>!7Mu+mumU5NJitf z?u9~I?ba3!WZs2-U!|5jf4i4(e+(+Ma8J67z#(M0_q)sC#F)wJZd#=I^pK?cU{LK0 zo72oPqG#+LrF&DtR$a|cI`5gbs+CRBZzEut9u*5`G@Kysy37w4G&%2LMEu2f_*isy zftP`NqURk`6Pf7&45u?THbcaU4F69t3wf|Je{GVJGd8Rt;^oHE`pyPxAO04lkACe0 z$Jw4gfnXF1_V+tEF~vKw(mX^`F!;v4dsIW8w&G#pdIqnBRKW@G(gvA;p`YE&HGFQ1 zB=cFJvQNRH(ZIMytkxxx$sK|8|B7x_KXv&g9ILC=V9PZa==ZyQ@N( zDfa|ASS{HRZVJ7U%+hN5NCDD@w=05=!xQep3A?A#h_W>)#J0t3d+Liz zP54jLt^{xSzqz#iNuamLbA(c@hhm8f_jWe?p6~!z9tEnndW4;{|G}(Js; zA@A`1xQ-^opXh&A)!+g3q&%>853wi@TRNMt_Q;{V)yE~28k+hkzfRnQbPj3ZU{J-* zAbJ=7=1J-y44^Gh2EB9pW6{6m?}Q+I9y=p4cRZoVB`Y%}B$9FP-Gu%K5lJsK(mp!x za$bF?*6;h6g*cxOQK3De&5UefOf8`NjL#IA-6C;Y)}v_w!r(E4BDvQx{SbTls3>;^nAJtG8b z+-)|A!i|)1uD$qr%T(@FhDk*2@W?acc4pqgV~WjI(R1cQp{I5$uyyCssqC-Xr}~}IuVY&`MThbBriF5)yDl=o;c$i2t5|hDCjcRHikxjoKBQ62b`eg*5){ z9xkRF;Nh1%#6dy`ATeaJA=jvpnFQ2QKTrRdp9;KGv;0~K%$Vxv;FnG*Ygn zRzJCY`9l??0wmOhkeXvsJ^9L~ohJb5zHBBeQ~E>#6A;cKndkEo=39!FLLnvMW%mHz zP0a~LN}hvjHZ*kYGey85!4)LQq2|MrRB0jgRw^+pXfROahaEC|w%WFHeYxn*Cygd^ zYZ+%T7(5dK6%glDWoGyfVHQlUBKw_Y2y{c~zR6U-QLI_$mzwmeY zoHxnFbtWsb^B!g%{!l$oSir$VTi9>T;M(kxW)93Jo2ObSSR}8125wFG&A=y`LED6k zmT^M--3!PTgeURW!eA14t^7q_I|d`>UvHwou!h$%CEaD^l{Eu-6l{>Du(jT^79(}kwpG{L*_x)wFSPH58h;37AEbmJ`ua0G9nR%CBB)&naqH+uZi3c|H z7wn|<*y3*m7Droc#1O;&pY0PPJ%ndQDLV3$+r2KV(D6_km6k`>%Pfve7~==+YeOoO zTW`kFgI+^Ll5SNAl*m_zMYG*lWPX|?DR3$i=#^Dzvumkh+^KaDU$IKIA9K8`83nX1 z4QLY8K9soqT9&yh;f;!k80pGZl$CM{(EL~Nhwjrly6joA-Yhpj(0T?Jnc)uF=Znku z+NPh5d&KYM4*{v0%X>CHH92fM*dBr>t$<-%53HcUkL?K1e`}rp&m@b5u~Lbh`9bY8 zonMZWcyLho`H0DWSgx2v<%vOJ8ycMr(?6+8ff&^u4Og|ze_O_uc>e# zwxsMq~L4@t8`=lDT0KBVHUBpm#>60mTMjnf@_8#gJ5Px9E#v{=V7n`TvMa z%~V75j1rNsya=NuPkIMU15|cF_yNIN>Jn|R@LVXJ4CD5bW0jB6V#vTAEW71rBPT)% z&Ac2)eR@*+qViFN>kKcixKJM4)_TYQN!;+^ooveZFE>s&?7UE3&=-^S_l_*1>=iic z(Cg=q7d<97HiKXIu3UMRD0^xer*?F_Ob%8GW#85!Hj}gxh?i?WZfr%`H3IAq#J0Xc ze{WVla?>njDL;cD5LchX+HMa@vimqb5jV~z0V#&dL5dT`Qi-0_5N5;KUWnu_e*rUjK(Bz^+@R3 zeeIG(Pw%357IFC1LDHPja6t`y1#==)CdjIdcwee0s+pm8RN^_$Z>$b8<)SPyI|y8ce~F}%jPT0UO+>rfktN#*(t_Z+jww<^w# zv>Hb;LbjSj3VX`VvH`xnO~B^Zf{gLBODv^Rzg$`-Cx5CsT(Z-+Q0N!zCj$SOLt^7d zxo9u%(yWa|w~qUvv}ki4u5!WM5k4pK?0Bty(d{TPCvN)!=IF&eZId>)_EInI{&{%hL;XxgoL)CHX?@XS=Q z9H$N3MqjXQ0)J1f1ZE8h6}2kr?JDUro)4UND((Mye3La)N@%p-{X1E!nsUuCisD-` zl-~X^E7Mat)Hxpa5Q)+Qd?|&?BGXlJ-5YGLpWo9y$f+NT9<5h{#-90RZ<<~{&9yAG z@&*f7WOV%z&TM{cO^JKmOJ|6AhGYG5DyHwlMJ@R&?+m&t{hYIjdDw)iE zRL%Gsn+psM{-9MU7?-LB&-eiF72^wcCK@|M=U{d;X+nlR4?TTB;^)hp+UA22u0~ghIFe%L3&O< z+!eA7XupzhF!%?h8l*uMFs=igas4H%xo}5J(>a`d&SDE#xMl1GMB{h9;;hyCrFoop ziBOqG=%R{0eV*)PUlkX4vlBWvyexDEFf93vE^hAIMwn7Rmf z`+X-wFB|=+j;}OI-qaRnV$T=z1w2pRF6Y6N@+-|wl=X}+W$@Y20rwO9-tB=z_2{m?RZ$ ztYt+Fnr}A6?5Oh*^)i<~93TeGb+QNRd2DjGcYMA~OJqNDB({hb*&W|QNY}~JFM&}rA3!?5- z28VJ-f8r`lN`XN=m7e6arBL*=JIAKUjO7Y3p7o zVW?m4M`cv1G{FmKw`oR-0xS!{a)E#J2c5#cR7J0G1`zDO5na|x)pF`lEoLxP_UJV5 z845hGU&D9&O_Pcx7y5qR?fI44DfevqluQ>hRI<$*%dkIZwVhk|LH&a`Kljl?U-at*)FY5df4B${aw?X zetH8dEe$7*`zJ!{=%k4qb8|md_nBbY)HZX2$WHPn{Nxn@LNFV-N3|DMoJ#LPWCged z6HYM>`R}eLltD?7jpHb{gDCNbCoG7dx!TqMNbQ=$MxT%`8D1i!{jGA$@Pyl#9v_*c z6jl_@KB)V214_DEJm^ZFl{I|0m2@V0Qt$T&O|nFX=|x=@uSxJH^|jKQTp9y0Z{lm^ zy;37;8U42taW`tR-2*6nJjP#U#{~0OtOl=1-NJ`YXT`8)Ry=!nku7S)-0-v?*Sh2Td1l zwstg2=v=qo`?QeLIX3Km!5;B7zeHsR{p%)>WpKq=L(5fBPN@~8z;9Qh4NX%>eY5ZP z3Zi$9m+(%iJbJVR6XDJ}>MzW2Se8)Nmtvc>_m07OQ0K%7FMp1k>AzW~r$ne?Lujh2 zQKj5@amZJxGJK=Cyt+)?P2%#Cz*!H?X$DS?=VxGnh zQ7isHSvSVi8A-lkQyuit1)d)d)cj|D{nXYMtz8{6>45$VTW`~LPuLVFSVDBUgOQE79DO6dug_(9uL|Cde1P?uR!kfT&oLdD%g&hkQ=h zXAccb>dkisAV6Jd0yr5q$I9H~+iz@r{4R~o-E%ifjfjQ zE`M2r&ffftwp4kio(Vn_YIYP!l!~{db8UW&&5Noi5gm4|V4{5`ISmzY1LQmqe3l0K zz3y#v(y@stc39+l3rUO(y&9S=WrDyK0_vab`{XDi%b{E-sZlJ5gz}JK#sSM6abE;f z``vxjpr~x06H%ZOQ2yo|N4#xl*}nhGtZ^EdIBh_(Sx`O^z7PJijE(87-l~nfTW{fL z{=r*P^{Z-(Ho7IyO$34bcY?y_1e_`3MK?G6QzB!BKTe$-jeg&CPm63euRGMm%8;xm z!-lVvoB)WVO2$cI#x}Mq9G!Qn$pe)D_$b`*YH$^jNESr}{_tU9D*A5>)^i)`iwb+l zljZ#AuY&K%7ZZs9sK$9kN1D*j9HCM~>v@Yrs@W}I_0xQwNvImFEC{L~h8CG*^ATj!Xo#VORKuK>9rp{Joc2DFAI3dcs=r6#$_ zCuD~X)~W+h*~O9tRqkLqdE*0c^=31wyda;BcH6IG8;io0YHlLH45_I;;l%%0j71Y1 z>NfY_b0_}Rgw*8-s%v323MY_IqJX^yg$rYO-KgCxT<@Tg=9RuGQg1|G28MIz&(AHk z5=ouP_acOEEC&$%2cF^Rk7qJj_h@veuKRAgrMN+}Q@XRub!Y(963g(AqmPQV^$QqY zB}Nq?1~z1EoDn~<9S1`B#g2`{Y-H|c0GR(N5l+xtiGZ0DB#srXaI=iH#GBK&o#F&e zBlklaaM+jZ`%^~F)I2HT*dJzzvEIN2=+0HeI6!F^hAm=m%i$YRnV*>`D5>v zEZo<7w#=_<LC7$7@r;(Fc_y40vEi+tD$QC5u`tM&GWi^-=ZlWtEfQ zxn70%XYd5f<1JIuhuQZcjDJN+k zIxD3>ppi);bn~OHw~X99i}n#z>)?aLG5@edUUd`R+LH|uo;>NNthhB*VvifMJ_%r_ zoJSs3_ni>a+}}I#4dsIFRNORQLmt32@Ly(>KrO?eEVs=|rXA7~MH#coMoJGr5)D%2 z+P~&m^yEElgyzWgW}W>(@BqU)R+q7;ar5!+)P8t*J{m#fsSETU-*@M6($pybfHG*k z{zWrtJgF!D85D)atgrUZ@p-Y%=&?_s3|U1Ri;>B9M2D)VKCIp?L;8nQ`sP{QJv>!h zW@))+cl2W-Z$2mz6>N|DQjeS5CZM1VRva!>K~KKKgy>?# z^Pj%@mYp?;h!A_APz0@!I~GCPIS!)g*qbX@m=)Pa?Us@e^;BB7^1V0dy6U$(qcg9r zCFlMz-T1l!dK8Y{9T$5SaKxq`oe4f*h!0#$lID#UGQmhuxtqiA%?a@YO<*2u+%Tn+jH(lWbvID`-?8uji zN~fP~4@+HczvcR7%de zF$(_@RIH#ngZC8-#JkNcPf@Qbf+=uq1av*hSqfW|EaXEnH1_u_80$>=)u?wezmtxn zqa;Td?bOszb082x;wZ3#my?Q0i-NYTnv8qA=JUOs8SeGBWX$A1NwEdqm`aN zYi?lrvQvFjrK8s9TQV0E}bw{0mu zwoo!SPbnoH4>8V$@lL@q3_1+wX6XYtfPHm$O>PEfvII$|Qb58(tm=-~shp4oaqN5^ z0T;0}lxZZG=5agq!oB@JEI8v~8R-rllo5m_tJ&@d*M~CI)(D1YKMIbU3@F{t$XQvC zI32_Xl-g|FQ*kzY#+i)JQnL^X+#Iz*aHv5#L^PKG3JGn6IkjISATw%VVVq@G@E}oI zIb#eeFUQv?TCNT0ZB}&(fL|*@=hb>Gy$Z!CSN^)BYXWKN0j!AB@Zfb}qi1nW@o z;|FWldc!Zlz{G;qHIQXIiCY7c+p4NYk3IH`>Mc7Je}E{~1%h2a^P=uEBU0$@bIIlR znUE?BvVbxnwfST!tem7`>o`_uPn^v=L(Y4wo4%o^IX)CC6IbOb&hnuL^qLSs$)PfG!6s;Meq2t#E(U+GsbgW@f}we zYec&X+>(q(OSCguKjcaVBsxhF$8R&@%pv(QuCT_SpS2Nj9oek8SGZ8Q2Sr&lp)L%UpNE26SGJULk;I$G(TagYpds?V*;b zkXg=M*oh5L4(Z^P%9L`{rh%}7xGxoNZISM45~4Lsd^0@kzLO_g%&Fk}Yjy+??BETG zk4LslAQ~Gd7<0YIF@`u?lb=`_a;eXnj_pYchdq%WCoC90`ZV62Hw5eRq!pRQN_rN)|caqr}xWuQ>QKHeXKS0$xBby6Hz{t zk0R(eW8&_jk-58Fj=vLSRoLvW=9%B(VlZ+QJy&mmtDf%LEKGLzx6_*^+g}cj{0$1 z-&SI4RybdGf->A)J>gF;8}5U?1!Qfn{jv;+#Ee$J++ZC2n$!}B-DB5%8Pi1nC1I(G zq%(>^JpD>q8N-Cr*Z$rZiw#E8S9`)L{B4suA)taVbYp5O2JjTup;67OC~$pUM`UOs zGIFU0eKpXMAl4+YG+sJ9qRs<|r{c0NTO!;#lJLfV)?L84P4i*dh z(6TE1SYK+x?t^jv%^Zo-LVq0`atbq>5zz(QXNiGg1d2&!?D?@Qj&3VEcu4%rej1WhTEx7>Z7PG~csc zV!Uv`R#2Wzik4~_j+WBS`5+azN!(Y%4%OsC(rphiW5a6>*~1CHwIji{bL6y_{)fF! z_P>PbrbJ*fq_IFZ<*pJ(TW0i%b#MVoDOiyAY0j1JZj7~Q&Rs{ykkoIFYs>*#2G{o2Y;z(6gDV_h)6p{l(?@bE< zD-|_SBM(kmUU*c~y@vA)o$n{?VztR!CuJ@a@&bGiIEw@|vO~dx5lHmAEo{tB+#~*w zY9P%Iz(#04$*r< z0aeKoXW}a+8*Y=7J0#bGtJzj>&SM|$U`#&+Zpyko&(AEShHi*{zjZPjNCcdLB}%gf zucTNWn=s4dBjNY|T*(f0KK;yDkNj;uQ1m%Y$kdX+oU-Hu>{mEIgK&mG%TuZG_@8cg z5J_2sDCB%EOc_^oLIL@*GfF5jD`NZH%Nb3SOF^t}g@@7v{cITI)Wy32>!(Q4ps2%oNL3&Tu;|+3d!!m|uwVz}?#wDYIfZWWlk_vqp3` zibDhhW=k0>rUr>`TOihZ&?sGUjhLN`+fYzVpK4e3O9rzKDY2Vq{iga*#G){WQr$+#-$rhWVdr0Q1J|Z0EucUA-#6)iCEMZe$xWviLk=es>`}7+3%g++F6P>bUh7q zxmym{IS8};WWVT9``Vx@ZoG=On>z1*4##!A88jR0x7el9(X$l(jpN z3oIv~a4JkxaSl|(CH}>eAV%aYmXq8x=6@rn_tG5t+?xKriU`)<=0Abspp4K#RXR)L zaJPvTKe0Bx?$cc_0@d_$U0ekFbe**a{AmLQMOXM5>{XkZ*Mr`E<{ocl6^reJ+;Oy2 z;o730?@~jcWmm;JCYp4$7?S*`WUQrKG_(@H#(yhP>zi(-P!F`g&gELf7(Tm)I{$rIoP5@I+TbWq5MG zsjlhYX=dC;2OOy_i$^CYkc7=hR^CSwOU*r5yb|tIR0rWjGs2vb8a-qz9^bpT%g2}a zC;u!Q&Pca(I6nf6{qM6!D$2y6*-y8ConXZ_o>UH#Dkl=@Xd>qg)EoLlZewI47fA@6k#c4t2F7QrK@XC-)JmMpl9;@M9_Q(9{q{7Zh9$Y= zwCxMlqFL@E8|*(2U&*qpu9=QrGr7i#1S;6aT$77gBBI%0HGXbw6|Tg*Ji@F77T@o_ zVunQ74fMaAQkbE$hx~@#L`ztIso%dup$n~`5`jzYNP~X}yD~H?&ql|2BsUfmUPhRG zx+rSDu?!nQ{!Izq=AZ5^jyT3~z(N}u?ej8g;1F=Xu%y3EO|I-duK1r=>w79)7 zf=U9mj*4dZF8xr7o8VtR-7`S+`o3qcv5h&XApd2}6IL~RbKqK}#K-Y*Ox?G2l%}Nr zWL|W9uWi&`S9O1HW;v}T%0O*V$p5Guwa+iX#xV52D~EfKf0`VWF54q&kV%faQYT^uNw)=K+3n@2m$5?YOpR1~uSTPeicZSx+>E|gQg7=Zg1P$( z%b@9~e&P^UUcT223pdWMoHC2D^^=@miyW7BHvDZM?oph3gBKpJBSj1j~DX2$<>VH0|~C-O=uK||gCM-S3a z+?n%MTyI0qfiO(Ha*RZ@P4cLQLA3pI+$<32@KWlkJ*v4^*7>Es_1 z2n^GT#UGK2=#{`P!oxC9OyLg%1H)U{F9Lu%o!y5)=b+v(P)RtZ4>ZVwo+eK{MaQbM z+S1&<&>EKWqRB6*43H1v@W=qbkd@b743`L*Q%cc*zrX}55r;n*zH>;;)_nJ8qj<0B zbHDt@S7rAhH?KHu$+5kfUt|OP*8#3*5oHNW{NXNT%V&rJamM*D;k&uXo$%5?3Tr#6 zvBATY-YS;HA;)An{0nl%@C-Ny+9JzdMPtTF6u8uSZ0kXSn^5?S3Y_d4&KUOr>>+N= zLD0Fa8SzmQRnl1*y?(3QNz=JZ_#G^$gc$ZDvt)r0^2FX z<4xw6R$z%|_2eBYDTt~oqW~>th6lpq`-Hwj7V>{_R+=`+w5W>*plw^49Qk_Uu9Rti zO0aJa+3b!u*a4SO<~P^fCWxW@COP@iJ0};qiD20OC0X^L=7umBP@768K0st0;9k4M z5CN^om6qV4=c3>45tvCMXqFHNt8xzTU=g>rG6~H<+woydl7MK9_4>xx;Lcpg+AKV6 ziO1tdwiMS8xxN$07ZE~Edblhfvm8)*fT_(bc{Ar{yd)mKHiOPS))B6DdgpbqSD5~J z67dNcW6k{BJf`oYBgq0m1t_K?)qMD-ZIVdM=qwWzbB_MijrCMVJQk`+*&Pb^6CX_( zXAYO@8le@aY6wsy`4X=_f8LA$ElVCGKmt~28-NC&tPk0~rK&tdfIKddAEOQM_2z1v z^-Opr8&KZ_G;NN!eC8IFR}jE8awHto6t{*6MqGjTw+FYyg5+Hju0pEhyEcEVTJe4D!28JJ_AgfE5Xw9riDDx7t^XH zTo%WK*t`~I{E6N7iXtDaSAYh&x({8!Hf?%X(Gkk8z4i6POUGQ}U}*dL^egGkGmN){ z%!Faq8W1joe`+fsz_G5F0K_bs^LXGnSiI)DA;siu!#O zV%(RECtbVUUyV%iTS{tN>9RZ2Ak6$*<--F37N7}xpbH<37F#ggIM1&np7#qROotJ$ zkQVc?ld0s3w~jFmdMu*w6sj5;bhVq=0HoQfof!gaKzDu-%*^Mw9UWyR&<60fphV zp^<#Gn*0B9Pa1ml51q?)_+F*{Z&xdaHV+>6q`M!-cG5(jT)IYJtFKyU|0x44K8l>F=a-^r*G@o%M?AMm5{Gu6c zj{~+)w*5)L9@u(JHwa1Ca5aBFCOSO$U^l@vDtVx`ji{6=ryYpA;%M4KoPTx6B0+3G zWf^mQ4oH{Db#g0~(0#~7qA$}z=&_Be(Hq06N zJr?r;53AZ{7fi0z!X)5+1yZ$h^yj4^Q@uTJuc>l6c36mdBW5j;>DGjzXa{2J1Jo20 zGTIrtP3LQrU%mrv5RcAJU!lO{QqVIWk$>q!{C@vH{(xQRY)cplY+?N75>E6iMqZPVX4&TX^22!)i}zp6q3!A}Z`g$q{t@bv zr14=hH^sv3N(b>9C;qqU31S_kIqUz;E^zTGu6PZl_x+fSR00$6hLfr)7(cO8yIkS) z;1kgkwsUUdw*ug|o)qIiw`A~JVsVl_%IZ-<3IYws)w{Obz6QqDf&cyIix#VZ^Lqi! zq++cC`G zz+I?SAnVq$Z25I&A(N(`Srjv~bZd`m&!;iUwT zKZEt%QiX}z-xT)6-)mJNN`m~$t7x0N;htz-ctKdrR}iez5i>e^ zahKW1QPekXE|a^4o4o>Uz?3f)5|1wnW;;B3X5yQ;>|DLYK9!&T(HMt)n1I1`E8?dS zAhf=pbGq3?vqC~8$Yzoc^ILv|Ww6Uzx&uw)L8{ijXubwr({D-eipzWqh9u4j00W%p zKJo;%(Bt#vI8pQv3xi#_pObf4A+dyd*h6t^T?=+N7rImXc9+=7vY;(tTH0xm;Z4t# zLHp`Wjn2OW=Q?R0HoT{GN(uLZM?z(>Ec>3Pdh;}9uGAY(yS{+vz4bv7^ufFTPpO)@ z#7;y@)utgQ>OBuSAf?TXImoF%ihch|{dOl7iq4Fl*(${RIb9?f$llID#2?<1Ugz{B zgIkKJL`CrZN@765kHS}M=O_QoAi>703i$||5!=2l;wRBE!S|b!+b71%i z7^oTB)M9%yM^fbhfb;LP3zcBJfy!s)9P7u&`6SPuiNC0@B$sNhfD)+95X#!{8}WioK(OrleCD`cd^^LE3ia{n z7|Dxk*L&W8G+d)=`*-V?&sjWBpw@&a!XL1hiHhVrErAiSQnopIB^|eVU(zT2C~PNH zoB-HPCX;lMJhXtQ3bE#fHwOQ6LpA&j5ZJk^Le0Kqh>K_@Z3zE5Q*vx(a=p|cSW`SL zdJ`X=_u}6WKmCHZDKo@E>2aGL+cq=T?nF1VV`EX^3b2A}Qh@j!W;*^ZRtcWLh@-@J z67zvDraKFz)m48Ke0jOWF z_qV)R?cA78-5~|Co zV5kBd9KM;<01wSh$~O}w$sLBXd6^GZw+eWQ$Ob8P@!&sb!hljv^LgKPSnK@du(?s5 z=l!w2SPSdvnVGyn777M%dp7Dqtj4`&>jh-DXP~ zmwaU5*g*L42vY9-u6$mG?tZA=+fPkXA_5fJubQzV|F!Inar6c{4AUl zs<|q_)0g7@lkqGC_F@=4QGAikAom(mG?M+eG+?NDJ2Z$VmNQ}qMAc4Uk^BtDFzw0?S-fMI&H7D8vehaBZ4siJd z|BD~DV5#j^#ls^ES(5iam4G3H;oTWj#LN?i{3LMnZUg4tSV5X-h4Vo}a{b4pfo-qc z`cyf;_1}tLI5FqX>G+;PC*Lgq>k{YEdtaAOx&>;c|`P<@!+~cj!o=aDjc~uWIt+LW|up*)ZX*T+* zV24M`Xq}t*(d*dUTF-*?&OB?|U}DEn_~MsvKjI*sR;LLrXz%8#8SEec8<-Ij;hD+z z8Jb*_X#;^xY7J<>_xeTUQSphFIpErLF&n9xqxzF{?Jv?R3`jLeaJ%NS{N8f6add~+ zzg!6D%Ga)EbH5#Y`KHmS~IedObSFz)ap2wJd zuJ93s70cFYsK?V(fxLX&^spBR$vQR*pguc8rdi+V`LNsvO}wze?8=|>oUoQmXrZ%g z*iCuM=2TXl^~~|kRQ&6fUfbpkn(3=VmU;_jKi&wgP)O!(8-*9L?0aHpz6oBSUF@pd zw_5xsrt$CulV?Eh0-q-rzCoIe;k#+q;&!0;KvB)o<(bSS?HV_+*bc|YGM4T6d`~`w z*C8OU0G7J0Fc%!{LgO5fSrRZBCd z35qoJlsr!E9l`@*-KfNV*89J{6}lZYBF*r7HwyHzriczw5y!Ga$!tJ8tvU^Qr_Sl(i>2?&)OMU zj|qGD(>v+9E?Y+83YnojA) zLceM0JuHT6pbvZ#-b*;IAx6)Uu`7EJ+~fElhT3|Z@IGfl82)oOP`oI*0P6NQ0!uQE z=%n0CQg>MBr;_73^EmXoYuS&Y<{Oiv%L9azMQZ8v3jBp#T|Rs7xDpSvOg}KRNgv3fO_QkYs{|=LZy? zL&QoUonxMlIJe+Nb6UuvytSIz&==7K{ud z?3&e2b@SL9mOpVX&**pVaQkmZnu5=Tn;P#c-Lby~^l9a#BmKhqba(y38kUVII$ZQ8oK?i<|DUs@(9v#|AP z)IAuieIp~C-X4LJ)C&$O5F5ltjUXeNQ+!M&hXrrTB%SDcd(CJh9-(Zd$`x1jZhw}@ znd24ZmGI#XP~+3T27Woyub{u9tL+UP?3^ zku15A9N2IvU94GdQ!bT!q|jZZJ35Xz5*BB;lu#Z>`y{#XFF{(p`ZrCzu7ycZ_N6oB z7TGz6J_fD;Mo|QGw&!l}3Fe6p6jR>yp_a|emH*sbC3SA0tq7A@7d${QZ#!z!?8{q> zLGu<3DPN{rcXh;j>fzoPT52QDW(FDd|hw?3>get8znjwRpDUAE&CCPLmR{q z{;N3I%-bNfM&)&)H}Gm*r?3k7;*2&#%ano5T=ruNPN%=%2j~YiJrfz=3D!;d#bO6) zlX?$68 ziSh&I$3_J415EBJTLQF-?b{VlDpeCwcr#$56`bB-rA!1Xg0wR#ADr5I%eMCvT z<95`Kn7q!oA5JYuT2za2)5@MO9ibBng}x3H$@un_By}`fiS$2uNgEdBbGjfh5xmLM znX~xQ4)lW;qtVGOjt^IJfC(+M>rC~HO*}vrgSV_{Y_E08&eDOgdM}eA3>Qg6_44-# zgS*4!XruL*Pl_zQcdpRTaJ3Sc^E zkcFMmt)ALOFL}B-MKyp%zt3XO~cE??=kYqDtcBmrhnBMo_9t6fd+PMuJjD?tS(7vN5xfL2Kl|A``sj5KT6>+ z4xslk_HekkomPQP!M(%2C(kEx{3 zWhyLW4GVNr0TTHfeH?(f(r(mwN3vIETG7%(ekwuJy`gDx(|S&zkK5~)y4MRgJX`ke zdoPajB!35GNWMV5J0J)-)Dyr)qItDC|AlMt zXqb3e4EhkV@T|7A_tlrKK_(B4BT)jCbD3+ipX%w+-;ggeQzf;1_Q`cDb*4}yG6b7P zHU0{^zTR&XD9smf5fb%3!!if`ryD%~=%^3_I=iTPEx8UsLXp@-(ij%ghfQEigUEk& zdPQBm$F%hV0q>yOtIb~!dqh48+iC4Dc6r!$Y1ujEqzys6d#oS%xDDV77n|a3{9Qa; zC<>a}IelU)hCEz>M#TRUck>yyG&VLhYJWX$6xg^MN2NCz_CEUo#f*^=Zwr;#Ocj>J zvw(cJ%fP2dZpFm7RNn;;^;w7Uo^okxDL}Hy1Sq08jgR(P84fIqezk`JPn{B`iX_kz z*_?sZOX4GSQY3w`<$?~)xNdITu~nY!(Xf_FxwMO0gP0GGsD8YYdsI4VZXebk~P`bG7f5k=yx592=;6OSkrpW%43uzVEWy=JW@s*6TpCEIZhR3_T) zVpS*xh&&5Rij{KUxT5}*mb>%Vne!IRWZyjJgPk3iC>y)yFfo#)ms!UxktVRqtWgO2 z$e)tVYP^i?8!2x-xT6&tO2;lYqMOtsMs+lG4gZJ4aVDzXNhTg7^N{R>Lh#zbm}!q2 z6gD1xjDpk78^HdNMk258m{BQJe2gsM-QsT;^^2YMrZo zga7#1;2*r#ep>g9Lq?I!r8Lq3wfSyJz!G5R=p37n3vsP$Qk-yfOxRS}i8Gs-By6Zy z>Uy{!p3&aZT%LhOXk$hO|IgPW_AZq!ORyK`d7v^w57ktFng{0_34;k$GbrSoK+dHV zojFR=%)r*#+2bB%SFa+&W&WyBLN|iDcVnBb1S^2q&NcafHfn2LJKx~+{S&>Ai2dBS zd|ymGBA_W)J|NB8>@blXm8h7ML6eb=!v%`+mmf|N6(Qc7EypBiL8T?5T-fyfO#7q~ z!j)U(!{9K)&Vm;u1-gs)z1OVBE2Ti?U$A^{m7%Qa_JS zWEGt$U{7qu5`oT?N z_W04a!@%aHbHnM1IaD|G;2lws$#3f7Em}yK*$6AObxHP9VW!nr(5_PM2`e}bnkU12 z^;U4|NZE1xS*S(Zo%LTxDwdJ0IKmh-CD9hm{~CDr^hsAROBu5G6y##J)Ib) zW@22=WON)lrspwKSApnb>w&2o=iJ<}Nn3~1>Z#G73P=GUEkm}r>hpmd2Z;XqGLFEK z^8Fj8M%q9MYWG0QCv#@;A5T?qOT;~p0O*@F8C<0x#c+r6b95+d!E^c_N??m8ElR4sxk4w{%=BMB)Ev(&a0q#&Pylt`$$YO@ z(uAB{Q0p0p6>uieO7;8GQ?=o&*mv=b1Me4YWn%g%0!u7j-0Zf(xD3sVcjwjz#R#gh zmI_9MNKceFsC*eQ3Kej~^J}Dt#k5zebu)YQwWlVh6m{AwyrehLho)G{#e8{U>M; zK0sYOh7_=fzPKbMrFsO_aL;>o432&P2_Xx{0CghNbBF`Kp-5ni<-26=<@xXbNZQ1x z8qSX>iU=KOHfzBbSnx~D!tKe$y?8sX1Ss+llY7~b$XEO_lZdb2Dy2x+|nEHee?JYVCwQDQ#T%wI#k zC`O;3%ppLWrIx%=qdVJ0-8*XViC6*{YNKwaAD34~F#e04go%<|LWG>VGb4?DjFB%& ze|ruxH`qn+7TbI)BHt43EGG}C$}+%mRVNo}ZzO4%_W6!7Xj^Z}fUa*M${ct9oh7YX zy4$->$sMGtoW2jk9@oAHg!F-V#uY-l1BFE(R^>!9x16RmXkCpqdM&yXz626@6K@m<_rL@?eAH ztcv_Ro~KFaJl01N^0zvILKNG~_0lFAvgrmxi0IP8ux~XlF&JOGLJ|LyF3sxA1SYLe zo6aL5ZvHQB0<-T?dVT&tMT|btb=P@x0y_;GzJyRkV2^ym(F)1Os)H3xZno5on+$B` ztYeP*=g93j!)%$zKTP^o9!7HwQXH5OsXPGNO1`#RX=!)Tr6d43ZmZvsmvvXfdo6H?ZJzH7OXl$LT^vLY8c;xo~(X)h%KiZ@e5w9^M}s z;%CWf#JfNBN9X(I_b8PDN$fO|FiDxsOgvLcN99>8Mv|bj(vXuO5>%VmDt==dmW4Z# zRRiTR#vxHcJNnao8&B_AmdymBwZnwylk!@pnsf#vwFs_Vb2_S~g}}929J;G&jonvt zOZ2ZA>#CJ4*EPdUy4(rsP{FUzkdn#SjfKpUHrxU^Kr)6{Z{~cWd6noS5Wj%#uS!T^ z3xAFANf;)ls)SsAHEAI?nf>&4jUJ+*%?iFQMCR1VYuBQOCQ$uv8dj$ke_!{}C`NWV zcGhmAU0B+YtmlB7e#U-%*sbJlL8T-$Uv8#!JZxxl^qSPlH75osL&zB<>1X#%P)dcv zlUb=2J>W@bP7t4mNy`Q1&Jc5w$8mG|CXux8(VqODVw;^qr|@mY4W(~?$yM%4Uj%`a zw7ucnGG1LF#oCElpD3qCo(lQ8UQiDV?Zbif7)Q)7ycoVRa*YJ%dl+e#dY+55i;sss zcI(AHjuXKR3xonTci$F#IULU$aS!-;foDb_?>!d$z`)5}S17rF<^h$Q9UCrC{X`F3 zF2#6qj{zA`qk1u3i`J_>rtKNRCX=IU{{X1oq>qs{st<0oUe7zFggvAnr@fh}kD%*HiWEJMgv}!DkUL~%;%Wli27sH#6Q?KXAcySCLap`8!90enOJ% zfW@GpXKGg1?h&ma&$nTUftZ50e)h(p4>Z5%hNgr75i}waH(Gaj5L}dgH;zMxiKH7G zEzE~U5ldDm)Kw5g4@OBthU%!_h?e9@4r&iNrOkZ*z(qVtaACu9HCDRnug?Ttq2yr~ zko}{j^qn;zfPU(w#1U)G-A(Ifn?31JaMZ2l`C)^Te^u=YhvBpAJ6i<+GpUU~CzEqIpZ$DxTWkH3I~LVP-kt(&(yvv> zF&=do$M%LAf>mw85zg>BMR;vwcg5K>4~EEqcU9!ZTxvpz8G!!xP+N*h`S9xoG~QRZ zvaquY>7F@PJSdkijylAHbP{Sy7C9_O;dz@Yag8c&8wz1V_)%wr_XBIdgC(5YSD{|hVX5ii zAK>0zr}d|nI5p}@p4H28pd(JAr!PUiyy`#c^xrXTR=#nj(1IVLX^xIuc}T2$-sbph zv_h{KqKN2Vi*89lFymLGzqIIHPwBoFQJiHf#1LgsgPYslR|^6947kSNwD{v`4b>JB z{T9hnE7bp4%wDXs`Ks50$j)y%_lui`XHGY?pI65q07n!W_854wc?f$Mszl`THB@ZW z*$~I`X+*tUzBf)rgy(({1ia3%F(Qm^T6LNSpfm;k%DTa^$*2*)@DReTOA`OaVQe$~ zXpx7-(B)f#bLn*%S#(VxHCy9;FSoABWS#W-3NE!DCIWyK;F+RZu zSFUo#NiyYe2ZnCM%p=`wluMx|86P}q<=5$%k$uvYe^6NlHK}3pbS6b@vmNF1dNb(< zxR$e~1&O5ID&5F@6UVwmgI=7?2%?H`Sg-;a{|{D_6=i`VT?GF+Dpw2Z)>*`v@-|jd zE?_&Wi@o0)@bMvY-rE~*OOVS2jcwC&5Wn-WcNzGu?K9Y(WIAl_9RBgdmNnR99s21) zsEh6hf_WJQ6hL~$k;@Nk5a;scwBa2^RFe*@Si4y|(_mJuNElM}+wPj640X=}kD1l} zWN?GM8&}gbHSk5p8V=JgGJ6f#4c8~pAH-^u0gog^6+S6j^)Rj3jWlJ3Ik2`NrEPn# zm4tn76K_jxv(UCuNksK4)PhE9Y%bD}QAM z*vy0Ni@Jv+FL5~*?;8~1W5v3&WK$x=O5VFOj|8l0Jb1zV&rY{lEJR-jB$$jajzelj zj?t>vf1H_UG4C;&iI%%`a_|9|JK0Q4I${GB2hdxfa$IX#qHPfW@9cJ9UsC_+3<_^7 zHO`i8()xi0c+dB**dF-b5eNLz?TEvTIO739L+?tVzhHa;FV-IEfE8_3pX`G?1-8nfkgCwp54 zw?YNR7WCU}D~MV`AveqVwtp*t1P)WN<#<)}plEdEeB$IAw3#2jv)vmW2bECa`PATB zAx`72TM0&Os!0?mhu77)HTAdBbA?|-DoZ)B)riwEK8S*X%%*G15?0_=u3H6mQ2GyS zY>b{vIiz>c$^qO{PL)@jSqjcnlEgZEnx;w22I^uX>Toct%=0q^IF<<}p0r0zM(vZ6E z*l~4P4N+^oQ%2P6bC5^w6uDf8mr%pfu@l*Cd0Y_B+ zPmeRC4p%r#-ZMBJzJC>f!!tpk8*RKt6>M{(Yo3ZErCeB-wM9#w4m3`vy_Z)*tkCW9 zY_z%l5ogE}(nNpRd`)0Tn1U|yHBs_MOr1K?s|iO#KF$&pcFul@0BWl5H+>;$M-ejW+wAP7=eoEC;q#p28)?$Q;I*{VR4sdo6W zm1prO-ZnKvrHwKi|BRAvA4Tc3ZUp!qig^2`F6ojPAy21*rR)-W*QNfPnOiKl&+={^ z;eoTE!I+Mor(?S}5GnjAYQ5A=G+jN##m6dI@FtdCN-`#T`KOc50vjM<^1ECW9m7O< zrGvhlq#WR-#_RdJL64%*HH8|76p1-bzH%L9#N-Iny;9#$4HSqvnlv#A;hz)?YI2+^%wl6Ci!KS~rTu~TZ|*1;qSJYr*1wB0D# zq5gU^D=Rr;51zc`JKs4QmbP0!5si~lAAcN22>_kBS}{YS+^iAym@3oA2hIa5&vL@` zxTXgtQR={$IydY7UKE&LyRTs+;#r;9d1!xeTNMqkTLg$p?xiL~hwQ*|(uG*|bHIoh z-$OuMNnI);c@9fjs>jP~boU*`a|%f_5WT?C11-G&QZENm8SvAzqOUq5%p7xS18 zJ48keKRrKntV&e)CmNtyZ)v01ufvH1-%%rgRgiOZu6`lRe4_Rr zu1PX$jv%_$8=Y7~FQrps*7Iiey%Q>0_Dwb!gsJ z0AsaCB{?QUu-@YR3Ya4hF7uBK3mNARx(KvLw=3v|*duj!w)hYnMT#ISs(bQxL#+}U z@gFydx8>0F(Y)Rp4+g2`r{Wdu$FfVwK>w-rU-$x2xJaYB$o!9S^La(6t{J>DRJP0oxo#-!9kNL>Lz zQ}z#yS~pOTJI#0397fI9^CM}tL$)+?-RsLov(-d=LUe@gQaR0k`tlsTCTJc3tqCfp z$GaBp5EifH7I08yO4Z>UCZ4%$9~6V~1GnE+xh;lHx^Dn-U#7}faWP?Z>o=FV?LdsM z>ytpm|0i;**@XO&C<4)kKBe>)lSn`nt@kc@EqO`neqMq${r zU@w}5@Wx@MF|4ub<$d&KuX13s$P93(-URLcj_UBGQc0+GdZru^ z1A+40OiS!-g;}8WTrG)M09izYGpggZ=hW1=c!q|?FGx)Q9ICp&IITRG z8nFWNk}X;2%eXX$g3rz|H54iEloC_Zsb{L6J3?0d4C3t1gGwm8OK&wl1W$bEjG94^rfTwGt%b*z?fBLx`Z~$6e3XCx(2wa9-t)OZc>E73NfgDbM?4zV8B#oE^uuVcu08g5=O|L`{)oP_Kihmb%!Rss`lWvLc*gp(72QEEB z29;%H?8j<51QjY}aY1F%uTmZ&%f$vt;N=j`@H}7m>qk;sGoW;c!6lc9Q}SG4%>)LV zIwhp|W2(_3$BDPpi18H-m-qHuwZ_s3^TOXUHQvIPD3oW2NCN-4_e>;}@|1!`;?;>+Q#zmB)`tW5kG@DaQXT$hmugjyv1?lu z{Jf{R`u(tR#73xy&YeO$$FU4WyAXqJyvh6BM z)922~cmkw|6trtM75;ap*olH`_i1c?;fR4= zA+Qbxag1L?GN1br!xAcozMTN>o2>OnHlQBwer@jyKOOybl7&zpZe1I5{j^ggRg zU)5OVDwKmQMpI0Vbns8lF~%A$7Aa~=E<YZStpTqnE^0*g9FkO zr~Pctofxpi|4E8lD~?RYUVoHysZUIczeoUl;^YRE#xHLg;orX#flddB+S0E=(o=!= z{@p&r?`(1q#sg1jsf4|r$?Sae^7UXN&nT!ih};m)K~gW^RJ|J?*r>z?s^ouiJcH8+ z-ndQPo-j7a^5|k4E)P3BpSXTmP#SbB3OC}ejQQ_{^_#PVJH@moCd{N9YNRLd?RlH) z?-!?XUN@69j~qMMpQt=QGSOZhJWZRs$H}`cp>N@w3_5%(S^eF*wx|bF{A`5jFb^^b zc{{Z8sX{1%#sJrQBBx)Y%Em-4Z>s>RJDXlP;xsxB@YfOo>$y^Bs)lkPNaiSd4ps^2 zK~o}K`aL)cxdCrLKSJt^EGuYJlpJW0aX=MGH3)+<=!&w$g<+ZC_m6cq-g3v;+x^%S zXDc?vQVt&=A_^Yp=ma_Wz;&d^-X3lQdLI8R)X}uF4u91`79c0x+s; zdT#v@8p|HMVpCz77lg-9<2(fO$!3-4GQ;}Xp*VX_Q9aXnvGO$r-bjCNu?H3+ZeY{0 zBYzXb)^al=SHMGdy~2LK8Jgx>~mIViO`$?B!QBznPKBHGgcw@6}`m|4zu6fX$jfm@c#08&PZ@o@@DLjy} z+T}$vD_aqU{-8%U?ez|9X2vl5XIkt+JDnBHW&SKiiciRpgBnC136V+~Kys-b=sN0y zLb{lwL1dZBkKDkDtq$wR)Z#-n4Kh`y8hYlell%?bE=!RFF3BMG{ zeAOD6fX>ESq59=y#V0q4cp2p3l;Kr-M$?oRo@vnFbbcnb(ekxVxJOblMnR{qqQQ4K z3O<;u_cj*QJAKVMEXr#G6-RS;y(balv(ox$JNgo3rrPbI3)|SE^=rT1uZ0I8=&@Mn z1kY+_;x_SB!O~d zSD<+3AtO7$g#qMdl)R4Q4L{FgD!dAzY{BaZ$gI<-wH+$NbyUf zg*u=5vYk36|HI{SL3_rpNMGHej21Q+;3 zHK5w$i&$6(O(BKQzev$?k-PR-rN^~MwWi~~Z9q}(2~6$@NY#eUM({5S&l!2)j! z?ucEm9o$)(zx=y>QZ0e4$QuGsUHj<`$CLdyi#1sMjoMb8bn8!ZP818Z;Fr{>V6W9$ zz?WN`^1;!lhSHK}{xB>snrNa!ZpN!v0n?CC;+jjYP*~mB%W8Yf9r zzp6x|Q&N5r9F7`oL)5kwaI67;L-Caw{eRH z^XxPb$p3~R8qfDo#kQOW4(`6PQr*P;-+pVD6Ioo=J-NyQUStrmIgWC^byP4Gu0k~; z86twwaC>w-VLkc~pRoDrfIr+fOyFFWniBv$K*GPOXi!+dQbZQgZ7960I1H0FrU&*t zjCGX4VLmM81`0gV3$A9I>SDUqN|L%xdh77xDm*BF0Wr1JD(%w12V1TqzTzqZCFq(< zn(#fUVTd*t7=X6q$ZV@jo|~-li>fZfnp14YK9RMZD+LmbPU?9#{~@=7>HwCWq$bvZgcj|EwYx}tGiOZ74)c>EE| z>r|W>E2FhdHl{ZtAw`w%98Wl5BXOhM#CRj7|Z+c~r{roph$3cFnIi^<76{V`ropv*23@gUSatVreDa!dHR|=q&^fr9D%F2I$fBkQ5Xdvt6}lS8R5LhtD^e0w znwP8dWTY}<8clk*3DJdzjd#FOe|Nx!(v|NaR!b<;7Jsgdmm`Aidokk)^)+!Q8Wvm@ zM{kA1F8X2Ad>(@)Vh(pb%>bYNcK*7BWS88!pSK(FPCWJ9l}z#U(b6T8=5z9h>K43cQrZp=7Nz)MP}Hr1PWNaJbszT^!n;0wV?ob86agH>TJ>jOn?iM zmSVT&ld-;F>7yp#UtH3KFaIM-NWHXji7&G(tixf!@6&J_T5R4wR6x)|Vb}Bl!euA^ zrvko}iV>XMnD|niGl0Xi{ygs)=D&XVQA(y%^qQ&L0!j>k{FEUpdpOTL(%LP80eIcg zkhm5_Orz)cSOfB2E}1Js23Z>E0eu=_-5k|19e==`mU_yhckdm|3tF9p%a;4c?}-v> ze=g`afz2&W{|XnU}-xrp8t)Bv&2>IUWMnB7gH zdggISX_XZih4Z!DDjhkc3rLdx@{XA$O8JD`33o75DIOAToi|eZF?LpBGk6+U%3^Zq zaxc1FeG0M?00St`GbQ;>sN-L{3E3oIn0;+DxEw<_I-FY?(B+M)j!-|S8l|x<1}~leGw-c_XX0Hojz-hyTiF3p;ki0hMy$U*Cg;N!3mw1J5B!sfra1mK7nyKLv`h3 zd;(=4-?3Wp3)0h-`nqnDq~y{Dddn*;A9Xftis?8k>7W`?Oz4={hI^i9<|5qJ!s5DA z^7@1w--1otob0{x$&UM=O@)X>tJ9PS%tZL$jW!DA54MbAO4MG#g$uLS(J+2iBwMH~ zghuv<%I7woCuDda-fnr5U%J@>V*XR|0`Nx#z$d7&fGNj>o97r@)rOZ_`y~EK`6gtV)+6rA0LKc5+jaxp4z46&qW!5yb36~^#53iDRpF@ zqHBhD$oWU+F!;xKbU1Qa(03Ew)-h>jR=pXpVn) ze`-%Kb@1|x6k-;qExeB8vW6I}T048DyF8q|P#YebChflq+`-&I*wf|>Y2^_QCRhTOG)p?7g`kMa9dlQAc$w8xh&{AzEq!ZFF`ENYGB18|sbxx2JHUa0g$~2`P z%oUcS8r!G94kD{C6ec)7-No2otGK=ADK40`;%N8@kDUC1ojw;a)rnP-z3gWeeNO}| zeT^g0chEGd&vhmy=3kiD8*w7#OZxaZ78T6~e;l2$q9=)Fy+bdK%daljpBpVDIQ^kl z@-qHZb#LFb!y2C-^=EYQYCGWy@G|VrPhj$laQ|HpgtKZv<$3v@ZM_Z*>~XA~&EJ;H zQhF|U93>o*R6lX11dcfke};^UJGOW@3)uSxPS+cedlk+L2*_K#awOr1bbK}x`TXLJ zbDXzF7B$u6YOM2Ve%=6Kv4n-*(nyPMWjOa(jYyk#uJ1uSX!Gm2m|~(x_G$V;#dc^x zjOHR<*7(tUcOgy>gdpGiBjrWK1WxnAi}BK1?vxQ!i_dpG5F`Ne9zI*1Pk{EE*Swh8 zBod{Iy@-0YAu7@LEua-Ga;GGwgI{_q5ySN_Uccm*PRX^k`xnLLn+>vpXi7;4gKCKEis&a z5K(Q90_|jEYQcG#AcPN!j}bxoG*a#HUVhF1%cArHdnl_n)EV=MGxCn3 zP3u3z-LmiE?xzoew@LR?)vrWr-C8N*mEUGunZz$)j;D}n{&URA^Cj7FV0fiuWvh;s zJF6w45PTf_X}~-&k%+15P@?MJ2E4@L5l#?o8;e85@5C3r%EXa4oDP#Upp;H9e7Ar< zE5Ktxu8Mm5Bqi(cm0>|2uHT3DdP;u*yE{`xaL$HW83Cd4P~buY8?EnBjH}r#6ysGu z`5LnC%h>RUY}Ig9l%j@1g*Dak^W^En%3kn^n}KPQiC<9oXAUqN8<>Oj4S)kbZPfRs z6_pod5(Xxj3$7^U)al66T4*2QuaNeKK*?v9msi z#NS_d4W)6LzGr+kJMN2d0JP1NjR2;g=_ros+3o>sMjb#k)=r~h6Y*d`n; z@SngTXO?&NCsN-&7CtJwUa_9&sbQb2XkW8i&U--@@RE+0T9Lxr7|$j<;qrOY;n+99 z$pp^1@|t~N;UAk2ngdRSz#P_1U(O?au)jvalkp0&4cqMclzA|H*rkm=F9EdhS>$ZX z>S1qL1FgO&P4FK1&ziu6P>y56*OUG)6IiU@BL|5I0on6x9weL!#2G&^!W=sfEC{%g zEiPK)i-cCVI>0fH7v#zdfkoL-DxAYmd@${RAGz)+#DS?M$la45vM{H~lp5$|MrOak zSxKO)z1I^eD=y*$#YbL8T0yj4#}|(4ob)Ss^D)@@BEeQt5Sq;!N=2~6p@Kyw!aJ|0 zaw!t#=P%^zi>&1m_tx>cNh+-t1Hqv%m1GD1c2D)aD`Oe^I^FKpW4qT7%4yHB=Nilu z3t!p`unXR>cUj=$`e1y)e4TlhaplHPgeq-F6sQBrJB9c_QUmPeMgo%i;46_j<)bf}ww-YjOJib^ruz7-f*>5Z+yj`k#80cC9lYm5f_5S+I5WE|#q^C)Y? z(>E0AFo|s^(G53_D5{}!NXU*8G!u|eZo4X?X@S&)2O7xh2_Q!htZYsmv#K#5wN%K^ z#-;r=5q)C};vYU?k>)PHa@H|bt6SLrDMa8G%rSPRXoKK1ndW0xSF$lUf? znpiAqPrz@kVmF4RB5s3B6&4BE4pYnNHyynGg^U2`cY%kwG>%&G?vMN#8cgkEB8`XYn2A z(6>;%Z{S({Fx0l;vMpidTk7bdP|vLr?d45}XJsH>F?uRPaLcown0bnmV2ZM=6|N_}PQize^IJ5|k3mbtu~Un!ws^CBlI{Ms%wS3qRVYXDb&*L~4)`M`bG?gc z^eGMe?k4{DO79fEEW^TG*i)c0k&a1!jLFePSVIGmRn%wROa2&k3*xw=J!6>UciR|V z%R!K&$5T!}&Oqkqzh2JpXo!EQNuicE+6bS#CnsA~aZUW7);w7sHto?TSxTaKoqk79 z<;yk3Ks)$QYd&I^vbq}6U?zzAloF$=$3UPI2>=r6BqphepBp^zQtZ}^=i^F($HxRU zSjGmkik;*wAZgye&EB36dC0Q44a;fTgFw-C?-ConJ7_mR*ZLe zb(A>*A&+w*%bqqH1hzehxsW|k^|#OW#FC`z7wO`e{Hq3>5k@N4$!5T*KlD{UG^X-m z3047eH%|f5_p{!iw_#FOx!$j9J3m$Pvu9e6w3$G(ebC?y0GR_c`ddeBhK8yF@V`Js zC6b8v_jS3a7M@I7z0P}rb;JHPx{67q->5pH_#0JO&hN>+!KpW6i*b7d+LXRpA}H5H zoKg5H?RRgyC~8H&m<;A(mnO6=VzYjVZ5hS&m;<+WQx3^BH-3MVY(nH3TDZhY1rD_WcviBu^JIMMegQBZd zlJAZPV8j%#?9SJv?an9Z7Q@vPm+@k}G2A93DUD!NUa*rZoz5)fEfoJM$3l}|r2$pb+RjS+$(h|8J*^!(QoH@@0^Wm}A<5j| zwxlhBagA zsfMu~mQzv#y?)@mbL#qli)?rOg2jNZ3vyY!ZdjIhjgJ%dDjws-CO3{Wb?Shwd+|(; z4S@rqBwo^xZE?Mz{p*0QiVr|oQP^XFTMSBaZ4P&$u)7u7kS}ZOh7s8wZKsBV+zI>1 z>8a9~`*jQF`?+S1s{ela_s<)#c?@49y}~cA@0ki_ZF>_GdV`a(>at_ORkNVhr3xjV zgxRkHRr5O?w(GWHJ21MAnc?Q9~Oy_-LYdkrb3gW#(kbe7n}DugSHP zXvNM5=!EulDZigVp(j6UWTkb};alDXd1SVN3|uKxvO1+Gy3{{LSwVA)9d0c!MGcc>by3|40_cWv~> zt;)OefTyk2zJ}P7;jhHFbbFYN|9;k#HG+`#EgzbPx}>U~EWq#6$8?>hrggye(rE-R z%7(uLetck}IC1|pw$;jV=Tn23-gz4sn+Le9(u?Ybaw1yi{v=P_Ky}-}&V@eZ1fp$L2+7n zqGDHn@=(tOJ=NbYf`zvL@biqTukgG$jG9Lu499|8NiM4rT~kQjF7*=%M176dU-)k7 za=UVSp1D=qXt2I*Rp#SE-0n;aRT*<-TDhHc8pYIyJavOH3x)4eEM>ev5KW54FXdq}lmQ=5=Hp z`EYRRVDmMyidWN?HV#@;O^pLu^~K*>4=E+4p+7(%@g~)pXM<{-S;^{qTZoAon)L!_ z8}%|P2|XS z%`P-$id>&q!oCgBzI8vYj!h_EW9lncdkTnECc~_PYIPc{*ugWK*NcOS>;j0rQkW-_W>S|`!*EXroxZSaSZ$;$xq_&Ji;D%{b(uh;LLZ9#Tow5GGvF(Z zm}=^j{VJD5I_^mJ5Z*|G25<@KTI@p6R7!Ki$G_r@GjrE1xOq4x{mgY=C|0&MqQkv* zubPd745Pf`h_L<~>H}Asf?O7x9tU7>Py!mKwM;i{C1V8Jc9%4J4g^_qP;W%mr(3fZ z6Y(^}%bh{g{+yCiLE|d9yr*zWjNG^?vXUbnOULW8gEbFzuh#gIX=qB+j}k+|ZsH-B z7OtbLjD~67D)ChNr>1q2-Tn;KKuHsfOcW61bVHE)Sglk4R;NK+E{^hCtr~39{_{8% z!>s^d>T{f=Pl3*Q%jq2SQzvNkM+&vycb$C)_5yj^6Q6@6PR5!}CcD0{YQH2nTE1&{ z*nwl)P7w$6Bm^z}?#0NwXS?c(T``9{&}Z=C-sRQ_DA|!v%4V2G{bzi+xsvja`KO%} zsKq)L6h3_s+Y}wCUL-EGN$&ib3e4aWOiGxkX9FZ*X{KQkGb43StTer?WKYKt_H44> zJLuRdPMs6G1O@L|>$A}P9b8sTg|#hj<7tMj6ka2^n?M9^FMnA|lg4SpRVlS4T0>PZ8)THaiEI zeN8GS>9Qru+YaLJJ>~-s zYVFdYX(shAw*rp?7AV5dS44mNQ78QR$Ch(Wag9sn2?T9u zsaU|J*UUyVz(0mP5_QSEoh9mY#wvV`EsS2U%}&8_>cQHVvRGU6&lgLBD`DNLT68aB zgrV<=iZTEYxI1}uj=M$3RgK5KM7FbATD(nA@p~;ts+eE6fsyCAP0xtR9u!gtp@H(q zA|mjqP88>*(}tt=yAy4@eA|Lg#O#}96uI)oFnxfTpql_K#0Jr;_&O#Kb$+qwXf+SR zLU2r0mCa7hEDrW=!zSfF%Ipm1UU=xH4HDcMzB)!2s=ITdws$yb-a*D*uuDlnr#*cW zD2ez%b4n?g~I5gF5$4;>s+jV>qNr zbnt-=y9qKInM9VDt_=Rxu zE0mU}&8y642+m`S0rCFNLsB^fD}2)iynB}(4K0puyF9qqAyK&=6&$3|@=l^U zwgUMgVmb)<2ZbrZFvVoP&={oDNht$^HFSE*8%J3C)JPt$3V778I!2>93}p&>jTXsk z{`yy2KZ|iKmm;#<6(GLdisXT=m21dbe%WHz`S_AlbvN|H1Ew$vyA8>@S1i2DS$)VC zb9up<4!t_R!WL#>6Z4Nj8X2Ia&sh3e3y%n-E27&buvjj{UNmV%uFU_Px$yB29g3bA zL+qXzBca@p1OatxN0cO_>Bzx|;GVvxal)<28yBB1mTc8~=iOE0?0W}AENiBFAKEYuGR82j~|@~CYnp2xnwpt1Vmi`MYj7KOEW*yXj)$QGy} z(%A3W>XhQRH`d+?ENodfm&-p0Hs#DVbaL-64@Xgz#3I7O*e!{WMtMF~8AHn+nkWuGmNL-;`dzGDB%-OOD_7m$m>^lxfTUy>rgl z=-XtH#MSlm>lnBymC^ULzSN2D(QfkD<4jOw$!!|8YDEoGM$1T$z@%7_-A9e6tJI!h?>f}96+6#4liCMp?k5Q?5;RMPPq942Q#+jBoxRbkAh3xF^ z{Z4(S0mHq6s=-e}4hw^2BcuNz-(v_W3 zueP*0GvACUK5iQ5ocStreiHo!5d9Qu?!)jWZRrIi1S)HJwV6SK!Z;)!QKWJI{#Lhw z7W&c3;W$x$FzMT`^TU$*J@q!A(PzpSnC6(NBEuqm$+wU>SRUU+w0r333XfZAnI|?x zX{-4kW#;{BYgJVMTjw9^&d95z`ngg;{lAU{%=DMr8f~&oCor(LTK0xeI7zwJPmau0 zk33g9VZsUX?$$-RLGhC~#VOpB7PJ6Z_=&e{$OUjB{{In?C>Mx!@=BV2?Kj?knm7YM zteFzy=y^qfdVH9XLS)hMtj))>1L4puh}hGu5N5!vk!`ccTW#~0ilPBoYkb4(YJD3dD+h3*=x5?(IuJ()F6z&4m4Du0<856o?f)$XBL>G!0*_e03|>#?xZd) zWHbmOj?6SxYW9^fp96rjR*DQa!Ng=9?X!Tt^lH!fmn z9J_E(a4^YC3fHiZsbBecMZIAww+mK?Rs2etkj=@%>cxSQM=BZc6j><%%O!RK-)-S^$W*uGlg@ndzJL<-#di;B3rTQzMC>Q z?Sg;9Ob9C9cXknWzQe?KjzXC^#G$lKTm<>5A;q2Nwhp{@s^wrJF^^^NcFCS2;9Ww{ z(bDg{?qF6;BttydECXM}?17X!4 z8U~kvMd0?PgNq;dBupp$z~Ot3nbyOB|5OPMTRm!-h{>e~jxe@^}puOodWR7Gs))kUyuJBt2NL5bvhoSwG4P%aCdZ2qS9+(7CM#e41ovm+v-*lK zbv?rS;2HBIj<#GUe>gLiWdS&&Dr+QdPu~u@h}UkTZ@Z>?b5WXNozWw;PF%&FL! zq=~zUQ}!ph8D1;FH-6rovWXlGMtR1uf+4Lobs>HX!9$;RH;Xo)t<&ckW?5F!6L7qs zUO*RLL;je(nJ=4V6;};lmq$cthim8syKYx+jz5mK;6Lq|!nRN(+kO@Y$d|wh()$*7 zR+TWlgS7%DW9N)Gu(6Ayedr(X#8LsBjeA!T45bFaDpm7umU@}e6S2Fosq}*j)<0GV zD+cBz4;6ZGibLNys}B)qG2CzG8$fz&sxe`@VnyFAjRUL7aGT0n@$6AXWs5uW*@k;*4 zuX)b(9=;}JcA3`tzx=cTTitHu3eluZ9simv<@J;GYLBB$c2Ry@385FuYN$c-J9V~v zk5pN~<~89$T9r(SQFu}?+&s}D&P|U4F)V*)0N)CCEfl+c?s3t z>sex{Jh*b|c_h}D@~ zzvN3{cSJ}F_z<-94>tO{#7xIM$VOH^J=F-XdI*{tU=vCpB+1#UXx8g51}kxwI5?nZ zA(x}^%gTDUFRv-6PNq4^_W~G(pnTO}SS(K5$IJ1#60rxBx&h6vEtsIU9=?wpshAO% z+#*1}OEF04IeD0f1*zpFTy5CBE?pDrj++H`7QwMlYv}`9_ zrqw11w|*N_J!qco&heZKyymMT_SZ>9-V@8LkxISZVdYY~EHKtwK6%s>Ae2U!Ry?NO z{8SI)(Gr#sI=JmmRVl6657=qX!c>!UUIPNRI=3~NFW%R29%>`1~(+0SCjZk=MEx$cWrq~{I^w7o-qKTwHcJsS%O;4V{ zM_BWRoI7Qx7d;gyD$m|R;qB~(wGUF;B}FoJ-PIl zj=ta!8n*dX)hHtl?j0_%-W$ySXee&l{^<)gdIEp2Yx5LI)4m6&Rl z-H;n*iu8Gn--Q^*OL8n@B__RPA^`N2p-fSIi4ffIgb8E(uxoL#zi~ePia1xwy%WM8 zelT_!_wdb%B+0c@M1=lw8DNz-TT1epir9#&wQA5cwyk-5rq4aAV)E|^Z)c({S|MS9 z+sIC11Xz(8E|%n=i}<~FhQ*I1vb~)tZ)496Iw@?x7e`Co%)+ApIgm|Ul&Y@u>PluZ z+X@}CykB~XDWNazPflyp;kT<|F~#x>+9)8FVWO}Kf}}+ zmO=L&VV`NM@utctFzpYtJ8LJy_v6QYz}UhLZ6?$DdIfJL4~5gQ#V z(OI)x1qT57P01VGJG+<VT+F1GcDhcHaQ{*?3S|uKbT937w0|fFmb%03$Gip6*E+)>YRQ>*IOR~*Y zVVAf&!#o_&wn&lSD4o8-B*c1I+cuA@P=ytC*b!q9P*Pl~TFGXY6w3-n8v`d6%JGq? zxSRhih$_z@SbhffPHtfx!d8J*Ef9*ZtQkST&sV{}9rV^09-vF^Khypd9+B zbFns|#6nFsGun}jDm}}lUIwDtoY4_A(a8MoIT-BdGv{i4FYnNUj$Q#D74YOp ziGV%tdfY+}%aBdwBf*=1R%SfQUS}LEcZ$+vJA08%3vibl;FMn9(zLzw93aRbF-ut+jSkkKcI z>hTrdGW&WIG>!E-sPVuhFpYKW6;4oGf7tSW6J^Tdx9k~rs+1~7-^^^3@`R`~6a4b{ z+lk7NOcmIBW^N#0Y-h$P7zJ^8nC0(dad&70LA{ouh%Zul?;!>m^Nz^+eT#f}+nxc= zP`tMUC&v~hg+K|g$aL^om(qMVV*BQHj~-X0Oq+w|jk8~2*i{wYKQd0GTMFVeD{=I1 zs?GEs!c$)ovjKyQ4+Rsm8bj9oIC8~pRo7VxI_UZ5-Cye#{I})|WNT0J*RYaIXfrZ?(C^!lsWe|KQWr7Q29AY)eNqkf9d2*we6B}|e zbOace_@Ub$=eCP0DQ|`uyC0N{A=H27Yfjx1psWd_b)c3s3!ou8ifWSOQUVg-T`FP= zh4&3Vbk{tb#4(dxFN-Q=cQ~K2qn(EUghy=jzgH~ZUGMF2yN*i-Jvrd#nFEEDSTX|IO++&IvTd25ep<%E zlOuUb5>0h_LgwWa$3#wV8%6L{jp#HU$;({A#Yj;|@YlXh3K8#n@+*EzXJ@_k`-sAf z7&|EA^Dxn-DgNO>1lw(koT5G2pfrX0barhH-b^=9=$qCXj6DjH(gxs!$iL>0&;EgH zL>M=41!I#TyaVS1<(wyZsk~k@KUxg=l}?zd+F!E^1W`*$MP#;o>FS3VSbzrB*-_I9O#D3Cp5_Z^_jAf+8GNWz!wW~E37Idhx<3Vw~Fi|{h` zToe5g*rQJ3k504gv>n=P^<}Ay;g3k>;R9@d* z`dy(s%N6DWxF(9lRc-}V#)Yh9FQ|=xgr(nTr30$)|3}(an2$o(Sl&^K&dA%D1rFpD z1k$|*qGtPhG>_xV#{nE+YGC+ouy#HA5uUpw^S<&Ibmcfd>*9(!lmBL8_45})>eHT- zuM>>*P;O(ZAW7@39PS!`JBJO@@?`TfE$FO*GM5b=4+Z`B1vNh8%5#0;dl)T9=;r+X*w1niFH;kb3ZjV+4s?X zi5cLNvSxztNdBX;{^K5nhs;|A7HJwlw>r9Y&eW5{w>$>p=pbN~J0mi6K<; zH*v8`UE)k%29sBcfrcjn_mp8Lk0R?vHmP5bsTu@#m^_>!2IM={s1Z)LGgQdpnl~^D z9^9+o7Ry@8@L!g6B70d^m*_pL4WlvX;kOs-bm?acXj>KpZUBB9@$; zgZw1}{~;N^b~#o}Z{reDT(>JP%mLXe)aviELU-JpT|_2*cOkN~u3aH%TE>t@oZF}S zvQ@PPB-L@*w8!jT$!hbDx_>t|V}Tpfw&Kx{|C24x5F-9D?B&W-~v20Kqt5Mgpnxr<&9RasixY^pYkkl=mn3A^CaH?7}i(LBo_=HugB?B-f~V6-30&7%~qVnGgiY zqOj$_VzS`RbrycH+iVCXaB+B0H}KJ9VAdhV&pS=X(^r$<_yoU)xL^(x+4X_2Fpc7b zt%C5#%^XSTo{y!h#?0UowM=m(YL#GLq;}3|e~>zc8ScSZ20i#%sj(rXE+;?iR6{|L z(;v89^jQrl6`X-5^p)A{gyHH4b^8+Z$Vk(f>j3==TpRAKhscV1?6?m!=M5(UJKXk6 z*DlwOl0t$kgY}vty`kHMG9lk89f0WEol#Bd@)_Ktzk2)~yNmhHD{x>cuid>p{ANrQ z8tY4GA>>!ZJk8y~+mG;uzbCt;XmhRtTr|6hp{|FILHY$Z4kj11AYIl&UepYJtyNl9 zNNawlp$c|n`sqZ~{)n9wIADB*#t+dY09K@?E6x{~9oP*cM_X(`{P;`A_r{I>j6TUP zs8uG5K>aD(r#ta9CPMN{x@3k2{si%*>h|;f`cmd__W@&M9HNwUzxG+(P9^bI7|%L# zF{hXxPTK*V^6rQy-6dvRDN+!E2XF*8qkEp*$Gh{rv%Pilz} zZ^T}&)Gs1Y29nZ82%Ja^K^bAi4vO#mhUZAm$N8$1Gdku{T9$!r%dt%{+nqnezwnXu zy)^xsrHP#IfXzL1E%m%ec913H=DES!q5JO1^*z|yM=LF-hA)moYQ;EkJKXk%a1eQb zsp#@?GwalhG8>lESpTwBgq&gV#WLGT%(5yu&*6CHF*cR^+9G zTN(plBDL~olxKPLl`$TVjfHEKwyus;R(kPjBhNLty~KBJybh0ujg#kiNVorJ@NrW6 zYlNEv4u@~ZbG(&MSFBfbg1f>%v8YR{7-X{cZe~sUaO8|EO8Rw!56tVF%!X2{oThA~ zqateavd$&)v(-OctS*rpl^rlswu4z2ntRQQn4l`qTbp?t>vnY?*6J0C-I8arqW@N# zOCm+RDPM=C2kl!rWvC0-zI#>JlY4>C8r!5S6L8yRW27(aCUjraJNdi&d4QbAcXj@n`#W`?`}vFT8N_SG}QKdwav>1g@}TFGY)b8_+}X3a#l3X#odfmmKlV(*+L8N zNzK$7=W`BTJetCWJWn5B{MU}I0n`u^+bF(O5vMma%Pyv(E|HCIL+m)eIOF-XcTbO< z9+0W&y9`uw<#ldD^xGIF64OrKE7lB_Q4Bus*laSeLtV3t61*&AxmHBJq~@&@HE&?* z7`}PM5ye(dfMrWG_2{q2ittYg|0<<&X`bc8N+cwb$w={-ck+Merk_0>j_4FL3f>v!2SULAux*aRFbiE(rk`f+b)e!VP@M8me}8DeS$c z@zO-2kAGSSpK_xi&wyhNR!)QLQGig`wh{Pp>Vyn2RoY*M0I-<};F60FpVIUa8)YjP zOjF{OB3w7_TkwukN-fA(YXr{%$KUdA7P>2y4!R#^3Lp&B@*$P8=fwe-`Pov-hua$y zxt!6kg)Ct2ofxlJ_Y#$!p@p2Loxy%63v*DEVHZnOvEPnjEGa2~ctbb!wPJz4+UJ&L zO}NUFodR^?aOuGNizL(dgRKWl80Z>vQxD{FvyfV~+cOg)7iXl1(VS39Dv)Oy;TQ2Z z*W*pGC?xi`ZdsC6JZ>XiiK049OGP6_I?U5zx7!U$yl|8j1S58Se?pN%;z6D1bK?Ma z2@-n)#O%X%q`gQtR`5v3a^SR;mhFF$&J#0F?Jw*CVV-V--jT^?HCJiJjgE5m)lsNCp&i^XqLT3jWyR@qBL!fi_K6c4@aFK`5{Qx^hdmOws@4ejD;+} zjWONYiL^1BQ)Wu+q}Te|=31IJ{0a3-XZs@f6#CfnChHsWG-gh%eo`ZEgK~ElybH;Q z7l3gM$R{}^zW0{s{=2aq3i)Y1k9r_t6s>CekLeHVHAI4_@5IYV8=SHbt2F44H4JQ# zly?l1NAnd9!rJPLzpoQ}TD~G30HRMq-k|N{xc9hSMZ{SC~Msm z^Rnlix(191>-Oo34lZ;kU}8WrG2Ay#J>0TT>DanQ#19C3q{*F+q9*;6GQ)?14#0bY z<+t*}fmHbGVMMt&XF4Wf7I=frvJiEG6bZNIK|#;=(^QRFaW&s9mH(C~c7{~wdQ~!9 zv})rydtytJbmu*tgb{ZUAQ!6M=d?0CczA0^*sj54(Lj>Ah$9Lu=Q_xj;xh><=O~cx zB+C^CuqmT1DFL=&BG!Xg*8gP+r!O(XX{fj>)^-zk7C;%OqSIKkjiIdOe7}wAh{l^* zG7t_kxn>{nCx?67@$Gm~`H|zXkC>@SVhzZ4?M8k2KgY5cB*s?=A4;F6m2Bl|&Xi$7 zVy;mc$MF{LfZgE(8v>$?+cOm#V8)yMyrCW>Ok-u#Bz+)H?R@-|FhSt)JVY50S;{GqRoaf|Pr`%S-Qx`+80e#+5g<7uVCO(iBzaVkwTJ*sy7kSR zde$57rv2A*(;G12v)>?<*ws@gkJyNW9`*_>K$oGn)%@}>JhNhiMfvS)kNLkyR9!cf zk|dBq>ye$ovOWef&uRD$u{Df|w8f%ye(Igk*o=77%=|j9T`K1wu|O8sz#bEayM{j; z`DY&Z?5F-{J?7!_aY0&AS>Y9A(&WQ?R(qdQ-Tb{hw&6FyX^Oej(JoljT-P5rj!IIU z>=0mydXQ=pm&5b!&m&jZRC|yNq@DG;&eHM{z?WwwvzOLg8gl>x5gUFZ%hdCunb#$> zG^jyPBX{HZxwup!UTjmCvS3$s`aekE~m6(Z613T zE;`zw&+Qf>)aSa#f^mKi&y_u3$gXtE%95C0{*oAQK4SZ&C`E;lm@(1#*jUqN;kzU| zWMM1^TpTK8l{R<6-g*WEDP{Wc5%IVVeJP*V0?!@Ho^t9-`IopQPmqDqtwuDJV^=o# zJO;8bMl`N~D*BR_->N81$>;=jJT_LLZr+ZpI+fM}a<^n;a<9+4STq~nai1p^`07gc z8=>N8&1UR??wN!lq~JBxKS2t03vNjVl6md@DB%qHH}Iv%+n1BQ(Xw)%^)hQZ{iq4P znEbO^9^}gzlS1F8>JeuuXx{V<`yd$EAAZ{>=RQ|0Ux?5#Mm}wuKgjYox?`MIdvqgr zM8%?t^Q6fqG#^M&9B*y6apF z?AP{yW@$Q>5S(!t!G~seg4lfGN2Jmb459h4^-6m-gzHeOF0EwzTU(;;gZEZhz|O>P z>qbN7|4!374-BG6&2!6@_RaAQ!iGc@;< zhDI*)X>OCtLfJn%eGPOH^Po-5E)VGm4y|mp@@0~lQ=vDH$hW^HeKzq{r7JekfG(7!N`=47R^``7Gzp7_0ap|v#5UO&w;9RL?lg+3!a>%tI`g#6z$A3Wi+FM0^sRm z{mhAi@3Ns#HAqvkXIQzK%Yl|_BN?S0%F}?n4(Um2s66FfU`$+0GfW)t{NeeQV=;IN zER(KgC`g>uA~8U&eYE^Qv<;Ab#l}(IU1$W!TC#5M23?p-Et>-(&?tU)1;1Xpa{r z3nY&5E>MS*a&-w65i`I?O$HjvP{CCrkj-Gk7M`^NipAQ~9|_$6j0ya&VPNl=^0wOg zPzzXZm;M0a5Eu7>@~jltWYg;7?Dyu}9demoP?u+Gf`U4J&5wDm#WhLFoOW--AN|LI znQHssHSIf}z4PGPA?R256FhkX+>FAw@NKq^X}DV{+n;Z*nR4F}LZ$$ww3@L|9A|m> zerMcIN6}0d>eM{~Y|k-G$HPSTnz+@R%jp81Rx^-26VRC!DeEs6Ohsh<6A-BIJS8xZ zpl=j~DJmeP6`zHU9u|cz_}@-;OV8bMtTYj}s-O;zi(xj|1Wnm=)l%o$aC~?XEi18n zSH^21itp}}8_PG5<r}=uCERDAX0B}jQM-SvpVm&G5g`ha9uQ4yrr z{r8Beld>>@W4uS*(LZ5gR9-Z)8{9X`J?NT9J#2kEB zYYD48velO7FKuiXYF80S=sQ8cermFiD@JSK273BV)r~`>Zb7J;gQ4)@FymW0@6meb zbM$1meithR1t@wHW_#x@U<5iTxkL|e z0yxRBhC_gCbdsj@g6$fdtDSpON510;2C?zlbecGFZu-QP9P&sVX~XX7(Vd+6KS*z>Lz5tv@M#!9cF zJItE>LmGLdE0w)2besf^j+nLsm{K$^jt!=PqZv%>nGLR!Yj)1AbW7Y@{BW<4UucQd z$V$*LiH4^ZvezWbYq07LbpmBV(rRsC`cb|0=n`20p#SpSr<_xGM-f?G{=Mn)6D{VB zHlldP!2A`>c%QP{vY6btfk)%(&3_a^h7}rJz)0ht=xX{F(N-|dw*xGL}IaJ5LqZWmZYO43oN!fH3=7dRp~n;>rYrht6KpCc9bv0zio0@8o+zy#zKGS5D$U|w%w(y8{^2U2z zs)<`P7xqWq8Fik6)qYrP9I8id zJj+`7HIas8Y1HzJGU5&U(o2GHL8;xYg=y~bQz>=*X2Z^l;CRRfa0#K6>^^D$bbMsM zkC{gJ7Rg#}?6Ryhsu=tz+U>eml0kbp`LDN9SY|dHjO*QqbqfxYuBX`rD(nx6DgtUr zlEYCQmqd&LPw`KT_ZDS98dXw(bUm#7Wdj;86bIW~54~M08luOs8S9G!*g-Pc7ysP> z?JfKRH?;)sd5(FkN==LV85=(BV2KFeITl}To{ZgnU*Ap(#BWvCg3!GYnCGAiF}r9f)oDYhJ##?;milkPxn{HcFJ?wUys z3GwWs{zYhRbB52P1r67ixiB%(HI5pif^u3Zv7F1T1f^Pqb*OpCx_^W)yzXw>HrVfl z#DoB=^AH1kT&P0#I_!dn@9a;n0MsRiK5AEun4`vBszcLcX>3I40U(`9N9)dOai0(D z>xBT%F7>QfQEaFC^^{T#s(|NJd!*Xt4xI%%B2H^zY=)uqP1G^;uF4dmh98q)Fy&s- zS6yZ{WV+Xk-!Sli*2s&?&2+*iYGp{6opFhd;o&Q#N!B^>mOWrMAt0k3T4Wu=X&>s- z^}`58usv>Lk@E1+ocrp?`Y`UrU3gU_;C=4d&uY#~;_{L=8k6FFIvlp9eJsSJEwh$j z5MM|o`N%4>)YSF1XydF!W_-k<$veB*oUZktigGZEDAG?wDy5c4Z`6R9sA#EL@$W2B zvSOsmLfQSrtOrXJJu4bJ>c1pM*EeAbw~lr!li?FuKgSPv$*#KXR`zH7Fd&Xvxcrj7v>P(wk$)iFa zKhhvLy;Ha1Fj=4f=w7ZcbU5 z(d*E(Y;pY-Q5H!I3zqe7*baEVA3DnBGbREJJi=Sidy+0S;E7kxX0%{?83x;Y>~l zu1ohOT?~yV$#76h=DH!GU^|wFn_-3Sx_g}$QwUR z??C_svu0mtp%HnClES--88dt$1Gq;KoHyqP+!r*x-wUU3Ut}r-OhgBGmVK|AH`1aZ=?3F z4TLZ1jd7xPq|`n7ySJ;<&z_$`)AmK?F%)NvhNZbuSzb$bVwVwX#*|IE&&V=51Kcu5 z{85&wPo`_oe_E)#(N!4XEew6Sy`MVsC|5t>_d-FoOnQO?01*9?T@9qu6%9NdTRR%xh1zYZYM&zz4$iW7i9u*>;e z&(#8^kNIaRt3FP_t6OIRv9zdV5#IWsH5WsQGSK%nQH(e2^i!ATxH4n0Y?YO8Oo80& z^B$ThLhZxRsC(CKwqE)3ZUQ8_UeQ;?lB_^Hm?r=S2cHJR&Nj~^bU*F)B|r8lA-O(j zDQcsA?n0WL^AnL_8B;i2eGY9KZb|~VT4u*t@X)iizn|c^DKhXZ+*kp+;V{Un9+86e zD*kUnq>8tfr*u4K81_mWDV3aEweVATng0N`ln9 zKqG&o9n&{i{U9X=BLLin^ZCze&sq~I2A{>S>D?KwC}9S6G9Mra4}}tDW6`itDolz; zu7>%#6RZv>D2ZeYf*97M#1Y2XhGN+xKuh7pF_OZ=k@*3@ZS2(DZ1EQl;lOxK7(%y$ z=K=Tf=k_>gOPxHS@;*z~DJ5GIaAYAc4INrH08>!ZZ#Dnm^bvU{+LQXKf&F%{4;i1> z-)?%QcE2JYR<=mS6UD#CVMp01Bm#yZ!Uqet7F=hUu|gA|3)wgKO3DAzau4oujr&vG zC7Jb@zFprXHhoMJYoCd8Ri77p*K>|mTC^J@iw6NQf>nUDo?>WO;F`$q_btDHE1X`(?o8Ht$MY?qakak${hkdskdEOi6#n8EO@M zxv`S1rjx~1`CX+WdLN-)doAqT{3@I{*cCzCv7P2(p&#B(PUCw_4W2w)GGclfW|JNR z1O~$xko>IfYv^a;EE~#Zd>e^xMh2!PM#Fs*V6iY{P+#$hlaxX zWZqk*hZbX&s`Hf!dhfaP5u9mxCq6T*e6%sM^IiL*;Y|n$P-Ga7dvV#9HB|^BeaPa#dBT1yb|EcCO3P^n0iFWdFKDrbfhPio-Bp6c@BAjiH+8=G4d!ADtgMDJfs5F zeX35ZYgWGm39{@4l&Z_%f)Qsb*o2VPn{r=Jn#2osUZb|jA2?w&^ocikc(PvjDVhIJIdq)-Pdfi_OO_Cq)UJEA=-lbfBqDhbm1* z+|DJUbCvyf?{ER~{y}-nnFTFBn*We!Ket^n?as`hYl#o)iqtTge80Ynopf40+futO1I7HnkIbj5X2#9aR_$<=dw26Wy2KbpeQ>F|uUr@6fTR%_yfaRVK^q#=h_tX(DK}S-?=J9orj-TdCM<{g zHV9c3+J%R92k%CGTar5{L}K^AWgywmjKZj#V|n22#eDq1V`{Hlu9UTAVA8KK7M6f) zk{~h7K%dvb)Iq@e8$&7Tc*&RmtG~hR}1uo0X>zqQouLq&8U|%8iK4wHYRiyc0(kSFC>7G}%9~@sr9T07k zgS?3bBd+AXwC3Z)<74o(2dkawGLb#d!mR1_6G%nG|N2lHTEHDrNGN$S?ohr(x#{KU z<&%E1LESso#eRf~w7jdo30mOdDLNq5?qFh&6BMW}P5#SI{jnGVyLr?jk-&9Y2Eg$3 zI@#x<-iW{;a+lK}slpR}%j5=>h0GUHBhWG6`vz_=JSSfOo=SIH7k3uH4KjWUZ+_-% zMq8;1Rms1glcR1M{-e7PhB;(RbR9Q-a@j>oVz><(q`nN5&uCVw0D=-iOXlabBuTgYk4`5!Yhe`n?1hT4S>5paII~r|J z(CEbXZ~WM{@2677jA0bb$DeW z8c_xVvP^(J0Fq2n%+mR$UMgb6bLKMXE3!B$QIZdH>6iE@eU`s4pKNja_|5x0#;eMS z+BBq=;GE{H`5n9Qn^*KEaF+l&K7a3tg!WC1=*+RRqFhFuE<5H{KZ>uNP#wOe53SVZ zikvLuQH`maJ+Mug;h2%iVfBf;TzUc`P68@&UzD13B}eRSLTJcqce${tu)_9evJ61{ zz?}gi#Isn4w3Z&NYv^cwRmE*c)2p+a8MhyS1|WhVY$5amB#eZ`+CKY<0tQ*45m0fD zzU_J1uk5%;NPDQ_S6uKTBh;yAbUd)V5o_@fBh2ZP_ydL~`nQ&?PNK~P-5?m(j!4_>>`a-n5P}MNF<65SZ-X=)#Rw{>xytYCw7K$v+CS3~V=p ztMUhXa{w=URcbhR|1*tS{+cQmOOM(KkouUm`3_|C6#t~Rk?QR7)L@}N!==&P&7+XP zeIwXANnh-4%QTRZzOhj#Mfjw9#^zy!W`?WXesL~iLgNr(F7np~6WFs?ODvnXrd)xr z`!c9odFE_YfJp__6P+$J>W)~q%VfV4^{GC3(Y^5S7M!ZDSsJuNI(_6q57 zGWNOs&yxnAo^Bc8(uZy|~v9~OU?gGqO(z3{yW~DJ*-DTxIMlgDiT9}={xyt8|Xc*oO5SF+; z!`<6IHa^f&m_`myPCW@fAzGJyg$WHOLqWP0HVuo(JzCtj z4Tv`WX6=cuFty-O(|OVFy2lonDG!tq$=Enc{dql#gyxgf(s}GAY^9B=5z^7y%Mm)_ z>!EX780s+-)>)dcpeZjSyc4vMGQ__iaVe#|wPc1OS7U879m_6eP;3YTH) z5(^*dYtUwB33;FT6?S5{%1s3e1^AcqFT1XUt$OvyiE!L;NywX?$hY>D0p@4p&l5LB z{q#}*;}vqt__&NV!~^6WCI*bsH?Z;dtGr|W5KYkdeIoI@sW4eKm9X*9&pc&Jmn4PI zbUNTXQO9VQ^AL;heE{cU8PgumIb{R9OJMQ%t5aJ>{N79C>~4Hl2k3CpfVDQasdVxt8hv>1xwkurE6e@LwVbq1TPI7f#8^mMY5&LZ z1rJtM8`&u$&i}VT0me$4EoX1=+72!FlQAc)1@<=ZIm;N9E9|R10NZxSh=IGEW&S*| zk(%oLE(;Wh|9AdmHjYI#FYSCe=-N+)mJw4wzdh_{hi}5Km3hsvVdHQ{4WGrEmww#o zJfNf6{v&B23j%d&g_;t5Im8_S#?j3b+CImgnb=9g3D@^^_NiR7UNYMx-2obge`=pn zZaXiWrSHPoFE}lK`W1=NiHhTK=7U#(55jZh+gT{fh|{jw9?bZ2*=DeZUfURb-}wZqzBP*)xXR@ z1ba5H)1~rx`<3j&Jpe@E(ub@!WhbS}d5E2qgUII1ONaS| zWc>RA+pTyu=KICuN-)U4PeKy2)pBE@#`{4e^0wj3Ou$sS6+-*yobdOp*A8a>^`8+< zsk0ps?XM8+ZX3jUGS^#z3||>O%E$ZW*{uFM;rQE|qtU+l?B{(C&3r8^^`s-$#)1qA zxjZ*RHvki~=`@@gl+TVsaZJ=g1C{I1S8T8zyDFTqGEK1vZ_gGdX95xc43W2r5 zU2jUA>sKxP-h5rSYjW*5fH1O!tpGv&Ed0LaMp0x3?&1VpZp-ib@%=aa6&TCqn%d|e$f?dSBLu&3 zoXLE;idX}%6Ld02BzP4a)u&--TKF=<4U6%6$MPfUr`D8(UfrR1l>HoqXOIstPt#d zml$|X%+rliNuLbD?5tJE9rx56T#)k{dUFYO5KY_;I%-OBs@OSrsDSASi9$n(9(AfI z;W0W~%5FlCxA0t_cio+$BPGC@?R8?5>(lu1g?F3AgUB4ci$I_4p9p;aY*cAaF{s=3 zu-=AQ^niKv?GjS!Py(fM6$2{ofhniW85%6m@=yR_7$&S=d90|<6-MZQIfTZ7h>t<8 zss;P3{9a-r8$#WTh{{E820f*gf|n{{zRofS5mRK|IcbNWI9k;=l#T=k`sHS-LLU{= zxwO8uiGZ6N+c%x{w@h#CWIdWaDHL<}E($3{pz>964xR?5AMV{0dh_IMe2az<=1ZgY z;LpsRLja;M7LJw9?iz^=jA1@>8ce}C6fZR`6&Rf_S!lr4!Xnm5B?eGgih zR-eO~1!NXxm(;AqmZMoJ?LLD%{#1c5%RA|ma@JyZ)lwJIz>G|i(a`r1HWLC9Hna@^ zSC#iIPSN+u*IAednD;$rnG)R@CQv|e?_=&SARAp3`{zB4MJj6i8D+syKCnM1v3+>e zK{4alRL_f}NU&B1wU)Rn+p97ev*p7mhaQo9^HW~m%0-&&q9=%-@d9LExa-kGxj6z)GwbsD z$ERh~6YbW|%C5Ka%gn-T#}55PaS*49I|5~|Q%pgdj8HE6Oi0~OZRI}2r8O9mYt!Zp zhzl)#3G)))))VFMK6TEhD(uWs5M^>r*RZjxz#?ZyYc$e-g^(f?1nG8mpUNlp|;N7TED zF#jx;>5ZCSOq*m*NU(?004fZF0^;m0GPj?z0vb?dmyM5d>;I~6E;8i9Wltu*3&*1e zh3H4EOV16D>nqYV8h;DSP6$S%)$K8ZU^?~sXE4CMLw;Yj!B5Dyg&Wg`?&q$BR~~;3Vz4jraF-YAnyH_l9#+Qa=t_L5w8`G<@C6`+kDwYoE%N{aq9QR3 z@(X!K zS$WXXuXQmJq0%t}fqe#t9lqj^9#cqNdCV%+(%1Ls};Km0zf0NQa{_IhPPki>;A zj>sz_0J3+MeO;nq*(dQ-fBCAzXty2d-cGx4IDbElUn8?|muLS%!!7k1AZOxF|It&p zLINz=aBt80cfPTJ0GXLm$?Ryy*}L%)2lkImp{vX<>7W^8$D7$@J0-M%ikU9?{TRXM zl@03x8wQL@SqEPA@A^Ze&S#{zSVU>ukmQ8_D||{22u2H4!8$k5rPC88Gbph5F;^7- zBSEvO3Xm4;?BQEbe%sJdGWJyGC}SFQf%aRV9k zVRGsWRk@@!!GNHgnES%xj+Cp@6qAF*=P}9*U>%1$#QqGLuRbklq|Mj)j_d10_n6s! zBCrK$J6j{#PTJ4dhw&kCIknP{0~E721LfDrpY^UedU;zi3CY!-b#BPIJ%u_JuFl3I zDQl4V9VAyC#${FZdyJR~Edw)}1yOG8##}uE?6z z=+D@OO7New~L2KEj0SNQ-Mdouu3%z8N;`C_SHT6 zao*9|v=w5T(=wIRrzi_&^2`|@lwLu1dH;^{MB+CdX0gYNqgastH*20G#<$U}O;ET& zzaF>gu%NUE9Hi?W70V?7ckfX-xVj)nmvo<;-1`m;Tk*ONICvuun zWULf?#qd#otk9nQY^Md}o;fjifN~z~(%?gMO>v>QpZ}jFhMim@FGl8MmFpm10_%QI z#*^EVj|yS3ratoR&x^fQ8S8b(7$0Q)C2ncC_H3%ur9v!9*`RV8)T1_F;jW!*DAhpr zJ<@nzD)oXCF_L>3z8qFK<`2GCf|zEAO&G{JX@gK>G1N%serT}GQlYNumlm6q%L<EP0N%VDKtH z5=q=MgNjIvc9b-QSu6Xabe0k0l`1pRF5LoEc<+Q$%U0_0z^#t98fCQ;tvKl~_u09F zQ7Mnpa%;7OPZJ+fiZg z<+Emj$%=kSYy#R+=CyK@26w(VpYR>_J*_OTuNZ~0IY%RmGEvGuiQ2w2)D~WKiJTx# z6QCh|)Dr3XH2^hm9 zu-`^r_FNU6CeD)<3d2p3UmhTfNB9+}CwrFS4)?i)s1d?||CJZ`nDHCL2YYau09tq3 zBh3pCRA1o!zlp0)Wu7Wzio0}7^Yq?QQhWBoNc0I7ssl{u=@_f=^0CZ1#T{;SWDD9K zh=Q>V+pMZ7cS`1rO)EMY(Y}je7W9Z8e!5 zi3vuc2u^W>99w734JACBF>UM$X^fP;u;tDAAF!LF`3g40a>=AxItIj)+l)2z=DtVw z9$kbq)mz-B4!{Kq7)Kiat zSVmlAqg5)%{Kre@LlR&lAHI}occ^_p_?(Z5VgZjicTGL8HY{nsl&|k9&bz1nXJBrP z$}m3M!*{6Q&vY~8)aXSTDlRo9Y+|Y)seEVG1Rh#s8zrZlSI4?E^R_F>c^w+su`|lX z`2lp6;cqo zx-j4G;rubf^zMc(mZ<<9S(!E8czj;%kaFGSo)T{}5o*ayU#+j(muqXQqFlof0np!( z{V#d0A-MbY3HD%+w)UN{wT;#Hid+w~%=*(!;a~l9XQ>0yeoBMo8*0Gdw&RJ-`c0@m zHG{-t5Jv~xoPog*JP9_s&IRm^Le?o45<7K1`!_a$<7P%Oz)RYNTrTNp!4Gk^}0AF5-DWea7-ez(dv`?Tc;!%V)I>8Dg62xV7ZMx*Y z-Fu`Z(On>}LA;iJ-ujWXt1)?LjUrWCyZG||tbk3@TMO4J$*_(VXmof9ZkDn9k$H4G z27c^>$rVq>Kjm(pe4T^t>J-FmRvw7FvWuSOGVHa!4nFCTD0~GmYv66utsd&poy#dg z{|t22x$CwN@=O7yz;B>ZW-Y}i3R4#vK46rxBa6xs zF*iVG@KF8Rg3S*-!9@El+)j%%ut)vX<84;a>yRYJ6qJ=}Ne{#*qV4X<0)*NbMe72t zVv{iE+^j^gZfaDQ6IKokgNlr$BPri}!J1kw6kC4f(`!p!*K(an6p$FMepwea8P&Lq zL2hTAvu_Iql4^~Cwx17M8?u5_bE^(Hh|=fY56{aSm+N)91L?!OSUN^K0ZImTrHb=kZtR z+Y3N)@d90ey<`~2QFGnIsiq|uxf|2fFM7G1r}Av>oOEXiY9#k;9h1nhxVXb6(m|2hMY=5Xnjv<&}po~<>YUaIf{uSy*>#tCn@5JIYJdZeKi|t9xmwQ>J+k~&U zr&Qw|>Y{ejFsG4$_t>Y{{c&JL^@di{+FOD8_rb^&sG{TW=%P(G_wE#<$NH{=tAzEzbxVA*qfaRci%XN zZu<`lX6b{k7!>US$tdmxN*huJA6;ej;WT%R7q&*`=zyP@3#hxQUuED)hjrXI@m5opHnD!36m zpCl5D{`6p%s^r$O$(Gb*%q2UycVR+4=k%#=2U)^cnLm+;sJETRhU3;k9o7Ii81j@~A~I&D@=R(B0k;Nvj)RMZb~CifsjeE#<&oHk<1ZcOTO;O`d+llY<{l5#^geXdk7SV!foZ z%q*6LeGQ==W_Z01#?+wAX&@ALVvZ_=yKio|m>c&LN%M+~O*Yb$;1FB#W3~MMYIruu z&73car+i?2^WsKZgBNANp!*$R*^5DYOc|VtJV{8N3m*z*s8Iyn`2C`Nh;zsE<2E?-|yK${}pqD>?I=kO7_MGu+};V7~C* z`XJlAe+BtAonRTVAc&1e0f72DmmA9?u$hlE<7o&{P&rW(yagMfsr3gh)4QMof&8ue ztOH&6T(%1-P*EI@vaq$jDq6C)v9ELzSZ5TagqdntkW<7-n1|Kz;)kQY)z$oEYQmxP zOWE63;s+F-um3XSYhKnSI%PABX3EVObmnM8(T+5mIKhTfw$J!h?fHKT(LtrBI)J8jH<@NT>W$tcn+4akwu6MQ-~|#1C|B?#G|-+f>Wac~m40~e!$8{s zV2;r({;AgBzGtxW#xJ>+RuQBFan16+*r7ZOs5;`UO?J)&>7Xm*z*E29N0( zCtkQt^ztIN-k*sI5yoFCD|L*Lfo#aJ9{;{i$fY~Wrc}`*t%iP=LWvfrpa*kPvZ7oB zp@K=Mrt~P*HbX?v5s0zCuI5fapg{(znY!cI8Vn3gkJ?wj$&l2(>;N_n;g!r+`{ZqH zo>p!dB>DF?*^P=o+85t*+iNBpbgF9JtYdRMajR z!~D22p^)rFZpH|#*9BjGS0xA{Wq#>Gg3&dFoW`IG&ZFqdG7b{7+O6bH6A_Anr32~| zxPO{tQ(y=bvPmO4!A$)+4_!IA-Bp$*D@XTr1%ltmsJOP?sb6dHQ>8L$ywfHs0<&)l zv*xkIPJ3H(V+pbkZ7KegFkGCjvIPyZ`AxXfPXtLs!i&ii@t3xSz0W}k4qjycTbGW@ ze)RrtgG5&GNTHLoieGD}Phq#JHC+6HY12j+}sRs|aKpV+HGDXTh28Cd^ zhH&G+L;;5+w_|Y4aQJnPto5q1gVXPeNE6JE3L;sz-4~w+Y(231UW-qyQ+IPCD-(KE z-!A}AR$X69o2>Sc#rfCZ$=jPy#Ha?Hncv(`8D{36tG3-GT2S15qb3`pem$I3^P~T& z&RZh4PE!*Q{j+QK%Yr=?ITu5RQ>ML1Fd z1{))pYB;V`jSgv|+S*)Gur*(qxK9NJ3b9#Im}-KuN%m30Hs9v;k>sY1H(qQdk$A{& zO$^D+w-t{|cRgAxgZ+b)m(Yaf!r4nEmJN&)g;*+!s2`lm#49(YsHO-1GshA7S*Y6L zn)%r1^{rBWlp$r}P;&Gi1MYQpOdC~@$2N2bfi0&mirK2U$wO#nS|p&aBlI%0q^UJ^ z-cP86BNVfsW5p(qigd!H>>ybH21z-fg{tz*tq@GHi~Fp*Lf2~@RyZ2ghOAL486|+M zGp#qq)mp!*X9bhjq_D_jF(x?xOW^J5D9g0?H6kR)VmL=sb~tqXG{YfxNA6jb4~}or zgF$1_5aSj_o8+h8N0Lf7W0@wXQP!9 zg)e=eappBjmLIK_C*(6*IBhJ8Y#vB_K%XpqI?*MH?l=C;zzY;4J-DU}Z^62ude@a@Y~(!L_%-$LCj6mflk)2`7X`4ay)Uhy(R4o+c% z!BU23MXeWk-?k_UzIDzFJ@+Ax&>jRRIVBg2na*(VC}HG~$xQkBuAEJ73c zZqS3S8#mEIpYEL0P}l_b{(KHUyZ$R2P%TeBI)&-JBMV0I*_QMqe%&s;!KojT=%u>w zMDf2}FscMBHb8oUT7&00_cNCGi4{|_VNhhJlYnCCVZcKw_2ys#L?UvN{$*|NwkETA z>hI}}fq^#F9LHa9WM@U#>!<@)rj1|#*;Sbnc!-`!w{w)$01U|$qFrUf zx}fPOCiMdB6?xRT+I?3s&?C?K3XP3iH5cUFgEElhV886git21QqgXWszVk`gyv`WD z=U&;`q%Cr|Xvwh&=2Yj>8f=Me{0zR*3sDy{VklWis8gy*mH?tYdT*h5&3x#VgXA=A z3)3kUE>|>S8=6eG@LLNNX?^rctj#Qtyta)qX*PF#aqaeX7zlkoHXCKuuW4GbL;s}9 zGS$*1l83NCt=NA&W9WDd>;9r5Gmoeg155>PC_&rWfjpN`UX$(`+pA~Kg)_s@n?wny zL{e7>dhl6O)w%dxWZ>df-3Cgpduu_GqI(GwmH?!7k|c-u%jR@#K#WgWh2tZ?Dk{>W zK#4(UKI>)e#LNBT04X%#SMHJ4K3AZh16!)A(a8k>l8GlFXXUv{w@nEl`I=|H0ebBw zMf>A-_D9QJyTYB6g5bo(XtaLU7{N~EGA&1ec7aS<0GRYgkDbU1HF;+m(ZW6Xkv;kl zZ1DQAu$f~OGr}GM`hE{AE}L+0GMN2aaZb z-OY4mb;Q$l0-t;4rOK6gOcC*{8j~O+rMfWLOYH@@rEra>uz^CvASov%&Oa6l9_}mE zeIyfZ26ASw5^)ZaV~R<%1(5mBq=r!B7iqc~aHygx3r|&TY%QCrw|AQjvUM!A`VCa( zM?Kpd>Xm)~IV+Ql`eaZj_(3U4Hk)#ryEgeYOf?f*V?k`TGAHpm3@}E>lHqgELOQxtDOrOHK54 z?ahfJ$E}biOcY$Vfx$o7jD0Tu&mn`FcH4v-XqK!|?9dLe8gf zSBTvWVhXJkX9*)qJ8WkFpkEFaw9+Rv28E>qO6qw62V&1c*yb+-E*O9Va!prD*lQ3K^O64dCi0j^d$*9&`^5Z30wp7gPOuOB&KW zPgv2w1`eSB*wH(9in>1p+AeHofEW*~ba*5vU!)_Kr$}|+iGUnE9?!^Mq`@j_y)vkF zKTg`2z$5MEhcAK2<%xG)?hwP`hSi9b0_^xgx=-*Yugt|>6*lo%t{f!GKP5eef_pVq zL>T)mp^IF4T10iC+6q+($=Y*K<4#V!>18>hS!qPmRnrXQeT#*oFja|GK7Ux(T&0ci zP3Qe;thMARkv+s2dcQwjGA8zDE~*h9PQUyuEN_79;dXWg4M(k^vcC5*oor}&wjdtl z$C^&A?==%YaTC~(VHVGE8xo5j!OMWLEiGzYu+voHt+ISaH*rW|KqlQJb*f0utOF!z4W&Hs3wLncAHDK|iHk z8ce*MJhB@2YzBF>G7_js#0FX>b*V_;+V+w#xd+THaX;f6fpkWX(%(2qxe5GDAu~25 zr^vR1GUPq77dAXv z#VISVB)ESX>j*hPSaQ0CZ*8)yiA^zywu0Q#*_&LJXLa@ivNKEK#OGFDH%5aHArwc+3FU?6?_LSi;+qdATr0#ey0NC=8Ze_hZ9dGx^Q(5Ilp!@biptlO9&rVEQF9V8JhWEJw!S6={Cm zNMW|7i}Jp#qCg_!iH3Q#V%^|n zH>|V{a4-7WFHZ+M=tL}vLb~XiM*rv^l0Yj%eB`v|APC!}lr*Qoi?nxa z8?mm8@Wul3N&J&i9sT@m0G#I)HTbk&fjDnGppDY^}D)MfgG||B;<{f+!z8YM2I`q5<{_Z}9WDiTXP!?~%Y+ ztu=&~ESo-yi3AL}{a`JYc72QyoDBV-7|Q1DZ!ckj|Az+Lu$8 z{k%;YIIBW@Dyu^&3N0b1+hguMT_P{%Z>Q6OSiD9N1?y=v-k-hsClE(^B>j^L zh5J#!n|snY!*x>Q*BP2k)8#w}rFHYD_k%W+KZi>w0y#$g*Jj`Vyli88)LSlXck~H6 zLi01%Y4@j6wT4`JEC4B61o(;Dd?9O0Ggjp`*HuOe%O}=JiB3_90$$V8k=#UggaT+2 zB0917#J|-t;R*$6Pk+V%t!c68Vr`vx8>EGk_;%{;hKK} zivq3(>b?P9eNqP4Qt5x3+Lq&T!D=D{46UgQ;xUJ7pNjnfItI~xo3Mx zojf>Smk+JPRb2v^TC@a}fbCTMmh{()#`-)8QtCkL(ICmnWp)9HWd;pSP5d+Q4o-*Bmu8xVW;I(r*Fa-E@%dNo;v=$Ot*|Jh|YLjv;^ z!j!fiQ8k!R2{lp*UabyRWl8*S0PC`2=IR?z|2Ft00TTe`Er|D0?o;Uw^4{1dvQlNM2e zTd3M0&;5X!<5TOndz>Z1cYIlH-GUDo`cnc8l_Bp5>BB?DlHo@O;u@ClBJhtSeztz& zEtm|Ox+y{P1x{IhgmE;L+S+QB9O2uCh<1@kp0=GSn&H+V5acq(*2m~#Mz7c}A3qXm zbw&08qo{UbLI5j|9mgO)NDw;6=kH}ykt07mi&B5y zz_xXG{lkew#AO0N^pD_>!g)H%&a);$d)Om@1U{fCXrNe$NsVVl8F`e6eODirwW7Nm zj%TFuu#V==f7?XHl$*dL3~ML*jTb(D|SE-nUg1WrQcO1+;g|^hl=@$<(6M> zbZB~!oK3XXnPG&D?r9{^lOf=6T3^cvIK5TPM%m%*6oDN`L0kQc-II`~EOHVH{{NZf z;fL2QRei&fq9sK{Jn7RxtvPI^y2dzLR~ZzUsc~}u9Wn-z_RdP$v1j@A)HHs z#`}-&p}C@mWeDuXV#37r{C!EG%_}md06X%SgN-|=zj1A z*21~Tu6D-uAoF<2a6@j(pT=HN_s0H*=cO#pDgv!k0sb}yC4H_JYeA8k-qO2PSt9I zOyVn|o13*1PXVgbubGL5FPL~`R;t<>_ySa6O2}r%xfHKz=U&PC6m2)xNp0IkGDBXJ z2q&>hs;(dY;Sds{*H@j?K-1icYcVaEY9hyvwx1F|VW$DbTebA)bmQgJ`=GMj1!_NB zbUH1vmxrP87Bf-Ls9!w1>i4BPFBwGq0o}#dYh-H-pX6^$RCS8$uA~dhzAsA!RsUF;EP90O?sqBo zRP0TFL54#}jAz!|vf5gbjWEc5%O}@G=CKDnJSf%m$pACfUtRuImiVI3fB@-4*m=48 zS`Q_5&3eE13(w+xweDozR~-+35D#Rg&Wt=VMHf%&-|WN*s%Q8lJm~kgzXKI4&DEuT z&w3=S?HmL{5J{U|AS!fFsSkycuzh7=_*Ofit*ApPU&B82`$dJ%w%y=VJ#B^Q5J&bA zP(YMFaj}<9nJ(z`_oVan8UpbvGh>)K<&sgc>WS4_zv5e@Vk`)sPuVF*zVdRpq?9g5v>o9!l7w9w{UA z^72Mr#XZdHT3brpmcD>7tzIJrK1C~LOeA{^hQoO=XMGQO9oGblMT&bmuRP*NB%@DS z$;p#z9gD8{%lC^bkpuTqM~FXkFxfxVk}POLp?3GF=)D7Gp92aWHY8zOn^_8nN|wp3 ze55a^Qg6ZC|L=m(BvFM~2}AU3fF`%!=Y6ONLvip#+eh$E62c*&7CV4p#PF#g5aqa>My*-s-rnS0^$|&T=X`l9>Cso!)fub&s^JEBWEiE6N}^*dN6J zOJb)U)}lt8HiT14L(js|J><&tGmDh#;Tp2R%=@Y7bQJ<)#qxOl$B~Y+gWi1iKn0c$ z7;XhfLZhe-F9i#K=z%k+N~2^C3`aaxlTwU}(2HN4(-jGcwUMBNl<0L9M&1&@G|av4 zu%~pV|DCDsX~~t!N+gU>xE`RTpQW#xLo!@60`#|_`x*h~yEsKXWJnr+O`y6&j``aI z&tgva*G1+?CUv^;_kK@)Xn|XR7=GzNnX9d6K*ZH;x;l%)%%&@4AL%0Lo>j)@xo|2* zbXM;{3A)*9_|PW9zhayzt>M#Y(by+n-umlz14~stlwvNgX-x_S)Tfal5WgX0Ofk~i z&7D1)O+R|p;lI|;=A{}eG)jcQ)(RPuwA!B|U_nLQZymbvbb()Is65{`4VA{nz!c1?Yi$j`FFSqCAS(cBW8T{S@@m4S}xHF)<4LoILF0WP-QhrTBwz77(=0LMXf6cLI&0 z{-%IU)dj>G$JOPf3d(*Y-n8nKa0###&4|q)@A}q<_P2b->CHSi-+O(PD~@->z{tm` z7g$cNKDR3CUG|Rs?G(+DPGQ?}wf%4_%}iy6@ca61W0khgM#`I%Ogm!=QL6g#b>+u1 zAVS-I%H>vuxu;M8;c$1%^TtdPtFV6({A~cd_C^md;P-izH-BwMXkJ5Vg9oA+)BwyFx+9VeUCt8=JtN7TP@e=io-v=oqyz#M#8drO3FcKrS%y{<<<)|Uw5 zFQ)-)Md=*{e<|yth_wFPTA0#u!CA8}rshe{i~i;y+oV?4VS~f;Hb#P&H+L+q8c@p| zt86;&oLykYa?Tf$WrO)Q)pnC7sDvGPC*2L}jaz~I7iKU+bFI-#dJ_MoC{PvY9KDBA zAEVv<)%&=Q_uXNXRxY^fu$1oahJRk*nmd;@RbM?a1mJiKU>5N4xO=~c$9`MrP*^1U zlE2m>Q^!LXKf$D|48EUIYa=SP*mz5{T@df^c^25;*V6|@xPlU<`U-bNgw^?czigad z?;%o}Zr-t>FS<5IuiOB%ORw2W*VN7l2w}=a#lb~aZOHDZqYv8*kJ+jsYMH~x;mg`h zW1u#{2(b>X;1~1`*hs|S;s1=?5}wco`)fqpSPpxFM+?+#u1(URB~uW2j_lQ1??;hX z6V^CDwk`&OeDEvG zv6>6dV*XDhrXu879t{+e-2jh_q8RI8E-yPr%%ST zv1j-B>+E>4oCIQzTCK-^=d|`fnX*w-_=W#tZEz} z->2w2%dluaoCDq-5HO0)*2yoz+FkgPmj%OXm;cO*tIF$#24_#Kj|C8~hDoU{RbYg{ zi)q8XWK5xPoa%rR9<)S^zg*0r?8l;W!0sq3>oc!t`VJjnljr(@7FAB+D=+a)#!=c| z93ut)j&4~6R`Yt|+kABdPpnVc*⋙yu%!K&&Z_~_(McVigtWW`jCTa1ec&JA!C&O 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

+wEnnRTOOsp1gLX_i5~ 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 z zBx`N9mM>W0G>r-Cf4P63Jpf1sX4fA(=71nÐ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