From e866021796c2e2dea3310e6290210d27cf46fd4b Mon Sep 17 00:00:00 2001 From: Lakshmi Krishnamurthy Date: Sun, 7 Jul 2024 00:32:55 -0400 Subject: [PATCH] Features: - Square Matrix is Triangularizable (1, 2) - Numerical R^1 -> R^1 Eigenvalue Characteristic Polynomial (3, 4, 5) - Square Matrix Eigenvalue Characteristic Polynomial (6, 7, 8) - Triangular Matrix Remove R2 Array (9, 10) - Triangular Matrix Zero Diagonal Entries (13, 14) - Triangular Matrix Is Uni Check (15, 16) - Triangular Matrix Is Triangularizable Check (19, 20) - Triangular Matrix Determinant and Permanent (21, 22) - Square Matrix Triangular Entries #1 (23, 24) - Square Matrix Triangular Entries #2 (25, 26) - Triangular Matrix Eigenvalue Multiplicity Map (27, 28, 29) - Triangular Matrix Eigenvalue Characteristic Polynomial (30, 31, 32) - Triangular Matrix Is Unit Check (33, 34) - Triangular Matrix Is Normed Check (35, 36) - Triangular Matrix Is Upper Unitriangular (37, 38) - Triangular Matrix Is Lower Unitriangular (39, 40) - Triangular Matrix Atomic Lower #1 (41, 42) - Triangular Matrix Atomic Lower #2 (43, 44) - Triangular Matrix Atomic Lower #3 (45, 46) - Triangular Matrix Atomic Upper #1 (47, 48) - Triangular Matrix Atomic Upper #2 (49, 50) - Triangular Matrix Is Atomic Unitriangular (51, 52) - Triangular Matrix Is Frobenius Unitriangular (53, 54) - Triangular Matrix Is Gauss Unitriangular (55, 56) - Triangular Matrix Gauss Transformation Unitriangular (57, 58) - Linear Algebra Triangular Matrix Constructor (59, 60) - Linear Algebra Triangular Matrix Standard (61, 62, 63) - Linear Algebra Triangular Matrix Type (64) - CRNG Random Matrix Generator Shell (65, 66) - Random Matrix Generator Upper Triangular (67, 68, 69) - Random Matrix Generator Lower Triangular (70, 71, 72) Bug Fixes/Re-organization: - Linear Algebra Triangular Matrix Revamp (11, 12) - Triangular Matrix Determinant/Permanent Revamp (17, 18) - Triangular Matrix Variants and Solutions (73, 74) Samples: - Lower Triangular Matrix Shell #1 (75, 76) - Lower Triangular Matrix Shell #2 (77, 78) - Lower Triangular Matrix Shell #3 (79, 80, 81) - Lower Triangular Matrix Shell #4 (82, 83, 84) - Lower Triangular Matrix Shell #5 (85, 86, 87) - Lower Triangular Matrix Shell #6 (88, 89, 90) - Lower Triangular Matrix Shell #7 (91, 92, 93) - Lower Triangular Matrix Shell #8 (94, 95, 96) - Lower Triangular Matrix Shell #9 (97, 98, 99) - Lower Triangular Matrix Shell #10 (100, 101, 102) - Lower Triangular Matrix Shell #11 (103, 104, 105) - Lower Triangular Matrix Shell #12 (106, 107, 108) - Lower Triangular Matrix Shell #13 (109, 110, 111) - Lower Triangular Matrix Shell #14 (112, 113, 114) - Lower Triangular Matrix Shell #15 (115, 116, 117) - Lower Triangular Matrix Shell #16 (118, 119, 120) IdeaDRIP: --- ReleaseNotes/02_06_2024.txt | 64 +++ .../measure/crng/RandomMatrixGenerator.java | 170 ++++++++ .../org/drip/numerical/eigen/EigenOutput.java | 27 ++ .../numerical/linearalgebra/SquareMatrix.java | 44 +- .../linearalgebra/TriangularMatrix.java | 393 ++++++++++++++---- .../sample/triangular/LowerTriangular.java | 219 ++++++++++ .../drip/sample/triangular/package-info.java | 8 + .../tridiagonal/NonPeriodicSolverSuite.java | 4 +- 8 files changed, 852 insertions(+), 77 deletions(-) create mode 100644 ReleaseNotes/02_06_2024.txt create mode 100644 src/main/java/org/drip/measure/crng/RandomMatrixGenerator.java create mode 100644 src/main/java/org/drip/sample/triangular/LowerTriangular.java create mode 100644 src/main/java/org/drip/sample/triangular/package-info.java diff --git a/ReleaseNotes/02_06_2024.txt b/ReleaseNotes/02_06_2024.txt new file mode 100644 index 00000000000..34ed541c86d --- /dev/null +++ b/ReleaseNotes/02_06_2024.txt @@ -0,0 +1,64 @@ + +Features: + + - Square Matrix is Triangularizable (1, 2) + - Numerical R^1 -> R^1 Eigenvalue Characteristic Polynomial (3, 4, 5) + - Square Matrix Eigenvalue Characteristic Polynomial (6, 7, 8) + - Triangular Matrix Remove R2 Array (9, 10) + - Triangular Matrix Zero Diagonal Entries (13, 14) + - Triangular Matrix Is Uni Check (15, 16) + - Triangular Matrix Is Triangularizable Check (19, 20) + - Triangular Matrix Determinant and Permanent (21, 22) + - Square Matrix Triangular Entries #1 (23, 24) + - Square Matrix Triangular Entries #2 (25, 26) + - Triangular Matrix Eigenvalue Multiplicity Map (27, 28, 29) + - Triangular Matrix Eigenvalue Characteristic Polynomial (30, 31, 32) + - Triangular Matrix Is Unit Check (33, 34) + - Triangular Matrix Is Normed Check (35, 36) + - Triangular Matrix Is Upper Unitriangular (37, 38) + - Triangular Matrix Is Lower Unitriangular (39, 40) + - Triangular Matrix Atomic Lower #1 (41, 42) + - Triangular Matrix Atomic Lower #2 (43, 44) + - Triangular Matrix Atomic Lower #3 (45, 46) + - Triangular Matrix Atomic Upper #1 (47, 48) + - Triangular Matrix Atomic Upper #2 (49, 50) + - Triangular Matrix Is Atomic Unitriangular (51, 52) + - Triangular Matrix Is Frobenius Unitriangular (53, 54) + - Triangular Matrix Is Gauss Unitriangular (55, 56) + - Triangular Matrix Gauss Transformation Unitriangular (57, 58) + - Linear Algebra Triangular Matrix Constructor (59, 60) + - Linear Algebra Triangular Matrix Standard (61, 62, 63) + - Linear Algebra Triangular Matrix Type (64) + - CRNG Random Matrix Generator Shell (65, 66) + - Random Matrix Generator Upper Triangular (67, 68, 69) + - Random Matrix Generator Lower Triangular (70, 71, 72) + + +Bug Fixes/Re-organization: + + - Linear Algebra Triangular Matrix Revamp (11, 12) + - Triangular Matrix Determinant/Permanent Revamp (17, 18) + - Triangular Matrix Variants and Solutions (73, 74) + + +Samples: + + - Lower Triangular Matrix Shell #1 (75, 76) + - Lower Triangular Matrix Shell #2 (77, 78) + - Lower Triangular Matrix Shell #3 (79, 80, 81) + - Lower Triangular Matrix Shell #4 (82, 83, 84) + - Lower Triangular Matrix Shell #5 (85, 86, 87) + - Lower Triangular Matrix Shell #6 (88, 89, 90) + - Lower Triangular Matrix Shell #7 (91, 92, 93) + - Lower Triangular Matrix Shell #8 (94, 95, 96) + - Lower Triangular Matrix Shell #9 (97, 98, 99) + - Lower Triangular Matrix Shell #10 (100, 101, 102) + - Lower Triangular Matrix Shell #11 (103, 104, 105) + - Lower Triangular Matrix Shell #12 (106, 107, 108) + - Lower Triangular Matrix Shell #13 (109, 110, 111) + - Lower Triangular Matrix Shell #14 (112, 113, 114) + - Lower Triangular Matrix Shell #15 (115, 116, 117) + - Lower Triangular Matrix Shell #16 (118, 119, 120) + + +IdeaDRIP: diff --git a/src/main/java/org/drip/measure/crng/RandomMatrixGenerator.java b/src/main/java/org/drip/measure/crng/RandomMatrixGenerator.java new file mode 100644 index 00000000000..a19632bcd0e --- /dev/null +++ b/src/main/java/org/drip/measure/crng/RandomMatrixGenerator.java @@ -0,0 +1,170 @@ + +package org.drip.measure.crng; + +import org.drip.numerical.linearalgebra.TriangularMatrix; + +/* + * -*- mode: java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + */ + +/*! + * Copyright (C) 2025 Lakshmi Krishnamurthy + * + * This file is part of DROP, an open-source library targeting analytics/risk, transaction cost analytics, + * asset liability management analytics, capital, exposure, and margin analytics, valuation adjustment + * analytics, and portfolio construction analytics within and across fixed income, credit, commodity, + * equity, FX, and structured products. It also includes auxiliary libraries for algorithm support, + * numerical analysis, numerical optimization, spline builder, model validation, statistical learning, + * graph builder/navigator, and computational support. + * + * https://lakshmidrip.github.io/DROP/ + * + * DROP is composed of three modules: + * + * - DROP Product Core - https://lakshmidrip.github.io/DROP-Product-Core/ + * - DROP Portfolio Core - https://lakshmidrip.github.io/DROP-Portfolio-Core/ + * - DROP Computational Core - https://lakshmidrip.github.io/DROP-Computational-Core/ + * + * DROP Product Core implements libraries for the following: + * - Fixed Income Analytics + * - Loan Analytics + * - Transaction Cost Analytics + * + * DROP Portfolio Core implements libraries for the following: + * - Asset Allocation Analytics + * - Asset Liability Management Analytics + * - Capital Estimation Analytics + * - Exposure Analytics + * - Margin Analytics + * - XVA Analytics + * + * DROP Computational Core implements libraries for the following: + * - Algorithm Support + * - Computation Support + * - Function Analysis + * - Graph Algorithm + * - Model Validation + * - Numerical Analysis + * - Numerical Optimizer + * - Spline Builder + * - Statistical Learning + * + * Documentation for DROP is Spread Over: + * + * - Main => https://lakshmidrip.github.io/DROP/ + * - Wiki => https://github.com/lakshmiDRIP/DROP/wiki + * - GitHub => https://github.com/lakshmiDRIP/DROP + * - Repo Layout Taxonomy => https://github.com/lakshmiDRIP/DROP/blob/master/Taxonomy.md + * - Javadoc => https://lakshmidrip.github.io/DROP/Javadoc/index.html + * - Technical Specifications => https://github.com/lakshmiDRIP/DROP/tree/master/Docs/Internal + * - Release Versions => https://lakshmidrip.github.io/DROP/version.html + * - Community Credits => https://lakshmidrip.github.io/DROP/credits.html + * - Issues Catalog => https://github.com/lakshmiDRIP/DROP/issues + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * RandomMatrixGenerator provides Functionality for generating different Kinds of Random Matrices. The + * References are: + * + *

