{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# General chain complexes in topaz \n",
    "\n",
    "Apart from being capable of computing integer homology of simplicial complexes (see this [tutorial](apps_topaz.ipynb) for an introduction), `polymake` is able to handle general chain complexes and compute homology for coefficients from different domains. When experimenting in the interactive shell, switch to the topology application first:\n",
    "\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "application 'topaz';"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "### Constructing a ChainComplex\n",
    "\n",
    "You can construct a chain complex via its differential matrices. For example purposes, we use the sparse boundary matrices of a triangulation of the real projective plane. You can then construct a general chain complex from it like this:\n",
    "\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "$bd1 = real_projective_plane()->boundary_matrix(1);\n",
    "$bd2 = real_projective_plane()->boundary_matrix(2);\n",
    "$a = new Array<SparseMatrix<Integer>>($bd1,$bd2);   # omit the trivial zeroth differential\n",
    "$cc = new ChainComplex<SparseMatrix<Integer>>($a,1);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "The template parameter of `ChainComplex` denotes the type of the boundary matrices. It defaults to `SparseMatrix<Integer>`, as this allows computation of integer homology. The second parameter of the chain complex constructor defaults to 0, indicating whether to perform a sanity check on the matrices (i.e. whether matrix dimensions match and successive maps compose to the zero map).\n",
    "\n",
    "You can access the data stored in the object like this:\n",
    "\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(15) (0 1) (1 -1) (2 1)\n",
       "(15) (0 1) (3 -1) (4 1)\n",
       "(15) (5 1) (6 -1) (7 1)\n",
       "(15) (1 -1) (5 1) (8 1)\n",
       "(15) (3 -1) (6 1) (9 1)\n",
       "(15) (7 1) (10 1) (11 -1)\n",
       "(15) (4 -1) (10 1) (12 1)\n",
       "(15) (2 -1) (11 1) (13 1)\n",
       "(15) (8 1) (12 -1) (14 1)\n",
       "(15) (9 -1) (13 1) (14 1)\n"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print $cc->boundary_matrix(2);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "### Computing integer homology\n",
    "\n",
    "There is a user function to compute integer homology of your complex. You can access the documentation by typing the name of the function in the interactive shell and then pressing F1.\n",
    "\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "({} 1)\n",
       "({(2 1)} 0)\n",
       "({} 0)\n"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print homology($cc,0);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The output rows correspond to the dimensions of your homology modules, containing the torsion coefficients in curly brackets, and the betti number. Note that this is non-reduced homology, unlike what gets computed when using the `HOMOLOGY` property of a simplicial complex.\n",
    "\n",
    "There is an extra function for computing the generators of the homology modules as well.\n",
    "\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(({} 1)\n",
       "<(6) (0 1)\n",
       ">\n",
       ")\n",
       "(({(2 1)} 0)\n",
       "<(15) (10 1) (11 -1) (12 1) (13 -1) (14 -1)\n",
       ">\n",
       ")\n",
       "(({} 0)\n",
       "<>\n",
       ")\n"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print homology_and_cycles($cc,0);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The output pairs the homology module representation with a representation of the cycles generating the respective modules, where the indices correspond to the indices in your input matrices.\n",
    "\n",
    "### Computing Betti numbers\n",
    "\n",
    "If your complex' differentials do not have `Integer` coefficients, computing integer homology is not possible. You can still (and very efficiently!) compute the Betti numbers by using the corresponding user function:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1 0 0"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print betti_numbers($cc);"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "polymake",
   "language": "polymake",
   "name": "polymake"
  },
  "language_info": {
   "codemirror_mode": "perl",
   "file_extension": ".pl",
   "mimetype": "text/x-polymake",
   "name": "polymake"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
