{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Introductory demo of `autodiff` module with the `gradpy` package" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Welcome to the introductory demo for automatic differentiation with `gradpy`! After you have successfully installed the `gradpy` package (please refer to the [Installation](https://autodiff.readthedocs.io/en/latest/Installation.html) page for reference), you can follow along the commands below to get started.\n", "\n", "### Single-variable function\n", "\n", "From the main module `autodiff`, we will begin by importing the elementary `Var` object, used to define independent variables in an equation or model of interest. We create a `Var` variable $x$ initialized with the value 1 and use it to create a simple user-defined function, $f = 3x^2+5$." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true }, "outputs": [], "source": [ "from gradpy.autodiff import Var\n", "\n", "x = Var(1)\n", "f = 3*x**2 + 5" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can obtain the value and derivative of $f$ with respect to $x$, evaluated at $x=1$, by accessing the `value` attribute, and calling the `der` method with the appropriate `Var` object as its argument:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "f(x) = 8\n", "f'(x) = 6\n" ] } ], "source": [ "fval = f.value\n", "fder = f.der(x)\n", "\n", "print(\"f(x) =\",fval)\n", "print(\"f'(x) =\",fder)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we do not know the value of $x$ ahead of time, or would like to change it later without redefining $f$, we can do so using the `set_value` method:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "f(x) = 32\n", "f'(x) = 18\n" ] } ], "source": [ "x.set_value(3)\n", "\n", "print(\"f(x) =\",f.value)\n", "print(\"f'(x) =\",f.der(x))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`Var` is itself a differentiable object; thus we can also do:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "x = 3\n", "x' = 1\n" ] } ], "source": [ "print(\"x =\",x.value)\n", "print(\"x' =\",x.der(x))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Multi-variable function\n", "\n", "Multi-variable functions can be defined by instantiating multiple `Var` instances as independent variables." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 0 0\n", "1 -2 2\n" ] } ], "source": [ "a = Var()\n", "b = Var()\n", "\n", "c = a**2 - 2*a*b + b**2\n", "\n", "a.set_value(2)\n", "b.set_value(2)\n", "print(c.value, c.der(a), c.der(b))\n", "\n", "a.set_value(3)\n", "b.set_value(4)\n", "print(c.value, c.der(a), c.der(b))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Derivatives with respect to several independent variables, comprising the gradient of a function, can be obtained simultaneously by supplying a list of `Var` objects to the `grad` method. The return type is a `numpy` array." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 [-2 2] \n" ] } ], "source": [ "print(c.value, c.grad([a,b]), type(c.grad([a,b])))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Vector-valued function\n", "\n", "Vector-valued functions can be initialized with the `Array` class. The `value` attribute and `der` method of `Array` objects also return `numpy` arrays." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ 8. 20.] [4. 5.]\n" ] } ], "source": [ "from gradpy.autodiff import Array\n", "\n", "t = Var(4)\n", "\n", "vec = Array([0.5*t**2,\n", " 5*t])\n", "\n", "print(vec.value, vec.der(t))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Vector-valued functions can also be multi-variable:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[ 0. -1. -1. ]\n", " [ 1. 0.1 0. ]\n", " [ 1. 0. -11. ]]\n", "[[ 0. -1. -1. ]\n", " [ 1. 0.1 0. ]\n", " [ 1. 0. -11. ]]\n", "[[ 0. -1. -1. ]\n", " [ 1. 0.1 0. ]\n", " [ 1. 0. -11. ]]\n" ] } ], "source": [ "import numpy as np\n", "\n", "x = Var(3)\n", "y = Var(2)\n", "z = Var(1)\n", "\n", "v = Array([-y - z,\n", " x + 0.1*y,\n", " 0.1 + z*(x - 14)])\n", "\n", "print(v.grad([x,y,z]))\n", "\n", "# is equivalent to ...\n", "print(np.array([v[0].grad([x,y,z]),\n", " v[1].grad([x,y,z]),\n", " v[2].grad([x,y,z])]))\n", "\n", "# is equivalent to ...\n", "print(np.array([[v[0].der(x), v[0].der(y), v[0].der(z)],\n", " [v[1].der(x), v[1].der(y), v[1].der(z)],\n", " [v[2].der(x), v[2].der(y), v[2].der(z)]]))" ] } ], "metadata": { "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.6" } }, "nbformat": 4, "nbformat_minor": 2 }