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

Vektorisierung einer Matrixbefüllung

 

Pixel
Forum-Newbie

Forum-Newbie


Beiträge: 2
Anmeldedatum: 27.10.13
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 27.10.2013, 14:16     Titel: Vektorisierung einer Matrixbefüllung
  Antworten mit Zitat      
Hallo,

für ein Programm mit dem ein Roboter später Hindernisse umfahren soll benötige ich an einem Punkt statt einer For-Schleife eine Vektorisierung und erhoffe mir davon eine bessere Performance.

Es geht darum, dass eine 3D-Matrix auf jeder Ebene ein 2D-Bild erhält, wobei der Index der Ebene angibt wie weit das auf ihr liegende Bild über circshift verschoben ist. Es gilt, die folgende Schleife zu vektorisieren:

Code:
for i=1:40
data(:,:,i)=circshift(bild,[0 (i)]);
end


Folgendes habe ich bereits probiert, was allerdings falsch zu sein scheint:

Code:
v=1:40;
data_c(:,:,v)=circshift(bild,[0 (v)])


Es kommt diese Fehlermeldung:
??? Assignment has fewer non-singleton rhs dimensions than
non-singleton
subscripts

Ich wäre für jede Hilfe dankbar!
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: 27.10.2013, 17:17     Titel: Re: Vektorisierung einer Matrixbefüllung
  Antworten mit Zitat      
Hallo Pixel,

Statt der Vektorisierung würde ich zunächst eine Kopie des Codes von CIRCSHIFT in Deine Schleife einfügen und dabei das Parsen der Inputs und das Error-Handling weglassen. Wenn Du das dann noch vereinfachst (die 0 in [0, i] kann man ja getrost ignorieren), sollte das schon sehr effizeint sein.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Pixel
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 2
Anmeldedatum: 27.10.13
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 27.10.2013, 17:34     Titel:
  Antworten mit Zitat      
Hallo Jan

danke für die Antwort. Könntest du mir vielleicht ein Beispiel zeigen, da ich als Matlab-Anfänger mit den Begriffen nichts anzufangen weiß.
Die Schleife muss am Ende nicht nur 40, sondern auch 200 mal für ein Bild durchlaufen, das dauert im Moment auch mal 2-10 Sekunden, im Idealfall hätte ich das natürlich gern deutlich schneller (<100-200ms).

Gibt es keine Möglichkeit, dem 3D-Array mit einem Befehl wie 'data(:,:,v)=...' in einer Zeile für jedes Element de Vektors die entsprechenden Werte zuzuweisen?

Gruß
Pixel
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: 27.10.2013, 23:15     Titel: Re: Vektorisierung einer Matrixbefüllung
  Antworten mit Zitat      
Hallo Pixel,

Code:
data = zeros([size(bild), 40]);  % Pre-allocation!!!
s2 = size(bild, 2);
for k = 1:40
  data(:,:,k) = bild(:, mod(-k:s2-1-k, s2) + 1);
end

Die Pre-allocation macht hier schon mal einen großen Unterschied, da nicht in jeder Iteration ein neues Array erstellt werden und die bisherigen daten kopiert werden müssen.
Damit komme ich bei einem 1000x1000 Array schon von 7.7 of 0.6 Sekdungen, wenn CIRCSHIFT benutzt wird. Mit dem inlined Code oben, der alles macht, was CIRCSHIFT auch macht, lassen sich kaum Verbesserungen erzielen, da der Overhead von CIRSHIFT hier vernachlässigbar ist.

Deutlich schneller wird das aber, wenn nicht die Input-Matrix immer wieder geshiftet wird, sondern der Index im zu erstellenden Output-Array:
Code:
n    = 40;
data = zeros([size(bild), n]);  % Pre-allocation!!!
s2   = size(bild, 2);
for k = 1:n
  data(:, mod(k:s2-1+k, s2) + 1, k) = bild;
end

Damit komme ich auf 0,35 Sekunden.

Die Vektorisierung würde huier nicht viel bringen, da dann das Erstellen der großen Index-Matrix viel Zeit beanspruchen würde.

Allerdings ist das Erstellen eines großen Arrays mit nahezu redundanter Information im Allgemeinen eine schlechte Strategie. Wozu soll das Array künstlich aufgeblasen werden? Wäre es nicht geschickter, das "on-the-fly" zu machen, wenn die geshifteten Untermatritzen verwendet werden?

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

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 28.10.2013, 01:04     Titel:
  Antworten mit Zitat      
Guten Abend,

wieder einmal vielen Dank für die Antwort. Innerhalb der Schleife soll im Programm nicht allein das geshiftete Bild, sondern der Betrag der Differenzen des geshifteten und eines weiteren Bildes gespeichert werden. Ich nahm Anfangs an, dass die Matrixgröße dabei keinen signifikanten Performanceeinfluss hat, doch damit lag ich wohl falsch. Auch wenn ich die Subtraktion mit dem Befehl 'imabsdiff' gegenüber einer manuellen Variante verbessern konnte, so beansprucht das Programm bei der vollen Bildauflösung von 1280*800p und 100 Verschiebungen knapp 5 Sekunden, was definitiv zu lang ist.

Momentan sieht das ganze so aus, wobei data_l und data_r die beiden verschiedenen Bilder sind:

Code:
data=ones(size(data_l,1),size(data_l,2),m);
s2   = size(data_l, 2);
for k=1:m
data_c(:,:,k) = imabsdiff((data_r(:, mod(-k:s2-1-k, s2) + 1)),(data_l));
%data(:,:,k) = (data_r(:, mod(-k:s2-1-k, s2) + 1));
end


Ich wäre froh wenn jemand noch ein paar Ideen zu Performanceverbesserung nennen könnte.

Gruß,
Pixel
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 29.10.2013, 13:51     Titel:
  Antworten mit Zitat      
Hallo Pixel_,

Oh, das Einfügen von IMABSDIFF ist eine andere Geschichte. Bitte poste solch wichtige Details unbedingt gleich am Anfang.
Da man IMABSDIFF für DOUBLEs laut des Hilfe-Textes mit ABS(A-B) ersetzen kann, würde ich das mal probieren. Es wundert mich aber immer noch, dass dieses Programm 5 Sekunden braucht.
Ich kann auch nicht mehr nachvollziehen, welche Geschwindigkeits-Gewinne meine Vorschläge bewirken. Das macht es schwierig, weitere Vorschläge zu machen.

Bitte verwende den Profiler um das Bottleneck zu finden.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen



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.