{
    "nbformat": 4,
    "nbformat_minor": 5,
    "metadata": {
        "kernelspec": {
            "display_name": "Python",
            "language": "python",
            "name": "python"
        },
        "language_info": {
            "name": "python"
        }
    },
    "cells": [
        {
            "id": "338977a9",
            "cell_type": "markdown",
            "source": "<div class='alert alert-warning'>\n\nSciPy's interactive examples with Jupyterlite are experimental and may not always work as expected. Execution of cells containing imports may result in large downloads (up to 60MB of content for the first import from SciPy). Load times when importing from SciPy may take roughly 10-20 seconds. If you notice any problems, feel free to open an [issue](https://github.com/scipy/scipy/issues/new/choose).\n\n</div>",
            "metadata": {}
        },
        {
            "id": "14b5fe46",
            "cell_type": "markdown",
            "source": "We illustrate the use of `brute` to seek the global minimum of a function\nof two variables that is given as the sum of a positive-definite\nquadratic and two deep \"Gaussian-shaped\" craters. Specifically, define\nthe objective function `f` as the sum of three other functions,\n``f = f1 + f2 + f3``. We suppose each of these has a signature\n``(z, *params)``, where ``z = (x, y)``,  and ``params`` and the functions\nare as defined below.\n",
            "metadata": {}
        },
        {
            "id": "d3ebc399",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "import numpy as np\nparams = (2, 3, 7, 8, 9, 10, 44, -1, 2, 26, 1, -2, 0.5)\ndef f1(z, *params):\n    x, y = z\n    a, b, c, d, e, f, g, h, i, j, k, l, scale = params\n    return (a * x**2 + b * x * y + c * y**2 + d*x + e*y + f)",
            "outputs": []
        },
        {
            "id": "5b250b1e",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "def f2(z, *params):\n    x, y = z\n    a, b, c, d, e, f, g, h, i, j, k, l, scale = params\n    return (-g*np.exp(-((x-h)**2 + (y-i)**2) / scale))",
            "outputs": []
        },
        {
            "id": "b07719a4",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "def f3(z, *params):\n    x, y = z\n    a, b, c, d, e, f, g, h, i, j, k, l, scale = params\n    return (-j*np.exp(-((x-k)**2 + (y-l)**2) / scale))",
            "outputs": []
        },
        {
            "id": "7857f967",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "def f(z, *params):\n    return f1(z, *params) + f2(z, *params) + f3(z, *params)",
            "outputs": []
        },
        {
            "id": "ca623875",
            "cell_type": "markdown",
            "source": "Thus, the objective function may have local minima near the minimum\nof each of the three functions of which it is composed. To\nuse `fmin` to polish its gridpoint result, we may then continue as\nfollows:\n",
            "metadata": {}
        },
        {
            "id": "be572eb6",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "rranges = (slice(-4, 4, 0.25), slice(-4, 4, 0.25))\nfrom scipy import optimize\nresbrute = optimize.brute(f, rranges, args=params, full_output=True,\n                          finish=optimize.fmin)\nresbrute[0]  # global minimum",
            "outputs": [
                {
                    "output_type": "execute_result",
                    "metadata": {},
                    "data": {
                        "text/plain": "array([-1.05665192,  1.80834843])"
                    },
                    "execution_count": null
                }
            ]
        },
        {
            "id": "a65b9e46",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "resbrute[1]  # function value at global minimum",
            "outputs": [
                {
                    "output_type": "execute_result",
                    "metadata": {},
                    "data": {
                        "text/plain": "-3.4085818767"
                    },
                    "execution_count": null
                }
            ]
        },
        {
            "id": "bfe7a021",
            "cell_type": "markdown",
            "source": "Note that if `finish` had been set to None, we would have gotten the\ngridpoint [-1.0 1.75] where the rounded function value is -2.892.",
            "metadata": {}
        }
    ]
}