Skip to content

Commit

Permalink
Merge branch 'update.domain' into update.interface
Browse files Browse the repository at this point in the history
  • Loading branch information
aoymt committed Jun 9, 2024
2 parents b3cbb83 + b5f1d8d commit fbde7f3
Show file tree
Hide file tree
Showing 9 changed files with 425 additions and 222 deletions.
173 changes: 0 additions & 173 deletions src/py2dmat/algorithm/_algorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,179 +112,6 @@ def __init_rng(self, info: py2dmat.Info) -> None:
else:
self.rng = np.random.RandomState(seed + self.mpirank * seed_delta)

def _read_param(
self, info: py2dmat.Info, num_walkers: int = 1
) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]:
"""Generate continuous data from info
Returns
=======
initial_list: np.ndarray
num_walkers \\times dimension array
min_list
max_list
unit_list
"""
if "param" not in info.algorithm:
raise exception.InputError(
"ERROR: [algorithm.param] is not defined in the input"
)
info_param = info.algorithm["param"]

if "min_list" not in info_param:
raise exception.InputError(
"ERROR: algorithm.param.min_list is not defined in the input"
)
min_list = np.array(info_param["min_list"])
if len(min_list) != self.dimension:
raise exception.InputError(
f"ERROR: len(min_list) != dimension ({len(min_list)} != {self.dimension})"
)

if "max_list" not in info_param:
raise exception.InputError(
"ERROR: algorithm.param.max_list is not defined in the input"
)
max_list = np.array(info_param["max_list"])
if len(max_list) != self.dimension:
raise exception.InputError(
f"ERROR: len(max_list) != dimension ({len(max_list)} != {self.dimension})"
)

unit_list = np.array(info_param.get("unit_list", [1.0] * self.dimension))
if len(unit_list) != self.dimension:
raise exception.InputError(
f"ERROR: len(unit_list) != dimension ({len(unit_list)} != {self.dimension})"
)

initial_list = np.array(info_param.get("initial_list", []))
if initial_list.ndim == 1:
initial_list = initial_list.reshape(1, -1)
if initial_list.size == 0:
initial_list = min_list + (max_list - min_list) * self.rng.rand(
num_walkers, self.dimension
)
# Repeat until an "initial_list" is generated
# that satisfies the constraint expression.
# If "co_a" and "co_b" are not set in [runner.limitation],
# all(isOK_judge) = true and do not repeat.
loop_count = 0
isOK_judge = np.full(num_walkers, False)
while True:
for index in np.where(~isOK_judge)[0]:
isOK_judge[index] = self.runner.limitation.judge(
initial_list[index,:]
)
if np.all(isOK_judge):
break
else:
initial_list[~isOK_judge] = (
min_list + (max_list - min_list) * self.rng.rand(
np.count_nonzero(~isOK_judge), self.dimension
) )
loop_count += 1
if initial_list.shape[0] != num_walkers:
raise exception.InputError(
f"ERROR: initial_list.shape[0] != num_walkers ({initial_list.shape[0]} != {num_walkers})"
)
if initial_list.shape[1] != self.dimension:
raise exception.InputError(
f"ERROR: initial_list.shape[1] != dimension ({initial_list.shape[1]} != {self.dimension})" )
judge_result = []
for walker_index in range(num_walkers):
judge = self.runner.limitation.judge(
initial_list[walker_index,:])
judge_result.append(judge)
if not all(judge_result):
raise exception.InputError(
"ERROR: initial_list does not satisfy the constraint formula."
)
return initial_list, min_list, max_list, unit_list

def _meshgrid(
self, info: py2dmat.Info, split: bool = False
) -> Tuple[np.ndarray, np.ndarray]:
"""Generate discrete data from info
Arguments
==========
info:
split:
if True, splits data into mpisize parts and returns mpirank-th one
(default: False)
Returns
=======
grid:
Ncandidate x dimension
id_list:
"""

if "param" not in info.algorithm:
raise exception.InputError(
"ERROR: [algorithm.param] is not defined in the input"
)
info_param = info.algorithm["param"]

if "mesh_path" in info_param:
mesh_path = (
self.root_dir / pathlib.Path(info_param["mesh_path"]).expanduser()
)
comments = info_param.get("comments", "#")
delimiter = info_param.get("delimiter", None)
skiprows = info_param.get("skiprows", 0)

data = np.loadtxt(
mesh_path, comments=comments, delimiter=delimiter, skiprows=skiprows,
)
if data.ndim == 1:
data = data.reshape(1, -1)
grid = data
else:
if "min_list" not in info_param:
raise exception.InputError(
"ERROR: algorithm.param.min_list is not defined in the input"
)
min_list = np.array(info_param["min_list"], dtype=float)
if len(min_list) != self.dimension:
raise exception.InputError(
f"ERROR: len(min_list) != dimension ({len(min_list)} != {self.dimension})"
)

if "max_list" not in info_param:
raise exception.InputError(
"ERROR: algorithm.param.max_list is not defined in the input"
)
max_list = np.array(info_param["max_list"], dtype=float)
if len(max_list) != self.dimension:
raise exception.InputError(
f"ERROR: len(max_list) != dimension ({len(max_list)} != {self.dimension})"
)

if "num_list" not in info_param:
raise exception.InputError(
"ERROR: algorithm.param.num_list is not defined in the input"
)
num_list = np.array(info_param["num_list"], dtype=int)
if len(num_list) != self.dimension:
raise exception.InputError(
f"ERROR: len(num_list) != dimension ({len(num_list)} != {self.dimension})"
)

