Class Eigenvalues

java.lang.Object
org.bzdev.math.Eigenvalues
All Implemented Interfaces:
Serializable

public class Eigenvalues extends Object implements Serializable
Eigenvalues and eigenvectors of a real n by n matrix A.

If A is symmetric, then A = V*D*VT where the eigenvalue matrix D is diagonal and the eigenvector matrix V is an orthogonal matrix whose columns are the eigenvectors of A. Since V is orthogonal, by definition all the eigenvectors are normalized. The eigenvalues are sorted in descending order and the eigenvector corresponding to the ith eigenvalue is stored in the ith column of V.

If A is not symmetric, then the eigenvalue matrix D is block diagonal with the real eigenvalues in 1-by-1 blocks and any complex eigenvalues, λ±iμ (where μ is positive), in 2-by-2 blocks:

     |  λ μ |
     | -μ λ |
 
For the 1-by-1 blocks, the corresponding column in V is a real-valued eigenvector. For the 2-by-2 blocks, the corresponding columns in V represent complex values. For the eigenvalue λ+μ, the first column contains the real components of the eigenvector and the second column contains the imaginary components of the eigenvector. For the eigenvalue λ-μ, the second column contains the real components of the eigenvector and the first column contains the imaginary components of the eigenvector: the matrix product
             |  λ μ |
     | a b | |                |
             | -μ λ |
 
has the value
     | (aλ-bμ) (aμ+bλ) |
 
but
     (a+bi)(λ+μi) = (aλ-bμ)+(aμ+bλ)i
 
and
    (b+ai)(λ-μi) = (aμ+bλ)+(aλ-bμ)i
 
which justifies the assignment of real and imaginary components to complex eigenvectors as described above. Conveniently, it is also true that AV = VD for a mix of real and complex eigenvalues.

The matrix V may be badly conditioned, or even singular, so the validity of the equation A = V*D*inverse(V) depends upon the condition number for V. The condition number for V can be computed by using the method SVDecomp.cond():


    (new SVDecomp(V)).cond()
 
For the nonsymmetric case, the eigenvectors are normalized but are not orthogonal in general.

The implementation is based on the one used in the Jama package (a public-domain package provided via a collaboration between MathWorks and the National Institute of Standards and Technology). Jama defines a matrix class whereas QRDecomp treats matrices as two-dimensional arrays, and was written so that the org.bzdev library is self-contained. Some additional runtime tests were added, and there are a few additional constructors and methods. The documentation was also extended. In addition, some code was added to normalize the eigenvectors in the nonsymmetric case. Since this is more or less a port of the Jama class, this particular class is in the public domain.

