Engineering für Super-Faulheit: Gleichungen lösen ohne das Gehirn einzuschalten

English Deutsch

Vorwort

In der Elektronikentwicklung muss man von Zeit zu Zeit Standardformeln verwenden, um Schaltungen zu charakterisieren. In welchem Umfang alle Parameter berechnet werden müssen, hängt meist von den Anforderungen ab.

Betrachten wir beispielsweise die Formel für die -3dB-Grenzfrequenz eines RC-Tiefpassfilters 1. Ordnung:

$$f_c=\frac{1}{2\pi RC}$$

Obwohl diese Gleichung recht einfach ist und die meisten Personen keine Probleme haben werden, sie in wenigen Sekunden nach einer beliebigen Variablen aufzulösen, kann sie als grundlegendes Beispiel dafür dienen, wie man eine Gleichung symbolisch löst.

Eine der einfachsten Möglichkeiten, diese Aufgabe auszuführen, ist die Verwendung von SymPy, einer Python-Bibliothek für symbolische Mathematik.

Ein einführendes Beispiel

Zuerst müssen wir SymPy mitteilen, wie die Formel lautet:

sympy_example.py
from sympy import *
f, R, C = symbols("f_c R C")
# Denk daran, dies nicht 'f' zu nennen (wir haben bereits ein Symbol namens f!)
eq1 = Eq(f, 1 / (2 * pi * R * C))

Durch die Verwendung der SymPy-Variante von $\pi$ anstelle der numpy-Version können wir eine höhere numerische Genauigkeit erzielen, und die resultierenden Gleichungen werden in einer menschenlesbareren Form formatiert, da sie $\pi$ als Symbol enthalten anstatt

Falls du eine Fehlermeldung wie

sympy_install.txt
ImportError: No module named 'sympy'

Du kannst das Paket mit pip installieren (empfohlen, aber easy_install funktioniert auch): pip install sympy

Details zu den verwendeten Funktionen findest du im ausgezeichneten SymPy-Tutorial.

Nun können wir die ursprüngliche Formel auswerten. Da dies eine Gleichung ist und wir die linke Seite ( $\frac{1}{2πRC}$ ) berechnen wollen, müssen wir die rechte Seite mit .rhs extrahieren und die Variablen durch tatsächliche Werte ersetzen (für dieses Beispiel verwenden wir $1 k\Omega$ und $1 {\mu}F$). Zu guter Letzt verwenden wir die Funktion evalf(), um die Formel zu einem einzelnen Gleitkommawert auszuwerten

sympy_eval.py
f_result = eq1.rhs.evalf(subs={C: 1e-6, R: 1e3})

Nach dem Ausführen dieses Codeblocks ist der Wert von f_result etwa 159.155 — dies ist korrekt, wie leicht überprüft werden kann mit

Der nächste Schritt besteht darin, SymPy die Gleichung nach R aufzulösen (in diesem Beispiel):

sympy_solve.py
from sympy.solvers import solve
eq1_R = solve(eq1, R)[0] # [0]: Nur die erste Lösung nehmen

Beachte, dass es bei komplexeren Gleichungen mehr als eine Lösung geben kann und du die richtige auswählen musst oder nicht. In diesem Fall gibt es nur eine Lösung: print(eq1_R) gibt 1/(2*pi*C*f_c) aus.

In Frontends wie kann SymPy auch verschiedene Methoden des Pretty-Printing verwenden. Du kannst die beste verfügbare Methode für das aktuelle Frontend initialisieren mit

sympy_print.py
from sympy import init_printing
init_printing()

In IPython wird die Formel als LaTeX ausgegeben, wobei eq1_R

$$f_c = \frac{1}{2πCf_c}$$

ergibt

Auf der Kommandozeile wird eine ASCII-basierte Ausgabe erzeugt:

sympy_ascii_output.txt
    1
─────────
2⋅π⋅C⋅f_c

Nun können wir einfach mit dem Einsetzen und Auswerten des neuen Ausdrucks fortfahren. Wir werden die Werte aus dem vorherigen Block verwenden, um die umgestellte Formel auszuwerten — es wird erwartet, dass das Ergebnis für R genau 1000$\Omega$ ist. solve(...)[0] gibt bereits die rechte Seite der Gleichung zurück, sodass wir .rhs nicht wie oben verwenden müssen.

sympy_eval_r.py
r_result = eq1_R.evalf(subs={C: 1e-6, f: f_result})

Der Wert von r_result ist genau

$$1000.0\Omega$$

. Bei komplexeren Gleichungen können numerische Fehler auftreten, auch wenn SymPy versucht, diese so gut wie möglich zu vermeiden. Du kannst oft kleine numerische Fehler umgehen, indem du das Argument chop=true an evalf() übergibst. Eine detaillierte Erklärung der beteiligten Mechanismen würde den Rahmen dieses Artikels sprengen, daher wird empfohlen, die SymPy-Referenz zur numerischen Auswertung zu lesen.

SI-Einheiten vereinfachen

Hast du schon einmal eine Physikklausur geschrieben, in der du die richtige Gleichung durch Abgleich der beteiligten Einheiten mit der erwarteten Ausgabeeinheit hergeleitet hast? Egal, das ist nicht mehr nötig.

SymPy kann nicht nur deinen Umgang mit symbolischen Gleichungen vereinfachen, sondern auch ein Einheitensystem integrieren.

Beispielsweise kannst du die Einheit der oben genannten Gleichung berechnen:

sympy_units_example.py
from sympy.physics.units import *
print(1 / (ohms * farads))

Dies gibt $\frac{1}{s}$ aus, was korrekt ist, da die obige Gleichung ein Ergebnis in Hz liefert.

SymPy kann nicht nur die korrekte abgeleitete Einheit berechnen, sondern auch ableiten, dass diese Hz genannt wird und

sympy_init_printing.py
print(find_unit(1 / (ohms * farads))) # ['Hz', 'hz', 'hertz', 'frequency']

Wir können auch SymPys Wissen über Einheiten nutzen, um eine Einheit zu extrahieren. Wir verwenden eq1 wie im vorherigen Abschnitt dieses Artikels aufgeführt.

Derzeit unterstützt SymPy keine vollständige Berechnung mit Einheiten (siehe dieses Issue). Die aktuelle Einheitenunterstützung kann jedoch bereits nützlich sein, um deine Gleichungen auf Plausibilität zu prüfen. In Zukunft werde ich versuchen, das Einheitensystem von UliEngineering mit SymPy zu integrieren.


Check out similar posts by category: Python