Commit 0a3fc5ae authored by Christoph Freysoldt's avatar Christoph Freysoldt
Browse files

tutorial files

parent 43274f6c
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "QHJs6azjC8Il"
},
"source": [
"# Tutorial 1: Introduction to active learning with Bayesian Optimization"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "i_kyWo5KFGQj"
},
"source": [
"## The principles Bayesian Optimization"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"On binder, we can just render any image (from the git repo or generated by BOSS) using markdown like so:\n",
"![](figs/example.png)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "hlWKlGryC8In",
"lines_to_next_cell": 2
},
"source": [
"## 1D example of Bayesian Optimization\n",
"A one dimensional problem is the simplest case to solve with BOSS. By looking at the plotted GP models step-by-step,\n",
"it is transparent what is going on in BOSS. Studying a 1D case is also often a part of solving a bigger optimization\n",
"problem, as short 1D searches of each simulation variable separately gives important insight on how to set up the large problem. In this demo the target function is"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Brbyz6tyC8Io"
},
"source": [
"This is a Gaussian added to a sine wave, which makes up a fairly simple but not trivial non-periodic 1D function. The\n",
"domain of the variable x is [0, 7] by defition, and because of the sine, the values of f(x) are known to be roughly within [􀀀1; 1]. Since we have an anlytic expression for the true function we can go ahead and plot it:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"executionInfo": {
"elapsed": 6370,
"status": "ok",
"timestamp": 1630579817024,
"user": {
"displayName": "Joakim Löfgren",
"photoUrl": "https://lh3.googleusercontent.com/a/default-user=s64",
"userId": "04244087693112310568"
},
"user_tz": -180
},
"id": "Q1wK8_INC8Ip",
"lines_to_next_cell": 1,
"outputId": "dea01038-08b2-48c0-be4c-bf888a532db2"
},
"outputs": [],
"source": [
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"%matplotlib inline\n",
"from boss.bo.bo_main import BOMain\n",
"from boss.pp.pp_main import PPMain"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"executionInfo": {
"elapsed": 225,
"status": "ok",
"timestamp": 1630579841548,
"user": {
"displayName": "Joakim Löfgren",
"photoUrl": "https://lh3.googleusercontent.com/a/default-user=s64",
"userId": "04244087693112310568"
},
"user_tz": -180
},
"id": "YemkoQ0LC8Ip",
"lines_to_next_cell": 1
},
"outputs": [],
"source": [
"def f(X):\n",
" x = X[0, 0]\n",
" y = np.sin(x) + 1.5*np.exp(-(x - 4.3)**2)\n",
" return y"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 313
},
"executionInfo": {
"elapsed": 709,
"status": "ok",
"timestamp": 1630579843739,
"user": {
"displayName": "Joakim Löfgren",
"photoUrl": "https://lh3.googleusercontent.com/a/default-user=s64",
"userId": "04244087693112310568"
},
"user_tz": -180
},
"id": "5VUbwTOtC8Iq",
"lines_to_next_cell": 2,
"outputId": "5e914b18-3cd1-41f1-f7f9-19975c3bb888"
},
"outputs": [],
"source": [
"bounds = np.array([[0., 7.]])\n",
"fig, ax = plt.subplots()\n",
"x = np.linspace(bounds[0, 0], bounds[0, 1], 100)\n",
"y_true = np.array([f(np.atleast_2d(xi)) for xi in x])\n",
"ax.plot(x, y_true)\n",
"ax.set_xlabel('x')\n",
"ax.set_ylabel('f(x)')\n",
"ax.set_title('True function')\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "dFzs0bD08gep"
},
"source": [
"# Running instructions"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "8EA4GyoCC8Ir",
"lines_to_next_cell": 2
},
"source": [
"The first step to running BOSS typically consists of defining an objective function and\n",
"the optimization bounds, where the latter should be specified as a hypercube.\n",
"For the Forrester problem, we define the function and bounds as follows"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "5ndWs_1kC8Ir",
"lines_to_next_cell": 2
},
"source": [
"Note that BOSS expects the objective function to take a single 2D numpy array \n",
"as argument and return a scalar value (this behaviour can be modified).\n",
"Next, we import BOMain, which will be used to launch and configure the optimization.\n",
"When creating this object we can supply any number of BOSS *keywords*,\n",
"these are used to provide essential input information and modify BOSS's behavior.\n",
"In the following, only a minimal set of keywords are provided for brevity."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"executionInfo": {
"elapsed": 208,
"status": "ok",
"timestamp": 1630579846701,
"user": {
"displayName": "Joakim Löfgren",
"photoUrl": "https://lh3.googleusercontent.com/a/default-user=s64",
"userId": "04244087693112310568"
},
"user_tz": -180
},
"id": "FbkFz5egC8It"
},
"outputs": [],
"source": [
"bo = BOMain(\n",
" f, \n",
" bounds, \n",
" yrange=[-1, 1],\n",
" kernel='rbf',\n",
" initpts=5,\n",
" iterpts=5,\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "eJ9_AjA3C8It"
},
"source": [
"Consider the variable boundary and estimated target function values range (keyword yrange). Are they set properly?\n",
"The kernel type should be chosen to be the non-periodic rbf (why?)."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"executionInfo": {
"elapsed": 1627,
"status": "ok",
"timestamp": 1630579850682,
"user": {
"displayName": "Joakim Löfgren",
"photoUrl": "https://lh3.googleusercontent.com/a/default-user=s64",
"userId": "04244087693112310568"
},
"user_tz": -180
},
"id": "Wqmj8WqrC8Iu"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"warning: overwriting file 'boss.out'\n",
"warning: overwriting file 'boss.rst'\n"
]
}
],
"source": [
"res = bo.run()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "zKy8LL1oC8Iu"
},
"source": [
"# Results and Analysis\n",
"Let's visualize the quality of the GP regression fit and the estimated minimum using the information provided the by the results object."
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 295
},
"executionInfo": {
"elapsed": 764,
"status": "ok",
"timestamp": 1630579855186,
"user": {
"displayName": "Joakim Löfgren",
"photoUrl": "https://lh3.googleusercontent.com/a/default-user=s64",
"userId": "04244087693112310568"
},
"user_tz": -180
},
"id": "MBWdGerPC8Iu",
"outputId": "d3697054-c4cf-4a79-84bb-1b5baf49ac3e"
},
"outputs": [],
"source": [
"import matplotlib.pyplot as plt\n",
"fig, ax = plt.subplots()\n",
"ax.plot(x, y_true, color='tab:blue', label='True') # Plot the true function.\n",
"y_fit = res.f(np.atleast_2d(x).T)\n",
"ax.plot(x, y_fit, color='tab:red', ls='--', label='Fit') # Plot the GP regression fit.\n",
"# Plot the estimated minimum. Note the use the xmin, and fmin members of the results object.\n",
"ax.plot(res.xmin, res.fmin, 'ro', label='Minimum')\n",
"ax.set_xlabel('x')\n",
"ax.set_ylabel('f(x)')\n",
"ax.set_title('BO minimization of Forrester function')\n",
"ax.legend()\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"executionInfo": {
"elapsed": 10651,
"status": "ok",
"timestamp": 1630579868087,
"user": {
"displayName": "Joakim Löfgren",
"photoUrl": "https://lh3.googleusercontent.com/a/default-user=s64",
"userId": "04244087693112310568"
},
"user_tz": -180
},
"id": "jtb44sk8EfoN"
},
"outputs": [],
"source": [
"pp = PPMain(res, pp_models=True, pp_acq_funcs=True, pp_truef_npts=100) # add some more pp keywords here if needed\n",
"pp.run()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can include images generated by BOSS the same way we do uploaded images \n",
"\n",
"![](postprocessing/acquisition_locations.png)"
]
}
],
"metadata": {
"colab": {
"collapsed_sections": [],
"name": "tutorial1.ipynb",
"provenance": []
},
"jupytext": {
"cell_metadata_filter": "-all",
"main_language": "python",
"notebook_metadata_filter": "-all"
},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.3"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
This diff is collapsed.
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Tutorial 2: Configurational Structure Search with BO"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This tutorial demonstrates how to use BO to optimize the atomistic configuration of materials. This can be done by mapping the configurational degrees of freedom to the total energy landscape, and inferring the global minimum of energy. The energy landscapes, refined by iterative data acquisitons, can be employed to visualise low energy configurations (they are chemically interpretable). \n",
"\n",
"<img src=\"../figures/ss_scenarios.png\" width=\"800px\"/>\n",
"\n",
"At the outset, the user should consider which **key degrees of freedom** control the energetics of the research problem. In the case of adsorption of organic molecules to the surface, these could be the molecule position or orientation above the surface. The molecular conformation can often be kept fixed. In the case of flexible molecules, we need to conduct a conformer search and minimize the energy with respect to dihedral angles. The degrees of freedom and their bounds define the N-dimensional BO structure search.\n",
"\n",
"BO can proceed on any data source (experiment or computation), any computer code (molecular mechanics or ab initio approaches), on any number of cores (it has an API and command line interface) and can fit a GP surrogate model of any or many materials properties extracted from calculations (energy, band gaps, HOMO/LUMO). Flexible use of external functions is facilitated by the BOSS **user function**, where the user transforms the BO sampling across the defined search domain into an atomistic configuration, the calculation is performed, and the desired value is parsed and returned.\n",
"\n",
"<img src=\"../figures/user_fn.png\" width=\"700px\"/>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Molecular conformer structure search\n",
"\n",
"Let us consider the problem of alanine conformational structure search, as shown in the image above. We identify 4 degrees of freedom, described by dihedral angles `[d1, d2, d3, d4]`. We will use BO to refine a GPR model mapping the state vector of dihedral angles to conformer energy `E`, as computed by an external total energy code. **Our objective is to find the state vector (configuration) that minimizes the total energy.**\n",
"\n",
"First, we load the required python packages."
]
},
{
"cell_type": "code",
"execution_count": 71,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import GPy\n",
"\n",
"from boss.bo.bo_main import BOMain\n",
"from boss.pp.pp_main import PPMain"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In the conformer structure research, we used the AMBER code and `gaff` force field to compute the total energy for each sampled configuration. To simplify this tutorial, we construted an **AMBER emulator function** to simulate AMBER energies without the code itself. We did this by building a GPR generative model based on AMBER data, then encoding it in an AMBER emulator function."
]
},
{
"cell_type": "code",
"execution_count": 61,
"metadata": {},
"outputs": [],
"source": [
"# Here we load AMBER data from a file and build an GPR model. \n",
"def load_model(filename):\n",
" \"\"\"Recreates a GPR model from saved parameters and data. \"\"\"\n",
"\n",
" # load saved data\n",
" data = np.load(filename)\n",
" dim = data[\"X\"].shape[1]\n",
"\n",
" # create kernel and mean functions\n",
" kernel = GPy.kern.StdPeriodic(input_dim=dim, ARD1=True, ARD2=True)\n",
" mean_func = GPy.mappings.Constant(dim, 1)\n",
"\n",
" # create model\n",
" model = GPy.models.GPRegression(\n",
" data[\"X\"], data[\"Y\"], kernel=kernel, mean_function=mean_func\n",
" )\n",
"\n",
" # set model params\n",
" model[:] = data[\"params\"]\n",
" model.fix()\n",
" model.parameters_changed()\n",
"\n",
" return model\n",
"\n",
"# Here, we define the AMBER emulator for a 2D example\n",
"AMBER_emulator2D = load_model(\"../data/model_2D_E0.npz\")\n",
"\n",
"# Here, we define the utility function that retrieves data from the AMBER emulator.\n",
"def f(X):\n",
" return AMBER_emulator2D.predict(np.atleast_2d(X))[0]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Running BO"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Once more, we need to set up the BO run by defining the:\n",
"\n",
"* `bounds` of the search domain: the number of [lower, upper] bound pairs in the vector will tell BOSS that this is a 2D search. \n",
"* `yrange` of the expected function\n",
"* `kernel`: since all dihedral angles are 360-periodic, we can set the kernel to *standard periodic*\n",
"* number of initial points `initpts` and BO iterations `iterpts`\n",
"\n",
"After setting BO, we are ready to run!"
]
},
{
"cell_type": "code",
"execution_count": 66,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"warning: overwriting file 'boss.out'\n",
"warning: overwriting file 'boss.rst'\n"
]
}
],
"source": [
"# Here, we define the BO run.\n",
"#bounds = [[-50.0, 310.0]] * 2 # It can be done like this, or explicitly below \n",
"bounds = [[-50.0, 310.0], [-50.0, 310.0]]\n",
"\n",
"bo = BOMain(\n",
" f,\n",
" bounds,\n",
" yrange=[0, 1],\n",
" kernel=\"stdp\",\n",
" initpts=5,\n",
" iterpts=10,\n",
")\n",
"\n",
"# Here we perform BO, it should take about 2 minutes.\n",
"res = bo.run()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We immediately run post-processing to check results:"
]
},
{
"cell_type": "code",
"execution_count": 68,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"warning: overwriting directory 'postprocessing'\n"
]
},
{
"ename": "ValueError",
"evalue": "could not broadcast input array from shape (5,1) into shape (4,1)",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-68-1e6b51289a2a>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mpp\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mPPMain\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mres\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mpp_models\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mpp_iters\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;31m#pp = PPMain(res, pp_models=True)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mpp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrun\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;32m~/Code/BOSS/BOSS_tutorial/env/lib/python3.6/site-packages/boss/pp/pp_main.py\u001b[0m in \u001b[0;36mrun\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 158\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mload_data\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 159\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdump_data\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 160\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 161\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 162\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mload_data\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/Code/BOSS/BOSS_tutorial/env/lib/python3.6/site-packages/boss/pp/pp_main.py\u001b[0m in \u001b[0;36mplot\u001b[0;34m(self, target)\u001b[0m\n\u001b[1;32m 367\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 368\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mtarget\u001b[0m \u001b[0;32min\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m\"model\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"all\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 369\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_plot_model\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 370\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 371\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mtarget\u001b[0m \u001b[0;32min\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m\"truef\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"all\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/Code/BOSS/BOSS_tutorial/env/lib/python3.6/site-packages/boss/pp/pp_main.py\u001b[0m in \u001b[0;36m_plot_model\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 493\u001b[0m \u001b[0mbo\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 494\u001b[0m \u001b[0mbo\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmodel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_all_params\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 495\u001b[0;31m \u001b[0mcurr_xhat\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 496\u001b[0m )\n\u001b[1;32m 497\u001b[0m mdata = np.loadtxt(\n",
"\u001b[0;32m~/Code/BOSS/BOSS_tutorial/env/lib/python3.6/site-packages/boss/io/dump.py\u001b[0m in \u001b[0;36mdump_model\u001b[0;34m(settings, dest_file, bo, mod_params, xhat)\u001b[0m\n\u001b[1;32m 46\u001b[0m \u001b[0mp\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minsert\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mp\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mp\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfloat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbo\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_mu\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mp\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 47\u001b[0m \u001b[0mp\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minsert\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mp\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mp\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfloat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbo\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_nu\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mp\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 48\u001b[0;31m \u001b[0mmodel_data\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minsert\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmodel_data\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmodel_data\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mp\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxis\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 49\u001b[0m titleLine = \"# Model output (x mu nu)\" + \", grid of %ix%i=%i pts\" % (\n\u001b[1;32m 50\u001b[0m \u001b[0mnpts\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m<__array_function__ internals>\u001b[0m in \u001b[0;36minsert\u001b[0;34m(*args, **kwargs)\u001b[0m\n",
"\u001b[0;32m~/Code/BOSS/BOSS_tutorial/env/lib/python3.6/site-packages/numpy/lib/function_base.py\u001b[0m in \u001b[0;36minsert\u001b[0;34m(arr, obj, values, axis)\u001b[0m\n\u001b[1;32m 4576\u001b[0m \u001b[0mnew\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mtuple\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mslobj\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0marr\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mtuple\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mslobj\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4577\u001b[0m \u001b[0mslobj\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0maxis\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mslice\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mindex\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindex\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0mnumnew\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 4578\u001b[0;31m \u001b[0mnew\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mtuple\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mslobj\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mvalues\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4579\u001b[0m \u001b[0mslobj\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0maxis\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mslice\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mindex\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0mnumnew\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4580\u001b[0m \u001b[0mslobj2\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mslice\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0mndim\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mValueError\u001b[0m: could not broadcast input array from shape (5,1) into shape (4,1)"
]
}
],
"source": [
"#pp = PPMain(res, pp_models=True, pp_iters=[0, 2])\n",
"pp = PPMain(res, pp_models=True)\n",
"pp.run()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "zKy8LL1oC8Iu"
},
"source": [
"## Results and Analysis\n",
"We start by checking **data acqusition** plots. Since we have 2 dimensions, the lower plot now features the sampling locations in both dihedrals. Amber energy values are all positive, and a global minimum was clearly idenfitifed. On the right, the **hyperparameter plot** indicates that the model has also converged.\n",
"\n",
"<table><tr><td><img src='postprocessing/acquisition_locations.png' width=\"400px\"></td><td><img src='postprocessing/hyperparameters.png' width=\"400px\"></td></tr></table>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let us review the potential energy surface (PES) landscapes simulated by GPR after 20 and 40 BO points.\n",
"<table><tr><td><img src='postprocessing/graphs_models/it0005_npts0010.png' width=\"400px\"></td><td><img src='postprocessing/graphs_models/it0010_npts0015.png' width=\"400px\"></td></tr></table>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"postprocessing/graphs_models/it0020_npts0025.png\" width=\"400px\">"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"jupytext": {
"cell_metadata_filter": "-all",
"main_language": "python",
"notebook_metadata_filter": "-all"
},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",