2017-03-05 6 views
0

Ich versuche, unsere Daten zu rekonstruieren, was scheinbar Wahrscheinlichkeitsellipse sein sollte. Als Eingabe bekomme ich eine Struktur, die kryptische Elemente enthält, insbesondere meanX, meanY, Co00, Co01 und Co10. Ich denke, x und y sind Mittelpunkt der Ellipse, und CoXX sind Kovarianzmatrix. Klingt wie ich sollte Eigenwerte und Eigenvektor verwenden, um zwei Radien der Ellipse zu finden. Ich fand die Eigen C++ - Bibliothek, aber ich habe eine Schwierigkeit herauszufinden, was ich mit Eigenberechnung Ergebnissen tun muss, wenn ich die Vektoren und Werte zurückbekomme. Wie finde ich zwei Radien und die Ellipse neigen?Herausfinden der Wahrscheinlichkeitsellipse aus der Kovarianzmatrix

Antwort

2

Let:

m = (meanX) 
    (meanY) 

sein, die (Vektor) bedeuten und:

S = (Co00 Co01) 
    (Co01 Co11) 

die Kovarianzmatrix der Daten sein. Der Mittelpunkt der Ellipse ist m, die Achsen der Ellipse sind die Eigenvektoren e1 und e2 der Matrix S (die Nebenachse e1 ist dem kleinsten Eigenwert von S zugeordnet). Die Radien sind proportional zu sqrt(λ1) und sqrt(λ2), wobei λ1 und λ2 die Eigenwerte sind, die e1 und e2 zugeordnet sind. Schließlich ist die Neigung der Ellipse atan2(e2_y, e2_x) (Winkel zwischen der Hauptachse und der x Achse).

Das kommt alles von Diagonalisierung der Matrix S und Erweiterung des Ausdrucks (X - m)^T S^-1 (X - m) = 1, um die erwartete Form (x/a)^2 + (y/b)^2 = 1 zu entsprechen. Beachten Sie, dass die Radien skaliert werden sollten, wenn ein bestimmtes Konfidenzniveau betrachtet wird. Bei 95% Konfidenz ist der Skalierungsfaktor .

Mit Eigen, das folgende Stück sollte der Code arbeiten:

#include <Eigen/Eigenvalues> 

// [...] 

Vector2d m; 
Matrix2d S; 

m << meanX, meanY; 
S << Co00, Co01, Co01, Co11; 

SelfAdjointEigenSolver<Matrix2d> solver(S); 
double l1 = solver.eigenvalues().x(); 
double l2 = solver.eigenvalues().y(); 
Vector2d e1 = solver.eigenvectors().col(0); 
Vector2d e2 = solver.eigenvectors().col(1); 

double scale95 = sqrt(5.991); 
double R1 = scale95 * sqrt(l1); 
double R2 = scale95 * sqrt(l2); 
double tilt = atan2(e2.y(), e2.x()); 
+0

Du bist der Mann! Sieht so aus, als ob es funktioniert und gibt die gleiche Ausgabe, die ich mit OpenCV erhalte. Vielen Dank! – kreuzerkrieg

Verwandte Themen