ubuntuusers.de

Operationen mit Matrizen

Status: Gelöst | Ubuntu-Version: Nicht spezifiziert
Antworten |

Hello_World

Anmeldungsdatum:
13. Juni 2006

Beiträge: Zähle...

PhotonX schrieb:

Was macht denn dieses izip()?

rtfm. http://docs.python.org/library/itertools.html#itertools.izip

Fredo Team-Icon

Avatar von Fredo

Anmeldungsdatum:
27. Juni 2005

Beiträge: 5244

Wohnort: Bochum

PhotonX schrieb:

Fredo: Die Denke bei Python war einfach die, dass es weit verbreitet ist (ergo viele Tutorials existieren und auch viele Forenmitglieder sich damit auskennen und helfen können 😉 ) und dass es ziemlich einfach sein soll. Und nachdem ich bisher noch überhaupt nicht programmieren kann, dachte ich, Python sei perfekt für den Einstieg.

Ja, Python ist auch ziemlich perfekt für den Einsteig in die Programmierung, aber …

Aber kann gut sein, dass R besser für mein Anliegen geeignet ist.

… genau das. Wenn man mit mehrdimensionalen Objekten arbeitet, ist es natürlich von Vorteil, wenn die verwendete Sprache das schon unterstützt. Und R ist für sowas nunmal konzipiert. Ich will auch gar nicht sagen, dass es mit Python nicht ginge. Und vermutlich lernst Du so auch noch einiges über Python. Aber R sollte zumindest in diesem Zusammenhang erwähnt werden, entscheiden kannst Du ja immer noch. ☺

Das Blöde ist, dass man nach "R" so schlecht googeln kann...

Ja, das ist wahr. Dafür gibt es aber immerhin http://www.rseek.org/

Ich bin mittlerweile zu Arch umgestiegen (man hat ja in den Sommerferien nichts zu tun 😉 ) und da hab ich bis jetzt nur ein Paket "r" finden können. Das entspricht wohl r-base aus den Ubuntu-Quellen - also nichts mit einem grafischen Editor und so. Nur die R-Konsole im Terminal. Und keine Ahnung, was man damit anstellen soll. ☺ Ich hab hier sowas gefunden: http://cran.r-project.org/doc/manuals/R-intro.html#Arrays-and-matrices Aber viel hilft mir das noch nicht... Erstmal: Wie schreibt man mit dem Ding überhaupt ein Programm? Es scheint ja sowas wie die Python Shell zu sein, oder?

Ja, genau. Es ist ein interaktiver Interpreter, wie bei Python auch. Du kannst aber auch gerne Dein Programm in eine Datei schreiben und dann mit

R < meinskript.R

ausführen.

Eine Matrix kriegt man auch recht einfach, und dann müsstest Du halt ein bisschen rumspielen. Eine gute Einführung ist simpleR.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
m <- matrix(c(1,1,0,0,
              0,1,1,0,
              1,0,1,0,
              1,0,0,1,
              0,1,0,1,
              0,0,1,1),
             nrow=6, byrow=TRUE)
print(m)
# Matrizen lassen sich wie Listen in Python ansprechen,
# nur haben sie zwei Dimensionen.
# Die erste Spalte kriegt man so:
print(m[,1]) # Achtung: In R fangen Indizes bei 1 an,
             # nicht wie in Python bei 0!

# Die Spalten lassen sich auch beliebig anordnen:
print(m[,c(4,3,2,1)])

Liebe Grüße
Fredo

PhotonX

(Themenstarter)
Avatar von PhotonX

Anmeldungsdatum:
3. Juni 2007

Beiträge: 4471

Wohnort: München

Fredo, vielen Dank, das klingt ja gar nicht so hoffnungslos mit dem R. ☺ Der Python-Code ist schon etwas gewachsen und sieht im Moment so aus: http://paste.ubuntuusers.de/396066/ Aber ich muss die Prozesse alle neu schreiben, weil mir eine andere Methode eingefallen ist (Ecken/Flächen- statt Ecken/Kanten-Inzidenzmatrizen), also mach ich das bei der Gelegenheit gleich in R. ☺ Hab noch eine eher kosmetische Frage: Im Moment hab ich es mir in GEdit mit dem Plugin für Externe Werkzeuge mit folgendem Befehl bequem gemacht:

