WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

Vektor effizient mehrfach teilweise auslesen

 

Eclipse

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 10.09.2010, 15:24     Titel: Vektor effizient mehrfach teilweise auslesen
  Antworten mit Zitat      
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
...
 

Eine for-Schleife ist deutlich zu langsam.

Mein Versuch war so etwas:
Code:

c(1:t) = f(1+(0:t-1)*2 : n+(0:t-1)*2) .* g
 


aber da funktioniert die "innere" Schleife nicht, also das 0:t-1, stattdessen ist die Ausgabe einfach nur f(1:n) .* g

Jemand eine Idee?


Eclipse

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 10.09.2010, 15:41     Titel:
  Antworten mit Zitat      
Sorry, 2 kleine Fehler drin, die ich leider oben nicht wegeditieren kann:

Code:

c(1:t) = sum(f(1+(0:t-1)*2 : n+(0:t-1)*2) .* g);
 


Und die Ausgabe ist dann nur sum(f(1:n) .*g ). Kern des Problems ist aber natürlich das gleiche.
 
lilov
Forum-Century

Forum-Century


Beiträge: 193
Anmeldedatum: 05.05.10
Wohnort: Bremerhaven
Version: ---
     Beitrag Verfasst am: 10.09.2010, 15:43     Titel:
  Antworten mit Zitat      
Hi,

hast du es mit
Code:
versucht?

Gruß,

lilov
Private Nachricht senden Benutzer-Profile anzeigen
 
Eclipse

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 10.09.2010, 15:52     Titel:
  Antworten mit Zitat      
Hi,

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

f2=[f(1) f(2) ... f(n) f(3) f(4) ... f(n+2) f(5) .... ]
 
Linus
Forum-Fortgeschrittener

Forum-Fortgeschrittener


Beiträge: 69
Anmeldedatum: 30.08.10
Wohnort: Aachen
Version: ---
     Beitrag Verfasst am: 10.09.2010, 16:31     Titel:
  Antworten mit Zitat      
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);

% magic ^^
c = dot(F, G);
 


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

RWTH - Mindstorms NXT Toolbox - free & open source
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 10.09.2010, 21:47     Titel: Re: Vektor effizient mehrfach teilweise auslesen
  Antworten mit Zitat      
Hallo Eclipse,

Ich verstehe schon die erste Zeile nicht:
Zitat:
Code:
c(1) = f(1:5) .* g

"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?

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
MatLabNooB
Forum-Guru

Forum-Guru


Beiträge: 262
Anmeldedatum: 27.03.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 11.09.2010, 11:24     Titel:
  Antworten mit Zitat      
moin,

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
Private Nachricht senden Benutzer-Profile anzeigen
 
Eclipse

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 11.09.2010, 13:20     Titel:
  Antworten mit Zitat      
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.

Also, Beispiel mit konkreten Zahlen:

Code:

f = [1 2 3 4 5 6 7 8 9];
g = [10 100 1000];

c(1) = sum(f(1:3) .* g) = 10 + 200 + 3000 = 3210
c(2) = sum(f(3:5) .* g) = 30 + 400 + 5000 = 5430
c(3) = sum(f(5:7) .* g) = 50 + 600 + 7000 = 7650
...
 


Code:

%Langsame Version
%anz = Anzahl der Einträge von c
c=zeros(1,anz);
for i=0:anz-1
c(1,i+1) = sum(f(1+2*i:length(g)+i*2) .* g);
end
 


@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.
 
MatLabNooB
Forum-Guru

Forum-Guru


Beiträge: 262
Anmeldedatum: 27.03.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 11.09.2010, 19:34     Titel:
  Antworten mit Zitat      
das sollte dann so gehn:

c = sum(f(iMat).*g)
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 12.09.2010, 21:07     Titel:
  Antworten mit Zitat      
Hallo Eclipse!

DOT ist wirklich langsam. Es wird aber automatisch bei der Matrix-Multiplikation durchgeführt:
Code:

f = [1 2 3 4 5 6 7 8 9];
g = [10 100 1000];
f = reshape(f, 3, []);
c = transpose(f) * g(:);

% c(1) = sum(f(1:3) .* g)
% c(2) = sum(f(4:6) .* g)  % Aber du willst 3:5 !
% c(3) = sum(f(7:9) .* g)  % Aber Du willst 5:7 !
 

Erstelle also zuerst eine [N x 3] Matrix und multipliziere sie mit g als [3 x 1] Vektor.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Eclipse

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 16.09.2010, 15:09     Titel:
  Antworten mit Zitat      
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?
 
Pinky
Forum-Anfänger

Forum-Anfänger


Beiträge: 34
Anmeldedatum: 14.11.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 14.11.2011, 15:08     Titel:
  Antworten mit Zitat      
Hallo,

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.

gruß Michael
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 14.11.2011, 23:23     Titel:
  Antworten mit Zitat      
Hallo Pinky,

Wie lautet Deine Frage?

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
lilov
Forum-Century

Forum-Century


Beiträge: 193
Anmeldedatum: 05.05.10
Wohnort: Bremerhaven
Version: ---
     Beitrag Verfasst am: 15.11.2011, 09:23     Titel:
  Antworten mit Zitat      
Hallo Pinky,


sind die Elemente denn indiziert? wenn ja, könnte es mit

Code:
klappen. Kannst du eine ausführliche Beschreibung deines Problems geben?

Gruß,

Hristo
Private Nachricht senden Benutzer-Profile anzeigen
 
Pinky
Forum-Anfänger

Forum-Anfänger


Beiträge: 34
Anmeldedatum: 14.11.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 15.11.2011, 09:26     Titel:
  Antworten mit Zitat      
Hallo Jan, die Frage ist wie gesagt fast die selbe wie die von Eclipse.

Ich habe eine Konnektivitätsmatrix und einen Vektor der Form:

Code:
Con = [ 1, 2, 0, 0; 3,4,5,0;6,0,0,0;7,8,9,10];
Vektor = 1:10;


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:

Code:
B = sum(Vektor(Con),2)


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

Code:
C = cell2mat(sum(Vektor(Con{:}),2))


nicht an. Vorrausgesetzt hierbei, ich habe Con als (4,1) cell mit (2 , 3, 1, 4) Einträgen eingegeben. Da erhalte ich immer nur den ersten Eintrag.

Leider kann ich das ganze auch nicht wirklich als Schleife schreiben, da es in einer DGL steht die ich lösen will.

Meine momentane Notlösung einer eigens definierten Funktion:

Code:
function [Erg]=summe(Con,vektor)
Dummy = zeros(size(Con));
Dummy(logical(Con'))=vektor;
Erg = sum(Dummy',2)


funktioniert zwar, ist aber recht langsam, besonders wenn die Matrix größer wird.

gruß Michael
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen

Gehe zu Seite 1, 2  Weiter

Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

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
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2025 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

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.