Seite 1 von 1
Wörterbuch als Matrix umformulieren
Verfasst: Montag 4. Januar 2021, 08:18
von CaptainNeemo
Hallo liebes Python Forum,
ich suche aktuell eine Möglichkeit um ein Wörterbuch wie dieses:
Code: Alles auswählen
Wörterbuch = {0 : [(1,1.),(2,2.)],
1 : [(0,1.),(3,3.)],
2 : [(0,2.),(3,3.),(4,4.)],
3 : [(1,3.),(2,3.),(5,5.)],
4 : [(3,4.),(5,5.)],
5 : [(3,5.),(4,5.)]}
möglichst einfach in eine Quadrat-Matrix umzuschreiben, wobei der key die Reihe in der Matrix und das a im Tupel (a,b) die Spalte und das b soll jeweils in die Matrix eingetragen werden. Die restlichen Felder werden 0
Ich habe es mit Schleifen versucht, dachte mir da gibt es aber bestimmt noch eine einfachere Möglichkeit. Die restlichen Felder werden 0
Vielen Dank schonmal im Vorraus für eure Hilfe
Re: Wörterbuch als Matrix umformulieren
Verfasst: Montag 4. Januar 2021, 08:32
von Sirius3
Nein, einfacher als zwei for-Schleifen geht es nicht. Saß ist ja durch die Datenstruktur so vorgegeben.
Re: Wörterbuch als Matrix umformulieren
Verfasst: Montag 4. Januar 2021, 11:24
von CaptainNeemo
@Sirius3: Okay vielen Dank ich habe es jetzt auch mit den zwei for-Schleifen geschrieben. Ich ätte noch eine Frage, die ich stellen wollte und zwar, habe ich jetzt eine Matrix und will diese jetzt lösen mit linalg.solve. Dort bekomme ich ja meine Matrix x. Allerdings sollen 2 Lösungen schon gegeben sein. Aktuell multipliziere ich dieLösungen in die Werte der ersten und der letzten Reihe der Matrix, jedoch scheint es nicht zu funktionieren.
Weißt du zufällig wie ich diese ander angeben könnte oder wo das Problem liegt? Hier mein Code falls dieser weiterhilft:
Code: Alles auswählen
ResiLink = {0 : [(1,1.),(2,2.)],
1 : [(0,1.),(3,3.)],
2 : [(0,2.),(3,3.),(4,4.)],
3 : [(1,3.),(2,3.),(5,5.)],
4 : [(3,4.),(5,5.)],
5 : [(3,5.),(,5.)]}
def Kirchhoffmain(ResiLink,sw=0,ew=1):
"""
Berechnung nach dem Knotenpotentialverfahren, wobei einem Knoten ein Anfangswert und ein Endwert gegeben werden kann. In diesem Falle per default(sw=0,ew=1).
"""
Ivec = np.zeros(len(ResiLink)).reshape(len(ResiLink),1) #Den Spaltenvektor der Spannungen
lgs = np.zeros((len(ResiLink))*(len(ResiLink))).reshape((len(ResiLink)),len(ResiLink))
#Matrix für die Zweigleitwerte
for i in range(int(len(ResiLink))): #Befüllen der Matrix
line = ResiLink[i]
for (j,r) in line:
if i == r:
if i==0:
lgs[i,j] = sw/r
if 0==(len(ResiLink)-1):
lgs[i,j] = ew/r
else:
lgs[i,j] = 1/r
else:
lgs[i,j] = -1/r
solved = np.linalg.solve(lgs,Ivec)
print(lgs)
print(Ivec)
return solved
Re: Wörterbuch als Matrix umformulieren
Verfasst: Montag 4. Januar 2021, 11:58
von Sirius3
Variablennamen werden wie Funktionen komplett klein geschrieben.
np.zeros kann auch gleich mehrdimensionale Arrays erzeugen.
Wenn ResiLink wirklich ein Wörterbuch ist, ist es komisch, dass Du da einen Index i erzeugst, um auf die Schlüssel zuzugreifen. Wenn das wirklich nur aufsteigende Zahlen sind, dann wäre eine Liste die richtige Datenstruktur.
Ansonsten iteriert man in Python auch nicht über einen Index.
Dann verstehe ich nicht, was Du da versuchst zu lösen. Warum ist der zweite Tupelwert zwar irgendwie der Wert eines Matrixelements, aber auch irgendwie ein Zeilenindex, denn r wird mit i verglichen.
Ivec ist immer ein Vektor mit nullen. Und das wird an solve übergeben?
Re: Wörterbuch als Matrix umformulieren
Verfasst: Montag 4. Januar 2021, 12:15
von pillmuncher
Was Sirius3 gesagt hat. Ich hab es mal etwas pythonischer umgeschrieben, unter Beibehaltung der Logik (hoffentlich):
Code: Alles auswählen
import numpy as np
def kirchhoff(resi_link, begin=0, end=1):
"""
Berechnung nach dem Knotenpotentialverfahren, wobei einem Knoten ein
Anfangswert und ein Endwert gegeben werden kann. In diesem Falle per
default(begin=0, end=1).
"""
# Spaltenvektor der Spannungen:
Ivec = np.zeros(len(resi_link)).reshape(len(resi_link), 1)
lgs = np.zeros((len(resi_link), len(resi_link)))
# Matrix für die Zweigleitwerte:
for i, line in enumerate(resi_link):
for n, r in line:
if i != r:
lgs[i, n] = -1 / r
elif len(resi_link) == 1:
lgs[i, n] = end / r
elif i == 0:
lgs[i, n] = begin / r
else:
lgs[i, n] = 1 / r
print(lgs)
print(Ivec)
return np.linalg.solve(lgs, Ivec)
def main():
print(kirchhoff([
[(1, 1.), (2, 2.)],
[(0, 1.), (3, 3.)],
[(0, 2.), (3, 3.), (4, 4.)],
[(1, 3.), (2, 3.), (5, 5.)],
[(3, 4.), (5, 5.)],
[(3, 5.), (4, 5.)]
]))
if __name__ == '__main__':
main()
Ergebnis:
Code: Alles auswählen
[[ 0. -1. -0.5 0. 0. 0. ]
[ 1. 0. 0. -0.33333333 0. 0. ]
[ 0.5 0. 0. -0.33333333 -0.25 0. ]
[ 0. 0.33333333 0.33333333 0. 0. -0.2 ]
[ 0. 0. 0. 0.25 0. -0.2 ]
[ 0. 0. 0. 0.2 0.2 0. ]]
[[0.]
[0.]
[0.]
[0.]
[0.]
[0.]]
[[ 0.]
[-0.]
[ 0.]
[ 0.]
[-0.]
[ 0.]]
Was soll anderes rauskommen? Wie unterscheidet sich das von der tatsächlichen Ausgabe?
Re: Wörterbuch als Matrix umformulieren
Verfasst: Montag 4. Januar 2021, 14:34
von CaptainNeemo
@Sirius3 und @pillmuncher:
Wir haben in dem Wörterbuch von unserem Dozenten {Knotenpunkt: (Verbindungspunkt, Widerstand)} gegeben. Das alles versuche ich nun so zu schreiben, dass man der Funktion eine Spannung geben kann, welche am ersten und am letztem Knotenpunkt anliegt und diese dann im Sinne des Knotenpotentialverfahrens, die restlichen Spannungen berechnet. Das i mit r verglichen wird war ein Fehler meinerseits. i muss mit j verglichen werden, damit auf der Diagonale der Matrix die positive Summe steht und beim Rest die negative. Und dort wo keine Verbindung zwischen zwei Knoten besteht ist eine 0.
Und eigentlich wollte ich somit die Spannungen, an jedem Knotenpunkt berechnen.
Hier die überarbeitete Version:
Code: Alles auswählen
ResiLink = {0 : [(1,1.),(2,2.)],
1 : [(0,1.),(3,3.)],
2 : [(0,2.),(3,3.),(4,4.)],
3 : [(1,3.),(2,3.),(5,5.)],
4 : [(3,4.),(5,5.0)],
5 : [(3,5.),(4,5.0)]}
def main(ResiLink,sw=0,ew=1):
"""
Berechnung nach dem Knotenpotentialverfahren, wobei einem Knoten ein Anfangswert und ein Endwert gegeben werden kann. In diesem Falle per default(sw=0,ew=1).
"""
size = len(ResiLink)
ivec = np.zeros((size,1)) #Den Spaltenvektor der Spannungen
lgs = np.zeros((size,size)) #Die Matrix der Leitwerte
for i in range(size): #Befüllen der Matrix
line = ResiLink[i]
for (j,r) in line:
if i == j:
lgs[i,j] = 1/r
else:
lgs[i,j] = -1/r
solved = np.linalg.solve(lgs,ivec)
return solved
if __name__ == '__main__':
main(ResiLink)
Re: Wörterbuch als Matrix umformulieren
Verfasst: Montag 4. Januar 2021, 15:00
von pillmuncher
Das Ergebnis ist immer noch
Was soll
ivec denn sein?
Re: Wörterbuch als Matrix umformulieren
Verfasst: Montag 4. Januar 2021, 15:07
von __blackjack__
@CaptainNeemo: Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (MixedCase).
Man sollte keine kryptischen Abkürzungen verwenden. Das wird auch noch mal schlimmer wenn man Deutsch und Englisch mischt, denn dann weiss man im Zweifelsfall nicht mal in welcher Sprache eigentlich abgekürzt wurde.
`line` würde eher `row` heissen. Man muss aber auch nicht jedes kleine Zwischenergebnis an einen Namen binden.
Überarbeitet (ungetestet):
Code: Alles auswählen
#!/usr/bin/env python3
import numpy as np
RESI_LINK = {
0: [(1, 1), (2, 2)],
1: [(0, 1), (3, 3)],
2: [(0, 2), (3, 3), (4, 4)],
3: [(1, 3), (2, 3), (5, 5)],
4: [(3, 4), (5, 5)],
5: [(3, 5), (4, 5)],
}
def main(resi_link, start_value=0, end_value=1):
"""
Berechnung nach dem Knotenpotentialverfahren, wobei einem Knoten ein
Anfangswert und ein Endwert gegeben werden kann. In diesem Falle per
default (start_value=0, end_value=1).
"""
size = len(resi_link)
linear_equation_system = np.zeros((size, size))
for i in range(size):
for j, resistance in resi_link[i]:
linear_equation_system[i, j] = (1 if i == j else -1) / resistance
return np.linalg.solve(linear_equation_system, np.zeros((size, 1)))
if __name__ == "__main__":
print(main(RESI_LINK))
Re: Wörterbuch als Matrix umformulieren
Verfasst: Montag 4. Januar 2021, 15:44
von CaptainNeemo
@Sirius3 :
Danke für die Tipps, gerade den Variablen Tipp versuche ich mir mal besser einzuprägen. Und deine Lösung funktioniert sehr gut ich habe sie getestet und ist zudem kompakt. Finde es immer beeindurckend, wie kompakt man diese Dinge doch schreiben kann.
@pillmuncher
Und Ivec ist das Ergebnis der Gleichung aus (Matrix der Leitwerte) x (Spannungen der einzelnen Knoten) = Ivec. Und als Ergebnis möchte ich die Spannung der einzelnen Knoten erhalten wobei ich schon zwei Spannungen kenne, nämlich die Spannung des ersten sowie des letzten Knotens. Sprich wenn linalg.solve Matrizen nach folgendem Schema löst Ax= b, dann versuche ich b herauszufinden, und habe schon zwei Lösungen gegeben und versuche die gerade "einzubauen"
Re: Wörterbuch als Matrix umformulieren
Verfasst: Montag 4. Januar 2021, 15:54
von pillmuncher
@CaptainNeemo: Warum stehen dann in ivec lauter Nullen?
Re: Wörterbuch als Matrix umformulieren
Verfasst: Mittwoch 6. Januar 2021, 10:04
von CaptainNeemo
@pillmuncher:
Ja da gab es eine Verwirrung meinerseits, konnte das pysikalische Problem jedoch mit einem Studenten höheren Semesters lösen.