R --vanilla --silent < $GEDIT_CURRENT_DOCUMENT_PATH

Da wird aber der ganze Programm-Code inkl. Kommentare ausgegeben. Kann man das irgendwie so ausführen lassen, dass nur das was mit print-Befehlen ausgegeben wird, angezeigt wird?

Und dann noch eine Sache, die mir in der Python-Version schon gefehlt und mich vom Schreiben des Hauptprogramms abgehalten hat (neben dem fehlenden Sortieralgorithmus): Kann man irgendwie Variablen mit variablen Dateinamen erstellen? Also etwas wie:

1
2
for prozess in [prozess_p3, prozess_q3, prozess_q3]:
  polyeder_$prozess=prozess(polyeder) # für $prozess soll der Prozessname eingefügt werden

Fredo Team-Icon

Avatar von Fredo

Anmeldungsdatum:
27. Juni 2005

Beiträge: 5244

Wohnort: Bochum

PhotonX schrieb:

Fredo, vielen Dank, das klingt ja gar nicht so hoffnungslos mit dem R. ☺ Der Python-Code ist schon etwas gewachsen und sieht im Moment so aus: http://paste.ubuntuusers.de/396066/ Aber ich muss die Prozesse alle neu schreiben, weil mir eine andere Methode eingefallen ist (Ecken/Flächen- statt Ecken/Kanten-Inzidenzmatrizen), also mach ich das bei der Gelegenheit gleich in R. ☺ Hab noch eine eher kosmetische Frage: Im Moment hab ich es mir in GEdit mit dem Plugin für Externe Werkzeuge mit folgendem Befehl bequem gemacht:

R --vanilla --silent < $GEDIT_CURRENT_DOCUMENT_PATH

Da wird aber der ganze Programm-Code inkl. Kommentare ausgegeben. Kann man das irgendwie so ausführen lassen, dass nur das was mit print-Befehlen ausgegeben wird, angezeigt wird?

Nein, ich befürchte, das geht nicht.

Und dann noch eine Sache, die mir in der Python-Version schon gefehlt und mich vom Schreiben des Hauptprogramms abgehalten hat (neben dem fehlenden Sortieralgorithmus): Kann man irgendwie Variablen mit variablen Dateinamen erstellen? Also etwas wie:

1
2
for prozess in [prozess_p3, prozess_q3, prozess_q3]:
  polyeder_$prozess=prozess(polyeder) # für $prozess soll der Prozessname eingefügt werden

Warum speicherst Du das nicht einfach in einer Liste?

Liebe Grüße
Fredo

PhotonX

(Themenstarter)
Avatar von PhotonX

Anmeldungsdatum:
3. Juni 2007

Beiträge: 4471

Wohnort: München

Naja, das Hauptprogramm wird (wenn alle Probleme irgendwann gelöst sind und alles funktioniert) bei einer Polyedermatrix starten, auf diese Matrix alle Prozesse anwenden, dann jedes der Ergebnisse nehmen und wieder alle Prozesse drüber laufen lassen, usw. Ich weiß gar nicht, wie man das sinnvoll in eine Liste organisieren könnte... Wobei eigentlich könnte man das ausprobieren, man müsste die Liste nur irgendwie dynamisch wachsend machen können, aber das geht ja. Dann könnte man die Matrizen mit gleichen Abmessungen in Unterlisten speichern und die Duplikatenchecks nur innerhalb der passenden Unterliste machen. Genial! 😀 Ok, das dauert jetzt ein paar Tage, bis ich mit meinen Kenntnissen das alles umgesetzt bekomme und sich das Problem der Sortierung stellt. ☺

PhotonX

(Themenstarter)
Avatar von PhotonX

Anmeldungsdatum:
3. Juni 2007

Beiträge: 4471

Wohnort: München

