{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "eaa65a42-a9a7-4420-acb7-4fee6610fa5b",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import sympy as sm \n",
    "import matplotlib.pyplot as plt\n",
    "from scipy.integrate import odeint"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a78f18ca-7b95-4f82-b501-ef9f402ecbc7",
   "metadata": {},
   "source": [
    "Dane Sabo\n",
    "October 2nd, 2024\n",
    "\n",
    "# Problem 3.7.2 (Written)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "0af0982d-25ae-4a1d-82d3-262935ab1d81",
   "metadata": {},
   "outputs": [],
   "source": [
    "def linear_phase_portrait_info(A):\n",
    "    print('\\n Input Matrix:')\n",
    "    print(A)\n",
    "    \n",
    "    print('\\n Eigenvalues and Eigenvectors:')\n",
    "    print(np.linalg.eig(A).eigenvalues)\n",
    "    print(np.linalg.eig(A).eigenvectors)\n",
    "    \n",
    "    print('\\n Trace:')\n",
    "    print(np.linalg.trace(A))\n",
    "\n",
    "    print('\\n Determinant:')\n",
    "    print(np.linalg.det(A))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bafdbc61-fba6-490b-8793-6b1820d6fbd4",
   "metadata": {},
   "source": [
    "Sketch phase portraits for the following linear systems:\n",
    "## $\\dot x = 0$, $\\dot y = x + 2y$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "37b37e65-7ade-473e-82ff-6391c6c6fe1d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      " Input Matrix:\n",
      "[[0 0]\n",
      " [1 2]]\n",
      "\n",
      " Eigenvalues and Eigenvectors:\n",
      "[2. 0.]\n",
      "[[ 0.          0.89442719]\n",
      " [ 1.         -0.4472136 ]]\n",
      "\n",
      " Trace:\n",
      "2\n",
      "\n",
      " Determinant:\n",
      "0.0\n"
     ]
    }
   ],
   "source": [
    "A = np.array([[0,0],[1,2]])\n",
    "linear_phase_portrait_info(A)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "966ca5a8-bcf4-4860-b923-f5cca9f6e1de",
   "metadata": {},
   "source": [
    "## $\\dot x = x+2y$, $\\dot y = 0$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "6e05a8d7-7bf6-4520-a3b6-0848d067b189",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      " Input Matrix:\n",
      "[[1 2]\n",
      " [0 0]]\n",
      "\n",
      " Eigenvalues and Eigenvectors:\n",
      "[1. 0.]\n",
      "[[ 1.         -0.89442719]\n",
      " [ 0.          0.4472136 ]]\n",
      "\n",
      " Trace:\n",
      "1\n",
      "\n",
      " Determinant:\n",
      "0.0\n"
     ]
    }
   ],
   "source": [
    "A = np.array([[1,2],[0,0]])\n",
    "linear_phase_portrait_info(A)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0179406c-daa5-47bf-a10f-126f1ffe92c4",
   "metadata": {},
   "source": [
    "## $\\dot x = 3x+4y$, $\\dot y = 4x - 3y$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "0c198580-fd00-43d8-aeb7-947c88f449c0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      " Input Matrix:\n",
      "[[ 3  4]\n",
      " [ 4 -3]]\n",
      "\n",
      " Eigenvalues and Eigenvectors:\n",
      "[ 5. -5.]\n",
      "[[ 0.89442719 -0.4472136 ]\n",
      " [ 0.4472136   0.89442719]]\n",
      "\n",
      " Trace:\n",
      "0\n",
      "\n",
      " Determinant:\n",
      "-25.000000000000007\n"
     ]
    }
   ],
   "source": [
    "A = np.array([[3,4],[4,-3]])\n",
    "linear_phase_portrait_info(A)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a41e8548-555b-4701-bad7-9049cb395dec",
   "metadata": {},
   "source": [
    "## $\\dot x = 3x+y$, $\\dot y = -x + 3y$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "40cd3d5a-a712-4fab-94bb-8148d2fd61ad",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      " Input Matrix:\n",
      "[[ 3  1]\n",
      " [-1  3]]\n",
      "\n",
      " Eigenvalues and Eigenvectors:\n",
      "[3.+1.j 3.-1.j]\n",
      "[[0.70710678+0.j         0.70710678-0.j        ]\n",
      " [0.        +0.70710678j 0.        -0.70710678j]]\n",
      "\n",
      " Trace:\n",
      "6\n",
      "\n",
      " Determinant:\n",
      "10.000000000000002\n"
     ]
    }
   ],
   "source": [
    "A = np.array([[3,1],[-1,3]])\n",
    "linear_phase_portrait_info(A)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0b285873-d263-4b48-b792-a8ac6a1e48b3",
   "metadata": {},
   "source": [
    "# Problem 3.7.4 (Python)\n",
    "Plot the phase portraits for the following systems:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "34f3f9f8-8c8c-4e08-aad4-e019b8f992d6",
   "metadata": {},
   "outputs": [],
   "source": [
    "def phase_portrait(P, Q, ts = [1], ic = [1]):\n",
    "    #Create symbolic variables\n",
    "    x, y = sm.symbols('x,y')\n",
    "\n",
    "    #def differential equation\n",
    "    def dX_dt(X,t, args = (P,Q)):\n",
    "        return [P(X[0],X[1]), Q(X[0],X[1])]\n",
    "    \n",
    "    #Set P(x,y) = 0 and Q(x,y) = 0\n",
    "    Peqn = sm.Eq(P(x,y),0)\n",
    "    Qeqn = sm.Eq(Q(x,y),0)\n",
    "\n",
    "    #solve our equations for populations of species of x and y\n",
    "    criticalpoints = sm.solve((Peqn,Qeqn),x,y)\n",
    "    print('Critical Points:')\n",
    "    print(criticalpoints)\n",
    "\n",
    "    #Set up Time and Initial Condition Domains\n",
    "    ts = np.linspace(0,-1,10) if ts[0] == 1 else ts\n",
    "    ic = np.linspace(-4, 4, 10) if ic[0] == 1 else ic\n",
    "    \n",
    "    #calculate a vectorfield\n",
    "    X,Y = np.mgrid[ic[0]:ic[-1]:20j,ic[0]:ic[-1]:20j]\n",
    "    u = P(X,Y)\n",
    "    v = Q(X,Y)\n",
    "    \n",
    "    \n",
    "    \n",
    "    #we can color our critical points algorithmically\n",
    "    plt.quiver(X,Y,u,v,color = \"red\")\n",
    "   \n",
    "    #plot trajectories\n",
    "    plt.title(f'Phase Portrait for $\\\\dot x = $ {Peqn.lhs} and $\\\\dot y = $ {Qeqn.lhs}')\n",
    "    plt.xlabel('x'); plt.ylabel('y'); plt.grid('both')\n",
    "    plt.xlim((ic[0],ic[-1])); plt.ylim((ic[0],ic[-1]))\n",
    "    \n",
    "    for r in ic:\n",
    "        for s in ic:\n",
    "            X0 = [r,s]\n",
    "            Xs = odeint(dX_dt,X0,ts)\n",
    "            plt.plot(Xs[:,0],Xs[:,1], \"royalblue\",linewidth = 0.75)\n",
    "\n",
    "    for i in range(np.size(criticalpoints)//2):\n",
    "        #Do NOT print imaginary critical points\n",
    "        if sm.im(criticalpoints[i][0]) == 0 and sm.im(criticalpoints[i][1]) == 0:\n",
    "            \n",
    "            plt.plot(criticalpoints[i][0],criticalpoints[i][1],\"yo\")\n",
    "            "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1b9e78d5-bf56-46af-b672-35290d33b788",
   "metadata": {},
   "source": [
    "## $\\dot x = y$, $\\dot y = x-y+x^3$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "21643903-10a1-47ca-b449-4dcb6a4819e7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Critical Points:\n",
      "[(0, 0), (-I, 0), (I, 0)]\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 198108 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "P = lambda x, y: y\n",
    "Q = lambda x, y: x - y + x**3\n",
    "phase_portrait(P, Q, ic = np.linspace(-1, 1, 10))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c6c01322-669f-4bd4-8727-addd978c85e2",
   "metadata": {},
   "source": [
    "## $\\dot x = -2x-y+2$, $\\dot y = xy$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "cd100989-95c4-4d6e-87a2-23468c3e7d30",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Critical Points:\n",
      "[(0, 2), (1, 0)]\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 128820 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "P = lambda x, y: -2*x - y + 2\n",
    "Q = lambda x, y: x*y \n",
    "phase_portrait(P, Q, ts = np.linspace(0,0.1,10))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "91f924f6-1567-47c9-893a-93cbf5753b98",
   "metadata": {},
   "source": [
    "## $\\dot x = x^2- y^2$, $\\dot y = xy-1$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "d9c0e844-0458-4025-87a6-2b7f0332e8f5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Critical Points:\n",
      "[(-1, -1), (1, 1), (-I, I), (I, -I)]\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 151684 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "P = lambda x, y: x**2 - y**2\n",
    "Q = lambda x, y: x*y - 1\n",
    "phase_portrait(P, Q, ts = np.linspace(0,0.2,10))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "312d3ea7-a2c1-4db3-9aef-d4882adba1f3",
   "metadata": {},
   "source": [
    "## $\\dot x = 2-x-y^2$, $\\dot y = -y(x^2 + y^2 -3x +1)$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "cfb3f6a8-fcf2-4669-a566-21ceea20b5ca",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Critical Points:\n",
      "[(1, -1), (1, 1), (2, 0), (3, -I), (3, I)]\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 143696 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "P = lambda x, y: 2 - x - y**2\n",
    "Q = lambda x, y: -y*(x**2 + y**2 - 3*x +1)\n",
    "phase_portrait(P, Q, ic = np.linspace(-2.5, 2.5, 10), ts = np.linspace(0,0.2,10))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "12ad95a7-06dd-45b9-8d48-4a7e0451422e",
   "metadata": {},
   "source": [
    "# Problem 3.7.5 (Written)\n",
    "Construct a nonlinear system that has four critical points: two saddle points, one stable focus, and one unstable focus."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "c9952ccd-c6f1-48e4-b017-901cbcbda30f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Critical Points:\n",
      "[(-1, -1), (-1, 1), (1, -1), (1, 1)]\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 593052 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "P = lambda x, y: y**2 - x**2\n",
    "Q = lambda x, y: x**2 + y**2 - 2\n",
    "phase_portrait(P, Q, ic = np.linspace(-5, 5, 50), ts = np.linspace(0,0.1,10))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cf8225d4-cedb-4daa-a7b0-ef9b032c4c92",
   "metadata": {},
   "source": [
    "# Problem 3.7.6 (Written)\n",
    "A nonlinear capacitor-resistor electrical circuit can be modeled using the differential equations\n",
    "$$ \\dot x = y $$\n",
    "$$\\dot y = -x + x^3 - (a_0 + x)y$$\n",
    "where $a_0$ is a nonzero constant and $x(t)$ represents the current in the circuit at time t. Sketch phase portraits when $a_0 > 0$ and $a_0<0$ and give a physical interpretation of the results."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "737e53cb-5f98-42b4-9ca5-696cc03cc724",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "66d21987-bc58-4f31-af7b-94bcaf967921",
   "metadata": {},
   "source": [
    "# Problem 4.5.6 (Python)\n",
    "A predator-prey system may be modeled using the differential equations\n",
    "$$ \\dot x = x (1-y-\\epsilon x)$$\n",
    "$$ \\dot y = y (-1 + x - \\epsilon y)$$\n",
    "where $x(t)$ is the population of prey and $y(t)$ is the predator population size at time t, respectively. Classify the critical points for $\\epsilon>0$ and plot phase portraits for the different types of qualitative behavior. Interpret the results in physical terms"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.12.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
