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

Matrix von Matrix berechnen

 

Vladi

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 04.08.2010, 20:38     Titel: Matrix von Matrix berechnen
  Antworten mit Zitat      
Guten abend an alle.

Zuerst einmal: schönes Forum, hat mir schon oft geholfen, leider hab ich diesesmal nichts gefunden was mir helfen könnte...

Ich habe folgendes Problem:

Ich habe einen Vektor
Code:
und eine Matrix
Code:

B=[1,2,3;
   2,3,4;
   3,4,5]
 
.
Ferner ist noch eine Matrix
Code:

A=[1,3,5,6;
   2,4,1,8;
   0,5,0,3;
   3,5,1,2;
   4,8,6,4]
gegeben.
Ich möchte nun auf die Spalten von A zugreifen, welche in C gegeben sind, und von der jeweiligen Spalte, die Zeiten, die in B gegeben sind. Klingt komisch...

Ergebnis E sollte also sein:
Code:

E=[1,1,3;
   2,0,2;
   0,1,4]
.

Code:
reduziert das Problem, da bereits die richtigen Spalten ausgewählt sind. Auf die Zeilen, die in B angegeben sind, kann ich jedoch nicht zugreifen. Vielleicht weiß ja hier jmd. wie das funktioniert.

ps: B ist übrigens zufällig, d.h. die Einträge der Spalte(i) ergibt sich nicht aus den der Spalte(i-1)+1.

Vielen Dank schonmal vorab.
Viele Grüße
der Vladi


Vladi

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 04.08.2010, 20:47     Titel:
  Antworten mit Zitat      
Was ich vergessen hatte, ich möchte auf eine Schleife versichten, die C durchläuft.

Ich denke, dass das mit EINEM Befehl möglich sein sollte.

Danke!

Viele Grüße
der Vladi
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 04.08.2010, 21:06     Titel:
  Antworten mit Zitat      
Hallo,

bitteschön...

Code:
A(sub2ind(size(A), B, repmat(C, size(B,1), 1)))


*Gehirnwindungen entknotet*

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
Vladi

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 05.08.2010, 10:53     Titel:
  Antworten mit Zitat      
Hallo Harald,

vielen Dank für deine Lösung.
Funktioniert!

Leider ist meine Matrix ziemlich groß. sub2ind benötigt jetzt so viel Zeit, dass die Schleife durch C die schnellere Alternative ist.

Gibts vllt. noch ne andere Methode die auf sub2ind verzichtet?

Danke nochmals
Viele Grüße
der Vladi
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 05.08.2010, 11:37     Titel:
  Antworten mit Zitat      
Hallo,

häng doch mal das konkrete Beispiel (oder einen ausreichend großen Teil davon) und deinen bisherigen Code an. Ich schau heute abend mal, ob ich Verbesserungen finde.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
Vladi

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 05.08.2010, 14:24     Titel:
  Antworten mit Zitat      
Hallo nochmals,

Code:
function codeBsp()

allValues = rand(7200,244);

columns_up   = (6:2:244);
columns_mid  = (5:2:243);
columns_down = (4:2:242);

rows_up   = (19:7183)';
rows_mid  = (17:7181)';
rows_down = (16:7180)';

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Approach 1: sub2ind
tic
repColumns = repmat(columns_down, size(rows_down), 1);
repRows = repmat(rows_down, size(columns_down), 1);
indices = sub2ind(size(allValues), repRows, repColumns);
table1 = allValues( indices );
%
% this is done 6 times for all possible combinations
% - rows_up AND columns_up
% - rows_mid AND columns_up
% - rows_down AND columns_up
% - rows_up AND columns_down
% - rows_mid AND columns_down
%
% the tables 1 to 6 are then added up.
repColumns = repmat(columns_down, size(rows_mid), 1);
repRows = repmat(rows_mid, size(columns_down), 1);
indices = sub2ind(size(allValues), repRows, repColumns);
table2 = table1 + allValues( indices );

repColumns = repmat(columns_down, size(rows_up), 1);
repRows = repmat(rows_up, size(columns_down), 1);
indices = sub2ind(size(allValues), repRows, repColumns);
table3 = table2 + allValues( indices );

repColumns = repmat(columns_up, size(rows_down), 1);
repRows = repmat(rows_down, size(columns_up), 1);
indices = sub2ind(size(allValues), repRows, repColumns);
table4 = table3 + allValues( indices );

repColumns = repmat(columns_up, size(rows_mid), 1);
repRows = repmat(rows_mid, size(columns_up), 1);
indices = sub2ind(size(allValues), repRows, repColumns);
table5 = table4 + allValues( indices );

repColumns = repmat(columns_up, size(rows_up), 1);
repRows = repmat(rows_up, size(columns_up), 1);
indices = sub2ind(size(allValues), repRows, repColumns);
table6 = table5 + allValues( indices );

