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

Jede Spalte multiplizieren von Matrizen

 

Gödzilla
Forum-Newbie

Forum-Newbie


Beiträge: 4
Anmeldedatum: 19.09.18
Wohnort: nähe Stuttgart
Version: ---
     Beitrag Verfasst am: 19.09.2018, 16:10     Titel: Jede Spalte multiplizieren von Matrizen
  Antworten mit Zitat      
Hallo Zusammen,

Ich habe folgendes Problem ich möchte mehrere Matrizen spaltenweise so multiplizieren das alle möglichen Kombinationen berechnet werden, ähnlich wie das Kronecker Produkt nur eben in einer Dimension. Das heißt aus einer [3x5] und [3x4] folgt eine [3x20] Matrix. Die [3x20] Matrix soll wiederrum mit z.B. einer [3x3] spaltenweis multipliziert werden, dass dann eine [3x60] folgt und das möcht ich x mal machen.

Derzeit hab ich das Problem wie folgt gelöst.

Code:
 
          begin = sp.(order{1});
            c = 1;
            for o = 2:length(order)
                m2 = sp.(order{o});
                out = [];
                for p = 1:size(sp.(order{o}),2)
                   
                    for q = 1:size(begin,2)
                        out(:,c) = (begin(:,q).*m2(:,p));
                        c = c+1;
                    end
                end

                begin = out;
                m2 = [];
                c = 1;
            end


Die Lösung funktioniert so. Ich habe nur das Problem, dass die Variable out jedesmal in begin Kopiert werden muss was dann zunehmend sehr Arbeitsspeicher und Rechen intensiv wird.

Hat jemand eine Idee wie man das besser lösen könnte.
Private Nachricht senden Benutzer-Profile anzeigen


J0nas
Forum-Century

Forum-Century


Beiträge: 208
Anmeldedatum: 10.09.15
Wohnort: ---
Version: ab 2016a
     Beitrag Verfasst am: 20.09.2018, 03:46     Titel:
  Antworten mit Zitat      
Hallo Gödzille,

spaltenweises multiplizieren zweier Matrizen geht auch ohne diese Schleife, als (etwas unschöner) Einzeiler:
Code:

x = [1 2; 3 4];
y = [1 2 3; 1 2 3];
z = transpose(sortrows(transpose(repmat(x,1,length(y(1,:)))))) .* repmat(y,1,length(x(1,:)))
 

Vielleicht kannst du das auf dein Problem umschreiben, ansonsten kann ich dir da auch gerne später (wenn ich mehr Zeit habe) behilflich sein.

Grüße
Jonas
_________________

1.) Ask Google & Matlab Documentation
2.) Ask gomatlab.de & Technical Support of MathWorks
3.) Go mad, your problem is unsolvable
Private Nachricht senden Benutzer-Profile anzeigen
 
Gödzilla
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 4
Anmeldedatum: 19.09.18
Wohnort: nähe Stuttgart
Version: ---
     Beitrag Verfasst am: 20.09.2018, 12:19     Titel:
  Antworten mit Zitat      
Hallo Jonas,

vielen Dank für den Tipp. Ich werde es mal einpflegen und testen.

Grüße Oliver
Private Nachricht senden Benutzer-Profile anzeigen
 
Gödzilla
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 4
Anmeldedatum: 19.09.18
Wohnort: nähe Stuttgart
Version: ---
     Beitrag Verfasst am: 24.09.2018, 15:50     Titel:
  Antworten mit Zitat      
Hallo Zusammen,

ich hab jetzt mal die Zeile eingefügt, und leider bekomme ich unterschiedliche Ergebnisse. Die Reihenfolge ist eine andere . Hat jemand eine Idee wie man das Anpassen kann.
Private Nachricht senden Benutzer-Profile anzeigen
 
J0nas
Forum-Century

Forum-Century


Beiträge: 208
Anmeldedatum: 10.09.15
Wohnort: ---
Version: ab 2016a
     Beitrag Verfasst am: 25.09.2018, 04:08     Titel:
  Antworten mit Zitat      
Hallo,

wie möchtest du die Zeilen denn sortiert haben? Erklär's am besten an dem einfachen Beispiel. Dann kann ich dir das anpassen.

Grüße
Jonas
_________________

1.) Ask Google & Matlab Documentation
2.) Ask gomatlab.de & Technical Support of MathWorks
3.) Go mad, your problem is unsolvable
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: 25.09.2018, 13:59     Titel: Re: Jede Spalte multiplizieren von Matrizen
  Antworten mit Zitat      
Hallo Gödzilla,

Das iterative Vergrößern von Arrays ist enorm ineffizient. Du weißt ja im Vorhinein, wie groß der Output wird, dann ist es sinnvoll ihn auch gleich mit der richtigen Größe zu allocieren:

Code:
begin = sp.(order{1});
s1 = size(begin, 1);
for o = 2:length(order)
  s2 = size(begin, 2);
  c = 1;
  m2 = sp.(order{o});
  out = zeros(s1, s2 * size(m2, 2));   % Statt [] !!!!!
  for p = 1:size(m2, 2)
    m2p = m2(:, p);
    for q = 1:s2
      out(:,c) = begin(:,q) .* m2p;
      c = c+1;
    end
  end
  begin = out;
end

Dann habe ich noch ein paar überflüssige Zeilen entfernt und die temporär variable m2p erstellt. Die pre-allocation sollte aber am hilfreichsten sein. Sei R2016b kann man .* auch auf eine Matrix und einen Vektor anwenden:

Code:
begin = sp.(order{1});
s1 = size(begin, 1);
for o = 2:length(order)
  s2 = size(begin, 2);
  c = 1;
  m2 = sp.(order{o});
  out = zeros(s1, s2 * size(m2, 2));   % Statt [] !!!!!
  for p = 1:size(m2, 2)
    out(:, c:c+s2-1) = begin .* m2(:, p);
    c = c + s2;
  end
  begin = out;
end

Das ist hübscher, aber ist es auch schneller?

Man könnte das auch weiter ausnutzen und die äußere Schleife ebenfalls entfernen:
Code:
begin = sp.(order{1});
s1 = size(begin, 1);
for o = 2:length(order)
  s2 = size(begin, 2);
  begin = reshape(begin, [s1, 1, s2]) .* sp.(order{o});
  begin = reshape(begin, s1, []);
end

Hier wird dann ein [N x 1 x M] und ein [N x P] Array mit einander elementweise multipliziert. Letzteres wird intern als [N x P x 1] interpretiert, da angehängte Dimensionen de Länge 1 in Matlab virtuell sind.

Ich kann den Code gerade nicht ausprobieren. Bitte debugge ihn selbst. Es wäre hilfreich, wenn Du die Laufzeiten der verschiedenen Methode hier postest, sowie die Größe der Inputs.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Gödzilla
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 4
Anmeldedatum: 19.09.18
Wohnort: nähe Stuttgart
Version: ---
     Beitrag Verfasst am: 26.09.2018, 17:20     Titel:
  Antworten mit Zitat      
Hallo Zusammen,

auf der Basis von Jans letztem Vorschlag konnte ich Version erstellen, die genau das gleiche macht wie die Version mit den Schleifen. Nur ist diese Faktor 30 schneller und braucht nur die hälfte des Arbeitsspeichers.

Code:

out = sp.(order{1});
 
for o = 2:length(order)
  [s1, s2] = size(sp.(order{o}));
  out = reshape(sp.(order{o}), [s1,1, s2]) .* out ;
  out = reshape(out,s1,size(out,2)*size(out,3));
end
 


Vielen Dank für eure Hilfe
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 - 2024 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.