Engineering für Super-Faulheit: Gleichungen lösen ohne das Gehirn einzuschalten
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:
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
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
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):
from sympy.solvers import solve
eq1_R = solve(eq1, R)[0] # [0]: Nur die erste Lösung nehmenBeachte, 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
from sympy import init_printing
init_printing()In IPython wird die Formel als LaTeX ausgegeben, wobei eq1_R
ergibt
Auf der Kommandozeile wird eine ASCII-basierte Ausgabe erzeugt:
1
─────────
2⋅π⋅C⋅f_cNun 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.
r_result = eq1_R.evalf(subs={C: 1e-6, f: f_result})Der Wert von r_result ist genau
. 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:
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
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.