% Create resulting matrix that has the columns of table6 at the columns
% given in columns_mid. The rows are given in rows_mid and don't differ
resultApproach1 = zeros(size(allValues));
resultApproach1(rows_mid(:,1), columns_mid) = table6;
display(['App 1: sub2ind took: ', num2str(toc), ' sec']);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Approach 2: loop
tic
resultApproach2 = zeros(size(allValues));
necessaryValues = zeros(size(rows_mid,1), 6);
for i = 1 : size(columns_mid,2)
    necessaryValues(:,1) = allValues( rows_down , columns_down(1,i) );
    necessaryValues(:,2) = allValues( rows_mid , columns_down(1,i) );
    necessaryValues(:,3) = allValues( rows_up , columns_down(1,i) );
    necessaryValues(:,4) = allValues( rows_down , columns_up(1,i) );
    necessaryValues(:,5) = allValues( rows_mid , columns_up(1,i) );
    necessaryValues(:,6) = allValues( rows_up , columns_up(1,i) );
   
    resultApproach2(rows_mid, columns_mid(1,i)) = sum(necessaryValues,2);
end
display(['App 2: looping took: ', num2str(toc), ' sec']);

if isequal(resultApproach1, resultApproach2)
    display('results are equal');
else
    display('results not equal');
end


Erklärung zum Beispiel:
Ich muss 6 Kombinationen berechnen und diese dann addieren.

Die erste Kombination entsteht für rows_down und columns_down.
rows_down und columns_down enthalten jeweils die Indizes mit denen dann auf allValues zugegriffen wird.
So entsteht eine erste Matrix der Größe (size(rows_down), size(columns_down)). Das passiert sechs mal (für die noch fehlenden Kombinationen).

Die sechs Matrizen werden dann addiert, es entsteht table6.

Diese Werte werden nun in eine leere Matrix geschrieben, und zwar an die Stellen, die in rows_mid und columns_mid angegeben werden. Hier braucht man kein sub2ind, denn rows_mid ist vektor.


Bei mir ist die erste Variante 5 mal langsamer als die zweite.
Das wird noch schlimmer für größere Matrizen.

Für weitere Fragen stehe ich natürlich gerne bereit. Danke schonmal für deine Mühe!

Viele Grüße
der Valdi

ps: In diesem Beispiel (und auf meinem Rechner) dauert das ca. 0.48 und 0.14 sec. Das ist nicht lange. In meinem eigentlichen Program, wird das allerdings sehr oft aufgerufen, weshalb das gerne auch ca. 30 Stunden rechnen kann. Wenn ich den Profiler benutze, erkennt man, dass das eintragen in die leere matrix, also folgende Zeile
Code:

resultApproach2(rows_mid, columns_mid(1,i)) = sum(necessaryValues,2);
 

sehr lange braucht. Ich dachte, ich kann mir Zeit ersparen, wenn ich die 6 Matrizen "on the fly" berechne und dann nur einmal eintragen muss.
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 05.08.2010, 21:54     Titel:
  Antworten mit Zitat      
Hallo,

auf den ersten Blick habe ich leider keine Idee. Aber vielleicht ja jemand anders.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
MatLabNooB
Forum-Guru

Forum-Guru


Beiträge: 262
Anmeldedatum: 27.03.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 05.08.2010, 22:23     Titel:
  Antworten mit Zitat      
ich hab mir nur dein erstes Post angeschaut, und da wär ne möglichkeit:
Code:
A(B+repmat(size(A,1)*(C-1),size(B,1),1))


gruß
Private Nachricht senden Benutzer-Profile anzeigen
 
Vladi

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 06.08.2010, 10:08     Titel:
  Antworten mit Zitat      
Hallo nochmal, und vielen Dank für eure Antworten.

@ MatLabNooB: Dein Vorschlag ist schneller, allerdings bin ich mit der Schleife durch C immer noch deutlich schneller.

@ alle:
Mein konkretes Programm sieht in etwa so aus.
Code:

for i = 1 : 200
    % 200 mal
    Ansatz Harald und MatLabNooB
end
 

oder so wie vorher
Code:

for i = 1 : 200
    for j = 1 : 70
        % 14.000 mal
        alter Ansatz
    end
end
 

Der neue Ansatz dauert 34 sek, der alte 12 sek.

Scheinbar ist die Schleife sehr effizient.

Danke nochmals und viele Grüße
der Vladi

ps: Die meiste Zeit geht bei der Schleife übrigens bei der Zuweisung
Code:

mat = zeros(7000, 200);
 

flöten. Gibts da vllt. ne andere Möglichkeit, ne Matrix auf "Null" zu setzen?
 
Vladi

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 06.08.2010, 10:28     Titel:
  Antworten mit Zitat      
Hab eben selbst schon etwas zu mat = zeros(7000,200) gefunden...

http://www.mathworks.de/matlabcentr.....eader/view_thread/288530.

Viele Grüße
der Vladi
 
Vladi

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 06.08.2010, 10:30     Titel:
  Antworten mit Zitat      
Sorry für den Link, der Punkt hinter 28850 muss weg, dann funktioniertes Wink

Viele Grüße
der Vladi
 
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.