Class SvdImplicitQrAlgorithm_DDRM

java.lang.Object
org.ejml.dense.row.decomposition.svd.implicitqr.SvdImplicitQrAlgorithm_DDRM

public class SvdImplicitQrAlgorithm_DDRM
extends java.lang.Object

Computes the QR decomposition of a bidiagonal matrix. Internally this matrix is stored as two arrays. Shifts can either be provided to it or it can generate the shifts on its own. It optionally computes the U and V matrices. This comparability allows it to be used to compute singular values and associated matrices efficiently.

A = U*S*VT
where A is the original m by n matrix.

Based off of the outline provided in:

David S. Watkins, "Fundamentals of Matrix Computations," Second Edition. Page 404-411

Note: To watch it process the matrix step by step uncomment commented out code.

  • Field Summary

    Fields 
    Modifier and Type Field Description
    protected double[] diag  
    protected EigenvalueSmall_F64 eigenSmall  
    protected double maxValue  
    protected int N  
    protected int nextExceptional  
    protected int numExceptional  
    protected int numSplits  
    protected double[] off  
    protected java.util.Random rand  
    protected int[] splits  
    protected int totalSteps  
    protected @Nullable org.ejml.data.DMatrixRMaj Ut  
    protected @Nullable org.ejml.data.DMatrixRMaj Vt  
    protected int x1  
    protected int x2  
  • Constructor Summary

    Constructors 
    Constructor Description
    SvdImplicitQrAlgorithm_DDRM()  
    SvdImplicitQrAlgorithm_DDRM​(boolean fastValues)  
  • Method Summary

    Modifier and Type Method Description
    boolean _process()  
    protected boolean checkForAndHandleZeros()
    Checks to see if either the diagonal element or off diagonal element is zero.
    protected void computeRotator​(double rise, double run)
    Computes a rotator that will set run to zero (?)
    protected void createBulge​(int x1, double p, double scale, boolean byAngle)
    Performs a similar transform on BTB-pI
    protected void eigenBB_2x2​(int x1)
    Computes the eigenvalue of the 2 by 2 matrix BTB
    void exceptionShift()
    It is possible for the QR algorithm to get stuck in a loop because of symmetries.
    double[] getDiag()  
    double getMaxValue()  
    int getNumberOfSingularValues()  
    double[] getOff()  
    double getSingularValue​(int index)  
    double[] getSingularValues()  
    @Nullable org.ejml.data.DMatrixRMaj getUt()  
    @Nullable org.ejml.data.DMatrixRMaj getVt()  
    void incrementSteps()  
    void initParam​(int M, int N)  
    boolean isDiagonalZero​(int i)  
    boolean isOffZero​(int i)  
    boolean nextSplit()
    Tells it to process the submatrix at the next split.
    void performImplicitSingleStep​(double scale, double lambda, boolean byAngle)
    Given the lambda value perform an implicit QR step on the matrix.
    void printMatrix()  
    boolean process()  
    boolean process​(double[] values)
    Perform a sequence of steps based off of the singular values provided.
    protected void removeBulgeLeft​(int x1, boolean notLast)  
    protected void removeBulgeRight​(int x1)  
    void resetSteps()  
    double selectWilkinsonShift​(double scale)
    Selects the Wilkinson's shift for BTB.
    void setFastValues​(boolean b)  
    void setMatrix​(int numRows, int numCols, double[] diag, double[] off)  
    void setMaxValue​(double maxValue)  
    void setSubmatrix​(int x1, int x2)  
    void setUt​(@Nullable org.ejml.data.DMatrixRMaj ut)  
    void setVt​(@Nullable org.ejml.data.DMatrixRMaj vt)  
    double[] swapDiag​(double[] diag)  
    double[] swapOff​(double[] off)  
    protected void updateRotator​(org.ejml.data.DMatrixRMaj Q, int m, int n, double c, double s)
    Multiplied a transpose orthogonal matrix Q by the specified rotator.

    Methods inherited from class java.lang.Object

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

    • rand

      protected java.util.Random rand
    • Ut

      @Nullable protected @Nullable org.ejml.data.DMatrixRMaj Ut
    • Vt

      @Nullable protected @Nullable org.ejml.data.DMatrixRMaj Vt
    • totalSteps

      protected int totalSteps
    • maxValue

      protected double maxValue
    • N

      protected int N
    • eigenSmall

      protected EigenvalueSmall_F64 eigenSmall
    • numExceptional

      protected int numExceptional
    • nextExceptional

      protected int nextExceptional
    • diag

      protected double[] diag
    • off

      protected double[] off
    • x1

      protected int x1
    • x2

      protected int x2
    • splits

      protected int[] splits
    • numSplits

      protected int numSplits
  • Constructor Details

  • Method Details

    • getUt

      @Nullable public @Nullable org.ejml.data.DMatrixRMaj getUt()
    • setUt

      public void setUt​(@Nullable @Nullable org.ejml.data.DMatrixRMaj ut)
    • getVt

      @Nullable public @Nullable org.ejml.data.DMatrixRMaj getVt()
    • setVt

      public void setVt​(@Nullable @Nullable org.ejml.data.DMatrixRMaj vt)
    • setMatrix

      public void setMatrix​(int numRows, int numCols, double[] diag, double[] off)
    • swapDiag

      public double[] swapDiag​(double[] diag)
    • swapOff

      public double[] swapOff​(double[] off)
    • setMaxValue

      public void setMaxValue​(double maxValue)
    • initParam

      public void initParam​(int M, int N)
    • process

      public boolean process()
    • process

      public boolean process​(double[] values)
      Perform a sequence of steps based off of the singular values provided.
    • _process

      public boolean _process()
    • incrementSteps

      public void incrementSteps()
    • isOffZero

      public boolean isOffZero​(int i)
    • isDiagonalZero

      public boolean isDiagonalZero​(int i)
    • resetSteps

      public void resetSteps()
    • nextSplit

      public boolean nextSplit()
      Tells it to process the submatrix at the next split. Should be called after the current submatrix has been processed.
    • performImplicitSingleStep

      public void performImplicitSingleStep​(double scale, double lambda, boolean byAngle)
      Given the lambda value perform an implicit QR step on the matrix. B^T*B-lambda*I
      Parameters:
      lambda - Stepping factor.
    • updateRotator

      protected void updateRotator​(org.ejml.data.DMatrixRMaj Q, int m, int n, double c, double s)
      Multiplied a transpose orthogonal matrix Q by the specified rotator. This is used to update the U and V matrices. Updating the transpose of the matrix is faster since it only modifies the rows.
      Parameters:
      Q - Orthogonal matrix
      m - Coordinate of rotator.
      n - Coordinate of rotator.
      c - cosine of rotator.
      s - sine of rotator.
    • createBulge

      protected void createBulge​(int x1, double p, double scale, boolean byAngle)
      Performs a similar transform on BTB-pI
    • computeRotator

      protected void computeRotator​(double rise, double run)
      Computes a rotator that will set run to zero (?)
    • removeBulgeLeft

      protected void removeBulgeLeft​(int x1, boolean notLast)
    • removeBulgeRight

      protected void removeBulgeRight​(int x1)
    • setSubmatrix

      public void setSubmatrix​(int x1, int x2)
    • selectWilkinsonShift

      public double selectWilkinsonShift​(double scale)
      Selects the Wilkinson's shift for BTB. See page 410. It is guaranteed to converge and converges fast in practice.
      Parameters:
      scale - Scale factor used to help prevent overflow/underflow
      Returns:
      Shifting factor lambda/(scale*scale)
    • eigenBB_2x2

      protected void eigenBB_2x2​(int x1)
      Computes the eigenvalue of the 2 by 2 matrix BTB
    • checkForAndHandleZeros

      protected boolean checkForAndHandleZeros()
      Checks to see if either the diagonal element or off diagonal element is zero. If one is then it performs a split or pushes it off the matrix.
      Returns:
      True if there was a zero.
    • exceptionShift

      public void exceptionShift()
      It is possible for the QR algorithm to get stuck in a loop because of symmetries. This happens more often with larger matrices. By taking a random step it can break the symmetry and finish.
    • printMatrix

      public void printMatrix()
    • getNumberOfSingularValues

      public int getNumberOfSingularValues()
    • getSingularValue

      public double getSingularValue​(int index)
    • setFastValues

      public void setFastValues​(boolean b)
    • getSingularValues

      public double[] getSingularValues()
    • getDiag

      public double[] getDiag()
    • getOff

      public double[] getOff()
    • getMaxValue

      public double getMaxValue()