{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# 1. Let N be the natural logarithm of 10.\n", "# (a) Give a floating-point approximation A of N,\n", "# accurate with 5 decimal places.\n", "# (b) Compute a rational approximation R for N,\n", "# accurate with 5 decimal places. Write the value for R.\n", "# Write the Sage command(s) and its output to verify that\n", "# R approximates N indeed with an accuracy of 5 decimal places.\n", "# (c) Give the Sage command to compute a list of the first 10\n", "# rational approximations of N.\n", "# Do not write the entire list, write only its last element." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2.3026\n" ] } ], "source": [ "# answer to 1 (a)\n", "N = ln(10)\n", "A = N.n(digits=5)\n", "print A" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2047/889\n", "2.14577e-6\n" ] } ], "source": [ "# answer to 1 (b)\n", "R = QQ(A)\n", "print R\n", "print (R-N).n(digits=6)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[23/10,\n", " 23/10,\n", " 274/119,\n", " 624/271,\n", " 2047/889,\n", " 3919/1702,\n", " 12381/5377,\n", " 53443/23210,\n", " 201391/87463,\n", " 563111/244556]" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# answer to 1 (c)\n", "[QQ(N.n(digits=k)) for k in range(1, 11)]" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "# 2. Let x and y be variables, declared via x, y = var('x,y').\n", "# Explain the difference between y = 2; x = y and y = 2; x = 'y'.\n", "# Explain the relations between x and y in both cases." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "x = 2\n", "y = 2\n" ] } ], "source": [ "reset()\n", "x, y = var('x,y')\n", "y = 2; x = y\n", "print 'x =', x\n", "print 'y =', y" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "x = y\n", "eval(x) = 2\n", "2\n" ] } ], "source": [ "# In the first case, in the assignment x = y, y is evaluated to 2\n", "# and 2 is assigned to x. Both x and y refer to the constant 2\n", "# and there is no relationship between x and y.\n", "y = 2; x = 'y'\n", "print 'x =', x\n", "print 'eval(x) =', eval(x)\n", "print y" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "# In the second case, the quotes around y prevent the evaluation\n", "# in the assignment, so the name y is assigned to x.\n", "# The relationship between the variables is that x refers to y,\n", "# and y refers to 2. Both x and y evaluate to 2.\n", "# If the value for y changes, then also the value for x will change." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "# 3. Let p be the polynomial\n", "# p = x^8 + 2 x^7 + 5 x^6 - 3 x^5 - 4 x^4 - x^3 + x^2 + x - 2.\n", "# What is the smallest number of arithmetical operations\n", "# needed to evaluate p?\n", "# What is the fastest way to evaluate p in hardware arithmetic?\n", "# (a) Give all Sage commands to convert p into an expression\n", "# best suited for fast evaluation.\n", "# Do not write the output of the Sage commands.\n", "# (b) Give timing results to compare the straightforward\n", "# evaluation of p with the evaluation of the form\n", "# for fast evaluation." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "x^8 + 2*x^7 + 5*x^6 - 3*x^5 - 4*x^4 - x^3 + x^2 + x - 2\n" ] } ], "source": [ "reset()\n", "x = var('x')\n", "p = x^8 + 2*x^7 + 5*x^6 - 3*x^5 - 4*x^4 - x^3 + x^2 + x - 2\n", "print p" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(((((((x + 2)*x + 5)*x - 3)*x - 4)*x - 1)*x + 1)*x + 1)*x - 2\n", "value of f at 3.14 : 18937.1020364512\n", "value of p at 3.14 : 18937.1020364512\n" ] } ], "source": [ "# Using the Horner form for p, 8 multiplications and 8 additions \n", "# (some of the additions are subtractions) suffice to evaluate p.\n", "# For fast evaluation with hardware numbers, we use the fast_callable.\n", "h = p.horner(x)\n", "print h\n", "f = fast_callable(h, vars=['x'])\n", "print 'value of f at 3.14 :', f(3.14)\n", "print 'value of p at 3.14 :', p(x=3.14)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "625 loops, best of 3: 97.8 µs per loop\n" ] } ], "source": [ "# We time the evaluation of p.\n", "timeit('p(x=3.14)')" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "625 loops, best of 3: 9.07 µs per loop\n" ] } ], "source": [ "# Then compare with the time of the fast callable f.\n", "timeit('f(3.14)')" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "# 4. For this question, write all relevant Sage commands and their output.\n", "# Define the polynomial p = 9 x^3 - 72 x^2 - 78 x + 3\n", "# over the field of rational coefficients.\n", "# (a) Is p irreducible? If not, what are the factors of p?\n", "# (b) Extend the field of rational numbers with sufficiently many\n", "# formal roots so p factors as a product of linear polynomials\n", "# over the field extension." ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "9*x^3 - 72*x^2 - 78*x + 3\n", "(9) * (x + 1) * (x^2 - 9*x + 1/3)\n" ] } ], "source": [ "reset()\n", "R. = PolynomialRing(QQ)\n", "p = 9*x^3 - 72*x^2 - 78*x + 3\n", "print p\n", "f = factor(p)\n", "print f" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[(x + 1, 1), (x^2 - 9*x + 1/3, 1)]\n" ] } ], "source": [ "# We see that p factors, let us make the list of factors.\n", "L = list(f)\n", "print L" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Number Field in a with defining polynomial x^2 - 9*x + 1/3\n", "(9) * (x - a) * (x + a - 9) * (x + 1)\n" ] } ], "source": [ "# We select the quadratic factor of L\n", "# to define the field extension of QQ.\n", "K. = QQ.extension(L[1][0])\n", "print K\n", "print factor(K[x](p))" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1/(x^2 + 3*y), x - y + 1]\n", "\n" ] } ], "source": [ "# 5. Type x, y = var('x, y'); q = (x-y+1)/(x^2+3*y)\n", "# and draw the expression tree of q.\n", "# Give some relevant Sage commands you used to\n", "# obtain your drawing.\n", "reset()\n", "x, y = var('x,y')\n", "q = (x-y+1)/(x^2 + 3*y)\n", "print q.operands()\n", "print q.operator()" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[x^2 + 3*y, -1], [x, -y, 1]]\n", "[, ]\n" ] } ], "source": [ "# Let us look at the operands and operators of the operands of q.\n", "L1 = [op.operands() for op in q.operands()]\n", "print L1\n", "print [op.operator() for op in q.operands()]" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[x^2, 3*y]\n" ] } ], "source": [ "print L1[0][0].operands()" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " ^_\n", " / /\n", "x 2\n", " *_\n", " / /\n", "3 y\n" ] } ], "source": [ "# Representing the operands x^2 and 3*x is straightforward.\n", "leafx = LabelledOrderedTree([], label='x')\n", "leafy = LabelledOrderedTree([], label='y')\n", "leaf2 = LabelledOrderedTree([], label='2')\n", "nodex2 = LabelledOrderedTree([leafx, leaf2], label='^')\n", "print ascii_art(nodex2)\n", "leaf3 = LabelledOrderedTree([], label='3')\n", "node3y = LabelledOrderedTree([leaf3, leafy], label='*')\n", "print ascii_art(node3y)" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " _+___\n", " / / \n", " ^_ *_\n", " / / / /\n", "x 2 3 y\n" ] } ], "source": [ "# The denominator is the sum of x^2 and 3*y.\n", "denominator = LabelledOrderedTree([nodex2, node3y], label='+')\n", "print ascii_art(denominator)" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " __^___\n", " / / \n", " _+___ -1\n", " / / \n", " ^_ *_ \n", " / / / / \n", "x 2 3 y \n" ] } ], "source": [ "# The inverse of the denominator is multiplied with the numerator.\n", "leafm1 = LabelledOrderedTree([], label='-1')\n", "inversedenominator = LabelledOrderedTree([denominator, leafm1], label='^')\n", "print ascii_art(inversedenominator)" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " ___+____\n", " / / /\n", "x *__ 1\n", " / /\n", " -1 y \n" ] } ], "source": [ "# For the numerator, note that -y is represented as (-1)*y.\n", "nodem1y = LabelledOrderedTree([leafm1,leafy], label='*')\n", "leaf1 = LabelledOrderedTree([], label='1')\n", "numerator = LabelledOrderedTree([leafx, nodem1y, leaf1], label='+')\n", "print ascii_art(numerator)" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/plain": [ " ____*______\n", " / / \n", " __^___ ___+____\n", " / / / / /\n", " _+___ -1 x *__ 1\n", " / / / /\n", " ^_ *_ -1 y \n", " / / / / \n", "x 2 3 y " ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Then the root of the expression tree has the * operator.\n", "exptree = LabelledOrderedTree([inversedenominator, numerator], label='*')\n", "ascii_art(exptree)" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [], "source": [ "# 6. For polynomials in several variables\n", "# explain the difference between the pure lexicographic\n", "# and the degree lexicographic order.\n", "# Illustrate the difference with good examples." ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [], "source": [ "# Let us create a polynomial ring R in three variables,\n", "# over the rational numbers, where the monomials are\n", "# ordered in pure lexicographic order.\n", "# In the ring R, we use the same variable,\n", "# the the order is the degree lexicographic order.\n", "R. = PolynomialRing(QQ, order='lex')\n", "S. = PolynomialRing(QQ, order='deglex')" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "-3/7*x^3*y^2 + 3/2*x^3*y - 5/2*x^3*z + x^3 - 16/5*x^2*y*z - 1/7*x^2*z^2 + 2*x*y^3*z + 1/5*x*y^2*z^2 - x*z^2 - 1/6*x*z - y^2*z^3 - y^2*z^2 - 1/9*y^2 - 3/2*y*z^4 - 2*y*z^3 - 2*z^3 + 1\n" ] } ], "source": [ "# To see the difference between the two,\n", "# consider a random polynomial of degree 5 with 20 terms in R.\n", "p = R.random_element(degree=5, terms=20)\n", "print p" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "-3/7*x^3*y^2 + 2*x*y^3*z + 1/5*x*y^2*z^2 - y^2*z^3 - 3/2*y*z^4 + 3/2*x^3*y - 5/2*x^3*z - 16/5*x^2*y*z - 1/7*x^2*z^2 - y^2*z^2 - 2*y*z^3 + x^3 - x*z^2 - 2*z^3 - 1/6*x*z - 1/9*y^2 + 1\n" ] } ], "source": [ "# In the pure lexicographic order, the terms with highest power in x\n", "# occur before all the other ones. This is not the case in the\n", "# degree lexicographic order, where terms are first ordered by degree.\n", "print S(p)" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [], "source": [ "# We see the difference between p and S(p) already in the second term,\n", "# which is of degree 5 and therefore occurs before the degree four terms\n", "# in S(p). In p, this second term of S(p) occurs later, because its\n", "# degree in x is only 2." ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [], "source": [ "# 7. What are the commands to transform\n", "# (x-y)^2/(x+y)^2 + 1 into ((x-y)^2 + (x+y)^2)/(x+y)^2?" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(x - y)^2/(x + y)^2 + 1\n" ] } ], "source": [ "reset()\n", "x,y = var('x,y')\n", "q = (x-y)^2/(x+y)^2 + 1\n", "print q" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(u^2 + v^2)/v^2\n", "((x + y)^2 + (x - y)^2)/(x + y)^2\n" ] } ], "source": [ "# To prevent (x-y)^2 and (x+y)^2 from expanding,\n", "# we replace x-y by u and x+y by v.\n", "u, v = var('u, v')\n", "p = q.subs({x-y:u, x+y:v})\n", "r = p.factor()\n", "print r\n", "print r(u=x-y, v=x+y)" ] } ], "metadata": { "kernelspec": { "display_name": "SageMath 8.3", "language": "", "name": "sagemath" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.15" } }, "nbformat": 4, "nbformat_minor": 2 }