diff --git a/ReleaseNotes/02_13_2024.txt b/ReleaseNotes/02_13_2024.txt new file mode 100644 index 00000000000..8f9992db508 --- /dev/null +++ b/ReleaseNotes/02_13_2024.txt @@ -0,0 +1,51 @@ + +Features: + + - Matrix Util Graham Schmidt #1 (1, 2, 3) + - Matrix Util Graham Schmidt #2 (4, 5, 6) + - Matrix Util Graham Schmidt #3 (7, 8, 9) + - Matrix Util Modulus Internal Unchecked (10, 11, 12) + - Matrix Util Graham Schmidt #4 (13, 14, 15) + + +Bug Fixes/Re-organization: + + - Matrix Graham Schmidt Process Run (16, 17) + - Matrix Util QR Decomposition Fix (37, 38, 39) + + +Samples: + + - Bartels Stewart Sylvester Solver #1 (18, 19, 20) + - Bartels Stewart Sylvester Solver #2 (21, 22) + - Matrix Graham Schmidt Process #1 (23, 24) + - Matrix Graham Schmidt Process #2 (25, 26) + - Matrix Graham Schmidt Process #3 (27, 28) + - Bartels Stewart Sylvester Solver #3 (29, 30) + - Matrix Graham Schmidt Process #4 (31, 32) + - Matrix Graham Schmidt Process #5 (33, 34) + - Bartels Stewart Sylvester Solver #4 (35, 36) + - Matrix Graham Schmidt Process #6 (40, 41, 42) + - Matrix Graham Schmidt Process #7 (43, 44, 45) + - Matrix Graham Schmidt Process #8 (46, 47, 48) + - Matrix Graham Schmidt Process #9 (49, 50, 51) + - Matrix Graham Schmidt Process #10 (52, 53, 54) + - Matrix Graham Schmidt Process #11 (55, 56, 57) + - Matrix Graham Schmidt Process #12 (58, 59, 60) + - Matrix Graham Schmidt Process #13 (61, 62, 63) + - Matrix Graham Schmidt Process #14 (64, 65, 66) + - Matrix Graham Schmidt Process #15 (67, 68, 69) + - Matrix Graham Schmidt Process #16 (70, 71, 72) + - Matrix Graham Schmidt Process #17 (73, 74, 75) + - Matrix Graham Schmidt Process #18 (76, 77, 78) + - Matrix Graham Schmidt Process #19 (79, 80, 81) + - Bartels Stewart Sylvester Solver #5 (85, 86, 87) + - Bartels Stewart Sylvester Solver #6 (88, 89, 90) + + +IdeaDRIP: + + - Bartels-Stewart Algorithm (91-97) + - Bartels-Stewart Algorithm The (98-117) + - Bartels-Stewart Algorithm The - Computational Cost (118) + - Bartels-Stewart Algorithm The - Simplifications and Special Cases (119, 120) diff --git a/src/main/java/org/drip/numerical/linearalgebra/MatrixUtil.java b/src/main/java/org/drip/numerical/linearalgebra/MatrixUtil.java index 5dcd6bb9558..d2fea3de754 100644 --- a/src/main/java/org/drip/numerical/linearalgebra/MatrixUtil.java +++ b/src/main/java/org/drip/numerical/linearalgebra/MatrixUtil.java @@ -128,6 +128,33 @@ private static final double DotProductInternal ( return dotProductInternal; } + private static final double[] ProjectVOnUInternal ( + final double[] u, + final double[] v) + { + double vDotUOverUDotU = DotProductInternal (u, v) / DotProductInternal (u, u); + + double[] projectVOnU = new double[u.length]; + + for (int i = 0; i < u.length; ++i) { + projectVOnU[i] = vDotUOverUDotU * u[i]; + } + + return projectVOnU; + } + + private static final double ModulusInternal ( + final double[] v) + { + double modulus = 0.; + + for (int i = 0; i < v.length; ++i) { + modulus += v[i] * v[i]; + } + + return Math.sqrt (modulus); + } + /** * Indicate if the Cell corresponds to Bottom Left Location in the Matrix * @@ -888,29 +915,22 @@ public static final double Sum ( /** * Compute the Modulus of the Input Vector * - * @param adbl The Input Vector + * @param v The Input Vector * - * @return TRUE - The Modulus of the Input Vector + * @return The Modulus of the Input Vector * - * @throws java.lang.Exception Thrown if the Inputs are Invalid + * @throws Exception Thrown if the Inputs are Invalid */ public static final double Modulus ( - final double[] adbl) - throws java.lang.Exception + final double[] v) + throws Exception { - if (null == adbl || !org.drip.numerical.common.NumberUtil.IsValid (adbl)) - throw new java.lang.Exception ("MatrixUtil::Modulus => Invalid Inputs"); - - double dblModulus = 0.; - int iSize = adbl.length; - - if (0 == iSize) throw new java.lang.Exception ("MatrixUtil::Modulus => Invalid Inputs"); - - for (int i = 0; i < iSize; ++i) - dblModulus += adbl[i] * adbl[i]; + if (null == v || 0 == v.length || !NumberUtil.IsValid (v)) { + throw new Exception ("MatrixUtil::Modulus => Invalid Inputs"); + } - return java.lang.Math.sqrt (dblModulus); + return ModulusInternal (v); } /** @@ -1019,58 +1039,39 @@ public static final double[] Normalize ( /** * Orthogonalize the Specified Matrix Using the Graham-Schmidt Method * - * @param aadblV The Input Matrix + * @param v The Input Matrix * * @return The Orthogonalized Matrix */ public static final double[][] GrahamSchmidtOrthogonalization ( - final double[][] aadblV) + final double[][] v) { - if (null == aadblV) return null; + if (null == v || 0 == v.length || v.length != v[0].length) { + return null; + } - int iSize = aadblV.length; - double[][] aadblU = new double[iSize][iSize]; + double[][] vTranspose = Transpose (v); - if (0 == iSize || null == aadblV[0] || iSize != aadblV[0].length) return null; + double[][] u = new double[vTranspose.length][vTranspose.length]; - for (int i = 0; i < iSize; ++i) { - for (int j = 0; j < iSize; ++j) - aadblU[i][j] = aadblV[i][j]; + for (int i = 0; i < vTranspose.length; ++i) { + for (int j = 0; j < vTranspose.length; ++j) { + u[i][j] = vTranspose[i][j]; + } + } + for (int i = 1; i < vTranspose.length; ++i) { for (int j = 0; j < i; ++j) { - double dblProjectionAmplitude = java.lang.Double.NaN; + double[] projectionTrimOff = ProjectVOnUInternal (u[j], vTranspose[i]); - try { - dblProjectionAmplitude = DotProduct (aadblV[i], aadblU[j]) / DotProduct (aadblU[j], - aadblU[j]); - } catch (java.lang.Exception e) { - e.printStackTrace(); - - return null; + for (int k = 0; k < projectionTrimOff.length; ++k) { + u[i][k] -= projectionTrimOff[k]; } - - for (int k = 0; k < iSize; ++k) - aadblU[i][k] -= dblProjectionAmplitude * aadblU[j][k]; } } - return aadblU; - } - - private static final double[] ProjectVOnUInternal ( - final double[] u, - final double[] v) - { - double vDotUOverUDotU = DotProductInternal (u, v) / DotProductInternal (u, u); - - double[] projectVOnU = new double[u.length]; - - for (int i = 0; i < u.length; ++i) { - projectVOnU[i] = vDotUOverUDotU * u[i]; - } - - return projectVOnU; + return u; } /** @@ -1084,30 +1085,17 @@ private static final double[] ProjectVOnUInternal ( public static final double[][] GrahamSchmidtOrthonormalization ( final double[][] v) { - if (null == v || 0 == v.length || v.length != v[0].length) { - return null; - } - - double[] uDotProduct = new double[v.length]; - double[][] u = new double[v.length][v.length]; - - for (int i = 0; i < v.length; ++i) { - uDotProduct[0] += u[0][i] * u[0][i]; - } + double[][] u = GrahamSchmidtOrthogonalization (v); - for (int i = 0; i < v.length; ++i) { - for (int j = 0; j < v.length; ++j) { - u[i][j] = v[i][j]; - } + if (null == u) { + return null; } - for (int i = 1; i < v.length; ++i) { - for (int j = 0; j < i; ++j) { - double[] projectionTrimOff = ProjectVOnUInternal (u[j], v[i]); + for (int i = 0; i < u.length; ++i) { + double modulusReciprocal = 1. / ModulusInternal (u[i]); - for (int k = 0; k < projectionTrimOff.length; ++k) { - u[i][j] -= projectionTrimOff[k]; - } + for (int j = 0; j < u.length; ++j) { + u[i][j] *= modulusReciprocal; } } @@ -1117,37 +1105,19 @@ public static final double[][] GrahamSchmidtOrthonormalization ( /** * Perform a QR Decomposition on the Input Matrix * - * @param aadblA The Input Matrix + * @param a The Input Matrix * * @return The Output of QR Decomposition */ - public static final org.drip.numerical.linearalgebra.QR QRDecomposition ( - final double[][] aadblA) + public static final QR QRDecomposition ( + final double[][] a) { - double[][] aadblQ = GrahamSchmidtOrthonormalization (aadblA); - - if (null == aadblQ) return null; - - for (int i = 0; i < aadblQ.length; ++i) { - System.out.println ( - "\t| Matrix GSOQ => [" + NumberUtil.ArrayRow (aadblQ[i], 2, 4, false) + " ]||" - ); - } - - int iSize = aadblQ.length; - double[][] aadblR = new double[iSize][iSize]; + double[][] q = GrahamSchmidtOrthonormalization (a); try { - /* for (int i = 0; i < iSize; ++i) { - for (int j = 0; j < iSize; ++j) - aadblR[i][j] = i > j ? DotProduct (aadblQ[i], aadblA[j]) : 0.; - } */ - - aadblR = Product (Transpose (aadblQ), aadblA); - - return new org.drip.numerical.linearalgebra.QR (aadblQ, aadblR); - } catch (java.lang.Exception e) { + return null == q ? null : new QR (q, Product (q, a)); + } catch (Exception e) { e.printStackTrace(); } diff --git a/src/main/java/org/drip/sample/matrix/GrahamSchmidtProcess.java b/src/main/java/org/drip/sample/matrix/GrahamSchmidtProcess.java index d3ce575ae9e..36e61520f76 100644 --- a/src/main/java/org/drip/sample/matrix/GrahamSchmidtProcess.java +++ b/src/main/java/org/drip/sample/matrix/GrahamSchmidtProcess.java @@ -123,6 +123,12 @@ public static final void main ( {7, 0, 4, 5} }; */ + /* double[][] aadblV = new double[][] { + { 12, 6, -4}, + {-51, 167, 24}, + { 4, -68, -41} + }; */ + double[][] aadblV = new double[][] { {12, -51, 4}, { 6, 167, -68}, @@ -165,6 +171,27 @@ public static final void main ( ) ); + System.out.println(); + + double[][] uvTranspose = MatrixUtil.Product (aadblUOrthonormal, aadblV); + + NumberUtil.PrintMatrix ( + "R CHECK #1.1", + uvTranspose + ); + + System.out.println(); + + NumberUtil.PrintMatrix ( + "R CHECK #1.2", + MatrixUtil.Product (MatrixUtil.Transpose (aadblUOrthonormal), uvTranspose) + ); + + /* NumberUtil.PrintMatrix ( + "R CHECK #2", + MatrixUtil.Product (aadblV, MatrixUtil.Transpose (aadblUOrthonormal)) + ); */ + EnvManager.TerminateEnv(); } }