{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "feb7MpFF4hKl",
    "pycharm": {}
   },
   "outputs": [],
   "source": [
    "import wot"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "JvT_bLlR4hKq",
    "pycharm": {}
   },
   "source": [
    "# Notebook 3: Computing long-range couplings\n",
    "\n",
    "In Notebook 2 we saw how to compute transport matrices $\\pi_{t_i,t_{i+1}}$ connecting adjacent time-points $(t_i,t_{i+1})$. Over short time-scales, this OT matrix is a good approximation to the true temporal coupling:\n",
    "\n",
    "$$ \\pi_{t_i,t_{i+1}} \\approx \\gamma_{t_i,t_{i+1}}. $$\n",
    "\n",
    "In this notebook we show how to infer transitions over a longer time interval $(t_i,t_j)$.\n",
    "To do this, we assume the developmental stochastic process ${\\mathbb{P}}_t$ is Markov. This means that the couplings $\\gamma_{s,t}$ satisfy the following algebraic relationship:\n",
    "\n",
    "$$ \\gamma_{t_1,t_3}(x,z) = \\iint \\gamma_{t_1,t_2}(x,y) \\gamma_{t_2,t_3}(y,z) dy$$\n",
    "\n",
    "for any $t_1 < t_2 < t_3$. The integral on the right hand side becomes a finite sum when we have a finite sample of cells. In fact, it's a matrix multiplication! \n",
    "\n",
    "Therefore we can infer long-range transitions by composing transport maps as follows:\n",
    "\n",
    "$$\\gamma_{t_i,t_j} = \\gamma_{t_i,t_{i+1}} \\circ \\gamma_{t_{i+1},t_{i+2}} \\circ \\cdots \\circ \\gamma_{t_{j-1},t_{j}} \n",
    "\\approx \\pi_{t_i,t_{i+1}} \\circ \\pi_{t_{i+1},t_{i+2}} \\circ \\cdots \\circ \\pi_{t_{j-1},t_{j}}.$$\n",
    "\n",
    "Here $\\circ$ denotes matrix multiplication. This is of course different than directly computing OT over longer time-intervals:\n",
    "\n",
    "$$ \\pi_{t_1,t_2} \\circ \\pi_{t_2,t_3} \\ne \\pi_{t_1,t_3}.$$\n",
    "\n",
    "In the following code block we construct a TransportMapModel from a directory of pre-computed transport matrices. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 34
    },
    "colab_type": "code",
    "id": "5lFF4FfhAexV",
    "outputId": "e5befe29-2896-45a2-ddc2-f37458648d5c",
    "pycharm": {}
   },
   "outputs": [],
   "source": [
    "tmap_model = wot.tmap.TransportMapModel.from_directory('tmaps/serum')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Composing couplings\n",
    "\n",
    "We can now easily compute the coupling between any pair of time-points as follows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AnnData object with n_obs × n_vars = 3815 × 2051 \n",
       "    obs: 'g0', 'g1', 'g2', 'g3'"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gamma_8_10 = tmap_model.get_coupling(8, 10)\n",
    "gamma_8_10"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The resulting temporal coupling $\\gamma_{t_i,t_j}$ has a row for each cell at time $t_i$ and a column for each cell at time $t_j$. \n",
    "Just like for a short-range coupling, the units are \"transported mass\". So a value of $\\gamma_{t_i,t_j}(x,y) = 0.2$ means that cell $x$ will have on average $0.2$ descendants with expression profile similar to $y$ at time $t_j$.\n",
    "Note that the sum of a row shows the total number of descendants that a cell will have at time $t_j$."
   ]
  }
 ],
 "metadata": {
  "colab": {
   "name": "wot-3.ipynb",
   "provenance": [],
   "version": "0.3.2"
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  },
  "pycharm": {
   "stem_cell": {
    "cell_type": "raw",
    "source": [],
    "metadata": {
     "collapsed": false
    }
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}