+ * + * + *

+ * + *

+ * + * @author Lakshmi Krishnamurthy + */ + +public class RandomMatrixGenerator +{ + + /** + * Construct a Lower Triangular Matrix of Random Elements up to the Maximum Value + * + * @param elementCount Number of Elements in the Array + * @param maximumElement Maximum Element + * @param isEntryInteger TRUE - Entry is an Integer + * + * @return Lower Triangular Matrix of Random Elements up to the Maximum Value + */ + + public static final TriangularMatrix LowerTriangular ( + final int elementCount, + final double maximumElement, + final boolean isEntryInteger) + { + double[][] r2Array = RdRandomSequence.TwoD (elementCount, maximumElement, isEntryInteger); + + for (int i = 0; i < r2Array.length; ++i) { + for (int j = i + 1; j < r2Array.length; ++j) { + r2Array[i][j] = 0.; + } + } + + return TriangularMatrix.Standard (r2Array); + } + + /** + * Construct an Upper Triangular Matrix of Random Elements up to the Maximum Value + * + * @param elementCount Number of Elements in the Array + * @param maximumElement Maximum Element + * @param isEntryInteger TRUE - Entry is an Integer + * + * @return Upper Triangular Matrix of Random Elements up to the Maximum Value + */ + + public static final TriangularMatrix UpperTriangular ( + final int elementCount, + final double maximumElement, + final boolean isEntryInteger) + { + double[][] r2Array = RdRandomSequence.TwoD (elementCount, maximumElement, isEntryInteger); + + for (int i = 0; i < r2Array.length; ++i) { + for (int j = 0; j < i; ++j) { + r2Array[i][j] = 0.; + } + } + + return TriangularMatrix.Standard (r2Array); + } +} diff --git a/src/main/java/org/drip/numerical/eigen/EigenOutput.java b/src/main/java/org/drip/numerical/eigen/EigenOutput.java index 97919f61c13..801fcb82cd1 100644 --- a/src/main/java/org/drip/numerical/eigen/EigenOutput.java +++ b/src/main/java/org/drip/numerical/eigen/EigenOutput.java @@ -4,6 +4,8 @@ import java.util.HashMap; import java.util.Map; +import org.drip.function.definition.R1ToR1; + /* * -*- mode: java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ @@ -197,4 +199,29 @@ public double determinant() return determinant; } + + /** + * Retrieve the Characteristic Polynomial of the Eigenvalues + * + * @return Characteristic Polynomial of the Eigenvalues + */ + + public R1ToR1 characteristicPolynomial() + { + return new R1ToR1 (null) + { + @Override public double evaluate ( + final double x) + throws Exception + { + double value = 1.; + + for (double eigenValue : _eigenValueArray) { + value *= (x - eigenValue); + } + + return value; + } + }; + } } diff --git a/src/main/java/org/drip/numerical/linearalgebra/SquareMatrix.java b/src/main/java/org/drip/numerical/linearalgebra/SquareMatrix.java index 559d8199de2..0360888769c 100644 --- a/src/main/java/org/drip/numerical/linearalgebra/SquareMatrix.java +++ b/src/main/java/org/drip/numerical/linearalgebra/SquareMatrix.java @@ -3,6 +3,7 @@ import java.util.Map; +import org.drip.function.definition.R1ToR1; import org.drip.numerical.common.NumberUtil; import org.drip.numerical.eigen.EigenOutput; import org.drip.numerical.eigen.QREigenComponentExtractor; @@ -129,7 +130,7 @@ public class SquareMatrix * @return Standard Instance of SquareMatrix */ - public static final SquareMatrix Standard ( + public static SquareMatrix Standard ( final double[][] r2Array) { if (!MatrixUtil.IsSquare (r2Array)) { @@ -253,6 +254,17 @@ public boolean isNormal() return true; } + /** + * Calculate whether the Matrix is "Triangularizable" + * + * @return TRUE - Matrix is "Triangularizable" + */ + + public boolean isTriangularizable() + { + return true; + } + /** * Eigenize and Extract the Components of the Specified Matrix * @@ -264,6 +276,23 @@ public EigenOutput eigenize() return QREigenComponentExtractor.Standard().eigenize (_r2Array); } + /** + * Retrieve the Array of Diagonal Entries + * + * @return Array of Diagonal Entries + */ + + public double[] diagonalEntryArray() + { + double[] diagonalEntryArray = new double[_r2Array.length]; + + for (int i = 0; i < _r2Array.length; ++i) { + diagonalEntryArray[i] = _r2Array[i][i]; + } + + return diagonalEntryArray; + } + /** * Retrieve the Eigenvalue Multiplicity Map * @@ -296,4 +325,17 @@ public double determinant() return eigenOutput.determinant(); } + + /** + * Retrieve the Characteristic Polynomial of the Eigenvalues + * + * @return Characteristic Polynomial of the Eigenvalues + */ + + public R1ToR1 characteristicPolynomial() + { + EigenOutput eigenOutput = QREigenComponentExtractor.Standard().eigenize (_r2Array); + + return null == eigenOutput ? null : eigenOutput.characteristicPolynomial(); + } } diff --git a/src/main/java/org/drip/numerical/linearalgebra/TriangularMatrix.java b/src/main/java/org/drip/numerical/linearalgebra/TriangularMatrix.java index f1da3cfdc06..c927cd3c532 100644 --- a/src/main/java/org/drip/numerical/linearalgebra/TriangularMatrix.java +++ b/src/main/java/org/drip/numerical/linearalgebra/TriangularMatrix.java @@ -1,6 +1,10 @@ package org.drip.numerical.linearalgebra; +import java.util.HashMap; +import java.util.Map; + +import org.drip.function.definition.R1ToR1; import org.drip.numerical.common.NumberUtil; /* @@ -113,47 +117,72 @@ * @author Lakshmi Krishnamurthy */ -public class TriangularMatrix +public class TriangularMatrix extends SquareMatrix { + /** + * Lower Triangular Matrix + */ + + public static int LOWER_TRIANGULAR = 1; + + /** + * Upper Triangular Matrix + */ + + public static int UPPER_TRIANGULAR = 2; + + /** + * Lower + Upper Triangular Matrix + */ + + public static int LOWER_AND_UPPER_TRIANGULAR = 3; + + /** + * Non Triangular Matrix + */ + + public static int NON_TRIANGULAR = 0; + + private int _type = Integer.MIN_VALUE; + /** * Retrieve the Triangular Type of the Matrix * - * @param squareMatrix Input Square Matrix + * @param r2Array R2 Array * * @return The Triangular Type */ public static final int Type ( - final double[][] squareMatrix) + final double[][] r2Array) { - if (null == squareMatrix) { + if (null == r2Array) { return NON_TRIANGULAR; } boolean lowerTriangular = true; boolean upperTriangular = true; - int size = squareMatrix.length; - if (1 >= size || null == squareMatrix[0] || size != squareMatrix[0].length) { + if (1 >= r2Array.length || null == r2Array[0] || r2Array.length != r2Array[0].length) { return NON_TRIANGULAR; } - for (int i = 0; i < size; ++i) { - for (int j = 0; j < size; ++j) { - if (i > j) { - if (NumberUtil.WithinTolerance (squareMatrix[i][j], 0.)) { - lowerTriangular = false; + for (int i = 0; i < r2Array.length; ++i) { + for (int j = 0; j < r2Array.length; ++j) { + if (i < j) { + if (NumberUtil.WithinTolerance (r2Array[i][j], 0.)) { + upperTriangular = false; - if (!upperTriangular) { + if (!lowerTriangular) { break; } } - } else if (i < j) { - if (NumberUtil.WithinTolerance (squareMatrix[i][j], 0.)) { - upperTriangular = false; + } else if (i > j) { + if (NumberUtil.WithinTolerance (r2Array[i][j], 0.)) { + lowerTriangular = false; - if (!lowerTriangular) { + if (!upperTriangular) { break; } } @@ -161,52 +190,27 @@ public static final int Type ( } } - if (lowerTriangular && upperTriangular) { + if (upperTriangular && lowerTriangular) { return LOWER_AND_UPPER_TRIANGULAR; } - if (lowerTriangular && !upperTriangular) { - return LOWER_TRIANGULAR; + if (upperTriangular && !lowerTriangular) { + return UPPER_TRIANGULAR; } - if (!lowerTriangular && upperTriangular) { - return UPPER_TRIANGULAR; + if (!upperTriangular && lowerTriangular) { + return LOWER_TRIANGULAR; } return NON_TRIANGULAR; } - /** - * Lower Triangular Matrix - */ - - public static int LOWER_TRIANGULAR = 1; - - /** - * Upper Triangular Matrix - */ - - public static int UPPER_TRIANGULAR = 2; - - /** - * Lower + Upper Triangular Matrix - */ - - public static int LOWER_AND_UPPER_TRIANGULAR = 3; - - /** - * Non Triangular Matrix - */ - - public static int NON_TRIANGULAR = 0; - - private int _type = Integer.MIN_VALUE; - private double[][] _squareMatrix = null; - private boolean zeroDiagonalEntries() { - for (int i = 0; i < _squareMatrix.length; ++i) { - if (0. != _squareMatrix[i][i]) { + double[][] r2Array = r2Array(); + + for (int i = 0; i < r2Array.length; ++i) { + if (0. != r2Array[i][i]) { return false; } } @@ -217,29 +221,26 @@ private boolean zeroDiagonalEntries() /** * TriangularMatrix Constructor * - * @param squareMatrix Input Square Matrix + * @param r2Array R2 Array * * @throws Exception Thrown if the Inputs are Invalid */ - public TriangularMatrix ( - final double[][] squareMatrix) - throws Exception + public static TriangularMatrix Standard ( + final double[][] r2Array) { - if (NON_TRIANGULAR == (_type = Type (_squareMatrix = squareMatrix))) { - throw new Exception ("TriangularMatrix Constructor => Invalid Inputs"); - } - } + int type = Type (r2Array); - /** - * Retrieve the Square Matrix - * - * @return Square Matrix - */ + return NON_TRIANGULAR == type ? null : new TriangularMatrix (r2Array, type); + } - public double[][] squareMatrix() + protected TriangularMatrix ( + final double[][] r2Array, + final int type) { - return _squareMatrix; + super (r2Array); + + _type = type; } /** @@ -287,14 +288,14 @@ public boolean isDiagonal() } /** - * Indicate if the Matrix is not a Valid Triangular Matrix + * Calculate whether the Matrix is "Triangularizable" * - * @return TRUE - Matrix is not a Valid Triangular Matrix + * @return TRUE - Matrix is "Triangularizable" */ - public boolean isInvalid() + @Override public boolean isTriangularizable() { - return LOWER_TRIANGULAR != _type && UPPER_TRIANGULAR != _type; + return true; } /** @@ -305,8 +306,10 @@ public boolean isInvalid() public boolean isUnitriangular() { - for (int i = 0; i < _squareMatrix.length; ++i) { - if (1. != _squareMatrix[i][i]) { + double[][] r2Array = r2Array(); + + for (int i = 0; i < r2Array.length; ++i) { + if (1. != r2Array[i][i]) { return false; } } @@ -314,6 +317,50 @@ public boolean isUnitriangular() return true; } + /** + * Indicate if the Matrix is "Unit" Triangular + * + * @return TRUE - Matrix is "Unit" Triangular + */ + + public boolean isUnit() + { + return isUnitriangular(); + } + + /** + * Indicate if the Matrix is "Normed" Triangular + * + * @return TRUE - Matrix is "Normed" Triangular + */ + + public boolean isNormed() + { + return isUnitriangular(); + } + + /** + * Indicate if the Matrix is Upper Unitriangular + * + * @return TRUE - Matrix is Upper Unitriangular + */ + + public boolean isUpperUnitriangular() + { + return UPPER_TRIANGULAR == _type && isUnitriangular(); + } + + /** + * Indicate if the Matrix is Lower Unitriangular + * + * @return TRUE - Matrix is Lower Unitriangular + */ + + public boolean isLowerUnitriangular() + { + return LOWER_TRIANGULAR == _type && isUnitriangular(); + } + /** * Indicate if the Matrix is Strictly Upper Triangular * @@ -336,18 +383,165 @@ public boolean strictlyLower() return zeroDiagonalEntries() && LOWER_TRIANGULAR == _type; } + /** + * Indicate if the Matrix is Lower "Atomic" Unitriangular + * + * @return TRUE - Matrix is Lower "Atomic" Unitriangular + */ + + public boolean isAtomicLower() + { + if (!isLowerUnitriangular()) { + return false; + } + + int unitValueColumnIndex = -1; + + double[][] r2Array = r2Array(); + + for (int columnIndex = 0; columnIndex < r2Array.length - 1; ++columnIndex) { + if (0 != r2Array[r2Array.length][columnIndex] && 1. != r2Array[r2Array.length][columnIndex]) { + return false; + } + + if (1. == r2Array[r2Array.length][columnIndex]) { + if (-1 != unitValueColumnIndex) { + return false; + } + + unitValueColumnIndex = columnIndex; + } + } + + if (-1 == unitValueColumnIndex) { + return false; + } + + for (int rowIndex = 0; rowIndex < r2Array.length - 1; ++rowIndex) { + for (int columnIndex = 0; columnIndex < rowIndex; ++columnIndex) { + if (unitValueColumnIndex == columnIndex) { + if (1. != r2Array[rowIndex][unitValueColumnIndex]) { + return false; + } + } else if (0. != r2Array[rowIndex][columnIndex]) { + return false; + } + } + } + + return true; + } + + /** + * Indicate if the Matrix is Upper "Atomic" Unitriangular + * + * @return TRUE - Matrix is Upper "Atomic" Unitriangular + */ + + public boolean isAtomicUpper() + { + if (!isUpperUnitriangular()) { + return false; + } + + int unitValueColumnIndex = -1; + + double[][] r2Array = r2Array(); + + for (int columnIndex = 0; columnIndex < r2Array.length - 1; ++columnIndex) { + if (0 != r2Array[0][columnIndex] && 1. != r2Array[0][columnIndex]) { + return false; + } + + if (1. == r2Array[0][columnIndex]) { + if (-1 != unitValueColumnIndex) { + return false; + } + + unitValueColumnIndex = columnIndex; + } + } + + if (-1 == unitValueColumnIndex) { + return false; + } + + for (int rowIndex = 1; rowIndex < r2Array.length - 1; ++rowIndex) { + for (int columnIndex = rowIndex + 1; columnIndex < r2Array.length; ++columnIndex) { + if (unitValueColumnIndex == columnIndex) { + if (1. != r2Array[rowIndex][unitValueColumnIndex]) { + return false; + } + } else if (0. != r2Array[rowIndex][columnIndex]) { + return false; + } + } + } + + return true; + } + + /** + * Indicate if the Matrix is "Atomic" Unitriangular + * + * @return TRUE - Matrix is "Atomic" Unitriangular + */ + + public boolean isAtomic() + { + return isAtomicUpper() || isAtomicLower(); + } + + /** + * Indicate if the Matrix is Frobenius Unitriangular + * + * @return TRUE - Matrix is Frobenius Unitriangular + */ + + public boolean isFrobenius() + { + return isAtomic(); + } + + /** + * Indicate if the Matrix is Gauss Unitriangular + * + * @return TRUE - Matrix is Gauss Unitriangular + */ + + public boolean isGauss() + { + return isAtomic(); + } + + /** + * Indicate if the Matrix is Gauss Transformation Unitriangular + * + * @return TRUE - Matrix is Gauss Transformation Unitriangular + */ + + public boolean isGaussTransformation() + { + return isAtomic(); + } + /** * Compute the Determinant of the Triangular Matrix * * @return Determinant of the Triangular Matrix + * + * @throws Exception Thrown if the Inputs are Invalid */ - public double determinant() + @Override public double determinant() + throws Exception { double determinant = 1.; - for (int i = 0; i < _squareMatrix.length; ++i) { - determinant *= _squareMatrix[i][i]; + double[][] r2Array = r2Array(); + + for (int i = 0; i < r2Array.length; ++i) { + determinant *= r2Array[i][i]; } return determinant; @@ -357,10 +551,61 @@ public double determinant() * Compute the Permanent of the Triangular Matrix * * @return Permanent of the Triangular Matrix + * + * @throws Exception Thrown if the Inputs are Invalid */ public double permanent() + throws Exception { return determinant(); } + + /** + * Retrieve the Eigenvalue Multiplicity Map + * + * @return Eigenvalue Multiplicity Map + */ + + public Map eigenValueMultiplicityMap() + { + Map eigenValueMultiplicityMap = new HashMap(); + + for (double eigenValue : diagonalEntryArray()) { + eigenValueMultiplicityMap.put ( + eigenValue, + eigenValueMultiplicityMap.containsKey (eigenValue) ? + eigenValueMultiplicityMap.get (eigenValue) + 1 : 1 + ); + } + + return eigenValueMultiplicityMap; + } + + /** + * Retrieve the Characteristic Polynomial of the Eigenvalues + * + * @return Characteristic Polynomial of the Eigenvalues + */ + + public R1ToR1 characteristicPolynomial() + { + final double[] diagonalEntryArray = diagonalEntryArray(); + + return new R1ToR1 (null) + { + @Override public double evaluate ( + final double x) + throws Exception + { + double value = 1.; + + for (double eigenValue : diagonalEntryArray) { + value *= (x - eigenValue); + } + + return value; + } + }; + } } diff --git a/src/main/java/org/drip/sample/triangular/LowerTriangular.java b/src/main/java/org/drip/sample/triangular/LowerTriangular.java new file mode 100644 index 00000000000..d5b7fab96c2 --- /dev/null +++ b/src/main/java/org/drip/sample/triangular/LowerTriangular.java @@ -0,0 +1,219 @@ + +package org.drip.sample.triangular; + +import java.util.Date; + +import org.drip.measure.crng.RandomMatrixGenerator; +import org.drip.numerical.common.NumberUtil; +import org.drip.numerical.linearalgebra.TriangularMatrix; +import org.drip.service.common.StringUtil; +import org.drip.service.env.EnvManager; + +/* + * -*- mode: java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + */ + +/*! + * Copyright (C) 2025 Lakshmi Krishnamurthy + * + * This file is part of DROP, an open-source library targeting analytics/risk, transaction cost analytics, + * asset liability management analytics, capital, exposure, and margin analytics, valuation adjustment + * analytics, and portfolio construction analytics within and across fixed income, credit, commodity, + * equity, FX, and structured products. It also includes auxiliary libraries for algorithm support, + * numerical analysis, numerical optimization, spline builder, model validation, statistical learning, + * graph builder/navigator, and computational support. + * + * https://lakshmidrip.github.io/DROP/ + * + * DROP is composed of three modules: + * + * - DROP Product Core - https://lakshmidrip.github.io/DROP-Product-Core/ + * - DROP Portfolio Core - https://lakshmidrip.github.io/DROP-Portfolio-Core/ + * - DROP Computational Core - https://lakshmidrip.github.io/DROP-Computational-Core/ + * + * DROP Product Core implements libraries for the following: + * - Fixed Income Analytics + * - Loan Analytics + * - Transaction Cost Analytics + * + * DROP Portfolio Core implements libraries for the following: + * - Asset Allocation Analytics + * - Asset Liability Management Analytics + * - Capital Estimation Analytics + * - Exposure Analytics + * - Margin Analytics + * - XVA Analytics + * + * DROP Computational Core implements libraries for the following: + * - Algorithm Support + * - Computation Support + * - Function Analysis + * - Graph Algorithm + * - Model Validation + * - Numerical Analysis + * - Numerical Optimizer + * - Spline Builder + * - Statistical Learning + * + * Documentation for DROP is Spread Over: + * + * - Main => https://lakshmidrip.github.io/DROP/ + * - Wiki => https://github.com/lakshmiDRIP/DROP/wiki + * - GitHub => https://github.com/lakshmiDRIP/DROP + * - Repo Layout Taxonomy => https://github.com/lakshmiDRIP/DROP/blob/master/Taxonomy.md + * - Javadoc => https://lakshmidrip.github.io/DROP/Javadoc/index.html + * - Technical Specifications => https://github.com/lakshmiDRIP/DROP/tree/master/Docs/Internal + * - Release Versions => https://lakshmidrip.github.io/DROP/version.html + * - Community Credits => https://lakshmidrip.github.io/DROP/credits.html + * - Issues Catalog => https://github.com/lakshmiDRIP/DROP/issues + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * LowerTriangularMatrix shows the Construction, the Usage, and the Analysis of a Lower Triangular + * Matrix. The References are: + * + *

+ *
    + *
  • + * Axler, S. J. (1997): Linear Algebra Done Right 2nd Edition Springer + * New York NY + *
  • + *
  • + * Bernstein, D. S. (2009): Matrix Mathematics: Theory, Facts, and Formulas 2nd + * Edition Princeton University Press Princeton NJ + *
  • + *
  • + * Herstein, I. N. (1975): Topics in Algebra 2nd Edition Wiley New York NY + *
  • + *
  • + * Prasolov, V. V. (1994): Topics in Algebra American Mathematical Society Providence + * RI + *
  • + *
  • + * Wikipedia (2024): Triangular Matrix https://en.wikipedia.org/wiki/Triangular_matrix + *
  • + *
+ * + *

+ * + *

+ * + * @author Lakshmi Krishnamurthy + */ + +public class LowerTriangular +{ + + private static final void Trial ( + final int elementCount, + final double maximumElement) + throws Exception + { + TriangularMatrix lowerTriangular = RandomMatrixGenerator.LowerTriangular ( + elementCount, + maximumElement, + true + ); + + System.out.println ("\t|-----------------------------------------------------------------||"); + + System.out.println ("\t| Trial at " + new Date()); + + System.out.println ("\t|-----------------------------------------------------------------||"); + + double[][] lowerTriangularR2Array = lowerTriangular.r2Array(); + + for (int i = 0; i < lowerTriangularR2Array.length; ++i) { + System.out.println ( + "\t| Tridiagonal " + elementCount + " x " + elementCount + " => [" + NumberUtil.ArrayRow ( + lowerTriangularR2Array[i], + 2, + 1, + false + ) + " ]||" + ); + } + + System.out.println ("\t|-----------------------------------------------------------------||"); + + System.out.println ( + "\t| Is Upper Triangular => " + StringUtil.ToString (lowerTriangular.isUpper()) + ); + + System.out.println ( + "\t| Is Lower Triangular => " + StringUtil.ToString (lowerTriangular.isLower()) + ); + + System.out.println ( + "\t| Is Diagonal => " + StringUtil.ToString (lowerTriangular.isDiagonal()) + ); + + System.out.println ( + "\t| Is Triangularizable => " + StringUtil.ToString (lowerTriangular.isTriangularizable()) + ); + + System.out.println ( + "\t| Is Unitriangular => " + StringUtil.ToString (lowerTriangular.isUnitriangular()) + ); + + System.out.println ( + "\t| Is Unit Triangular => " + StringUtil.ToString (lowerTriangular.isUnit()) + ); + + System.out.println ( + "\t| Is Normed Triangular => " + StringUtil.ToString (lowerTriangular.isNormed()) + ); + + System.out.println ( + "\t| Is Upper Unitriangular => " + StringUtil.ToString (lowerTriangular.isUpperUnitriangular()) + ); + + System.out.println ( + "\t| Is Lower Unitriangular => " + StringUtil.ToString (lowerTriangular.isLowerUnitriangular()) + ); + + System.out.println ("\t|-----------------------------------------------------------------||"); + } + + /** + * Entry Point + * + * @param argumentArray Command Line Argument Array + * + * @throws Exception Thrown on Error/Exception Situation + */ + + public static final void main ( + final String[] argumentArray) + throws Exception + { + EnvManager.InitEnv ( + "" + ); + + int elementCount = 6; + double maximumElement = 99.; + + Trial (elementCount, maximumElement); + + EnvManager.TerminateEnv(); + } +} diff --git a/src/main/java/org/drip/sample/triangular/package-info.java b/src/main/java/org/drip/sample/triangular/package-info.java new file mode 100644 index 00000000000..dbca7dbc876 --- /dev/null +++ b/src/main/java/org/drip/sample/triangular/package-info.java @@ -0,0 +1,8 @@ + +/** + * Triangular Matrix Variants and Solutions + * + * @author Lakshmi Krishnamurthy + */ + +package org.drip.sample.triangular; diff --git a/src/main/java/org/drip/sample/tridiagonal/NonPeriodicSolverSuite.java b/src/main/java/org/drip/sample/tridiagonal/NonPeriodicSolverSuite.java index da495906473..c7f329cf9b5 100644 --- a/src/main/java/org/drip/sample/tridiagonal/NonPeriodicSolverSuite.java +++ b/src/main/java/org/drip/sample/tridiagonal/NonPeriodicSolverSuite.java @@ -150,10 +150,10 @@ private static final void Trial ( ); } - double[] rhsArray = MatrixUtil.Product (tridiagonalMatrix, xArray); - System.out.println ("\t|-----------------------------------------------------------------||"); + double[] rhsArray = MatrixUtil.Product (tridiagonalMatrix, xArray); + System.out.println ( "\t| RHS Input {" + NumberUtil.ArrayRow (rhsArray, 5, 0, false) + "} ||" );