Verfasst am: 03.10.2014, 14:58
Titel: Vektor mit Indizes benutzen um Felder auszulesen. Ohne For
Ich würde gerne meine for-Schleife ersetzen.
Code:
% Das Programm:
a_1 = [1, 3, 5];
a_2 = [5,10,20]; % jedem Wert aus a_1 wird ein Wert zugordnet. (1->5, 3->10, 5->20)
b_1 = [3,3,3,5,1];
b_2 = zeros(1,size(b_1,1)); % Initialisierung des Lösungsvektors: b_2 = [0,0,0,0,0]; Wobei die Nullen ersetzt werden sollen.
% in b_1 stehen nun Werte aus a_1. In b_2 sollen nun die entsprechenden Werte aus a_2 stehen. Der Lösungsvektor ergäbe also: b_2 = [10, 10, 10, 20, 5].
% folgende for- Schleife würde das Problem lösen. for i = 1 : size(b_1,2) [wert index] = find( a_1==b_1(i),1,'last' ); % die 1 und das last könnte man sich hier auch sparen.
b_2(i) = a_2(index);
end
Warum sollte eine Ausdruck ohne Schleife wirklich viel schneller sein? In meinen Augen wird viel zu oft nach Ausdrücken ohne Schleife gefragt, die aber eher selten einen Performance Vorteil bringen, erst recht wenn die Matrizen recht kurz sind.
In deinem Fall wirst du aber auf die Schleife nicht verzichten können, wenn a_1 und b_1 eine unterschiedliche Anzahl an Elementen haben. Man könnte aber allein schon die Laufzeit verkürzen, wenn die Anzahl an Umläufen nach dem kürzeren Array a_1 ausgelegt ist.
Verfasst am: 03.10.2014, 19:03
Titel: Re: Vektor mit Indizes benutzen um Felder auszulesen. Ohne F
Hallo einfachrolf,
Der 2. Output von ISMEMBER wäre hier hilfreich. Bei größeren Datenmengen ist das effizienter, weil es die Inputs sortiert und die viel schnellere Binary Search angewendet wird.
Wenn es um die Performance geht, ist eine korrekte pre-allocation wichtig.
b_2 wird mit "size(b_1,1)" Elementen vordefiniert, später werden aber bis zu "size(b_1,2)" Elemente hineingeschrieben in Deinem Code.
FIND gibt den row und column Index aus, wenn es zwei Outputs zurück gibt. Dazu passen die Variablennamen "wert" und "index" nicht. Das klingt eher nach MAX oder MIN.
Warum sollte eine Ausdruck ohne Schleife wirklich viel schneller sein? In meinen Augen wird viel zu oft nach Ausdrücken ohne Schleife gefragt, die aber eher selten einen Performance Vorteil bringen, erst recht wenn die Matrizen recht kurz sind.
Natürlich sind die Matrizen in den Beispielen sehr klein.
Ich möchte statt den Schleifen versuchen möglichst auf Matlab-builtin Funktionen zurückgreifen.
Dies konnte ich durch einen komplizierten Umweg auch bereits erreichen und einiges an Rechenzeit einsparen. (Bei einigen Operationen fiel so die Rechenzeit von 30sec auf ca 1sec. Da ich einige dieser Operationen durchführe macht dies in der Summe einiges aus)
Verfasst am: 03.10.2014, 20:35
Titel: Re: Vektor mit Indizes benutzen um Felder auszulesen. Ohne F
Jan S hat Folgendes geschrieben:
Der 2. Output von ISMEMBER wäre hier hilfreich. Bei größeren Datenmengen ist das effizienter, weil es die Inputs sortiert und die viel schnellere Binary Search angewendet wird.
Vielen Dank! Werde ich gleich mal ausprobieren
Jan S hat Folgendes geschrieben:
Wenn es um die Performance geht, ist eine korrekte pre-allocation wichtig.
b_2 wird mit "size(b_1,1)" Elementen vordefiniert, später werden aber bis zu "size(b_1,2)" Elemente hineingeschrieben in Deinem Code.
Soll natürlich in beiden Fällen size(b_1,2) heißen .
FIND gibt den row und column Index aus, wenn es zwei Outputs zurück gibt. Dazu passen die Variablennamen "wert" und "index" nicht. Das klingt eher nach MAX oder MIN.
Stimmt natürlich auch. Meine Konzentration hat schon etwas nachgelassen.
a_1 = [1, 3, 5];
a_2 = [5,10,20]; % jedem Wert aus a_1 wird ein Wert zugordnet. (1->5, 3->10, 5->20)
b_1 = [3,3,3,5,1];
b_2 = zeros(1,size(b_1,2)); % Initialisierung des Lösungsvektors: b_2 = [0,0,0,0,0]; Wobei die Nullen ersetzt werden sollen.
% in b_1 stehen nun Werte aus a_1. In b_2 sollen nun die entsprechenden Werte aus a_2 stehen. Der Lösungsvektor ergäbe also: b_2 = [10, 10, 10, 20, 5].
% folgende for- Schleife würde das Problem lösen. for i = 1 : size(b_1,2) [row, col] = find( a_1==b_1(i),1,'last' );
b_2(i) = a_2(col);
end
% durch ismember bekomme ich [loca, locb] = ismember(b_1,a_1);
locb liefert mir nun die Indizies, wo meine gewünschten Werte in a_2 stehen. Wie bekomme ich nun aus dem Vektor mit den Indizes den Vektor mit den Werten?
Dazu reicht es nun das Problem nochmal seperat zu betrachten in folgendem unabhängigen Code:
Code:
locb = [22231];
a_2 = [5,10,20];
b_2 = ?
% Nun soll b_2 = [10, 10, 10, 20, 5] werden indem für die Indizes in locb jeweils die Werte aus a_2 eingetragen werden.
Dein erster Vorschlag ist leider nicht allgemein. Aber ein guter Ansatz wie ich finde. Da muss ich nochmal in Ruhe drüber nachdenken, ob man es irgendwie so verallgemeinern kann.
Genau das tust du zwar im nächsten Vorschlag, jedoch möchte ich keine Schleife benutzen. Deshalb bin ich noch nicht wirklich weiter.
Einstellungen und Berechtigungen
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.