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.

Files changed (328) hide show
  1. pymoo/__init__.py +3 -0
  2. pymoo/algorithms/__init__.py +0 -0
  3. pymoo/algorithms/base/__init__.py +0 -0
  4. pymoo/algorithms/base/bracket.py +38 -0
  5. pymoo/algorithms/base/genetic.py +109 -0
  6. pymoo/algorithms/base/line.py +62 -0
  7. pymoo/algorithms/base/local.py +39 -0
  8. pymoo/algorithms/base/meta.py +79 -0
  9. pymoo/algorithms/hyperparameters.py +89 -0
  10. pymoo/algorithms/moo/__init__.py +0 -0
  11. pymoo/algorithms/moo/age.py +310 -0
  12. pymoo/algorithms/moo/age2.py +194 -0
  13. pymoo/algorithms/moo/ctaea.py +298 -0
  14. pymoo/algorithms/moo/dnsga2.py +76 -0
  15. pymoo/algorithms/moo/kgb.py +446 -0
  16. pymoo/algorithms/moo/moead.py +183 -0
  17. pymoo/algorithms/moo/nsga2.py +113 -0
  18. pymoo/algorithms/moo/nsga3.py +358 -0
  19. pymoo/algorithms/moo/pinsga2.py +370 -0
  20. pymoo/algorithms/moo/rnsga2.py +188 -0
  21. pymoo/algorithms/moo/rnsga3.py +246 -0
  22. pymoo/algorithms/moo/rvea.py +214 -0
  23. pymoo/algorithms/moo/sms.py +195 -0
  24. pymoo/algorithms/moo/spea2.py +190 -0
  25. pymoo/algorithms/moo/unsga3.py +47 -0
  26. pymoo/algorithms/soo/__init__.py +0 -0
  27. pymoo/algorithms/soo/convex/__init__.py +0 -0
  28. pymoo/algorithms/soo/nonconvex/__init__.py +0 -0
  29. pymoo/algorithms/soo/nonconvex/brkga.py +161 -0
  30. pymoo/algorithms/soo/nonconvex/cmaes.py +554 -0
  31. pymoo/algorithms/soo/nonconvex/de.py +279 -0
  32. pymoo/algorithms/soo/nonconvex/direct.py +149 -0
  33. pymoo/algorithms/soo/nonconvex/es.py +203 -0
  34. pymoo/algorithms/soo/nonconvex/g3pcx.py +94 -0
  35. pymoo/algorithms/soo/nonconvex/ga.py +93 -0
  36. pymoo/algorithms/soo/nonconvex/ga_niching.py +223 -0
  37. pymoo/algorithms/soo/nonconvex/isres.py +74 -0
  38. pymoo/algorithms/soo/nonconvex/nelder.py +251 -0
  39. pymoo/algorithms/soo/nonconvex/optuna.py +80 -0
  40. pymoo/algorithms/soo/nonconvex/pattern.py +183 -0
  41. pymoo/algorithms/soo/nonconvex/pso.py +399 -0
  42. pymoo/algorithms/soo/nonconvex/pso_ep.py +297 -0
  43. pymoo/algorithms/soo/nonconvex/random_search.py +25 -0
  44. pymoo/algorithms/soo/nonconvex/sres.py +56 -0
  45. pymoo/algorithms/soo/univariate/__init__.py +0 -0
  46. pymoo/algorithms/soo/univariate/backtracking.py +59 -0
  47. pymoo/algorithms/soo/univariate/exp.py +46 -0
  48. pymoo/algorithms/soo/univariate/golden.py +65 -0
  49. pymoo/algorithms/soo/univariate/quadr_interp.py +81 -0
  50. pymoo/algorithms/soo/univariate/wolfe.py +163 -0
  51. pymoo/config.py +33 -0
  52. pymoo/constraints/__init__.py +3 -0
  53. pymoo/constraints/adaptive.py +62 -0
  54. pymoo/constraints/as_obj.py +56 -0
  55. pymoo/constraints/as_penalty.py +41 -0
  56. pymoo/constraints/eps.py +26 -0
  57. pymoo/constraints/from_bounds.py +36 -0
  58. pymoo/core/__init__.py +0 -0
  59. pymoo/core/algorithm.py +394 -0
  60. pymoo/core/callback.py +38 -0
  61. pymoo/core/crossover.py +77 -0
  62. pymoo/core/decision_making.py +102 -0
  63. pymoo/core/decomposition.py +76 -0
  64. pymoo/core/duplicate.py +163 -0
  65. pymoo/core/evaluator.py +116 -0
  66. pymoo/core/indicator.py +34 -0
  67. pymoo/core/individual.py +784 -0
  68. pymoo/core/infill.py +64 -0
  69. pymoo/core/initialization.py +42 -0
  70. pymoo/core/mating.py +39 -0
  71. pymoo/core/meta.py +21 -0
  72. pymoo/core/mixed.py +165 -0
  73. pymoo/core/mutation.py +44 -0
  74. pymoo/core/operator.py +40 -0
  75. pymoo/core/parameters.py +134 -0
  76. pymoo/core/plot.py +210 -0
  77. pymoo/core/population.py +180 -0
  78. pymoo/core/problem.py +460 -0
  79. pymoo/core/recorder.py +99 -0
  80. pymoo/core/repair.py +23 -0
  81. pymoo/core/replacement.py +96 -0
  82. pymoo/core/result.py +52 -0
  83. pymoo/core/sampling.py +43 -0
  84. pymoo/core/selection.py +61 -0
  85. pymoo/core/solution.py +10 -0
  86. pymoo/core/survival.py +103 -0
  87. pymoo/core/termination.py +70 -0
  88. pymoo/core/variable.py +399 -0
  89. pymoo/cython/__init__.py +0 -0
  90. pymoo/cython/calc_perpendicular_distance.cpython-312-x86_64-linux-gnu.so +0 -0
  91. pymoo/cython/calc_perpendicular_distance.pyx +67 -0
  92. pymoo/cython/decomposition.cpython-312-x86_64-linux-gnu.so +0 -0
  93. pymoo/cython/decomposition.pyx +165 -0
  94. pymoo/cython/hv.cpython-312-x86_64-linux-gnu.so +0 -0
  95. pymoo/cython/hv.pyx +18 -0
  96. pymoo/cython/info.cpython-312-x86_64-linux-gnu.so +0 -0
  97. pymoo/cython/info.pyx +5 -0
  98. pymoo/cython/mnn.cpython-312-x86_64-linux-gnu.so +0 -0
  99. pymoo/cython/mnn.pyx +273 -0
  100. pymoo/cython/non_dominated_sorting.cpython-312-x86_64-linux-gnu.so +0 -0
  101. pymoo/cython/non_dominated_sorting.pyx +645 -0
  102. pymoo/cython/pruning_cd.cpython-312-x86_64-linux-gnu.so +0 -0
  103. pymoo/cython/pruning_cd.pyx +197 -0
  104. pymoo/cython/stochastic_ranking.cpython-312-x86_64-linux-gnu.so +0 -0
  105. pymoo/cython/stochastic_ranking.pyx +49 -0
  106. pymoo/cython/utils.pxd +129 -0
  107. pymoo/cython/vendor/__init__.py +0 -0
  108. pymoo/cython/vendor/hypervolume.cpp +1621 -0
  109. pymoo/cython/vendor/hypervolume.h +63 -0
  110. pymoo/decomposition/__init__.py +0 -0
  111. pymoo/decomposition/aasf.py +24 -0
  112. pymoo/decomposition/asf.py +10 -0
  113. pymoo/decomposition/pbi.py +13 -0
  114. pymoo/decomposition/perp_dist.py +13 -0
  115. pymoo/decomposition/tchebicheff.py +11 -0
  116. pymoo/decomposition/util.py +13 -0
  117. pymoo/decomposition/weighted_sum.py +8 -0
  118. pymoo/docs.py +187 -0
  119. pymoo/experimental/__init__.py +0 -0
  120. pymoo/experimental/algorithms/__init__.py +0 -0
  121. pymoo/experimental/algorithms/gde3.py +57 -0
  122. pymoo/gradient/__init__.py +21 -0
  123. pymoo/gradient/automatic.py +57 -0
  124. pymoo/gradient/grad_autograd.py +105 -0
  125. pymoo/gradient/grad_complex.py +35 -0
  126. pymoo/gradient/grad_jax.py +51 -0
  127. pymoo/gradient/toolbox/__init__.py +6 -0
  128. pymoo/indicators/__init__.py +0 -0
  129. pymoo/indicators/distance_indicator.py +55 -0
  130. pymoo/indicators/gd.py +7 -0
  131. pymoo/indicators/gd_plus.py +7 -0
  132. pymoo/indicators/hv/__init__.py +63 -0
  133. pymoo/indicators/hv/exact.py +71 -0
  134. pymoo/indicators/hv/exact_2d.py +102 -0
  135. pymoo/indicators/hv/monte_carlo.py +74 -0
  136. pymoo/indicators/igd.py +7 -0
  137. pymoo/indicators/igd_plus.py +7 -0
  138. pymoo/indicators/kktpm.py +151 -0
  139. pymoo/indicators/migd.py +55 -0
  140. pymoo/indicators/rmetric.py +203 -0
  141. pymoo/indicators/spacing.py +52 -0
  142. pymoo/mcdm/__init__.py +0 -0
  143. pymoo/mcdm/compromise_programming.py +19 -0
  144. pymoo/mcdm/high_tradeoff.py +40 -0
  145. pymoo/mcdm/pseudo_weights.py +32 -0
  146. pymoo/operators/__init__.py +0 -0
  147. pymoo/operators/control.py +187 -0
  148. pymoo/operators/crossover/__init__.py +0 -0
  149. pymoo/operators/crossover/binx.py +45 -0
  150. pymoo/operators/crossover/dex.py +122 -0
  151. pymoo/operators/crossover/erx.py +162 -0
  152. pymoo/operators/crossover/expx.py +51 -0
  153. pymoo/operators/crossover/hux.py +37 -0
  154. pymoo/operators/crossover/nox.py +13 -0
  155. pymoo/operators/crossover/ox.py +84 -0
  156. pymoo/operators/crossover/pcx.py +82 -0
  157. pymoo/operators/crossover/pntx.py +49 -0
  158. pymoo/operators/crossover/sbx.py +125 -0
  159. pymoo/operators/crossover/spx.py +5 -0
  160. pymoo/operators/crossover/ux.py +20 -0
  161. pymoo/operators/mutation/__init__.py +0 -0
  162. pymoo/operators/mutation/bitflip.py +17 -0
  163. pymoo/operators/mutation/gauss.py +58 -0
  164. pymoo/operators/mutation/inversion.py +42 -0
  165. pymoo/operators/mutation/nom.py +7 -0
  166. pymoo/operators/mutation/pm.py +94 -0
  167. pymoo/operators/mutation/rm.py +23 -0
  168. pymoo/operators/repair/__init__.py +0 -0
  169. pymoo/operators/repair/bounce_back.py +32 -0
  170. pymoo/operators/repair/bounds_repair.py +95 -0
  171. pymoo/operators/repair/inverse_penalty.py +89 -0
  172. pymoo/operators/repair/rounding.py +18 -0
  173. pymoo/operators/repair/to_bound.py +31 -0
  174. pymoo/operators/repair/vtype.py +11 -0
  175. pymoo/operators/sampling/__init__.py +0 -0
  176. pymoo/operators/sampling/lhs.py +73 -0
  177. pymoo/operators/sampling/rnd.py +50 -0
  178. pymoo/operators/selection/__init__.py +0 -0
  179. pymoo/operators/selection/rnd.py +72 -0
  180. pymoo/operators/selection/tournament.py +76 -0
  181. pymoo/operators/survival/__init__.py +0 -0
  182. pymoo/operators/survival/rank_and_crowding/__init__.py +1 -0
  183. pymoo/operators/survival/rank_and_crowding/classes.py +209 -0
  184. pymoo/operators/survival/rank_and_crowding/metrics.py +208 -0
  185. pymoo/optimize.py +72 -0
  186. pymoo/problems/__init__.py +157 -0
  187. pymoo/problems/dyn.py +47 -0
  188. pymoo/problems/dynamic/__init__.py +0 -0
  189. pymoo/problems/dynamic/cec2015.py +108 -0
  190. pymoo/problems/dynamic/df.py +452 -0
  191. pymoo/problems/dynamic/misc.py +167 -0
  192. pymoo/problems/functional.py +48 -0
  193. pymoo/problems/many/__init__.py +5 -0
  194. pymoo/problems/many/cdtlz.py +159 -0
  195. pymoo/problems/many/dcdtlz.py +88 -0
  196. pymoo/problems/many/dtlz.py +264 -0
  197. pymoo/problems/many/wfg.py +550 -0
  198. pymoo/problems/multi/__init__.py +14 -0
  199. pymoo/problems/multi/bnh.py +34 -0
  200. pymoo/problems/multi/carside.py +48 -0
  201. pymoo/problems/multi/clutch.py +104 -0
  202. pymoo/problems/multi/csi.py +55 -0
  203. pymoo/problems/multi/ctp.py +198 -0
  204. pymoo/problems/multi/dascmop.py +213 -0
  205. pymoo/problems/multi/kursawe.py +25 -0
  206. pymoo/problems/multi/modact.py +68 -0
  207. pymoo/problems/multi/mw.py +400 -0
  208. pymoo/problems/multi/omnitest.py +48 -0
  209. pymoo/problems/multi/osy.py +32 -0
  210. pymoo/problems/multi/srn.py +28 -0
  211. pymoo/problems/multi/sympart.py +94 -0
  212. pymoo/problems/multi/tnk.py +24 -0
  213. pymoo/problems/multi/truss2d.py +83 -0
  214. pymoo/problems/multi/welded_beam.py +41 -0
  215. pymoo/problems/multi/wrm.py +36 -0
  216. pymoo/problems/multi/zdt.py +151 -0
  217. pymoo/problems/multi_to_single.py +22 -0
  218. pymoo/problems/single/__init__.py +12 -0
  219. pymoo/problems/single/ackley.py +24 -0
  220. pymoo/problems/single/cantilevered_beam.py +34 -0
  221. pymoo/problems/single/flowshop_scheduling.py +112 -0
  222. pymoo/problems/single/g.py +874 -0
  223. pymoo/problems/single/griewank.py +18 -0
  224. pymoo/problems/single/himmelblau.py +15 -0
  225. pymoo/problems/single/knapsack.py +48 -0
  226. pymoo/problems/single/mopta08.py +26 -0
  227. pymoo/problems/single/multimodal.py +20 -0
  228. pymoo/problems/single/pressure_vessel.py +30 -0
  229. pymoo/problems/single/rastrigin.py +20 -0
  230. pymoo/problems/single/rosenbrock.py +22 -0
  231. pymoo/problems/single/schwefel.py +18 -0
  232. pymoo/problems/single/simple.py +13 -0
  233. pymoo/problems/single/sphere.py +19 -0
  234. pymoo/problems/single/traveling_salesman.py +79 -0
  235. pymoo/problems/single/zakharov.py +19 -0
  236. pymoo/problems/static.py +14 -0
  237. pymoo/problems/util.py +42 -0
  238. pymoo/problems/zero_to_one.py +27 -0
  239. pymoo/termination/__init__.py +23 -0
  240. pymoo/termination/collection.py +12 -0
  241. pymoo/termination/cv.py +48 -0
  242. pymoo/termination/default.py +45 -0
  243. pymoo/termination/delta.py +64 -0
  244. pymoo/termination/fmin.py +16 -0
  245. pymoo/termination/ftol.py +144 -0
  246. pymoo/termination/indicator.py +49 -0
  247. pymoo/termination/max_eval.py +14 -0
  248. pymoo/termination/max_gen.py +15 -0
  249. pymoo/termination/max_time.py +20 -0
  250. pymoo/termination/robust.py +34 -0
  251. pymoo/termination/xtol.py +33 -0
  252. pymoo/util/__init__.py +0 -0
  253. pymoo/util/archive.py +150 -0
  254. pymoo/util/cache.py +29 -0
  255. pymoo/util/clearing.py +82 -0
  256. pymoo/util/display/__init__.py +0 -0
  257. pymoo/util/display/column.py +52 -0
  258. pymoo/util/display/display.py +34 -0
  259. pymoo/util/display/multi.py +96 -0
  260. pymoo/util/display/output.py +53 -0
  261. pymoo/util/display/progress.py +54 -0
  262. pymoo/util/display/single.py +67 -0
  263. pymoo/util/dominator.py +67 -0
  264. pymoo/util/function_loader.py +129 -0
  265. pymoo/util/hv.py +23 -0
  266. pymoo/util/matlab_engine.py +39 -0
  267. pymoo/util/misc.py +460 -0
  268. pymoo/util/mnn.py +70 -0
  269. pymoo/util/nds/__init__.py +0 -0
  270. pymoo/util/nds/dominance_degree_non_dominated_sort.py +159 -0
  271. pymoo/util/nds/efficient_non_dominated_sort.py +152 -0
  272. pymoo/util/nds/fast_non_dominated_sort.py +70 -0
  273. pymoo/util/nds/naive_non_dominated_sort.py +36 -0
  274. pymoo/util/nds/non_dominated_sorting.py +67 -0
  275. pymoo/util/nds/tree_based_non_dominated_sort.py +133 -0
  276. pymoo/util/normalization.py +312 -0
  277. pymoo/util/optimum.py +42 -0
  278. pymoo/util/plotting.py +177 -0
  279. pymoo/util/pruning_cd.py +89 -0
  280. pymoo/util/randomized_argsort.py +60 -0
  281. pymoo/util/ref_dirs/__init__.py +24 -0
  282. pymoo/util/ref_dirs/construction.py +88 -0
  283. pymoo/util/ref_dirs/das_dennis.py +52 -0
  284. pymoo/util/ref_dirs/energy.py +319 -0
  285. pymoo/util/ref_dirs/energy_layer.py +119 -0
  286. pymoo/util/ref_dirs/genetic_algorithm.py +63 -0
  287. pymoo/util/ref_dirs/incremental.py +68 -0
  288. pymoo/util/ref_dirs/misc.py +128 -0
  289. pymoo/util/ref_dirs/optimizer.py +59 -0
  290. pymoo/util/ref_dirs/performance.py +162 -0
  291. pymoo/util/ref_dirs/reduction.py +85 -0
  292. pymoo/util/ref_dirs/sample_and_map.py +24 -0
  293. pymoo/util/reference_direction.py +260 -0
  294. pymoo/util/remote.py +55 -0
  295. pymoo/util/roulette.py +27 -0
  296. pymoo/util/running_metric.py +128 -0
  297. pymoo/util/sliding_window.py +25 -0
  298. pymoo/util/stochastic_ranking.py +32 -0
  299. pymoo/util/value_functions.py +719 -0
  300. pymoo/util/vectors.py +40 -0
  301. pymoo/util/vf_dominator.py +99 -0
  302. pymoo/vendor/__init__.py +0 -0
  303. pymoo/vendor/cec2018.py +398 -0
  304. pymoo/vendor/gta.py +617 -0
  305. pymoo/vendor/hv.py +267 -0
  306. pymoo/vendor/vendor_cmaes.py +412 -0
  307. pymoo/vendor/vendor_coco.py +81 -0
  308. pymoo/vendor/vendor_scipy.py +232 -0
  309. pymoo/version.py +1 -0
  310. pymoo/visualization/__init__.py +8 -0
  311. pymoo/visualization/fitness_landscape.py +127 -0
  312. pymoo/visualization/heatmap.py +123 -0
  313. pymoo/visualization/pcp.py +120 -0
  314. pymoo/visualization/petal.py +91 -0
  315. pymoo/visualization/radar.py +108 -0
  316. pymoo/visualization/radviz.py +68 -0
  317. pymoo/visualization/scatter.py +150 -0
  318. pymoo/visualization/star_coordinate.py +75 -0
  319. pymoo/visualization/util.py +123 -0
  320. pymoo/visualization/video/__init__.py +0 -0
  321. pymoo/visualization/video/callback_video.py +82 -0
  322. pymoo/visualization/video/one_var_one_obj.py +57 -0
  323. pymoo/visualization/video/two_var_one_obj.py +62 -0
  324. pymoo-0.6.1.5.dev0.dist-info/METADATA +187 -0
  325. pymoo-0.6.1.5.dev0.dist-info/RECORD +328 -0
  326. pymoo-0.6.1.5.dev0.dist-info/WHEEL +6 -0
  327. pymoo-0.6.1.5.dev0.dist-info/licenses/LICENSE +191 -0
  328. pymoo-0.6.1.5.dev0.dist-info/top_level.txt +1 -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
@@ -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