{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Short Introduction to application `matroid`\n",
    "\n",
    "**This tutorial is also available as a {{ :tutorial:apps_matroid.ipynb |jupyter notebook}} for polymake 3.1.**\n",
    "\n",
    "This tutorial is meant to show the main features for handling matroids available. To make `matroid` your current application start `polymake` with the option `-A matroid` or use the context switch\n",
    "\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "application \"matroid\";"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "from within the `polymake` shell.  A permanent setting can be stored with `%%set_custom $default_application=\"matroid\";%%`\n",
    "\n",
    "## Constructing a Simple Matroid and Playing Around\n",
    "\n",
    "This is how to produce a matroid from a vector configuration.  The matroid is defined by the linear dependence among subsets of these vectors.\n",
    "\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "$M=new Matroid(VECTORS=>[[1,0,0],[1,0,1],[1,1,0],[1,0,2]]);"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "If `matroid` is not your default application you have to qualify `Matroid` as in:\n",
    "\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "$M=new matroid::Matroid(VECTORS=>[[1,0,0],[1,0,1],[1,1,0],[1,0,2]]);"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "Output of basic statistics.\n",
    "\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3 4 3\n",
       "\n"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print $M->N_BASES, \" \", $M->N_ELEMENTS, \" \", $M->RANK;"
   ]
  },
  {
   "attachments": {
    "matroid_lattice_of_flats_example.png": {
     "image/png": [
      "[encoded data, 32580 characters]"
     ]
    }
   },
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![{{ :tutorial:matroid_lattice_of_flats_example.png?nolink&200|}}](attachment:matroid_lattice_of_flats_example.png)\n",
    "The `VECTORS` are numbered consecutively, starting from zero.  The bases are encoded as sets of these ordinal numbers.\n",
    "\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{0 1 2}\n",
       "{0 2 3}\n",
       "{1 2 3}\n",
       "\n"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print $M->BASES;"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "Similarly you can compute the circuits and cocircuits.\n",
    "\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{0 1 3}\n",
       "    \n"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print $M->CIRCUITS;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{2}\n",
       "{0 1}\n",
       "{0 3}\n",
       "{1 3}\n",
       "\n"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print $M->COCIRCUITS;"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "You can also compute other properties, like \n",
    "\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1 1 0 0\n",
       "    \n"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print $M->PAVING?\"1\":\"0\", \" \",\n",
    "$M->BINARY?\"1\":\"0\", \" \",\n",
    "$M->SERIES_PARALLEL?\"1\":\"0\", \" \",\n",
    "$M->CONNECTED?\"1\":\"0\";"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{0 1 3}\n",
       "{2}\n",
       "    \n"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print $M->CONNECTED_COMPONENTS;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "x*y + y^3 + y^2\n",
       "\n"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print $M->TUTTE_POLYNOMIAL;"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "Even the lattice of flats could be computed and visualised.\n",
    "\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{0 2} {0 1 3} {1 2} {2 3}\n",
       " \n"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "$lattice=$M->LATTICE_OF_FLATS;\n",
    "foreach (@{$lattice->nodes_of_rank(2)}){print $lattice->FACES->[$_],\" \"};"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{0 1 3}\n",
       "{0 2}\n",
       "{1 2}\n",
       "{2 3}\n",
       "    \n"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print $M->MATROID_HYPERPLANES;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "$M->LATTICE_OF_FLATS->VISUAL;"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "## Matroid Polytopes\n",
    "\n",
    "You can construct a polytope from the bases of a matroid as the convex hull of the characteristic vectors of the bases.  This is the *matroid polytope* of that matroid, sometimes also called the *matroid bases polytope*.  The matroid polytope of the matroid `$M` is a subobject `POLYTOPE` of type `polytope::Polytope<Rational>.\n",
    "\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1 1 1 1 0\n",
       "1 1 0 1 1\n",
       "1 0 1 1 1\n",
       "    \n"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print $M->POLYTOPE->VERTICES;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3 3\n",
       "\n"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print $M->POLYTOPE->F_VECTOR;"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "## Other Constructions\n",
    "\n",
    "The vertices of a polytope give rise to a matroid.  Here is an example for the vertices of the three-dimensional regular cube.  Notice that point coordinates in the application 'polytope' are given by homogeneous coordinates.  Hence this matroid is defined by the relation of affine dependence.\n",
    "\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "$C=new Matroid(VECTORS=>polytope::cube(3)->VERTICES);"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "58\n",
       "\n"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print $C->N_BASES;"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "The system also allows you to construct a matroid from a graph.  The bases correspond to the spanning trees then.  Notice that there is more than one way to encode a graph in `polymake`.  Read the [tutorial on graphs](apps_graph) for details.\n",
    "\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "$G=matroid_from_graph(polytope::cube(3)->GRAPH);"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "792\n",
       "\n"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print $G->N_BASES;"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "It is also possible to derive a new matroid from others. \n",
    "\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# The arguments are two matroids and for each matroid a basepoint. The basepoints will be identified. \n",
    "$se=series_extension(uniform_matroid(2,3),0,uniform_matroid(1,3),0);"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1 0 0\n",
       "0 1 0\n",
       "0 0 1\n",
       "1 1 1\n",
       "    \n"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print deletion($se,4)->VECTORS;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "$pe=parallel_extension(uniform_matroid(1,3),0,uniform_matroid(2,3),0);"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1 0 0\n",
       "0 1 0\n",
       "0 0 1\n",
       "1 1 1\n",
       "    \n"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print dual(contraction($pe,4))->VECTORS;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "234\n",
       "    \n"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print projective_plane(3)->N_BASES;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "28\n",
       "    \n"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print fano_matroid()->N_BASES;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "6552 = 234*28\n",
       "    \n"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print direct_sum(projective_plane(3),fano_matroid())->N_BASES,\" = 234*28\";"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{0 1 2}\n",
       "{3 4 5}\n",
       "{0 1 3 4}\n",
       "{0 1 3 5}\n",
       "{0 1 4 5}\n",
       "{0 2 3 4}\n",
       "{0 2 3 5}\n",
       "{0 2 4 5}\n",
       "{1 2 3 4}\n",
       "{1 2 3 5}\n",
       "{1 2 4 5}\n",
       "\n"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print two_sum(uniform_matroid(2,4),0,uniform_matroid(2,4),0)->CIRCUITS;"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "Of course you can also construct your matroid from scratch by specifying, e.g., its set of bases or non-bases and then compute other properties. The following constructs the Fano matroid, which is the simplest matroid that cannot be constructed from a vector configuration (over a field with a characteristic other than two).\n",
    "\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       " \n"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "$a=new Array<Set<Int>>([0,1,5],[1,2,6],[0,2,3],[1,3,4],[2,4,5],[3,5,6],[0,4,6]);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "$m=new Matroid(NON_BASES=>$a,N_ELEMENTS=>7);"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{0 1 2 4}\n",
       "{0 1 3 6}\n",
       "{0 2 5 6}\n",
       "{0 3 4 5}\n",
       "{1 2 3 5}\n",
       "{1 4 5 6}\n",
       "{2 3 4 6}\n",
       "    \n"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print $m->COCIRCUITS;"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "Note that you have to specify N_ELEMENTS when constructing a matroid in this way because this is not implicit in BASES, etc.\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "polymake",
   "language": "polymake",
   "name": "polymake"
  },
  "language_info": {
   "codemirror_mode": "perl",
   "file_extension": ".pm",
   "mimetype": "text/x-polymake",
   "name": "polymake"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}