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)

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)

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