Source code for bsmart.tools.toy_targets

"""
Tool to generate example optimisation targets


This tool defines example target functions that are commonly used to test Black Box optimisation algorithms.

The results are stored directly as observables:
* Rosenbrock
* Rastrigin
* Ackley
* Himmelblau
* Easom

So these can be obtained directly as observables using "FUNCTION": "Rosenbrock" etc; alternatively they can be obtained in the block TOYTARGETS:

Block TOYTARGETS 
  1  <>   # Rosenbrock function
  2  <>   # Rastrigin
  3  <>   # Ackley
  4  <>   # Himmelblau
  5  <>   # Easom

But be warned that no SLHA file is read or written for this tool: data is held in memory only. 

Note that, since the functions are positive-definite and supposed to be minimised, this is equivelent to a negative-log-likelihood, so they should be declared with scaling "MINUSEXPUSER" (since this would transform the value into a 'likelihood' between 0 and 1)

The following parameters can be configured in the settings for this tool:
* `Rosenbrock a`: The 'a' parameter for the Rosenbrock function (default: 1.0).
* `Rosenbrock b`: The 'b' parameter for the Rosenbrock function (default: 100.0).
* `Rastrigin A`: The 'A' parameter for the Rastrigin function (default: 10.0).
* `Ackley a`: The 'a' parameter for the Ackley function (default: 20.0).
* `Ackley b`: The 'b' parameter for the Ackley function (default: 0.2).
* `Ackley c`: The 'c' parameter for the Ackley function (default: 2*pi).
* `Himmelblau a`: The 'a' parameter for Himmelblau's function (default: 11.0).
* `Himmelblau b`: The 'b' parameter for Himmelblau's function (default: 7.0).
* `Easom center`: The [x, y] center for the Easom function (default: [pi, pi]).

Example usage in a BSMArt JSON file:
.. code-block:: json

    "Codes": {
            "toy_targets": {
                "Run": "True",
                "Rosenbrock a": 1.5,
                "Observables":
                {
                            "Rosen": {
                            "FUNCTION": "Rosenbrock",
                            "SCALING" : "MINUSEXPUSER"
                            },
                            "Rastrigin" : {
                            "SLHA":  [ "TOYTARGETS", [2]],
                            "SCALING": "MINUSEXPUSER"
                            }

                 }
            }



"""

__meta__ = {
 "name": "toy_targets",
 "requires": [],
 "settings": {
        'Rosenbrock a': "The 'a' parameter for the Rosenbrock function (default: 1.0).",
        'Rosenbrock b': "The 'b' parameter for the Rosenbrock function (default: 100.0).",
        'Rastrigin A': "The 'A' parameter for the Rastrigin function (default: 10.0).",
        'Ackley a': "The 'a' parameter for the Ackley function (default: 20.0).",
        'Ackley b': "The 'b' parameter for the Ackley function (default: 0.2).",
        'Ackley c': "The 'c' parameter for the Ackley function (default: 2*pi).",
        'Himmelblau a': "The 'a' parameter for Himmelblau's function (default: 11.0).",
        'Himmelblau b': "The 'b' parameter for Himmelblau's function (default: 7.0).",
        'Easom center': "The [x, y] center for the Easom function (default: [pi, pi])."
    }
}

import os

from bsmart import debug
from bsmart.HEPRun import HepTool, DataPoint
from bsmart import zslha


import math
[docs] class NewTool(HepTool): """ overload the init to initialise variables """ def __init__(self, name, settings,global_settings=None): HepTool.__init__(self, name, settings,global_settings) self.Rosenbrock_a = self.settings.get('Rosenbrock a',1.0) self.Rosenbrock_b = self.settings.get('Rosenbrock b',100.0) self.Rastrigin_A = self.settings.get('Rastrigin A', 10.0) self.Ackley_a = self.settings.get('Ackley a', 20.0) self.Ackley_b = self.settings.get('Ackley b', 0.2) self.Ackley_c = self.settings.get('Ackley c', 2.0 * math.pi) self.Himmelblau_a = self.settings.get('Himmelblau a', 11.0) self.Himmelblau_b = self.settings.get('Himmelblau b', 7.0) self.Easom_center = self.settings.get('Easom center', [math.pi, math.pi])
[docs] def run(self, spc_file, temp_dir, log,data_point): vars = data_point.inputs # don't care about the names! n = len(vars) x = vars blocks = {} blockcomments = {} if n > 0: # Rosenbrock function if n == 1: rosenbrock = (self.Rosenbrock_a - x[0])**2.0 else: # n > 1 rosenbrock = sum(self.Rosenbrock_b*(x[i+1]-x[i]**2.0)**2.0 + (self.Rosenbrock_a-x[i])**2.0 for i in range(n-1)) blocks['1'] = rosenbrock blockcomments['1'] = 'Rosenbrock function' data_point.obs_dict['Rosenbrock'] = rosenbrock # Rastrigin function rastrigin = self.Rastrigin_A*n + sum(xi**2 - self.Rastrigin_A * math.cos(2 * math.pi * xi) for xi in x) blocks['2'] = rastrigin blockcomments['2'] = 'Rastrigin function' data_point.obs_dict['Rastrigin'] = rastrigin # Ackley function sum_sq_term = 1.0/n * sum(xi**2 for xi in x) sum_cos_term = 1.0/n * sum(math.cos(self.Ackley_c*xi) for xi in x) ackley = -self.Ackley_a * math.exp(-self.Ackley_b * math.sqrt(sum_sq_term)) - math.exp(sum_cos_term) + self.Ackley_a + math.exp(1) blocks['3'] = ackley blockcomments['3'] = 'Ackley function' data_point.obs_dict['Ackley'] = ackley if n > 1: # Himmelblau's function himmelblau = (x[0]**2 + x[1] - self.Himmelblau_a)**2 + (x[0] + x[1]**2 - self.Himmelblau_b)**2 blocks['4'] = himmelblau blockcomments['4'] = "Himmelblau's function" data_point.obs_dict['Himmelblau'] = himmelblau # Easom function easom = -math.cos(x[0]) * math.cos(x[1]) * math.exp(-((x[0] - self.Easom_center[0])**2 + (x[1] - self.Easom_center[1])**2)) blocks['5'] = easom blockcomments['5'] = "Easom function" data_point.obs_dict['Easom'] = easom data_point.spc = zslha.SLHA() data_point.spc.blocks['TOYTARGETS']=blocks data_point.spc.blockcomments['TOYTARGETS']=blockcomments return