{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A short note on variable naming up front: You can alter variable names used for parsing polynomials and for pretty-printing using the `set_var_names` or `local_var_names` functions. Refer to their [documentation](https://polymake.org/doku.php/documentation/latest/common#set_var_names) for defaults and usage information. To restore the default settings, type this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "reset_custom %polynomial_var_names;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Usage of Polynomials in Perl\n",
    "\n",
    "#### Constructors\n",
    "The easiest way to create a simple [Polynomial](https://polymake.org/doku.php/documentation/latest/common#polynomial) object is through a string:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "$p = new Polynomial(\"4 + 3x_1 + x_2^5\");"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "Sometimes it's convenient to use the constructor that takes a vector of coefficients and a matrix of exponents:\n",
    "\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-5*x_0^8*x_1^3 + 9*x_1^4"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "$coeff = new Vector([9,-5]);\n",
    "$exp = new Matrix<Int>([[0,4],[8,3]]);\n",
    "$p2 = new Polynomial($coeff, $exp);\n",
    "print $p2;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "There is a separate type for univariate polynomials, called [UniPolynomial](https://polymake.org/doku.php/documentation/latest/common#unipolynomial)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "$up = new UniPolynomial(\"3x + 2x^2 + 4\");"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "Polynomials (and UniPolynomials) are templated by their coefficient and exponent types, defaulting to Rational for coefficients and Int for exponents. You can even have polynomials of polynomials (of polynomials...).\n",
    "\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(4*x^2 + 5)*y^3/2 + (-5/3*x^4)*y^2/3"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "$pp = new UniPolynomial<UniPolynomial<Rational,Int>,Rational>(\"(4x^2+5)y3/2 - 5/3x4y2/3\");\n",
    "print $pp;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Computations\n",
    "\n",
    "The standard arithmetic functions \"+\", \"-\", \"*\", \"^\" are defined for polynomials of matching type."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "9*x_1^2 + 6*x_1*x_2^5 + 27*x_1 + x_2^10 + 9*x_2^5 + 20"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print $p + ($p^2);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "However, note that due to the fact that their precedence is given in perl, it may be necessary to write more parentheses than expected at first sight. For example, as above, you always have to write \"($p^2)\" because of the lower precedence of the \"^\" operator..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "36*x_1^2 + 24*x_1*x_2^5 + 96*x_1 + 4*x_2^10 + 32*x_2^5 + 64"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print $p + $p^2;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For UniPolynomials, we even have polynome division:\n",
    "\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(2*x^2 + 3*x + 4)/(1)"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print (($up^2)/$up);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "#### Example: Newton Polynomials\n",
    "\n",
    "Here is one way to produce polytopes from polynomials (as the convex hull of the exponent vectors of all terms).\n",
    "\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1 0 0 0\n",
       "1 0 0 10\n",
       "1 0 2 0\n"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/html": [
       "<details><summary><pre style=\"display:inline\"><small>Click here for additional output</small></pre></summary>\n",
       "<pre>\n",
       "polymake: used package cdd\n",
       "  cddlib\n",
       "  Implementation of the double description method of Motzkin et al.\n",
       "  Copyright by Komei Fukuda.\n",
       "  http://www-oldurls.inf.ethz.ch/personal/fukudak/cdd_home/\n",
       "\n",
       "</pre>\n",
       "</details>\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "$np = newton($p*($p+$p));\n",
    "print $np->VERTICES;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "true"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/html": [
       "<details><summary><pre style=\"display:inline\"><small>Click here for additional output</small></pre></summary>\n",
       "<pre>\n",
       "polymake: used package lrs\n",
       "  Implementation of the reverse search algorithm of Avis and Fukuda.\n",
       "  Copyright by David Avis.\n",
       "  http://cgm.cs.mcgill.ca/~avis/C/lrs.html\n",
       "\n",
       "</pre>\n",
       "</details>\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "print equal_polyhedra($np,minkowski_sum(newton($p),newton($p+$p)));"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The Newton polytope of the product of two polynomials always equals the Minkowski sum of the Newton polytopes of the factors."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Example: Toric Degeneration\n",
    "\n",
    "The following describes how to construct the polynomial which describes the toric deformation with respect to a point configuration and a height function.  This is the input data:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "$points = new Matrix<Int>([1,0],[0,1]);\n",
    "$height = new Vector<Int>([2,3]);\n",
    "$coefficients = new Vector<Rational>([-1/2,1/3]);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The following is generic (assuming that the dimensions of the objects above match)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "$p = new Polynomial($coefficients,$height|$points);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Notice that the points are given in Euclidean coordinates; that is, if applied, e.g., to the VERTICES of a polytope do not forget to strip the homogenizing coordinate. The output in our example looks like this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1/3*x_0^3*x_2 -1/2*x_0^2*x_1"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print $p;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Puiseux Fractions\n",
    "\n",
    "Polymake supports the usage of Puiseux fractions - see for example [this paper](https://arxiv.org/abs/1507.08092) for reference.\n",
    "\n",
    "The preferred way of creating a new Puiseux fraction is to create an ordinary monomial, and then use that to define a new `PuiseuxFraction` object:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "$x = monomials<Rational,Rational>(1); # create a list of `1` monomial, with `Rational` coefficients and `Rational` exponents\n",
    "$f = new PuiseuxFraction<Min>(2*($x^(1/3)) + ($x^(5/2)));"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you have the common denominator of all exponents at hand you could also intermediately set `$x = $x^(1/N)` to save yourself some work."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can compute the valuation of a puiseux fraction:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1/3"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print $f->val;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Evaluate a puiseux fraction at $2^6$:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "32776"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print evaluate($f,2,6);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Operators like `+`, `-`, `*`, `/` are defined as you'd expect.\n",
    "\n",
    "Besides, puiseux fractions, similar to rational functions over any ordered field, have a natural ordering induced by the ordering of the coefficients (see the above mentioned paper for detals) - polymake correspondingly overloads the operators `<`, `>`, `<=`, `>=`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "true"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "$g = new PuiseuxFraction<Min>(3*($x^(3/2)));\n",
    "print $f>$g;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Applications"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "One usage example is parametrized polyhedra.\n",
    "As an example we compute a family of 3 dimensional Klee-Minty cubes:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "facets:\n",
       "(0) (1) (0) (0)\n",
       "(1) (- 1) (0) (0)\n",
       "(0) (-2*x^1/3 - x^5/2) (1) (0)\n",
       "(1) (-2*x^1/3 - x^5/2) (- 1) (0)\n",
       "(0) (0) (-2*x^1/3 - x^5/2) (1)\n",
       "(1) (0) (-2*x^1/3 - x^5/2) (- 1)\n",
       "\n",
       "volume:\n",
       "(1 -4*x^1/3 + 4*x^2/3 -2*x^5/2 + 4*x^17/6 + x^5)"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "$k = klee_minty_cube(3, $f);\n",
    "print \"facets:\\n\", $k->FACETS, \"\\nvolume:\\n\", $k->VOLUME;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can even check for (combinatorial) isomorphy:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "true"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/html": [
       "<details><summary><pre style=\"display:inline\"><small>Click here for additional output</small></pre></summary>\n",
       "<pre>\n",
       "polymake: used package nauty\n",
       "  Computation of automorphism groups of graphs.\n",
       "  Copyright by Brendan McKay and Adolfo Piperno.\n",
       "  http://pallini.di.uniroma1.it/\n",
       "</pre>\n",
       "</details>\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "print isomorphic($k, cube(3));"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As another example related to linear optimization we compute a family of 3 dimensional Goldfarb-Sit cubes (again, see the above mentioned paper, and consult:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1)"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/html": [
       "<details><summary><pre style=\"display:inline\"><small>Click here for additional output</small></pre></summary>\n",
       "<pre>\n",
       "polymake: used package tosimplex\n",
       "  Dual simplex algorithm implemented by Thomas Opfer\n",
       "\n",
       "</pre>\n",
       "</details>\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "$l = goldfarb_sit(3, $g, 1/2);\n",
    "print $l->LP->MAXIMAL_VALUE;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1) (0) (0) (1)"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print $l->LP->MAXIMAL_VERTEX;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(27/8*x^9/2 -81/4*x^6 + 243/8*x^15/2)"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print $l->VOLUME;"
   ]
  }
 ],
 "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
}
