{ "cells": [ { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "# Solving Non-linear Equations\n", "\n", "The [Roots](https://github.com/JuliaMath/Roots.jl) package provides methods for solving a non-linear equation (one variable, one function). \n", "\n", "For a system of non-linear equations, use [NLsolve](https://github.com/JuliaNLSolvers/NLsolve.jl)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Load Packages and Extra Functions" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "printyellow (generic function with 1 method)" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "using Printf, Roots, NLsolve\n", "\n", "include(\"jlFiles/printmat.jl\")" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "using Plots\n", "\n", "#pyplot(size=(600,400))\n", "gr(size=(480,320))\n", "default(fmt = :svg)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Defining and Plotting the Function\n", "\n", "The next few cells define a fairly simple function and then plots it. \n", "\n", "If possible, plot your function before trying to find the roots. Maybe you see something strange, perhaps there are several roots? It also helps you set the initial guesses (or brackets) for root solving." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "fn1 (generic function with 1 method)" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fn1(x,c) = 2*(x - 1.1)^2 - c" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "x = -1:0.1:3\n", "\n", "p1 = plot( x,fn1.(x,0.5),\n", " linecolor = :red,\n", " linewidth = 2,\n", " legend = nothing,\n", " title = \"the fn1(x,0.5) function\",\n", " xlabel = \"x\",\n", " ylabel = \"y\" )\n", "display(p1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There seems to be two roots: around 0.6 and 1.6." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Solving a Non-Linear Equation\n", "\n", "The Roots package wants a function with only one input. An easy way to turn ```fn1(a,0.5)``` into that form is by defining an anonymous function:\n", "```\n", "x->fn1(x,0.5)\n", "```\n", "\n", "Then, running \n", "```\n", "find_zero(x->fn1(x,0.5),(x₀,x₁))\n", "```\n", "searches for a root in the `[x₀,x₁]` interval. Alternatively, you can also do \n", "```\n", "find_zero(x->fn1(x,0.5),x₂)\n", "``` \n", "where `x₂` is a single starting guess.\n", "\n", "Instead, running\n", "```\n", "find_zeros(x->fn1(x,0.5),x₀,x₁)\n", "```\n", "searches for all roots between x₀ and x₁. (Notice the *s* in `find_zeros`.)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "at which x is fn1(x,0.5) = 0? 0.600\n", "at which x is fn1(x,0.5) = 0? 1.600\n", "\n", "\u001b[34m\u001b[1myes, there are several roots. Just look at it (in the plot)\u001b[22m\u001b[39m\n" ] } ], "source": [ "xRoot1 = find_zero(x->fn1(x,0.5),(-1,1)) #searches for roots in [-1,1]\n", "printlnPs(\"at which x is fn1(x,0.5) = 0? \",xRoot1)\n", "\n", "xRoot2 = find_zero(x->fn1(x,0.5),2) #searches for roots around 2\n", "printlnPs(\"at which x is fn1(x,0.5) = 0? \",xRoot2)\n", "\n", "printblue(\"\\nyes, there are several roots. Just look at it (in the plot)\")" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "at which x is fn1(x,0.5) = 0? 0.600 1.600\n" ] } ], "source": [ "xRootsAll = find_zeros(x->fn1(x,0.5),-1,3) #find_zeros (notice the \"s\")\n", "\n", "printlnPs(\"at which x is fn1(x,0.5) = 0? \",xRootsAll)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Solving a System of Non-Linear Equations\n", "\n", "The NLsolve package has many options. The cells below illustrate a very simple case (2 non-linear equations with 2 unknowns, no information about the derivatives).\n", "\n", "The two equations are\n", "\n", "$ \n", "y-x^2-1=0\n", "$\n", "\n", "$\n", "y-x-1=0\n", "$\n", "\n", "and the roots are at $(x,y)=(0,1)$ and also at $(1,2)$." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "fn2 (generic function with 1 method)" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "function fn2(p) #p is a vector with 2 elements, the output too\n", " (x,y) = (p[1],p[2])\n", " z = [y-x^2-1;y-x-1] #equal to [0,0]\n", " return z\n", "end" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "There is a solution at -0.000 1.000\n", "There is a another solution at 1.000 2.000\n" ] } ], "source": [ "Sol2a = nlsolve(fn2,[0.0,0.5])\n", "printlnPs(\"There is a solution at \",Sol2a.zero)\n", "\n", "Sol2b = nlsolve(fn2,[1.0,0.0]) #try again, using another starting guess\n", "printlnPs(\"There is a another solution at \",Sol2b.zero)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "@webio": { "lastCommId": null, "lastKernelId": null }, "anaconda-cloud": {}, "kernelspec": { "display_name": "Julia 1.6.0", "language": "julia", "name": "julia-1.6" }, "language_info": { "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", "version": "1.6.0" } }, "nbformat": 4, "nbformat_minor": 1 }