From 341108b08eae0b5985192cb2d2bdf0f7a587a2d5 Mon Sep 17 00:00:00 2001 From: Ravin Kumar Date: Sun, 30 Jan 2022 09:20:02 -0800 Subject: [PATCH 01/11] Add preliminary shapes doc --- docs/source/api.rst | 9 +- docs/source/learn/examples.md | 1 + docs/source/learn/examples/shapes.ipynb | 2201 +++++++++++++++++++++++ 3 files changed, 2210 insertions(+), 1 deletion(-) create mode 100644 docs/source/learn/examples/shapes.ipynb diff --git a/docs/source/api.rst b/docs/source/api.rst index b62b9145c7..4bf6644df6 100644 --- a/docs/source/api.rst +++ b/docs/source/api.rst @@ -23,8 +23,15 @@ API Reference api/shape_utils api/misc +------------------ +shapes, size, dims +------------------ +some placeholder text +The {ref}`GLM_linear` notebook provides is +The {ref}`shapes` notebook provides is + -------------- -API extensions +api extensions -------------- Plots, stats and diagnostics diff --git a/docs/source/learn/examples.md b/docs/source/learn/examples.md index 7a2af2451b..1a255a3319 100644 --- a/docs/source/learn/examples.md +++ b/docs/source/learn/examples.md @@ -37,4 +37,5 @@ examples/pymc_overview examples/GLM_linear examples/model_comparison examples/posterior_predictive +examples/shapes ::: diff --git a/docs/source/learn/examples/shapes.ipynb b/docs/source/learn/examples/shapes.ipynb new file mode 100644 index 0000000000..9bb39e50eb --- /dev/null +++ b/docs/source/learn/examples/shapes.ipynb @@ -0,0 +1,2201 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "# Shapes" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import pymc as pm\n", + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'4.0.0b2'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pm.__version__" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "%3\n", + "\n", + "\n", + "cluster3\n", + "\n", + "3\n", + "\n", + "\n", + "clusteryear (3)\n", + "\n", + "year (3)\n", + "\n", + "\n", + "clusterA (4)\n", + "\n", + "A (4)\n", + "\n", + "\n", + "clusterB (2)\n", + "\n", + "B (2)\n", + "\n", + "\n", + "\n", + "scalar\n", + "\n", + "scalar\n", + "~\n", + "Normal\n", + "\n", + "\n", + "\n", + "vector (from shape)\n", + "\n", + "vector (from shape)\n", + "~\n", + "Normal\n", + "\n", + "\n", + "\n", + "vector (from size)\n", + "\n", + "vector (from size)\n", + "~\n", + "Normal\n", + "\n", + "\n", + "\n", + "vector (implied)\n", + "\n", + "vector (implied)\n", + "~\n", + "Normal\n", + "\n", + "\n", + "\n", + "vector (from dims)\n", + "\n", + "vector (from dims)\n", + "~\n", + "Normal\n", + "\n", + "\n", + "\n", + "one\n", + "\n", + "one\n", + "~\n", + "Normal\n", + "\n", + "\n", + "\n", + "two\n", + "\n", + "two\n", + "~\n", + "Normal\n", + "\n", + "\n", + "\n", + "one->two\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "red\n", + "\n", + "red\n", + "~\n", + "Normal\n", + "\n", + "\n", + "\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "with pm.Model(coords={\n", + " \"year\": [2020, 2021, 2022],\n", + "}) as pmodel:\n", + " # Univariate RVs (ndim_support == 0)\n", + " pm.Normal(\"scalar\") # shape=()\n", + " pm.Normal(\"vector (implied)\", mu=[1,2,3])\n", + " pm.Normal(\"vector (from shape)\", shape=(3,))\n", + " pm.Normal(\"vector (from size)\", size=(3,))\n", + " pm.Normal(\"vector (from dims)\", dims=(\"year\",))\n", + "\n", + " # Creating dims from RVs\n", + " assert \"A\" not in pmodel.dim_lengths\n", + " pm.Normal(\"one\", [1,2,3,4], dims=\"A\") # (4,)\n", + " assert \"A\" in pmodel.dim_lengths\n", + " pm.Normal(\"two\", dims=\"A\")\n", + "\n", + " pm.Normal(\"red\", size=2, dims=\"B\")\n", + " assert \"B\" in pmodel.dim_lengths\n", + "\n", + "pm.model_to_graphviz(pmodel)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pm.MvNormal.rv_op.ndim_supp" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'year': ,\n", + " 'A': Subtensor{int64}.0,\n", + " 'B': Subtensor{int64}.0}" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pmodel.dim_lengths" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[2]\n", + "[3 2]\n", + "[3 2]\n" + ] + }, + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "%3\n", + "\n", + "\n", + "cluster2\n", + "\n", + "2\n", + "\n", + "\n", + "clusterrepeats (3) x implied (2)\n", + "\n", + "repeats (3) x implied (2)\n", + "\n", + "\n", + "clusterrepeats (3) x None (2)\n", + "\n", + "repeats (3) x None (2)\n", + "\n", + "\n", + "\n", + "implied\n", + "\n", + "implied\n", + "~\n", + "MvNormal\n", + "\n", + "\n", + "\n", + "with size\n", + "\n", + "with size\n", + "~\n", + "MvNormal\n", + "\n", + "\n", + "\n", + "with shape\n", + "\n", + "with shape\n", + "~\n", + "MvNormal\n", + "\n", + "\n", + "\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "with pm.Model() as pmodel:\n", + " # Multivariate RVs (ndim_supp > 0)\n", + " mv = pm.MvNormal(\"implied\", mu=[0, 0], cov=np.eye(2))\n", + " assert mv.ndim == 1\n", + " print(mv.shape.eval())\n", + "\n", + " mv = pm.MvNormal(\"with size\", mu=[0, 0], cov=np.eye(2), size=3, dims=(\"repeats\", \"implied\"))\n", + " print(mv.shape.eval())\n", + " # ⚠ Size dims are always __prepended__\n", + "\n", + " mv = pm.MvNormal(\"with shape\", mu=[0, 0], cov=np.eye(2), shape=(3, ...), dims=(\"repeats\", ...))\n", + " print(mv.shape.eval())\n", + "\n", + "\n", + "pm.model_to_graphviz(pmodel)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 0.65466774, 0.22397546],\n", + " [-0.27033677, -1.38344819],\n", + " [ 0.75297778, -0.64158639]])" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pmodel[\"with shape\"].eval()" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'seconds': ('time',), 'obs': ('time',), 'y': ('time',)}" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "with pm.Model() as pmodel:\n", + " seconds = pm.ConstantData(\"seconds\", [1,2,3], dims=\"time\")\n", + " observations = pm.MutableData(\"obs\", [2,3,1,2], dims=\"time\")\n", + " a = pm.Normal(\"a\")\n", + " b = pm.Normal(\"b\")\n", + " y = pm.Deterministic(\n", + " \"y\",\n", + " a * seconds + b,\n", + " dims=\"time\"\n", + " )\n", + "pmodel.RV_dims" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "%3\n", + "\n", + "\n", + "clustertime (3)\n", + "\n", + "time (3)\n", + "\n", + "\n", + "\n", + "obs\n", + "\n", + "obs\n", + "~\n", + "MutableData\n", + "\n", + "\n", + "\n", + "seconds\n", + "\n", + "seconds\n", + "~\n", + "ConstantData\n", + "\n", + "\n", + "\n", + "y\n", + "\n", + "y\n", + "~\n", + "Deterministic\n", + "\n", + "\n", + "\n", + "seconds->y\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "b\n", + "\n", + "b\n", + "~\n", + "Normal\n", + "\n", + "\n", + "\n", + "b->y\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "a\n", + "\n", + "a\n", + "~\n", + "Normal\n", + "\n", + "\n", + "\n", + "a->y\n", + "\n", + "\n", + "\n", + "\n", + "\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pm.model_to_graphviz(pmodel)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Auto-assigning NUTS sampler...\n", + "Initializing NUTS using jitter+adapt_diag...\n", + "Multiprocess sampling (4 chains in 4 jobs)\n", + "NUTS: [a, b]\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + "
\n", + " \n", + " \n", + " 100.00% [8000/8000 00:01<00:00 Sampling 4 chains, 0 divergences]\n", + "
\n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Sampling 4 chains for 1_000 tune and 1_000 draw iterations (4_000 + 4_000 draws total) took 1 seconds.\n" + ] + } + ], + "source": [ + "with pmodel:\n", + " idata = pm.sample()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
\n", + "
\n", + "
arviz.InferenceData
\n", + "
\n", + "
    \n", + " \n", + "
  • \n", + " \n", + " \n", + "
    \n", + "
    \n", + "
      \n", + "
      \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
      <xarray.Dataset>\n",
      +       "Dimensions:  (chain: 4, draw: 1000, time: 3)\n",
      +       "Coordinates:\n",
      +       "  * chain    (chain) int64 0 1 2 3\n",
      +       "  * draw     (draw) int64 0 1 2 3 4 5 6 7 8 ... 992 993 994 995 996 997 998 999\n",
      +       "  * time     (time) int64 0 1 2\n",
      +       "Data variables:\n",
      +       "    a        (chain, draw) float64 -2.032 -0.1187 -0.1207 ... 0.8091 0.3232\n",
      +       "    b        (chain, draw) float64 -0.3398 1.038 -1.631 ... -1.068 1.132 -0.6527\n",
      +       "    y        (chain, draw, time) float64 -2.371 -4.403 ... -0.006344 0.3168\n",
      +       "Attributes:\n",
      +       "    created_at:                 2022-01-30T17:17:55.014275\n",
      +       "    arviz_version:              0.11.4\n",
      +       "    inference_library:          pymc\n",
      +       "    inference_library_version:  4.0.0b1\n",
      +       "    sampling_time:              1.3605358600616455\n",
      +       "    tuning_steps:               1000

      \n", + "
    \n", + "
    \n", + "
  • \n", + " \n", + "
  • \n", + " \n", + " \n", + "
    \n", + "
    \n", + "
      \n", + "
      \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
      <xarray.Dataset>\n",
      +       "Dimensions:             (chain: 4, draw: 1000)\n",
      +       "Coordinates:\n",
      +       "  * chain               (chain) int64 0 1 2 3\n",
      +       "  * draw                (draw) int64 0 1 2 3 4 5 6 ... 994 995 996 997 998 999\n",
      +       "Data variables: (12/13)\n",
      +       "    lp                  (chain, draw) float64 -3.959 -2.384 ... -2.806 -2.103\n",
      +       "    n_steps             (chain, draw) float64 1.0 3.0 3.0 3.0 ... 3.0 3.0 3.0\n",
      +       "    step_size           (chain, draw) float64 1.239 1.239 1.239 ... 1.211 1.211\n",
      +       "    tree_depth          (chain, draw) int64 1 2 2 2 2 2 2 2 ... 1 2 2 2 2 2 2 2\n",
      +       "    energy_error        (chain, draw) float64 -0.2226 -0.6445 ... 0.1284 -0.2516\n",
      +       "    perf_counter_start  (chain, draw) float64 8.296e+04 8.296e+04 ... 8.296e+04\n",
      +       "    ...                  ...\n",
      +       "    max_energy_error    (chain, draw) float64 -0.2226 -0.6445 ... -0.2631\n",
      +       "    step_size_bar       (chain, draw) float64 1.182 1.182 1.182 ... 1.121 1.121\n",
      +       "    process_time_diff   (chain, draw) float64 0.0002103 0.000378 ... 0.0003762\n",
      +       "    perf_counter_diff   (chain, draw) float64 0.0002102 0.000378 ... 0.000376\n",
      +       "    acceptance_rate     (chain, draw) float64 1.0 0.9548 ... 0.9662 0.9773\n",
      +       "    energy              (chain, draw) float64 5.165 4.163 3.903 ... 3.001 2.816\n",
      +       "Attributes:\n",
      +       "    created_at:                 2022-01-30T17:17:55.018630\n",
      +       "    arviz_version:              0.11.4\n",
      +       "    inference_library:          pymc\n",
      +       "    inference_library_version:  4.0.0b1\n",
      +       "    sampling_time:              1.3605358600616455\n",
      +       "    tuning_steps:               1000

      \n", + "
    \n", + "
    \n", + "
  • \n", + " \n", + "
  • \n", + " \n", + " \n", + "
    \n", + "
    \n", + "
      \n", + "
      \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
      <xarray.Dataset>\n",
      +       "Dimensions:  (time: 4)\n",
      +       "Coordinates:\n",
      +       "  * time     (time) int64 0 1 2 3\n",
      +       "Data variables:\n",
      +       "    seconds  (time) float64 1.0 2.0 3.0 nan\n",
      +       "    obs      (time) int32 2 3 1 2\n",
      +       "Attributes:\n",
      +       "    created_at:                 2022-01-30T17:17:55.021942\n",
      +       "    arviz_version:              0.11.4\n",
      +       "    inference_library:          pymc\n",
      +       "    inference_library_version:  4.0.0b1

      \n", + "
    \n", + "
    \n", + "
  • \n", + " \n", + "
\n", + "
\n", + " " + ], + "text/plain": [ + "Inference data with groups:\n", + "\t> posterior\n", + "\t> sample_stats\n", + "\t> constant_data" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "idata" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "interpreter": { + "hash": "f574fac5b7e4a41f7640949d1e1759089329dd116ff7b389caa9cf21f93d872d" + }, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} From 43179cf6b196208a03065591030218c08fbe8efa Mon Sep 17 00:00:00 2001 From: Ravin Kumar Date: Sun, 30 Jan 2022 16:46:13 -0800 Subject: [PATCH 02/11] Update notebook --- docs/source/learn/examples/shapes.ipynb | 40 ++++++++++++++----------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/docs/source/learn/examples/shapes.ipynb b/docs/source/learn/examples/shapes.ipynb index 9bb39e50eb..789cfa0967 100644 --- a/docs/source/learn/examples/shapes.ipynb +++ b/docs/source/learn/examples/shapes.ipynb @@ -8,7 +8,14 @@ } }, "source": [ - "# Shapes" + "# PyMC Dimensionality\n", + "thers a bunch of ways to work with shapes. Here's the glossary of terms\n", + "\n", + "Let's dive into examples\n", + "\n", + "Reccomendations\n", + "## Recommendations\n", + "1. For any real work stick with dims because it'll label the InferenceData. Best practice transparency, For a three dimensional thing what these dimensions correspond to. Not going to know this unless dims" ] }, { @@ -22,23 +29,10 @@ ] }, { - "cell_type": "code", - "execution_count": 2, + "cell_type": "markdown", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'4.0.0b2'" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], "source": [ - "pm.__version__" + "## Example Scalar Distributions" ] }, { @@ -173,7 +167,7 @@ " pm.Normal(\"vector (from size)\", size=(3,))\n", " pm.Normal(\"vector (from dims)\", dims=(\"year\",))\n", "\n", - " # Creating dims from RVs\n", + " # Creating dims from Random Variables\n", " assert \"A\" not in pmodel.dim_lengths\n", " pm.Normal(\"one\", [1,2,3,4], dims=\"A\") # (4,)\n", " assert \"A\" in pmodel.dim_lengths\n", @@ -185,6 +179,11 @@ "pm.model_to_graphviz(pmodel)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + }, { "cell_type": "code", "execution_count": 4, @@ -227,6 +226,13 @@ "pmodel.dim_lengths" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Vector Distributions" + ] + }, { "cell_type": "code", "execution_count": 6, From e6126bba06578ea5d6534e811fd55a0f30058e66 Mon Sep 17 00:00:00 2001 From: Ravin Kumar Date: Mon, 31 Jan 2022 21:15:30 -0800 Subject: [PATCH 03/11] Update dimensionality notebook --- docs/source/learn/examples/shapes.ipynb | 2394 +++++------------------ 1 file changed, 448 insertions(+), 1946 deletions(-) diff --git a/docs/source/learn/examples/shapes.ipynb b/docs/source/learn/examples/shapes.ipynb index 789cfa0967..60c4448e55 100644 --- a/docs/source/learn/examples/shapes.ipynb +++ b/docs/source/learn/examples/shapes.ipynb @@ -9,13 +9,36 @@ }, "source": [ "# PyMC Dimensionality\n", - "thers a bunch of ways to work with shapes. Here's the glossary of terms\n", + "PyMC provides a number of ways to specify the dimensionality of its distributions. In this document we will not provide an exhaustive explanation but rather an overview and current best practices. \n", "\n", - "Let's dive into examples\n", + "## Glossary\n", + "In this document we'll be using the term dimensionality to refer to the idea of dimensions. Each of the terms below has a specific\n", + "semantic and computational definition in PyMC. While we share them here they will make much more sense when viewed in the examples below.\n", "\n", - "Reccomendations\n", - "## Recommendations\n", - "1. For any real work stick with dims because it'll label the InferenceData. Best practice transparency, For a three dimensional thing what these dimensions correspond to. Not going to know this unless dims" + "+ *Implied dimensions* → dimensionality that follows from inputs to the RV\n", + "+ *Support dimensions* → dimensions you can NEVER get rid of\n", + "+ *`ndim_support`* → smallest shape that can result from a random draw. This is a fixed attribute in the distribution definition\n", + "+ *Shape* → final resulting tensor shape\n", + "+ *Size* → shape minus the support dimensions\n", + "+ *Dims* → A named array that can be used to specify dimensionality\n", + "\n", + "## General Recommendations\n", + "### When prototyping implied and size are convenient\n", + "Implied dimensions are easy to specify and great for quickly expanding an existing RV. F\n", + "\n", + "### For reusable code we suggest dims\n", + "TODO(ravin): Make this nicer\n", + "For any more important work stick with dims because it'll label the InferenceData. Best practice transparency, For a three dimensional thing what these dimensions correspond to. Not going to know this unless dims\n", + "\n", + "### Use shape if you'd like to be strict\n", + "Use shape if you'd like to bypass any dimensionality calculations implicit in PyMC. This will strictly specify the dimensionality to Aesara" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Code Examples" ] }, { @@ -32,12 +55,178 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Example Scalar Distributions" + "## Scalar distribution example\n", + "We can start with the simplest case, a single Normal distribution. We specify one as shown below" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [], + "source": [ + "normal_dist = pm.Normal.dist()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can then take a random sample from that same distribution and print both the draw and shape" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(array(1.14185467), ())" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "random_sample = normal_dist.eval()\n", + "random_sample, random_sample.shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In this case we end up with a single scalar value. This is consistent with the distributions `ndim_supp` as the smallest random draw dimension is a scalar which has a dimension of zero" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pm.Normal.rv_op.ndim_supp" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Implied Example" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If we wanted three draws from differently centered Normals we instead could pass a vector to the parameters. When generating a random draw we would now expect a vector value, in this case a vector if size 3. This is a case of *implied dimensions*" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(array([ 0.99996052, 9.99993143, 100.0000965 ]), (3,))" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "random_sample = pm.Normal.dist(mu=[1,10,100], sd=.0001).eval()\n", + "random_sample, random_sample.shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Shape and Size" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Alternatively we may just want three draws from identical distributions. In this case we could use either `shape` or `size` to specify this" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(array([-1.31442847, 1.09896843, 0.42476213]), (3,))" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "random_sample = pm.Normal.dist(size=(3,)).eval()\n", + "random_sample, random_sample.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(array([-0.93941749, 0.1875374 , -0.56144478]), (3,))" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "random_sample = pm.Normal.dist(shape=(3,)).eval()\n", + "random_sample, random_sample.shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Inspecting dimensionality with a model graph\n", + "A powerful tool to understand and debug dimensionality in PyMC is the `pm.model_to_graphviz` functionality. Rather than inspecting array outputs we instead can read the Graphviz output to understand the dimensionality.\n", + "\n", + "In the example below the number on the bottom left of each box indicates the dimensionality of the Random Variable. With the scalar distribution it is implied to be one random draw of `ndim_support`" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 47, "metadata": {}, "outputs": [ { @@ -49,109 +238,217 @@ "\n", "\n", - "\n", - "\n", + "\n", + "\n", "%3\n", - "\n", + "\n", "\n", "cluster3\n", - "\n", - "3\n", + "\n", + "3\n", "\n", "\n", - "clusteryear (3)\n", - "\n", - "year (3)\n", + "cluster4\n", + "\n", + "4\n", "\n", "\n", - "clusterA (4)\n", - "\n", - "A (4)\n", - "\n", - "\n", - "clusterB (2)\n", - "\n", - "B (2)\n", + "cluster5\n", + "\n", + "5\n", "\n", "\n", "\n", "scalar\n", - "\n", - "scalar\n", - "~\n", - "Normal\n", + "\n", + "scalar\n", + "~\n", + "Normal\n", "\n", - "\n", + "\n", "\n", + "vector (implied)\n", + "\n", + "vector (implied)\n", + "~\n", + "Normal\n", + "\n", + "\n", + "\n", "vector (from shape)\n", - "\n", - "vector (from shape)\n", - "~\n", - "Normal\n", + "\n", + "vector (from shape)\n", + "~\n", + "Normal\n", "\n", "\n", - "\n", + "\n", "vector (from size)\n", - "\n", - "vector (from size)\n", - "~\n", - "Normal\n", + "\n", + "vector (from size)\n", + "~\n", + "Normal\n", "\n", - "\n", - "\n", - "vector (implied)\n", - "\n", - "vector (implied)\n", - "~\n", - "Normal\n", "\n", - "\n", - "\n", - "vector (from dims)\n", - "\n", - "vector (from dims)\n", - "~\n", - "Normal\n", + "\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "with pm.Model() as pmodel:\n", + " pm.Normal(\"scalar\") # shape=()\n", + " pm.Normal(\"vector (implied)\", mu=[1,2,3])\n", + " pm.Normal(\"vector (from shape)\", shape=(4,))\n", + " pm.Normal(\"vector (from size)\", size=(5,))\n", + " \n", + "pm.model_to_graphviz(pmodel)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Dims\n", + "A new feature of PyMC is `dims` support. With many random variables it can become confusing which dimensionality corresponds to which \"real world\" idea, e.g. number of observations, number of treated units etc. The dims argument is an additional label to help." + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "%3\n", + "\n", + "\n", + "clusterB (2)\n", + "\n", + "B (2)\n", + "\n", + "\n", + "clusterDim_A (4)\n", + "\n", + "Dim_A (4)\n", + "\n", + "\n", + "\n", + "red\n", + "\n", + "red\n", + "~\n", + "Normal\n", "\n", "\n", - "\n", + "\n", "one\n", - "\n", - "one\n", - "~\n", - "Normal\n", + "\n", + "one\n", + "~\n", + "Normal\n", "\n", "\n", - "\n", + "\n", "two\n", - "\n", - "two\n", - "~\n", - "Normal\n", + "\n", + "two\n", + "~\n", + "Normal\n", "\n", "\n", "\n", "one->two\n", - "\n", - "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "red\n", - "\n", - "red\n", - "~\n", - "Normal\n", + "\n", + "\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 59, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "with pm.Model() as pmodel:\n", + " pm.Normal(\"red\", size=2, dims=\"B\")\n", + "\n", + " pm.Normal(\"one\", [1,2,3,4], dims=\"Dim_A\") # (4,)\n", + " pm.Normal(\"two\", dims=\"Dim_A\")\n", + "\n", + "\n", + "pm.model_to_graphviz(pmodel)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Where dims can become increasingly powerful is with the use of `coords` specified in the model itself. With this it becomes easy to track. As an added bonus the coords and dims will also be present in the returned `azInferenceData` simplifying the entire workflow." + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "%3\n", + "\n", + "\n", + "clusteryear (3)\n", + "\n", + "year (3)\n", + "\n", + "\n", + "\n", + "Normal_RV\n", + "\n", + "Normal_RV\n", + "~\n", + "Normal\n", "\n", "\n", "\n" ], "text/plain": [ - "" + "" ] }, - "execution_count": 3, + "execution_count": 61, "metadata": {}, "output_type": "execute_result" } @@ -160,33 +457,23 @@ "with pm.Model(coords={\n", " \"year\": [2020, 2021, 2022],\n", "}) as pmodel:\n", - " # Univariate RVs (ndim_support == 0)\n", - " pm.Normal(\"scalar\") # shape=()\n", - " pm.Normal(\"vector (implied)\", mu=[1,2,3])\n", - " pm.Normal(\"vector (from shape)\", shape=(3,))\n", - " pm.Normal(\"vector (from size)\", size=(3,))\n", - " pm.Normal(\"vector (from dims)\", dims=(\"year\",))\n", - "\n", - " # Creating dims from Random Variables\n", - " assert \"A\" not in pmodel.dim_lengths\n", - " pm.Normal(\"one\", [1,2,3,4], dims=\"A\") # (4,)\n", - " assert \"A\" in pmodel.dim_lengths\n", - " pm.Normal(\"two\", dims=\"A\")\n", + " \n", + " pm.Normal(\"Normal_RV\", dims=\"year\")\n", "\n", - " pm.Normal(\"red\", size=2, dims=\"B\")\n", - " assert \"B\" in pmodel.dim_lengths\n", - "\n", - "pm.model_to_graphviz(pmodel)" + " pm.model_to_graphviz(pmodel)" ] }, { "cell_type": "markdown", "metadata": {}, - "source": [] + "source": [ + "## Vector Distributions\n", + "Some distributions by definition cannot return scalar values as random samples, but instead will return an array as their result. An example is the Multivariate Normal. The simplest possible return shape can be verified using `ndim_supp`. The value here indicates the smallest shape that can be returned is a vector" + ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 52, "metadata": {}, "outputs": [ { @@ -195,7 +482,7 @@ "1" ] }, - "execution_count": 4, + "execution_count": 52, "metadata": {}, "output_type": "execute_result" } @@ -204,38 +491,64 @@ "pm.MvNormal.rv_op.ndim_supp" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This can be verified with a random sample as well." + ] + }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 66, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "{'year': ,\n", - " 'A': Subtensor{int64}.0,\n", - " 'B': Subtensor{int64}.0}" + "array([0.22626491, 2.01962398, 0.89651223])" ] }, - "execution_count": 5, + "execution_count": 67, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "pmodel.dim_lengths" + "pm.MvNormal.dist(mu=0, cov=np.eye(2)).eval()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Vector Distributions" + "Like scalar distributions we can also use all our dimensionality tools as well to specify a set of Multivariate normals." + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[0.99574816, 2.01114084],\n", + " [3.00552369, 4.0058218 ]])" + ] + }, + "execution_count": 72, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pm.MvNormal.dist(mu=[[1,2], [3,4]], cov=np.eye(2)*.0001).eval()" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 76, "metadata": {}, "outputs": [ { @@ -244,6 +557,7 @@ "text": [ "[2]\n", "[3 2]\n", + "[3 2]\n", "[3 2]\n" ] }, @@ -256,11 +570,11 @@ "\n", "\n", - "\n", + "\n", "\n", "%3\n", - "\n", + "\n", "\n", "cluster2\n", "\n", @@ -276,6 +590,11 @@ "\n", "repeats (3) x None (2)\n", "\n", + "\n", + "clusteryear (3) x None (2)\n", + "\n", + "year (3) x None (2)\n", + "\n", "\n", "\n", "implied\n", @@ -300,20 +619,30 @@ "~\n", "MvNormal\n", "\n", + "\n", + "\n", + "with coords\n", + "\n", + "with coords\n", + "~\n", + "MvNormal\n", + "\n", "\n", "\n" ], "text/plain": [ - "" + "" ] }, - "execution_count": 6, + "execution_count": 76, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "with pm.Model() as pmodel:\n", + "with pm.Model(coords={\n", + " \"year\": [2020, 2021, 2022],\n", + "}) as pmodel:\n", " # Multivariate RVs (ndim_supp > 0)\n", " mv = pm.MvNormal(\"implied\", mu=[0, 0], cov=np.eye(2))\n", " assert mv.ndim == 1\n", @@ -321,1863 +650,36 @@ "\n", " mv = pm.MvNormal(\"with size\", mu=[0, 0], cov=np.eye(2), size=3, dims=(\"repeats\", \"implied\"))\n", " print(mv.shape.eval())\n", + " \n", " # ⚠ Size dims are always __prepended__\n", - "\n", " mv = pm.MvNormal(\"with shape\", mu=[0, 0], cov=np.eye(2), shape=(3, ...), dims=(\"repeats\", ...))\n", " print(mv.shape.eval())\n", + " \n", + " mv = pm.MvNormal(\"with coords\", mu=[0, 0], cov=np.eye(2), dims=(\"year\", ...))\n", + " print(mv.shape.eval())\n", + "\n", "\n", "\n", "pm.model_to_graphviz(pmodel)" ] }, { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([[ 0.65466774, 0.22397546],\n", - " [-0.27033677, -1.38344819],\n", - " [ 0.75297778, -0.64158639]])" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "pmodel[\"with shape\"].eval()" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'seconds': ('time',), 'obs': ('time',), 'y': ('time',)}" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "with pm.Model() as pmodel:\n", - " seconds = pm.ConstantData(\"seconds\", [1,2,3], dims=\"time\")\n", - " observations = pm.MutableData(\"obs\", [2,3,1,2], dims=\"time\")\n", - " a = pm.Normal(\"a\")\n", - " b = pm.Normal(\"b\")\n", - " y = pm.Deterministic(\n", - " \"y\",\n", - " a * seconds + b,\n", - " dims=\"time\"\n", - " )\n", - "pmodel.RV_dims" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "%3\n", - "\n", - "\n", - "clustertime (3)\n", - "\n", - "time (3)\n", - "\n", - "\n", - "\n", - "obs\n", - "\n", - "obs\n", - "~\n", - "MutableData\n", - "\n", - "\n", - "\n", - "seconds\n", - "\n", - "seconds\n", - "~\n", - "ConstantData\n", - "\n", - "\n", - "\n", - "y\n", - "\n", - "y\n", - "~\n", - "Deterministic\n", - "\n", - "\n", - "\n", - "seconds->y\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "b\n", - "\n", - "b\n", - "~\n", - "Normal\n", - "\n", - "\n", - "\n", - "b->y\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "a\n", - "\n", - "a\n", - "~\n", - "Normal\n", - "\n", - "\n", - "\n", - "a->y\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "pm.model_to_graphviz(pmodel)" - ] - }, - { - "cell_type": "code", - "execution_count": 10, + "cell_type": "markdown", "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Auto-assigning NUTS sampler...\n", - "Initializing NUTS using jitter+adapt_diag...\n", - "Multiprocess sampling (4 chains in 4 jobs)\n", - "NUTS: [a, b]\n" - ] - }, - { - "data": { - "text/html": [ - "\n", - "
\n", - " \n", - " \n", - " 100.00% [8000/8000 00:01<00:00 Sampling 4 chains, 0 divergences]\n", - "
\n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Sampling 4 chains for 1_000 tune and 1_000 draw iterations (4_000 + 4_000 draws total) took 1 seconds.\n" - ] - } - ], "source": [ - "with pmodel:\n", - " idata = pm.sample()" + "### User caution and practical tips." ] }, { - "cell_type": "code", - "execution_count": 11, + "cell_type": "markdown", "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "
\n", - "
\n", - "
arviz.InferenceData
\n", - "
\n", - "
    \n", - " \n", - "
  • \n", - " \n", - " \n", - "
    \n", - "
    \n", - "
      \n", - "
      \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
      <xarray.Dataset>\n",
      -       "Dimensions:  (chain: 4, draw: 1000, time: 3)\n",
      -       "Coordinates:\n",
      -       "  * chain    (chain) int64 0 1 2 3\n",
      -       "  * draw     (draw) int64 0 1 2 3 4 5 6 7 8 ... 992 993 994 995 996 997 998 999\n",
      -       "  * time     (time) int64 0 1 2\n",
      -       "Data variables:\n",
      -       "    a        (chain, draw) float64 -2.032 -0.1187 -0.1207 ... 0.8091 0.3232\n",
      -       "    b        (chain, draw) float64 -0.3398 1.038 -1.631 ... -1.068 1.132 -0.6527\n",
      -       "    y        (chain, draw, time) float64 -2.371 -4.403 ... -0.006344 0.3168\n",
      -       "Attributes:\n",
      -       "    created_at:                 2022-01-30T17:17:55.014275\n",
      -       "    arviz_version:              0.11.4\n",
      -       "    inference_library:          pymc\n",
      -       "    inference_library_version:  4.0.0b1\n",
      -       "    sampling_time:              1.3605358600616455\n",
      -       "    tuning_steps:               1000

      \n", - "
    \n", - "
    \n", - "
  • \n", - " \n", - "
  • \n", - " \n", - " \n", - "
    \n", - "
    \n", - "
      \n", - "
      \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
      <xarray.Dataset>\n",
      -       "Dimensions:             (chain: 4, draw: 1000)\n",
      -       "Coordinates:\n",
      -       "  * chain               (chain) int64 0 1 2 3\n",
      -       "  * draw                (draw) int64 0 1 2 3 4 5 6 ... 994 995 996 997 998 999\n",
      -       "Data variables: (12/13)\n",
      -       "    lp                  (chain, draw) float64 -3.959 -2.384 ... -2.806 -2.103\n",
      -       "    n_steps             (chain, draw) float64 1.0 3.0 3.0 3.0 ... 3.0 3.0 3.0\n",
      -       "    step_size           (chain, draw) float64 1.239 1.239 1.239 ... 1.211 1.211\n",
      -       "    tree_depth          (chain, draw) int64 1 2 2 2 2 2 2 2 ... 1 2 2 2 2 2 2 2\n",
      -       "    energy_error        (chain, draw) float64 -0.2226 -0.6445 ... 0.1284 -0.2516\n",
      -       "    perf_counter_start  (chain, draw) float64 8.296e+04 8.296e+04 ... 8.296e+04\n",
      -       "    ...                  ...\n",
      -       "    max_energy_error    (chain, draw) float64 -0.2226 -0.6445 ... -0.2631\n",
      -       "    step_size_bar       (chain, draw) float64 1.182 1.182 1.182 ... 1.121 1.121\n",
      -       "    process_time_diff   (chain, draw) float64 0.0002103 0.000378 ... 0.0003762\n",
      -       "    perf_counter_diff   (chain, draw) float64 0.0002102 0.000378 ... 0.000376\n",
      -       "    acceptance_rate     (chain, draw) float64 1.0 0.9548 ... 0.9662 0.9773\n",
      -       "    energy              (chain, draw) float64 5.165 4.163 3.903 ... 3.001 2.816\n",
      -       "Attributes:\n",
      -       "    created_at:                 2022-01-30T17:17:55.018630\n",
      -       "    arviz_version:              0.11.4\n",
      -       "    inference_library:          pymc\n",
      -       "    inference_library_version:  4.0.0b1\n",
      -       "    sampling_time:              1.3605358600616455\n",
      -       "    tuning_steps:               1000

      \n", - "
    \n", - "
    \n", - "
  • \n", - " \n", - "
  • \n", - " \n", - " \n", - "
    \n", - "
    \n", - "
      \n", - "
      \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
      <xarray.Dataset>\n",
      -       "Dimensions:  (time: 4)\n",
      -       "Coordinates:\n",
      -       "  * time     (time) int64 0 1 2 3\n",
      -       "Data variables:\n",
      -       "    seconds  (time) float64 1.0 2.0 3.0 nan\n",
      -       "    obs      (time) int32 2 3 1 2\n",
      -       "Attributes:\n",
      -       "    created_at:                 2022-01-30T17:17:55.021942\n",
      -       "    arviz_version:              0.11.4\n",
      -       "    inference_library:          pymc\n",
      -       "    inference_library_version:  4.0.0b1

      \n", - "
    \n", - "
    \n", - "
  • \n", - " \n", - "
\n", - "
\n", - " " - ], - "text/plain": [ - "Inference data with groups:\n", - "\t> posterior\n", - "\t> sample_stats\n", - "\t> constant_data" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], "source": [ - "idata" + "While we provide all these tools for convenience, and while PyMC does it best to understand user intent, the result of mixed dimensionality tools may not always result in the final dimensionality intended. Sometimes the model may not indicate an error until sampling, or not indicate an issue at all. When working with dimensionality, particular more complex ones we suggest\n", + "\n", + "* Using GraphViz to visualize your model before sampling\n", + "* Using the prior predictive to catch errors early\n", + "* Inspecting the returned `az.InferenceData` object to ensure all array sizes are as intended" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { From 8d1b61c62a49b9c437205776f19925d118af88dc Mon Sep 17 00:00:00 2001 From: Ravin Kumar Date: Mon, 31 Jan 2022 21:15:58 -0800 Subject: [PATCH 04/11] Rename notebook to dimensionality --- docs/source/learn/examples/{shapes.ipynb => dimensionality.ipynb} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/source/learn/examples/{shapes.ipynb => dimensionality.ipynb} (100%) diff --git a/docs/source/learn/examples/shapes.ipynb b/docs/source/learn/examples/dimensionality.ipynb similarity index 100% rename from docs/source/learn/examples/shapes.ipynb rename to docs/source/learn/examples/dimensionality.ipynb From 561d490be5f2048de5c0a74fc582dc891a108af2 Mon Sep 17 00:00:00 2001 From: Ravin Kumar Date: Tue, 1 Feb 2022 20:20:03 -0800 Subject: [PATCH 05/11] Address comments --- .../learn/examples/dimensionality.ipynb | 187 ++++++++++-------- 1 file changed, 108 insertions(+), 79 deletions(-) diff --git a/docs/source/learn/examples/dimensionality.ipynb b/docs/source/learn/examples/dimensionality.ipynb index 60c4448e55..1cccbfc6a5 100644 --- a/docs/source/learn/examples/dimensionality.ipynb +++ b/docs/source/learn/examples/dimensionality.ipynb @@ -20,17 +20,18 @@ "+ *`ndim_support`* → smallest shape that can result from a random draw. This is a fixed attribute in the distribution definition\n", "+ *Shape* → final resulting tensor shape\n", "+ *Size* → shape minus the support dimensions\n", - "+ *Dims* → A named array that can be used to specify dimensionality\n", + "+ *Dims* → An array of dimension names\n", + "+ *Coords* → A named array that can be used to specify dimensionality\n", + "\n", "\n", "## General Recommendations\n", "### When prototyping implied and size are convenient\n", "Implied dimensions are easy to specify and great for quickly expanding an existing RV. F\n", "\n", "### For reusable code we suggest dims\n", - "TODO(ravin): Make this nicer\n", - "For any more important work stick with dims because it'll label the InferenceData. Best practice transparency, For a three dimensional thing what these dimensions correspond to. Not going to know this unless dims\n", + "For any more important work, or reuable work we suggest dims and coords as the labels will be passed to {class}'arviz.InferenceData'. This is both best practice transparency and readability for others. It also is useful in single developer workflows, for example, in cases where there is a 3 dimensional or higher RV it'll help indiciate which dimension corresponds to which model concept.\n", "\n", - "### Use shape if you'd like to be strict\n", + "### Use shape if you'd like to be explicit\n", "Use shape if you'd like to bypass any dimensionality calculations implicit in PyMC. This will strictly specify the dimensionality to Aesara" ] }, @@ -61,7 +62,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -77,16 +78,16 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "(array(1.14185467), ())" + "(array(-1.11530499), ())" ] }, - "execution_count": 39, + "execution_count": 3, "metadata": {}, "output_type": "execute_result" } @@ -105,7 +106,7 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -114,7 +115,7 @@ "0" ] }, - "execution_count": 40, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -139,16 +140,16 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "(array([ 0.99996052, 9.99993143, 100.0000965 ]), (3,))" + "(array([ 1.00002897, 9.9999175 , 99.99994224]), (3,))" ] }, - "execution_count": 43, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -174,16 +175,16 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "(array([-1.31442847, 1.09896843, 0.42476213]), (3,))" + "(array([-0.56435014, 0.28613655, -0.92945242]), (3,))" ] }, - "execution_count": 45, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -195,16 +196,16 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "(array([-0.93941749, 0.1875374 , -0.56144478]), (3,))" + "(array([ 0.23463317, -0.24455629, -2.23058663]), (3,))" ] }, - "execution_count": 44, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } @@ -226,7 +227,7 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -294,10 +295,10 @@ "\n" ], "text/plain": [ - "" + "" ] }, - "execution_count": 47, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -322,7 +323,7 @@ }, { "cell_type": "code", - "execution_count": 59, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -383,10 +384,10 @@ "\n" ], "text/plain": [ - "" + "" ] }, - "execution_count": 59, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -406,53 +407,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Where dims can become increasingly powerful is with the use of `coords` specified in the model itself. With this it becomes easy to track. As an added bonus the coords and dims will also be present in the returned `azInferenceData` simplifying the entire workflow." + "Where dims can become increasingly powerful is with the use of `coords` specified in the model itself. With this it becomes easy to track. As an added bonus the coords and dims will also be present in the returned {class}'arviz.InferenceData' simplifying the entire workflow." ] }, { "cell_type": "code", - "execution_count": 61, + "execution_count": 10, "metadata": {}, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "%3\n", - "\n", - "\n", - "clusteryear (3)\n", - "\n", - "year (3)\n", - "\n", - "\n", - "\n", - "Normal_RV\n", - "\n", - "Normal_RV\n", - "~\n", - "Normal\n", - "\n", - "\n", - "\n" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 61, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "with pm.Model(coords={\n", " \"year\": [2020, 2021, 2022],\n", @@ -473,7 +435,7 @@ }, { "cell_type": "code", - "execution_count": 52, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -482,7 +444,7 @@ "1" ] }, - "execution_count": 52, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -500,16 +462,16 @@ }, { "cell_type": "code", - "execution_count": 66, + "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "array([0.22626491, 2.01962398, 0.89651223])" + "array([-0.62108096, 0.94452907])" ] }, - "execution_count": 67, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -527,17 +489,17 @@ }, { "cell_type": "code", - "execution_count": 72, + "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "array([[0.99574816, 2.01114084],\n", - " [3.00552369, 4.0058218 ]])" + "array([[0.99955303, 2.01326016],\n", + " [3.00629284, 3.99512915]])" ] }, - "execution_count": 72, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } @@ -548,7 +510,74 @@ }, { "cell_type": "code", - "execution_count": 76, + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "ERROR (aesara.graph.opt): Optimization failure due to: constant_folding\n", + "ERROR (aesara.graph.opt): node: Assert{msg=Could not broadcast dimensions}(TensorConstant{3}, TensorConstant{False})\n", + "ERROR (aesara.graph.opt): TRACEBACK:\n", + "ERROR (aesara.graph.opt): Traceback (most recent call last):\n", + " File \"/home/canyon/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/graph/opt.py\", line 1992, in process_node\n", + " replacements = lopt.transform(fgraph, node)\n", + " File \"/home/canyon/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/graph/opt.py\", line 1203, in transform\n", + " return self.fn(fgraph, node)\n", + " File \"/home/canyon/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/tensor/basic_opt.py\", line 2930, in constant_folding\n", + " required = thunk()\n", + " File \"/home/canyon/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/graph/op.py\", line 662, in rval\n", + " thunk()\n", + " File \"/home/canyon/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/link/c/basic.py\", line 1772, in __call__\n", + " raise exc_value.with_traceback(exc_trace)\n", + "AssertionError: Could not broadcast dimensions\n", + "\n" + ] + }, + { + "ename": "AssertionError", + "evalue": "Could not broadcast dimensions", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mAssertionError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/tmp/ipykernel_33002/460580557.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mpm\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mMvNormal\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmu\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\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[0;36m3\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m4\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcov\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0meye\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0;36m.0001\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0meval\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[0m", + "\u001b[0;32m~/repos/pymc/pymc/distributions/multivariate.py\u001b[0m in \u001b[0;36mdist\u001b[0;34m(cls, mu, cov, tau, chol, lower, **kwargs)\u001b[0m\n\u001b[1;32m 242\u001b[0m \u001b[0mcov\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mquaddist_matrix\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcov\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mchol\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtau\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlower\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 243\u001b[0m \u001b[0;31m# Aesara is stricter about the shape of mu, than PyMC used to be\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 244\u001b[0;31m \u001b[0mmu\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mat\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbroadcast_arrays\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmu\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcov\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m...\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\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[0m\n\u001b[0m\u001b[1;32m 245\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0msuper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mmu\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcov\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 246\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/tensor/extra_ops.py\u001b[0m in \u001b[0;36mbroadcast_arrays\u001b[0;34m(*args)\u001b[0m\n\u001b[1;32m 1640\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1641\u001b[0m \"\"\"\n\u001b[0;32m-> 1642\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mtuple\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbroadcast_to\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbroadcast_shape\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0ma\u001b[0m \u001b[0;32min\u001b[0m \u001b[0margs\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~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/tensor/extra_ops.py\u001b[0m in \u001b[0;36m\u001b[0;34m(.0)\u001b[0m\n\u001b[1;32m 1640\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1641\u001b[0m \"\"\"\n\u001b[0;32m-> 1642\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mtuple\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbroadcast_to\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbroadcast_shape\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0ma\u001b[0m \u001b[0;32min\u001b[0m \u001b[0margs\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~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/tensor/extra_ops.py\u001b[0m in \u001b[0;36m__call__\u001b[0;34m(self, a, shape, **kwargs)\u001b[0m\n\u001b[1;32m 1580\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1581\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__call__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mshape\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\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-> 1582\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0msuper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__call__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\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 1583\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1584\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mmake_node\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0mshape\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~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/graph/op.py\u001b[0m in \u001b[0;36m__call__\u001b[0;34m(self, *inputs, **kwargs)\u001b[0m\n\u001b[1;32m 281\u001b[0m \"\"\"\n\u001b[1;32m 282\u001b[0m \u001b[0mreturn_list\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mkwargs\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpop\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"return_list\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 283\u001b[0;31m \u001b[0mnode\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmake_node\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0minputs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\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 284\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 285\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mconfig\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcompute_test_value\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0;34m\"off\"\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/tensor/extra_ops.py\u001b[0m in \u001b[0;36mmake_node\u001b[0;34m(self, a, *shape)\u001b[0m\n\u001b[1;32m 1586\u001b[0m \u001b[0mshape\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0maet\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mas_tensor_variable\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mndim\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1587\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1588\u001b[0;31m \u001b[0mshape\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbcast\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0maet\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minfer_broadcastable\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mshape\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 1589\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1590\u001b[0m \u001b[0mout\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtype\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtype\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdtype\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtype\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdtype\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbroadcastable\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mbcast\u001b[0m\u001b[0;34m)\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~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/tensor/basic.py\u001b[0m in \u001b[0;36minfer_broadcastable\u001b[0;34m(shape)\u001b[0m\n\u001b[1;32m 1353\u001b[0m \u001b[0mclone\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1354\u001b[0m )\n\u001b[0;32m-> 1355\u001b[0;31m \u001b[0mfolded_shape\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0moptimize_graph\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mshape_fg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcustom_opt\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtopo_constant_folding\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0moutputs\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1356\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1357\u001b[0m \u001b[0mbcast\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtuple\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgetattr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"data\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ms\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m1\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0ms\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mfolded_shape\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/graph/opt_utils.py\u001b[0m in \u001b[0;36moptimize_graph\u001b[0;34m(fgraph, include, custom_opt, clone, **kwargs)\u001b[0m\n\u001b[1;32m 45\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 46\u001b[0m \u001b[0mcanonicalize_opt\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0moptdb\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mquery\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mOptimizationQuery\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minclude\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0minclude\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\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---> 47\u001b[0;31m \u001b[0m_\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcanonicalize_opt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0moptimize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfgraph\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 48\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 49\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mcustom_opt\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/graph/opt.py\u001b[0m in \u001b[0;36moptimize\u001b[0;34m(self, fgraph, *args, **kwargs)\u001b[0m\n\u001b[1;32m 100\u001b[0m \"\"\"\n\u001b[1;32m 101\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_requirements\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfgraph\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 102\u001b[0;31m \u001b[0mret\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mapply\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfgraph\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\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 103\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mret\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 104\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/graph/opt.py\u001b[0m in \u001b[0;36mapply\u001b[0;34m(self, fgraph)\u001b[0m\n\u001b[1;32m 277\u001b[0m \u001b[0mnb_nodes_before\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfgraph\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mapply_nodes\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 278\u001b[0m \u001b[0mt0\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtime\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtime\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--> 279\u001b[0;31m \u001b[0msub_prof\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0moptimizer\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0moptimize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfgraph\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 280\u001b[0m \u001b[0ml\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfloat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtime\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtime\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0mt0\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 281\u001b[0m \u001b[0msub_profs\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msub_prof\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/graph/opt.py\u001b[0m in \u001b[0;36moptimize\u001b[0;34m(self, fgraph, *args, **kwargs)\u001b[0m\n\u001b[1;32m 100\u001b[0m \"\"\"\n\u001b[1;32m 101\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_requirements\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfgraph\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 102\u001b[0;31m \u001b[0mret\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mapply\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfgraph\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\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 103\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mret\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 104\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/graph/opt.py\u001b[0m in \u001b[0;36mapply\u001b[0;34m(self, fgraph, start_from)\u001b[0m\n\u001b[1;32m 2497\u001b[0m \u001b[0mnb\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mchange_tracker\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnb_imported\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2498\u001b[0m \u001b[0mt_opt\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtime\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtime\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-> 2499\u001b[0;31m \u001b[0msub_prof\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mgopt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mapply\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfgraph\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 2500\u001b[0m \u001b[0mtime_opts\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mgopt\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0mtime\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtime\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0mt_opt\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2501\u001b[0m \u001b[0msub_profs\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msub_prof\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/graph/opt.py\u001b[0m in \u001b[0;36mapply\u001b[0;34m(self, fgraph, start_from)\u001b[0m\n\u001b[1;32m 2100\u001b[0m \u001b[0;32mcontinue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2101\u001b[0m \u001b[0mcurrent_node\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnode\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2102\u001b[0;31m \u001b[0mnb\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mprocess_node\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfgraph\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnode\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 2103\u001b[0m \u001b[0mloop_t\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtime\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtime\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0mt0\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2104\u001b[0m \u001b[0;32mfinally\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/graph/opt.py\u001b[0m in \u001b[0;36mprocess_node\u001b[0;34m(self, fgraph, node, lopt)\u001b[0m\n\u001b[1;32m 1993\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mException\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1994\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfailure_callback\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1995\u001b[0;31m self.failure_callback(\n\u001b[0m\u001b[1;32m 1996\u001b[0m \u001b[0me\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[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mx\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mnode\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0moutputs\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlopt\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnode\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1997\u001b[0m )\n", + "\u001b[0;32m~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/graph/opt.py\u001b[0m in \u001b[0;36mwarn_inplace\u001b[0;34m(exc, nav, repl_pairs, local_opt, node)\u001b[0m\n\u001b[1;32m 1896\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mexc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mInconsistencyError\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 1897\u001b[0m \u001b[0;32mreturn\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1898\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mNavigatorOptimizer\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwarn\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mexc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnav\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrepl_pairs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlocal_opt\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnode\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 1899\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1900\u001b[0m \u001b[0;34m@\u001b[0m\u001b[0mstaticmethod\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/graph/opt.py\u001b[0m in \u001b[0;36mwarn\u001b[0;34m(exc, nav, repl_pairs, local_opt, node)\u001b[0m\n\u001b[1;32m 1884\u001b[0m \u001b[0;31m# We always crash on AssertionError because something may be\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1885\u001b[0m \u001b[0;31m# seriously wrong if such an exception is raised.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1886\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mexc\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1887\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1888\u001b[0m \u001b[0;34m@\u001b[0m\u001b[0mstaticmethod\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/graph/opt.py\u001b[0m in \u001b[0;36mprocess_node\u001b[0;34m(self, fgraph, node, lopt)\u001b[0m\n\u001b[1;32m 1990\u001b[0m \u001b[0mlopt\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlopt\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlocal_opt\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1991\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1992\u001b[0;31m \u001b[0mreplacements\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlopt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtransform\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfgraph\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnode\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 1993\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mException\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1994\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfailure_callback\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/graph/opt.py\u001b[0m in \u001b[0;36mtransform\u001b[0;34m(self, fgraph, node)\u001b[0m\n\u001b[1;32m 1201\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1202\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1203\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfn\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfgraph\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnode\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 1204\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1205\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0madd_requirements\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfgraph\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~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/tensor/basic_opt.py\u001b[0m in \u001b[0;36mconstant_folding\u001b[0;34m(fgraph, node)\u001b[0m\n\u001b[1;32m 2928\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2929\u001b[0m \u001b[0mthunk\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnode\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mop\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmake_thunk\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnode\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstorage_map\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcompute_map\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mno_recycling\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m[\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-> 2930\u001b[0;31m \u001b[0mrequired\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mthunk\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[0m\u001b[1;32m 2931\u001b[0m \u001b[0;31m# A node whose inputs are all provided should always return successfully\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2932\u001b[0m \u001b[0;32massert\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mrequired\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/graph/op.py\u001b[0m in \u001b[0;36mrval\u001b[0;34m()\u001b[0m\n\u001b[1;32m 660\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 661\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mrval\u001b[0m\u001b[0;34m(\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--> 662\u001b[0;31m \u001b[0mthunk\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[0m\u001b[1;32m 663\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mo\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mnode\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0moutputs\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 664\u001b[0m \u001b[0mcompute_map\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mo\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/link/c/basic.py\u001b[0m in \u001b[0;36m__call__\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 1770\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0merror_storage\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfile\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0msys\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstderr\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1771\u001b[0m \u001b[0;32mraise\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1772\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mexc_value\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwith_traceback\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mexc_trace\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 1773\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1774\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__str__\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[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mAssertionError\u001b[0m: Could not broadcast dimensions" + ] + } + ], + "source": [ + "# Temporary addition to make feedback easier to get\n", + "# Not sure what is meant by this comment\n", + "# From Michael: In this example, using eye(3) would make it clear which output dimensions correspond to the support dim. \n", + "pm.MvNormal.dist(mu=[[1,2], [3,4]], cov=np.eye(3)*.0001).eval()" + ] + }, + { + "cell_type": "code", + "execution_count": 14, "metadata": {}, "outputs": [ { @@ -631,10 +660,10 @@ "\n" ], "text/plain": [ - "" + "" ] }, - "execution_count": 76, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } From b7a9f55f015798333934d56abcad7cac862f0cea Mon Sep 17 00:00:00 2001 From: Ravin Kumar Date: Tue, 1 Feb 2022 20:22:14 -0800 Subject: [PATCH 06/11] Add prime number advice --- docs/source/learn/examples/dimensionality.ipynb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/source/learn/examples/dimensionality.ipynb b/docs/source/learn/examples/dimensionality.ipynb index 1cccbfc6a5..bff0fcfca4 100644 --- a/docs/source/learn/examples/dimensionality.ipynb +++ b/docs/source/learn/examples/dimensionality.ipynb @@ -32,7 +32,11 @@ "For any more important work, or reuable work we suggest dims and coords as the labels will be passed to {class}'arviz.InferenceData'. This is both best practice transparency and readability for others. It also is useful in single developer workflows, for example, in cases where there is a 3 dimensional or higher RV it'll help indiciate which dimension corresponds to which model concept.\n", "\n", "### Use shape if you'd like to be explicit\n", - "Use shape if you'd like to bypass any dimensionality calculations implicit in PyMC. This will strictly specify the dimensionality to Aesara" + "Use shape if you'd like to bypass any dimensionality calculations implicit in PyMC. This will strictly specify the dimensionality to Aesara\n", + "\n", + "### When debugging use unique prime numbers\n", + "By using prime numbers it will be easier to determine where how input dimensionalities are being converted to output dimensionalities.\n", + "Once confident with result then change the dimensionalities to match your data or modeling needs." ] }, { From 6dec20e590bbc0969cc7837939af1cf5f50bd22d Mon Sep 17 00:00:00 2001 From: Ravin Kumar Date: Tue, 1 Feb 2022 20:23:03 -0800 Subject: [PATCH 07/11] Fix exmaples.md name --- docs/source/learn/examples.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/learn/examples.md b/docs/source/learn/examples.md index 1a255a3319..4512fe9e8c 100644 --- a/docs/source/learn/examples.md +++ b/docs/source/learn/examples.md @@ -37,5 +37,5 @@ examples/pymc_overview examples/GLM_linear examples/model_comparison examples/posterior_predictive -examples/shapes +examples/dimensionality ::: From ba9f9fba31f60ed28a14230f318d920280594314 Mon Sep 17 00:00:00 2001 From: Ravin Kumar Date: Tue, 1 Feb 2022 20:27:10 -0800 Subject: [PATCH 08/11] Update api.rst --- docs/source/api.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/source/api.rst b/docs/source/api.rst index 4bf6644df6..7568a9a2f1 100644 --- a/docs/source/api.rst +++ b/docs/source/api.rst @@ -24,14 +24,14 @@ API Reference api/misc ------------------ -shapes, size, dims +Dimensionality ------------------ -some placeholder text -The {ref}`GLM_linear` notebook provides is -The {ref}`shapes` notebook provides is +PyMC provides numerous methods, and syntatic sugar, to easily specify the dimensionality of +Random Variables in modeling. Refer to {ref}`dimensionality` notebook to see examples +demonstrating the functionality. -------------- -api extensions +API extensions -------------- Plots, stats and diagnostics From cc0cd22645b089bc59db18148e17ed6694273cfd Mon Sep 17 00:00:00 2001 From: Ravin Kumar Date: Thu, 3 Feb 2022 19:18:16 -0800 Subject: [PATCH 09/11] Update to mu=[0,0] per comment --- docs/source/learn/examples/dimensionality.ipynb | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/source/learn/examples/dimensionality.ipynb b/docs/source/learn/examples/dimensionality.ipynb index bff0fcfca4..caa57fb408 100644 --- a/docs/source/learn/examples/dimensionality.ipynb +++ b/docs/source/learn/examples/dimensionality.ipynb @@ -466,22 +466,22 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "array([-0.62108096, 0.94452907])" + "array([-0.90716283, 1.07225702])" ] }, - "execution_count": 12, + "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "pm.MvNormal.dist(mu=0, cov=np.eye(2)).eval()" + "pm.MvNormal.dist(mu=[0,0], cov=np.eye(2)).eval()" ] }, { @@ -493,17 +493,17 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "array([[0.99955303, 2.01326016],\n", - " [3.00629284, 3.99512915]])" + "array([[0.98079328, 2.00918604],\n", + " [3.00853795, 4.01186033]])" ] }, - "execution_count": 18, + "execution_count": 21, "metadata": {}, "output_type": "execute_result" } From c6273956418a7cf4a78b6d4bb03c4e0abcf528e3 Mon Sep 17 00:00:00 2001 From: Ravin Kumar Date: Sat, 5 Feb 2022 14:21:35 -0800 Subject: [PATCH 10/11] Update shapes notebook --- .../learn/examples/dimensionality.ipynb | 120 +++--------------- 1 file changed, 16 insertions(+), 104 deletions(-) diff --git a/docs/source/learn/examples/dimensionality.ipynb b/docs/source/learn/examples/dimensionality.ipynb index caa57fb408..5acd09944b 100644 --- a/docs/source/learn/examples/dimensionality.ipynb +++ b/docs/source/learn/examples/dimensionality.ipynb @@ -466,129 +466,42 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "array([-0.90716283, 1.07225702])" + "array([[1.00273693, 1.99583834, 2.99674157],\n", + " [4.01036637, 5.00775714, 5.97952974]])" ] }, - "execution_count": 20, + "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "pm.MvNormal.dist(mu=[0,0], cov=np.eye(2)).eval()" + "pm.MvNormal.dist(mu=[[1,2,3], [4,5,6]], cov=np.eye(3)*.0001).eval()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Like scalar distributions we can also use all our dimensionality tools as well to specify a set of Multivariate normals." + "Like scalar distributions we can also use all our dimensionality tools as well to specify a set of Multivariate normals" ] }, { "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([[0.98079328, 2.00918604],\n", - " [3.00853795, 4.01186033]])" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "pm.MvNormal.dist(mu=[[1,2], [3,4]], cov=np.eye(2)*.0001).eval()" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "ERROR (aesara.graph.opt): Optimization failure due to: constant_folding\n", - "ERROR (aesara.graph.opt): node: Assert{msg=Could not broadcast dimensions}(TensorConstant{3}, TensorConstant{False})\n", - "ERROR (aesara.graph.opt): TRACEBACK:\n", - "ERROR (aesara.graph.opt): Traceback (most recent call last):\n", - " File \"/home/canyon/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/graph/opt.py\", line 1992, in process_node\n", - " replacements = lopt.transform(fgraph, node)\n", - " File \"/home/canyon/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/graph/opt.py\", line 1203, in transform\n", - " return self.fn(fgraph, node)\n", - " File \"/home/canyon/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/tensor/basic_opt.py\", line 2930, in constant_folding\n", - " required = thunk()\n", - " File \"/home/canyon/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/graph/op.py\", line 662, in rval\n", - " thunk()\n", - " File \"/home/canyon/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/link/c/basic.py\", line 1772, in __call__\n", - " raise exc_value.with_traceback(exc_trace)\n", - "AssertionError: Could not broadcast dimensions\n", - "\n" - ] - }, - { - "ename": "AssertionError", - "evalue": "Could not broadcast dimensions", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mAssertionError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m/tmp/ipykernel_33002/460580557.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mpm\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mMvNormal\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmu\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\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[0;36m3\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m4\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcov\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0meye\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0;36m.0001\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0meval\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[0m", - "\u001b[0;32m~/repos/pymc/pymc/distributions/multivariate.py\u001b[0m in \u001b[0;36mdist\u001b[0;34m(cls, mu, cov, tau, chol, lower, **kwargs)\u001b[0m\n\u001b[1;32m 242\u001b[0m \u001b[0mcov\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mquaddist_matrix\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcov\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mchol\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtau\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlower\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 243\u001b[0m \u001b[0;31m# Aesara is stricter about the shape of mu, than PyMC used to be\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 244\u001b[0;31m \u001b[0mmu\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mat\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbroadcast_arrays\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmu\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcov\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m...\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\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[0m\n\u001b[0m\u001b[1;32m 245\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0msuper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mmu\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcov\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 246\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/tensor/extra_ops.py\u001b[0m in \u001b[0;36mbroadcast_arrays\u001b[0;34m(*args)\u001b[0m\n\u001b[1;32m 1640\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1641\u001b[0m \"\"\"\n\u001b[0;32m-> 1642\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mtuple\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbroadcast_to\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbroadcast_shape\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0ma\u001b[0m \u001b[0;32min\u001b[0m \u001b[0margs\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~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/tensor/extra_ops.py\u001b[0m in \u001b[0;36m\u001b[0;34m(.0)\u001b[0m\n\u001b[1;32m 1640\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1641\u001b[0m \"\"\"\n\u001b[0;32m-> 1642\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mtuple\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbroadcast_to\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbroadcast_shape\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0ma\u001b[0m \u001b[0;32min\u001b[0m \u001b[0margs\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~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/tensor/extra_ops.py\u001b[0m in \u001b[0;36m__call__\u001b[0;34m(self, a, shape, **kwargs)\u001b[0m\n\u001b[1;32m 1580\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1581\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__call__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mshape\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\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-> 1582\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0msuper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__call__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\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 1583\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1584\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mmake_node\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0mshape\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~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/graph/op.py\u001b[0m in \u001b[0;36m__call__\u001b[0;34m(self, *inputs, **kwargs)\u001b[0m\n\u001b[1;32m 281\u001b[0m \"\"\"\n\u001b[1;32m 282\u001b[0m \u001b[0mreturn_list\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mkwargs\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpop\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"return_list\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 283\u001b[0;31m \u001b[0mnode\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmake_node\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0minputs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\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 284\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 285\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mconfig\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcompute_test_value\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0;34m\"off\"\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/tensor/extra_ops.py\u001b[0m in \u001b[0;36mmake_node\u001b[0;34m(self, a, *shape)\u001b[0m\n\u001b[1;32m 1586\u001b[0m \u001b[0mshape\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0maet\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mas_tensor_variable\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mndim\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1587\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1588\u001b[0;31m \u001b[0mshape\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbcast\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0maet\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minfer_broadcastable\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mshape\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 1589\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1590\u001b[0m \u001b[0mout\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtype\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtype\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdtype\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtype\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdtype\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbroadcastable\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mbcast\u001b[0m\u001b[0;34m)\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~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/tensor/basic.py\u001b[0m in \u001b[0;36minfer_broadcastable\u001b[0;34m(shape)\u001b[0m\n\u001b[1;32m 1353\u001b[0m \u001b[0mclone\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1354\u001b[0m )\n\u001b[0;32m-> 1355\u001b[0;31m \u001b[0mfolded_shape\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0moptimize_graph\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mshape_fg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcustom_opt\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtopo_constant_folding\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0moutputs\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1356\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1357\u001b[0m \u001b[0mbcast\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtuple\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgetattr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"data\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ms\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m1\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0ms\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mfolded_shape\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/graph/opt_utils.py\u001b[0m in \u001b[0;36moptimize_graph\u001b[0;34m(fgraph, include, custom_opt, clone, **kwargs)\u001b[0m\n\u001b[1;32m 45\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 46\u001b[0m \u001b[0mcanonicalize_opt\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0moptdb\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mquery\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mOptimizationQuery\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minclude\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0minclude\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\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---> 47\u001b[0;31m \u001b[0m_\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcanonicalize_opt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0moptimize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfgraph\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 48\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 49\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mcustom_opt\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/graph/opt.py\u001b[0m in \u001b[0;36moptimize\u001b[0;34m(self, fgraph, *args, **kwargs)\u001b[0m\n\u001b[1;32m 100\u001b[0m \"\"\"\n\u001b[1;32m 101\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_requirements\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfgraph\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 102\u001b[0;31m \u001b[0mret\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mapply\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfgraph\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\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 103\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mret\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 104\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/graph/opt.py\u001b[0m in \u001b[0;36mapply\u001b[0;34m(self, fgraph)\u001b[0m\n\u001b[1;32m 277\u001b[0m \u001b[0mnb_nodes_before\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfgraph\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mapply_nodes\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 278\u001b[0m \u001b[0mt0\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtime\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtime\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--> 279\u001b[0;31m \u001b[0msub_prof\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0moptimizer\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0moptimize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfgraph\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 280\u001b[0m \u001b[0ml\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfloat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtime\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtime\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0mt0\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 281\u001b[0m \u001b[0msub_profs\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msub_prof\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/graph/opt.py\u001b[0m in \u001b[0;36moptimize\u001b[0;34m(self, fgraph, *args, **kwargs)\u001b[0m\n\u001b[1;32m 100\u001b[0m \"\"\"\n\u001b[1;32m 101\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_requirements\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfgraph\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 102\u001b[0;31m \u001b[0mret\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mapply\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfgraph\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\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 103\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mret\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 104\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/graph/opt.py\u001b[0m in \u001b[0;36mapply\u001b[0;34m(self, fgraph, start_from)\u001b[0m\n\u001b[1;32m 2497\u001b[0m \u001b[0mnb\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mchange_tracker\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnb_imported\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2498\u001b[0m \u001b[0mt_opt\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtime\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtime\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-> 2499\u001b[0;31m \u001b[0msub_prof\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mgopt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mapply\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfgraph\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 2500\u001b[0m \u001b[0mtime_opts\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mgopt\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0mtime\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtime\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0mt_opt\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2501\u001b[0m \u001b[0msub_profs\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msub_prof\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/graph/opt.py\u001b[0m in \u001b[0;36mapply\u001b[0;34m(self, fgraph, start_from)\u001b[0m\n\u001b[1;32m 2100\u001b[0m \u001b[0;32mcontinue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2101\u001b[0m \u001b[0mcurrent_node\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnode\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2102\u001b[0;31m \u001b[0mnb\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mprocess_node\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfgraph\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnode\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 2103\u001b[0m \u001b[0mloop_t\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtime\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtime\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0mt0\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2104\u001b[0m \u001b[0;32mfinally\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/graph/opt.py\u001b[0m in \u001b[0;36mprocess_node\u001b[0;34m(self, fgraph, node, lopt)\u001b[0m\n\u001b[1;32m 1993\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mException\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1994\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfailure_callback\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1995\u001b[0;31m self.failure_callback(\n\u001b[0m\u001b[1;32m 1996\u001b[0m \u001b[0me\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[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mx\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mnode\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0moutputs\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlopt\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnode\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1997\u001b[0m )\n", - "\u001b[0;32m~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/graph/opt.py\u001b[0m in \u001b[0;36mwarn_inplace\u001b[0;34m(exc, nav, repl_pairs, local_opt, node)\u001b[0m\n\u001b[1;32m 1896\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mexc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mInconsistencyError\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 1897\u001b[0m \u001b[0;32mreturn\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1898\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mNavigatorOptimizer\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwarn\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mexc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnav\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrepl_pairs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlocal_opt\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnode\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 1899\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1900\u001b[0m \u001b[0;34m@\u001b[0m\u001b[0mstaticmethod\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/graph/opt.py\u001b[0m in \u001b[0;36mwarn\u001b[0;34m(exc, nav, repl_pairs, local_opt, node)\u001b[0m\n\u001b[1;32m 1884\u001b[0m \u001b[0;31m# We always crash on AssertionError because something may be\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1885\u001b[0m \u001b[0;31m# seriously wrong if such an exception is raised.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1886\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mexc\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1887\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1888\u001b[0m \u001b[0;34m@\u001b[0m\u001b[0mstaticmethod\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/graph/opt.py\u001b[0m in \u001b[0;36mprocess_node\u001b[0;34m(self, fgraph, node, lopt)\u001b[0m\n\u001b[1;32m 1990\u001b[0m \u001b[0mlopt\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlopt\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlocal_opt\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1991\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1992\u001b[0;31m \u001b[0mreplacements\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlopt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtransform\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfgraph\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnode\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 1993\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mException\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1994\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfailure_callback\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/graph/opt.py\u001b[0m in \u001b[0;36mtransform\u001b[0;34m(self, fgraph, node)\u001b[0m\n\u001b[1;32m 1201\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1202\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1203\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfn\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfgraph\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnode\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 1204\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1205\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0madd_requirements\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfgraph\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~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/tensor/basic_opt.py\u001b[0m in \u001b[0;36mconstant_folding\u001b[0;34m(fgraph, node)\u001b[0m\n\u001b[1;32m 2928\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2929\u001b[0m \u001b[0mthunk\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnode\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mop\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmake_thunk\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnode\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstorage_map\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcompute_map\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mno_recycling\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m[\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-> 2930\u001b[0;31m \u001b[0mrequired\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mthunk\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[0m\u001b[1;32m 2931\u001b[0m \u001b[0;31m# A node whose inputs are all provided should always return successfully\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2932\u001b[0m \u001b[0;32massert\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mrequired\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/graph/op.py\u001b[0m in \u001b[0;36mrval\u001b[0;34m()\u001b[0m\n\u001b[1;32m 660\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 661\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mrval\u001b[0m\u001b[0;34m(\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--> 662\u001b[0;31m \u001b[0mthunk\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[0m\u001b[1;32m 663\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mo\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mnode\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0moutputs\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 664\u001b[0m \u001b[0mcompute_map\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mo\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/miniconda3/envs/pymc/lib/python3.9/site-packages/aesara/link/c/basic.py\u001b[0m in \u001b[0;36m__call__\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 1770\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0merror_storage\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfile\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0msys\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstderr\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1771\u001b[0m \u001b[0;32mraise\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1772\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mexc_value\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwith_traceback\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mexc_trace\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 1773\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1774\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__str__\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[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mAssertionError\u001b[0m: Could not broadcast dimensions" - ] - } - ], - "source": [ - "# Temporary addition to make feedback easier to get\n", - "# Not sure what is meant by this comment\n", - "# From Michael: In this example, using eye(3) would make it clear which output dimensions correspond to the support dim. \n", - "pm.MvNormal.dist(mu=[[1,2], [3,4]], cov=np.eye(3)*.0001).eval()" - ] - }, - { - "cell_type": "code", - "execution_count": 14, + "execution_count": 33, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "[2]\n", + "[3]\n", "[3 2]\n", "[3 2]\n", "[3 2]\n" @@ -609,9 +522,9 @@ "%3\n", "\n", "\n", - "cluster2\n", + "cluster3\n", "\n", - "2\n", + "3\n", "\n", "\n", "clusterrepeats (3) x implied (2)\n", @@ -664,10 +577,10 @@ "\n" ], "text/plain": [ - "" + "" ] }, - "execution_count": 14, + "execution_count": 33, "metadata": {}, "output_type": "execute_result" } @@ -676,10 +589,11 @@ "with pm.Model(coords={\n", " \"year\": [2020, 2021, 2022],\n", "}) as pmodel:\n", + " mv = pm.MvNormal(\"implied\", mu=[0, 0, 0], cov=np.eye(3))\n", + " print(mv.shape.eval())\n", + "\n", " # Multivariate RVs (ndim_supp > 0)\n", - " mv = pm.MvNormal(\"implied\", mu=[0, 0], cov=np.eye(2))\n", " assert mv.ndim == 1\n", - " print(mv.shape.eval())\n", "\n", " mv = pm.MvNormal(\"with size\", mu=[0, 0], cov=np.eye(2), size=3, dims=(\"repeats\", \"implied\"))\n", " print(mv.shape.eval())\n", @@ -691,8 +605,6 @@ " mv = pm.MvNormal(\"with coords\", mu=[0, 0], cov=np.eye(2), dims=(\"year\", ...))\n", " print(mv.shape.eval())\n", "\n", - "\n", - "\n", "pm.model_to_graphviz(pmodel)" ] }, @@ -700,7 +612,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### User caution and practical tips." + "### User caution and practical tips" ] }, { From e4e80b768b9d1eba603e269b4f11841e1f0b1b6a Mon Sep 17 00:00:00 2001 From: Ravin Kumar Date: Sun, 13 Feb 2022 08:02:01 -0800 Subject: [PATCH 11/11] Update docs/source/learn/examples/dimensionality.ipynb Co-authored-by: Michael Osthege --- docs/source/learn/examples/dimensionality.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/learn/examples/dimensionality.ipynb b/docs/source/learn/examples/dimensionality.ipynb index 5acd09944b..363d8e8a9b 100644 --- a/docs/source/learn/examples/dimensionality.ipynb +++ b/docs/source/learn/examples/dimensionality.ipynb @@ -21,7 +21,7 @@ "+ *Shape* → final resulting tensor shape\n", "+ *Size* → shape minus the support dimensions\n", "+ *Dims* → An array of dimension names\n", - "+ *Coords* → A named array that can be used to specify dimensionality\n", + "+ *Coords* → A dictionary mapping dimension names to coordinate values\n", "\n", "\n", "## General Recommendations\n",