{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "### Example 2.8 (Rooted Binary Trees) \n", "Some computational experiments with the generating function for rooted binary trees. \n", "*Requirements: [ore_algebra package](https://github.com/mkauers/ore_algebra/)* \n", "**Note: See the Maple worksheet corresponding to this example for a better treatment of algebraic functions**" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "y^2*z - y + 1" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Define the minimal polynomial P(z,y) of the generating function y(z)\n", "var('y z')\n", "P = z*y^2-y+1\n", "P" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}[1]{\\mathbf{#1}}\\verb|There|\\phantom{\\verb!x!}\\verb|are|\\phantom{\\verb!x!}\\verb|two|\\phantom{\\verb!x!}\\verb|roots|\\phantom{\\verb!x!}\\verb|in|\\phantom{\\verb!x!}\\verb|y:| \\left[y = -\\frac{\\sqrt{-4 \\, z + 1} - 1}{2 \\, z}, y = \\frac{\\sqrt{-4 \\, z + 1} + 1}{2 \\, z}\\right]\n", "\\end{math}" ], "text/plain": [ "'There are two roots in y:' [y == -1/2*(sqrt(-4*z + 1) - 1)/z, y == 1/2*(sqrt(-4*z + 1) + 1)/z]" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "The generating function begins 1 + 1*z + 2*z^2 + 5*z^3 + 14*z^4 + 42*z^5 + 132*z^6 + 429*z^7 + 1430*z^8 + 4862*z^9 + Order(z^10)\n", "The other root has series expansion 1*z^(-1) + (-1) + (-1)*z + (-2)*z^2 + (-5)*z^3 + (-14)*z^4 + (-42)*z^5 + (-132)*z^6 + (-429)*z^7 + (-1430)*z^8 + (-4862)*z^9 + Order(z^10)\n" ] } ], "source": [ "# There are two solutions -- the generating function is the one defined at z=0\n", "show(\"There are two roots in y:\", P.solve(y))\n", "[gf, other] = [k.rhs() for k in P.solve(y)]\n", "print(\"The generating function begins {}\".format(gf.series(z,10)))\n", "print(\"The other root has series expansion {}\".format(other.series(z,10)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There is no good built-in method to compute series solutions to bivariate algebraic equations (Puiseux Series were officially added to Sage in 2020, closing a ticket open for 11 years!). The Maple gfun package of Salvy and Zimmerman has better support for solving algebraic equations. In Sage the best workaround is to use the fact that any algebraic function is D-finite, and use the ore_algebra package which can compute with D-finite functions." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "# Define the ring of linear differential operators with polynomial coefficients\n", "from ore_algebra import *\n", "Pols. = PolynomialRing(QQ); Diff. = OreAlgebra(Pols)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/latex": [ "\\begin{math}\n", "\\newcommand{\\Bold}[1]{\\mathbf{#1}}\\left(4 z^{2} - z\\right) \\mathit{Dz}^{2} + \\left(10 z - 2\\right) \\mathit{Dz} + 2\n", "\\end{math}" ], "text/plain": [ "(4*z^2 - z)*Dz^2 + (10*z - 2)*Dz + 2" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# The GF here satisfies z*(4*z - 1)*diff(y(z), z, z) + 2*(5*z - 1)*diff(y(z), z) + 2*y(z) = 0\n", "deq = z*(4*z - 1)*Dz^2 + 2*(5*z - 1)*Dz + 2\n", "show(deq)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1 + z + 2*z^2 + 5*z^3 + 14*z^4 + O(z^5),\n", " z^(-1)*(1 - 2*z - 2*z^2 - 4*z^3 - 10*z^4 + O(z^5))]" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# A basis of series spanning the solutions to the differential equation at the origin can be computed\n", "# Here there are two solutions: one for the generating function and one for the other root\n", "deq.generalized_series_solutions()" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(-n^2 - 3*n - 2)*Sn + 4*n^2 + 6*n + 2" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# The coefficients of an algebraic function satisfy a P-recurrence\n", "# This computation shows (n^2 + 3*n + 2)*c_{n+1} = (4*n^2 + 6*n + 2)*c_n\n", "Ind. = PolynomialRing(QQ); Shift. = OreAlgebra(Ind)\n", "rec = deq.to_S(Shift)\n", "rec" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1,\n", " 1,\n", " 2,\n", " 5,\n", " 14,\n", " 42,\n", " 132,\n", " 429,\n", " 1430,\n", " 4862,\n", " 16796,\n", " 58786,\n", " 208012,\n", " 742900,\n", " 2674440,\n", " 9694845,\n", " 35357670,\n", " 129644790,\n", " 477638700,\n", " 1767263190,\n", " 6564120420,\n", " 24466267020,\n", " 91482563640,\n", " 343059613650,\n", " 1289904147324,\n", " 4861946401452,\n", " 18367353072152,\n", " 69533550916004,\n", " 263747951750360,\n", " 1002242216651368,\n", " 3814986502092304,\n", " 14544636039226909,\n", " 55534064877048198,\n", " 212336130412243110,\n", " 812944042149730764,\n", " 3116285494907301262,\n", " 11959798385860453492,\n", " 45950804324621742364,\n", " 176733862787006701400,\n", " 680425371729975800390,\n", " 2622127042276492108820,\n", " 10113918591637898134020,\n", " 39044429911904443959240,\n", " 150853479205085351660700,\n", " 583300119592996693088040,\n", " 2257117854077248073253720,\n", " 8740328711533173390046320,\n", " 33868773757191046886429490,\n", " 131327898242169365477991900,\n", " 509552245179617138054608572,\n", " 1978261657756160653623774456,\n", " 7684785670514316385230816156,\n", " 29869166945772625950142417512,\n", " 116157871455782434250553845880,\n", " 451959718027953471447609509424,\n", " 1759414616608818870992479875972,\n", " 6852456927844873497549658464312,\n", " 26700952856774851904245220912664,\n", " 104088460289122304033498318812080,\n", " 405944995127576985730643443367112,\n", " 1583850964596120042686772779038896,\n", " 6182127958584855650487080847216336,\n", " 24139737743045626825711458546273312,\n", " 94295850558771979787935384946380125,\n", " 368479169875816659479009042713546950,\n", " 1440418573150919668872489894243865350,\n", " 5632681584560312734993915705849145100,\n", " 22033725021956517463358552614056949950,\n", " 86218923998960285726185640663701108500,\n", " 337485502510215975556783793455058624700,\n", " 1321422108420282270489942177190229544600,\n", " 5175569924646105559418940193995065716350,\n", " 20276890389709399862928998568254641025700,\n", " 79463489365077377841208237632349268884500,\n", " 311496878311103321137536291518809134027240,\n", " 1221395654430378811828760722007962130791020,\n", " 4790408930363303911328386208394864461024520,\n", " 18793142726809884575211361279087545193250040,\n", " 73745243611532458459690151854647329239335600,\n", " 289450081175264899454283846029490767264392230,\n", " 1136359577947336271931632877004667456667613940,\n", " 4462290049988320482463241297506133183499654740,\n", " 17526585015616776834735140517915655636396234280,\n", " 68854441132780194707888052034668647142985206100,\n", " 270557451039395118028642463289168566420671280440,\n", " 1063353702922273835973036658043476458723103404520,\n", " 4180080073556524734514695828170907458428751314320,\n", " 16435314834665426797069144960762886143367590394940,\n", " 64633260585762914370496637486146181462681535261000,\n", " 254224158304000796523953440778841647086547372026600,\n", " 1000134600800354781929399250536541864362461089950800,\n", " 3935312233584004685417853572763349509774031680023800,\n", " 15487357822491889407128326963778343232013931127835600,\n", " 60960876535340415751462563580829648891969728907438000,\n", " 239993345518077005168915776623476723006280827488229600,\n", " 944973797977428207852605870454939596837230758234904050,\n", " 3721443204405954385563870541379246659709506697378694300,\n", " 14657929356129575437016877846657032761712954950899755100,\n", " 57743358069601357782187700608042856334020731624756611000,\n", " 227508830794229349661819540395688853956041682601541047340]" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# The recurrence can be used to compute many terms of the sequence efficiently\n", "# We must give the initial term in the sequence (to specify which solution we care about)\n", "rec.to_list([1],100)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "SageMath 9.2", "language": "sage", "name": "sagemath" }, "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.8.5" } }, "nbformat": 4, "nbformat_minor": 4 }