Visualizing Matrices

There are various scenarios (e.g., covariance matrices, inertia matrices, quadratic forms) in which you'd want to represent a (square) matrix visually, and ultimately it comes down to Eigen decompositions.

In graphics, it's generally preferable to draw an "unrotated" version of your graphic, and then apply a rotation. Thus, the methods below will focus on extracting semi-major axis lengths and a rotation from the Eigen decomposition. Example code will be given in Matlab.

For testing, here's some Matlab code for generating a random $n\times n$ positive-definite matrix:

function A = generateSPDmatrix(n) % Generate a dense n x n symmetric, positive definite matrix

A = rand(n,n); % generate a random n x n matrix

% construct a symmetric matrix using either A = 0.5*(A+A'); OR A = A*A'; % The first is significantly faster: O(n^2) compared to O(n^3)

% since A(i,j) < 1 by construction and a symmetric diagonally dominant matrix % is symmetric positive definite, which can be ensured by adding nI A = A + n*eye(n);


Two/Three-Dimensional Positive Definite Matrix (Ellipse/Ellipsoid)

Matrix: $\boldsymbol A\in \mathbb{R}^{2\times 2}$ or $\boldsymbol A\in \mathbb{R}^{3\times 3}$, $\boldsymbol A > 0$

Get the principal axis lengths:

  • Find eigenvalues of $\boldsymbol A$. These are the (ordered) semi-major axis lengths.
    • Let's say that by convention, $\boldsymbol A$ is expressed in frame $W$, and when it's expressed in frame $F$, it's diagonal ($\boldsymbol D$) with the eigenvalues on the diagonal.

Get the rotation matrix:

  • Find the (ordered) eigenvectors of $\boldsymbol A$. These form the column vectors of $\boldsymbol R_F^W$.
  • Check the determinant of $\boldsymbol R_F^W$; if it's -1, then flip the sign of the last column to make the determinant +1.
  • From matrix basis change rules, you can check your work by making sure that $\boldsymbol D=\left(\boldsymbol R_F^W\right)^{-1}\boldsymbol A\boldsymbol R_F^W$.

Matlab code:

% Get random positive definite matrix A = generateRandom2x2PDMatrix();

% Extract axis lengths and rotation [R,D] = eig(A); x_axis_len = D(1,1); y_axis_len = D(2,2); if det(R) < 0 R(:,2) = -1 * R(:,2); end

% Draw unrotated ellipse theta = linspace(0,2*pi,100); coords = [x_axis_len * cos(theta); y_axis_len * sin(theta)]; plot(coords(1,:),coords(2,:),'k--') hold on; grid on

% Draw rotated ellipse (R acts like active rotation % since it's B2W convention rotated_coords = R * coords; plot(rotated_coords(1,:),rotated_coords(2,:),'k-','Linewidth',2.0) hold off


function A = generateRandom2x2PDMatrix() A = rand(2,2); A = AA'; A = A + 2eye(2); end

$$\boldsymbol A=\begin{bmatrix}3.0114 & 0.9353\0.9353 & 2.9723\end{bmatrix}$$