{ "cells": [ { "cell_type": "markdown", "id": "b431cb01", "metadata": {}, "source": [ "Quiz 3, on Friday 9 September 2022, due 10:50am." ] }, { "cell_type": "markdown", "id": "c2793288", "metadata": {}, "source": [ "Suppose we want to approximate a root of $p = x^3 - x - 1$.\n", "\n", "1. What are the conditions for the secant method to apply to this problem?\n", "\n", " What could go wrong?\n", "\n", "\n", "2. Starting at 1.3, how many steps of the secant method are needed to\n", " obtain eight correct decimal places of a root of $p$? \n", " \n", " Justify your answer." ] }, { "cell_type": "markdown", "id": "11299471", "metadata": {}, "source": [ "# Answer to 1" ] }, { "cell_type": "markdown", "id": "6ab0a607", "metadata": {}, "source": [ "The convergence of the secant method is local. For the secant method to apply, we need an approximation that is sufficiently close to a root.\n", "\n", "The secant fails if $p(x_1) = p(x_2)$ where $x_1$ and $x_2$ are the two current approximations." ] }, { "cell_type": "markdown", "id": "9675b78e", "metadata": {}, "source": [ "# Anwer to 2" ] }, { "cell_type": "code", "execution_count": 1, "id": "622525c2", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "-0.10299999999999954" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p(x) = x^3 - x - 1\n", "p(1.3)" ] }, { "cell_type": "markdown", "id": "ee5d8b17", "metadata": {}, "source": [ "Assuming a good condition number, the backward error equals the forward error and we have already one decimal place correct, or the error is 0.1. \n", "\n", "To estimate the number of steps, we use the superlinear convergence of the secant method. The error in the next step is the previous error raised to the exponent 1.618. We want to compute $N$, the number of steps so the following holds:\n", "\n", "$$\n", " 0.1^{1.618N} = 10^{-8}\n", "$$\n", "\n", "or taking logarithms: $1.618N \\log(0.1) = \\log(10^{-8})$." ] }, { "cell_type": "code", "execution_count": 2, "id": "06ed572d", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "4.944375772558715" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "log(10^(-8))/(1.618*log(0.1))" ] }, { "cell_type": "markdown", "id": "ead10e5c", "metadata": {}, "source": [ "In five steps we will have 8 correct decimal places. Let us verify this and run the secant method, using 1.4 as the second point." ] }, { "cell_type": "code", "execution_count": 3, "id": "86e87624", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "secant" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "using Printf\n", "\"\"\"\n", "Applies the secant method to a function.\n", "\n", "ON ENTRY :\n", "\n", " f a function in one variable\n", " x1,x2 two start points\n", " dxtol tolerance on the forward error\n", " fxtol tolerance on the backward error\n", " N maximum number of iterations\n", "\n", "ON RETURN : (x, absdx, absfx, nbrit, fail)\n", "\n", " x approximation for the root\n", " absdx estimated forward error\n", " absfx estimated backward error\n", " nbrit number of iterations\n", " fail true if tolerances not reached,\n", " false otherwise.\n", "\n", "EXAMPLE:\n", "\n", " (root, err, res, nit, fail) = secant(cos,pi/4,2*pi/3)\n", "\"\"\"\n", "function secant(f::Function,x1::Float64,x2::Float64,\n", " dxtol::Float64=1.0e-8,fxtol::Float64=1.0e-8,N::Int64=10)\n", " dx = 1\n", " println(\"running the secant method...\")\n", " title = \" root |dx| |f(x)|\"\n", " println(\"step : $title\")\n", " fx1 = f(x1)\n", " fx2 = f(x2)\n", " for i = 1:N\n", " dx = fx2*(x2 - x1)/(fx2 - fx1)\n", " x1 = x2 # store x2 for next step\n", " x2 = x2 - dx\n", " fx1 = fx2\n", " fx2 = f(x2)\n", " stri = @sprintf(\"%3d\", i)\n", " strx = @sprintf(\"%.16e\", x2)\n", " strdx = @sprintf(\"%.2e\", abs(dx))\n", " strfx = @sprintf(\"%.2e\", abs(fx2))\n", " println(\"$stri : $strx $strdx $strfx\")\n", " if((abs(fx2) < dxtol) | (abs(dx) < fxtol))\n", " stri = string(i)\n", " println(\"succeeded after $stri steps\")\n", " return (x2, abs(dx), abs(fx2), i, false)\n", " end\n", " end\n", " strN = string(N)\n", " println(\"failed requirements after $strN steps\")\n", " return (x2, abs(dx), abs(fx2), N, true)\n", "end" ] }, { "cell_type": "code", "execution_count": 4, "id": "2ca737b6", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "running the secant method...\n", "step : root |dx| |f(x)|\n", " 1 : 1.3230425055928412e+00 7.70e-02 7.13e-03\n", " 2 : 1.3246060608507002e+00 1.56e-03 4.77e-04\n", " 3 : 1.3247181321646786e+00 1.12e-04 7.46e-07\n", " 4 : 1.3247179572265049e+00 1.75e-07 7.78e-11\n", " 5 : 1.3247179572447461e+00 1.82e-11 2.22e-16\n", "succeeded after 5 steps\n" ] }, { "data": { "text/plain": [ "(1.324717957244746, 1.824108624274744e-11, 2.220446049250313e-16, 5, false)" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "secant(p,1.3,1.4,1.0e-16,1.0e-8)" ] }, { "cell_type": "markdown", "id": "03d13167", "metadata": {}, "source": [ "Indeed, after five steps, we have more than 8 correct decimal places." ] } ], "metadata": { "kernelspec": { "display_name": "Julia 1.8.0", "language": "julia", "name": "julia-1.8" }, "language_info": { "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", "version": "1.8.0" } }, "nbformat": 4, "nbformat_minor": 5 }