pymoo 0.6.1.5.dev0__cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pymoo might be problematic. Click here for more details.
- pymoo/__init__.py +3 -0
- pymoo/algorithms/__init__.py +0 -0
- pymoo/algorithms/base/__init__.py +0 -0
- pymoo/algorithms/base/bracket.py +38 -0
- pymoo/algorithms/base/genetic.py +109 -0
- pymoo/algorithms/base/line.py +62 -0
- pymoo/algorithms/base/local.py +39 -0
- pymoo/algorithms/base/meta.py +79 -0
- pymoo/algorithms/hyperparameters.py +89 -0
- pymoo/algorithms/moo/__init__.py +0 -0
- pymoo/algorithms/moo/age.py +310 -0
- pymoo/algorithms/moo/age2.py +194 -0
- pymoo/algorithms/moo/ctaea.py +298 -0
- pymoo/algorithms/moo/dnsga2.py +76 -0
- pymoo/algorithms/moo/kgb.py +446 -0
- pymoo/algorithms/moo/moead.py +183 -0
- pymoo/algorithms/moo/nsga2.py +113 -0
- pymoo/algorithms/moo/nsga3.py +358 -0
- pymoo/algorithms/moo/pinsga2.py +370 -0
- pymoo/algorithms/moo/rnsga2.py +188 -0
- pymoo/algorithms/moo/rnsga3.py +246 -0
- pymoo/algorithms/moo/rvea.py +214 -0
- pymoo/algorithms/moo/sms.py +195 -0
- pymoo/algorithms/moo/spea2.py +190 -0
- pymoo/algorithms/moo/unsga3.py +47 -0
- pymoo/algorithms/soo/__init__.py +0 -0
- pymoo/algorithms/soo/convex/__init__.py +0 -0
- pymoo/algorithms/soo/nonconvex/__init__.py +0 -0
- pymoo/algorithms/soo/nonconvex/brkga.py +161 -0
- pymoo/algorithms/soo/nonconvex/cmaes.py +554 -0
- pymoo/algorithms/soo/nonconvex/de.py +279 -0
- pymoo/algorithms/soo/nonconvex/direct.py +149 -0
- pymoo/algorithms/soo/nonconvex/es.py +203 -0
- pymoo/algorithms/soo/nonconvex/g3pcx.py +94 -0
- pymoo/algorithms/soo/nonconvex/ga.py +93 -0
- pymoo/algorithms/soo/nonconvex/ga_niching.py +223 -0
- pymoo/algorithms/soo/nonconvex/isres.py +74 -0
- pymoo/algorithms/soo/nonconvex/nelder.py +251 -0
- pymoo/algorithms/soo/nonconvex/optuna.py +80 -0
- pymoo/algorithms/soo/nonconvex/pattern.py +183 -0
- pymoo/algorithms/soo/nonconvex/pso.py +399 -0
- pymoo/algorithms/soo/nonconvex/pso_ep.py +297 -0
- pymoo/algorithms/soo/nonconvex/random_search.py +25 -0
- pymoo/algorithms/soo/nonconvex/sres.py +56 -0
- pymoo/algorithms/soo/univariate/__init__.py +0 -0
- pymoo/algorithms/soo/univariate/backtracking.py +59 -0
- pymoo/algorithms/soo/univariate/exp.py +46 -0
- pymoo/algorithms/soo/univariate/golden.py +65 -0
- pymoo/algorithms/soo/univariate/quadr_interp.py +81 -0
- pymoo/algorithms/soo/univariate/wolfe.py +163 -0
- pymoo/config.py +33 -0
- pymoo/constraints/__init__.py +3 -0
- pymoo/constraints/adaptive.py +62 -0
- pymoo/constraints/as_obj.py +56 -0
- pymoo/constraints/as_penalty.py +41 -0
- pymoo/constraints/eps.py +26 -0
- pymoo/constraints/from_bounds.py +36 -0
- pymoo/core/__init__.py +0 -0
- pymoo/core/algorithm.py +394 -0
- pymoo/core/callback.py +38 -0
- pymoo/core/crossover.py +77 -0
- pymoo/core/decision_making.py +102 -0
- pymoo/core/decomposition.py +76 -0
- pymoo/core/duplicate.py +163 -0
- pymoo/core/evaluator.py +116 -0
- pymoo/core/indicator.py +34 -0
- pymoo/core/individual.py +784 -0
- pymoo/core/infill.py +64 -0
- pymoo/core/initialization.py +42 -0
- pymoo/core/mating.py +39 -0
- pymoo/core/meta.py +21 -0
- pymoo/core/mixed.py +165 -0
- pymoo/core/mutation.py +44 -0
- pymoo/core/operator.py +40 -0
- pymoo/core/parameters.py +134 -0
- pymoo/core/plot.py +210 -0
- pymoo/core/population.py +180 -0
- pymoo/core/problem.py +460 -0
- pymoo/core/recorder.py +99 -0
- pymoo/core/repair.py +23 -0
- pymoo/core/replacement.py +96 -0
- pymoo/core/result.py +52 -0
- pymoo/core/sampling.py +43 -0
- pymoo/core/selection.py +61 -0
- pymoo/core/solution.py +10 -0
- pymoo/core/survival.py +103 -0
- pymoo/core/termination.py +70 -0
- pymoo/core/variable.py +399 -0
- pymoo/cython/__init__.py +0 -0
- pymoo/cython/calc_perpendicular_distance.cpython-312-x86_64-linux-gnu.so +0 -0
- pymoo/cython/calc_perpendicular_distance.pyx +67 -0
- pymoo/cython/decomposition.cpython-312-x86_64-linux-gnu.so +0 -0
- pymoo/cython/decomposition.pyx +165 -0
- pymoo/cython/hv.cpython-312-x86_64-linux-gnu.so +0 -0
- pymoo/cython/hv.pyx +18 -0
- pymoo/cython/info.cpython-312-x86_64-linux-gnu.so +0 -0
- pymoo/cython/info.pyx +5 -0
- pymoo/cython/mnn.cpython-312-x86_64-linux-gnu.so +0 -0
- pymoo/cython/mnn.pyx +273 -0
- pymoo/cython/non_dominated_sorting.cpython-312-x86_64-linux-gnu.so +0 -0
- pymoo/cython/non_dominated_sorting.pyx +645 -0
- pymoo/cython/pruning_cd.cpython-312-x86_64-linux-gnu.so +0 -0
- pymoo/cython/pruning_cd.pyx +197 -0
- pymoo/cython/stochastic_ranking.cpython-312-x86_64-linux-gnu.so +0 -0
- pymoo/cython/stochastic_ranking.pyx +49 -0
- pymoo/cython/utils.pxd +129 -0
- pymoo/cython/vendor/__init__.py +0 -0
- pymoo/cython/vendor/hypervolume.cpp +1621 -0
- pymoo/cython/vendor/hypervolume.h +63 -0
- pymoo/decomposition/__init__.py +0 -0
- pymoo/decomposition/aasf.py +24 -0
- pymoo/decomposition/asf.py +10 -0
- pymoo/decomposition/pbi.py +13 -0
- pymoo/decomposition/perp_dist.py +13 -0
- pymoo/decomposition/tchebicheff.py +11 -0
- pymoo/decomposition/util.py +13 -0
- pymoo/decomposition/weighted_sum.py +8 -0
- pymoo/docs.py +187 -0
- pymoo/experimental/__init__.py +0 -0
- pymoo/experimental/algorithms/__init__.py +0 -0
- pymoo/experimental/algorithms/gde3.py +57 -0
- pymoo/gradient/__init__.py +21 -0
- pymoo/gradient/automatic.py +57 -0
- pymoo/gradient/grad_autograd.py +105 -0
- pymoo/gradient/grad_complex.py +35 -0
- pymoo/gradient/grad_jax.py +51 -0
- pymoo/gradient/toolbox/__init__.py +6 -0
- pymoo/indicators/__init__.py +0 -0
- pymoo/indicators/distance_indicator.py +55 -0
- pymoo/indicators/gd.py +7 -0
- pymoo/indicators/gd_plus.py +7 -0
- pymoo/indicators/hv/__init__.py +63 -0
- pymoo/indicators/hv/exact.py +71 -0
- pymoo/indicators/hv/exact_2d.py +102 -0
- pymoo/indicators/hv/monte_carlo.py +74 -0
- pymoo/indicators/igd.py +7 -0
- pymoo/indicators/igd_plus.py +7 -0
- pymoo/indicators/kktpm.py +151 -0
- pymoo/indicators/migd.py +55 -0
- pymoo/indicators/rmetric.py +203 -0
- pymoo/indicators/spacing.py +52 -0
- pymoo/mcdm/__init__.py +0 -0
- pymoo/mcdm/compromise_programming.py +19 -0
- pymoo/mcdm/high_tradeoff.py +40 -0
- pymoo/mcdm/pseudo_weights.py +32 -0
- pymoo/operators/__init__.py +0 -0
- pymoo/operators/control.py +187 -0
- pymoo/operators/crossover/__init__.py +0 -0
- pymoo/operators/crossover/binx.py +45 -0
- pymoo/operators/crossover/dex.py +122 -0
- pymoo/operators/crossover/erx.py +162 -0
- pymoo/operators/crossover/expx.py +51 -0
- pymoo/operators/crossover/hux.py +37 -0
- pymoo/operators/crossover/nox.py +13 -0
- pymoo/operators/crossover/ox.py +84 -0
- pymoo/operators/crossover/pcx.py +82 -0
- pymoo/operators/crossover/pntx.py +49 -0
- pymoo/operators/crossover/sbx.py +125 -0
- pymoo/operators/crossover/spx.py +5 -0
- pymoo/operators/crossover/ux.py +20 -0
- pymoo/operators/mutation/__init__.py +0 -0
- pymoo/operators/mutation/bitflip.py +17 -0
- pymoo/operators/mutation/gauss.py +58 -0
- pymoo/operators/mutation/inversion.py +42 -0
- pymoo/operators/mutation/nom.py +7 -0
- pymoo/operators/mutation/pm.py +94 -0
- pymoo/operators/mutation/rm.py +23 -0
- pymoo/operators/repair/__init__.py +0 -0
- pymoo/operators/repair/bounce_back.py +32 -0
- pymoo/operators/repair/bounds_repair.py +95 -0
- pymoo/operators/repair/inverse_penalty.py +89 -0
- pymoo/operators/repair/rounding.py +18 -0
- pymoo/operators/repair/to_bound.py +31 -0
- pymoo/operators/repair/vtype.py +11 -0
- pymoo/operators/sampling/__init__.py +0 -0
- pymoo/operators/sampling/lhs.py +73 -0
- pymoo/operators/sampling/rnd.py +50 -0
- pymoo/operators/selection/__init__.py +0 -0
- pymoo/operators/selection/rnd.py +72 -0
- pymoo/operators/selection/tournament.py +76 -0
- pymoo/operators/survival/__init__.py +0 -0
- pymoo/operators/survival/rank_and_crowding/__init__.py +1 -0
- pymoo/operators/survival/rank_and_crowding/classes.py +209 -0
- pymoo/operators/survival/rank_and_crowding/metrics.py +208 -0
- pymoo/optimize.py +72 -0
- pymoo/problems/__init__.py +157 -0
- pymoo/problems/dyn.py +47 -0
- pymoo/problems/dynamic/__init__.py +0 -0
- pymoo/problems/dynamic/cec2015.py +108 -0
- pymoo/problems/dynamic/df.py +452 -0
- pymoo/problems/dynamic/misc.py +167 -0
- pymoo/problems/functional.py +48 -0
- pymoo/problems/many/__init__.py +5 -0
- pymoo/problems/many/cdtlz.py +159 -0
- pymoo/problems/many/dcdtlz.py +88 -0
- pymoo/problems/many/dtlz.py +264 -0
- pymoo/problems/many/wfg.py +550 -0
- pymoo/problems/multi/__init__.py +14 -0
- pymoo/problems/multi/bnh.py +34 -0
- pymoo/problems/multi/carside.py +48 -0
- pymoo/problems/multi/clutch.py +104 -0
- pymoo/problems/multi/csi.py +55 -0
- pymoo/problems/multi/ctp.py +198 -0
- pymoo/problems/multi/dascmop.py +213 -0
- pymoo/problems/multi/kursawe.py +25 -0
- pymoo/problems/multi/modact.py +68 -0
- pymoo/problems/multi/mw.py +400 -0
- pymoo/problems/multi/omnitest.py +48 -0
- pymoo/problems/multi/osy.py +32 -0
- pymoo/problems/multi/srn.py +28 -0
- pymoo/problems/multi/sympart.py +94 -0
- pymoo/problems/multi/tnk.py +24 -0
- pymoo/problems/multi/truss2d.py +83 -0
- pymoo/problems/multi/welded_beam.py +41 -0
- pymoo/problems/multi/wrm.py +36 -0
- pymoo/problems/multi/zdt.py +151 -0
- pymoo/problems/multi_to_single.py +22 -0
- pymoo/problems/single/__init__.py +12 -0
- pymoo/problems/single/ackley.py +24 -0
- pymoo/problems/single/cantilevered_beam.py +34 -0
- pymoo/problems/single/flowshop_scheduling.py +112 -0
- pymoo/problems/single/g.py +874 -0
- pymoo/problems/single/griewank.py +18 -0
- pymoo/problems/single/himmelblau.py +15 -0
- pymoo/problems/single/knapsack.py +48 -0
- pymoo/problems/single/mopta08.py +26 -0
- pymoo/problems/single/multimodal.py +20 -0
- pymoo/problems/single/pressure_vessel.py +30 -0
- pymoo/problems/single/rastrigin.py +20 -0
- pymoo/problems/single/rosenbrock.py +22 -0
- pymoo/problems/single/schwefel.py +18 -0
- pymoo/problems/single/simple.py +13 -0
- pymoo/problems/single/sphere.py +19 -0
- pymoo/problems/single/traveling_salesman.py +79 -0
- pymoo/problems/single/zakharov.py +19 -0
- pymoo/problems/static.py +14 -0
- pymoo/problems/util.py +42 -0
- pymoo/problems/zero_to_one.py +27 -0
- pymoo/termination/__init__.py +23 -0
- pymoo/termination/collection.py +12 -0
- pymoo/termination/cv.py +48 -0
- pymoo/termination/default.py +45 -0
- pymoo/termination/delta.py +64 -0
- pymoo/termination/fmin.py +16 -0
- pymoo/termination/ftol.py +144 -0
- pymoo/termination/indicator.py +49 -0
- pymoo/termination/max_eval.py +14 -0
- pymoo/termination/max_gen.py +15 -0
- pymoo/termination/max_time.py +20 -0
- pymoo/termination/robust.py +34 -0
- pymoo/termination/xtol.py +33 -0
- pymoo/util/__init__.py +0 -0
- pymoo/util/archive.py +150 -0
- pymoo/util/cache.py +29 -0
- pymoo/util/clearing.py +82 -0
- pymoo/util/display/__init__.py +0 -0
- pymoo/util/display/column.py +52 -0
- pymoo/util/display/display.py +34 -0
- pymoo/util/display/multi.py +96 -0
- pymoo/util/display/output.py +53 -0
- pymoo/util/display/progress.py +54 -0
- pymoo/util/display/single.py +67 -0
- pymoo/util/dominator.py +67 -0
- pymoo/util/function_loader.py +129 -0
- pymoo/util/hv.py +23 -0
- pymoo/util/matlab_engine.py +39 -0
- pymoo/util/misc.py +460 -0
- pymoo/util/mnn.py +70 -0
- pymoo/util/nds/__init__.py +0 -0
- pymoo/util/nds/dominance_degree_non_dominated_sort.py +159 -0
- pymoo/util/nds/efficient_non_dominated_sort.py +152 -0
- pymoo/util/nds/fast_non_dominated_sort.py +70 -0
- pymoo/util/nds/naive_non_dominated_sort.py +36 -0
- pymoo/util/nds/non_dominated_sorting.py +67 -0
- pymoo/util/nds/tree_based_non_dominated_sort.py +133 -0
- pymoo/util/normalization.py +312 -0
- pymoo/util/optimum.py +42 -0
- pymoo/util/plotting.py +177 -0
- pymoo/util/pruning_cd.py +89 -0
- pymoo/util/randomized_argsort.py +60 -0
- pymoo/util/ref_dirs/__init__.py +24 -0
- pymoo/util/ref_dirs/construction.py +88 -0
- pymoo/util/ref_dirs/das_dennis.py +52 -0
- pymoo/util/ref_dirs/energy.py +319 -0
- pymoo/util/ref_dirs/energy_layer.py +119 -0
- pymoo/util/ref_dirs/genetic_algorithm.py +63 -0
- pymoo/util/ref_dirs/incremental.py +68 -0
- pymoo/util/ref_dirs/misc.py +128 -0
- pymoo/util/ref_dirs/optimizer.py +59 -0
- pymoo/util/ref_dirs/performance.py +162 -0
- pymoo/util/ref_dirs/reduction.py +85 -0
- pymoo/util/ref_dirs/sample_and_map.py +24 -0
- pymoo/util/reference_direction.py +260 -0
- pymoo/util/remote.py +55 -0
- pymoo/util/roulette.py +27 -0
- pymoo/util/running_metric.py +128 -0
- pymoo/util/sliding_window.py +25 -0
- pymoo/util/stochastic_ranking.py +32 -0
- pymoo/util/value_functions.py +719 -0
- pymoo/util/vectors.py +40 -0
- pymoo/util/vf_dominator.py +99 -0
- pymoo/vendor/__init__.py +0 -0
- pymoo/vendor/cec2018.py +398 -0
- pymoo/vendor/gta.py +617 -0
- pymoo/vendor/hv.py +267 -0
- pymoo/vendor/vendor_cmaes.py +412 -0
- pymoo/vendor/vendor_coco.py +81 -0
- pymoo/vendor/vendor_scipy.py +232 -0
- pymoo/version.py +1 -0
- pymoo/visualization/__init__.py +8 -0
- pymoo/visualization/fitness_landscape.py +127 -0
- pymoo/visualization/heatmap.py +123 -0
- pymoo/visualization/pcp.py +120 -0
- pymoo/visualization/petal.py +91 -0
- pymoo/visualization/radar.py +108 -0
- pymoo/visualization/radviz.py +68 -0
- pymoo/visualization/scatter.py +150 -0
- pymoo/visualization/star_coordinate.py +75 -0
- pymoo/visualization/util.py +123 -0
- pymoo/visualization/video/__init__.py +0 -0
- pymoo/visualization/video/callback_video.py +82 -0
- pymoo/visualization/video/one_var_one_obj.py +57 -0
- pymoo/visualization/video/two_var_one_obj.py +62 -0
- pymoo-0.6.1.5.dev0.dist-info/METADATA +187 -0
- pymoo-0.6.1.5.dev0.dist-info/RECORD +328 -0
- pymoo-0.6.1.5.dev0.dist-info/WHEEL +6 -0
- pymoo-0.6.1.5.dev0.dist-info/licenses/LICENSE +191 -0
- pymoo-0.6.1.5.dev0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from pymoo.core.problem import Problem
|
|
6
|
+
from pymoo.util.remote import Remote
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class COCOProblem(Problem):
|
|
10
|
+
|
|
11
|
+
def __init__(self, name, n_var=10, pf_from_file=True, **kwargs):
|
|
12
|
+
self.function, self.instance, self.object = get_bbob(name, n_var)
|
|
13
|
+
self.name = name
|
|
14
|
+
self.pf_from_file = pf_from_file
|
|
15
|
+
|
|
16
|
+
coco = self.object
|
|
17
|
+
n_var, n_obj, n_ieq_constr = coco.number_of_variables, coco.number_of_objectives, coco.number_of_constraints
|
|
18
|
+
xl, xu = coco.lower_bounds, coco.upper_bounds
|
|
19
|
+
|
|
20
|
+
super().__init__(n_var=n_var,
|
|
21
|
+
n_obj=n_obj,
|
|
22
|
+
n_ieq_constr=n_ieq_constr,
|
|
23
|
+
xl=xl,
|
|
24
|
+
xu=xu,
|
|
25
|
+
**kwargs)
|
|
26
|
+
|
|
27
|
+
def _calc_pareto_set(self, *args, **kwargs):
|
|
28
|
+
if self.n_obj == 1:
|
|
29
|
+
fname = '._bbob_problem_best_parameter.txt'
|
|
30
|
+
|
|
31
|
+
self.object._best_parameter(what="print")
|
|
32
|
+
ps = np.loadtxt(fname)
|
|
33
|
+
os.remove(fname)
|
|
34
|
+
|
|
35
|
+
return ps
|
|
36
|
+
|
|
37
|
+
def _calc_pareto_front(self, *args, **kwargs):
|
|
38
|
+
if self.pf_from_file:
|
|
39
|
+
return Remote.get_instance().load("pymoo", "pf", "bbob.pf", to="json")[str(self.function)][str(self.instance)]
|
|
40
|
+
else:
|
|
41
|
+
ps = self.pareto_set()
|
|
42
|
+
if ps is not None:
|
|
43
|
+
return self.evaluate(ps)
|
|
44
|
+
|
|
45
|
+
def _evaluate(self, X, out, *args, **kwargs):
|
|
46
|
+
out["F"] = np.array([self.object(x) for x in X])
|
|
47
|
+
|
|
48
|
+
def __getstate__(self):
|
|
49
|
+
d = self.__dict__.copy()
|
|
50
|
+
d["object"] = None
|
|
51
|
+
return d
|
|
52
|
+
|
|
53
|
+
def __setstate__(self, d):
|
|
54
|
+
self.__dict__.update(d)
|
|
55
|
+
self.object = get_bbob(self.name, self.n_var)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def get_bbob(name, n_var=10, **kwargs):
|
|
59
|
+
try:
|
|
60
|
+
import cocoex as ex
|
|
61
|
+
except:
|
|
62
|
+
raise Exception("COCO test suite not found. \nInstallation Guide: https://github.com/numbbo/coco")
|
|
63
|
+
|
|
64
|
+
args = name.split("-")
|
|
65
|
+
|
|
66
|
+
n_instance = int(args[-1])
|
|
67
|
+
n_function = int(args[-2].replace("f", ""))
|
|
68
|
+
|
|
69
|
+
assert 1 <= n_function <= 24, f"BBOB has 24 different functions to be chosen. {n_function} is out of range."
|
|
70
|
+
|
|
71
|
+
suite_filter_options = f"function_indices: {n_function} " \
|
|
72
|
+
f"instance_indices: {n_instance} " \
|
|
73
|
+
f"dimensions: {n_var}"
|
|
74
|
+
|
|
75
|
+
problems = ex.Suite("bbob", "", suite_filter_options)
|
|
76
|
+
assert len(problems) == 1, "COCO problem not found."
|
|
77
|
+
|
|
78
|
+
coco = problems.next_problem()
|
|
79
|
+
|
|
80
|
+
return n_function, n_instance, coco
|
|
81
|
+
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
|
|
2
|
+
from pymoo.core.termination import NoTermination
|
|
3
|
+
from pymoo.termination.max_eval import MaximumFunctionCallTermination
|
|
4
|
+
from pymoo.util.display.single import SingleObjectiveOutput
|
|
5
|
+
|
|
6
|
+
try:
|
|
7
|
+
from scipy.optimize import minimize as scipy_minimize, NonlinearConstraint, LinearConstraint
|
|
8
|
+
except:
|
|
9
|
+
raise Exception("Please install SciPy: pip install scipy")
|
|
10
|
+
|
|
11
|
+
import warnings
|
|
12
|
+
|
|
13
|
+
import numpy as np
|
|
14
|
+
|
|
15
|
+
from pymoo.algorithms.base.local import LocalSearch
|
|
16
|
+
from pymoo.core.individual import Individual, constr_to_cv
|
|
17
|
+
from pymoo.core.population import Population
|
|
18
|
+
|
|
19
|
+
from pymoo.termination.max_gen import MaximumGenerationTermination
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
# ---------------------------------------------------------------------------------------------------------
|
|
24
|
+
# Interface
|
|
25
|
+
# ---------------------------------------------------------------------------------------------------------
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class Optimizer(LocalSearch):
|
|
29
|
+
|
|
30
|
+
def __init__(self, method, with_bounds=False, with_constr=False, require_jac=False,
|
|
31
|
+
use_bounds=True, use_constr=True, estm_gradients=True, disp=False, show_warnings=False, **kwargs):
|
|
32
|
+
|
|
33
|
+
super().__init__(output=SingleObjectiveOutput(), **kwargs)
|
|
34
|
+
|
|
35
|
+
self.method, self.with_bounds, self.with_constr, self.require_jac = method, with_bounds, with_constr, require_jac
|
|
36
|
+
self.show_warnings = show_warnings
|
|
37
|
+
self.use_bounds = use_bounds
|
|
38
|
+
self.use_constr = use_constr
|
|
39
|
+
self.estm_gradients = estm_gradients
|
|
40
|
+
|
|
41
|
+
self.options = {
|
|
42
|
+
'maxiter': int(1e8), # because of C code interfacing this can not be inf
|
|
43
|
+
'disp': disp}
|
|
44
|
+
|
|
45
|
+
def _setup(self, problem, **kwargs):
|
|
46
|
+
if isinstance(self.termination, MaximumGenerationTermination):
|
|
47
|
+
self.options["maxiter"] = self.termination.n_max_gen
|
|
48
|
+
elif isinstance(self.termination, MaximumFunctionCallTermination):
|
|
49
|
+
self.options["maxfev"] = self.termination.n_max_evals
|
|
50
|
+
|
|
51
|
+
self.termination = NoTermination()
|
|
52
|
+
self.return_least_infeasible = True
|
|
53
|
+
|
|
54
|
+
def _advance(self, **kwargs):
|
|
55
|
+
problem, evaluator = self.problem, self.evaluator
|
|
56
|
+
|
|
57
|
+
# add the box constraints defined in the problem
|
|
58
|
+
bounds = None
|
|
59
|
+
if self.use_bounds:
|
|
60
|
+
|
|
61
|
+
xl, xu = self.problem.bounds()
|
|
62
|
+
if self.with_bounds:
|
|
63
|
+
bounds = np.column_stack([xl, xu])
|
|
64
|
+
else:
|
|
65
|
+
if xl is not None or xu is not None:
|
|
66
|
+
raise Exception(f"Error: Boundary constraints can not be handled by {self.method}")
|
|
67
|
+
|
|
68
|
+
# define the actual constraints if supported by the algorithm
|
|
69
|
+
constr = []
|
|
70
|
+
if self.use_constr:
|
|
71
|
+
|
|
72
|
+
constr = [LinearConstraint(np.eye(self.problem.n_var), xl, xu)]
|
|
73
|
+
|
|
74
|
+
if problem.has_constraints():
|
|
75
|
+
|
|
76
|
+
if self.with_constr:
|
|
77
|
+
def fun_constr(x):
|
|
78
|
+
g = problem.evaluate(x, return_values_of=["G"])
|
|
79
|
+
cv = constr_to_cv(g)
|
|
80
|
+
return cv
|
|
81
|
+
|
|
82
|
+
non_lin_constr = NonlinearConstraint(fun_constr, -float("inf"), 0)
|
|
83
|
+
|
|
84
|
+
constr.append(non_lin_constr)
|
|
85
|
+
|
|
86
|
+
else:
|
|
87
|
+
raise Exception(f"Error: Constraint handling is not supported by {self.method}")
|
|
88
|
+
|
|
89
|
+
# the objective function to be optimized and add gradients if available
|
|
90
|
+
if self.estm_gradients:
|
|
91
|
+
jac = None
|
|
92
|
+
|
|
93
|
+
def fun_obj(x):
|
|
94
|
+
f = problem.evaluate(x, return_values_of=["F"])[0]
|
|
95
|
+
evaluator.n_eval += 1
|
|
96
|
+
return f
|
|
97
|
+
|
|
98
|
+
else:
|
|
99
|
+
jac = True
|
|
100
|
+
|
|
101
|
+
def fun_obj(x):
|
|
102
|
+
f, df = problem.evaluate(x, return_values_of=["F", "dF"])
|
|
103
|
+
|
|
104
|
+
if df is None:
|
|
105
|
+
raise Exception("If the gradient shall not be estimate, please set out['dF'] in _evaluate. ")
|
|
106
|
+
|
|
107
|
+
evaluator.n_eval += 1
|
|
108
|
+
return f[0], df[0]
|
|
109
|
+
|
|
110
|
+
# the arguments to be used
|
|
111
|
+
kwargs = dict(args=(), method=self.method, bounds=bounds, constraints=constr, jac=jac, options=self.options)
|
|
112
|
+
|
|
113
|
+
# the starting solution found by sampling beforehand
|
|
114
|
+
x0 = self.opt[0].X
|
|
115
|
+
|
|
116
|
+
# actually run the optimization
|
|
117
|
+
if not self.show_warnings:
|
|
118
|
+
warnings.simplefilter("ignore")
|
|
119
|
+
|
|
120
|
+
res = scipy_minimize(fun_obj, x0, **kwargs)
|
|
121
|
+
|
|
122
|
+
opt = Population.create(Individual(X=res.x))
|
|
123
|
+
self.evaluator.eval(self.problem, opt, algorithm=self)
|
|
124
|
+
|
|
125
|
+
self.pop, self.off = opt, opt
|
|
126
|
+
|
|
127
|
+
self.termination.force_termination = True
|
|
128
|
+
|
|
129
|
+
if hasattr("res", "nit"):
|
|
130
|
+
self.n_gen = res.nit + 1
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
# ---------------------------------------------------------------------------------------------------------
|
|
134
|
+
# Object Oriented Interface
|
|
135
|
+
# ---------------------------------------------------------------------------------------------------------
|
|
136
|
+
|
|
137
|
+
# +++++++++++++++++++++++++++++++++++++++++
|
|
138
|
+
# UNCONSTRAINED
|
|
139
|
+
# +++++++++++++++++++++++++++++++++++++++++
|
|
140
|
+
|
|
141
|
+
class NelderMead(Optimizer):
|
|
142
|
+
|
|
143
|
+
def __init__(self, **kwargs):
|
|
144
|
+
super().__init__("Nelder-Mead", **kwargs)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
class CG(Optimizer):
|
|
148
|
+
|
|
149
|
+
def __init__(self, **kwargs):
|
|
150
|
+
super().__init__("CG", require_jac=True, **kwargs)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
class NewtonCG(Optimizer):
|
|
154
|
+
|
|
155
|
+
def __init__(self, **kwargs):
|
|
156
|
+
super().__init__("Newton-CG", require_jac=True, **kwargs)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
class BFGS(Optimizer):
|
|
160
|
+
|
|
161
|
+
def __init__(self, **kwargs):
|
|
162
|
+
super().__init__("BFGS", **kwargs)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
class Powell(Optimizer):
|
|
166
|
+
|
|
167
|
+
def __init__(self, **kwargs):
|
|
168
|
+
super().__init__("Powell", **kwargs)
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
class Dogleg(Optimizer):
|
|
172
|
+
|
|
173
|
+
def __init__(self, **kwargs):
|
|
174
|
+
super().__init__("dogleg", require_jac=True, **kwargs)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
class TrustNCG(Optimizer):
|
|
178
|
+
|
|
179
|
+
def __init__(self, **kwargs):
|
|
180
|
+
super().__init__("trust-ncg", require_jac=True, **kwargs)
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
class TrustExact(Optimizer):
|
|
184
|
+
|
|
185
|
+
def __init__(self, **kwargs):
|
|
186
|
+
super().__init__("trust-exact", require_jac=True, **kwargs)
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
class TrustKrylov(Optimizer):
|
|
190
|
+
|
|
191
|
+
def __init__(self, **kwargs):
|
|
192
|
+
super().__init__("trust-krylov", require_jac=True, **kwargs)
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
# +++++++++++++++++++++++++++++++++++++++++
|
|
196
|
+
# BOX CONSTRAINS
|
|
197
|
+
# +++++++++++++++++++++++++++++++++++++++++
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
class LBFGSB(Optimizer):
|
|
201
|
+
|
|
202
|
+
def __init__(self, **kwargs):
|
|
203
|
+
super().__init__("L-BFGS-B", with_bounds=True, **kwargs)
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
class TNC(Optimizer):
|
|
207
|
+
|
|
208
|
+
def __init__(self, **kwargs):
|
|
209
|
+
super().__init__("TNC", with_bounds=True, **kwargs)
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
# +++++++++++++++++++++++++++++++++++++++++
|
|
213
|
+
# NON-LINEAR CONSTRAINTS
|
|
214
|
+
# +++++++++++++++++++++++++++++++++++++++++
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
class COBYLA(Optimizer):
|
|
218
|
+
|
|
219
|
+
def __init__(self, **kwargs):
|
|
220
|
+
super().__init__("COBYLA", with_bounds=False, with_constr=True, **kwargs)
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
class SLSQP(Optimizer):
|
|
224
|
+
|
|
225
|
+
def __init__(self, **kwargs):
|
|
226
|
+
super().__init__("SLSQP", with_bounds=True, with_constr=True, **kwargs)
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
class TrustConstr(Optimizer):
|
|
230
|
+
|
|
231
|
+
def __init__(self, **kwargs):
|
|
232
|
+
super().__init__("trust-constr", with_bounds=True, with_constr=True, **kwargs)
|
pymoo/version.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.6.1.5.dev"
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from pymoo.docs import parse_doc_string
|
|
4
|
+
from pymoo.core.plot import Plot
|
|
5
|
+
from pymoo.util.misc import all_combinations
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class FitnessLandscape(Plot):
|
|
9
|
+
|
|
10
|
+
def __init__(self,
|
|
11
|
+
problem,
|
|
12
|
+
_type="surface+contour",
|
|
13
|
+
n_samples=100,
|
|
14
|
+
colorbar=False,
|
|
15
|
+
contour_levels=30,
|
|
16
|
+
kwargs_surface=None,
|
|
17
|
+
kwargs_contour=None,
|
|
18
|
+
kwargs_contour_labels=None,
|
|
19
|
+
**kwargs):
|
|
20
|
+
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
Fitness Landscape
|
|
24
|
+
|
|
25
|
+
Parameters
|
|
26
|
+
----------------
|
|
27
|
+
|
|
28
|
+
problem : The problem to be plotted
|
|
29
|
+
_type : str
|
|
30
|
+
Either "contour", "surface" or "contour+surface"
|
|
31
|
+
labels : {labels}
|
|
32
|
+
|
|
33
|
+
Other Parameters
|
|
34
|
+
----------------
|
|
35
|
+
|
|
36
|
+
figsize : {figsize}
|
|
37
|
+
title : {title}
|
|
38
|
+
legend : {legend}
|
|
39
|
+
tight_layout : {tight_layout}
|
|
40
|
+
cmap : {cmap}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
Returns
|
|
44
|
+
-------
|
|
45
|
+
FitnessLandscape : :class:`~pymoo.core.analytics.visualization.fitness_landscape.FitnessLandscape`
|
|
46
|
+
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
super().__init__(**kwargs)
|
|
50
|
+
self.problem = problem
|
|
51
|
+
self.n_samples = n_samples
|
|
52
|
+
self._type = _type
|
|
53
|
+
self.colorbar = colorbar
|
|
54
|
+
|
|
55
|
+
self.contour_levels = contour_levels
|
|
56
|
+
|
|
57
|
+
self.kwargs_surface = kwargs_surface
|
|
58
|
+
if self.kwargs_surface is None:
|
|
59
|
+
self.kwargs_surface = dict(cmap="summer", rstride=1, cstride=1)
|
|
60
|
+
|
|
61
|
+
self.kwargs_contour = kwargs_contour
|
|
62
|
+
if self.kwargs_contour is None:
|
|
63
|
+
self.kwargs_contour = dict(linestyles="solid", offset=-1)
|
|
64
|
+
|
|
65
|
+
self.kwargs_contour_labels = kwargs_contour_labels
|
|
66
|
+
|
|
67
|
+
def _do(self):
|
|
68
|
+
|
|
69
|
+
problem, n_samples, _type = self.problem, self.n_samples, self._type
|
|
70
|
+
|
|
71
|
+
if problem.n_var == 1 and problem.n_obj == 1:
|
|
72
|
+
|
|
73
|
+
self.init_figure()
|
|
74
|
+
|
|
75
|
+
X = np.linspace(problem.xl[0], problem.xu[0], num=n_samples)[:, None]
|
|
76
|
+
Z = problem.evaluate(X, return_values_of=["F"])
|
|
77
|
+
self.ax.plot(X, Z)
|
|
78
|
+
self.ax.set_xlabel("x")
|
|
79
|
+
self.ax.set_ylabel("f(x)")
|
|
80
|
+
|
|
81
|
+
elif problem.n_var == 2 and problem.n_obj == 1:
|
|
82
|
+
|
|
83
|
+
A = np.linspace(problem.xl[0], problem.xu[0], n_samples)
|
|
84
|
+
B = np.linspace(problem.xl[1], problem.xu[1], n_samples)
|
|
85
|
+
X = all_combinations(A, B)
|
|
86
|
+
|
|
87
|
+
F = np.reshape(problem.evaluate(X, return_values_of=["F"]), (n_samples, n_samples))
|
|
88
|
+
|
|
89
|
+
_X = X[:, 0].reshape((n_samples, n_samples))
|
|
90
|
+
_Y = X[:, 1].reshape((n_samples, n_samples))
|
|
91
|
+
_Z = F.reshape((n_samples, n_samples))
|
|
92
|
+
|
|
93
|
+
def plot_surface():
|
|
94
|
+
surf = self.ax.plot_surface(_X, _Y, _Z, **self.kwargs_surface)
|
|
95
|
+
|
|
96
|
+
if self.colorbar:
|
|
97
|
+
self.fig.colorbar(surf)
|
|
98
|
+
|
|
99
|
+
def plot_contour():
|
|
100
|
+
CS = self.ax.contour(_X, _Y, _Z, self.contour_levels, **self.kwargs_contour)
|
|
101
|
+
if self.kwargs_contour_labels is not None:
|
|
102
|
+
self.ax.clabel(CS, **self.kwargs_contour_labels)
|
|
103
|
+
|
|
104
|
+
if self.colorbar:
|
|
105
|
+
self.fig.colorbar(CS)
|
|
106
|
+
|
|
107
|
+
if _type == "surface":
|
|
108
|
+
self.init_figure(plot_3D=True)
|
|
109
|
+
plot_surface()
|
|
110
|
+
elif _type == "contour":
|
|
111
|
+
self.init_figure(plot_3D=False)
|
|
112
|
+
|
|
113
|
+
if "offset" in self.kwargs_contour:
|
|
114
|
+
del self.kwargs_contour["offset"]
|
|
115
|
+
|
|
116
|
+
plot_contour()
|
|
117
|
+
elif _type == "surface+contour":
|
|
118
|
+
|
|
119
|
+
self.init_figure(plot_3D=True)
|
|
120
|
+
plot_surface()
|
|
121
|
+
plot_contour()
|
|
122
|
+
|
|
123
|
+
else:
|
|
124
|
+
raise Exception("Only landscapes of problems with one or two variables and one objective can be visualized.")
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
parse_doc_string(FitnessLandscape.__init__)
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from pymoo.visualization.util import parse_bounds, normalize
|
|
4
|
+
from pymoo.docs import parse_doc_string
|
|
5
|
+
from pymoo.core.plot import Plot
|
|
6
|
+
from pymoo.util.misc import set_if_none_from_tuples
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Heatmap(Plot):
|
|
10
|
+
|
|
11
|
+
def __init__(self,
|
|
12
|
+
cmap="Blues",
|
|
13
|
+
order_by_objectives=False,
|
|
14
|
+
reverse=True,
|
|
15
|
+
solution_labels=True,
|
|
16
|
+
**kwargs):
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
Heatmap
|
|
20
|
+
|
|
21
|
+
Parameters
|
|
22
|
+
----------------
|
|
23
|
+
|
|
24
|
+
cmap : str
|
|
25
|
+
The color map to be used.
|
|
26
|
+
|
|
27
|
+
order_by_objectives : int or list
|
|
28
|
+
Whether the result should be ordered by an objective. If false no order.
|
|
29
|
+
Otherwise, either supply just the objective or a list. (it is lexicographically sorted).
|
|
30
|
+
|
|
31
|
+
reverse : bool
|
|
32
|
+
If true large values are white and small values the corresponding color. Otherwise, the other way around.
|
|
33
|
+
|
|
34
|
+
solution_labels : bool or list
|
|
35
|
+
If False no labels are plotted in the y axis. If true just the corresponding index. Otherwise, the label provided.
|
|
36
|
+
|
|
37
|
+
bounds : {bounds}
|
|
38
|
+
|
|
39
|
+
labels : {labels}
|
|
40
|
+
|
|
41
|
+
Other Parameters
|
|
42
|
+
----------------
|
|
43
|
+
|
|
44
|
+
figsize : {figsize}
|
|
45
|
+
title : {title}
|
|
46
|
+
legend : {legend}
|
|
47
|
+
tight_layout : {tight_layout}
|
|
48
|
+
cmap : {cmap}
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
super().__init__(cmap=cmap, reverse=reverse, **kwargs)
|
|
54
|
+
self.order_by_objectives = order_by_objectives
|
|
55
|
+
self.solution_labels = solution_labels
|
|
56
|
+
|
|
57
|
+
# set default style
|
|
58
|
+
set_if_none_from_tuples(self.axis_style, ("interpolation", "nearest"), ("vmin", 0), ("vmax", 1))
|
|
59
|
+
|
|
60
|
+
def _do(self):
|
|
61
|
+
|
|
62
|
+
if len(self.to_plot) != 1:
|
|
63
|
+
raise Exception("Only one element can be added to a heatmap.")
|
|
64
|
+
|
|
65
|
+
# initial a figure with a single plot
|
|
66
|
+
self.init_figure()
|
|
67
|
+
|
|
68
|
+
# normalize the input
|
|
69
|
+
bounds = parse_bounds(self.bounds, self.n_dim)
|
|
70
|
+
to_plot_norm = normalize(self.to_plot, bounds, reverse=self.reverse)
|
|
71
|
+
(F, kwargs) = to_plot_norm[0]
|
|
72
|
+
|
|
73
|
+
# dot the sorting if required
|
|
74
|
+
if self.order_by_objectives is not None and self.order_by_objectives is not False:
|
|
75
|
+
|
|
76
|
+
if isinstance(self.order_by_objectives, list) and len(self.order_by_objectives) == self.n_dim:
|
|
77
|
+
L = self.order_by_objectives
|
|
78
|
+
elif isinstance(self.order_by_objectives, int):
|
|
79
|
+
L = [i for i in range(F.shape[1]) if i != self.order_by_objectives]
|
|
80
|
+
L.insert(0, self.order_by_objectives)
|
|
81
|
+
else:
|
|
82
|
+
L = range(self.n_dim)
|
|
83
|
+
|
|
84
|
+
_F = [F[:, j] for j in L]
|
|
85
|
+
I = np.lexsort(_F[::-1])
|
|
86
|
+
else:
|
|
87
|
+
I = np.arange(len(F))
|
|
88
|
+
|
|
89
|
+
# plot the data
|
|
90
|
+
self.ax.imshow(F[I], cmap=self.cmap, **self.axis_style)
|
|
91
|
+
|
|
92
|
+
# set the x ticks and labels
|
|
93
|
+
self.ax.set_xticks(np.arange(self.n_dim))
|
|
94
|
+
self.ax.set_xticklabels(self.get_labels())
|
|
95
|
+
|
|
96
|
+
# no solution labels should be used
|
|
97
|
+
if self.solution_labels is None:
|
|
98
|
+
pass
|
|
99
|
+
|
|
100
|
+
# if true, just use a number for each solution
|
|
101
|
+
elif isinstance(self.solution_labels, bool) and self.solution_labels:
|
|
102
|
+
self.solution_labels = np.arange(len(F)) + 1
|
|
103
|
+
|
|
104
|
+
# otherwise, use directly the label provided
|
|
105
|
+
else:
|
|
106
|
+
if len(self.solution_labels) != len(F):
|
|
107
|
+
raise Exception(
|
|
108
|
+
"The labels provided for each solution must be equal to the number of solutions being plotted.")
|
|
109
|
+
|
|
110
|
+
if self.solution_labels is None:
|
|
111
|
+
self.ax.set_yticks([])
|
|
112
|
+
self.ax.set_yticklabels([])
|
|
113
|
+
|
|
114
|
+
else:
|
|
115
|
+
|
|
116
|
+
# for ordered by objective apply it to labels
|
|
117
|
+
self.solution_labels = [self.solution_labels[i] for i in I]
|
|
118
|
+
|
|
119
|
+
self.ax.set_yticks(np.arange(len(F)))
|
|
120
|
+
self.ax.set_yticklabels(self.solution_labels)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
parse_doc_string(Heatmap.__init__)
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from pymoo.docs import parse_doc_string
|
|
4
|
+
from pymoo.core.plot import Plot
|
|
5
|
+
from pymoo.util.misc import set_if_none, set_if_none_from_tuples
|
|
6
|
+
from pymoo.visualization.util import parse_bounds, normalize
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class PCP(Plot):
|
|
10
|
+
|
|
11
|
+
def __init__(self,
|
|
12
|
+
bounds=None,
|
|
13
|
+
show_bounds=True,
|
|
14
|
+
n_ticks=5,
|
|
15
|
+
normalize_each_axis=True,
|
|
16
|
+
bbox=False,
|
|
17
|
+
**kwargs):
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
Parallel Coordinate Plot
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
Parameters
|
|
24
|
+
----------------
|
|
25
|
+
|
|
26
|
+
bounds : {bounds}
|
|
27
|
+
|
|
28
|
+
axis_style : {axis_style}
|
|
29
|
+
|
|
30
|
+
labels : {labels}
|
|
31
|
+
|
|
32
|
+
n_ticks : int
|
|
33
|
+
Number of ticks to be shown on each parallel axis.
|
|
34
|
+
|
|
35
|
+
show_bounds : bool
|
|
36
|
+
Whether the value of the boundaries are shown in the plot or not.
|
|
37
|
+
|
|
38
|
+
normalize_each_axis : bool
|
|
39
|
+
Whether the values should be normalized either by bounds or implicitly.
|
|
40
|
+
|
|
41
|
+
Other Parameters
|
|
42
|
+
----------------
|
|
43
|
+
|
|
44
|
+
figsize : {figsize}
|
|
45
|
+
title : {title}
|
|
46
|
+
legend : {legend}
|
|
47
|
+
tight_layout : {tight_layout}
|
|
48
|
+
cmap : {cmap}
|
|
49
|
+
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
super().__init__(bounds=bounds, **kwargs)
|
|
53
|
+
self.show_bounds = show_bounds
|
|
54
|
+
self.n_ticks = n_ticks
|
|
55
|
+
self.bbox = bbox
|
|
56
|
+
self.normalize_each_axis = normalize_each_axis
|
|
57
|
+
|
|
58
|
+
set_if_none_from_tuples(self.axis_style, ("color", "red"), ("linewidth", 2), ("alpha", 0.75))
|
|
59
|
+
|
|
60
|
+
def _do(self):
|
|
61
|
+
|
|
62
|
+
# initial a figure with a single plot
|
|
63
|
+
self.init_figure()
|
|
64
|
+
|
|
65
|
+
# if no normalization of each axis the bounds are based on the overall min and max
|
|
66
|
+
if not self.normalize_each_axis and self.bounds is None:
|
|
67
|
+
_F = np.row_stack([e[0] for e in self.to_plot])
|
|
68
|
+
self.bounds = [_F.min(), _F.max()]
|
|
69
|
+
|
|
70
|
+
# normalize the input
|
|
71
|
+
bounds = parse_bounds(self.bounds, self.n_dim)
|
|
72
|
+
to_plot_norm, bounds = normalize(self.to_plot, bounds, return_bounds=True)
|
|
73
|
+
|
|
74
|
+
# plot for each set the lines
|
|
75
|
+
for k, (F, kwargs) in enumerate(to_plot_norm):
|
|
76
|
+
|
|
77
|
+
_kwargs = kwargs.copy()
|
|
78
|
+
set_if_none(_kwargs, "color", self.colors[k % len(self.colors)])
|
|
79
|
+
|
|
80
|
+
for i in range(len(F)):
|
|
81
|
+
self.ax.plot(np.arange(F.shape[1]), F[i, :], **_kwargs)
|
|
82
|
+
|
|
83
|
+
# Plot the parallel coordinate axes
|
|
84
|
+
for i in range(self.n_dim):
|
|
85
|
+
self.ax.axvline(i, **self.axis_style)
|
|
86
|
+
|
|
87
|
+
bottom, top = -0.1, 1.075
|
|
88
|
+
margin_left = 0.08
|
|
89
|
+
|
|
90
|
+
if self.show_bounds:
|
|
91
|
+
lower = self.ax.text(i - margin_left, bottom, self.func_number_to_text(bounds[0][i]))
|
|
92
|
+
upper = self.ax.text(i - margin_left, top, self.func_number_to_text(bounds[1][i]))
|
|
93
|
+
|
|
94
|
+
if self.bbox:
|
|
95
|
+
lower.set_bbox(dict(facecolor='white', alpha=0.8))
|
|
96
|
+
upper.set_bbox(dict(facecolor='white', alpha=0.8))
|
|
97
|
+
|
|
98
|
+
if self.n_ticks is not None:
|
|
99
|
+
n_length = 0.03
|
|
100
|
+
for y in np.linspace(0, 1, self.n_ticks):
|
|
101
|
+
self.ax.hlines(y, i - n_length, i + n_length, **self.axis_style)
|
|
102
|
+
|
|
103
|
+
# if bounds are shown, then move them to the bottom
|
|
104
|
+
if self.show_bounds:
|
|
105
|
+
self.ax.tick_params(axis='x', which='major', pad=25)
|
|
106
|
+
|
|
107
|
+
self.ax.spines['right'].set_visible(False)
|
|
108
|
+
self.ax.spines['left'].set_visible(False)
|
|
109
|
+
|
|
110
|
+
self.ax.set_yticklabels([])
|
|
111
|
+
self.ax.set_yticks([])
|
|
112
|
+
self.ax.set_ylim((-0.05, 1.05))
|
|
113
|
+
|
|
114
|
+
self.ax.set_xticks(np.arange(self.n_dim))
|
|
115
|
+
self.ax.set_xticklabels(self.get_labels())
|
|
116
|
+
|
|
117
|
+
return self
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
parse_doc_string(PCP.__init__)
|