six_hump_camel

This module contains various versions that evaluate the six-hump camel function.

Six-hump camel function is documented here:

https://www.sfu.ca/~ssurjano/camel6.html

six_hump_camel.six_hump_camel(H, persis_info, sim_specs, libE_info)

Input Fields: ['x']

Output Datatypes: [('f', <class 'float'>)]

Evaluates the six hump camel function for a collection of points given in H["x"]. Additionally evaluates the gradient if "grad" is a field in sim_specs["out"] and pauses for sim_specs["user"]["pause_time"]] if defined.

six_hump_camel.six_hump_camel_simple(x, _, sim_specs)

Input Fields: ['x']

Output Datatypes: [('f', <class 'float'>)]

Evaluates the six hump camel function for a single point x.

six_hump_camel.persistent_six_hump_camel(H, persis_info, sim_specs, libE_info)

Similar to six_hump_camel, but runs in persistent mode.

six_hump_camel.py
  1"""
  2This module contains various versions that evaluate the six-hump camel function.
  3
  4Six-hump camel function is documented here:
  5  https://www.sfu.ca/~ssurjano/camel6.html
  6
  7"""
  8
  9__all__ = [
 10    "six_hump_camel",
 11    "six_hump_camel_simple",
 12    "persistent_six_hump_camel",
 13]
 14
 15import sys
 16import time
 17
 18import numpy as np
 19
 20from libensemble.message_numbers import EVAL_SIM_TAG, FINISHED_PERSISTENT_SIM_TAG, PERSIS_STOP, STOP_TAG
 21from libensemble.specs import input_fields, output_data
 22from libensemble.tools.persistent_support import PersistentSupport
 23
 24
 25@input_fields(["x"])
 26@output_data([("f", float)])
 27def six_hump_camel(H, persis_info, sim_specs, libE_info):
 28    """
 29    Evaluates the six hump camel function for a collection of points given in ``H["x"]``.
 30    Additionally evaluates the gradient if ``"grad"`` is a field in
 31    ``sim_specs["out"]`` and pauses for ``sim_specs["user"]["pause_time"]]`` if
 32    defined.
 33
 34    .. seealso::
 35        `test_uniform_sampling.py  <https://github.com/Libensemble/libensemble/blob/develop/libensemble/tests/functionality_tests/test_uniform_sampling.py>`_ # noqa
 36    """
 37
 38    batch = len(H["x"])
 39    H_o = np.zeros(batch, dtype=sim_specs["out"])
 40
 41    for i, x in enumerate(H["x"]):
 42        H_o["f"][i] = six_hump_camel_func(x)
 43
 44        if "grad" in H_o.dtype.names:
 45            H_o["grad"][i] = six_hump_camel_grad(x)
 46
 47        if "user" in sim_specs and "pause_time" in sim_specs["user"]:
 48            time.sleep(sim_specs["user"]["pause_time"])
 49
 50    return H_o, persis_info
 51
 52
 53@input_fields(["x"])
 54@output_data([("f", float)])
 55def six_hump_camel_simple(x, _, sim_specs):
 56    """
 57    Evaluates the six hump camel function for a single point ``x``.
 58
 59    .. seealso::
 60        `test_fast_alloc.py <https://github.com/Libensemble/libensemble/blob/develop/libensemble/tests/functionality_tests/test_fast_alloc.py>`_ # noqa
 61    """
 62
 63    H_o = np.zeros(1, dtype=sim_specs["out"])
 64
 65    H_o["f"] = six_hump_camel_func(x[0][0][:2])  # Ignore more than 2 entries of x
 66
 67    if sim_specs["user"].get("pause_time"):
 68        time.sleep(sim_specs["user"]["pause_time"])
 69
 70    if sim_specs["user"].get("rand"):
 71        H_o["f"] += np.random.normal(0, 1)
 72
 73    return H_o
 74
 75
 76def persistent_six_hump_camel(H, persis_info, sim_specs, libE_info):
 77    """
 78    Similar to ``six_hump_camel``, but runs in persistent mode.
 79    """
 80
 81    ps = PersistentSupport(libE_info, EVAL_SIM_TAG)
 82
 83    # Either start with a work item to process - or just start and wait for data
 84    if H.size > 0:
 85        tag = None
 86        Work = None
 87        calc_in = H
 88    else:
 89        tag, Work, calc_in = ps.recv()
 90
 91    while tag not in [STOP_TAG, PERSIS_STOP]:
 92        # calc_in: This should either be a function (unpack_work ?) or included/unpacked in ps.recv/ps.send_recv.
 93        if Work is not None:
 94            persis_info = Work.get("persis_info", persis_info)
 95            libE_info = Work.get("libE_info", libE_info)
 96
 97        # Call standard six_hump_camel sim
 98        H_o, persis_info = six_hump_camel(calc_in, persis_info, sim_specs, libE_info)
 99
100        tag, Work, calc_in = ps.send_recv(H_o)
101
102    final_return = None
103
104    # Overwrite final point - for testing only
105    if sim_specs["user"].get("replace_final_fields", 0):
106        calc_in = np.ones(1, dtype=[("x", float, (2,))])
107        H_o, persis_info = six_hump_camel(calc_in, persis_info, sim_specs, libE_info)
108        final_return = H_o
109
110    return final_return, persis_info, FINISHED_PERSISTENT_SIM_TAG
111
112
113def six_hump_camel_func(x):
114    """
115    Definition of the six-hump camel
116    """
117    x1 = x[0]
118    x2 = x[1]
119    term1 = (4 - 2.1 * x1**2 + (x1**4) / 3) * x1**2
120    term2 = x1 * x2
121    term3 = (-4 + 4 * x2**2) * x2**2
122
123    return term1 + term2 + term3
124
125
126def six_hump_camel_grad(x):
127    """
128    Definition of the six-hump camel gradient
129    """
130
131    x1 = x[0]
132    x2 = x[1]
133    grad = np.zeros(2)
134
135    grad[0] = 2.0 * (x1**5 - 4.2 * x1**3 + 4.0 * x1 + 0.5 * x2)
136    grad[1] = x1 + 16 * x2**3 - 8 * x2
137
138    return grad
139
140
141if __name__ == "__main__":
142    x = (float(sys.argv[1]), float(sys.argv[2]))
143    result = six_hump_camel_func(x)
144    print(result)