{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2-Port Network: 'BFU520_05V0_005mA_NF_SP',  0.4-2.0 GHz, 1001 pts, z0=[ 50.+0.j  50.+0.j]"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "import skrf\n",
    "from skrf.media import DistributedCircuit\n",
    "import skrf.frequency as freq\n",
    "import skrf.network as net\n",
    "import skrf.util\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "plt.rcParams['figure.figsize'] = [10, 10]\n",
    "\n",
    "f = freq.Frequency(0.4, 2, 1001)\n",
    "tem = DistributedCircuit(f, z0=50)\n",
    "\n",
    "bjt = net.Network('BFU520_Spar_NF_400MHz-2GHz/BFU520_05V0_005mA_NF_SP.s2p').interpolate(f)\n",
    "\n",
    "bjt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 143624 characters]\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f67a0085208>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "bjt.plot_s_smith()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(2.8394677846594996, (1.2371751344204285+3.2424616116062022j))"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# calculate the stability circles for the source and load impedances\n",
    "\n",
    "idx_900mhz = skrf.util.find_nearest_index(bjt.f, 915.e+6)\n",
    "\n",
    "sqabs = lambda x: np.square(np.absolute(x))\n",
    "\n",
    "delta = bjt.s11.s*bjt.s22.s - bjt.s12.s*bjt.s21.s\n",
    "rl = np.absolute((bjt.s12.s * bjt.s21.s)/(sqabs(bjt.s22.s) - sqabs(delta)))\n",
    "cl = np.conj(bjt.s22.s - delta*np.conj(bjt.s11.s))/(sqabs(bjt.s22.s) - sqabs(delta))\n",
    "\n",
    "rl_900mhz = rl[idx_900mhz][0, 0]\n",
    "cl_900mhz = cl[idx_900mhz][0, 0]\n",
    "\n",
    "rl_900mhz, cl_900mhz"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 131960 characters]\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f679e47a630>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "def calc_circle(c, r):\n",
    "    theta = np.linspace(0, 2*np.pi, 1000)\n",
    "    return c + r*np.exp(1.0j*theta)\n",
    "\n",
    "def plot_smith(pts):\n",
    "    n = net.Network(s=pts)\n",
    "    n.plot_s_smith()\n",
    "    \n",
    "cl_points = calc_circle(cl_900mhz, rl_900mhz)\n",
    "plot_smith(cl_points)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(3.1199726116705513, (-2.9669977643038008+2.2819464699039518j))"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rs = np.absolute((bjt.s12.s * bjt.s21.s)/(sqabs(bjt.s11.s) - sqabs(delta)))\n",
    "cs = np.conj(bjt.s11.s - delta*np.conj(bjt.s22.s))/(sqabs(bjt.s11.s) - sqabs(delta))\n",
    "\n",
    "rs_900mhz = rs[idx_900mhz][0, 0]\n",
    "cs_900mhz = cs[idx_900mhz][0, 0]\n",
    "\n",
    "rs_900mhz, cs_900mhz"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 133884 characters]\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f679fe7aef0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "cs_points = calc_circle(cs_900mhz, rs_900mhz)\n",
    "plot_smith(cs_points)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 189560 characters]\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f679fe2c400>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# let's plot all of them\n",
    "# output stability first\n",
    "\n",
    "for i, f in enumerate(bjt.f):\n",
    "    # decimate it a little\n",
    "    if i % 100 != 0:\n",
    "        continue\n",
    "    n = net.Network(name=str(f/1.e+9), s=calc_circle(cl[i][0, 0], rl[i][0, 0]))\n",
    "    n.plot_s_smith()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 199156 characters]\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f679ff5a5f8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# input stability\n",
    "for i, f in enumerate(bjt.f):\n",
    "    if i % 100 != 0:\n",
    "        continue\n",
    "    n = net.Network(name=str(f/1.e+9), s=calc_circle(cs[i][0, 0], rs[i][0, 0]))\n",
    "    n.plot_s_smith()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "the optimum source reflection coefficient is  (0.0983297857508+0.147483438082j)\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 166840 characters]\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f679e470c88>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# let's draw some constant noise circles\n",
    "# first we grab the noise parameters for our target frequency from the network model\n",
    "idx_915mhz = skrf.util.find_nearest_index(bjt.f, 915.e+6)\n",
    "\n",
    "# we need the normalized equivalent noise and optimum source coefficient to calculate the constant noise circles\n",
    "rn = bjt.rn[idx_915mhz]/50\n",
    "gamma_opt = bjt.g_opt[idx_915mhz]\n",
    "fmin = bjt.nfmin[idx_915mhz]\n",
    "\n",
    "for nf_added in [0, 0.05, 0.1, 0.2, 0.3]:\n",
    "    nf = 10**(nf_added/10) * fmin\n",
    "    \n",
    "    N = (nf - fmin)*abs(1+gamma_opt)**2/(4*rn)\n",
    "    c_n = gamma_opt/(1+N)\n",
    "    r_n = 1/(1-N)*np.sqrt(N**2 + N*(1-abs(gamma_opt)**2))\n",
    "    \n",
    "    n = net.Network(name=str(nf_added), s=calc_circle(c_n, r_n))\n",
    "    n.plot_s_smith()\n",
    "\n",
    "print(\"the optimum source reflection coefficient is \", gamma_opt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(0.098329785750829277+0.14748343808162145j)"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gamma_s = bjt.g_opt[idx_900mhz]\n",
    "gamma_s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((0.42267113183938537+0.4147830810062007j), True)"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# so I need to calculate the load reflection coefficient to get a conjugate match when the input sees 50 ohms\n",
    "gamma_l = np.conj(bjt.s22.s - bjt.s21.s*gamma_s*bjt.s12.s/(1-bjt.s11.s*gamma_s))\n",
    "is_gamma_l_stable = np.absolute(gamma_l[idx_900mhz, 0, 0] - cl_900mhz) > rl_900mhz\n",
    "\n",
    "gamma_l = gamma_l[idx_900mhz, 0, 0]\n",
    "gamma_l, is_gamma_l_stable"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((64.242549793673973+82.077788585900919j),\n",
       " -636.2306653569593j,\n",
       " 77.17093294453807j)"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def calc_matching_network_vals(z1, z2):\n",
    "    flipped = ((abs(np.imag(z2)) < 1e-6 and np.real(z1) < np.real(z2)) or\n",
    "            (abs(np.imag(z2)) > 1e-6 and np.real(z1) < np.real(1/(1/z2-1/(1.j*np.imag(z2))))))\n",
    "    if flipped:\n",
    "        z2, z1 = z1, z2\n",
    "        \n",
    "    # cancel out the imaginary parts of both input and output impedances    \n",
    "    z1_par = 1e+10\n",
    "    if abs(np.imag(z1)) > 1e-6:\n",
    "        # parallel something to cancel out the imaginary part of\n",
    "        # z1's impedance\n",
    "        z1_par = 1/(-1j*np.imag(1/z1))\n",
    "        z1 = 1/(1./z1 + 1/z1_par)\n",
    "    z2_ser = 0.0\n",
    "    if abs(np.imag(z2)) > 1e-6:\n",
    "        z2_ser = -1j*np.imag(z2)\n",
    "        z2 = z2 + z2_ser\n",
    "        \n",
    "    Q = np.sqrt((np.real(z1) - np.real(z2))/np.real(z2))\n",
    "    x1 = -1.j * np.real(z1)/Q\n",
    "    x2 = 1.j * np.real(z2)*Q\n",
    "    \n",
    "    x1_tot = 1/(1/z1_par + 1/x1)\n",
    "    x2_tot = z2_ser + x2\n",
    "    if flipped:\n",
    "        return x2_tot, x1_tot\n",
    "    else:\n",
    "        return x1_tot, x2_tot\n",
    "\n",
    "z_l = net.s2z(np.array([[[gamma_l]]]))[0,0,0]\n",
    "# note that we're matching against the conjugate;\n",
    "# this is because we want to see z_l from the BJT side\n",
    "# if we plugged in z the matching network would make\n",
    "# the 50 ohms look like np.conj(z) to match against it, so\n",
    "# we use np.conj(z_l) so that it'll look like z_l from the BJT's side\n",
    "z_par, z_ser = calc_matching_network_vals(np.conj(z_l), 50)\n",
    "z_l, z_par, z_ser"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(2.7339114253184115e-13, 1.3423098842772051e-08)"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# let's calculate what the component values are\n",
    "c_par = np.real(1/(2j*np.pi*915e+6*z_par))\n",
    "l_ser = np.real(z_ser/(2j*np.pi*915e+6))\n",
    "\n",
    "c_par, l_ser"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 144020 characters]\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f679ff807b8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# the capacitance is kind of low but the inductance seems reasonable\n",
    "# let's test it out\n",
    "\n",
    "output_network = tem.inductor(l_ser) ** tem.shunt_capacitor(c_par)\n",
    "\n",
    "amplifier = tem.inductor(1.3e-9) ** bjt ** output_network\n",
    "\n",
    "amplifier.plot_s_smith()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.78454633962737463"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 28700 characters]\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f679e3a9588>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "amplifier.s11.plot_s_db()\n",
    "amplifier.s22.plot_s_db()\n",
    "10*np.log10(amplifier.nf(50.)[idx_900mhz])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 27920 characters]\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f679e2a3e10>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "amplifier.s21.plot_s_db()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x7f679ff8f940>]"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 23776 characters]\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f679e5819b0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# that's probably good enough for the first stage\n",
    "# for the second stage let's stabilize the transistor by adding some parallel resistance\n",
    "# and then simultaneous conjugate matching so that both the input and output are matched to 50 ohms\n",
    "\n",
    "# let's calculate the stability factor to see where it's unstable\n",
    "sqabs = lambda x: np.square(np.absolute(x))\n",
    "delta = bjt.s11.s*bjt.s22.s - bjt.s12.s*bjt.s21.s\n",
    "K = ((1 - sqabs(bjt.s11.s) - sqabs(bjt.s22.s) + sqabs(delta))/(2*np.absolute(bjt.s12.s*bjt.s21.s)))[:,0,0]\n",
    "\n",
    "plt.plot(bjt.f, K)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 142716 characters]\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f67a0085240>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#so it's basically always unstable\n",
    "#let's add a 250 ohm shunt to the output and see how much that improves it\n",
    "\n",
    "bjt_comp = bjt ** tem.shunt(tem.resistor(75.) ** tem.short())\n",
    "bjt_comp.plot_s_smith()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x7f679e4daf28>]"
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 23176 characters]\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f679e3daf98>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# let's calculate K again\n",
    "delta2 = bjt_comp.s11.s*bjt_comp.s22.s - bjt_comp.s12.s*bjt_comp.s21.s\n",
    "K2 = ((1 - sqabs(bjt_comp.s11.s) - sqabs(bjt_comp.s22.s) + sqabs(delta2))/(2*np.absolute(bjt_comp.s12.s*bjt_comp.s21.s)))[:,0,0]\n",
    "\n",
    "plt.plot(bjt_comp.f, K2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x7f679e30ccf8>]"
      ]
     },
     "execution_count": 70,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 31688 characters]\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f679e494518>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# that's a pretty nice improvement! let's check the delta to be sure, and\n",
    "# find the new source stability circles to see if we need to add some series resistance there\n",
    "\n",
    "# K > 1 and |delta| < 1 for stability\n",
    "plt.plot(bjt_comp.f, np.absolute(delta2[:,0,0]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 149804 characters]\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f679e20a400>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "rs2 = np.absolute((bjt_comp.s12.s * bjt_comp.s21.s)/(sqabs(bjt_comp.s11.s) - sqabs(delta2)))\n",
    "cs2 = np.conj(bjt_comp.s11.s - delta2*np.conj(bjt_comp.s22.s))/(sqabs(bjt_comp.s11.s) - sqabs(delta2))\n",
    "\n",
    "# input stability\n",
    "for i, f in enumerate(bjt_comp.f):\n",
    "    if i % 100 != 0:\n",
    "        continue\n",
    "    n = net.Network(name=str(f/1.e+9), s=calc_circle(cs2[i][0, 0], rs2[i][0, 0]))\n",
    "    n.plot_s_smith()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((14.453769011425337+31.967494868137187j),\n",
       " (28.41148437701095+33.098424068469981j))"
      ]
     },
     "execution_count": 72,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# that doesn't look too bad, so let's move forward and try to conjugate match\n",
    "delta2 = bjt_comp.s11.s*bjt_comp.s22.s - bjt_comp.s12.s*bjt_comp.s21.s\n",
    "\n",
    "B1 = 1 + sqabs(bjt_comp.s11.s) - sqabs(bjt_comp.s22.s) - sqabs(delta2)\n",
    "B2 = 1 + sqabs(bjt_comp.s22.s) - sqabs(bjt_comp.s11.s) - sqabs(delta2)\n",
    "C1 = bjt_comp.s11.s - delta2*np.conj(bjt_comp.s22.s)\n",
    "C2 = bjt_comp.s22.s - delta2*np.conj(bjt_comp.s11.s)\n",
    "\n",
    "gamma_s_all = (B1 - np.sqrt(np.square(B1) - 4*sqabs(C1) + 0j))/(2*C1)\n",
    "gamma_l_all = (B2 - np.sqrt(np.square(B2) - 4*sqabs(C2) + 0j))/(2*C2)\n",
    "\n",
    "gamma_s = gamma_s_all[idx_900mhz, 0, 0]\n",
    "gamma_l = gamma_l_all[idx_900mhz, 0, 0]\n",
    "\n",
    "z_s = net.s2z(np.array([[[gamma_s]]]))[0,0,0]\n",
    "z_l = net.s2z(np.array([[[gamma_l]]]))[0,0,0]\n",
    "\n",
    "# this section broke when I switched to a lower bias current so just ignore this\n",
    "z_s, z_l"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(54.634144641220715j,\n",
       " (1.0165472266293926e-07-31.88333775860665j),\n",
       " 57.8645657612208j,\n",
       " (3.290115549532768e-07-57.35952884685131j))"
      ]
     },
     "execution_count": 73,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x_s_1, x_s_2 = calc_matching_network_vals(np.conj(z_s), 50)\n",
    "x_l_1, x_l_2 = calc_matching_network_vals(np.conj(z_l), 50)\n",
    "\n",
    "x_s_1, x_s_2, x_l_1, x_l_2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(5.4555087623716236e-12,\n",
       " 9.503053749997663e-09,\n",
       " 3.032448697062142e-12,\n",
       " 1.0064952645644079e-08)"
      ]
     },
     "execution_count": 75,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "c_s_shunt = np.real(1/(2j*np.pi*915e+6*x_s_1))\n",
    "c_s_ser = np.real(1/(2j*np.pi*915e+6*x_s_2))\n",
    "l_s_ser = np.real(x_s_2/(2j*np.pi*915e+6))\n",
    "c_l_shunt = np.real(1/(2j*np.pi*915e+6*x_l_1))\n",
    "l_l_ser = np.real(x_l_2/(2j*np.pi*915e+6))\n",
    "\n",
    "c_s_shunt2 = np.real(1/(2j*np.pi*915e+6*x_s_2))\n",
    "l_s_ser2 = np.real(x_s_1/(2j*np.pi*915e+6))\n",
    "\n",
    "c_l_shunt2 = np.real(1/(2j*np.pi*915e+6*x_l_2))\n",
    "l_l_ser2 = np.real(x_l_1/(2j*np.pi*915e+6))\n",
    "\n",
    "#c_s_shunt, c_s_ser, c_l_shunt, l_l_ser\n",
    "c_s_shunt2, l_s_ser2, c_l_shunt2, l_l_ser2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 152052 characters]\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f679e0f6cc0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#input_network2 = tem.capacitor(c_s_ser) ** tem.shunt_capacitor(c_s_shunt)\n",
    "#input_network2 = tem.inductor(l_s_ser) ** tem.shunt_capacitor(c_s_shunt)\n",
    "input_network2 = tem.shunt_capacitor(c_s_shunt2) ** tem.inductor(l_s_ser2)\n",
    "\n",
    "#output_network2 = tem.shunt_capacitor(c_l_shunt) ** tem.inductor(l_l_ser)\n",
    "output_network2 = tem.inductor(l_l_ser2) ** tem.shunt_capacitor(c_l_shunt2)\n",
    "\n",
    "amplifier2 = input_network2 ** bjt_comp ** output_network2\n",
    "#amplifier2 = input_network2 ** bjt #** output_network2\n",
    "\n",
    "amplifier2.plot_s_smith()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 26884 characters]\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f679fe7a470>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "amplifier2.s21.plot_s_db()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 24708 characters]\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f679e2faa58>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "amplifier2.s11.plot_s_db()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 25132 characters]\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f679e0ccc50>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "amplifier2.s22.plot_s_db()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.5225393220600005"
      ]
     },
     "execution_count": 80,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "10*np.log10(amplifier2.nf(50.)[idx_900mhz])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x7f679e056208>]"
      ]
     },
     "execution_count": 81,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 23176 characters]\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f679e118518>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# check stability again\n",
    "delta2 = amplifier2.s11.s*amplifier2.s22.s - amplifier2.s12.s*amplifier2.s21.s\n",
    "K2 = ((1 - sqabs(amplifier2.s11.s) - sqabs(amplifier2.s22.s) + sqabs(delta2))/(2*np.absolute(amplifier2.s12.s*amplifier2.s21.s)))[:,0,0]\n",
    "\n",
    "plt.plot(amplifier2.f, K2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((16.211209907925852+25.548553377005881j),\n",
       " (31.935019262196562+53.460553910461819j))"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 133104 characters]\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f67a00af2e8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# of course, it matches the other one since all we did was transform the impedances at the input and output\n",
    "# let's try again with 10 ohms of resistance in series with the base to stabilize that side\n",
    "\n",
    "bjt_comp2 = tem.resistor(10) ** bjt_comp\n",
    "\n",
    "delta3 = bjt_comp2.s11.s*bjt_comp2.s22.s - bjt_comp2.s12.s*bjt_comp2.s21.s\n",
    "\n",
    "B1 = 1 + sqabs(bjt_comp2.s11.s) - sqabs(bjt_comp2.s22.s) - sqabs(delta3)\n",
    "B2 = 1 + sqabs(bjt_comp2.s22.s) - sqabs(bjt_comp2.s11.s) - sqabs(delta3)\n",
    "C1 = bjt_comp2.s11.s - delta3*np.conj(bjt_comp2.s22.s)\n",
    "C2 = bjt_comp2.s22.s - delta3*np.conj(bjt_comp2.s11.s)\n",
    "\n",
    "gamma_s_all = (B1 - np.sqrt(np.square(B1) - 4*sqabs(C1) + 0j))/(2*C1)\n",
    "gamma_l_all = (B2 - np.sqrt(np.square(B2) - 4*sqabs(C2) + 0j))/(2*C2)\n",
    "\n",
    "gamma_s = gamma_s_all[idx_900mhz, 0, 0]\n",
    "gamma_l = gamma_l_all[idx_900mhz, 0, 0]\n",
    "\n",
    "z_s = net.s2z(np.array([[[gamma_s]]]))[0,0,0]\n",
    "z_l = net.s2z(np.array([[[gamma_l]]]))[0,0,0]\n",
    "\n",
    "bjt_comp2.plot_s_smith()\n",
    "z_s, z_l"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 135116 characters]\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f679ff3dba8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "n = net.Network(name=\"g_ms\", s=gamma_s_all)\n",
    "n.plot_s_smith()\n",
    "n = net.Network(name=\"g_ml\", s=gamma_l_all)\n",
    "n.plot_s_smith()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x7f679fec5cf8>]"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 23052 characters]\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f679e2fde10>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "K3 = ((1 - sqabs(bjt_comp2.s11.s) - sqabs(bjt_comp2.s22.s) + sqabs(delta3))/(2*np.absolute(bjt_comp2.s12.s*bjt_comp2.s21.s)))[:,0,0]\n",
    "\n",
    "plt.plot(bjt_comp2.f, K3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(48.95276600459623j,\n",
       " (1.1994517903534313e-07-34.63310252278059j),\n",
       " 77.47941124866512j,\n",
       " (4.419464892559804e-07-66.47905604444007j))"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x_s_1, x_s_2 = calc_matching_network_vals(np.conj(z_s), 50)\n",
    "x_l_1, x_l_2 = calc_matching_network_vals(np.conj(z_l), 50)\n",
    "\n",
    "x_s_1, x_s_2, x_l_1, x_l_2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(5.022357682258479e-12,\n",
       " 8.514835724210252e-09,\n",
       " 2.616460564654482e-12,\n",
       " 1.3476755506092735e-08)"
      ]
     },
     "execution_count": 57,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "c_s_shunt = np.real(1/(2j*np.pi*915e+6*x_s_2))\n",
    "l_s_ser = np.real(x_s_1/(2j*np.pi*915e+6))\n",
    "\n",
    "l_l_ser = np.real(x_l_1/(2j*np.pi*915e+6))\n",
    "c_l_shunt = np.real(1/(2j*np.pi*915e+6*x_l_2))\n",
    "\n",
    "#c_s_shunt, c_s_ser, c_l_shunt, l_l_ser\n",
    "c_s_shunt, l_s_ser, c_l_shunt, l_l_ser"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 152604 characters]\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f679e55f208>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "input_network3 = tem.shunt_capacitor(c_s_shunt) ** tem.inductor(l_s_ser)\n",
    "output_network3 = tem.inductor(l_l_ser) ** tem.shunt_capacitor(c_l_shunt)\n",
    "\n",
    "amplifier3 = input_network3 ** tem.resistor(10.) ** bjt_comp ** output_network3\n",
    "\n",
    "amplifier3.plot_s_smith()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 26580 characters]\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f679fec3198>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "amplifier3.s21.plot_s_db()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.5079267817918054"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "10*np.log10(amplifier3.nf(50.)[idx_900mhz])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 33288 characters]\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f679e22a390>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "amplifier3.s11.plot_s_db()\n",
    "amplifier3.s22.plot_s_db()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 160320 characters]\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f679fec0e10>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# let's see how it works cascaded\n",
    "\n",
    "cascaded = amplifier3 ** amplifier3\n",
    "cascaded.plot_s_smith()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 27072 characters]\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f679e3d15f8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "cascaded.s21.plot_s_db()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.533262687029886"
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 33356 characters]\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f679e2db630>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "cascaded.s11.plot_s_db()\n",
    "cascaded.s22.plot_s_db()\n",
    "10*np.log10(cascaded.nf(50.)[idx_900mhz])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "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.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
