def val_rank(pds, dim=None, funcId=None, groupby=None): if groupby is None: groupby = np.median pfsize = len(pds.algds.keys()) try: # funcId is array? # _pds_plot_iterator[] uses funcId only for things we don't care for fakeFuncId = funcId[0] manyranking = np.array([pds.ranking((dim, i), groupby) for i in funcId]) rankcount = np.shape(manyranking[0])[1] - 1 amanyranking = ra.alignArrayData(ra.VArrayMultiReader(manyranking)) budget = amanyranking[:,0] rankings = np.hsplit(amanyranking[:,1:], len(funcId)) avgranking = np.average(rankings, axis=0) ranking = np.vstack([budget, avgranking.T]).T except TypeError: # funcId is scalar fakeFuncId = funcId ranking = pds.ranking((dim, funcId), groupby) ranks = [] i = 0 for (kind, name, ds) in _pds_table_iterator(pds, dim, fakeFuncId): ranks.append(tuple(ranking[-1,1+i])) i += 1 return ranks
def val_rank(pds, dim=None, funcId=None, groupby=None): if groupby is None: groupby = np.median pfsize = len(pds.algds.keys()) try: # funcId is array? # _pds_plot_iterator[] uses funcId only for things we don't care for fakeFuncId = funcId[0] manyranking = np.array( [pds.ranking((dim, i), groupby) for i in funcId]) rankcount = np.shape(manyranking[0])[1] - 1 amanyranking = ra.alignArrayData(ra.VArrayMultiReader(manyranking)) budget = amanyranking[:, 0] rankings = np.hsplit(amanyranking[:, 1:], len(funcId)) avgranking = np.average(rankings, axis=0) ranking = np.vstack([budget, avgranking.T]).T except TypeError: # funcId is scalar fakeFuncId = funcId ranking = pds.ranking((dim, funcId), groupby) ranks = [] i = 0 for (kind, name, ds) in _pds_table_iterator(pds, dim, fakeFuncId): ranks.append(tuple(ranking[-1, 1 + i])) i += 1 return ranks
def alignData(i0, i1): """Returns two arrays of fevals aligned on function evaluations. """ res = readalign.alignArrayData( readalign.HArrayMultiReader([i0.evals, i1.evals])) idx = 1 + i0.nbRuns() data0 = res[:, np.r_[0, 1:idx]] data1 = res[:, np.r_[0, idx:idx + i1.nbRuns()]] return data0, data1
def alignData(i0, i1): """Returns two arrays of fevals aligned on function evaluations. """ res = readalign.alignArrayData(readalign.HArrayMultiReader([i0.evals, i1.evals])) idx = 1 + i0.nbRuns() data0 = res[:, np.r_[0, 1:idx]] data1 = res[:, np.r_[0, idx:idx+i1.nbRuns()]] return data0, data1
def ranking(self, dimfun, groupby, ftarget=10**-8): """ Produce a set of function evaluation ranks over all algorithms and strategies. Returns a set of rows where each row contains a budget as first element and ranks for individual algorithms and strategies as the second element (in the order of the strategies in the output of algds_dimfunc(), and stratds_dimfunc() respectively). The ranks are always computed based on function values after a particular budget. If multiple algorithms reach ftarget, they are ranked by the order in which they did. """ nameds = list( itertools.chain(self.algds_dimfunc(dimfun), self.stratds_dimfunc(dimfun))) count = len(nameds) # Produce "fv" items, one per dataset, containing single function value # for each budget fvset = [] for (name, ds) in nameds: budgets = ds.funvals[:, 0] f1vals = np.maximum(groupby(ds.funvals[:, 1:], axis=1), ftarget) fv = np.transpose(np.vstack([budgets, f1vals])) fvset.append(fv) # Align the "fv" items by budget and merge them fva = ra.alignArrayData(ra.VArrayMultiReader(fvset)) budgets = fva[:, 0] # Assign function values and rank them # However, we want to resolve eventual ties by ranking first # converging function first. So we do a trick and rewrite ftarget # values in increasing convergence sort order. values = fva[:, 1:].copy() firstconv = np.ones(count) * (np.size(budgets) + 1 ) # runlength+1 is default for i in range(count): # XXX: drop the loop try: firstconv[i] = np.nonzero(values[:, i] == ftarget)[0][0] except IndexError: continue # no rewriting needed firstconvranks = ss.mstats.rankdata(firstconv) for i in range(count): r = firstconvranks[i] values[firstconv[i]:, i] = ftarget - (1 - r / count) * ftarget ranks = ss.mstats.rankdata(values, axis=1) return np.transpose(np.vstack([budgets, ranks.T]))
def fval_by_budget(ax, pds, baseline_ds=None, baseline_label="", dim=None, funcId=None, groupby=None): """ Plot a classic "convergence plot" that shows how the function value approaches optimum as time passes, in terms of raw performance. groupby is the method of aggregating results of multiple instances -- a callable, stringable object, GroupByMedian by default. By default, raw function values (as difference to optimum) are shown, but relative values to some baseline dataset can be shown instead. """ if groupby is None: groupby = GroupByMedian() pfsize = len(pds.algds.keys()) if baseline_ds: baseline_budgets = baseline_ds.funvals[:, 0] baseline_funvals = groupby(baseline_ds.funvals[:, 1:], axis=1) baseline_safefunvals = np.maximum(baseline_funvals, 10**-8) # eschew zeros # fvb is matrix with each row being [budget,funval] baseline_fvb = np.transpose(np.vstack([baseline_budgets, baseline_safefunvals])) for (kind, name, ds, style) in _pds_plot_iterator(pds, dim, funcId): #print name, ds budgets = ds.funvals[:, 0] funvals = groupby(ds.funvals[:, 1:], axis=1) # Throw away funvals after ftarget reached try: limit = np.nonzero(funvals < 10**-8)[0][0] + 1 except IndexError: limit = np.size(budgets)+1 budgets = budgets[:limit] funvals = funvals[:limit] fvb = np.transpose(np.vstack([budgets[:limit], funvals[:limit]])) if baseline_ds: # Relativize by baseline fvba = ra.alignArrayData(ra.VArrayMultiReader([fvb, baseline_fvb])) budgets = fvba[:, 0] funvals = fvba[:, 1] / fvba[:, 2] style['markevery'] = 16 ax.loglog(budgets, funvals, label=name, basex=pfsize, **style) if baseline_ds: ax.set_yticks([1], minor=True) ax.set_xlabel('Budget') ax.set_ylabel(_fval_label(baseline_ds, baseline_label, str(groupby))) ax.grid() if baseline_ds: ax.yaxis.grid(True, which = 'minor')
def append(self, o): """Redefines the append method to check for unicity.""" if not isinstance(o, DataSet): raise Exception() isFound = False for i in self: if i == o: isFound = True tmp = set(i.dataFiles).symmetric_difference(set(o.dataFiles)) #Check if there are new data considered. if tmp: i.dataFiles.extend(tmp) i.indexFiles.extend(o.indexFiles) i.funvals = alignArrayData( VArrayMultiReader([i.funvals, o.funvals])) i.finalfunvals = numpy.r_[i.finalfunvals, o.finalfunvals] i.evals = alignArrayData( HArrayMultiReader([i.evals, o.evals])) i.maxevals = numpy.r_[i.maxevals, o.maxevals] i.computeERTfromEvals() if getattr(i, 'pickleFile', False): i.modsFromPickleVersion = True for j in dir(i): if isinstance(getattr(i, j), list): getattr(i, j).extend(getattr(o, j)) else: if getattr(i, 'pickleFile', False): i.modsFromPickleVersion = False elif getattr(o, 'pickleFile', False): i.modsFromPickleVersion = False i.pickleFile = o.pickleFile break if not isFound: list.append(self, o)
def ranking(self, dimfun, groupby, ftarget=10**-8): """ Produce a set of function evaluation ranks over all algorithms and strategies. Returns a set of rows where each row contains a budget as first element and ranks for individual algorithms and strategies as the second element (in the order of the strategies in the output of algds_dimfunc(), and stratds_dimfunc() respectively). The ranks are always computed based on function values after a particular budget. If multiple algorithms reach ftarget, they are ranked by the order in which they did. """ nameds = list(itertools.chain(self.algds_dimfunc(dimfun), self.stratds_dimfunc(dimfun))) count = len(nameds) # Produce "fv" items, one per dataset, containing single function value # for each budget fvset = [] for (name, ds) in nameds: budgets = ds.funvals[:,0] f1vals = np.maximum(groupby(ds.funvals[:, 1:], axis=1), ftarget) fv = np.transpose(np.vstack([budgets, f1vals])) fvset.append(fv) # Align the "fv" items by budget and merge them fva = ra.alignArrayData(ra.VArrayMultiReader(fvset)) budgets = fva[:,0] # Assign function values and rank them # However, we want to resolve eventual ties by ranking first # converging function first. So we do a trick and rewrite ftarget # values in increasing convergence sort order. values = fva[:,1:].copy() firstconv = np.ones(count) * (np.size(budgets)+1) # runlength+1 is default for i in range(count): # XXX: drop the loop try: firstconv[i] = np.nonzero(values[:,i] == ftarget)[0][0] except IndexError: continue # no rewriting needed firstconvranks = ss.mstats.rankdata(firstconv) for i in range(count): r = firstconvranks[i] values[firstconv[i]:, i] = ftarget - (1-r/count)*ftarget ranks = ss.mstats.rankdata(values, axis=1) return np.transpose(np.vstack([budgets, ranks.T]))
def rank_by_budget(ax, pds, dim=None, funcId=None, groupby=None): """ Plot each algorithm/method's rank evolving as budget increases. groupby is the method of aggregating results of multiple instances -- a callable, stringable object, GroupByMedian by default. Note that funcId may be an array of id numbers; in that case, an average rank over listed functions is taken. """ if groupby is None: groupby = GroupByMedian() pfsize = len(pds.algds.keys()) try: # funcId is array? # _pds_plot_iterator[] uses funcId only for things we don't care for fakeFuncId = funcId[0] manyranking = np.array([pds.ranking((dim, i), groupby) for i in funcId]) rankcount = np.shape(manyranking[0])[1] - 1 amanyranking = ra.alignArrayData(ra.VArrayMultiReader(manyranking)) budget = amanyranking[:,0] rankings = np.hsplit(amanyranking[:,1:], len(funcId)) avgranking = np.average(rankings, axis=0) ranking = np.vstack([budget, avgranking.T]).T except TypeError: # funcId is scalar fakeFuncId = funcId ranking = pds.ranking((dim, funcId), groupby) i = 0 for (kind, name, ds, style) in _pds_plot_iterator(pds, dim, fakeFuncId): if kind != 'algorithm' and kind != 'strategy': continue #print name, ds budgets = ranking[:,0] ranks = ranking[:,1+i] style['markevery'] = 64 ax.plot(budgets, ranks, label=name, **style) i += 1 ax.set_xlabel('Budget') ax.set_ylabel('Rank by '+str(groupby).title()+' Function Value') ax.set_xscale('log', basex=pfsize) ax.grid()
def generateData(ds0, ds1): #Align ert arrays on targets array0 = numpy.vstack([ds0.target, ds0.ert]).transpose() array1 = numpy.vstack([ds1.target, ds1.ert]).transpose() data = readalign.alignArrayData(readalign.HArrayMultiReader([array0, array1])) #Downsample? adata = data[data[:, 0]<=10, :] try: adata = adata[adata[:, 0]>=1e-8, :] except IndexError: #empty data pass #set_trace() targets = adata[:, 0] ert0 = adata[:, 1] ert1 = adata[:, 2] return targets, ert0, ert1
def __init__(self, dslist): """Instantiate one algorithm portfolio data set. :param dict dslist: list of :py:class:`pproc.DataSetList` instances. """ def _conv_evals(evals, algnb, maxevals): if evals > maxevals[algnb]: return np.nan res = 0. mevals = np.asarray(maxevals) if evals > len(maxevals) or not isinstance(evals, int): smevals = np.sort(mevals) for i in smevals: res += min(evals - 1, i) else: for i in range(1, evals): res += np.sum(i <= mevals) res += np.sum(evals <= mevals[:algnb+1]) return res # Checking procedure d = set() f = set() trials = [] for i in dslist: d.add(i.dim) f.add(i.funcId) trials.append(i.createDictInstanceCount()) if len(f) > 1 or len(d) > 1: raise Usage('%s: Expect the data of algorithms for only one ' 'function and one dimension.' % (dslist)) elif trials[1:] != trials[:-1]: # this check will be superfluous if we find that all instances # are equivalent. # raise Usage('%s: Expect the data to have the same instances.' # % (dslist)) warnings.warn('portfolio will be generated from algorithm with different instances') self.dim = d.pop() self.funcId = f.pop() algId = [] comment = [] for i in dslist: algId.append(i.algId) comment.append(i.comment) self.algId = tuple(algId) self.comment = tuple(comment) # Data handling nbruns = dslist[0].nbRuns() # all data sets have the same #runs corresp = [[]] * len(dslist) if False: # find correspondence with respect to first element in dslist dictref = dslist[0].createDictInstance() for i, ds in enumerate(dslist): tmpdict = ds.createDictInstance() for j in sorted(dictref): corresp[i].extend(tmpdict[j]) else: for i in range(len(dslist)): corresp[i] = range(nbruns) self.instancenumbers = trials.pop() maxevals = [] finalfunvals = [] evals = [] funvals = [] for i in range(nbruns): tmpmaxevals = [] tmpfinalfunvals = [] tmpevals = [] tmpfunvals = [] for j, ds in enumerate(dslist): tmpmaxevals.append(ds.maxevals[corresp[j][i]]) tmpfinalfunvals.append(ds.finalfunvals[corresp[j][i]]) tmpevals.append(ds.evals[:, np.r_[0, corresp[j][i]+1]]) tmpfunvals.append(ds.funvals[:, np.r_[0, corresp[j][i]+1]].copy()) maxevals.append(np.sum(tmpmaxevals)) finalfunvals.append(min(tmpfinalfunvals)) tmpevals = ra.alignArrayData(ra.HArrayMultiReader(tmpevals)) tmpres = [] for j in tmpevals: tmp = [] for k, e in enumerate(j[1:]): tmp.append(_conv_evals(e, k, tmpmaxevals)) tmpres.append(min(tmp)) evals.append(np.column_stack((tmpevals[:, 0], tmpres))) for j, a in enumerate(tmpfunvals): for k in range(len(a[:, 0])): a[k, 0] = _conv_evals(a[k, 0], j, tmpmaxevals) tmpfunvals = ra.alignArrayData(ra.VArrayMultiReader(tmpfunvals)) tmpres = [] for j in tmpfunvals: tmpres.append(min(j[1:])) funvals.append(np.column_stack((tmpfunvals[:, 0], tmpres))) self.maxevals = np.array(maxevals) self.finalfunvals = np.array(finalfunvals) self.evals = ra.alignArrayData(ra.HArrayMultiReader(evals)) self.funvals = ra.alignArrayData(ra.VArrayMultiReader(funvals)) self.computeERTfromEvals()
def __init__(self, dictAlg): """Instantiate one best algorithm data set. :keyword dictAlg: dictionary of datasets, keys are algorithm names, values are 1-element :py:class:`DataSetList`. """ # values of dict dictAlg are DataSetList which should have only one # element which will be assigned as values in the following lines. d = set() f = set() for i in dictAlg.values(): d |= set(j.dim for j in i) f |= set(j.funcId for j in i) if len(f) > 1 or len(d) > 1: Usage('Expect the data of algorithms for only one function and ' 'one dimension.') f = f.pop() d = d.pop() dictMaxEvals = {} dictFinalFunVals = {} tmpdictAlg = {} for alg, i in dictAlg.iteritems(): if len(i) == 0: warnings.warn('Algorithm %s was not tested on f%d %d-D.' % (alg, f, d)) continue elif len(i) > 1: warnings.warn('Algorithm %s has a problem on f%d %d-D.' % (alg, f, d)) continue tmpdictAlg[alg] = i[0] # Assign ONLY the first element as value dictMaxEvals[alg] = i[0].maxevals dictFinalFunVals[alg] = i[0].finalfunvals dictAlg = tmpdictAlg sortedAlgs = dictAlg.keys() # algorithms will be sorted along sortedAlgs which is now a fixed list # Align ERT erts = list(np.transpose(np.vstack([dictAlg[i].target, dictAlg[i].ert])) for i in sortedAlgs) res = readalign.alignArrayData(readalign.HArrayMultiReader(erts, False)) resalgs = [] reserts = [] # For each function value for i in res: # Find best algorithm curerts = i[1:] assert len((np.isnan(curerts) == False)) > 0 currentbestert = np.inf currentbestalg = '' for j, tmpert in enumerate(curerts): if np.isnan(tmpert): continue # TODO: don't disregard these entries if tmpert == currentbestert: # TODO: what do we do in case of ties? # look at function values corresponding to the ERT? # Look at the function evaluations? the success ratio? pass elif tmpert < currentbestert: currentbestert = tmpert currentbestalg = sortedAlgs[j] reserts.append(currentbestert) resalgs.append(currentbestalg) dictiter = {} dictcurLine = {} resDataSet = [] # write down the #fevals to reach the function value. for funval, alg in zip(res[:, 0], resalgs): it = dictiter.setdefault(alg, iter(dictAlg[alg].evals)) curLine = dictcurLine.setdefault(alg, np.array([np.inf, 0])) while curLine[0] > funval: try: curLine = it.next() except StopIteration: break dictcurLine[alg] = curLine.copy() tmp = curLine.copy() tmp[0] = funval resDataSet.append(tmp) setalgs = set(resalgs) dictFunValsNoFail = {} for alg in setalgs: if not dictAlg[alg].isBiobjective(): for curline in dictAlg[alg].funvals: if (curline[1:] == dictAlg[alg].finalfunvals).any(): # only works because the funvals are monotonous break dictFunValsNoFail[alg] = curline.copy() self.evals = resDataSet # evals is not a np array but a list of arrays because they may not # all be of the same size. self.maxevals = dict((i, dictMaxEvals[i]) for i in setalgs) self.finalfunvals = dict((i, dictFinalFunVals[i]) for i in setalgs) self.funvalsnofail = dictFunValsNoFail self.dim = d self.funcId = f self.algs = resalgs self.algId = 'Virtual Best Algorithm' self.comment = 'Combination of ' + ', '.join(sortedAlgs) self.ert = np.array(reserts) self.target = res[:, 0] bestfinalfunvals = np.array([np.inf]) for alg in sortedAlgs: if np.median(dictAlg[alg].finalfunvals) < np.median(bestfinalfunvals): bestfinalfunvals = dictAlg[alg].finalfunvals algbestfinalfunvals = alg self.bestfinalfunvals = bestfinalfunvals self.algbestfinalfunvals = algbestfinalfunvals
def __init__(self, dictAlg): """Instantiate one best algorithm data set. :keyword dictAlg: dictionary of datasets, keys are algorithm names, values are 1-element :py:class:`DataSetList`. """ # values of dict dictAlg are DataSetList which should have only one # element which will be assigned as values in the following lines. d = set() f = set() for i in dictAlg.values(): d |= set(j.dim for j in i) f |= set(j.funcId for j in i) if len(f) > 1 or len(d) > 1: Usage('Expect the data of algorithms for only one function and ' 'one dimension.') f = f.pop() d = d.pop() dictMaxEvals = {} dictFinalFunVals = {} tmpdictAlg = {} for alg, i in dictAlg.iteritems(): if len(i) == 0: warnings.warn('Algorithm %s was not tested on f%d %d-D.' % (alg, f, d)) continue elif len(i) > 1: warnings.warn('Algorithm %s has a problem on f%d %d-D.' % (alg, f, d)) continue tmpdictAlg[alg] = i[0] # Assign ONLY the first element as value dictMaxEvals[alg] = i[0].maxevals dictFinalFunVals[alg] = i[0].finalfunvals dictAlg = tmpdictAlg sortedAlgs = dictAlg.keys() # algorithms will be sorted along sortedAlgs which is now a fixed list # Align ERT erts = list(np.transpose(np.vstack([dictAlg[i].target, dictAlg[i].ert])) for i in sortedAlgs) res = readalign.alignArrayData(readalign.HArrayMultiReader(erts)) resalgs = [] reserts = [] # For each function value for i in res: # Find best algorithm curerts = i[1:] assert len((np.isnan(curerts) == False)) > 0 currentbestert = np.inf currentbestalg = '' for j, tmpert in enumerate(curerts): if np.isnan(tmpert): continue # TODO: don't disregard these entries if tmpert == currentbestert: # TODO: what do we do in case of ties? # look at function values corresponding to the ERT? # Look at the function evaluations? the success ratio? pass elif tmpert < currentbestert: currentbestert = tmpert currentbestalg = sortedAlgs[j] reserts.append(currentbestert) resalgs.append(currentbestalg) dictiter = {} dictcurLine = {} resDataSet = [] # write down the #fevals to reach the function value. for funval, alg in zip(res[:, 0], resalgs): it = dictiter.setdefault(alg, iter(dictAlg[alg].evals)) curLine = dictcurLine.setdefault(alg, np.array([np.inf, 0])) while curLine[0] > funval: try: curLine = it.next() except StopIteration: break dictcurLine[alg] = curLine.copy() tmp = curLine.copy() tmp[0] = funval resDataSet.append(tmp) setalgs = set(resalgs) dictFunValsNoFail = {} for alg in setalgs: for curline in dictAlg[alg].funvals: if (curline[1:] == dictAlg[alg].finalfunvals).any(): # only works because the funvals are monotonous break dictFunValsNoFail[alg] = curline.copy() self.evals = resDataSet # evals is not a np array but a list of arrays because they may not # all be of the same size. self.maxevals = dict((i, dictMaxEvals[i]) for i in setalgs) self.finalfunvals = dict((i, dictFinalFunVals[i]) for i in setalgs) self.funvalsnofail = dictFunValsNoFail self.dim = d self.funcId = f self.algs = resalgs self.algId = 'Virtual Best Algorithm of BBOB' self.comment = 'Combination of ' + ', '.join(sortedAlgs) self.ert = np.array(reserts) self.target = res[:, 0] bestfinalfunvals = np.array([np.inf]) for alg in sortedAlgs: if np.median(dictAlg[alg].finalfunvals) < np.median(bestfinalfunvals): bestfinalfunvals = dictAlg[alg].finalfunvals algbestfinalfunvals = alg self.bestfinalfunvals = bestfinalfunvals self.algbestfinalfunvals = algbestfinalfunvals
def __init__(self, dictAlg): # values of dict dictAlg are DataSetList which should have only one # element which will be assigned as values in the following lines. d = set() f = set() for i in dictAlg.values(): d |= set(j.dim for j in i) f |= set(j.funcId for j in i) if len(f) > 1 or len(d) > 1: #set_trace() Usage( 'Expect the data of algorithms for only one function and one dimension.' ) f = f.pop() d = d.pop() dictMaxEvals = {} dictFinalFunVals = {} tmpdictAlg = {} for alg, i in dictAlg.iteritems(): if len(i) != 1: # Special case could occur? txt = ('Algorithm %s has problem in this case: f%d %d-D.' % (alg, f, d)) warnings.warn(txt) continue tmpdictAlg[alg] = i[0] # Assign the first element as value for alg dictMaxEvals[alg] = i[0].maxevals dictFinalFunVals[alg] = i[0].finalfunvals dictAlg = tmpdictAlg sortedAlgs = dictAlg.keys() # get a fixed list of the algs, algorithms will be sorted along sortedAlgs #Align ERT erts = list( numpy.transpose(numpy.vstack([dictAlg[i].target, dictAlg[i].ert])) for i in sortedAlgs) res = readalign.alignArrayData(readalign.HArrayMultiReader(erts)) resalgs = [] reserts = [] #Foreach function value for i in res: #find best algorithm curerts = i[1:] assert len((numpy.isnan(curerts) == False)) > 0 currentbestert = numpy.inf currentbestalg = '' #currentbestval = dictMaxEvals[alg] for j, tmpert in enumerate(curerts): if numpy.isnan(tmpert): continue if tmpert == currentbestert: # in case of tie? TODO: look at function values corresponding to the ERT? # Look at the function evaluations? the success ratio? pass elif tmpert < currentbestert: currentbestert = tmpert currentbestalg = sortedAlgs[j] reserts.append(currentbestert) resalgs.append(currentbestalg) dictiter = {} dictcurLine = {} resDataSet = [] #write down the #fevals to reach the function value. for funval, alg in zip(res[:, 0], resalgs): it = dictiter.setdefault(alg, iter(dictAlg[alg].evals)) curLine = dictcurLine.setdefault(alg, numpy.array([numpy.inf, 0])) while curLine[0] > funval: try: curLine = it.next() except StopIteration: break dictcurLine[alg] = curLine.copy() tmp = curLine.copy() tmp[0] = funval resDataSet.append(tmp) setalgs = set(resalgs) dictFunValsNoFail = {} for alg in setalgs: for curline in dictAlg[alg].funvals: if (curline[1:] == dictAlg[alg].finalfunvals).any(): # only works because the funvals are monotonous break dictFunValsNoFail[alg] = curline.copy() self.evals = resDataSet # evals is not a numpy array but a list of arrays because they may not # all be of the same size. self.maxevals = dict((i, dictMaxEvals[i]) for i in setalgs) self.finalfunvals = dict((i, dictFinalFunVals[i]) for i in setalgs) self.funvalsnofail = dictFunValsNoFail self.dim = d self.funcId = f # What if some algorithms don't have the same number of runs # How do we save maxfunevals (to compute the ERT...?) self.algs = resalgs self.algId = 'Virtual Best Algorithm of BBOB 2009' self.comment = 'Combination of ' + ', '.join(algs) self.ert = numpy.array(reserts) self.target = res[:, 0] #return resds bestfinalfunvals = numpy.array([numpy.inf]) for alg in sortedAlgs: if numpy.median(dictAlg[alg].finalfunvals) < numpy.median( bestfinalfunvals): bestfinalfunvals = dictAlg[alg].finalfunvals algbestfinalfunvals = alg self.bestfinalfunvals = bestfinalfunvals self.algbestfinalfunvals = algbestfinalfunvals