From b7fc15fdd5168fb1fcc477dfb8fce0e0971af782 Mon Sep 17 00:00:00 2001 From: Lakshmi Krishnamurthy Date: Sun, 21 Jul 2024 12:55:46 -0400 Subject: [PATCH] Features: - Matrix Util QR Graham Schmidt Orthonormalization (1, 2, 3) - Matrix Util RQ Graham Schmidt Orthonormalization (6, 7, 8) - Matrix Util RQ Decomposition Composite (14, 15, 16) - Unsafe QR Graham Schmidt Orthogonalization (17, 18) - Square Matrix Annotated QR Decomposition (19, 20, 21) - Square Matrix Annotated RQ Decomposition (22, 23) Bug Fixes/Re-organization: - Matrix Util QR Decomposition Revamp (10, 11, 12) Samples: - Gram-Schmidt Process Test #1 (4, 5) - Gram-Schmidt Process Test #2 (9) - Gram-Schmidt Process Test #3 (13) IdeaDRIP: - QR Algorithm (24-26) - The Practical QR Algorithm (27-50) - QR Algorithm Visualization (51-66) - QR Algorithm Visualization - Finding Eigenvalues versus Eigenvectors (67-87) - QR Algorithm Visualization - Speeding Up: Shifting and Deflation (88-97) - The Implicit QR Algorithm (98-104) - The Implicit QR Algorithm - Renaming Proposal (105, 106) - QR Algorithm Interpretation and Convergence (107-113) - QR Algorithm History (114-120) --- ReleaseNotes/02_25_2024.txt | 34 ++++++++ .../eigen/QREigenComponentExtractor.java | 6 +- .../numerical/linearalgebra/MatrixUtil.java | 84 ++++++++++++++++--- .../numerical/linearalgebra/SquareMatrix.java | 22 +++++ .../linearsolver/BartelsStewartScheme.java | 5 +- .../sample/matrix/GrahamSchmidtProcess.java | 2 +- .../drip/sample/matrix/QRDecomposition.java | 2 +- 7 files changed, 134 insertions(+), 21 deletions(-) create mode 100644 ReleaseNotes/02_25_2024.txt diff --git a/ReleaseNotes/02_25_2024.txt b/ReleaseNotes/02_25_2024.txt new file mode 100644 index 00000000000..769815dc0f2 --- /dev/null +++ b/ReleaseNotes/02_25_2024.txt @@ -0,0 +1,34 @@ + +Features: + + - Matrix Util QR Graham Schmidt Orthonormalization (1, 2, 3) + - Matrix Util RQ Graham Schmidt Orthonormalization (6, 7, 8) + - Matrix Util RQ Decomposition Composite (14, 15, 16) + - Unsafe QR Graham Schmidt Orthogonalization (17, 18) + - Square Matrix Annotated QR Decomposition (19, 20, 21) + - Square Matrix Annotated RQ Decomposition (22, 23) + + +Bug Fixes/Re-organization: + + - Matrix Util QR Decomposition Revamp (10, 11, 12) + + +Samples: + + - Gram-Schmidt Process Test #1 (4, 5) + - Gram-Schmidt Process Test #2 (9) + - Gram-Schmidt Process Test #3 (13) + + +IdeaDRIP: + + - QR Algorithm (24-26) + - The Practical QR Algorithm (27-50) + - QR Algorithm Visualization (51-66) + - QR Algorithm Visualization - Finding Eigenvalues versus Eigenvectors (67-87) + - QR Algorithm Visualization - Speeding Up: Shifting and Deflation (88-97) + - The Implicit QR Algorithm (98-104) + - The Implicit QR Algorithm - Renaming Proposal (105, 106) + - QR Algorithm Interpretation and Convergence (107-113) + - QR Algorithm History (114-120) diff --git a/src/main/java/org/drip/numerical/eigen/QREigenComponentExtractor.java b/src/main/java/org/drip/numerical/eigen/QREigenComponentExtractor.java index 6857df127a2..527a09627c5 100644 --- a/src/main/java/org/drip/numerical/eigen/QREigenComponentExtractor.java +++ b/src/main/java/org/drip/numerical/eigen/QREigenComponentExtractor.java @@ -157,8 +157,7 @@ public int maxIterations() final double[][] a) { org.drip.numerical.linearalgebra.QR qr = org.drip.numerical.linearalgebra.MatrixUtil.QRDecomposition ( - a, - false + a ); if (null == qr) @@ -215,8 +214,7 @@ public int maxIterations() v, q ) - ), - false + ) ))) { return null; diff --git a/src/main/java/org/drip/numerical/linearalgebra/MatrixUtil.java b/src/main/java/org/drip/numerical/linearalgebra/MatrixUtil.java index 90b0e993aa1..bf8a9a3e233 100644 --- a/src/main/java/org/drip/numerical/linearalgebra/MatrixUtil.java +++ b/src/main/java/org/drip/numerical/linearalgebra/MatrixUtil.java @@ -247,6 +247,21 @@ public static final double[][] UnsafeRQGrahamSchmidtOrthogonalization ( return u; } + /** + * Orthogonalize the Specified Matrix Using the QR Graham-Schmidt Method. Unsafe Methods do not validate + * the Input Arguments, so use caution in applying these Methods + * + * @param a The Input Matrix + * + * @return The QR Orthogonalized Matrix + */ + + public static final double[][] UnsafeQRGrahamSchmidtOrthogonalization ( + final double[][] a) + { + return Transpose (UnsafeRQGrahamSchmidtOrthogonalization (Transpose (a))); + } + /** * Indicate if the Cell corresponds to Bottom Left Location in the Matrix * @@ -1135,27 +1150,52 @@ public static final double[][] QRGrahamSchmidtOrthogonalization ( return Transpose (RQGrahamSchmidtOrthogonalization (Transpose (a))); } + /** + * Orthonormalize the Specified Matrix Using the RQ Graham-Schmidt Method + * + * @param a The Input Matrix + * + * @return The RQ Orthonormalized Matrix + */ + + public static final double[][] RQGrahamSchmidtOrthonormalization ( + final double[][] a) + { + double[][] u = RQGrahamSchmidtOrthogonalization (a); + + if (null == u) { + return null; + } + + for (int i = 0; i < u.length; ++i) { + double modulusReciprocal = 1. / UnsafeModulus (u[i]); + + for (int j = 0; j < u.length; ++j) { + u[i][j] *= modulusReciprocal; + } + } + + return u; + } + /** * Orthonormalize the Specified Matrix Using the QR Graham-Schmidt Method * * @param a The Input Matrix - * @param vectorsInColumns TRUE - Vectors in Columns * * @return The QR Orthonormalized Matrix */ - public static final double[][] GrahamSchmidtOrthonormalization ( - final double[][] a, - final boolean vectorsInColumns) + public static final double[][] QRGrahamSchmidtOrthonormalization ( + final double[][] a) { - double[][] uOrthogonal = vectorsInColumns ? QRGrahamSchmidtOrthogonalization (a) : - RQGrahamSchmidtOrthogonalization (a); + double[][] uOrthogonal = QRGrahamSchmidtOrthogonalization (a); if (null == uOrthogonal) { return null; } - double[][] u = vectorsInColumns ? Transpose (uOrthogonal) : uOrthogonal; + double[][] u = Transpose (uOrthogonal); for (int i = 0; i < u.length; ++i) { double modulusReciprocal = 1. / UnsafeModulus (u[i]); @@ -1165,23 +1205,43 @@ public static final double[][] GrahamSchmidtOrthonormalization ( } } - return vectorsInColumns ? Transpose (u) : u; + return Transpose (u); } /** * Perform a QR Decomposition on the Input Matrix * * @param a The Input Matrix - * @param vectorsInColumns TRUE - Vectors in Columns * * @return The Output of QR Decomposition */ public static final QR QRDecomposition ( - final double[][] a, - final boolean vectorsInColumns) + final double[][] a) + { + double[][] q = QRGrahamSchmidtOrthonormalization (a); + + try { + return null == q ? null : new QR (q, Product (q, a)); + } catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + /** + * Perform a RQ Decomposition on the Input Matrix + * + * @param a The Input Matrix + * + * @return The Output of RQ Decomposition + */ + + public static final QR RQDecomposition ( + final double[][] a) { - double[][] q = GrahamSchmidtOrthonormalization (a, vectorsInColumns); + double[][] q = RQGrahamSchmidtOrthonormalization (a); try { return null == q ? null : new QR (q, Product (q, a)); diff --git a/src/main/java/org/drip/numerical/linearalgebra/SquareMatrix.java b/src/main/java/org/drip/numerical/linearalgebra/SquareMatrix.java index 0360888769c..d1c6cfdb766 100644 --- a/src/main/java/org/drip/numerical/linearalgebra/SquareMatrix.java +++ b/src/main/java/org/drip/numerical/linearalgebra/SquareMatrix.java @@ -265,6 +265,28 @@ public boolean isTriangularizable() return true; } + /** + * Generate the QR Decomposition of the Square Matrix + * + * @return QR Decomposition + */ + + public QR qrDecomposition() + { + return MatrixUtil.QRDecomposition (_r2Array); + } + + /** + * Generate the RQ Decomposition of the Square Matrix + * + * @return RQ Decomposition + */ + + public QR rqDecomposition() + { + return MatrixUtil.RQDecomposition (_r2Array); + } + /** * Eigenize and Extract the Components of the Specified Matrix * diff --git a/src/main/java/org/drip/numerical/linearsolver/BartelsStewartScheme.java b/src/main/java/org/drip/numerical/linearsolver/BartelsStewartScheme.java index 0ec27e989e7..99052ba5e9c 100644 --- a/src/main/java/org/drip/numerical/linearsolver/BartelsStewartScheme.java +++ b/src/main/java/org/drip/numerical/linearsolver/BartelsStewartScheme.java @@ -189,7 +189,7 @@ public double[][] rhsMatrix() public void solve() { - QR qrA = MatrixUtil.QRDecomposition (_sylvesterEquation.squareMatrixA().r2Array(), false); + QR qrA = MatrixUtil.QRDecomposition (_sylvesterEquation.squareMatrixA().r2Array()); System.out.println(); @@ -214,8 +214,7 @@ public void solve() System.out.println(); QR qrBTranspose = MatrixUtil.QRDecomposition ( - _sylvesterEquation.squareMatrixB().transpose().r2Array(), - false + _sylvesterEquation.squareMatrixB().transpose().r2Array() ); double[][] v = qrBTranspose.q(); diff --git a/src/main/java/org/drip/sample/matrix/GrahamSchmidtProcess.java b/src/main/java/org/drip/sample/matrix/GrahamSchmidtProcess.java index c8571a77de9..a1b4b277034 100644 --- a/src/main/java/org/drip/sample/matrix/GrahamSchmidtProcess.java +++ b/src/main/java/org/drip/sample/matrix/GrahamSchmidtProcess.java @@ -133,7 +133,7 @@ public static final void main ( FormatUtil.FormatDouble ( MatrixUtil.DotProduct (uTranspose[0], uTranspose[1]), 1, 1, 1.) ); - double[][] q = MatrixUtil.GrahamSchmidtOrthonormalization (a, true); + double[][] q = MatrixUtil.QRGrahamSchmidtOrthonormalization (a); NumberUtil.PrintMatrix ("ORTHONORMAL", q); diff --git a/src/main/java/org/drip/sample/matrix/QRDecomposition.java b/src/main/java/org/drip/sample/matrix/QRDecomposition.java index 1ce364b8b5e..5061266c0e6 100644 --- a/src/main/java/org/drip/sample/matrix/QRDecomposition.java +++ b/src/main/java/org/drip/sample/matrix/QRDecomposition.java @@ -128,7 +128,7 @@ public static final void main ( { 0.0, 0.4, 1.0} }; - QR qr = MatrixUtil.QRDecomposition (aadblA, false); + QR qr = MatrixUtil.QRDecomposition (aadblA); double[][] aadblR = qr.r();