.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/electrical_engineering/electronics/plot_01_ragazzini_operational_amplifier.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code or to run this example in your browser via JupyterLite. .. rst-class:: sphx-glr-example-title .. _sphx_glr_api_gallery_electrical_engineering_electronics_plot_01_ragazzini_operational_amplifier.py: Ragazzini's operational amplifier (1947) ======================================== Analog computers of the 1940s solved differential equations with high-gain DC amplifiers wrapped in resistive and capacitive feedback. John Ragazzini, Robert Randall and Frederick Russell of Columbia University analysed them in 1947 and named them *operational amplifiers*, because each performed a mathematical operation: with a large enough gain the feedback forces the inverting input to a virtual ground, so the output depends only on the feedback network. A resistor ratio scales and inverts (:func:`~engineeringkit.electrical_engineering.inverting_amplifier_gain`), the non-inverting connection scales without inversion (:func:`~engineeringkit.electrical_engineering.noninverting_amplifier_gain`) and a feedback capacitor integrates (:func:`~engineeringkit.electrical_engineering.op_amp_integrator`). This example checks the ideal gains against an amplifier of finite open-loop gain, then wires two integrators into a loop that solves :math:`\ddot y = -\omega^2 y`, as an analog computer did. .. GENERATED FROM PYTHON SOURCE LINES 23-28 .. code-block:: Python import matplotlib.pyplot as plt import numpy as np from engineeringkit.electrical_engineering import inverting_amplifier_gain, noninverting_amplifier_gain, op_amp_integrator .. GENERATED FROM PYTHON SOURCE LINES 29-35 The ideal gains and a finite open-loop gain ------------------------------------------- With open-loop gain :math:`A`, the inverting amplifier gives :math:`-(R_f/R_i)/(1 + (1 + R_f/R_i)/A)`; the ideal value is the limit :math:`A \to \infty`. .. GENERATED FROM PYTHON SOURCE LINES 35-44 .. code-block:: Python Rf, Ri = 100e3, 10e3 ideal_inv, ideal_non = inverting_amplifier_gain(Rf, Ri), noninverting_amplifier_gain(Rf, Ri) print(f"ideal gains: inverting {ideal_inv:.1f}, non-inverting {ideal_non:.1f}") for A in (1e2, 1e4, 1e6): actual = -(Rf / Ri) / (1 + (1 + Rf / Ri) / A) print(f"A = {A:.0e}: inverting gain {actual:.4f} ({abs(actual / ideal_inv - 1):.2%} short)") assert abs(-(Rf / Ri) / (1 + (1 + Rf / Ri) / 1e6) / ideal_inv - 1) < 2e-5 .. rst-class:: sphx-glr-script-out .. code-block:: none ideal gains: inverting -10.0, non-inverting 11.0 A = 1e+02: inverting gain -9.0090 (9.91% short) A = 1e+04: inverting gain -9.9890 (0.11% short) A = 1e+06: inverting gain -9.9999 (0.00% short) .. GENERATED FROM PYTHON SOURCE LINES 45-54 Two integrators in a loop: an analog computer --------------------------------------------- Integrating :math:`\ddot y` twice gives :math:`y`; feeding :math:`-\omega^2 y` back as :math:`\ddot y` closes the loop. Each inverting integrator flips the sign, so a unity-gain inverter (:math:`R_f = R_i`) restores the minus sign of :math:`-\omega^2 y`; without it the loop would grow exponentially. The circuit is stepped forward in short intervals, each integrator integrating its sampled input. .. GENERATED FROM PYTHON SOURCE LINES 54-84 .. code-block:: Python R, C = 100e3, 1e-6 # RC = 0.1 s, so omega = 1/RC = 10 rad/s omega = 1 / (R * C) dt, n = 1e-4, 12000 t = np.arange(n) * dt inverter = inverting_amplifier_gain(R, R) y, u = np.empty(n), np.empty(n) y[0], u[0] = 1.0, 0.0 for k in range(n - 1): span = t[k : k + 2] # First integrator: input y, output u = -(1/RC) int y dt. u[k + 1] = op_amp_integrator([y[k], y[k]], span, R, C, v0=u[k])[-1] # Inverter, then the second integrator: input -u, output y = (1/RC) int u dt. y[k + 1] = op_amp_integrator(inverter * u[[k + 1, k + 1]], span, R, C, v0=y[k])[-1] print(f"after {t[-1]:.1f} s: y = {y[-1]:.4f}, exact cos(omega t) = {np.cos(omega * t[-1]):.4f}") assert np.max(np.abs(y - np.cos(omega * t))) < 2e-2 fig, axes = plt.subplots(1, 2, figsize=(10, 3.6)) for A in (1e1, 1e2, 1e3): ratio = np.logspace(0, 3, 50) axes[0].semilogx(ratio, (ratio / (1 + (1 + ratio) / A)) / ratio, label=f"A = {A:.0e}") axes[0].set(xlabel="ideal gain magnitude $R_f/R_i$", ylabel="actual / ideal", title="Finite open-loop gain") axes[0].legend(fontsize="small") axes[1].plot(t, y, label="integrator loop") axes[1].plot(t, np.cos(omega * t), "k:", label="cos(omega t)") axes[1].set(xlabel="time [s]", ylabel="output [V]", title="Two-integrator oscillator") axes[1].legend(fontsize="small") fig.tight_layout() plt.show() .. image-sg:: /api/gallery/electrical_engineering/electronics/images/sphx_glr_plot_01_ragazzini_operational_amplifier_001.png :alt: Finite open-loop gain, Two-integrator oscillator :srcset: /api/gallery/electrical_engineering/electronics/images/sphx_glr_plot_01_ragazzini_operational_amplifier_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none after 1.2 s: y = 0.8436, exact cos(omega t) = 0.8433 .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 1.349 seconds) .. _sphx_glr_download_api_gallery_electrical_engineering_electronics_plot_01_ragazzini_operational_amplifier.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: lite-badge .. image:: images/jupyterlite_badge_logo.svg :target: ../../../../lite/lab/index.html?path=api/gallery/electrical_engineering/electronics/plot_01_ragazzini_operational_amplifier.ipynb :alt: Launch JupyterLite :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_01_ragazzini_operational_amplifier.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_01_ragazzini_operational_amplifier.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_01_ragazzini_operational_amplifier.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_