Ich bin ein Designer für analoge Schaltungen. Vor kurzem habe ich angefangen, Python als Hobby zu studieren.
Der numerische Analyseschaltungssimulator von SPICE wird häufig bei der Konstruktion von analogen Schaltungen verwendet. Der numerische Analysesimulator allein vertieft jedoch nicht das Verständnis der entworfenen Schaltung. Manchmal ist es notwendig, die von Ihnen entworfene Schaltung zu vereinfachen, eine Schaltungsgleichung zu formulieren und zu lösen. Das Lösen von Schaltungsgleichungen ist eine mühsame Aufgabe. Es ist in Ordnung, es vorerst zu lösen, aber ich habe vorerst Ergebnisse erhalten, z. B. einen Berechnungsfehler, und ich konnte kein nützliches Ergebnis erzielen. Die Formel war kompliziert und ich konnte keinen Einblick erhalten und musste sie nicht lösen. Man kann sagen, dass es schwierig ist, sie loszuwerden. Diesmal habe ich es also möglich gemacht, die Schaltungsgleichung mit Sympy zu lösen. Bei der Erstellung des Programms war ich mir bewusst, die Anzahl der von Menschen eingegebenen Stellen so weit wie möglich zu reduzieren.
・ Schaltungsdesigner hat es satt, das Schaltungsdesign zu lösen ・ Ich habe mit Python und Jupyter-Notebook gespielt ・ Ich habe Sympy ein wenig berührt
Die angenommene Situation ist wie folgt "Ich habe ein Schaltbild in ein Notizbuch gezeichnet und eine Gleichung formuliert. Es gibt viele Gleichungen, und es scheint, dass es einige Zeit dauern wird, sie zu lösen. Ich weiß nicht, ob ich aussagekräftige Ergebnisse erzielen kann, selbst wenn ich sie löse ... Okay, lass Sympy es tun! "
Python: 3.7.4、SymPy: 1.6.2
Berechnen wir als einfaches Beispiel die Übertragungsfunktion der unten gezeigten Schaltung. Schaltungskomponentenkonstanten sind eher Symbole als Zahlen.
Formulieren wir zunächst die Schaltungsgleichung selbst, wie in der folgenden Abbildung gezeigt. Wenn es darum geht, Sympy Schaltungsgleichungen lösen zu lassen, müssen Sie keine Möglichkeiten finden, um die Anzahl der Gleichungen zu reduzieren, was Ihre Kopfenergie spart.
Nachdem bestätigt wurde, dass die Unbekannten (hier ZP, ZM, IT, VOUT) und die Anzahl der Gleichungen übereinstimmen, ist die Erstellung der Schaltungsgleichung abgeschlossen.
Lassen Sie es von nun an auf dem Jupyter-Notebook laufen.
Plötzlich ist der gesamte Code unten.
Alle Codes
#Geben Sie die Schaltungsgleichung ein
ce = """
ZP = RP / (1 + s*CP*RP)
ZM = RM / (1 + s*CM*RM)
VIN = (s*LP + ZP + ZM)*IT
VOUT = ZM * IT
"""
#Unbekannt eingeben
uk = "ZP, ZM, IT, VOUT"
#Geben Sie die Variable ein, die Sie suchen möchten
wn = "VOUT"
#----------------------------------------------------
#Unten gibt es keinen Platz für den Benutzer
#Grundeinstellung
from sympy import *
from IPython.display import Math
from collections import Counter
#Extrahieren Sie das Symbol aus der Schaltungsgleichung und deklarieren Sie es als Symbol
rep_char = ["+", "-", "*", "/", "s", "=", "\n", "(", ")"]
ce_rep = ce
for i in range(len(rep_char)):
ce_rep = ce_rep.replace(rep_char[i], " ")
ce_sym = ce_rep.split()
ce_sym = list(Counter(ce_sym).keys())
for i in reversed(range(len(ce_sym))): #Löschen Sie die Zahlen in der Liste
if ce_sym[i].isdecimal():
del ce_sym[i]
s = Symbol("s", real=True)
for i in range(len(ce_sym)):
exec(ce_sym[i] + " = Symbol(\"" + ce_sym[i] + "\", real=True)")
#Generieren Sie ein Array für die TeX-Anzeige
ce_tex = []
for i in range(len(ce_sym)):
if len(ce_sym[i]) == 1:
ce_tex.append(ce_sym[i][0])
else:
ce_tex.append(ce_sym[i][0] + "_{" + ce_sym[i][1:] + "}")
#Schaltungsgleichung und unbekannte Symbolliste generieren
start = 3
ind_eq = -1
ind_rt = 2
ce_sol = []
while True:
ind_eq = ce.find("=", ind_eq+1)
ind_rt = ce.find("\n", ind_rt+1)
if ind_rt == -1:
break
exec("ce_sol.append(" + ce[start:ind_eq] + "-(" + ce[ind_eq+1: ind_rt] + "))")
start=ind_rt + 1
exec("uk_sol = " + uk)
exec("wn_sol = " + wn)
#Gleichungen lösen und organisieren
if len(uk_sol) != len(ce_sol):
print("Richten Sie die Anzahl der Unbekannten an der Anzahl der Gleichungen aus.")
else:
sol = solve(ce_sol, uk_sol, dict=True)[0][wn_sol]
#Organisieren Sie das Nennermolekül
nu = collect(expand(numer(sol)), s) #Zähler, Molekül
de = collect(expand(denom(sol)), s) #Nenner, Nenner
sol = nu / de
#Ausdrücke anzeigen
sol_tex = latex(sol)
for i in range(len(ce_sym)):
sol_tex = sol_tex.replace(latex(ce_sym[i]), ce_tex[i])
display(Math(sol_tex))
Wenn Sie dies tun, erhalten Sie die folgenden Ergebnisse:
\displaystyle \frac{C_{P} R_{M} R_{P} V_{IN} s + R_{M} V_{IN}}{C_{M} C_{P} L_{P} R_{M} R_{P} s^{3} + R_{M} + R_{P} + s^{2} \left(C_{M} L_{P} R_{M} + C_{P} L_{P} R_{P}\right) + s \left(C_{M} R_{M} R_{P} + C_{P} R_{M} R_{P} + L_{P}\right)}
Lassen Sie uns den Ablauf des Programms und seine Details erklären.
#Geben Sie die Schaltungsgleichung ein
ce = """
ZP = RP / (1 + s*CP*RP)
ZM = RM / (1 + s*CM*RM)
VIN = (s*LP + ZP + ZM)*IT
VOUT = ZM * IT
"""
#Unbekannt eingeben
uk = "ZP, ZM, IT, VOUT"
#Geben Sie die Variable ein, die Sie suchen möchten
wn = "VOUT"
Geben Sie die Schaltungsgleichung, Unbekannte und die Variablen ein, die Sie suchen möchten. Beginnen Sie bei der Eingabe von Schaltungsgleichungen mit Großbuchstaben für andere Parameter als s. Dies liegt daran, dass es unpraktisch ist, wenn das Berechnungsergebnis in Kleinbuchstaben in TeX angezeigt wird.
python
from sympy import *
from IPython.display import Math
from collections import Counter
Importieren Sie das Modul. Es ist kein spezieller Kommentar erforderlich.
python
rep_char = ["+", "-", "*", "/", "s", "=", "\n", "(", ")"]
ce_rep = ce
for i in range(len(rep_char)):
ce_rep = ce_rep.replace(rep_char[i], " ")
ce_sym = ce_rep.split()
ce_sym = list(Counter(ce_sym).keys())
for i in reversed(range(len(ce_sym))): #Löschen Sie die Zahlen in der Liste
if ce_sym[i].isdecimal():
del ce_sym[i]
Hier wird die folgende Verarbeitung durchgeführt __ (i) Die Schaltungsgleichung ce wird in SCHRITT 1 eingegeben __ ZP = RP / (1 + sCPRP) ZM = RM / (1 + sCM+RM) VIN = (sLP + ZP + ZM)*IT VOUT = ZM * IT
__ (ii) Ersetzen Sie die Operatoren (+ - * /), s, den Zeilenvorschub (\ n) usw. durch Leerzeichen aus der Eingangsschaltungsgleichung (ce in SCHRITT 1) __ ce_rep: ZP RP 1 CP RP ZM RM 1 CM RM VIN LP ZP ZM IT VOUT ZM IT
__ (iii) Extrahieren Sie die Symbole, die in der Gleichung __ erscheinen ce_sym: ['ZP', 'RP', '1', 'CP', 'ZM', 'RM', 'CM', 'VIN', 'LP', 'IT', 'VOUT']
__ (iii) Suchen Sie die Nummer in der oben erhaltenen Liste und löschen Sie sie (in diesem Fall wird 1 gelöscht) __ ce_sym: ['ZP', 'RP', 'CP', 'ZM', 'RM', 'CM', 'VIN', 'LP', 'IT', 'VOUT']
Nun haben wir eine Liste der Symbole, die in der Schaltungsgleichung im obigen Prozess verwendet wurden Deklarieren Sie es als Sympysymbol.
python
s = Symbol("s", real=True)
for i in range(len(ce_sym)):
exec(ce_sym[i] + " = Symbol(\"" + ce_sym[i] + "\", real=True)")
Code, der in __exec ausgeführt wird: __ ZP = Symbol("ZP", real=True) RP = Symbol("RP", real=True) CP = Symbol("CP", real=True) ZM = Symbol("ZM", real=True) RM = Symbol("RM", real=True) CM = Symbol("CM", real=True) VIN = Symbol("VIN", real=True) LP = Symbol("LP", real=True) IT = Symbol("IT", real=True) VOUT = Symbol("VOUT", real=True)
python
ce_tex = []
for i in range(len(ce_sym)):
if len(ce_sym[i]) == 1:
ce_tex.append(ce_sym[i][0])
else:
ce_tex.append(ce_sym[i][0] + "_{" + ce_sym[i][1:] + "}")
Ich möchte das Ausgabeergebnis in TeX anzeigen, daher werde ich eine Liste dafür erstellen. Basierend auf der Liste von ce_sym wird die Liste ce_tex generiert, die nach dem zweiten Zeichen untergeordnet werden soll [^ 1]. Beispiel: VOUT → V_ {OUT}, $ V_ {OUT} $
ce_tex: ['Z_{P}', 'R_{P}', 'C_{P}', 'Z_{M}', 'R_{M}', 'C_{M}', 'V_{IN}', 'L_{P}', 'I_{T}', 'V_{OUT}']
__ (Referenz) ce_sym: __ erhalten in STEP3 ['ZP', 'RP', 'CP', 'ZM', 'RM', 'CM', 'VIN', 'LP', 'IT', 'VOUT']
[^ 1]: Beachten Sie, dass bei Verwendung des Symbols BW1 die Tex-Anzeige nicht $ BW_1 $, sondern $ B_ {W1} $ lautet.
python
start = 3
ind_eq = -1
ind_rt = 2
ce_sol = []
while True:
ind_eq = ce.find("=", ind_eq+1)
ind_rt = ce.find("\n", ind_rt+1)
if ind_rt == -1:
break
exec("ce_sol.append(" + ce[start:ind_eq] + "-(" + ce[ind_eq+1: ind_rt] + "))")
start=ind_rt + 1
exec("uk_sol = " + uk)
exec("wn_sol = " + wn)
Die Gleichung und die Liste der unbekannten Symbole werden durch die folgende Verarbeitung erzeugt.
__ (i) Die Schaltungsgleichung ce wird in SCHRITT 1 eingegeben __ ce: ZP = RP / (1 + sCPRP) ZM = RM / (1 + sCMRM) VIN = (s*LP + ZP + ZM)*IT VOUT = ZM * IT
Suchen Sie das gleiche '=' und den Zeilenumbruch '\ n'von __ (ii) ce und erstellen Sie eine Liste, bei der die rechte Seite nach links verschoben ist __ ce_sol: -RP/(CPRPs + 1) + ZP, -RM/(CMRMs + 1) + ZM, -IT*(LPs + ZM + ZP) + VIN, -ITZM + VOUT
__ (iii) Führen Sie den folgenden Code für das Unbekannte (uk) und die Variable (wn) aus, die Sie suchen möchten __ uk_sol = ZP, ZM, IT, VOUT wn_sol = VOUT
Dies ist der Teil, der die Gleichung endgültig löst.
python
if len(uk_sol) != len(ce_sol):
print("Richten Sie die Anzahl der Unbekannten an der Anzahl der Gleichungen aus.")
else:
sol = solve(ce_sol, uk_sol, dict=True)[0][wn_sol]
#Organisieren Sie das Nennermolekül
nu = collect(expand(numer(sol)), s) #Zähler, Molekül
de = collect(expand(denom(sol)), s) #Nenner, Nenner
sol = nu / de
Wenn die Anzahl der Unbekannten und die Anzahl der Gleichungen nicht gleich sind, kann keine Lösung gefunden werden. Überprüfen Sie dies daher zuerst.
Die Gleichung wird durch den folgenden Code gelöst.
sol = solve(ce_sol, uk_sol, dict=True)[0][wn_sol]
Wenn Sie lösen ausführen (ce_sol, uk_sol, dict = True), erhalten Sie alle unbekannten Lösungen wie folgt. Durch Hinzufügen von [0] [wn_sol] wird nur die Lösung (diesmal VOUT) extrahiert, die Sie suchen möchten.
Ergebnis der Ausführung von ___sol = lösen (ce_sol, uk_sol, dict = True): __ ZP: RP/(CPRPs + 1) ZM: RM/(CMRMs + 1) IT: VIN * (CM * RM * s + 1) * (CP ~ weggelassen ~ VOUT: RM * VIN * (CP * RP * s + 1 ~ weggelassen ~
Nach dem Finden der Lösung wird das Nennermolekül für s organisiert.
Die erhaltene Lösung ist wie unten gezeigt schwer abzulesen.
sol:
#Ausdrücke anzeigen
sol_tex = latex(sol)
for i in range(len(ce_sym)):
sol_tex = sol_tex.replace(latex(ce_sym[i]), ce_tex[i])
display(Math(sol_tex))
Um die Anzeige der Gleichung zu vereinfachen, wird sie daher in die TeX-Anzeige konvertiert. Wenn es sich beispielsweise um VOUT handelt, ersetzen Sie es durch V_ {OUT}.
Das Endergebnis ist wie folgt und die Lesbarkeit wurde durch Verwendung des TeX-Displays verbessert.
Die Formel wird ersetzt, um TeX anzuzeigen. Abhängig vom Symbolnamen kann sie sich jedoch unerwartet verhalten. Die Verwendung des Symbols ac ersetzt beispielsweise \ fr ac im TeX-Code. Aus diesem Grund sollten Symbole grundsätzlich mit Großbuchstaben beginnen.
Das ist alles für die Erklärung. Da der Benutzer nur die Schaltungsgleichung, das Unbekannte und die zu erhaltende Variable eingibt, kann die Schaltungsgleichung mit minimalem Aufwand gelöst werden. Der eingesparte Aufwand kann zur Interpretation der erzielten Ergebnisse verwendet werden. Zum Beispiel könnte die Formel aus der Größenbeziehung der Terme vereinfacht werden.
Diesmal haben die Menschen die Schaltungsgleichung aufgestellt, aber ich denke, dass selbst das Aufstellen der Schaltungsgleichung problematisch sein kann (keine Zeit). In diesem Fall können Sie auch die Formulierung von Schaltungsgleichungen mithilfe eines Python-Pakets namens Lcapy automatisieren. Der Benutzer muss lediglich einen Schaltplan zeichnen. Ich habe einen Kommentar dazu geschrieben. Wenn Sie also interessiert sind, schauen Sie bitte auch dort nach.
[Circuit x Python] Aktivieren des linearen Schaltungsanalysepakets Lcapy [Circuit x Python] So finden Sie die Übertragungsfunktion einer Schaltung mit Lcapy [Circuit x Python] Erweitern und Berechnen von Übertragungsfunktionen mit Lcapy
Recommended Posts