Ich hab hier nach langem Rumgesuche den Prozess p3 für Ecken/Flächen-Inzidenzmatrizen in R nachgeschrieben:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
prozess_p3=function(polytop, ecke){

if(sum(polytop[,ecke])==3){

polytop_backup=polytop

polytop1=polytop[polytop[,ecke]==1,]
zusatz1=matrix(c(0,1,1,1,0,1,1,1,0), nrow=3)
polytop1=cbind(polytop1,zusatz1)

polytop0=polytop[polytop[,ecke]==0,]

polytop=matrix(0,(nrow(polytop_backup)+1),(ncol(polytop_backup)+3))

polytop[0:3,0:(ncol(polytop_backup)+3)]=polytop1
polytop[4:nrow(polytop_backup),0:ncol(polytop_backup)]=polytop0
polytop[nrow(polytop_backup)+1,(ncol(polytop_backup)+1):(ncol(polytop_backup)+3)]=1

polytop=polytop[,-ecke]

polytop}}

Ohne einer Beschreibung der Vorgehensweise kann man das vermutlich nicht nachvollziehen, aber evtl. hab ich ja etwas offensichtlich Blödes gemacht... Übrigens, den ganzen unnötigen Output kann man bei R mit der Option --slave verstecken. ☺ Das Problem mit der Sortierung hat sich mittlerweile durch die e/f-Inzidenzmatrizen erledigt. Was mir aber noch abgeht, ist eine Möglichkeit, ganze Matrizen in eine "Obermega-Matrix" einzubinden (so wie du vorgeschlagen hast, nur nicht einfach in eine Liste speichern, sondern in eine Datenbank-Matrix, sodass jedes database[x,y] eine Liste mit Matrizen der Abmessungen x und y beinhaltet). Kann man das irgendwie realisieren? 😕

Fredo Team-Icon

Avatar von Fredo

Anmeldungsdatum:
27. Juni 2005

Beiträge: 5244

Wohnort: Bochum

PhotonX schrieb:

Ohne einer Beschreibung der Vorgehensweise kann man das vermutlich nicht nachvollziehen, aber evtl. hab ich ja etwas offensichtlich Blödes gemacht...

Sieht doch erst mal gut aus. R-Code ist leider auch selten schön zu lesen.

Übrigens, den ganzen unnötigen Output kann man bei R mit der Option --slave verstecken. ☺

Auch gut zu wissen. ☺

Das Problem mit der Sortierung hat sich mittlerweile durch die e/f-Inzidenzmatrizen erledigt. Was mir aber noch abgeht, ist eine Möglichkeit, ganze Matrizen in eine "Obermega-Matrix" einzubinden (so wie du vorgeschlagen hast, nur nicht einfach in eine Liste speichern, sondern in eine Datenbank-Matrix, sodass jedes database[x,y] eine Liste mit Matrizen der Abmessungen x und y beinhaltet). Kann man das irgendwie realisieren? 😕

Puh, da bin ich auch etwas überfragt. Vielleicht kann man etwas mit geschachtelten Listen machen, aber so richtig komfortabel ist das auch nicht. Vielleicht mal auf der R-Mailingsliste nachfragen? Das ist ja schon ein etwas spezielleres Problem.

Liebe Grüße
Fredo

PhotonX

(Themenstarter)
Avatar von PhotonX

Anmeldungsdatum:
3. Juni 2007

Beiträge: 4471

Wohnort: München

Ich habe ziemlich schnell eine Antwort bei der Mailing-List bekommen, es geht so:

database=matrix(list(),10,10)

Die ganze Liste kriegt man so:

database[[x,y]]

und ein einzelnes Element der Liste ganz normal so:

database[[x,y]][n]

Aber leider hab ich mich zu früh gefreut, was die Sortierung der Matrizen angeht... Die muss man doch machen. 😕 Naja, im Notfall frag ich da auch wieder in der Mailing-List nach. ☺

PhotonX

(Themenstarter)
Avatar von PhotonX

Anmeldungsdatum:
3. Juni 2007

Beiträge: 4471

Wohnort: München

Hallo noch mal, ☺

