Initialization
This chapter describes the SACOBRA initialization and the options (or hyperparameters) of SACOBRA.
CobraInitializer
The initialization in SACOBRA_Py is done by creating an object of class CobraInitializer and it consists of the following steps:
pass in the specification of the COP
pass in all the options in
SACoptionss_opt(optional, if
s_opts.ID.rescale==True) rescale the problem in input spacecreate the initial design, see
InitDesigneradjust several elements according to constraint range, see
adCon()calculate for each initial design point
numViol, the number of violated constraints, andmaxViol, the maximum constraint violation. If equality constraints are involved, calculate \(\mu_{init}\), the radius for an artificial feasibility tube around each equality constraint (seeEQUoptions) and base the calculation ofnumViolandmaxViolon this artificial feasibility.calculate the so-far best (artificial) feasible point. If no point fulfills (artificial) feasibility, form the set of points with minimum
numVioland take from this set the one point with the best objective.set up result dictionary sac_res
- class cobraInit.CobraInitializer(x0, fn: object, f_name: str, lower: ~numpy.ndarray, upper: ~numpy.ndarray, is_equ: ~numpy.ndarray, solu=None, s_opts: ~opt.sacOptions.SACoptions = <opt.sacOptions.SACoptions object>)
Initialize SACOBRA optimization:
problem formulation: x0, fn, lower, upper, is_equ, solu
parameter settings: s_opts via
SACoptionscreate initial design: A, Fres, Gres via
InitDesigner
- Parameters:
x0 (np.ndarray or None) – start point, if given, then its dim has to be the same as
lower. If it is/has NaN or None on input, it is replaced by a random point from[lower, upper].fn – function returning
(1+nConstraints)-dim vector: [objective to minimize, constraints]f_name – function name
lower – lower bound, its dimension defines input space dimension
upper – upper bound (same dim as lower)
is_equ – boolean vector with dim
nConstraints: Which constraints are equality constraints?solu (np.ndarray or None) – (optional, for diagnostics) true solution vector or solution matrix (one solution per row): one or several feasible x that deliver the minimal objective value
s_opts (SACoptions) – the options. If not specified, take the default
SACoptionsobject
Objects of class
CobraInitializer(usually namedcobrabelow) have the following useful attributes:phase name of the optimization phase [‘init’ | ‘phase1’ | ‘phase2’]
rng random number generator
rw RescaleWrapper
sac_opts object of class
SACoptionscontaining all the optionssac_res dictionary with the SACOBRA results from initialization and optimization, see cobra.sac_res in the appendix for details
df data frame with diagnostic information from optimization, see cobra.df in the appendix for details
df2 data frame with further diagnostic information from optimization, see cobra.df2 in the appendix for details
See Appendix for more details on cobra.sacres, cobra.df, cobra.df2.
- adCon()
Adjust several elements according to constraint range.
The following elements of
self.sac_resmay be changed: ‘fn’, ‘Gres’, ‘Grange’, ‘GrangeEqu’.
- get_fbest()
Return the original objective function value at the best feasible solution.
If no feasible solution was found, return the objective value of the solution with the least maximum violation. (Note: In this case, the objective value may be seemingly ‘better’ than the true optimal objective.)
- get_feasible_best()
Return the original objective function value at the best feasible solution.
If no feasible solution was found, return NaN.
- get_xbest()
- Returns:
best feasible solution in original space
- Return type:
np.ndarray
If no feasible solution was found, return the solution with the least maximum violation.
- get_xbest_cobra()
- Returns:
best feasible solution in COBRA space (maybe rescaled)
- Return type:
np.ndarray
- class initDesigner.InitDesigner(x0: ndarray, fn, rng, lower: ndarray, upper: ndarray, is_equ: ndarray, s_opts: SACoptions)
The initial design is a set of
Ppoints from input space with dimensiond. The problem functions \(f,g,h\) are evaluated at thesePpoints and these evaluated sets form the basis of the later optimization: From the characteristics of the evaluated sets, the classesCobraInitializerandCobraPhaseIIdeduce decisions about certain adjustments:whether to adjust constraint functions or not, see
CobraInitializer.adCon(),which DRC to select, see
CobraInitializer.adDRC().whether to apply \(plog(f)\) or not, see AdFitter (called in each iteration in
CobraPhaseII),
CobraPhaseIIuses the evaluated sets to train the initial fitness and constraint surrogate models.In detail, the constructor of
InitDesignerdoes the following: Create the initial design in matrix self.A with shape(P, d)of sample points in (potentially rescaled) input space[lower, upper]\(\subset \mathbb{R}^d\), whereP = s_opts.ID.initDesPointsandd =input space dimension. The recipe how to select the sample points is prescribed by the type of initial designs_opts.ID.initDesign.Apply
fnto these points and split the result in objective function (\(f\)) values self.Fres with shape(P,)and constraint function (\(g,h\)) values self.Gres with shape(P,nC), wherenC= number of constraints.- Parameters:
x0 – For the cases
ID.initDesign = "OPTCOBYLA" | "OPTBIASED, takex0as start point for a short optimization run. In the otherID.initDesignchoices, set the last pointself.A[-1,:]tox0.x0is rescaled to [lower, upper] ifs_opts.ID.rescaleis set.fn – see parameter
fnincobraInit.CobraInitializerrng – RNG (random number generator) from
cobraInit.CobraInitializerlower – vector of shape
(d,)upper – vector of shape
(d,)is_equ – boolean vector with dim
nConstraints: Which constraints are equality constraints?s_opts (
SACoptions) – the options. Here we uses_opts.cobraSeedand from elementIDoptionss_opts.IDthe elementsinitDesign,initBiasandinitDesPoints.
- __call__() tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray]
Return the three results
A,FresandGresof the initial design- Returns:
tuple (self.A, self.Fres, self.Gres)
- Return type:
(np.ndarray, np.ndarray, np.ndarray)
The return tuple contains:
self.A:
(P,d)-matrix with initial designself.Fres:
(P,)-vector with objective evaluated at each initial design pointself.Gres:
(P,nC)-matrix with constraints evaluated at each initial design point
Types of Initial Design
The initial design creates a matrix self.A with shape (P, d) of P sample points in (potentially rescaled)
input space [lower, upper] \(\subset \mathbb{R}^d\),
where P = s_opts.ID.initDesPoints and d = input space dimension.
The recipe how to select the sample points is prescribed by s_opts.ID.initDesign:
“RANDOM”: uniform random
“RAND_REP”: uniform random with reproducible random numbers (both in R and in Python)
“LHS”: Latin Hypercube Sampling, see SciPy’s LatinHyperCube
“BIASED”: random sample from a normal distribution with mean
x0and standard deviations_opts.ID.initBias. This is useful ifx0is already in the interesting (e.g. near-feasible or objective-minimizing) region.“OPTCOBYLA”: optimized design: perform a short COBYLA optimization run starting from
x0with the real objective and constraint functions. Extract with the help ofFnArchiveFactoryfrom the function evaluations the firstPindependent points. The idea is that we sample not randomly but in the relevant part of the input space.“OPTBIASED”: establish from a short COBYLA run a new suitable point
new_x0(best feasible or near-feasible). Generate a random sample from a normal distribution with meannew_x0and standard deviations_opts.ID.initBias.
- class fnArchiveFact.FnArchiveFactory(fn, x0)
Build a wrapper for function
fnwith input and function value archive.Usage:
fnArch = FnArchiveFactory(fn, x0) val = fnArch(x) # ... f_arch = fnArch.getFuncArchive()
- Parameters:
fn – the function to be wrapped and archived
x0 – a typical input vector, needed only to infer the archive sizes
- __call__(x)
Call
v = fn(x)and storexand function valuevin archives.
- getFuncArchive()
- Returns:
an array where each row is an
vfrom a call tov = fnArch(x)
- getSoluArchive()
- Returns:
an array where each row is an
xfrom a call tofnArch(x)
Distance Requirement Cycle (DRC)
The Distance Requirement Cycle (DRC) is the vector XI that controls exploration: Each already evaluated infill point is surrounded by a forbidden-sphere of radius XI[c] with c = i mod XI.size (c loops cyclically through XI’s inidices`, that’s where the name cycle comes from). A new infill point is searched under the additional constraint that it has to be a distance XI[c] away from all other already evaluted infill points. The larger XI[c], the more exploration.
XI is set by class SACoptions.
If XI==None, then CobraInitializer will set it, depending on objective range, to short DRC [0.001, 0.0] or long DRC [0.3, 0.05, 0.001, 0.0005, 0.0]. Both vectors contain XI[c] = 0 which enforces exploitation. (If all entries were XI[c] > 0 then a good region would never be exploited further, since the search could never continue in the close vicinity of an already good infill point.)
Options
All paramters (options) for SACOBRA_Py have sensible defaults defined. The user has only to specify those parameters where a setting different from the defaults is desired.
- class opt.sacOptions.SACoptions(feval=50, XI=None, skipPhaseI=True, saveIntermediate=False, verbose=1, verboseIter=10, important=True, cobraSeed=42, ID=<opt.idOptions.IDoptions object>, RBF=<opt.rbfOptions.RBFoptions object>, SEQ=<opt.seqOptions.SEQoptions object>, EQU=<opt.equOptions.EQUoptions object>, ISA=<opt.isaOptions.ISAoptions object>, MS=<opt.msOptions.MSoptions object>, RI=<opt.riOptions.RIoptions object>, TR=<opt.trOptions.TRoptions object>)
The collection of all parameters (options) for SACOBRA_Py. Except for some general parameters defined in this class, they are hierarchically organized in nested option classes.
- Parameters:
feval – number of function evaluations
XI – Distance-Requirement-Cycle (DRC) that controls exploration: Each infill point has a forbidden-sphere of radius
XI[c]around it.cloops cyclically throughXI’s inidices. IfXI==None, thenCobraInitializerwill set it, depending on objective range, to short DRC[0.001, 0.0]or long DRC[0.3, 0.05, 0.001, 0.0005, 0.0].skipPhaseI – whether to skip SACOBRA_Py phase I or not
saveIntermediate – whether to save intermediate results (including surrogates) or not. If True, save to
f'results/cobra-{f_name}-{SEQ.optimizer}-{cobraSeed}.pkl'verbose – verbosity level: 0: print nothing. 1: print only important messages. 2: print every message
verboseIter – an integer value, after how many iterations to print summarized results.
important – controls the importance level for some
verboseprint’s inupdateInfoAndCounterscobraSeed – the seed for RNGs. SACOBRA_Py guarantees the same results for the same seed
ID (IDoptions) – nested options for initial design
RBF (RBFoptions) – nested options for radial basis functions
SEQ (SEQoptions) – nested options for sequential optimizer
EQU (EQUoptions) – nested options for equality constraints
ISA (ISAoptions) – nested Internal SACOBRA options
MS (MSoptions) – nested options for model selection (TODO)
RI – nested options for repair infeasible (TODO)
TR (TRoptions) – nested options for trust region (TODO)
- class opt.idOptions.IDoptions(initDesign='RANDOM', initDesPoints: int | None = None, initDesOptP: int | None = None, initBias=0.005, rescale=True, newLower=-1, newUpper=1)
Options for the initial design (\(d\) = input dimension of problem).
- Parameters:
initDesign – options: “RANDOM”, “RAND_R”, “RAND_REP”, “LHS”, … (see Types of initial design)
initDesPoints – number of initial design points. If None, cobraInit will set it to \(d+1\) if RBF.degree=1 or to \((d+1)(d+2)/2\) if RBF.degree=2
initDesOptP – if None, cobraInit will set it to initDesPoints
initBias – standard deviation for normal distribution in cases
initDesign = "BIASED" | "OPTBIASED"rescale – if True, rescale input space from [lower, upper] to \([\) newLower, newUpper \(]^d\)
newLower – common new lower bound for each of the \(d\) input dimensions
newUpper – common new upper bound for each of the \(d\) input dimensions
- class opt.rbfOptions.RBFoptions(kernel='cubic', degree=2, rho=0.0, rhoDec=2.0, rhoGrow=0, width=None, widthFactor=1.0, widthRule=W_RULE.ONE, interpolator='scipy', test_pmat=False)
Options for the RBF surrogate models
- Parameters:
kernel – RBF kernel type, see below
degree – degree of polynomial tail for RBF kernel. See SciPy’s RBFInterpolator for details.
rho – Smoothing parameter \(\rho\). If \(\rho=0\), use interpolating RBFs: The surrogate model surface passes exactly through the points. If \(\rho>0\), use approximating RBFs (spline-like). The larger \(\rho\), the smoother the surrogate model.
rhoDec – exponential decay factor for \(\rho\)
rhoGrow – every
rhoGrow(e.g. 100) iterations, re-enlarge \(\rho\). If 0, then re-enlarge neverwidth –
only relevant for the scale-variant kernel types.
width =\(\sigma\) translates to shape parameterepsilon =\(\epsilon = 1/\sqrt{2\sigma}\) in SciPy’s RBFInterpolator.widthRule – only relevant for the scale-variant kernels: If
width=None, calculate the appropriate width from the data by heuristic ruleW_RULE.ONEorW_RULE.THREEwidthFactor – only for scale-variant kernels. Additional constant factor applied to each width \(\sigma\)
interpolator –
”scipy” or “sacobra”, which interpolation method to use. In case of “scipy”, use SciPy’s RBFInterpolator (faster and simpler in code). In case of “sacobra”, use an object of class
RBFsacob, which is SACOBRA’s own implementation of RBF models (allows withdegree=1.5the option equivalent tosquares=Tin SACOBRA R, which means only pure squares in the polynomial tail).test_pmat – only for testing the RBFsacob implementation (degree=1, 1.5)
Parameter
kernelspecifies the kernel type and is one out of"cubic","quintic","thin_plate_spline","gaussian","multiquadric".scale-invariant kernel types:
"cubic","quintic","thin_plate_spline"scale-variant kernel types:
"gaussian","multiquadric"
- class opt.seqOptions.SEQoptions(optimizer='COBYLA', feMax=1000, tol=1e-06, conTol=0.0, penaF=[3.0, 1.7, 300000.0], sigmaD=[3.0, 2.0, 100], epsilonInit=None, epsilonMax=None, finalEpsXiZero=True, Tfeas=None, Tinfeas=None, trueFuncForSurrogates=False)
Options for the sequential optimization
- Parameters:
optimizer – string defining the optimization method for SACOBRA phase I and II. One out of [“COBYLA”,”ISRESN”] (see
SeqOptimizer)feMax – maximum number of function evaluations on the surrogate model
tol – convergence tolerance for sequential optimizer
conTol – constraint violation tolerance
penaF – (TODO)
sigmaD – (TODO)
epsilonInit – initial value for
EPS.EPSis a constant added to each constraint to maintain a certain margin to the boundary. If None, thenepsilonInitis set to \(0.005 \ell\), where \(\ell\) is the length of smallest side of search spaceepsilonMax – maximum value for
EPS. If None, thenepsilonMaxis set to \(2*0.005 \ell\).finalEpsXiZero – if True, set in final iteration
EPSandXIto zero for best exploitationTfeas – threshold for count of feasible iterations in a row. If None,
CobraInitializerwill set it to \(floor(2\sqrt{d})\).Tinfeas – threshold for count of infeasible iterations in a row. If None,
CobraInitializerwill set it to \(floor(2\sqrt{d})\).trueFuncForSurrogates – if True, use the true (constraint & fitness) functions instead of surrogates (only for debug analysis)
- class opt.equOptions.EQUoptions(active=True, initType='TAV', muType='expFunc', muDec=1.5, muFinal=1e-07, mu4inequality=False, muGrow=0, refine=True, refineMaxit=1000, refineAlgo='BFGS_0', refinePrint=False)
Equality handling options
- Parameters:
active – if set to TRUE, the equality-handling (EH) technique is activated. The EH technique transforms each equality constraint \(h(\mathbf{x})=0\) into two inequality constraints \(h(\mathbf{x})-\mu <0\) and \(-h(\mathbf{x})-\mu<0\) with an adaptive (normally decaying) margin \(\mu\).
initType – the equality margin \(\mu\) is initialized with one of these choices:
["TAV" | "TMV" | "EMV" | "useGrange"]muType – type of function used to shrink margin \(\mu\) during the optimization process. One out of
["SAexpFunc" | "expFunc" | "funcDim" | "funcSDim" | "Zhang" | "CONS"], seemodifyMuinequHandling.pymuDec – decay factor for margin \(\mu\), see
modifyMumuFinal – lower bound for margin \(\mu\).
muFinalshould be set to a small but non-zero value (larger than machine accuracy).muGrow – every
muGrow(e.g. 100) iterations, re-enlarge the \(\mu\)-band. If 0, then re-enlarge nevermu4inequality – use the artificial feasibility band also for inequalities (experimental)
refine – enables the refine step for equality handling
refineMaxit – maximum number of iterations used in the refine step. Note that the refine step runs on the surrogate models and does not impose any extra real function evaluations
refineAlgo – optimizer for refine step [“BFGS_0” | “BFGS_1” | “COBYQA” | “COBYLA”]
refinePrint – whether to print “cg-values (before,after,true)” after each refine step
- class opt.riOptions.RIoptions(repairInfeas=True, eps1=0.0001, eps2=0.0001, q=3.0, mmax=1000, gradEps=None, repairMargin=0.01, repairOnlyFresBetter=False, marFres=0.0, trueFuncForSurrogates=False, checkIt=False)
Options for
RI2(method to repair infeasible solutions)The infeasibility of a solution is its maximum constraint violation (0 for a feasible solution).
A solution \(x\) is \(\epsilon\)-feasible for constraint function \(g\) if \(g(x) + \epsilon < 0\).
- Parameters:
repairInfeas – switch to turn repair infeasible on or off
eps1 – include all constraints not
eps1-feasible into the repair mechanismeps2 – selects the solution with the shortest shift among all random realizations which are
eps2-feasibleq – draw coefficients \(\alpha_k\) from uniform distribution \(U[0, q]\)
mmax – draw
mmaxrandom realizationsgradEps – stepsize for numerical gradient calculation. If None, set it to 1/1000 of smallest search space box side
repairMargin – repair only solutions whose infeasibility is less than this margin
repairOnlyFresBetter – if True, then repair only iterates with
fitness < so-far-best-fitness + marFresmarFres – only relevant if
repairOnlyFresBetter==TruetrueFuncForSurrogates – use true constraint functions instead of constraint surrogates
checkIt – if true, print debug and check info
- class opt.isaOptions.ISAoptions(isa_ver=1, RS=True, RStype=RSTYPE.CONSTANT, RSauto=False, RSmax=0.3, RSmin=0.05, RS_Cs=10, RS_rep=False, RS_verb=False, aDRC=True, aFF=True, aCF=True, TFRange=100000.0, TGR=1000.0, adaptivePLOG=False, onlinePLOG=O_LOGIC.NONE, onlineFreqPLOG=10, pEffectInit=0, pEffNpts=3, pEff_DBG=False)
Internal self-adjusting (ISA) options for SACOBRA.
Defaults for
isa_ver=1(SACOBRA settings with fewer online adjustments). Other choices areisa_ver=0(ISAoptions0, COBRA-R settings = turn off SACOBRA), andisa_ver=2(ISAoptions2, SACOBRA settings with fewer parameters and more online adjustments).
The choice is made by choosing the appropriate class object
ISAoptions,ISAoptions0orISAoptions2forcobra.sac_opts.ISA.- Parameters:
isa_ver – ISA version number (was
DOSACin R)RS – flag to enable/disable random start algorithm
RStype – type of function to calculate probability to start the internal optimizer with a random start point. One out of [RSTYPE.CONSTANT, RSTYPE.SIGMOID]
RSauto –
RSmax – maximum probability of a random start
RSmin – minimum probability of a random start
RS_Cs – if RS_Cs iterations w/o progress, do a random start
RS_rep – if True, generate reproducible random numbers with my_rng2 (R and Python)
RS_verb – if True, be verbose in RandomStarter.random_start
aDRC – flag for automatic DRC adjustment
aFF – flag for automatic objective function transformation
aCF – flag for automatic constraint function transformation
TFRange – threshold, if the min-max-range of
Fres[0:idp]is larger thanTFRangeand ifonlinePLOG=NONE, then apply plog toFres(objective function values)TGR – threshold: If
GRatio > TGR, then apply automatic constraint function transformation.GRatiois the ratio “largest GR / smallest GR” where GR is the min-max range of a specific constraint. IfTGR < 1, then the transformation is always performed.adaptivePLOG – (experimental) flag for objective function transformation with
plog, where the parameterpShiftis adapted during iterationsonlinePLOG – three-valued logic for online decision-making:
O_LOGIC.NONE(no online, only fixed initial decision whether to use plog);O_LOGIC.XNEW(online plog decision according to pEffect, where pEffect-calculation is based on new infill pointxNew);O_LOGIC.MIDPTS(online plog decision according to pEffect, where pEffect-calculation is based on midpoints)onlineFreqPLOG – after how many iterations the surrogates for online plog check are calculated again (only relevant for case
O_LOGIC.XNEW)pEffectInit – the initial value for
pEffect, needed for first pass through cobraPhaseII while loop in caseO_LOGIC.XNEW. Not needed in casesO_LOGIC.NONEorO_LOGIC.MIDPTSpEffNpts – only for case
O_LOGIC.MIDPTS: the number p of initial design points to take from initial design matrixA: Form p*(p-1)/2 pairs and calculate the midpoints for all those pairspEff_DBG – temporary debug: replace xNew with a single midpoint (needed only by testCOP.py, which activates a certain branch in cobraPhaseII.py)
- class opt.isaOptions.ISAoptions0(isa_ver=0, RS=False, RStype=RSTYPE.CONSTANT, RSauto=False, RSmax=0.3, RSmin=0.05, RS_Cs=10, RS_rep=False, RS_verb=False, aDRC=False, aFF=False, aCF=False, TFRange=inf, TGR=inf, adaptivePLOG=False, onlinePLOG=O_LOGIC.NONE, onlineFreqPLOG=10, pEffectInit=0, pEffNpts=3, pEff_DBG=False)
Internal self-adjusting options for
isa_ver=0(COBRA-R settings = turn off SACOBRA).Differs only in default settings. The parameters and their meaning are the same as in
ISAoptions.
- class opt.isaOptions.ISAoptions2(isa_ver=2, RS=True, RStype=RSTYPE.CONSTANT, RSauto=True, RSmax=0.3, RSmin=0.05, RS_Cs=10, RS_rep=False, RS_verb=False, aDRC=True, aFF=True, aCF=True, TFRange=-1, TGR=-1, adaptivePLOG=False, onlinePLOG=O_LOGIC.NONE, onlineFreqPLOG=10, pEffectInit=3, pEffNpts=3, pEff_DBG=False)
Internal self-adjusting options for
isa_ver=2(SACOBRA with fewer parameters and more online adjustments).Differs only in default settings. The parameters and their meaning are the same as in
ISAoptions.