codex/voltage-and-power-gain-loading.py

voltage-and-power-gain-loading.py
"""Original resistive Thévenin amplifier model: loaded voltage and power gain."""
from pathlib import Path

import matplotlib.pyplot as plt
import numpy as np


def main():
    open_gain, output_resistance, input_resistance = .6, 10., 10_000.
    load = np.logspace(0, 4, 801)
    voltage_gain = open_gain*load/(output_resistance+load)
    power_gain = voltage_gain**2*input_resistance/load
    assert np.isclose(voltage_gain[np.argmin(abs(load-50))], .5, rtol=.002)
    assert np.isclose(power_gain.max(), 90.)
    assert np.isclose(load[np.argmax(power_gain)], output_resistance)
    assert np.isclose(open_gain*50/(output_resistance+50), .5)
    assert np.isclose(.5**2*input_resistance/50, 50.)
    assert np.isclose((1/(30+40j)).real/(1/50), .6)
    assert np.isclose(20*np.log10(.5), -6.020599913279624)
    assert np.isclose(10*np.log10(50), 16.989700043360187)
    assert np.isclose((1e6/(50+1e6))**2/1e6, .9999000074995e-6)
    fig, (voltage, power) = plt.subplots(1, 2, figsize=(9.4, 4.2), dpi=100,
                                       layout="constrained")
    fig.set_facecolor("white")
    voltage.semilogx(load, voltage_gain, color="#155da0", lw=2)
    voltage.axhline(open_gain, color="#777777", ls="--", lw=1,
                    label="Open-circuit voltage gain = 0.6")
    power.semilogx(load, power_gain, color="#155da0", lw=2)
    for resistance, color in [(10., "#b84c13"), (50., "#4b812c")]:
        av = open_gain*resistance/(output_resistance+resistance)
        gp = av**2*input_resistance/resistance
        voltage.scatter(resistance, av, color=color, zorder=4,
                        label=f"{resistance:g} Ω load: voltage gain {av:g}")
        power.scatter(resistance, gp, color=color, zorder=4,
                      label=f"{resistance:g} Ω load: power gain {gp:g}")
    voltage.set(title="Higher load resistance preserves voltage",
                ylabel="Loaded voltage gain |Aᵥ|", ylim=(0, .67))
    power.set(title="Power transfer peaks at a finite load",
              ylabel="Power gain Gₚ", ylim=(0, 105))
    for ax in [voltage, power]:
        ax.set(xlabel="Load resistance Rₗ (Ω)", xlim=(1, 1e4))
        ax.grid(alpha=.18, which="both")
        ax.legend(loc="lower right" if ax is voltage else "upper right", fontsize=8)
    fig.savefig(Path(__file__).with_suffix(".png").name, facecolor="white")
    plt.close(fig)


if __name__ == "__main__":
    main()