{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# \n", "\n", "# Investigating limits with Julia\n", "\n", "To get started, we load the `MTH229` package so that we can make plots\n", "and use some symbolic math:" ], "id": "491206ae-1911-4e3a-956f-d2ff41f70961" }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "using MTH229\n", "using Plots\n", "plotly()" ], "id": "9aabd026" }, { "cell_type": "markdown", "metadata": {}, "source": [ "------------------------------------------------------------------------\n", "\n", "### Quick background\n", "\n", "Read about this material here: [Investigating limits with\n", "Julia](http://mth229.github.io/limits.html).\n", "\n", "The expression\n", "\n", "$$\n", "\\lim_{x \\rightarrow c} f(x) = L\n", "$$\n", "\n", "says that the limit as $x$ goes to $c$ of $f$ is $L$.\n", "\n", "> Intuitively, as $x$ gets “close” to $c$, $f(x)$ should be close to\n", "> $L$.\n", "\n", "If $f(x)$ is *continuous* at $x=c$, then $L=f(c)$. This is almost always\n", "the case for a randomly chosen $c$ - but almost never the case for a\n", "textbook choice of $c$. Invariably with text book examples—though not\n", "always—we will have `f(c) = NaN` indicating the function is\n", "indeterminate at `c`. For such cases we need to do more work to identify\n", "if any such $L$ exists and when it does, what its value is.\n", "\n", "In this project, we investigate limits three ways: graphically, with a\n", "table of numbers, and analytically, developing the inituition of limits\n", "along the way.\n", "\n", "#### Graphical approach\n", "\n", "The graphical approach is to plot the expression *near* $c$ and look\n", "visually what $f(x)$ goes to as $x$ gets close to $c$.\n", "\n", "For example, what is this limit?\n", "\n", "$$\n", "\\lim_{x \\rightarrow \\pi/2} \\frac{1 - \\sin(x)}{(\\pi/2 - x)^2}?\n", "$$\n", "\n", "Here is a graph to investigate the problem. We simply graph near $c$ and\n", "look:" ], "id": "8bda4595-2156-41af-b345-a191bdf4b270" }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "output_type": "display_data", "metadata": {}, "data": { "text/html": [ "" ] } } ], "source": [ "f(x) = (1-sin(x)) / (pi/2 - x)^2\n", "c = pi/2\n", "plot(f, c - pi/6, c + pi/6)" ], "id": "e0bb78c3" }, { "cell_type": "markdown", "metadata": {}, "source": [ "From the graph, we see clearly that as $x$ is close to $c=\\pi/2$, $f(x)$\n", "is close to $1/2$. (The fact that `f(pi/2) = NaN` will either not come\n", "up, as `pi/2` is not among the points sampled or the `NaN` values will\n", "not be plotted.)\n", "\n", "## Using tables to investigate limits\n", "\n", "Investigating a limit numerically requires us to operationalize the idea\n", "of $x$ getting close to $c$ and $f(x)$ getting close to $L$. Here we do\n", "this manually:" ], "id": "10190b81-2884-4ede-bc9d-404acd088fc9" }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "output_type": "display_data", "metadata": {}, "data": { "text/plain": [ "(0.9983341664682815, 0.9999833334166665, 0.9999998333333416, 0.9999999983333334, 0.9999999999833332, 0.9999999999998334)" ] } } ], "source": [ "f(x) = sin(x)/x\n", "f(0.1), f(0.01), f(0.001), f(0.0001), f(0.00001), f(0.000001)" ], "id": "132df3bb" }, { "cell_type": "markdown", "metadata": {}, "source": [ "From this we see a *right* limit at 0 appears to be $1$.\n", "\n", "We can put the above into a column, by wrapping things in square\n", "brackets (forming a vector):" ], "id": "141b0f46-c9aa-476a-b987-45981299edcd" }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "output_type": "display_data", "metadata": {}, "data": { "text/plain": [ "6-element Vector{Float64}:\n", " 0.9983341664682815\n", " 0.9999833334166665\n", " 0.9999998333333416\n", " 0.9999999983333334\n", " 0.9999999999833332\n", " 0.9999999999998334" ] } } ], "source": [ "[f(0.1), f(0.01), f(0.001), f(0.0001), f(0.00001), f(0.000001)]" ], "id": "4d85b4f3" }, { "cell_type": "markdown", "metadata": {}, "source": [ "The style of printing makes it clear, the limit here should be $L=1$.\n", "\n", "Limits when $c\\neq 0$ are similar, but require points getting close to\n", "$c$. For example,\n", "\n", "$$\n", "\\lim_{x \\rightarrow \\pi/2} \\frac{1 - \\sin(x)}{(\\pi/2 - x)^2}\n", "$$\n", "\n", "has a limit of $1/2$. We can investigate with:" ], "id": "e7840500-b46b-4957-93bc-035f8f2abb8d" }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "output_type": "display_data", "metadata": {}, "data": { "text/plain": [ "5-element Vector{Float64}:\n", " 0.49958347219742816\n", " 0.4999999583256134\n", " 0.5000000413636343\n", " 0.49960036049791995\n", " 0.0" ] } } ], "source": [ "c = pi/2\n", "f(x) = (1 - sin(x))/(pi/2 - x)^2\n", "[f(c+.1), f(c+.001), f(c+.00001), f(c+.0000001), f(c+.000000001)]" ], "id": "01dbf765" }, { "cell_type": "markdown", "metadata": {}, "source": [ "Wait, is the limit $1/2$ or $0$? At first $1/2$ seems like the answer,\n", "but the last number is $0$.\n", "\n", "Here we see a limitation of tables - when numbers get too small, that\n", "fact that they are represented in floating point becomes important. In\n", "this case, for numbers too close to $\\pi/2$ the value on the computer\n", "for `sin(x)` is just 1 and not a number near 1. Hence the denominator\n", "becomes $0$, and so then the expression. (Near $1$, the floating point\n", "values are about $10^{-16}$ apart, so when two numbers are within\n", "$10^{-16}$ of each other, they can be rounded to the same number.) So\n", "watch out when seeing what the values of $f(x)$ get close to. Here it is\n", "clear that the limit is heading towards $0.5$ until we get too close.\n", "\n", "For convenience, the `lim` function from the `MTH229` package can make\n", "the above computations easier to do. Its use follows the common pattern:\n", "`action(function, arguments...)`. For example, the limit of $1$ is\n", "clearly suggested below:" ], "id": "d2deb755-4427-4979-9e2d-79669a70a7ed" }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "output_type": "display_data", "metadata": {}, "data": { "text/html": [ "
 0.100000     0.9983341664682815\n",
              " 0.010000     0.9999833334166665\n",
              " 0.001000     0.9999998333333416\n",
              " 0.000100     0.9999999983333334\n",
              " 0.000010     0.9999999999833332\n",
              " 0.000001     0.9999999999998334\n",
              "     ⋮              ⋮\n",
              "     c              L?\n",
              "     ⋮              ⋮\n",
              "-0.000001     0.9999999999998334\n",
              "-0.000010     0.9999999999833332\n",
              "-0.000100     0.9999999983333334\n",
              "-0.001000     0.9999998333333416\n",
              "-0.010000     0.9999833334166665\n",
              "-0.100000     0.9983341664682815
" ] } } ], "source": [ "f(x) = sin(x) / x\n", "lim(f, 0)" ], "id": "ff30f3de" }, { "cell_type": "markdown", "metadata": {}, "source": [ "The limit of $1/2$ is suggested by the following" ], "id": "573df535-4b66-4933-99b9-2dab0f65e36a" }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "output_type": "display_data", "metadata": {}, "data": { "text/html": [ "
1.670796     0.49958347219742816\n",
              "1.580796     0.4999958333473655\n",
              "1.571796     0.4999999583256134\n",
              "1.570896     0.4999999969613747\n",
              "1.570806     0.5000000413636343\n",
              "1.570797     0.5000444503734445\n",
              "     ⋮              ⋮\n",
              "     c              L?\n",
              "     ⋮              ⋮\n",
              "1.570795     0.5000444503734445\n",
              "1.570786     0.5000000413636343\n",
              "1.570696     0.4999999969613747\n",
              "1.569796     0.4999999583256134\n",
              "1.560796     0.4999958333473655\n",
              "1.470796     0.49958347219742816
" ] } } ], "source": [ "f(x) = (1 - sin(x))/(pi/2 - x)^2\n", "lim(f, pi/2)" ], "id": "5d827351" }, { "cell_type": "markdown", "metadata": {}, "source": [ "The above will generate values just bigger than `pi/2` and just smaller\n", "than `pi/2` which are helpful to investigate the limit from *both*\n", "sides. For just a *left* limit, pass in `dir=\"-\"`, as with" ], "id": "3b4984ec-0554-4dc2-bed7-b524835d6b14" }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "output_type": "display_data", "metadata": {}, "data": { "text/html": [ "
     c              L?\n",
              "     ⋮              ⋮\n",
              "1.570795     0.5000444503734445\n",
              "1.570786     0.5000000413636343\n",
              "1.570696     0.4999999969613747\n",
              "1.569796     0.4999999583256134\n",
              "1.560796     0.4999958333473655\n",
              "1.470796     0.49958347219742816
" ] } } ], "source": [ "lim(f, pi/2, dir=\"-\")" ], "id": "fe9fb465" }, { "cell_type": "markdown", "metadata": {}, "source": [ "Similarly, pass in `dir=\"+\"` to get just the right limit.\n", "\n", "## Symbolic limits\n", "\n", "The add-on package `SymPy` can be used to analytically compute the limit\n", "of a symbolic expression. The package is loaded when `MTH229` is.\n", "`SymPy` provides the `limit` function. A sample usage is shown below:" ], "id": "45870d7f-e502-4fee-81e7-7f92f0db7739" }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "f(x) = sin(x)/x\n", "@syms x\n", "limit(f(x), x => 0)" ], "id": "d0ffe84d" }, { "cell_type": "markdown", "metadata": {}, "source": [ "The new command, `@syms x`, creates a symbolic variable named `x`. This\n", "makes `f(x)` a symbolic expression" ], "id": "82e0c4ef-57d2-4f64-8910-072a29dbaee6" }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "f(x)" ], "id": "4eccff9d" }, { "cell_type": "markdown", "metadata": {}, "source": [ "To find the limit of an expression, `ex`, as a symbolic variable, `x`,\n", "goes towards some value `c`, `0` in the above example, is performed by\n", "the command `limit(ex, x => c)`.\n", "\n", "SymPy finds the *right limit by default*. A left limit can be asked for\n", "with the additional argument `dir=\"-\"`. Passing `dir=\"+-\"` to SymPy asks\n", "for both the left and right limit and a test for their equality (e.g.,\n", "the limit).\n", "\n", "------------------------------------------------------------------------" ], "id": "f2074309-d50c-40e6-b1bb-52bbbc49583c" }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "# Your commands go here\n" ], "id": "4fe72985" } ], "nbformat": 4, "nbformat_minor": 5, "metadata": { "kernelspec": { "name": "julia-1.11", "display_name": "Julia 1.11.2", "language": "julia", "path": "/Users/jverzani/Library/Jupyter/kernels/julia-1.11" }, "language_info": { "name": "julia", "file_extension": ".jl", "mimetype": "application/julia", "version": "1.11.2" } } }