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

Mahalanobis Distanzmatrix

 

Romanov

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 24.05.2016, 21:31     Titel: Mahalanobis Distanzmatrix
  Antworten mit Zitat      
Hallo zusammen,

ich suche eine möglichst effiziente Berechnung einer Distanzmatrix aus einem Datensatz von Vektoren. Dabei soll die Mahalanobis Distanz verwendet werden. Matlab bietet pdist2.m als Lösung an. Matlab benutzt dabei ein mex-file, auf das es zurückgreift. Ich suche aber nach einer möglichst effizienten Lösung ohne mex-file, also in Matlab-standard-Code. Hat hier jemand eine Lösung.

Danke!


Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 25.05.2016, 11:11     Titel: Re: Mahalanobis Distanzmatrix
  Antworten mit Zitat      
Hallo Romanov,

Was genau ist "ein Datensatz"? Soclhe Details kann man nicht erraten, es ist für die Implementierung aber grundlegend.
Wieso möchtest Du kein Mex-File verwenden? Effizienter geht es nicht.

Es gibt im FileExchange einige Tools zur Berechnung der Distanz-Matrix. Suche dort einfach mal.

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

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 25.05.2016, 11:58     Titel:
  Antworten mit Zitat      
Hallo Jan,

mit Datensatz ist eine Menge an verschiedenen Vektoren {x,x',...,x(n-1)} gemeint ( Strich steht für die Unterscheidung, nicht die Ableitung der Vektoren), dessen paarweise Abstände ich in eine Matrix, die Distanzmatrix schreiben möchte.

Ich möchte sehen, wie schnell ich mit standard code werde im Vergleich zu der Verwendung von mex-files. Ich habe hier keine besonderen Beweggründe.
 
Jan S
Moderator

Moderator


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

Das ist immer noch nicht klar. Hast Du die Vektoren in einem Cell-Array gespeichert, snd es Zeile oder Spalten einer Matrix, sind es verschiedene Variablen, steht das in einem Excel-File oder sind es Felder eines Structs.

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

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 31.05.2016, 16:56     Titel:
  Antworten mit Zitat      
Hallo Jan,

ich habe die Vektoren in einer Matrix X als Spalten eingetragen.
Bis dato ist der Code der nun folgt, das schnellste was ich hinbekomme:

Code:

nX = size(X,1);
D = zeros(nX,nX);
L = chol(Sigma);
for i = 1:nX
        Xi = repmat(X(:,i),1,nX);
        X_diff = X - Xi;
        zeta = solve_chol(L,X_diff);
        D(i,:) =  sum(X_center2 .* zeta,1);
end
D = sqrt(D);
 
Romanov

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 31.05.2016, 17:02     Titel:
  Antworten mit Zitat      
Hallo Jan,

eine Korrektur im Code:

Code:

nX = size(X,2);
 
 
Romanov

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 31.05.2016, 17:14     Titel:
  Antworten mit Zitat      
Hallo Jan,

solve_chol.m enthält nur den Befehl L'\L\X_diff.
 
Jan S
Moderator

Moderator


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

Zitat:
ich habe die Vektoren in einer Matrix X als Spalten eingetragen.

Prima, ab jetzt muss man die grundlegenden Details nicht mehr raten.

Code:
nX = size(X, 2);
D = zeros(nX, nX);
L = chol(Sigma);
L2 = L' \ L;
for i = 1:nX
        X_diff = bsxfun(@minus, X - X(:,i));
        zeta = L2 \ X_diff;
        D(i,:) =  sum(X_center2 .* zeta, 1);
end
D = sqrt(D);

bsxfun ist smarter als repmat .
In jeder Iteration L'\L wieder zu berechnen ist Zeitverschwendung, oder verstehe ich da etwas falsch? Eine Unterfunktion dafür aufzurufen benötigt ebenfalls Zeit, also besser direkt in den Code schreiben.
Könnte mal L2 \ X_diff aufteilen zu L2 \ X - L2 \ X(:, i), natürlich unter Berücksichtigung der Dimensionen? Der erste Teil ist nämlich konstant und könnte auch aus der Schleife rausgezogen werden.

Wenn Du ein paar realistische Test-Daten zur Verfügung stellst, könnte man einfacher weiter forschen. Es macht einen Unterschied of nX 100 oder 10'000 ist. Per rand erzeugte Daten könnten da praktisch sein.

Gruß, Jan

Jetzt kommt es noch auf die Größen des
Private Nachricht senden Benutzer-Profile anzeigen
 
Romanov

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 01.06.2016, 15:15     Titel:
  Antworten mit Zitat      
Hallo Jan,

danke bis hier her.

Ich war nicht ganz genau bei solve_chol.m .

Code:
function [alpha] = solve_chol(L,y)

alpha = L\(L'\y);

end


Ich verwende hier die Choleskyzerlegung um das Gleichungssystem zu lösen. Daher macht L\L' vorher definieren keinen Sinn.

Sonst würde mich interessieren, was an der Funktion bsxfun schneller oder smarter ist? Ich habe das nun schon öfter gehört.
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 02.06.2016, 10:33     Titel:
  Antworten mit Zitat      
Hallo Romanov,

Wenn man mit repmat zuerst aus einem Vektor eine Matrix erzeugt, benötigt man dazu eine temporären Speicher. So lange das in den Prozessor-Cache passt, klappt das effizient. Wenn aber 2nd-Level-Caches oder sogar das langsame RAM dafür herhalten muss, bremst das den Code ungemein. Regel: Rechnen kann der Prozessor viel schneller als Daten aus dem Speicher besorgen.

bsxfun erlaubt es, das repmat nur intern während der Operation anzuwenden. Es wird also nur der Vektor verwendet und man spart das erzeugen der redundanten Werte im Speicher.

Zitat:
Ich war nicht ganz genau bei solve_chol.m .

Bitte poste deshalb immer lieber den Original-Code, statt ihn nur ungefähr zu erklären. Das schont die Zeit der jenigen, die Antworten schreiben. Danke!

Verwende den Profiler um die Zeilen zu finden, die die meiste Zeit benötigen. Versuche dort vektorisierten Code und vermeide wiederholte Berechnungen so weit wie möglich.
Wenn die größte Zei in L\(L'\y) benötigt wird, lohnt es sich kaum an der Schleife zu basteln. Regel: Wenn in einem Programm-Teil nur 2% der Rechenzeit benötigt werden, kann eine Beschleunigung um den Faktor unendlich die Gesamt-Rechenzeit nur um 2% verkürzen.

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.