Verfasst am: 10.09.2010, 15:24
Titel: Vektor effizient mehrfach teilweise auslesen
Moin,
der Titel ist vielleicht etwas irreführend, deswegen erkläre ich mein Problem etwas ausführlicher:
Ich habe einen langen Vektor f (mehrere 1000 Einträge) und möchte daraus jeweils n-Blöcke (mit kleinem n, z.B. 4) auslesen, um diesen dann komponentenweise mit einem anderen Vektor g der Länge n zu multiplizieren.
Beispiel:
c soll der Ergebnisvektor sein.
Code:
c(1) = f(1:5) .* g
c(2) = f(3:7) .* g
c(3) = f(5:9) .* g
...
da seh ich absolut nicht, wie mir das helfen kann leider. Das Problem ist ja, dass ich den Vektor f nicht nur irgendwie reshapen möchte, sondern dass da auch Einträge u.U. mehrfach vorkommen müssen.
In obigem Bsp. müsste er z.B. die Form haben
Ich hätte da ne ganz ganz grobe Idee, aber keine Ahnung ob das schneller Funktioniert...
Du würdest dir erst eine nxN-Matrix aus f basteln (N = length(f)), in der Hoffnung das das nicht zu lange dauert. Dortselbst sind als Spalten die Einträge von f drin, die du brauchst, also:
Code:
% gehe davon aus, dass f ein Zeilenvektor ist, sonst transponieren weglassen
F = [f(1:5)' f(3:7)' ...];
% natürlich muss das hier schön automatisch schnell gehen...
% dann baust du dir das gleiche aus g: % gehe wieder davon aus, dass g ein Zeilenvektor ist
G = repmat(g', 1, N);
Das hier würde natürlich viel Speicher brauchen, ein vielfaches von f leider. Aber denke trotzdem dass das kein Problem sein sollte. Das schöne ist, dass dot() vektorisiert ist, wenn du also 2 gleichgroße Matrizen reinschiebst, wird spaltenweise das .* ausgeführt, und du kriegst einen Zeilenvektor mit den einzelnen Ergebnissen...
_________________
"c(1)" ist ein Skalar, "f(1:5) .* g" hat aber 5 Elemente.
Bitte gibt nochmla ein Beispiel mit echten Zahlen für c, f und g an. Poste auch Deine langsame Schleife. Eigetnlich sind ein paar tausend Zahlen kein Problem. Möglicherweise ist c nit preallociert?
ich hab wie Jan S. auch ein Verständnisproblem sollte der Output Skalar sein, es müsste ein Vektor sein, wenn ja, dann kannst du sowas machen:
du baust mittels meshgrid oder repmat ne indexmatrix auf zB:
iMat = [1 3 5; 2 4 6; 3 5 7; 4 6 8; 5 7 9]
dann musst du nurnoch berechnen
c = f(iMat).*g
Eclipse
Gast
Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
Verfasst am: 11.09.2010, 13:20
Titel:
Ihr habt natürlich beide Recht, habe da oben im ersten Post überall das sum() vergessen, bzw. sehe gerade, dass der Befehl, nach dem ich mich totgesucht hatte dot() lautet, der macht ja eben das - komponentenweise multiplizieren, dann addieren. Allerdings habe ich festgestellt, dass dot deutlich langsamer ist, als sum(a .* b), jedenfalls für Vektoren.
@Linus:
Danke für deine Ideen. Leider ist der Kern des Problems eben die erste Zeile, das automatisch und effizient hinzubekommen ist ja schon das schwierigste.
Der Speicherbedarf ist allerdings auch ein Problem.
Ich habe eine alternative Implementierung mittels Sparse-Matrizen gebaut, die aber auch noch um den Faktor 10 langsamer als die Referenzimplementierung ist.
Erstelle also zuerst eine [N x 3] Matrix und multipliziere sie mit g als [3 x 1] Vektor.
Gruß, Jan
Eclipse
Gast
Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
Verfasst am: 16.09.2010, 15:09
Titel:
Danke für eure Tips und Hinweise, aber ich halte mich jetzt an die schnelle Variante (Faltung und dann jeden 2. Eintrag nehmen, falls es interessiert).
Dabei ist mir allerdings eine interessante Sache aufgefallen:
Wieso läuft Faltung von Vektoren per conv2 schneller als per conv? Gibt es da irgendwo eine Doku zu?
ich möchte an der Stelle eine ähnliche Frage stellen, für die ich keine zufriedenstellende Lösung gefunden habe.
Mein Problem ist eigentlich das selbe wie das von Eclipse, bis auf den kleinen Umstand, dass die jeweilige Länge der zu summierenden Elemente variabel ist.
Ich habe also einen langen Vektor dessen ersten 4 Elemente ich summieren will, dann 7 dann 5 usw. Der Weg mit der Matrix geht dann leider nicht und auch mit cells tut sich matlab da sehr schwer.
Nun will ich relativ ähnlich zu Eclipse dass entsprechend der (zufällig ermittelten) Matrix die Elemente des Vektors addiert werden. Raus kommen soll also ein Vektor der Form:
Das Problem, dass Matlab mir nun bereitet ist, dass es mit den leeren Einträge nicht klar kommt. Es kann den Index 0 nicht finden. Wenn ich allerdings logical(Con) oder ähnliches eingebe, bekomme ich einen Vektor den ich dann eben nicht wie gewollt aufsummieren kann.
Ich habe es auch schon mit einem cell-array probiert, allerdings nimmt matlab die Eingabe
Du kannst Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen. Du kannst Dateien in diesem Forum posten Du kannst Dateien in diesem Forum herunterladen
MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.