## msign

Check to see if a matrix is positive-definite, positive-semidefinite, indefinite, negative-semidefinite, or negative-definite.

An optional tolerance, tol, can be provided. Any eigenvalues between -tol and tol will be treated as 0. By default, the tolerance is the machine precision of the maximum eigenvalue.

s = msign(P);
s = msign(P, tol);

## Inputs

P Square matrix to test Tolerance to use for comparison (optional)

## Outputs

s "Sign" of matrix:  2 positive-definite (all eigenvalues are > the tolerance) 1 positive-semidefinite (all eigs are >= -tol) 0 indefinite (some eigs between -tol and tol) -1 negative-semidefinite (all eigs are <= tol) -2 negative-definite (all eigenvalues are < -tol)

## Example

When we generate a random matrix, we expect a positive-definite matrix. Let's test:

X = randcov(3);
msign(X) % Expect 2 to indicate PD
ans =
2

## Example: Positive-semidefinite

If we multiply a 2D covariance matrix by a 3-by-2 matrix on each side, we'll end up with a 3-by-3 positive-semidefinite matrix.

F = [1 0; 0 1; -1 0];
P = [1 0; 0 1];
msign(F * P * F.') % Expect 1
ans =
1

## Example: Indefinite

Let's manually construct an indefinite matrix and see that we get the right thing.

A = randn(3);
P = A * diag([1 2 -3]) * A.';
msign(P)
ans =
0

## Example: Negative-semidefinite

P = [0 0; 0 -1];
msign(P)
ans =
-1

## Example: Negative-definite with tolerance

We'll use exactly 0 as the tolerance to test a badly-scaled matrix for negative-definiteness (2).

P = [-1e12 0; 0 -1e-6];
msign(P, 0)
ans =
-2

Note that the default tolerance, for numerical reasons, would say that this matrix only appears to be negaitve-semidefinite (-1).

msign(P)
ans =
-1