Source code for pysmac.utils.pcs_merge
import re
[docs]def merge_configuration_spaces(*args, **kwargs):
"""
Convenience function to merge several algorithms with their respective config spaces into a single one.
Using pySMAC to optimize the parameters of a single function/algorithm
is a very important usecase, but finding the best algorithm and its
configuration across multiple choices. For example, when multiple different
algorithms can be used to solve the same problem, and it is unclear
which one will be the best choice.
The arguments to this function is a number of tuples, each with the
following content: (callable, pcs, conditionals, forbiddens). The
callable is a valid python function in the current namespace. The
Parameter Configuration Space (pcs) is the definition of its
parameters, while conditionals and forbiddens express dependencies and
restrictions within that space.
:returns: the merged configuration space, a list of conditionals, a list of forbiddens, and a string that defines two functions (see :ref:`merge_pcs`).
"""
names = []
parameters = {}
conditionals = []
forbiddens = []
# go through all the provided arguments
for (callabl, params, conds, forbs) in args:
# store callable's name
name = callabl.__name__
names.append(name)
# modify the parameter names
for p in params:
parameters[name + '_' + p] = params[p]
# modify existing conditionals
already_conditioned = set()
for c in conds:
c = c.strip(' ')
already_conditioned.update( (c.split('|')[0].strip(' '),))
for p in params:
c = (re.subn( p, name + '_' + p , c)[0])
conditionals.append( c.rstrip() + ' && algorithm == '+name)
# add new conditionals
for p in params:
if p not in already_conditioned:
conditionals.append(name + '_' + p + ' | algorithm == ' + name)
for f in forbs:
f = f.strip()
for p in params:
f = (re.subn( p, name + '_' + p , f)[0])
forbiddens.append(f)
parameters['algorithm'] = ('categorical', names, names[0])
wrapper_str="""import re
def pysmac_merged_pcs_reduce_args(algorithm=None, *args, **kwds):
# create a set of algorithm names to filter out the inactive parameters
names = %s"""%(names) + '\n\tcallables = [' + ",".join(names) + """]
# remove unused arguments
new_kwds = {}
for p in kwds:
is_algorithm_parameter = False
for a in names:
l = re.split(a+'_', p, maxsplit=1)
if len(l) == 2:
is_algorithm_parameter = True
if a == algorithm:
new_kwds[l[1]] = kwds[p]
break
if not is_algorithm_parameter:
new_kwds[p] = kwds[p]
i = names.index(algorithm)
return((callables[i], new_kwds))
def pysmac_merged_pcs_wrapper(algorithm=None, *args, **kwds):
call, args = pysmac_merged_pcs_reduce_args(algorithm = algorithm, *args, **kwds)
return(call(**args))"""
return(parameters, conditionals, forbiddens, wrapper_str)