{ "cells": [ { "cell_type": "markdown", "id": "db85c74b", "metadata": {}, "source": [ "## Test computational scaling \n", "\n", "Here we give an example of how to measure the training computation time as a function of training iteration and number of dimensions." ] }, { "cell_type": "code", "execution_count": 1, "id": "4c28f189", "metadata": { "execution": { "iopub.execute_input": "2026-02-21T08:21:38.133751Z", "iopub.status.busy": "2026-02-21T08:21:38.133557Z", "iopub.status.idle": "2026-02-21T08:21:39.173499Z", "shell.execute_reply": "2026-02-21T08:21:39.169219Z" } }, "outputs": [], "source": [ "import alabi\n", "from alabi.core import SurrogateModel\n", "from alabi import benchmarks as bm\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "from functools import partial\n", "from scipy.stats import multivariate_normal" ] }, { "cell_type": "markdown", "id": "46523e6c", "metadata": {}, "source": [ "Define common settings for all tests" ] }, { "cell_type": "code", "execution_count": 2, "id": "7bdb28fc", "metadata": { "execution": { "iopub.execute_input": "2026-02-21T08:21:39.177192Z", "iopub.status.busy": "2026-02-21T08:21:39.176940Z", "iopub.status.idle": "2026-02-21T08:21:39.183870Z", "shell.execute_reply": "2026-02-21T08:21:39.181221Z" } }, "outputs": [], "source": [ "ncore = 1 # we'll run one active learning chain on one core\n", "ntrain = 100 # number of initial training samples\n", "savedir = \"results/scaling\" # directory to save results\n", "\n", "gp_kwargs = {\"kernel\": \"ExpSquaredKernel\", \n", " \"fit_amp\": True, \n", " \"fit_mean\": True, \n", " \"fit_white_noise\": False, \n", " \"white_noise\": -12,\n", " \"gp_opt_method\": \"l-bfgs-b\",\n", " \"gp_scale_rng\": [-2,2],\n", " \"optimizer_kwargs\": {\"max_iter\": 50, \"xatol\": 1e-3, \"fatol\": 1e-2, \"adaptive\": True}}\n", "\n", "al_kwargs = {\"algorithm\": \"bape\",\n", " \"gp_opt_freq\": 20,\n", " \"obj_opt_method\": \"nelder-mead\",\n", " \"nopt\": 1,\n", " \"optimizer_kwargs\": {\"max_iter\": 50, \"xatol\": 1e-3, \"fatol\": 1e-2, \"adaptive\": True}}" ] }, { "cell_type": "markdown", "id": "d07801a5", "metadata": {}, "source": [ "Define a general function that trains `alabi` on an N-dimensional Gaussian for `max_iter` iterations" ] }, { "cell_type": "code", "execution_count": 3, "id": "a3c90bc1", "metadata": { "execution": { "iopub.execute_input": "2026-02-21T08:21:39.187717Z", "iopub.status.busy": "2026-02-21T08:21:39.187585Z", "iopub.status.idle": "2026-02-21T08:21:39.215724Z", "shell.execute_reply": "2026-02-21T08:21:39.215227Z" } }, "outputs": [], "source": [ "def run_alabi(ndim, max_iter=100, savedir=\"results/scaling\"):\n", "\n", " path = f\"{savedir}/multivariate_normal_{ndim}d/\"\n", "\n", " # Define the multivariate normal likelihood function\n", " mean = np.zeros(ndim)\n", " cov = bm.random_gaussian_covariance(ndim)\n", " lnlike = partial(multivariate_normal.logpdf, mean=mean, cov=cov)\n", "\n", " # Train surrogate model\n", " sm = SurrogateModel(lnlike_fn=lnlike,\n", " bounds=[(-3., 3.) for _ in range(ndim)],\n", " savedir=path,\n", " cache=True,\n", " verbose=True,\n", " ncore=ncore)\n", " \n", " # save the true mean and covariance to a file\n", " np.savez(f\"{path}gaussian_mean_cov.npz\", mean=mean, cov=cov)\n", "\n", " # Initialize surrogate model \n", " if ndim >= 40:\n", " sm.init_samples(ntrain=ntrain, sampler=\"uniform\")\n", " else:\n", " sm.init_samples(ntrain=ntrain, sampler=\"sobol\")\n", "\n", " sm.init_gp(**gp_kwargs)\n", " sm.active_train(niter=max_iter, **al_kwargs)\n", " sm.plot(plots=[\"gp_all\"])" ] }, { "cell_type": "markdown", "id": "a6d24630", "metadata": {}, "source": [ "For a quick test, we'll just run `alabi` for a 5-dimensional gaussian and measure the amount of computational overhead `alabi` takes to train the surrogate model. To test more dimensions add them to the `dimensions` array, or to test for more iterations increase `max_iter`. " ] }, { "cell_type": "code", "execution_count": 4, "id": "21367840", "metadata": { "execution": { "iopub.execute_input": "2026-02-21T08:21:39.216949Z", "iopub.status.busy": "2026-02-21T08:21:39.216814Z", "iopub.status.idle": "2026-02-21T08:21:50.664918Z", "shell.execute_reply": "2026-02-21T08:21:50.664322Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Initialized GP with squared exponential kernel.\n", "Successfully initialized GP on attempt 1\n", "\n", "Optimizing GP hyperparameters using 5-fold cross-validation...\n", "Evaluating 100 hyperparameter candidates using 5-fold CV...\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Running 200 active learning iterations using bape...\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "\r", " 0%| | 0/200 [00:00" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "logy = False\n", "\n", "fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(10, 18), sharex=True)\n", "plt.subplots_adjust(hspace=0.05)\n", "\n", "# Top panel - Training time\n", "for ii, ndim in enumerate(dimensions):\n", " ax1.plot(iterations, train_time[ii], label=f\"{dimensions[ii]} dimensions\", linewidth=1)\n", "ax1.set_ylabel(\"GP training time (s)\", fontsize=22)\n", "ax1.legend(loc=\"upper left\", fontsize=18)\n", "ax1.minorticks_on()\n", "\n", "# Middle panel - Optimization time\n", "for ii, ndim in enumerate(dimensions):\n", " ax2.plot(iterations, opt_time[ii], linewidth=1)\n", "ax2.set_ylabel(\"BAPE optimization time (s)\", fontsize=22)\n", "ax2.minorticks_on()\n", "\n", "# # Bottom panel - Total time\n", "for ii, ndim in enumerate(dimensions):\n", " ax3.plot(hp_opt_iter[ii], hp_opt_time[ii][1:], linewidth=1.5)\n", "ax3.set_xlabel(\"Number of active learning iterations\", fontsize=22)\n", "ax3.set_ylabel(\"Hyperparameter optimization time (s)\", fontsize=22)\n", "ax3.minorticks_on()\n", "\n", "if logy:\n", " ax1.set_yscale(\"log\")\n", " ax2.set_yscale(\"log\")\n", " # ax3.set_yscale(\"log\")\n", "ax1.set_xlim(0, iterations[-1])\n", "\n", "plt.savefig(f\"{savedir}/multivariate_normal_training_time.png\", bbox_inches='tight', dpi=800)\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "25f0132e", "metadata": {}, "source": [ "Plot the cummulative training time as a bar chart for each dimension." ] }, { "cell_type": "code", "execution_count": 7, "id": "975eb5fd", "metadata": { "execution": { "iopub.execute_input": "2026-02-21T08:21:54.513439Z", "iopub.status.busy": "2026-02-21T08:21:54.513301Z", "iopub.status.idle": "2026-02-21T08:21:54.952728Z", "shell.execute_reply": "2026-02-21T08:21:54.952010Z" } }, "outputs": [ { "data": { "image/png": "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WApTKaEnPj4+R/ultL81NBUvXlySlJSUZKUsAACAPGMpTKWEny1btuRov5T2KedIpYiJiZEkuw8ZAgAAOJulMBUQECDTNLVgwQKFhITYtc/vv/+uhQsXyjAMNW3aNM22Y8eOSbp5XpUznTx5Uq+99pruuecelS5dWh4eHqpcubLatGmjiRMn6sCBA06tDwAA5B+WwtSIESMkSYmJierUqZPmzJmjxMTEDNsmJiZq9uzZ6tKli27cuCFJGjVqVJo2mzdvlmEYuuuuu6yUZcmMGTNUr149TZ48WX/88YcuX76s+Ph4nT59Wr/++qumTJmi2bNnO60+AACQv1hatLN79+4aOHCgFi9erKioKI0aNUovvviiWrVqpRo1aqho0aKKjY3VP//8o+3bt+vq1au2ldAHDhyobt262fo6efKktm3bJknq1KmTlbJu2xtvvKFXX31VklS7dm2NHDlSAQEB8vX11ZUrV7Rnzx59//333EcQAADYWF60MykpSY8//rjmzp37v04zuV9fylDDhw/X559/rgIFCti2hYWF6Y8//pAkdenSRV5eXlbKyrGNGzeqY8eOkqTBgwdr9uzZKlSoUIZtExISVLhwYbv7ZtFOAAByj7MX7bQcplIEBwfrgw8+0Nq1a22H8VIrVKiQunTpov/85z9q3769I4Z0mOTkZPn7++vvv/9Ww4YNFRISooIFLU3apUGYAgAg9zg7TDksMbRv317t27dXfHy8/vzzT509e1YxMTHy9PRUhQoV1LBhQ7m7uztqOIdat26d/v77b0nS+PHjHRqkAADAv5vDU4O7u3u6q/Tyu2XLlkm6eXjygQcesL0fHh6uK1euqGTJkizXAAAAMsSZ1PrfSuxVq1aVt7e3Fi9erLvvvlslS5ZU7dq1VbJkSdWpU0fvvfdejhcoBQAA/253fJhKTk7WkSNHJN1c3+rpp5/WI488km4tqaNHj+qFF15Qhw4dFBERkWWf8fHxioqKSvMAAAD/Tg49zHfu3DkdOHBAV69e1fXr1+3aZ/DgwY4sIcciIyOVnJwsSdq/f7927dql8uXL691339X9998vDw8P7dq1S+PHj9fOnTu1fft2DRs2TMuXL8+0z6lTp+r111/Pq48AAACcyCFX83399dd6++23tX///pwNbhiZLvKZV06fPq3KlSvbXhctWlS7d+9WnTp10rSLi4tT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y5dr1KhRtpnHDh06qE+fPipZsqRCQ0M1f/58bdmyRcOGDctx31nZvXu3pk2bpgIFCuipp55S06ZNVaBAAW3atEnz5s1TYmKiXnnlFbVq1Uq7d+/W5MmT5efnp6FDh8rf318xMTFaunSp1q1bpxs3bmjo0KH666+/VKpUqQzHGzJkiBYuXChJKlGihAYMGKAmTZrIx8dHFy9e1OrVq7VmzRqdPn1a7du3V0hIiGrXrp1p/YmJierTp482b96sFi1aqE+fPqpcubLCw8P1zTffaNOmTUpMTNTw4cPVtGlT1ahRI83+sbGx6tWrl86fPy9JatKkiR588EFVrFhRnp6eunr1qg4fPqzg4OAczbzdas6cORoxYoTtdadOndSrVy+VLFlSYWFhWrBggQ4ePKhTp06pXbt22r59uxo0aJBln6+88ooWL16sqlWratCgQapbt65u3LihjRs3auHChUpOTtann36qli1bZnjRzciRI7Vz505JUuXKlfXQQw+pVq1aKl68uGJiYvT3339rx44d2rp1621/btjJ2WkOyIqUdmbKNE3zjTfesL0/bty4dPs4c2ZK/zcrktFf5MHBwaZhGKYks2rVqmbJkiXNgIAA88qVK+napp49GD16dIZ13TrLUqtWLfPUqVPp2u3fv98sXbq0rd2SJUvStYmJiTGrV69uSjKLFi2a6exERESE2b59e1tf69evT9cm9ddLklm7dm3zxIkTGfaXE9HR0WbZsmVt/U6aNMk2w5fi1pmXsmXLmlFRURn2l3pmxKqIiIg0X+MPPvggXZv4+HizX79+ab42jpiZSvl+Cg0NTddu/vz5tjb169c33d3dzW7dupmxsbHp2g4ePNjW9p133smwrs8//9zWpnv37ubVq1czbPfdd9/ZZq4y+xlM+fpn9TUzTdMcMWKErc3YsWPTbV+2bJlt+7PPPpthHykOHjxoXrx4Md372c1MhYWF2WakDMMw58yZk67NjRs3zGHDhqX5eiclJaVrl/rfVpI5YMCADGeMFyxYYGtz9913p9t+4cIF083NzZRktmzZ0oyLi8v0c1+8eNE8dOhQptthHWEK+VpGYeratWu2Kf3ChQun+2Xj7DC1aNGiTPvq2LGjrZ27u7sZFhaWYbvY2FjbYZvq1atn2Cb1LwA3Nzdzz549mY67cuVKW9tGjRql2/7RRx/Zti9YsCDTfkzz5qEFHx8fU5J53333pdue+utlGIa5e/fuLPuz18cff2zr9/7778+y7X333Wdr++GHH2bYxpFhKvXXr2/fvpm2i4mJMatUqeLwMLVt27ZMx6xVq5atXZkyZczIyMgM2508edIW9jt06JBu+/Xr183y5cubksy6deua8fHxmY5pmqb50ksv2cbduXNnuu2pw9TgwYMz7efq1aumh4eHKcmsWbNmuu1Tp0619XPw4MEsa8pMdmEq9SH0zP64Mc2bgeruu++2tV2xYkW6Nqn/bWvXrp3lofdmzZrZ2p4+fTrNth07dti2ffrpp/Z/WOQKTkCHy/H09NTEiRMlSQkJCXr11VedXNH/lClTRgMGDMh0e+oV2bt37y4/P78M2xUpUkT33HOPJOn48eO6fv16luN27tzZdvgqIz169FCdOnUk3TycFxoammb7/PnzJUkVK1bMdg2vlBPkpZsnQqdcFZeR1q1bq1GjRln2Z6/ly5fbno8fPz7Lti+99FKG++WW1GM899xzmbYrWrSoxowZ49CxGzdurJYtW2a6vVWrVrbngwcPlo+PT4btKleubPt+PHToULrt69at07lz5yRJzzzzjAoXLpxlXUOGDLE9X7t2bZZtn3322Uy3FStWzPaz8M8//6T7WfD09LQ9/+OPP7Ic53al/PsahqEXX3wx03YFCxbUCy+8kG6/zIwePdp2UU1GOnXqZHt+4MCBNNvy4nPDfpwzBZc0YsQIvf/++zp27JgWL16sF154IdvzE/LCPffcY1tBOyOpzxNq2rRpln2ltDVNUxEREVmeY9SxY8dsa+vYsaP++usvSdLvv/+u6tWrS7p5FdTevXslSeXLl9cPP/yQbV8pAer69es6fvx4pud0tWnTJtu+7GGapn7//XdJNwNJdrcJatWqlTw9PRUTE6Ndu3YpOTnZtk6Zo5mmabvC0cvLK9t/13vvvdeh4zdv3jzL7Tn9ngsLC9PVq1fTbduyZYvteXR0tFasWJFlX6nXgssonKXw9PTM9mc3ZR2wjH4WOnbsKMMwZJqmnnzySR07dkwPP/xwtucZ2uvixYu2q+5q166d6R9AKVKfo5dyPlNmWrRokeX21Ouf3fpvUq9ePVWsWFFnzpzR3LlzlZSUpJEjR6p58+ZZ/h+E3EGYgksqVKiQ3njjDT300ENKTk7WhAkTbCtaO1PJkiWz3J76r9CctM1uZqpWrVrZ1pa6zdmzZ23PT506ZbsnXUhIiB588MFs+0otPDw8022OWgwzKirKdql9jRo1sg1Gbm5uqlmzpv7880/FxcUpIiJCJUqUcEgtt4qMjFRMTIwkqXr16tnWVrNmTYeOnxvfcxnNNqZeouH555/PQYVZf4+UKFEi29tDZfWzULduXb3yyiuaMmWKYmJiNHnyZE2ePFnly5dXy5Yt1aZNG9133322mdmcSpmNk5TlifQpypQpI19fX0VGRqbZNyOZneSfIqvPXaBAAX3xxRfq3bu34uPjNX/+fM2fP18+Pj5q1qyZWrVqpY4dO6ply5bcfisPcJgPLqt///62q65++umnNH85O0tOZj8cOVOSesrfnjYpV+xJynRNJntltG5PiiJFiljqO0Xqeu35rNLNWaKM9ne01OudFS1aNNv29tZvr7z6nrPyfZLV94gjfg4mT56sH374Ic3hznPnzum7777TM888I39/f7Vu3Vq//fZbjvu28r2X3Vp4Vj/7/fffr5CQEPXt29d22DUqKkrr16/XpEmT1Lp1a9WoUcN29SVyD2EKLsswDL399tu21//9739zZRx7F1p0ppSZEXvbeHt7256nDh29e/eWefPCFLsf7dq1c+hnyUjqeu35rFLaX2Sp93e01F+/7BaqlOyvP79J/Tn37duXo++R21mANqe6d++ubdu26fz581q2bJmeffZZNWnSxDYrs23bNrVp00YbNmzIUb9WvvdSf81yS/369bVs2TKFh4dr7dq1ev3119WxY0fbrNbx48c1aNAgvf7667ley52MMAWX1qlTJ9v5Qjt27ND3339v136pp8+z+qtZki5fvnz7BeaRY8eO5ahNhQoVbM8rVqxoe55yv7r8xsfHxzYrEBoaajssmZnk5GT9888/km7OjhUrVizXavP19U1Tm3nLCve3suffKj9Kfcg2v36fSFLZsmXVt29fTZ8+XSEhIQoLC1O/fv0k3TyP6z//+U+O+itfvrzt+d9//51t+4sXLyoyMlJS2p+z3Obp6anOnTtr4sSJWr9+vS5duqQpU6bYtr/55pu2tbjgeIQpuLy3337b9tfnyy+/bNdMUvHixW3Pz5w5k2Xb7du3WyswD6xfvz7bNqn/Im/WrJntealSpXTXXXdJurkA5IULFxxfoEWGYSggIEDSzdmBbdu2Zdl+27Zt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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plt.bar(dimensions, cum_time, width=1, color='blue', alpha=0.7)\n", "plt.xlabel(\"Number of dimensions\", fontsize=22)\n", "plt.ylabel(\"Total training time (s)\", fontsize=22)\n", "plt.xticks(dimensions, fontsize=20)\n", "plt.yticks(fontsize=20)\n", "plt.savefig(f\"{savedir}/multivariate_normal_total_training_time.png\", bbox_inches='tight', dpi=600)\n", "plt.show()" ] } ], "metadata": { "kernelspec": { "display_name": "py310", "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.14.2" } }, "nbformat": 4, "nbformat_minor": 5 }