Evolutionary Optimization

The evolutionary optimization module EO provides an interface between pyGDM and the pagmo/pygmo. pygmo is capable to do massively parallelized optimizations via what their authors call the “generalized island model”, however, due to the recent transition from pygmo 1.x to version 2.x, this parallelization technique is not yet supported in pyGDM. A pyGDM-interface to pagmo/pygmo 1.x exists, with support for the generalized island model. We can provide this older interface upon request.

EO.core

core contains the main optimization routine.

run_eo: Launch an optimization

pyGDM2.EO.core.run_eo(problem=None, population=20, algorithm=<class 'pygmo.core.sade'>, algorithm_kwargs={}, plot_interval=0, generations=10, max_time=3600, max_iter=200, max_nonsuccess=20, filename='', save_interval=1, save_all_generations=False, continue_eo=False, verbose=False)

run nano-photonic geometry evolutionary optimization

Parameters:
  • problem (class inheriting from problems.BaseProblem) – problem definition including the structure-model and pyGDM simulation setup

  • population (int, default: 20) – number of individuals in the population

  • algorithm (pygmo.algorithm object, default: pygmo.sade) – the EO algorithm to use.

  • algorithm_kwargs (dict, default {}) – optional kwargs, passed to algorithm

  • plot_interval (int, default: 0) – plot each N number of improvements. 0 = no plotting

  • generations (int, default: 10) – number of generations to evolve per iteration (i.e. nr of generations between status reports)

  • max_time (int, default: 3600) – stop criterion: maximum time in seconds

  • max_iter (int, default: 200) – stop criterion: maximum number of iterations

  • max_nonsuccess (int, default: 20) – stop criterion: maximum consecutive iterations without improvement

  • filename (str, default '') – path to file. dictionary containing optimization status and results will be saved for later re-use / analysis using pythons pickle. Empty string means no run-time saving.

  • save_interval (int, default: 1) – save results to file each N improvements

  • save_each_generation (bool, default: False) – wether or not to save the full population at each iteration. If False, only the best candidate in each iteration will be saved

  • continue_eo (bool, default: False) – wether to continue an existing optimization. We encourag to use the wrapper continue_eo instead.

  • verbose (bool, default: False) – if True, print more detailed runtime info

Returns:

dict

Return type:

dictionary containing optimization data and log

Notes

To reload and continue an optimization (continue_eo==True), “filename” is used to identify the stored optimization (“filename” can be either a dict as returned by run_eo(), or a path to a file containing the pickeled dict).

