pymoo 0.6.1.5.dev0__cp311-cp311-musllinux_1_2_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-311-x86_64-linux-musl.so +0 -0
- pymoo/cython/calc_perpendicular_distance.pyx +67 -0
- pymoo/cython/decomposition.cpython-311-x86_64-linux-musl.so +0 -0
- pymoo/cython/decomposition.pyx +165 -0
- pymoo/cython/hv.cpython-311-x86_64-linux-musl.so +0 -0
- pymoo/cython/hv.pyx +18 -0
- pymoo/cython/info.cpython-311-x86_64-linux-musl.so +0 -0
- pymoo/cython/info.pyx +5 -0
- pymoo/cython/mnn.cpython-311-x86_64-linux-musl.so +0 -0
- pymoo/cython/mnn.pyx +273 -0
- pymoo/cython/non_dominated_sorting.cpython-311-x86_64-linux-musl.so +0 -0
- pymoo/cython/non_dominated_sorting.pyx +645 -0
- pymoo/cython/pruning_cd.cpython-311-x86_64-linux-musl.so +0 -0
- pymoo/cython/pruning_cd.pyx +197 -0
- pymoo/cython/stochastic_ranking.cpython-311-x86_64-linux-musl.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 +330 -0
- pymoo-0.6.1.5.dev0.dist-info/WHEEL +5 -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
- pymoo.libs/libgcc_s-2298274a.so.1 +0 -0
- pymoo.libs/libstdc++-08d5c7eb.so.6.0.33 +0 -0
pymoo/core/plot.py
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import importlib
|
|
2
|
+
|
|
3
|
+
import matplotlib
|
|
4
|
+
import matplotlib.pyplot as plt
|
|
5
|
+
import numpy as np
|
|
6
|
+
from matplotlib.colors import ListedColormap
|
|
7
|
+
|
|
8
|
+
from pymoo.util.misc import set_if_none
|
|
9
|
+
from pymoo.visualization.util import default_number_to_text, in_notebook
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Plot:
|
|
13
|
+
|
|
14
|
+
def __init__(self,
|
|
15
|
+
fig=None,
|
|
16
|
+
ax=None,
|
|
17
|
+
figsize=(8, 6),
|
|
18
|
+
title=None,
|
|
19
|
+
legend=False,
|
|
20
|
+
tight_layout=False,
|
|
21
|
+
bounds=None,
|
|
22
|
+
reverse=False,
|
|
23
|
+
cmap="tab10",
|
|
24
|
+
axis_style=None,
|
|
25
|
+
axis_label_style=None,
|
|
26
|
+
func_number_to_text=default_number_to_text,
|
|
27
|
+
labels="f",
|
|
28
|
+
close_on_destroy=True,
|
|
29
|
+
**kwargs):
|
|
30
|
+
|
|
31
|
+
super().__init__()
|
|
32
|
+
|
|
33
|
+
# change the font of plots to serif (looks better)
|
|
34
|
+
plt.rc('font', family='serif')
|
|
35
|
+
|
|
36
|
+
# the matplotlib classes
|
|
37
|
+
self.fig = fig
|
|
38
|
+
self.ax = ax
|
|
39
|
+
self.figsize = figsize
|
|
40
|
+
|
|
41
|
+
# whether the figure should be closed when object is destroyed
|
|
42
|
+
self.close_on_destroy = close_on_destroy
|
|
43
|
+
|
|
44
|
+
# the title of the figure - can also be a list if subfigures
|
|
45
|
+
self.title = title
|
|
46
|
+
|
|
47
|
+
# the style to be used for the axis
|
|
48
|
+
if axis_style is None:
|
|
49
|
+
self.axis_style = {}
|
|
50
|
+
else:
|
|
51
|
+
self.axis_style = axis_style.copy()
|
|
52
|
+
|
|
53
|
+
# the style of the axes
|
|
54
|
+
if axis_label_style is None:
|
|
55
|
+
self.axis_label_style = {}
|
|
56
|
+
else:
|
|
57
|
+
self.axis_label_style = axis_label_style.copy()
|
|
58
|
+
|
|
59
|
+
# how numbers are represented if plotted
|
|
60
|
+
self.func_number_to_text = func_number_to_text
|
|
61
|
+
|
|
62
|
+
# if data are normalized reverse can be applied
|
|
63
|
+
self.reverse = reverse
|
|
64
|
+
|
|
65
|
+
# the labels for each axis
|
|
66
|
+
self.axis_labels = labels
|
|
67
|
+
|
|
68
|
+
# the data to plot
|
|
69
|
+
self.to_plot = []
|
|
70
|
+
|
|
71
|
+
# whether to plot a legend or apply tight layout
|
|
72
|
+
self.legend = legend
|
|
73
|
+
self.tight_layout = tight_layout
|
|
74
|
+
|
|
75
|
+
# the colormap or the color lists to use
|
|
76
|
+
if isinstance(cmap, str):
|
|
77
|
+
self.cmap = matplotlib.pyplot.get_cmap(cmap)
|
|
78
|
+
else:
|
|
79
|
+
self.cmap = cmap
|
|
80
|
+
if isinstance(self.cmap, ListedColormap):
|
|
81
|
+
self.colors = self.cmap.colors
|
|
82
|
+
|
|
83
|
+
# the dimensionality of the data
|
|
84
|
+
self.n_dim = None
|
|
85
|
+
|
|
86
|
+
# the boundaries for normalization
|
|
87
|
+
self.bounds = bounds
|
|
88
|
+
|
|
89
|
+
def init_figure(self, n_rows=1, n_cols=1, plot_3D=False, force_axes_as_matrix=False):
|
|
90
|
+
if self.ax is not None:
|
|
91
|
+
return
|
|
92
|
+
|
|
93
|
+
if not plot_3D:
|
|
94
|
+
self.fig, self.ax = plt.subplots(nrows=n_rows, ncols=n_cols, figsize=self.figsize)
|
|
95
|
+
else:
|
|
96
|
+
importlib.import_module("mpl_toolkits.mplot3d")
|
|
97
|
+
self.fig = plt.figure(figsize=self.figsize)
|
|
98
|
+
self.ax = self.fig.add_subplot(1, 1, 1, projection='3d')
|
|
99
|
+
|
|
100
|
+
# if there is more than one figure we represent it as a 2D numpy array
|
|
101
|
+
if (n_rows > 1 or n_cols > 1) or force_axes_as_matrix:
|
|
102
|
+
self.ax = np.array(self.ax).reshape(n_rows, n_cols)
|
|
103
|
+
|
|
104
|
+
def do(self):
|
|
105
|
+
|
|
106
|
+
if len(self.to_plot) > 0:
|
|
107
|
+
unique_dim = np.unique(np.array([e[0].shape[-1] for e in self.to_plot]))
|
|
108
|
+
if len(unique_dim) > 1:
|
|
109
|
+
raise Exception("Inputs with different dimensions were added: %s" % unique_dim)
|
|
110
|
+
|
|
111
|
+
self.n_dim = unique_dim[0]
|
|
112
|
+
|
|
113
|
+
# actually call the class
|
|
114
|
+
self._do()
|
|
115
|
+
|
|
116
|
+
# convert the axes to a list
|
|
117
|
+
axes = np.array(self.ax).flatten()
|
|
118
|
+
|
|
119
|
+
for i, ax in enumerate(axes):
|
|
120
|
+
|
|
121
|
+
legend, kwargs = get_parameter_with_options(self.legend)
|
|
122
|
+
if legend:
|
|
123
|
+
ax.legend(**kwargs)
|
|
124
|
+
|
|
125
|
+
title, kwargs = get_parameter_with_options(self.title)
|
|
126
|
+
if self.title:
|
|
127
|
+
if isinstance(self.title, list):
|
|
128
|
+
ax.set_title(title[i], **kwargs)
|
|
129
|
+
else:
|
|
130
|
+
ax.set_title(title, **kwargs)
|
|
131
|
+
|
|
132
|
+
if self.tight_layout:
|
|
133
|
+
self.fig.tight_layout()
|
|
134
|
+
|
|
135
|
+
return self
|
|
136
|
+
|
|
137
|
+
def apply(self, func):
|
|
138
|
+
func(self.ax)
|
|
139
|
+
return self
|
|
140
|
+
|
|
141
|
+
def get_plot(self):
|
|
142
|
+
return self.ax
|
|
143
|
+
|
|
144
|
+
def set_axis_style(self, **kwargs):
|
|
145
|
+
for key, val in kwargs.items():
|
|
146
|
+
self.axis_style[key] = val
|
|
147
|
+
return self
|
|
148
|
+
|
|
149
|
+
def reset(self):
|
|
150
|
+
self.fig = plt.figure(figsize=self.figsize)
|
|
151
|
+
self.ax = None
|
|
152
|
+
return self
|
|
153
|
+
|
|
154
|
+
def add(self, F, **kwargs):
|
|
155
|
+
|
|
156
|
+
if F is None:
|
|
157
|
+
return self
|
|
158
|
+
elif F.ndim == 1:
|
|
159
|
+
self.to_plot.append([F[None, :], kwargs])
|
|
160
|
+
elif F.ndim == 2:
|
|
161
|
+
self.to_plot.append([F, kwargs])
|
|
162
|
+
elif F.ndim == 3:
|
|
163
|
+
[self.to_plot.append([_F, kwargs.copy()]) for _F in F]
|
|
164
|
+
|
|
165
|
+
return self
|
|
166
|
+
|
|
167
|
+
def plot_if_not_done_yet(self):
|
|
168
|
+
if self.ax is None:
|
|
169
|
+
self.do()
|
|
170
|
+
|
|
171
|
+
def show(self, **kwargs):
|
|
172
|
+
self.plot_if_not_done_yet()
|
|
173
|
+
|
|
174
|
+
# in a notebook the plot method need not to be called explicitly
|
|
175
|
+
if not in_notebook() and matplotlib.get_backend() != "agg":
|
|
176
|
+
plt.show(**kwargs)
|
|
177
|
+
plt.close()
|
|
178
|
+
|
|
179
|
+
return self
|
|
180
|
+
|
|
181
|
+
def save(self, fname, **kwargs):
|
|
182
|
+
self.plot_if_not_done_yet()
|
|
183
|
+
set_if_none(kwargs, "bbox_inches", "tight")
|
|
184
|
+
self.fig.savefig(fname, **kwargs)
|
|
185
|
+
return self
|
|
186
|
+
|
|
187
|
+
def get_labels(self):
|
|
188
|
+
if isinstance(self.axis_labels, list):
|
|
189
|
+
if len(self.axis_labels) != self.n_dim:
|
|
190
|
+
raise Exception("Number of axes labels not equal to the number of axes.")
|
|
191
|
+
else:
|
|
192
|
+
return self.axis_labels
|
|
193
|
+
else:
|
|
194
|
+
return [f"${self.axis_labels}_{{{i}}}$" for i in range(1, self.n_dim + 1)]
|
|
195
|
+
|
|
196
|
+
def __del__(self):
|
|
197
|
+
if self.fig is not None and self.close_on_destroy:
|
|
198
|
+
plt.close(self.fig)
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def get_parameter_with_options(param):
|
|
202
|
+
if param is None:
|
|
203
|
+
return None, None
|
|
204
|
+
else:
|
|
205
|
+
if isinstance(param, tuple):
|
|
206
|
+
val, kwargs = param
|
|
207
|
+
else:
|
|
208
|
+
val, kwargs = param, {}
|
|
209
|
+
|
|
210
|
+
return val, kwargs
|
pymoo/core/population.py
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from pymoo.core.individual import Individual
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Population(np.ndarray):
|
|
7
|
+
|
|
8
|
+
def __new__(cls, individuals=[]):
|
|
9
|
+
if isinstance(individuals, Individual):
|
|
10
|
+
individuals = [individuals]
|
|
11
|
+
return np.array(individuals).view(cls)
|
|
12
|
+
|
|
13
|
+
def has(self, key):
|
|
14
|
+
return all([ind.has(key) for ind in self])
|
|
15
|
+
|
|
16
|
+
def collect(self, func, to_numpy=True):
|
|
17
|
+
val = []
|
|
18
|
+
for i in range(len(self)):
|
|
19
|
+
val.append(func(self[i]))
|
|
20
|
+
if to_numpy:
|
|
21
|
+
val = np.array(val)
|
|
22
|
+
return val
|
|
23
|
+
|
|
24
|
+
def apply(self, func):
|
|
25
|
+
self.collect(func, to_numpy=False)
|
|
26
|
+
|
|
27
|
+
def set(self, *args, **kwargs):
|
|
28
|
+
|
|
29
|
+
# if population is empty just return
|
|
30
|
+
if self.size == 0:
|
|
31
|
+
return
|
|
32
|
+
|
|
33
|
+
# done for the old interface with the interleaving variable definition
|
|
34
|
+
kwargs = interleaving_args(*args, kwargs=kwargs)
|
|
35
|
+
|
|
36
|
+
# for each entry in the dictionary set it to each individual
|
|
37
|
+
for key, values in kwargs.items():
|
|
38
|
+
is_iterable = hasattr(values, '__len__') and not isinstance(values, str)
|
|
39
|
+
|
|
40
|
+
if is_iterable and len(values) != len(self):
|
|
41
|
+
raise Exception("Population Set Attribute Error: Number of values and population size do not match!")
|
|
42
|
+
|
|
43
|
+
for i in range(len(self)):
|
|
44
|
+
val = values[i] if is_iterable else values
|
|
45
|
+
|
|
46
|
+
# check for view and make copy to prevent memory leakage (#455)
|
|
47
|
+
if isinstance(val, np.ndarray) and not val.flags["OWNDATA"]:
|
|
48
|
+
val = val.copy()
|
|
49
|
+
|
|
50
|
+
self[i].set(key, val)
|
|
51
|
+
|
|
52
|
+
return self
|
|
53
|
+
|
|
54
|
+
def get(self, *args, to_numpy=True, **kwargs):
|
|
55
|
+
|
|
56
|
+
val = {}
|
|
57
|
+
for c in args:
|
|
58
|
+
val[c] = []
|
|
59
|
+
|
|
60
|
+
# for each individual
|
|
61
|
+
for i in range(len(self)):
|
|
62
|
+
|
|
63
|
+
# for each argument
|
|
64
|
+
for c in args:
|
|
65
|
+
val[c].append(self[i].get(c, **kwargs))
|
|
66
|
+
|
|
67
|
+
# convert the results to a list
|
|
68
|
+
res = [val[c] for c in args]
|
|
69
|
+
|
|
70
|
+
# to numpy array if desired - default true
|
|
71
|
+
if to_numpy:
|
|
72
|
+
res = [np.array(e) for e in res]
|
|
73
|
+
|
|
74
|
+
# return as tuple or single value
|
|
75
|
+
if len(args) == 1:
|
|
76
|
+
return res[0]
|
|
77
|
+
else:
|
|
78
|
+
return tuple(res)
|
|
79
|
+
|
|
80
|
+
@classmethod
|
|
81
|
+
def merge(cls, a, b, *args):
|
|
82
|
+
|
|
83
|
+
# do the regular merge between first and second element
|
|
84
|
+
m = merge(a, b)
|
|
85
|
+
|
|
86
|
+
# process the list of others and merge as well
|
|
87
|
+
others = list(args)
|
|
88
|
+
while len(others) > 0:
|
|
89
|
+
m = merge(m, others.pop(0))
|
|
90
|
+
|
|
91
|
+
return m
|
|
92
|
+
|
|
93
|
+
@classmethod
|
|
94
|
+
def create(cls, *args):
|
|
95
|
+
return Population.__new__(cls, args)
|
|
96
|
+
|
|
97
|
+
@classmethod
|
|
98
|
+
def empty(cls, size=0):
|
|
99
|
+
individuals = [Individual() for _ in range(size)]
|
|
100
|
+
return Population.__new__(cls, individuals)
|
|
101
|
+
|
|
102
|
+
@classmethod
|
|
103
|
+
def new(cls, *args, **kwargs):
|
|
104
|
+
kwargs = interleaving_args(*args, kwargs=kwargs)
|
|
105
|
+
|
|
106
|
+
if len(kwargs) > 0:
|
|
107
|
+
sizes = np.unique(np.array([len(v) for _, v in kwargs.items()]))
|
|
108
|
+
if len(sizes) == 1:
|
|
109
|
+
size = sizes[0]
|
|
110
|
+
else:
|
|
111
|
+
raise Exception(f"Population.new needs to be called with same-sized inputs, but the sizes are {sizes}")
|
|
112
|
+
else:
|
|
113
|
+
size = 0
|
|
114
|
+
|
|
115
|
+
pop = Population.empty(size)
|
|
116
|
+
pop.set(**kwargs)
|
|
117
|
+
|
|
118
|
+
return pop
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def pop_from_array_or_individual(array, pop=None):
|
|
122
|
+
# the population type can be different - (different type of individuals)
|
|
123
|
+
if pop is None:
|
|
124
|
+
pop = Population.empty()
|
|
125
|
+
|
|
126
|
+
# provide a whole population object - (individuals might be already evaluated)
|
|
127
|
+
if isinstance(array, Population):
|
|
128
|
+
pop = array
|
|
129
|
+
elif isinstance(array, np.ndarray):
|
|
130
|
+
pop = pop.new("X", np.atleast_2d(array))
|
|
131
|
+
elif isinstance(array, Individual):
|
|
132
|
+
pop = Population.empty(1)
|
|
133
|
+
pop[0] = array
|
|
134
|
+
else:
|
|
135
|
+
return None
|
|
136
|
+
|
|
137
|
+
return pop
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def merge(a, b):
|
|
141
|
+
if a is None:
|
|
142
|
+
return b
|
|
143
|
+
elif b is None:
|
|
144
|
+
return a
|
|
145
|
+
|
|
146
|
+
a, b = pop_from_array_or_individual(a), pop_from_array_or_individual(b)
|
|
147
|
+
|
|
148
|
+
if len(a) == 0:
|
|
149
|
+
return b
|
|
150
|
+
elif len(b) == 0:
|
|
151
|
+
return a
|
|
152
|
+
else:
|
|
153
|
+
obj = np.concatenate([a, b]).view(Population)
|
|
154
|
+
return obj
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def interleaving_args(*args, kwargs=None):
|
|
158
|
+
if len(args) % 2 != 0:
|
|
159
|
+
raise Exception(f"Even number of arguments are required but {len(args)} arguments were provided.")
|
|
160
|
+
|
|
161
|
+
if kwargs is None:
|
|
162
|
+
kwargs = {}
|
|
163
|
+
|
|
164
|
+
for i in range(int(len(args) / 2)):
|
|
165
|
+
key, values = args[i * 2], args[i * 2 + 1]
|
|
166
|
+
kwargs[key] = values
|
|
167
|
+
return kwargs
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def calc_cv(pop, config=None):
|
|
171
|
+
|
|
172
|
+
if config is None:
|
|
173
|
+
config = Individual.default_config()
|
|
174
|
+
|
|
175
|
+
G, H = pop.get("G", "H")
|
|
176
|
+
|
|
177
|
+
from pymoo.core.individual import calc_cv as func
|
|
178
|
+
CV = np.array([func(g, h, config) for g, h in zip(G, H)])
|
|
179
|
+
|
|
180
|
+
return CV
|