xs = [
np.linspace(mn, mx, num=nm)
for mn, mx, nm in zip(min_list, max_list, num_list)
]
data = np.array([g.flatten() for g in np.meshgrid(*xs)]).transpose()
grid = np.array([np.hstack([i, d]) for i, d in enumerate(data)])
ncandidates = grid.shape[0]
ns_total = np.arange(ncandidates)
if split:
id_list = np.array_split(ns_total, self.mpisize)[self.mpirank]
return grid[id_list, :], id_list
else:
return grid, ns_total

def set_runner(self, runner: py2dmat.Runner) -> None:
self.runner = runner

Expand Down
13 changes: 11 additions & 2 deletions src/py2dmat/algorithm/bayes.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import numpy as np

import py2dmat
import py2dmat.domain


class Algorithm(py2dmat.algorithm.AlgorithmBase):
Expand All @@ -43,7 +44,9 @@ class Algorithm(py2dmat.algorithm.AlgorithmBase):
fx_list: List[float]
param_list: List[np.ndarray]

def __init__(self, info: py2dmat.Info, runner: py2dmat.Runner = None) -> None:
def __init__(self, info: py2dmat.Info,
runner: py2dmat.Runner = None,
domain = None) -> None:
super().__init__(info=info, runner=runner)

info_param = info.algorithm.get("param", {})
Expand All @@ -67,7 +70,13 @@ def __init__(self, info: py2dmat.Info, runner: py2dmat.Runner = None) -> None:
print(f"interval = {self.interval}")
print(f"num_rand_basis = {self.num_rand_basis}")

self.mesh_list, actions = self._meshgrid(info, split=False)
#self.mesh_list, actions = self._meshgrid(info, split=False)
if domain and isinstance(domain, py2dmat.domain.MeshGrid):
self.domain = domain
else:
self.domain = py2dmat.domain.MeshGrid(info)
self.mesh_list = np.array(self.domain.grid)

X_normalized = physbo.misc.centering(self.mesh_list[:, 1:])
comm = self.mpicomm if self.mpisize > 1 else None
self.policy = physbo.search.discrete.policy(test_X=X_normalized, comm=comm)
Expand Down
27 changes: 20 additions & 7 deletions src/py2dmat/algorithm/mapper_mpi.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,34 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see http://www.gnu.org/licenses/.

from typing import List, Union

from pathlib import Path
from io import open
import numpy as np
import os
import time

import py2dmat

import py2dmat.domain

class Algorithm(py2dmat.algorithm.AlgorithmBase):
mesh_list: np.ndarray
#mesh_list: np.ndarray
mesh_list: List[Union[int, float]]

def __init__(self, info: py2dmat.Info, runner: py2dmat.Runner = None) -> None:
def __init__(self, info: py2dmat.Info,
runner: py2dmat.Runner = None,
domain = None) -> None:
super().__init__(info=info, runner=runner)
self.mesh_list, actions = self._meshgrid(info, split=True)

if domain and isinstance(domain, py2dmat.domain.MeshGrid):
self.domain = domain
else:
self.domain = py2dmat.domain.MeshGrid(info)

self.domain.do_split()
self.mesh_list = self.domain.grid_local


def _run(self) -> None:
# Make ColorMap
Expand All @@ -51,7 +64,7 @@ def _run(self) -> None:
iterations = len(self.mesh_list)
for iteration_count, mesh in enumerate(self.mesh_list):
print("Iteration : {}/{}".format(iteration_count + 1, iterations))
print("mesh before:", mesh)
# print("mesh before:", mesh)

time_sta = time.perf_counter()
for value in mesh[1:]:
Expand All @@ -61,7 +74,7 @@ def _run(self) -> None:

# update information
args = (int(mesh[0]), 0)
x = mesh[1:]
x = np.array(mesh[1:])

time_sta = time.perf_counter()
fx = run.submit(x, args)
Expand All @@ -74,7 +87,7 @@ def _run(self) -> None:
time_end = time.perf_counter()
self.timer["run"]["file_CM"] += time_end - time_sta

print("mesh after:", mesh)
# print("mesh after:", mesh)

if iterations > 0:
fx_order = np.argsort(fx_list)
Expand Down
23 changes: 15 additions & 8 deletions src/py2dmat/algorithm/min_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from scipy.optimize import minimize

import py2dmat
import py2dmat.domain


class Algorithm(py2dmat.algorithm.AlgorithmBase):
Expand All @@ -46,16 +47,22 @@ class Algorithm(py2dmat.algorithm.AlgorithmBase):
fx_for_simplex_list: List[float]
callback_list: List[List[int]]

def __init__(self, info: py2dmat.Info, runner: py2dmat.Runner = None) -> None:
def __init__(self, info: py2dmat.Info,
runner: py2dmat.Runner = None,
domain = None) -> None:
super().__init__(info=info, runner=runner)

(
self.initial_list,
self.min_list,
self.max_list,
self.unit_list,
) = self._read_param(info)
self.initial_list = self.initial_list.flatten()
if domain and isinstance(domain, py2dmat.domain.Region):
self.domain = domain
else:
self.domain = py2dmat.domain.Region(info)

self.min_list = self.domain.min_list
self.max_list = self.domain.max_list
self.unit_list = self.domain.unit_list

self.domain.initialize(rng=self.rng, limitation=runner.limitation)
self.initial_list = self.domain.initial_list[0]

info_minimize = info.algorithm.get("minimize", {})
self.initial_scale_list = info_minimize.get(
Expand Down
Loading

0 comments on commit fbde7f3

Please sign in to comment.