The halloffame in the eo-dictionary contains
  • for single-objective: [#iter, best_f, best_x]

  • for multi-objective: [#iter, ideal, nadir]

For details on the underlyign pagmo/pygmo library, see also

[1] https://esa.github.io/pagmo2/

[2] Biscani, F., Izzo, D. & Yam, C. H.:

A Global Optimisation Toolbox for Massively Parallel Engineering Optimisation. arXiv:1004.3824 [cs, math] (2010).

[3] Izzo, D., Ruciński, M. & Biscani, F.:

The Generalized Island Model in Parallel Architectures and Bioinspired Algorithms (eds. Vega, F. F. de, Pérez, J. I. H. & Lanchares, J.) pp. 151–169 (Springer Berlin Heidelberg, 2012).

continue_eo: continue a former optimization

pyGDM2.EO.core.continue_eo(filename, plot_interval=0, generations=10, max_time=3600, max_iter=200, max_nonsuccess=20, save_all_generations=False, verbose=False)

Continue an evolutionary optimization

Parameters:

filename (str or dict) – path to file or dict containing the saved optimization

Notes

all other arguments are explained in run_eo()

EO.models

models contains the structure models (geometries to optimize).

BaseModel: Base class for model definitions

class pyGDM2.EO.models.BaseModel(sim, warn=False)

Base class describing a structure model for evolutionary optimization

Model classes must call the BaseModel constructor with an instance of pyGDM2.core.simulation as input parameter

Mandatory functions for re-implementation :

  • get_bounds(self)no argmuents

    returns 2 vectors for lower and upper box-boundaries of the input parameters [lbnds, ubnds]

  • generate_structure(self, params)array-like params

    params: list of length corresponding to the problem’s dimensionality. Implements the structure-generation as function of params. must(!!) call self.set_structure(geometry) to internally set the new structure.

Parameters:

sim (pyGDM2.core.simulation) – simulation description

generate_structure(params)

the main structure generator

get_bounds()

return lower and upper bounds as required by pyGMO models

get_dim()

get problem dimension (nr of free parameters)

plot_structure(interactive=True, show=True, **kwargs)

plot the structure (2D, matplotlib)

kwargs are passed to pyGMD2.visu.structure

print_info()

print information about structure to stdout

random_structure()

generate a randomized structure

set_step(step)

set the stepsize of the geometry

may also be used as optimization-parameter (in generate_structure)

set_structure(geometry, material=None)

replace structure-geometry in core.simulation object

Predefined models

class pyGDM2.EO.models.RectangularAntenna(sim, limits_W, limits_L, limits_pos, height)

optimization-model for simple geometry, consisting of one rectangular antenna

free parameters: width W, length L, x_offset X, y_offset Y
  • W,L : units of stepsize

  • X,Y : units of nm

Parameters:
  • sim (pyGDM2.core.simulation) – simulation description

  • limits_W (list of 2 int) – box-constraints for width [lower limit, upper limit]. units of stepsize

  • limits_L (list of 2 int) – box-constraints for length [lower limit, upper limit]. units of stepsize

  • limits_pos (list of 2 elements) – box-constraints for position offset parameter. If empty list ([]), the structure position is fixed. in units of nm

  • height (int) – height of the structure in units of stepsize

Notes

The purpose of this model is merely for demonstration.

class pyGDM2.EO.models.CrossAntenna(sim, limits_W, limits_L, limits_pos, height)

optimization-model for simple geometry, consisting of a cross-shaped structure

free parameters: 2 widths W1, W2; 2 lengths L1, L2, x_offset X, y_offset Y
  • Wi,Li : units of stepsize

  • X,Y : units of nm

  • height (fixed) : units of stepsize

Parameters:
  • sim (pyGDM2.core.simulation) – simulation description

  • limits_W (list of 2 int) – box-constraints for widths [lower limit, upper limit]. units of stepsize

  • limits_L (list of 2 int) – box-constraints for lengths [lower limit, upper limit]. units of stepsize

  • limits_pos (list of 2 elements) – box-constraints for position offset parameter. If empty list ([]), the structure position is fixed. in units of nm

  • height (int) – height of the structure in units of stepsize

Notes

The purpose of this model is merely for demonstration.

class pyGDM2.EO.models.MultiRectAntenna(sim, N_antennas, limits_W, limits_L, limits_pos_x, limits_pos_y, height)

optimization-model for geometry consisting of multiple rectangular pads

free parameters: N times (width; length; x_pos; y_pos)
  • N: number of rectangles

  • all parameters in units of stepsize

Parameters:
  • sim (pyGDM2.core.simulation) – simulation description

  • N_antennas (int) – Number of rectangular antennas

  • limits_W (list of 2 int) – box-constraints for widths [lower limit, upper limit]. units of stepsize

  • limits_L (list of 2 int) – box-constraints for lengths [lower limit, upper limit]. units of stepsize

  • limits_pos_x (each a list of 2 int) – box-constraints for x/y position offset. units of stepsize

  • limits_pos_y (each a list of 2 int) – box-constraints for x/y position offset. units of stepsize

  • height (int) – height of the structure in units of stepsize

class pyGDM2.EO.models.BlockModel(sim, N, block_nx, block_ny, block_nz, area_limits, forbidden=[], fixed_meshpoints=[], symmetric=False, fit_offset=False)

structure consisting of N blocks of variable positions

Parameters:
  • sim (pyGDM2.core.simulation) – simulation description

  • N (int) – Number of blocks

  • block_nx (int, int, int) – number of meshpoints in X, Y and Z dimension for each block

  • block_ny (int, int, int) – number of meshpoints in X, Y and Z dimension for each block

  • block_nz (int, int, int) – number of meshpoints in X, Y and Z dimension for each block

  • area_limits (list of 2 elements) – [lower limit, upper limit] box-constraints for area on which the material-blocks are positioned. units of stepsize

  • forbidden (list of 3-tuples, default: []) – list of forbidden positions (list of coordinates [x,y,z]). Material at these coordiantes will be removed. units of stepsize

  • fixed_meshpoints (list of 3-tuples, default: []) – list of additional fixed meshpoints not to be moved by optimizer. Units of stepsize. Note: forbidden has priority over fixed_meshpoints.

  • symmetric (bool, default: False) – if true, a symmtery-axis (parallel to X-axis) will be imposed

  • fit_offset (bool, default: False) – if true, additional x/y-offset parameters will be included in the optimization. These will be applied after the symmetry- operation (if symmetric = True), which effectively shifts the symmtery-axis as well. The offset-limits are the same as area_limits.

EO.problems

problems contains the problems defining the optimization target(s).

BaseProblem: Base class for problem definitions

class pyGDM2.EO.problems.BaseProblem(model=None, field_index=0, maximize=True)

Base pyGDM2 problem

Problem classes must call the BaseProblem constructor with at least an instance of a model-class (see models.BaseModel)

Parameters:
  • model (instance of class implementing models.BaseModel) – Definition of structure model and pyGDM-simulation

  • field_index (int, default: 0) – field_index to use from pyGDM simulation.

  • maximize (bool, default: True) – whether to maximize (True) or minimize (False) the fitness function

equality_constraints(params)

Optional (nonlinear) equality constraints (as 1D array)

Equality constraints are regarded satisfied if == 0

fitness(dv)

Virtual objective function, single objective (PyGMO requirement)

get_extra_info()

Return extra info, e.g. a more detailed problem description

get_name()

Return problem object name

get_nobj()

number of objectives

inequality_constraints(params)

Optional (nonlinear) inequality constraints (as 1D array)

Inequality constraints are regarded satisfied if <= 0

objective_function(params)

To be reimplemented! Evaluates the objective function

Predefined problems

class pyGDM2.EO.problems.ProblemScat(model, field_index=0, opt_target='Qscat', maximize=True)

optimize for scat./ext./abs. cross-section or efficiency

Parameters:
  • model (instance of class implementing models.BaseModel) – Definition of structure model and pyGDM-simulation

  • field_index (int, default: 0) – field_index to use from pyGDM simulation.

  • opt_target (str, default: 'Qscat') –

    Optimization target. One of [‘Qscat’, ‘Qext’, ‘Qabs’, ‘CSscat’, ‘CSext’, ‘CSabs’]

    • CS: cross-section (absolute value)

    • Q: efficiency (CS divided by geometrical CS)

  • maximize (bool, default: True) – whether to maximize (True) or minimize (False) the fitness function

class pyGDM2.EO.problems.ProblemNearfield(model, field_index=0, r_probe=(0, 0, 0), opt_target='E', maximize=True)

optimize near-field enhancement ($|E|^2$ or $|B|^2$)

opt_target defines wether the E-field (‘E’) or the B-field (‘B’) shall be maximized (or optionally minimized)

Parameters:
  • model (instance of class implementing models.BaseModel) – Definition of structure model and pyGDM-simulation

  • field_index (int, default: 0) – field_index to use from pyGDM simulation.

  • r_probe (3-tuple, default: (0,0,0)) – defines the (x,y,z) position where field enhancemnt is to be maximized / minimized

  • opt_target (str, default: 'E') – Optimization target. Electric or magnetic field intensity. One of [‘E’, ‘B’].

  • maximize (bool, default: True) – whether to maximize (True) or minimize (False) the fitness function

class pyGDM2.EO.problems.ProblemDirectivity(model, field_index=0, dir_index=[5], which_field='e_sc', kwargs_farfield={'Nphi': 5, 'Nteta': 3, 'tetamax': 1.5707963267948966, 'tetamin': 0}, consider_dS=False, averaging=True, absoluteI=False, kwargs_scatter={}, maximize=True)

Problem to optimize directionality of scattering from nanostructure

Use EO.tools.calculate_solid_angle_by_dir_index to define ‘dir_index’ for the desired target solid angle

Parameters:
  • model (instance of class implementing models.BaseModel) – Definition of structure model and pyGDM-simulation

  • field_index (list of int, default: 0) – “field_index” in case of multiple pyGDM-simulation configurations

  • dir_index (list of int; list of list of int, default: [5]) – which solid-angle elements to consider for optimization. If list of lists of int (e.g. [[4], [5], [1,2]]), will run multi-objective optimization using each of the sub-lists as target solid angle

  • which_field (str, default: 'e_sc') –

    optimize using one of [‘e_sc’, ‘e_tot’, ‘e0’].
    • ’e_sc’: scattered field

    • ’e_tot’: total field (= e0 + e_sc)

    • ’e0’: fundamental field (rather for testing)

  • kwargs_farfield (dict, default: dict(Nteta=3, Nphi=5, tetamin=0, tetamax=np.pi/2.)) – kwargs, passed to pyGDM2.linear.farfield(), defining the farfield scattering calculation. Required arguments are: Nteta, Nphi, tetamin, tetamax

  • (False) (absoluteI) –

    Additional flags (defaults in paranthesis):
    • consider_dS: correct (True) solid angle integration or simple sum (False)

    • averaging: avgerage (True) or integrate (False) solid angle intensity

    • absoluteI: maximize total intensity through selected solid angle instead of ratio

  • (True) (averaging) –

    Additional flags (defaults in paranthesis):
    • consider_dS: correct (True) solid angle integration or simple sum (False)

    • averaging: avgerage (True) or integrate (False) solid angle intensity

    • absoluteI: maximize total intensity through selected solid angle instead of ratio

  • (False)

    Additional flags (defaults in paranthesis):
    • consider_dS: correct (True) solid angle integration or simple sum (False)

    • averaging: avgerage (True) or integrate (False) solid angle intensity

    • absoluteI: maximize total intensity through selected solid angle instead of ratio

  • kwargs_scatter (dict, default: {}) – additional kwargs, passed to pyGDM2.core.sactter()

  • maximize (bool, default: True) – whether to maximize (True) or minimize (False) the fitness function

EO.tools

tools contains various EO helper functions.

Get results from stored optimization

pyGDM2.EO.tools.reload_eo(filename)

Reload saved evol. optimization from file

Parameters:

filename (str or dict) – either path to filename (pickled optimization data) or the optimization dictionary. In the latter case, the input will simply be returned unaltered.

Returns:

dict

Return type:

evolutionary optimization data

pyGDM2.EO.tools.get_best_candidate(filename, iteration=-1, do_test=True, verbose=False)

generate simuation object for best solution

Parameters:
  • filename (str or dict) – either path to filename (pickled optimization data) or the optimization dictionary. In the latter case, the input will simply be returned unaltered.

  • iteration (int, default: -1) – iteration (Nr of improvements) to use. Best candidate of selected iteration will be returned. Python indexing, hence positive and negative numbers possible.

  • do_test (bool, default: True) – whether to test the stored fitness (redo the simulation) or not

  • verbose (bool, default: False) – print some information

Returns:

sim

Return type:

pyGDM2.core.simulation instance of best candidate

pyGDM2.EO.tools.get_best_candidate_f_x(filename, iteration=-1)

get best fitness and parameter vector of a specific generation.

Returns also the total number of generations with improvements accessible by the iteration parameter.

Parameters:
  • filename (str or dict) – either path to filename (pickled optimization data) or the optimization dictionary. In the latter case, the input will simply be returned unaltered.

  • iteration (int, default: -1) – iteration (Nr of improvements) to use. Best candidate of selected iteration will be returned. Python indexing, hence positive and negative numbers possible.

Returns:

  • f (array like) – fitness(-vector) of best candidate

  • x (array like) – parameter vector of best candidate

  • N (int) – number of iterations with improvement

pyGDM2.EO.tools.get_model(filename)

get instance of model object used in optimization

Parameters:

filename (str or dict) – either path to filename (pickled optimization data) or the optimization dictionary. In the latter case, the input will simply be returned unaltered.

Returns:

model – Model used in the loaded EO

Return type:

Instance of class based on model.BaseClass

pyGDM2.EO.tools.get_problem(filename)

get instance of problem object used in optimization

Parameters:

filename (str or dict) – either path to filename (pickled optimization data) or the optimization dictionary. In the latter case, the input will simply be returned unaltered.

Returns:

model – Problem used in the loaded EO

Return type:

Instance of class based on problems.BaseProblem

pyGDM2.EO.tools.get_population(filename)

get full final population

Parameters:

filename (str or dict) – either path to filename (pickled optimization data) or the optimization dictionary. In the latter case, the input will simply be returned unaltered.

Returns:

list of lists – Full population of final iteration. Each individual is stored as tuple (f, x) with f fitness the of parameter-vector x

Return type:

list of tuples (f, x)

Results from Pareto multi-objective optimization

pyGDM2.EO.tools.get_pareto_fronts(filename, iteration=-1, recalc=False, verbose=False)

get Pareto fronts and corresponding simulations of multi-objective optimization

Parameters:
  • filename (str or dict) – either path to filename (pickled optimization data) or the optimization dictionary. In the latter case, the input will simply be returned unaltered.

  • iteration (int, default: -1) – iteration number. Python indexing (pos. and neg. indices possible).

Returns:

list of lists – Full population of final iteration. Each individual is stored as tuple (f, x) with f fitness the of parameter-vector x

Return type:

list of tuples (f, x)

pyGDM2.EO.tools.plot_pareto_2d(pareto, print_indices=True, cutoff_indexprint=-1, marker='x', mew=1.5, ms=7, show=True, **kwargs)

plot the pareto-front, optionally print index numbers for identification

Parameters:
  • pareto (list of tuples) – Pareto-front as list of objective-value tuples (2 objectives)

  • print_indices (bool, default: True) – print index of individuals next to pareto-front points

  • cutoff_indexprint (float, default: -1) – optional: manual value for minimum distance between two individuals in Pareto plot for allowing the printing of a new index-value label

  • marker (str, float, float. defaults: 'x', 1.5, 7) – marker type, marker linewith and marker size for step-plot

  • mew (str, float, float. defaults: 'x', 1.5, 7) – marker type, marker linewith and marker size for step-plot

  • ms (str, float, float. defaults: 'x', 1.5, 7) – marker type, marker linewith and marker size for step-plot

  • show (bool, default: True) – whether or not to run plt.show()

  • **kwargs (are passed to matplotlib’s plt.step) –

Return type:

return value of matplotlib’s plt.step

pyGDM2.EO.tools.plot_all_pareto_fronts_2d(all_paretos, cmap=None, show=True, **kwargs)

Plot all Pareto-fronts

Parameters:
  • all_paretos (list of lists of tuples) – List of all non-dominated fronts as obtained by get_pareto_fronts()

  • cmap (matplotlib colormap, default: None) – A colormap for the different pareto-fronts. Default “None” will use matplotlib’s Blues

  • show (bool, default: True) – whether or not to run plt.show()

  • **kwargs (are passed to plot_pareto_2d()) –