{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Fyrirlestur 5\n",
    "### 4. febrúar\n",
    "\n",
    "Python uppsetning"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "import matplotlib\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "import math"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Ólínulegar jöfnur\n",
    "\n",
    "Skoðum jöfnuna $$x^3 - x - 1 = 0$$ "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "def f(x):\n",
    "    return x**3 - x -1\n",
    "def fp(x):\n",
    "    return 3*x**2-1\n",
    "x = np.arange(-2,2,0.01)\n",
    "plt.plot(x,f(x))\n",
    "plt.axhline(color='red')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Helmingunarleit\n",
    "\n",
    "Skilgreinum fall sem tekur inn tvær tölur og eitt fall"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def bisection(f,a,b):\n",
    "    fa = f(a)\n",
    "    if fa==0:\n",
    "        return a;\n",
    "    fb = f(b)\n",
    "    if fb==0:\n",
    "        return b\n",
    "    assert fa*fb < 0, \"Values must have opposite signs\"\n",
    "    c = (a+b)/2\n",
    "    while a!=c and b!=c:\n",
    "        fc = f(c)\n",
    "    \n",
    "        if fc==0:\n",
    "            return c\n",
    "        elif fa*fc < 0:\n",
    "            b,fb = c,fc \n",
    "        else:\n",
    "            a,fa = c,fc\n",
    "        c = (a+b)/2\n",
    "\n",
    "    return c\n",
    "    \n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "print(lambda x: x**2-2)\n",
    "print(bisection(lambda x: x**2-2,0,2))\n",
    "print(bisection(lambda x: x**2-2,0,2) - math.sqrt(2))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Lausn á 3. stigs jöfnu"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "bisection(f,0,2)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "## Newtons aðferð\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def simple_newtons_method(f,fp,x0,limit=20):\n",
    "    n = 0\n",
    "    eps = 1e-15\n",
    "    fx0 = f(x0)\n",
    "    fpx0 = fp(x0)\n",
    "    x = x0 - fx0/fpx0\n",
    "    print(\"iteration: %d, x=%.16f, f(x)=%.16f, e=%.16f\"%(n,x,fx0,x-x0))\n",
    "    while n < limit and abs(fx0) > eps and abs(x-x0) > eps:\n",
    "        n += 1\n",
    "        x0 = x\n",
    "        fx0 = f(x0)\n",
    "        fpx0 = fp(x0)\n",
    "        x = x0-fx0/fpx0\n",
    "        print(\"iteration: %d, x=%.16f, f(x)=%.16f, e=%.16f\"%(n,x,fx0,x-x0))\n",
    "    return x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "simple_newtons_method(f,fp,1,limit=30)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "def sgn(x):\n",
    "    if x > 0:\n",
    "        return 1\n",
    "    elif x < 0:\n",
    "        return -1\n",
    "    else:\n",
    "        return 0\n",
    "    \n",
    "def power_func(a):\n",
    "    return (lambda x: abs(x)**a,lambda x: a*abs(x)**(a-1)*sgn(x))\n",
    "\n",
    "g1,gp1 = power_func(0.25)\n",
    "simple_newtons_method(g1,gp1,1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "g2,gp2 = power_func(0.5)\n",
    "simple_newtons_method(g2,gp2,1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "g3,gp3 = power_func(0.51)\n",
    "simple_newtons_method(g3,gp3,1,limit=10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "g4,gp4 = power_func(2)\n",
    "simple_newtons_method(g4,gp4,1,limit=10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Reiknum $\\frac{1}{\\sqrt{c}}$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "c = 2\n",
    "def h(x):\n",
    "    return x**2-1/c\n",
    "ans = simple_newtons_method(h,lambda x: 2*x,1/c)\n",
    "print(ans - 1/math.sqrt(c))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Sniðilsaðferð\n",
    "\n",
    "Tökum bara inn fallið $f$ og tvo upphafspunkta"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def simple_secant_method(f,x0,x1,limit=20):\n",
    "    n = 0\n",
    "    eps = 1e-15\n",
    "    fx0 = f(x0)\n",
    "    fx1 = f(x1)\n",
    "    x2 = (fx1*x0 - fx0*x1)/(fx1-fx0)\n",
    "    x0 = x1\n",
    "    x1 = x2\n",
    "    fx1 = f(x1)\n",
    "    print(\"iteration: %d, x=%.16f, f(x)=%.16f e=%.16f\"%(n,x1,fx1,x1-x0))\n",
    "    while n < limit and abs(fx1) > eps and abs(x1-x0) > eps:\n",
    "        n += 1\n",
    "        x2 = (fx1*x0 - fx0*x1)/(fx1-fx0)\n",
    "        x0 = x1\n",
    "        fx0 = fx1\n",
    "        x1 = x2\n",
    "        fx1 = f(x2)\n",
    "\n",
    "        print(\"iteration: %d, x=%.16f, f(x)=%.16f e=%.16f\"%(n,x1,fx1,x1-x0))\n",
    "    return x1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "simple_secant_method(f,1,1.5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "simple_secant_method(g1,1,2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Bestun\n",
    "\n",
    "Finnum núllstöðvar $f'(x)$ með vel völdum upphafsgildum og skoðum formerkið á $f''(x)$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "x = np.arange(-1,2,0.01)\n",
    "plt.plot(x,f(x))\n",
    "plt.plot(x,fp(x),color='purple')\n",
    "plt.axhline(color='red')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "def fpp(x):\n",
    "    return 6*x\n",
    "\n",
    "ans = simple_newtons_method(fp,fpp,1)\n",
    "print(fpp(ans))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "ans = simple_newtons_method(fp,fpp,-0.5)\n",
    "print(fpp(ans))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "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.5.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
