{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Intrepydd functions reference\n", "\n", "This notebook serves as a \"executable\" reference guide to the functions available in reference, as summarized [here in the Intrepydd Guide](https://hpcgarage.github.io/intrepyddguide/library/functions.html).\n", "\n", "**Run these first.** If you are executing this reference, please run the following two code cells first. You can then run any subsection, as there are no additional dependencies among them." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "from os import makedirs\n", "makedirs('ref', exist_ok=True)" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "from numpy import array, float32, int32" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Table of contents\n", "\n", "The following [Python builtins](https://docs.python.org/3/library/functions.html) have counterparts in Intrepydd.\n", "\n", "- [`abs`](#abs): Absolute value of an iterable collection\n", "- [`all`](#all): Check whether all elements of an iterable collection are `True`\n", "- [`any`](#any): Check whether any element of an iterable collection is `True`\n", "- [`len`](#len): Returns the length of an iterable collection\n", "- [`max`](#max): Returns the largest value in an iterable collection\n", "- [`pow`](#pow): Raises a given value or every element of an iterable object to some power\n", "- [`range`](#range): Generates an integer range (sequence).\n", "- [`sum`](#sum): Returns the sum of the elements in an iterable object.\n", "- [Type conversion](#type_conv):`int32`, `int64`, `float32`, `float64`: Constructors and converters for basic primitive types.\n", "\n", "Intrepydd also provides counterparts to a subset of the functions available in [Numpy/Scipy](https://www.numpy.org/).\n", "\n", "- [Basic arithmetic, unary operators](#unary) `elemwise_not`, `minus`: Elementwise arithmetic on a single input array.\n", "- [Basic arithmetic, binary operators](#binary) `add`, `sub`, `mul`, `div`: Elementwise arithmetic between pairs of arrays.\n", "- [Comparisons](#comparisons) `eq`, `ge`, `gt`, `le`, `lt`: Elementwise signed comparison (e.g., equality, less than, greater than).\n", "- [Trignometric functions](#trig), `acos`, `asin`, `atan`, `cos`, `sin`, `sqrt`, `tan`: Elementwise trigonometric functions.\n", "- [`allclose`](#allclose): Returns `True` if all elements of a given array are close to a given value.\n", "- [`argmin`](#argmin): Returns the location of the minimum value in an array.\n", "- [`argmax`](#argmax): Returns the location of the maximum value in an array.\n", "- [`empty`](#empty): Returns an \"empty\" (uninitialized) multidimensional array.\n", "- [`innerprod`](#innerprod): Returns the inner product (dot-product) between two arrays of the same size.\n", "- [`isinf`, `isnan`](#isfpXXX): Tests for IEEE-754 floating-point infinity (`inf`) and not-a-number (`NaN`) values.\n", "- [`prod`](#prod): Returns the product of all elements of a collection.\n", "- [`transpose`](#transpose): Returns the transpose of a matrix.\n", "- [`zeros`](#zeros): Returns an array of all zero elements." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Python builtin-equivalents" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='abs'></a>\n", "\n", "## Function: `abs`\n", "\n", "Returns the absolute value of a given object or iterable; equivalent to its [Python builtin](https://docs.python.org/3/library/functions.html#abs)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Example.**" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Overwriting ref/abs.pydd\n" ] } ], "source": [ "%%writefile ref/abs.pydd\n", "\n", "def demo_float32(x: float32) -> float32:\n", " return abs(x)\n", "\n", "def demo_Array(x: Array(float64, 2)) -> Array(float64, 2):\n", " return abs(x)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "!pyddc ref/abs.pydd" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3.140000104904175\n", "[[1. 2. 3.]\n", " [4. 5. 6.]]\n" ] } ], "source": [ "import ref.abs\n", "print(ref.abs.demo_float32(-3.14))\n", "\n", "A = array([[-1., 2., -3.],\n", " [4., -5., 6.]])\n", "print(ref.abs.demo_Array(A))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='all'></a>\n", "\n", "## Function: `all`\n", "\n", "Returns `True` if all elements of a given iterable object are `True`; equivalent to its [Python builtin](https://docs.python.org/3/library/functions.html#all)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Example.**" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Overwriting ref/all.pydd\n" ] } ], "source": [ "%%writefile ref/all.pydd\n", "\n", "def demo_bool(A: Array(bool, 2)) -> bool:\n", " return all(A)\n", "\n", "def demo_int(A: Array(int64)) -> bool:\n", " return all(A)\n", "\n", "def demo_double(A: Array(float64, 2)) -> bool:\n", " return all(A)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "!pyddc ref/all.pydd" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n", "False\n", "[0 1 2 3 4 5 6 7 8 9]\n", "False\n", "True\n", "[[ 1. -2. 3.]\n", " [-4. 5. 6.]]\n", "True\n", "[[ 1. -2. 3.]\n", " [-4. 5. 0.]]\n", "False\n" ] } ], "source": [ "import ref.all\n", "\n", "A = array(2 * [3 * [True]])\n", "print(ref.all.demo_bool(A))\n", "\n", "A[0, 1] = False\n", "print(ref.all.demo_bool(A))\n", "\n", "L = array(range(10)) # Doesn't work with `list(range(10))`\n", "print(L)\n", "print(ref.all.demo_int(L)) # False\n", "\n", "L[0] = -1\n", "print(ref.all.demo_int(L)) # True\n", "\n", "A = array([[1., -2., 3.],\n", " [-4., 5., 6.]])\n", "print(A)\n", "print(ref.all.demo_double(A))\n", "\n", "A[-1, -1] = 0.0\n", "print(A)\n", "print(ref.all.demo_double(A))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='any'></a>\n", "\n", "## Function: `any`\n", "\n", "Returns `True` if any element of a given iterable object is `True`; equivalent to its [Python builtin](https://docs.python.org/3/library/functions.html#any)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Example.**" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Overwriting ref/any.pydd\n" ] } ], "source": [ "%%writefile ref/any.pydd\n", "\n", "def demo_bool(A: Array(bool, 2)) -> bool:\n", " return any(A)\n", "\n", "def demo_int(A: Array(int64)) -> bool:\n", " return any(A)\n", "\n", "def demo_double(A: Array(float64, 2)) -> bool:\n", " return any(A)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "!pyddc ref/any.pydd" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n", "True\n", "[0 0 0 0 0]\n", "False\n", "True\n" ] } ], "source": [ "import ref.any\n", "\n", "A = array(2 * [3 * [False]])\n", "print(ref.any.demo_bool(A))\n", "\n", "A[0, 1] = True\n", "print(ref.any.demo_bool(A))\n", "\n", "L = array([0] * 5) # Doesn't work with `list(range(10))`\n", "print(L)\n", "print(ref.any.demo_int(L)) # False\n", "\n", "L[0] = -1\n", "print(ref.any.demo_int(L)) # True" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='len'></a>\n", "\n", "## Function: `len`\n", "\n", "Returns the length of the object; equivalent to its [Python builtin](https://docs.python.org/3/library/functions.html#len)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Example.**" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Overwriting ref/len.pydd\n" ] } ], "source": [ "%%writefile ref/len.pydd\n", "\n", "def demo_list(L: List(int)) -> int64:\n", " return len(L)\n", "\n", "def demo_dict(D: Dict(int64, float64)) -> int64:\n", " return len(D)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "!pyddc ref/len.pydd" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3\n", "4\n" ] } ], "source": [ "import ref.len\n", "print(ref.len.demo_list([-1, -2, -3]))\n", "print(ref.len.demo_dict({1: 3.14, 2: 2.718, 3: 6.9824, 4: -1.2}))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='max'></a>\n", "\n", "## Function: `max`\n", "\n", "Returns the maximum value of an iterable; equivalent to its [Python builtin](https://docs.python.org/3/library/functions.html#max)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Example.**" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Overwriting ref/max.pydd\n" ] } ], "source": [ "%%writefile ref/max.pydd\n", "\n", "def demo_int(A: Array(int64, 1)) -> int64:\n", " return max(A)\n", "\n", "def demo_float32_2d(A: Array(float32, 2)) -> float32:\n", " return max(A)" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "!pyddc ref/max.pydd" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "100\n", "100.0\n" ] } ], "source": [ "import ref.max\n", "print(ref.max.demo_int(array([3, 2, 100, 7])))\n", "print(ref.max.demo_float32_2d(array([[3, 2, 100, 33], [-500, 1, 0, -40]], dtype=float32)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='min'></a>\n", "\n", "## Function: `min`\n", "\n", "Returns the maximum value of an iterable object; equivalent to its [Python builtin](https://docs.python.org/3/library/functions.html#max)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Example.**" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Overwriting ref/min.pydd\n" ] } ], "source": [ "%%writefile ref/min.pydd\n", "\n", "def demo_int(A: Array(int64, 1)) -> int64:\n", " return min(A)\n", "\n", "def demo_float32_2d(A: Array(float32, 2)) -> float32:\n", " return min(A)" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [], "source": [ "!pyddc ref/min.pydd" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2\n", "-500.0\n" ] } ], "source": [ "import ref.min\n", "print(ref.min.demo_int(array([3, 2, 100, 7])))\n", "print(ref.min.demo_float32_2d(array([[3, 2, 100, 33], [-500, 1, 0, -40]], dtype=float32)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='pow'></a>\n", "\n", "## Function: `pow`\n", "\n", "Raises a given value or every element of an iterable object to some power; equivalent to its [Python builtin](https://docs.python.org/3/library/functions.html#pow)." ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Overwriting ref/pow.pydd\n" ] } ], "source": [ "%%writefile ref/pow.pydd\n", "\n", "def demo_float32(x: float32, p: float32) -> float32:\n", " return pow(x, p)\n", "\n", "def demo_float32_1d(A: Array(float32, 1), p: float32) -> Array(float32, 1):\n", " return pow(A, p)" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [], "source": [ "!pyddc ref/pow.pydd" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "9.859601020812988\n", "[ 30.959146 -30.959146]\n" ] } ], "source": [ "import ref.pow\n", "\n", "print(ref.pow.demo_float32(3.14, 2.0))\n", "print(ref.pow.demo_float32_1d(array([3.14, -3.14], dtype=float32), 3.0))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='print'></a>\n", "\n", "## Function: `print`\n", "\n", "Prints a value to standard output.\n", "\n", "This function is equivalent to its [Python builtin](https://docs.python.org/3/library/functions.html#print). However, in the current version of Intrepydd, it is limited to accepting just one argument, i.e., `print(x)`, where `x` must be a primitive type." ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Overwriting ref/print.pydd\n" ] } ], "source": [ "%%writefile ref/print.pydd\n", "\n", "def demo_float32(x: float32):\n", " print(x)\n", "\n", "def demo_float32_1d(A: Array(float32, 1)):\n", " for i in range(shape(A, 0)):\n", " print(A[i])" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [], "source": [ "!pyddc ref/print.pydd" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3.140000104904175\n", "1.0\n", "2.0\n", "3.0\n" ] } ], "source": [ "import ref.print\n", "ref.print.demo_float32(3.14)\n", "ref.print.demo_float32_1d(array([1, 2, 3], dtype=float32))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='range'></a>\n", "\n", "## Function: `range`\n", "\n", "Generates an integer range (sequence); equivalent to its [Python builtin](https://docs.python.org/3/library/functions.html#func-range)." ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Overwriting ref/range.pydd\n" ] } ], "source": [ "%%writefile ref/range.pydd\n", "\n", "def demo_std(n: int64) -> int64:\n", " s = 0\n", " for i in range(n):\n", " s += i\n", " print(i)\n", " return s\n", " \n", "def demo_start_end(a: int64, b: int64) -> int64:\n", " s = 0\n", " for i in range(a, b):\n", " print(i)\n", " s += i\n", " return s\n", "\n", "def demo_start_end_step(a: int64, b: int64, c: int64) -> int64:\n", " s = 0\n", " for i in range(a, b, c):\n", " print(i)\n", " s += i\n", " return s" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [], "source": [ "!pyddc ref/range.pydd" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0\n", "1\n", "2\n", "3\n", "4\n", "-3\n", "-2\n", "-1\n", "0\n", "1\n", "2\n", "3\n", "4\n", "5\n", "6\n", "-3\n", "-1\n", "1\n", "3\n", "5\n" ] }, { "data": { "text/plain": [ "5" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import ref.range\n", "ref.range.demo_std(5)\n", "ref.range.demo_start_end(-3, 7)\n", "ref.range.demo_start_end_step(-3, 7, 2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='sum'></a>\n", "\n", "## Function: `sum`\n", "\n", "Returns the sum of the elements in an iterable object.\n", "\n", "This function is equivalent to its [Python builtin](https://docs.python.org/3/library/functions.html#sum), except it does **not** support the optional start argument, i.e., it does not support the calling signature, `sum(x, start)`, where in standard Python `start` is the position of the first index at which to begin the sum." ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Overwriting ref/sum.pydd\n" ] } ], "source": [ "%%writefile ref/sum.pydd\n", "\n", "def demo(x: Array(int64, 2)) -> int64:\n", " return sum(x)" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [], "source": [ "!pyddc ref/sum.pydd" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "55" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import ref.sum\n", "ref.sum.demo(array([[1, 2, 3, 4, 5],\n", " [6, 7, 8, 9, 10]]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='type_conv'></a>\n", "\n", "## Type conversion\n", "\n", "Construct or convert scalar variables among primitive types: `int32`, `int64`, `float32`, `float64`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Example:** `float32`." ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Overwriting ref/types.pydd\n" ] } ], "source": [ "%%writefile ref/types.pydd\n", "\n", "def do_float32() -> float32:\n", " return float32()\n", "\n", "def do_float32_2(val: int32) -> float32:\n", " return float32(val)" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [], "source": [ "!pyddc ref/types.pydd" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.0\n", "124.0\n", "1.0\n" ] } ], "source": [ "import ref.types\n", "\n", "print(ref.types.do_float32()) # 0, as a float\n", "print(ref.types.do_float32_2(124))\n", "print(ref.types.do_float32_2(True))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Numpy equivalents" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='unary'></a>\n", "\n", "## Basic arithmetic: unary operators, `elemwise_not`, `minus`\n", "\n", "Applies basic arithmetic options elementwise to an input. These are equivalent to their Numpy counterparts; e.g., see [Numpy's `logical_not`](https://docs.scipy.org/doc/numpy/reference/generated/numpy.logical_not.html)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Example:** `minus`." ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Overwriting ref/minus.pydd\n" ] } ], "source": [ "%%writefile ref/minus.pydd\n", "\n", "def demo_float32(x: Array(float32, 2)) -> Array(float32, 2):\n", " return minus(x)\n", "\n", "def demo_int64(x: Array(int64, 2)) -> Array(int64, 2):\n", " return minus(x)" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [], "source": [ "!pyddc ref/minus.pydd" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[-1., -2., -3.],\n", " [-4., -5., -6.]], dtype=float32)" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import ref.minus\n", "x = array([[1, 2, 3], [4, 5, 6]], dtype=float32)\n", "ref.minus.demo_float32(x)" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[-1, 2, -3],\n", " [ 4, -5, 6]])" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y = array([[1, -2, 3], [-4, 5, -6]], dtype=int)\n", "ref.minus.demo_int64(y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='binary'></a>\n", "\n", "## Basic arithmetic: binary operators, `add`, `sub`, `mul`, `div`\n", "\n", "Applies basic arithmetic options elementwise to a pair of inputs. These are equivalent to their Numpy counterparts; e.g., see [Numpy's `add`](https://docs.scipy.org/doc/numpy/reference/generated/numpy.add.html?highlight=add#numpy.add)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Example:** `add`." ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Overwriting ref/add.pydd\n" ] } ], "source": [ "%%writefile ref/add.pydd\n", "\n", "def demo_float32(x: Array(float32, 2), y: Array(float32, 2)) -> Array(float32, 2):\n", " return add(x, y)\n", "\n", "def demo_int64(x: Array(int64, 2), y: Array(int64, 2)) -> Array(int64, 2):\n", " return add(x, y)" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [], "source": [ "!pyddc ref/add.pydd" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 2., 0., 6.],\n", " [ 0., 10., 0.]], dtype=float32)" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import ref.add\n", "x = array([[1, 2, 3], [4, 5, 6]], dtype=float32)\n", "y = array([[1, -2, 3], [-4, 5, -6]], dtype=float32)\n", "ref.add.demo_float32(x, y)" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 2, 0, 6],\n", " [ 0, 10, 0]], dtype=int64)" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = array([[1, 2, 3], [4, 5, 6]], dtype=int)\n", "y = array([[1, -2, 3], [-4, 5, -6]], dtype=int)\n", "ref.add.demo_int64(x, y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='comparisons'></a>\n", "\n", "## Comparisons: binary logical operators, `eq`, `ge`, `gt`, `le`, `lt`\n", "\n", "Given a pair of inputs, performs elementwise binary comparisons: equality (`eq`), greater than (`gt`), greater than or equal to (`ge`), less than (`lt`), and less than or equal to (`le`). These are equivalent to their Numpy counterparts; e.g., see [Numpy's `eq`](https://docs.scipy.org/doc/numpy/reference/generated/numpy.eq.html?highlight=eq#numpy.eq) for an example of equality comparison.\n", "\n", "> When the inputs are floating-point, it is usually better to apply `allclose` rather than `eq` to test for approximate equality due to round-off errors with floating-point arithmetic." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Example:** greater than (`gt`)." ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Overwriting ref/gt.pydd\n" ] } ], "source": [ "%%writefile ref/gt.pydd\n", "\n", "def demo_float32(x: Array(float32, 2), y: Array(float32, 2)) -> Array(bool, 2):\n", " return gt(x, y)\n", "\n", "def demo_int64(x: Array(int64, 2), y: Array(int64, 2)) -> Array(bool, 2):\n", " return gt(x, y)" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [], "source": [ "!pyddc ref/gt.pydd" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[False, True, False],\n", " [ True, False, True]])" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import ref.gt\n", "eps = 1e-6 # greater than float32 machine epsilon\n", "x = array([[1, 2, 3], [4, 5, 6]], dtype=float32)\n", "y = x + eps*array([[1, -1, 1], [-1, 0, -1]], dtype=float32)\n", "ref.gt.demo_float32(x, y)" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[False, True, False],\n", " [ True, False, True]])" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = array([[1, 2, 3], [4, 5, 6]], dtype=int)\n", "y = x + array([[1, -1, 1], [-1, 0, -1]], dtype=int)\n", "ref.gt.demo_int64(x, y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='elemfun'></a>\n", "\n", "## Elementary functions: `acos`, `asin`, `atan`, `cos`, `exp`, `log`, `sin`, `sqrt`, `tan`\n", "\n", "Applies trigonometric function elementwise and returns the result. These are equivalent to their Numpy equivalents, e.g., see [Numpy's `arccos`](https://docs.scipy.org/doc/numpy/reference/generated/numpy.arccos.html).\n", "\n", "**Example:** `acos`." ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Overwriting ref/acos.pydd\n" ] } ], "source": [ "%%writefile ref/acos.pydd\n", "\n", "def demo(x: Array(float32, 2)) -> Array(float32, 2):\n", " return acos(x)" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [], "source": [ "!pyddc ref/acos.pydd" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[0.99999994 0.6666667 0.5 ]\n", " [0.5 0.33333328 0. ]] * pi\n" ] } ], "source": [ "import math\n", "import ref.acos\n", "theta_over_pi = ref.acos.demo(array([[-1, -0.5, 0],\n", " [0, 0.5, 1]], dtype=float32))/math.pi\n", "print('{} * pi'.format(theta_over_pi))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='allclose'></a>\n", "\n", "## Function: `allclose`\n", "\n", "Returns `True` if all elements of a given array are close to a given value.\n", "\n", "This function implements `allclose(x, atol)`, where `x` is an input array and `atol` is an absolute threshold. Therefore, Intrepydd's `allclose` is similar to, but **not** equivalent to, its [Numpy counterpart](https://docs.scipy.org/doc/numpy/reference/generated/numpy.allclose.html)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Numpy's `allclose`.** In particular, Numpy's `allclose` evaluates the logical operation $\\bigwedge_i \\left( |a_i - b_i| \\leq \\alpha + \\rho |b_i| \\right)$, where $\\bigwedge$ denotes logical-and, $a_i$ and $b_i$ are the elements of two arrays, and $\\alpha$ and $\\rho$ are absolute and relative threshold parameters, respectively. (The values of $\\alpha$ and $\\rho$ are the `atol` and `rtol` arguments to `allclose()`.) For instance, suppose we have two Numpy arrays, `a` and `b`, and suppose the absolute difference between any pair of corresponding elements is $10^{-10}$.\n", "\n", "```python\n", "# Numpy allclose\n", "from numpy import allclose, array\n", "tiny_diff = 1e-10\n", "a = array([1., 2., 3.])\n", "b = a + array([tiny_diff, -tiny_diff, tiny_diff])\n", "```\n", "\n", "Consider two calls to `allclose`: one that checks whether the absolute difference is less than $10^{-11}$, which will be false, and the other that checks against $10^{-9}$, which will be true.\n", "\n", "```python\n", "print(allclose(a, b, atol=1e-11, rtol=0)) # False!\n", "print(allclose(a, b, atol=1e-9, rtol=0)) # True!\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Intrepydd's `allclose`.** By contrast, Intrepydd's interface, `allclose(x, atol)`, is \"lighter.\" It accepts just a single array (`x`) and an absolute tolerance (`atol`). There is no direct relative tolerance support (but see below!). The previous two checks would be rewritten as follows:\n", "\n", "```python\n", " # Intrepydd:\n", " allclose(abs(a-b), 1e-11) # False!\n", " allclose(abs(a-b), 1e-9) # True!\n", "```\n", "\n", "To implement something like Numpy's `allclose()`, which accepts both `atol` and `rtol` parameters, see the `demo` function in the code cells below." ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[-1.00000008e-10 1.00000008e-10 -1.00000008e-10]\n", "False\n", "True\n" ] } ], "source": [ "from numpy import allclose, array\n", "a = array([1., 2., 3.])\n", "b = a + array([1e-10, -1e-10, 1e-10])\n", "print(a-b)\n", "print(allclose(a, b, atol=1e-11, rtol=0)) # False!\n", "print(allclose(a, b, atol=1e-9, rtol=0)) # True!" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Overwriting ref/allclose.pydd\n" ] } ], "source": [ "%%writefile ref/allclose.pydd\n", "\n", "def scale_array(x: Array(float64, 2), s: float64) -> Array(float64, 2):\n", " y = empty([shape(x, 0), shape(x, 1)])\n", " for i in range(shape(y, 0)):\n", " for j in range(shape(y, 1)):\n", " y[i, j] = x[i, j] * s\n", " return y\n", "\n", "def demo(a: Array(float64, 2), b: Array(float64, 2), atol: float64, rtol: float64) -> bool:\n", " diff = abs(sub(a, b))\n", " relterm = abs(scale_array(b, rtol))\n", " x = sub(diff, relterm)\n", " return allclose(x, atol)" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [], "source": [ "!pyddc ref/allclose.pydd" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n", "True\n" ] } ], "source": [ "import ref.allclose\n", "\n", "a = array([[1., 2., 3.],\n", " [4., 5., 6.]])\n", "b = a + 1e-10\n", "print(ref.allclose.demo(a, b, 1e-11, 0.)) # False?\n", "print(ref.allclose.demo(a, b, 1e-9, 0.)) # True?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='argmin'></a>\n", "\n", "## Function: `argmin`\n", "\n", "Returns the location of the minimum value of an array; equivalent to its [Numpy counterpart](https://docs.scipy.org/doc/numpy/reference/generated/numpy.argmin.html?highlight=add#numpy.argmin).\n", "\n", "The return value is a list, since the input array may be multidimensional. A best-practice in the current version of Intrepydd is to recast this return as an array before returning, as the following example shows.\n", "\n", "> If there are duplicates, one of them will be returned. The precise one is not specified." ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Overwriting ref/argmin.pydd\n" ] } ], "source": [ "%%writefile ref/argmin.pydd\n", "\n", "def demo(A: Array(float64, 3)) -> Array(int32) :\n", " r = argmin(A)\n", " r_np = empty((3,), int32())\n", " r_np[0] = r[0]\n", " r_np[1] = r[1]\n", " r_np[2] = r[2]\n", " return r_np" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [], "source": [ "!pyddc ref/argmin.pydd" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1 1 2] : <class 'numpy.ndarray'>\n", "Min value is -6.0, which resides at location x[1 1 2]\n" ] } ], "source": [ "import ref.argmin\n", "plane = array([[1., 2., 3.],\n", " [4., 5., 6.]])\n", "x = array([plane, -plane, plane])\n", "loc = ref.argmin.demo(x)\n", "print(loc, ':', type(loc))\n", "print(\"Min value is {}, which resides at location x{}\".format(x[loc[0], loc[1], loc[2]], loc))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='argmax'></a>\n", "\n", "## Function: `argmax`\n", "\n", "Returns the location of the maximum value of an array; equivalent to its [Numpy counterpart](https://docs.scipy.org/doc/numpy/reference/generated/numpy.argmax.html?highlight=add#numpy.argmax).\n", "\n", "The return value is a list, since the input array may be multidimensional. A best-practice in the current version of Intrepydd is to recast this return as an array before returning, as the following example shows.\n", "\n", "> If there are duplicates, one of them will be returned. The precise one is not specified." ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Overwriting ref/argmax.pydd\n" ] } ], "source": [ "%%writefile ref/argmax.pydd\n", "\n", "def demo(A: Array(float64, 3)) -> Array(int32) :\n", " r = argmax(A)\n", " r_np = empty((3,), int32())\n", " r_np[0] = r[0]\n", " r_np[1] = r[1]\n", " r_np[2] = r[2]\n", " return r_np" ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [], "source": [ "!pyddc ref/argmax.pydd" ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1 1 2] : <class 'numpy.ndarray'>\n", "Max value is 6.0, which resides at location x[1 1 2]\n" ] } ], "source": [ "import ref.argmax\n", "plane = array([[1., 2., 3.],\n", " [4., 5., 6.]])\n", "x = array([-plane, plane, -plane])\n", "loc = ref.argmax.demo(x)\n", "print(loc, ':', type(loc))\n", "print(\"Max value is {}, which resides at location x{}\".format(x[loc[0], loc[1], loc[2]], loc))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='empty'></a>\n", "\n", "## Function: `empty`\n", "\n", "Returns an \"empty\" (uninitialized) multidimensional array; equivalent to its [Numpy counterpart](https://docs.scipy.org/doc/numpy/reference/generated/numpy.empty.html?highlight=add#numpy.empty).\n", "\n", "> Intrepydd does not currently implement the `order` parameter, which would be used to specify row- vs. column-major layouts. Intrepydd's default is row-major." ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Overwriting ref/empty.pydd\n" ] } ], "source": [ "%%writefile ref/empty.pydd\n", "\n", "def demo_int32(shape: List(int32)) -> Array(int32):\n", " return empty(shape, int32())\n", "\n", "def demo_float64(shape: List(int32)) -> Array(float64):\n", " return empty(shape, float64())" ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [], "source": [ "!pyddc ref/empty.pydd" ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "<class 'numpy.ndarray'> int32\n", "[[[ 0 -1074790400]\n", " [ 0 -1073741824]\n", " [ 0 -1073217536]]\n", "\n", " [[ 0 -1072693248]\n", " [ 0 -1072431104]\n", " [ 0 -1072168960]]]\n", "<class 'numpy.ndarray'> float64\n", "[[[-8.39911598e-323 -0.00000000e+000]\n", " [ 1.49458072e-154 -0.00000000e+000]\n", " [ 7.41098469e-323 0.00000000e+000]]\n", "\n", " [[ 0.00000000e+000 0.00000000e+000]\n", " [ 0.00000000e+000 0.00000000e+000]\n", " [ 0.00000000e+000 0.00000000e+000]]]\n" ] } ], "source": [ "import ref.empty\n", "A = ref.empty.demo_int32([2, 3, 2])\n", "print(type(A), A.dtype)\n", "print(A)\n", "\n", "B = ref.empty.demo_float64([2, 3, 2])\n", "print(type(B), B.dtype)\n", "print(B)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='innerprod'></a>\n", "\n", "## Function: `innerprod`\n", "\n", "Returns the inner product (dot-product) between two arrays of the same size. Its closest counterpart in Numpy is [`numpy.ma.innerproduct`](https://docs.scipy.org/doc/numpy/reference/generated/numpy.ma.innerproduct.html)." ] }, { "cell_type": "code", "execution_count": 64, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Overwriting ref/innerprod.pydd\n" ] } ], "source": [ "%%writefile ref/innerprod.pydd\n", "\n", "def func(A: Array(int32, 1), B: Array(float64, 1)) -> float64:\n", " return innerprod(A, B)" ] }, { "cell_type": "code", "execution_count": 65, "metadata": {}, "outputs": [], "source": [ "!pyddc ref/innerprod.pydd" ] }, { "cell_type": "code", "execution_count": 66, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "14.0" ] }, "execution_count": 66, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import ref.innerprod\n", "\n", "x = array([1, 2, 3], dtype=int32)\n", "y = array([1., 2., 3.])\n", "\n", "ref.innerprod.func(x, y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='isfpXXX'></a>\n", "\n", "## Functions: `isinf`, `isnan`\n", "\n", "Tests whether values of an array are IEEE floating-point infinity (`inf`) or not-a-number (`NaN`) values; equivalent to the Numpy functions [`numpy.isinf`](https://docs.scipy.org/doc/numpy/reference/generated/numpy.isinf.html) and [`numpy.isnan`](https://docs.scipy.org/doc/numpy/reference/generated/numpy.isnan.html)." ] }, { "cell_type": "code", "execution_count": 67, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Overwriting ref/isfpXXX.pydd\n" ] } ], "source": [ "%%writefile ref/isfpXXX.pydd\n", "\n", "def demo_isinf(x: Array(float64, 2)) -> Array(bool, 2):\n", " return isinf(x)\n", "\n", "def demo_isnan(x: Array(float32, 2)) -> Array(bool, 2):\n", " return isnan(x)" ] }, { "cell_type": "code", "execution_count": 68, "metadata": {}, "outputs": [], "source": [ "!pyddc ref/isfpXXX.pydd" ] }, { "cell_type": "code", "execution_count": 69, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[False True False]\n", " [False False True]]\n", "[[False False False]\n", " [ True False False]]\n" ] } ], "source": [ "import ref.isfpXXX\n", "\n", "z = array([[1.0, float('inf'), 0.0],\n", " [float('nan'), -2.0, float('inf')]])\n", "\n", "print(ref.isfpXXX.demo_isinf(z))\n", "print(ref.isfpXXX.demo_isnan(z.astype(float32)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='prod'></a>\n", "\n", "## Function: `prod`\n", "\n", "Returns the product of all elements of a collection; equivalent to its [`Numpy counterpart`](https://docs.scipy.org/doc/numpy/reference/generated/numpy.prod.html)." ] }, { "cell_type": "code", "execution_count": 70, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Overwriting ref/prod.pydd\n" ] } ], "source": [ "%%writefile ref/prod.pydd\n", "\n", "def demo(arr: Array(int64)) -> int64:\n", " return prod(arr)" ] }, { "cell_type": "code", "execution_count": 71, "metadata": {}, "outputs": [], "source": [ "!pyddc ref/prod.pydd" ] }, { "cell_type": "code", "execution_count": 72, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "-30" ] }, "execution_count": 72, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import ref.prod\n", "ref.prod.demo(array([1, -2, 3, 5], dtype=int))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='transpose'></a>\n", "\n", "## Function: `transpose`\n", "\n", "Returns the transpose of a matrix.\n", "\n", "This function is roughly equivalent to its [`Numpy counterpart`](https://docs.scipy.org/doc/numpy/reference/generated/numpy.transpose.html), except that it works only for matrix (2-D) inputs." ] }, { "cell_type": "code", "execution_count": 73, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Overwriting ref/transpose.pydd\n" ] } ], "source": [ "%%writefile ref/transpose.pydd\n", "\n", "def demo(arr: Array(int32, 2)) -> Array(int32, 2):\n", " return transpose(arr)" ] }, { "cell_type": "code", "execution_count": 74, "metadata": {}, "outputs": [], "source": [ "!pyddc ref/transpose.pydd" ] }, { "cell_type": "code", "execution_count": 75, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1, 4],\n", " [2, 5],\n", " [3, 6]], dtype=int32)" ] }, "execution_count": 75, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import ref.transpose\n", "ref.transpose.demo(array([[1, 2, 3], [4, 5, 6]], dtype=int32))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<a id='zeros'></a>\n", "\n", "## Function: `zeros`\n", "\n", "Returns an array of all zeros; equivalent to its [`Numpy counterpart`](https://docs.scipy.org/doc/numpy/reference/generated/numpy.zeros.html)." ] }, { "cell_type": "code", "execution_count": 76, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Overwriting ref/zeros.pydd\n" ] } ], "source": [ "%%writefile ref/zeros.pydd\n", "\n", "def zeros_1d(n: int) -> Array(float64, 1):\n", " return zeros(n, float64())\n", "\n", "def ones_2d(m:int, n: int) -> Array(float64, 2):\n", " C = zeros([m, n], float64())\n", " return cos(C)" ] }, { "cell_type": "code", "execution_count": 77, "metadata": {}, "outputs": [], "source": [ "!pyddc ref/zeros.pydd" ] }, { "cell_type": "code", "execution_count": 78, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0. 0. 0. 0.]\n", "[[1. 1. 1.]\n", " [1. 1. 1.]]\n" ] } ], "source": [ "import ref.zeros\n", "print(ref.zeros.zeros_1d(4))\n", "print(ref.zeros.ones_2d(2, 3))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "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.7.3" } }, "nbformat": 4, "nbformat_minor": 2 }