[Circuit x Python] So lösen Sie Schaltungsgleichungen symbolisch mit sympy

Einführung

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.

Für solche Leute

・ 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! "

Umgebung

Python: 3.7.4、SymPy: 1.6.2

Schaltung zu analysieren

Berechnen wir als einfaches Beispiel die Übertragungsfunktion der unten gezeigten Schaltung. Schaltungskomponentenkonstanten sind eher Symbole als Zahlen. image.png

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. image.png

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.

Alle Codes

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.

SCHRITT 1: Geben Sie die Schaltungsgleichung ein und unbekannt

#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.

SCHRITT 2: Modul importieren

python


from sympy import *
from IPython.display import Math
from collections import Counter

Importieren Sie das Modul. Es ist kein spezieller Kommentar erforderlich.

SCHRITT 3: Extrahieren Sie das Symbol aus der Schaltungsgleichung und deklarieren Sie es als Symbol

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)

SCHRITT 4: Generieren Sie ein Array für die TeX-Anzeige

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.

SCHRITT 5: Schaltungsgleichung und unbekannte Symbolliste erstellen

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

SCHRITT 6: Lösen und organisieren Sie Gleichungen

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: $\displaystyle \frac{CP RM RP VIN s + RM VIN}{CM CP LP RM RP s^{3} + RM + RP + s^{2} \left(CM LP RM + CP LP RP\right) + s \left(CM RM RP + CP RM RP + LP\right)}$

    #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. $\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)}$

Variablennamen

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.

abschließend

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

[Circuit x Python] So lösen Sie Schaltungsgleichungen symbolisch mit sympy
[Circuit x Python] So erweitern und berechnen Sie Übertragungsfunktionen mit Lcapy
[Python] Löse Gleichungen mit Sympy
[Circuit x Python] So ermitteln Sie die Übertragungsfunktion eines Schaltkreises mit Lcapy
So installieren Sie Python mit Anaconda
So lösen Sie simultane lineare Gleichungen
[Circuit x Python] Aktivieren des linearen Schaltungsanalysepakets Lcapy
So löschen Sie Python 2.x auf einem Mac.
Lösen wir simultane lineare Gleichungen mit Python Sympy!
[Algorithmus x Python] Verwendung der Liste
Lösen Sie simultane Gleichungen sofort mit Python
So installieren Sie Python
Verwendung von SymPy
So richten Sie eine Python-Umgebung mit pyenv ein
So senden Sie Microsoft Forms automatisch mit Python (Mac-Version)
Lösen Sie simultane normale Differentialgleichungen mit Python und SymPy.
So erstellen Sie ein Python-Paket mit VS Code
Beenden bei Verwendung von Python in Terminal (Mac)
So rufen Sie mehrere Arrays mit Slice in Python ab.
[Einführung in Python] Wie stoppe ich die Schleife mit break?
So führen Sie einen Befehl mit einem Unterprozess in Python aus
[Einführung in Python] So schreiben Sie sich wiederholende Anweisungen mit for-Anweisungen
[Neueste Version 2020.8] So installieren Sie Python
So installieren Sie Python [Windows]
[Einführung in Python] Wie man bedingte Verzweigungen mit if-Anweisungen schreibt
python3: Verwendung der Flasche (2)
[Python] Verwendung von Liste 1
So aktualisieren Sie Pythons Tkinter auf 8.6
So verschieben Sie ein zweidimensionales Array nur mit Python [Hinweis]
Mit Python auf Twitter posten
Wie benutzt man Python Argparse?
Starten Sie mit Python zu Selen
Python: Wie man pydub benutzt
[Python] Verwendung von checkio
So führen Sie Notepad ++ Python aus
So ändern Sie die Python-Version
13. Offline-Echtzeit So lösen Sie Schreibprobleme mit Python
Wie man in Python entwickelt
So aktualisieren Sie FC2-Blogs usw. mithilfe von XMLRPC mit Python
[Python] Wie man Skalar beurteilt
[Python] Verwendung von input ()
Wie benutzt man Python Lambda?
[Python] Verwendung von virtualenv
python3: Verwendung der Flasche (3)
python3: Wie man eine Flasche benutzt
Konvertieren Sie Python 3.x-Code in Python 2.x.
Verwendung von Python-Bytes
So zeigen Sie Formeln in Latex an, wenn Sie sympy (> = 1.4) in Google Colaboratory verwenden
So erhalten Sie mithilfe der Mastodon-API Follower und Follower von Python
17. Offline-Echtzeit So lösen Sie Schreibprobleme mit Python
So schreiben Sie offline in Echtzeit Lösen von E04-Problemen mit Python
So erstellen Sie eine Python-Umgebung mit Virtualenv unter Ubuntu 18.04 LTS
So aktualisieren Sie eine in Tableau gepackte Arbeitsmappen-Datenquelle mit Python
So schreiben Sie offline in Echtzeit Lösen von F01-Problemen mit Python
So installieren Sie Theano unter Mac OS X 10.10 (mit pyenv, anaconda)
[Python] Wie man MP3-Daten fFT