In [1]:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
from matplotlib.animation import FuncAnimation
from matplotlib import rcParams
from IPython.display import HTML

from matplotlib.ticker import EngFormatter

plt.style.use('seaborn-poster')
rcParams['font.size'] = 18

#plt.ion()
In [2]:
fT = 10e6
Av0 = 100e3
fH0 = fT / Av0

f = np.logspace(1, 8, 1000)

def Amag(f, beta_inv):
    A = Av0 / (1 + 1j*f/fH0)
    Av = A / (1 + A/beta_inv)
    return abs(Av)
In [3]:
def nstages(G):
    fig, ax = plt.subplots(figsize=(10,7))
    ax.set(xlim=(min(f)/2, max(f)*2),
           ylim=(0.1, Av0),
           xlabel='Hz',
           ylabel='V / V',
           title='Frequency response of N stages for\nfixed system gain = %.0f' % G)
    
    ax.loglog(f, Amag(f, 1e6), '-k')
    ax.hlines(1, min(f), max(f), linewidth=1)

    ax.grid(True, linewidth=0.8)

    formatter1 = EngFormatter(places=0)
    ax.xaxis.set_major_formatter(formatter1)
    ax.yaxis.set_major_formatter(formatter1)

    # first line
    line = ax.plot(f, Amag(f, G), color='b', lw=2)[0]
    N_text = ax.text(2*fT/G, 2*G, 'N = 1', size='xx-large')
    g_text = ax.text(0.01*fT/G, 0.7*G, 'g = %i'%G, size='large', va='top')

    def amp(frame):
        n = frame + 1
        g = G**(1.0/n)
        a = Amag(f, g)**n
        line.set_ydata(a)
        N_text.set_text('N = %i' % n)
        g_text.set_text('g = %.1f' % g)
        return (line,)

    anim = FuncAnimation(fig, amp, interval=500, frames=7, repeat=True)
    return anim
In [4]:
HTML(nstages(10).to_html5_video())
Out[4]:
In [5]:
HTML(nstages(100).to_html5_video())
Out[5]:
In [6]:
HTML(nstages(1000).to_html5_video())
Out[6]:
In [7]:
HTML(nstages(10000).to_html5_video())
Out[7]:
In [8]:
#
# TODO: this is just for a fixed system gain A
# plot for a series of system gains


# -3dB frequency vs. N stages for fixed system gain A and individual stage GBW

def f3(N, A, fT):
    g = A**(1.0/N)
    return (fT/g) * np.sqrt(2**(1.0/N)-1)

n = np.arange(1, 16)

A = 100
fT = 10e6

bw = f3(n, A, fT)/(fT/A)


plt.close('all')
fig, ax = plt.subplots()

ax.plot(n, bw, 'o')
ax.set(xticks=n, xlim=(0, n[-1]+1))

yt = np.around(bw, 1)
ax.set(yticks=bw[(0, 1, 2, 3, 4, 5, 8),])

formatter1 = EngFormatter(places=1)
ax.yaxis.set_major_formatter(formatter1)

ax.plot((0, 9), (bw[8], bw[8]), 'k', linewidth=1)

ax.set(
    title='Bandwidth increase using N stages\nwith system gain = %.0f' % A,
    xlabel='N stages',
    ylabel='$BW_N \, / \, BW_1$')

ax.text(9, (f3(9, A, fT)*A/fT - 0.5), '9', va='top', ha='center')

plt.show()
In [12]:
def plot_closedloop():
    fig, ax = plt.subplots(figsize=(10,7))
    ax.set(xlim=(min(f)/2, max(f)*2),
           ylim=(0.1, 2*Av0),
           ylabel='gain (V/V)',
           xlabel='Hz',
           title=r'Closed-loop gain and $1/\beta$ gain prediction')
    
    # open-loop amplifier, set 1/beta ~0
    ax.loglog(f, Amag(f, 1e9), '-k')
    ax.hlines(1, min(f), max(f), linewidth=1)

    ax.grid(True, linewidth=0.8)

    formatter1 = EngFormatter(places=0)
    ax.xaxis.set_major_formatter(formatter1)
    ax.yaxis.set_major_formatter(formatter1)
    
    # line and text
    bi = 1e9
    line_beta = ax.plot((f[0], f[-1]), [bi, bi], 'r')
    line_a = ax.plot(f, Amag(f, bi), color='b', lw=2)[0]
    
    A_text = ax.text(0.5*fT/bi, 0.7*Amag(0.5*fT/bi, bi), '$|A|$', size='large', color='b', va='top')
    beta_text = ax.text(7*fT/bi, 0.7*bi, r'$1 / \beta', size='large', color='r', va='top')

    bis = [1, 2, 5, 10, 20, 50, 100, 200, 500, 1e3, 2e3, 5e3, 10e3, 20e3, 50e3, 100e3]
    bis = [1, 10, 100, 1e3, 3e3, 10e3, 20e3, 50e3, 80e3, 100e3]
    #bis = np.logspace(0, np.log10(Av0), 20)
    bis = np.concatenate((bis, np.flip(bis,0)))

    def amp(frame):
        bi = bis[frame]
        a = Amag(f, bi)
        line_beta[0].set_ydata([bi, bi])
        line_a.set_ydata(a)
        
        A_text.set_position((0.5*fT/bi, 0.7*Amag(0.5*fT/bi, bi)))
        beta_text.set_position((7*fT/bi, 0.7*bi))
        beta_text.set_text(r'$1 / \beta$')
        
    
        return (line_a,)

    anim = FuncAnimation(fig, amp, interval=500, frames=len(bis), repeat=True, blit=True)
    return anim

HTML(plot_closedloop().to_html5_video())
Out[12]:
In [ ]: