<jupyter_start><jupyter_text>Example 2: Iterative optimization of a function, which can be sampledIn this notebook the framework is used to iteratively optimize a function which can be sampled. For simplicity we will use a known function to illustrate, but it is not a requirement that the function can be written down explicitly as we do below. Hence, this option of using the framework allows for optimizing _unknown_ functions or _functions without explicit definitions_ and will come in handy for e.g. optimizing complex experiments. In the following we will use the same function as for Example 1$$f(x) = - (6x - 2)^2 \sin{(12 x - 4 )}, \quad x \in [0; 1].$$It is known that the function above has its maximum at $x^* = 0.75725$; the only covariate is $x$. Framework approachWe will leverage the iterative optimization approach of the framework which requires using the methods `.ask` and `.tell`. This approach allows for iterative optimization and optimization of any callable function, known or otherwise.The optimization process can be stopped after any number of iterations. Technical noteInstallation of `torch` and `torchvision` (required dependencies) cannot be bundled as part of the `creative_project` installable. This is unfortunate, but a known issue it seems. Therefore these must be installed first, before installing `creative_project`.<jupyter_code># Preamble

# Install torch and torchvision. Use this link to identify the right versions to install on your system 
# depending on configuration: https://pytorch.org/get-started/locally/
#
#pip install torch==1.6.0+cpu torchvision==0.7.0+cpu -f https://download.pytorch.org/whl/torch_stable.html
#
# Install creative_project from github (will require authentication with password)
#pip install --user https://github.com/svedel/kre8_core/
! pip install --user greattunes
# import
import numpy as np
import torch
from greattunes import TuneSession
import matplotlib.pyplot as plt
%matplotlib inline<jupyter_output><empty_output><jupyter_text>Define the problem to optimize. Here we define a known function, but it's not necessary that the function to optimize can be written down; all that's needed is that it can be sampled_Technical note_: Compared to Example 1 the objective function does not need to take a pandas dataframe as input, because we are not using the backend function evaluation of the `.auto`-method. For simplicity and illustrativeness we keep this function in `torch` tensor format, but the mathematics is the same as the objective function in Example 1.<jupyter_code>def f(x):
    return -(6*x - 2)**2*torch.sin(12*x-4)

x = torch.linspace(0,1)
plt.figure(figsize=(8, 4))
plt.plot(x.numpy(), f(x).numpy())
plt.show()<jupyter_output><empty_output><jupyter_text>Set up the problem<jupyter_code># define the range of the covariate 'x'
x_exp = 0.5  # start point for x (a priori expectation)
x_min = 0  # minimum allowed value of x
x_max = 1  # maximum allowed value of x
x_input=[(x_exp, x_min, x_max)]
# initialize class instance
cc = TuneSession(covars=x_input, model="SimpleCustomMaternGP", nu=2.5)<jupyter_output><empty_output><jupyter_text>Define the loop to solve iteratively. Here we use the option of adding the sampled covariates and associated response of the system (what we're using the function `f` for defined above) as input to `.tell`. If not added directly, `.tell` will prompt the user to provide sampled covariate points and responses at each iteration.<jupyter_code># iteration limit
max_iter = 25

# run the solution
for i in range(max_iter):

    # generate candidate
    cc.ask()

    # sample response
    covars = cc.proposed_X[-1].reshape(1,1) # reshape to tensor of size (#observations, #covariates)
    response = f(covars)

    # report response
    cc.tell(covar_obs=covars, response_obs=response)<jupyter_output><empty_output><jupyter_text>Best guess after solving<jupyter_code>cc.current_best()<jupyter_output><empty_output><jupyter_text>Plot the solution<jupyter_code>cc.plot_1d_latest()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.07926678226405746, 'fraction_numerical': 0.01164230864503344, 'mean_word_length': 5.241112828438949, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 25, 'https://': 3, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '85808', 'license': 'MIT', 'n_tokens_mistral': 1202, 'n_tokens_neox': 1139, 'n_words': 493, 'path': 'examples/Example 2 - Iterative optimization of function, which can be sampled.ipynb', 'repo_name': 'svedel/greattunes', 'size': '4037'}