ich bin mittlerweile an einem Punkt angelangt, wo das Vergleichen zweier Matrizen nötig geworden ist. Das Programm läuft schon, aber im Moment wird einfach anhand der Zeilen- und Spaltensummen verglichen und, wenn sie übereinstimmen, dann werden die Matrizen als äquivalent angenommen. Das stimmt natürlich nicht, deswegen muss ein guter Vergleichs- bzw. Sortierungsalgorithmus her... Mein Ansatz ist wie folgt (in Pseudocode):

# Ziel: Schreibt man alle Reihen der Matrix nach der Sortierung in eine Zeile hintereinander, soll eine möglichst große Binärzahl herauskommen.
# Erlaubte Operationen beim Sortieren: Vertauschen von Zeilen, Vertauschen von Spalten.
# Beispielmatrix, die sortiert werden soll:

     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,]    0    1    1    1    0    1    1    0
[2,]    1    1    0    0    0    1    0    1
[3,]    1    0    1    0    0    0    1    1
[4,]    1    1    0    0    1    0    0    0
[5,]    1    0    1    1    1    0    0    0
[6,]    0    1    0    1    1    0    0    0
[7,]    0    0    0    0    0    1    1    1

# Nützliche Eigenschaften der Matrizen:
# - Jede zwei Zeilen haben an maximal 2 Stellen beide Einsen (Bsp. Zeilen 1 und 2: [1,2]<>[2,2] und [1,6]<>[2,6]). Das Gleiche gilt für jede zwei Spalten.
# - In jeder Spalte und in jeder Zeile gibt es mindestens 3 Einsen und mindestens 1 Null. 

# Ansatz:
- Sortiere die Zeilen nach Anzahl der Einsen (die Beispielmatrix ist schon so sortiert). # Realisierung in echtem Code kein Problem 
- Sortiere die Spalten so, dass die Spalten, in denen in der ersten Zeile Einsen stehen vorne stehen. Speichere den linken Teil der Matrix (nur Einsen in der ersten Zeile) und den rechten Teil (nur Nullen in der ersten Zeile) in getrennten Matrizen, # Realisierung in echtem Code auch kein Problem.
- Sortiere die Spalten beider Teilmatrizen so, dass in der zweiten Zeile die Einsen vorne und die Nullen hinten stehen. Trenne sie wieder in je zwei Teilmatrizen.
- Führe den letzten Schritt so oft aus, bis jede Teilmatrix aus einer einzigen Spalte besteht. Setze alle Spalten danach sortiert zu einer Matrix zusammen. # Da weiß ich nicht, wie man die ganzen Schritte, die sich auch noch verzweigen in eine Schleife packen kann... Das Speichern von beliebig vielen Teilmatrizen und das richtige Zusammensetzen aller Spalten ist auch noch ein Problem, aber vermutlich kann man das mit Listen und Unter(unter)listen machen.
- Mache das gleiche mit einer zweiten Matrix und vergleiche beide elementenweise # Auch kein Problem

Die Methode hat zwei Probleme: Einerseits weiß ich nicht, wie man die Verzweigungen in eine Schleife packen kann, andererseits gibt es noch ein grundlegendes Problem: Was ist, wenn es zwei oder mehr Zeilen mit gleicher Anzahl von Einsen gibt? Kommt man dann je nachdem, welche der Zeilen nach oben gekommen ist, zu unterschiedlichen Endergebnissen bei eigentlich äquivalenten Matrizen? Bei beliebigen Matrizen wäre es sicher der Fall, aber bei solchen besonderen (siehe nützliche Eigenschaften) vielleicht nicht? Bitte um etwas Input! ☺

MfG PhotonX

P.S.: Das ganze Programm sieht momentan so aus: http://paste.ubuntuusers.de/396134/ Wenn es etwas offensichtlich Blödes gibt, bitte meckern! ☺

berndth

Anmeldungsdatum:
26. September 2007

Beiträge: 290

Kleiner Tipp zum Thema Numerik (insbesondere Matrizenrechnung) und Python: SciPy / Numpy sind ganz nett.

PhotonX

(Themenstarter)
Avatar von PhotonX

Anmeldungsdatum:
3. Juni 2007

Beiträge: 4471

Wohnort: München

Danke, Numpy kenn ich schon, aber ich versuch das ja in R zu schreiben, das von vornherein gut mit Matrizen umgehen kann. ☺

Antworten |