See Also:
  • Constructor Summary

    Constructors
    Constructor
    Description
    Eigenvalues(double[][] A)
    Constructor.
    Eigenvalues(double[][] A, int n, boolean strict)
    Constructor given the number of rows and columns.
    Eigenvalues(double[] flatMatrix, boolean columnMajorOrder, int n, boolean strict)
    Constructor for a flat matrix.
  • Method Summary

    Modifier and Type
    Method
    Description
    double[][]
    Get the block diagonal eigenvalue matrix Real eigenvalues are represented by 1-by-1 blocks containing the value itself.
    double
    Get the imaginary part of an eigenvalue.
    double[]
    Get the imaginary parts of the eigenvalues.
    double[]
    Get a vector containing the imaginary part of the kth eigenvector.
    int
    Get the number of columns for the matrix that was decomposed.
    int
    Get the number of rows for the matrix that was decomposed.
    double
    Get the real part of an eigenvalue.
    double[]
    Get the real parts of the eigenvalues.
    double[]
    Get a vector containing the real part of the kth eigenvector.
    double[][]
    Get the eigenvector matrix V.
    double[][]
    Get the transpose of the eigenvector matrix V.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • Eigenvalues

      public Eigenvalues(double[][] A) throws IllegalArgumentException
      Constructor.
      Parameters:
      A - a square matrix
      Throws:
      IllegalArgumentException
    • Eigenvalues

      public Eigenvalues(double[][] A, int n, boolean strict) throws IllegalArgumentException
      Constructor given the number of rows and columns.
      Parameters:
      A - an array containing a square matrix
      n - the number of rows and columns for A
      strict - true if the array A must contain exactly n rows and columns; false if A's rows and columns can be longer (in which case the additional entries will be ignored)
      Throws:
      IllegalArgumentException
    • Eigenvalues

      public Eigenvalues(double[] flatMatrix, boolean columnMajorOrder, int n, boolean strict) throws IllegalArgumentException
      Constructor for a flat matrix.
      Parameters:
      flatMatrix - an array representing a square matrix
      n - the number of rows and columns for the square matrix
      columnMajorOrder - true if the matrix is stored in the flatMatrix array in column-major order; false if it is stored in row-major order.
      strict - true if the array A must have a length of n*n; false if it can be longer.
      Throws:
      IllegalArgumentException
  • Method Details

    • getNumberOfRows

      public int getNumberOfRows()
      Get the number of rows for the matrix that was decomposed.
      Returns:
      the number of rows.
    • getNumberOfColumns

      public int getNumberOfColumns()
      Get the number of columns for the matrix that was decomposed.
      Returns:
      the number of columns.
    • getV

      public double[][] getV()
      Get the eigenvector matrix V. The matrix returned stores the eigenvectors in columns. An eigenvector is represented by a single column when the eigenvalue is a real number and by two adjacent columns when the eigenvector is a complex number. The real part of the ith eigenvector is stored in the ith column. The complex part is stored in column i+1) when the imaginary part of an eigenvalue is stored in column i+1 in the matrix D (See getD()), and in column i-1 when the imaginary part of the eigenvalue is stored in column i-1. The i+1 case occurs when the imaginary part of the eigenvalue is positive and the i-1 case occurs when it is negative.
      Returns:
      the eigenvector matrix.
    • getVT

      public double[][] getVT()
      Get the transpose of the eigenvector matrix V. This is the transpose of the matrix returned by getV(). It is useful when an eigenvector should be accessed as a one-dimensional array. This method is provided to avoid the need to first create V and then compute its transpose.
      Returns:
      the transpose of V
      See Also:
    • getRealEigenvector

      public double[] getRealEigenvector(int k) throws IllegalArgumentException
      Get a vector containing the real part of the kth eigenvector.
      Parameters:
      k - the index for the eigenvector's eigenvalue
      Returns:
      the real part of the kth eigenvector
      Throws:
      IllegalArgumentException - the index is out of range
    • getImagEigenvector

      public double[] getImagEigenvector(int k) throws IllegalArgumentException
      Get a vector containing the imaginary part of the kth eigenvector.
      Parameters:
      k - the index for the eigenvector's eigenvalue
      Returns:
      the imaginary part of the kth eigenvector
      Throws:
      IllegalArgumentException - the index is out of range
    • getRealEigenvalues

      public double[] getRealEigenvalues()
      Get the real parts of the eigenvalues. These are stored largest first.
      Returns:
      the real parts of the eigenvalues
    • getImagEigenvalues

      public double[] getImagEigenvalues()
      Get the imaginary parts of the eigenvalues. These are stored in order of their real parts, with complex conjugate pairs adjacent, the one with a positive imaginary part first.
      Returns:
      the imaginary parts of the eigenvalues
    • getRealEigenvalue

      public double getRealEigenvalue(int i) throws IllegalArgumentException
      Get the real part of an eigenvalue. These are stored largest first.
      Parameters:
      i - an index in the range [0,n) naming the eigenvalue
      Returns:
      the real parts of the eigenvalue
      Throws:
      IllegalArgumentException - the index is out of range
    • getImagEigenvalue

      public double getImagEigenvalue(int i) throws IllegalArgumentException
      Get the imaginary part of an eigenvalue. These are stored in order of their real parts, with complex conjugate pairs adjacent, the one with a positive imaginary part first.
      Parameters:
      i - an index in the range [0,n) naming the eigenvalue
      Returns:
      the real parts of the eigenvalue
      Throws:
      IllegalArgumentException - the index is out of range
    • getD

      public double[][] getD()
      Get the block diagonal eigenvalue matrix Real eigenvalues are represented by 1-by-1 blocks containing the value itself. Complex eigenvalues occur in pairs (one the complex conjugate of the other. For eigenvalues λ±μ with μ≥0, there are two rows in the matrix. for the λ+μ case, the real part of the eigenvalue is on the matrice's diagonal and the imaginary part is in the next column in the same row. For the λ-μ case, the real part of the eigenvalue is on the matrice's diagonal and the imaginary part is in the previous column in the same row. For each pair, the one with the positive imaginary part occurs first.
      Returns:
      the block diagonal eigenvalue matrix