diff --git a/ReleaseNotes/03_18_2024.txt b/ReleaseNotes/03_18_2024.txt
new file mode 100644
index 00000000000..9580fd2e497
--- /dev/null
+++ b/ReleaseNotes/03_18_2024.txt
@@ -0,0 +1,47 @@
+
+Features:
+
+ - C1 Matrix Util Product #1 (1, 2, 3)
+ - C1 Matrix Util Product #2 (4, 5, 6)
+ - C1 Matrix Util Product #3 (7, 8, 9)
+ - C1 Matrix Util Product #4 (10, 11, 12)
+ - C1 Matrix Util Product #5 (13, 14, 15)
+ - C1 Matrix Util Product #6 (16, 17, 18)
+ - C1 Matrix Util Product #7 (19, 20, 21)
+ - C1 Matrix Util Product #8 (22, 23, 24)
+ - C1 Cartesian Phi Alpha Beta Theta Standard (25, 26, 27)
+ - C1 Cartesian Phi Psi Theta Delta Standard #1 (28, 29, 30)
+ - C1 Cartesian Phi Psi Theta Delta Standard #2 (31, 32, 33)
+ - C1 Cartesian Phi Psi Theta Delta Alpha (34, 35, 36)
+ - C1 Cartesian Phi Psi Theta Delta Beta (37, 38, 39)
+ - C1 Cartesian Fuhr Rzeszotnik Shell (40, 41, 42)
+ - C1 Cartesian Fuhr Rzeszotnik Rho (43, 44)
+ - C1 Cartesian Fuhr Rzeszotnik Epsilon (45, 46)
+ - C1 Cartesian Fuhr Rzeszotnik Eta (47, 48)
+ - C1 Cartesian Fuhr Rzeszotnik Sigma (49, 50)
+ - C1 Cartesian Fuhr Rzeszotnik Constructor #1 (51, 52)
+ - C1 Cartesian Fuhr Rzeszotnik Constructor #2 (53, 54)
+ - C1 Cartesian Fuhr Rzeszotnik Jordan Normal Left (55, 56)
+ - C1 Cartesian Fuhr Rzeszotnik Jordan Normal Center (57, 58)
+ - C1 Cartesian Fuhr Rzeszotnik Jordan Normal Right (58, 60)
+ - C1 Cartesian Fuhr Rzeszotnik #1 (61, 62, 63)
+ - C1 Cartesian Fuhr Rzeszotnik #2 (64, 65)
+ - Numerical Common Unitary Matrix Shell (66, 67, 68)
+ - Numerical Common Unitary Matrix Constructor (69, 70)
+ - C1 Util Numerical Complex Unitary (71, 72)
+ - C1 Matrix Util Unsafe Determinant #1 (73, 74, 75)
+ - C1 Matrix Util Unsafe Determinant #2 (76, 77, 78)
+ - Standard Instance of the Unitary Matrix (79, 80, 81)
+ - Unitary Matrix Condition Number (82, 83, 84)
+
+
+Bug Fixes/Re-organization:
+
+Samples:
+
+IdeaDRIP:
+
+ - Matrix Norm (85-87)
+ - Matrix Norm Preliminaries (88-106)
+ - Matrix Norms Induced by Vector (107-117)
+ - Matrix Norms Induced by Vector p-Norms (118-120)
diff --git a/src/main/java/org/drip/numerical/complex/C1CartesianFuhrRzeszotnik.java b/src/main/java/org/drip/numerical/complex/C1CartesianFuhrRzeszotnik.java
new file mode 100644
index 00000000000..eef537fe7cb
--- /dev/null
+++ b/src/main/java/org/drip/numerical/complex/C1CartesianFuhrRzeszotnik.java
@@ -0,0 +1,278 @@
+
+package org.drip.numerical.complex;
+
+import org.drip.numerical.matrix.R1SquareRotation2x2;
+
+/*
+ * -*- 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.
+ */
+
+/**
+ * C1CartesianFuhrRzeszotnik implements the type and Functionality associated with a C1
+ * Square Matrix parameterized by the Fuhr-Rzeszotnik parameters rho
, epsilon
,
+ * eta
, and sigma
Fields. The References are:
+ *
+ *
+ *
Rho
+ *
+ * @return Rho
+ */
+
+ public double rho()
+ {
+ return _rho;
+ }
+
+ /**
+ * Retrieve Epsilon
+ *
+ * @return Epsilon
+ */
+
+ public double epsilon()
+ {
+ return _epsilon;
+ }
+
+ /**
+ * Retrieve Eta
+ *
+ * @return Eta
+ */
+
+ public double eta()
+ {
+ return _eta;
+ }
+
+ /**
+ * Retrieve Sigma
+ *
+ * @return Sigma
+ */
+
+ public double sigma()
+ {
+ return _sigma;
+ }
+
+ /**
+ * Retrieve the Jordan Normal Left Part of C1CartesianPhiPsiThetaDelta
+ *
+ * @return Jordan Normal Left Part of C1CartesianPhiPsiThetaDelta
+ */
+
+ public R1SquareRotation2x2 jordanNormalLeft()
+ {
+ return _jordanNormalLeft;
+ }
+
+ /**
+ * Retrieve the Jordan Normal Center Part of C1CartesianPhiPsiThetaDelta
+ *
+ * @return Jordan Normal Center Part of C1CartesianPhiPsiThetaDelta
+ */
+
+ public C1Square jordanNormalCenter()
+ {
+ return _jordanNormalCenter;
+ }
+
+ /**
+ * Retrieve the Jordan Normal Right Part of C1CartesianPhiPsiThetaDelta
+ *
+ * @return Jordan Normal Right Part of C1CartesianPhiPsiThetaDelta
+ */
+
+ public R1SquareRotation2x2 jordanNormalRight()
+ {
+ return _jordanNormalRight;
+ }
+}
diff --git a/src/main/java/org/drip/numerical/complex/C1CartesianPhiAlphaBetaTheta.java b/src/main/java/org/drip/numerical/complex/C1CartesianPhiAlphaBetaTheta.java
index 850bcdc812c..121c1f5c4fe 100644
--- a/src/main/java/org/drip/numerical/complex/C1CartesianPhiAlphaBetaTheta.java
+++ b/src/main/java/org/drip/numerical/complex/C1CartesianPhiAlphaBetaTheta.java
@@ -147,23 +147,43 @@ public static C1CartesianPhiAlphaBetaTheta Standard (
C1Cartesian ePowerIPhi = C1Cartesian.UnitImaginary().scale (0.5 * phi).exponentiate();
+ if (null == ePowerIPhi) {
+ return null;
+ }
+
C1Cartesian ePowerIAlpha = C1Cartesian.UnitImaginary().scale (alpha).exponentiate();
+ if (null == ePowerIAlpha) {
+ return null;
+ }
+
C1Cartesian ePowerIBeta = C1Cartesian.UnitImaginary().scale (beta).exponentiate();
- C1Cartesian[][] c1Grid = new C1Cartesian[2][2];
+ if (null == ePowerIBeta) {
+ return null;
+ }
double sinTheta = Math.sin (theta);
double cosTheta = Math.cos (theta);
- c1Grid[1][1] = ePowerIPhi.divide (ePowerIAlpha).scale (cosTheta);
+ C1Cartesian[][] c1Grid = new C1Cartesian[2][2];
- c1Grid[0][1] = ePowerIPhi.product (ePowerIBeta).scale (sinTheta);
+ if (null == (c1Grid[0][0] = ePowerIPhi.product (ePowerIAlpha).scale (cosTheta))) {
+ return null;
+ }
- c1Grid[0][0] = ePowerIPhi.product (ePowerIAlpha).scale (cosTheta);
+ if (null == (c1Grid[0][1] = ePowerIPhi.product (ePowerIBeta).scale (sinTheta))) {
+ return null;
+ }
- c1Grid[1][0] = ePowerIPhi.divide (ePowerIBeta).scale (-1. * sinTheta);
+ if (null == (c1Grid[1][0] = ePowerIPhi.divide (ePowerIBeta).scale (-1. * sinTheta))) {
+ return null;
+ }
+
+ if (null == (c1Grid[1][1] = ePowerIPhi.divide (ePowerIAlpha).scale (cosTheta))) {
+ return null;
+ }
return new C1CartesianPhiAlphaBetaTheta (c1Grid, alpha, beta, theta, phi);
}
diff --git a/src/main/java/org/drip/numerical/complex/C1CartesianPhiPsiThetaDelta.java b/src/main/java/org/drip/numerical/complex/C1CartesianPhiPsiThetaDelta.java
index 3471048eb1c..a7410b45303 100644
--- a/src/main/java/org/drip/numerical/complex/C1CartesianPhiPsiThetaDelta.java
+++ b/src/main/java/org/drip/numerical/complex/C1CartesianPhiPsiThetaDelta.java
@@ -126,6 +126,17 @@ public class C1CartesianPhiPsiThetaDelta extends C1Square
private C1Square _jordanNormalRight = null;
private R1SquareRotation2x2 _jordanNormalCenter = null;
+ /**
+ * Construct a Standard Instance of C1CartesianPhiPsiThetaDelta
+ *
+ * @param phi "Phi"
+ * @param psi "Psi"
+ * @param theta "Theta"
+ * @param delta "Delta"
+ *
+ * @return C1CartesianPhiPsiThetaDelta Instance
+ */
+
public static C1CartesianPhiPsiThetaDelta Standard (
final double phi,
final double psi,
@@ -138,24 +149,44 @@ public static C1CartesianPhiPsiThetaDelta Standard (
return null;
}
+ C1Cartesian ePowerIPhi = C1Cartesian.UnitImaginary().scale (0.5 * phi).exponentiate();
+
+ if (null == ePowerIPhi) {
+ return null;
+ }
+
+ C1Square jordanNormalLeft = C1Square.Rotation2x2 (psi);
+
+ if (null == jordanNormalLeft || (null == (jordanNormalLeft = jordanNormalLeft.product (ePowerIPhi))))
+ {
+ return null;
+ }
+
R1SquareRotation2x2 jordanNormalCenter = R1SquareRotation2x2.Standard (theta);
+ if (null == jordanNormalCenter) {
+ return null;
+ }
+
C1Square jordanNormalRight = C1Square.Rotation2x2 (delta);
- C1Square jordanNormalLeft = C1Square.Rotation2x2 (psi);
+ if (null == jordanNormalRight) {
+ return null;
+ }
- C1Cartesian[][] c1Grid = new C1Cartesian[2][2];
-
- return new C1CartesianPhiPsiThetaDelta (
- c1Grid,
- phi,
- psi,
- theta,
- delta,
- jordanNormalLeft,
- jordanNormalCenter,
- jordanNormalRight
- );
+ C1Square c1Square = jordanNormalLeft.product (jordanNormalCenter);
+
+ return null == c1Square || null == (c1Square = c1Square.product (jordanNormalRight)) ?
+ null : new C1CartesianPhiPsiThetaDelta (
+ c1Square.c1Grid(),
+ phi,
+ psi,
+ theta,
+ delta,
+ jordanNormalLeft,
+ jordanNormalCenter,
+ jordanNormalRight
+ );
}
private C1CartesianPhiPsiThetaDelta (
@@ -255,4 +286,26 @@ public C1Square jordanNormalRight()
{
return _jordanNormalRight;
}
+
+ /**
+ * Calculate Alpha
+ *
+ * @return Alpha
+ */
+
+ public double alpha()
+ {
+ return _psi + _delta;
+ }
+
+ /**
+ * Calculate Beta
+ *
+ * @return Beta
+ */
+
+ public double beta()
+ {
+ return _psi - _delta;
+ }
}
diff --git a/src/main/java/org/drip/numerical/complex/C1MatrixUtil.java b/src/main/java/org/drip/numerical/complex/C1MatrixUtil.java
index 4af1199e6c3..05b771efe85 100644
--- a/src/main/java/org/drip/numerical/complex/C1MatrixUtil.java
+++ b/src/main/java/org/drip/numerical/complex/C1MatrixUtil.java
@@ -1,6 +1,8 @@
package org.drip.numerical.complex;
+import org.drip.numerical.common.NumberUtil;
+
/*
* -*- mode: java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*/
@@ -213,6 +215,111 @@ public static final C1Cartesian[][] UnsafeProduct (
return product;
}
+ /**
+ * Compute the Product of the Input Matrices. Unsafe Methods do not validate the Input Arguments, so
+ * use caution in applying these Methods
+ *
+ * @param r1GridA Grid of R1
+ * @param c1GridB Grid of C1
+ *
+ * @return The Product Matrix
+ */
+
+ public static final C1Cartesian[][] UnsafeProduct (
+ final double[][] r1GridA,
+ final C1Cartesian[][] c1GridB)
+ {
+ C1Cartesian[][] product = new C1Cartesian[r1GridA.length][c1GridB[0].length];
+
+ for (int rowIndex = 0; rowIndex < r1GridA.length; ++rowIndex) {
+ for (int columnIndex = 0; columnIndex < c1GridB[0].length; ++columnIndex) {
+ product[rowIndex][columnIndex] = C1Cartesian.Zero();
+ }
+ }
+
+ for (int rowIndex = 0; rowIndex < r1GridA.length; ++rowIndex) {
+ for (int columnIndex = 0; columnIndex < c1GridB[0].length; ++columnIndex) {
+ for (int k = 0; k < r1GridA[0].length; ++k) {
+ if (null == product[rowIndex][columnIndex].scale (
+ r1GridA[rowIndex][k]
+ ).add (
+ c1GridB[k][columnIndex]
+ )
+ )
+ {
+ return null;
+ }
+ }
+ }
+ }
+
+ return product;
+ }
+
+ /**
+ * Compute the Product of the Input Matrix and the Complex Number. Unsafe Methods do not validate the
+ * Input Arguments, so use caution in applying these Methods
+ *
+ * @param c1Grid Grid of C1
+ * @param c1 C1
+ *
+ * @return The Product Matrix
+ */
+
+ public static final C1Cartesian[][] UnsafeProduct (
+ final C1Cartesian[][] c1Grid,
+ final C1Cartesian c1)
+ {
+ C1Cartesian[][] product = new C1Cartesian[c1Grid.length][c1Grid[0].length];
+
+ for (int rowIndex = 0; rowIndex < c1Grid.length; ++rowIndex) {
+ for (int columnIndex = 0; columnIndex < c1Grid[0].length; ++columnIndex) {
+ if (null == (product[rowIndex][columnIndex] = c1Grid[rowIndex][columnIndex].product (c1))) {
+ return null;
+ }
+ }
+ }
+
+ return product;
+ }
+
+ /**
+ * Determinant of the Input Matrix. Unsafe Methods do not validate the Input Arguments, so use
+ * caution in applying these Methods
+ *
+ * @param c1Grid Grid of C1 Instances
+ *
+ * @return The Determinant
+ */
+
+ public static final double UnsafeDeterminant (
+ final C1Cartesian[][] c1Grid)
+ {
+ if (1 == c1Grid.length) {
+ return Math.sqrt (c1Grid[0][0].modulus());
+ }
+
+ if (2 == c1Grid.length) {
+ return Math.sqrt (
+ C1Util.UnsafeDotProduct (c1Grid[0][0], c1Grid[1][1]) -
+ C1Util.UnsafeDotProduct (c1Grid[0][1], c1Grid[1][0])
+ );
+ }
+
+ int slimSize = c1Grid.length - 1;
+
+ C1Cartesian[][] c1GridNew = new C1Cartesian[slimSize][slimSize];
+
+ for (int i = 0; i < slimSize; ++i) {
+ for (int j = 0; j < slimSize; ++j) {
+ c1GridNew[i][j] = c1Grid[i][j];
+ }
+ }
+
+ return UnsafeDeterminant (c1GridNew) * c1Grid[slimSize][slimSize].l2Norm() -
+ c1Grid[slimSize][slimSize].l2Norm() * c1Grid[slimSize][slimSize].l2Norm();
+ }
+
/**
* Indicate the C1 Vector is Valid
*
@@ -300,44 +407,96 @@ public static final C1Cartesian[][] Product (
/**
* Compute the Product of the Input Matrices
*
- * @param c1GridA Grid of C1
- * @param r1GridB Grid of R1
+ * @param c1Grid rid of C1
+ * @param r1Grid Grid of R1
*
* @return The Product Matrix
*/
public static final C1Cartesian[][] Product (
- final C1Cartesian[][] c1GridA,
- final double[][] r1GridB)
+ final C1Cartesian[][] c1Grid,
+ final double[][] r1Grid)
{
- if (!IsGridValid (c1GridA) ||
- null == r1GridB || 0 == r1GridB.length ||
- null == r1GridB[0] || 0 == r1GridB[0].length)
- {
- return null;
- };
+ return !IsGridValid (c1Grid) ||
+ null == r1Grid || 0 == r1Grid.length ||
+ c1Grid[0].length != r1Grid.length ||
+ !NumberUtil.IsValid (r1Grid) ?
+ null : UnsafeProduct (c1Grid, r1Grid);
+ }
- C1Cartesian[][] product = new C1Cartesian[c1GridA.length][r1GridB[0].length];
+ /**
+ * Compute the Product of the Input Matrices
+ *
+ * @param r1Grid Grid of R1
+ * @param c1Grid Grid of C1
+ *
+ * @return The Product Matrix
+ */
- for (int rowIndex = 0; rowIndex < c1GridA.length; ++rowIndex) {
- for (int columnIndex = 0; columnIndex < r1GridB[0].length; ++columnIndex) {
- product[rowIndex][columnIndex] = C1Cartesian.Zero();
- }
+ public static final C1Cartesian[][] Product (
+ final double[][] r1Grid,
+ final C1Cartesian[][] c1Grid)
+ {
+ return null == r1Grid || 0 == r1Grid.length || null == r1Grid[0] ||
+ !NumberUtil.IsValid (r1Grid) || !IsGridValid (c1Grid) || r1Grid[0].length != c1Grid.length ?
+ null : UnsafeProduct (r1Grid, c1Grid);
+ }
+
+ /**
+ * Compute the Product of the Input Matrix and the Complex Number
+ *
+ * @param c1Grid Grid of C1
+ * @param c1 C1
+ *
+ * @return The Product Matrix
+ */
+
+ public static final C1Cartesian[][] Product (
+ final C1Cartesian[][] c1Grid,
+ final C1Cartesian c1)
+ {
+ return !IsGridValid (c1Grid) || null == c1 ? null : UnsafeProduct (c1Grid, c1);
+ }
+
+ /**
+ * Determinant of the Input Matrix
+ *
+ * @param c1Grid Grid of C1Cartesian Instances
+ *
+ * @return The Determinant
+ *
+ * @throws Exception Thrown if the Inputs are Invalid
+ */
+
+ public static final double Determinant (
+ final C1Cartesian[][] c1Grid)
+ throws Exception
+ {
+ if (null == c1Grid || 0 == c1Grid.length || 0 == c1Grid[0].length) {
+ throw new Exception ("C1MatrixUtil::Determinant => Invalid Inputs");
}
- for (int rowIndex = 0; rowIndex < c1GridA.length; ++rowIndex) {
- for (int columnIndex = 0; columnIndex < r1GridB[0].length; ++columnIndex) {
- for (int k = 0; k < c1GridA[0].length; ++k) {
- if (null == product[rowIndex][columnIndex].add (
- c1GridA[rowIndex][k].scale (r1GridB[k][columnIndex])
- ))
- {
- return null;
- }
- }
- }
+ return UnsafeDeterminant (c1Grid);
+ }
+
+ /**
+ * Indicate if the Input Matrix is Unitary
+ *
+ * @param c1Grid Grid of C1Cartesian Instances
+ *
+ * @return TRUE - Input Matrix is Unitary
+ *
+ * @throws Exception Thrown if the Inputs are Invalid
+ */
+
+ public static final boolean IsUnitary (
+ final C1Cartesian[][] c1Grid)
+ throws Exception
+ {
+ if (null == c1Grid || 0 == c1Grid.length || 0 == c1Grid[0].length) {
+ throw new Exception ("C1MatrixUtil::Determinant => Invalid Inputs");
}
- return product;
+ return NumberUtil.WithinTolerance (UnsafeDeterminant (c1Grid), 0.);
}
}
diff --git a/src/main/java/org/drip/numerical/complex/C1Square.java b/src/main/java/org/drip/numerical/complex/C1Square.java
index d23aad3e1b6..bd772c8c913 100644
--- a/src/main/java/org/drip/numerical/complex/C1Square.java
+++ b/src/main/java/org/drip/numerical/complex/C1Square.java
@@ -2,6 +2,7 @@
package org.drip.numerical.complex;
import org.drip.numerical.common.NumberUtil;
+import org.drip.numerical.matrix.R1Square;
/*
* -*- mode: java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
@@ -174,6 +175,38 @@ public static final C1Square Rotation2x2 (
return new C1Square (c1Grid);
}
+ /**
+ * Construct a 2x2 Rotation C1 Matrix
+ *
+ * @param theta1 The Left Rotation Angle
+ * @param theta2 The Right Rotation Angle
+ *
+ * @return 2x2 Rotation C1 Matrix
+ */
+
+ public static final C1Square Rotation2x2 (
+ final double theta1,
+ final double theta2)
+ {
+ if (!NumberUtil.IsValid (theta1) || !NumberUtil.IsValid (theta2)) {
+ return null;
+ }
+
+ C1Cartesian c1Zero = C1Cartesian.Zero();
+
+ C1Cartesian c1UnitImaginary = C1Cartesian.UnitImaginary();
+
+ C1Cartesian[][] c1Grid = new C1Cartesian[2][2];
+ c1Grid[1][0] = c1Zero;
+ c1Grid[0][1] = c1Zero;
+
+ c1Grid[0][0] = c1UnitImaginary.scale (theta1).exponentiate();
+
+ c1Grid[1][1] = c1UnitImaginary.scale (theta2).exponentiate();
+
+ return new C1Square (c1Grid);
+ }
+
protected C1Square (
final C1Cartesian[][] c1Grid)
{
@@ -262,7 +295,7 @@ public C1Square slimContract()
public double determinant()
{
- return C1Util.UnsafeDeterminant (c1Grid());
+ return C1MatrixUtil.UnsafeDeterminant (c1Grid());
}
/**
@@ -286,4 +319,34 @@ public boolean isUnitary()
{
return isUnitDeterminant();
}
+
+ /**
+ * Compute the Product with the other Square Matrix
+ *
+ * @param r1Square R1 Square Matrix
+ *
+ * @return Resulting Product
+ */
+
+ public C1Square product (
+ final R1Square r1Square)
+ {
+ return null == r1Square ? null : new C1Square (
+ C1MatrixUtil.UnsafeProduct (c1Grid(), r1Square.r1Grid())
+ );
+ }
+
+ /**
+ * Compute the Product of the Input Matrix and the Complex Number
+ *
+ * @param c1 C1
+ *
+ * @return The Product C1Square
+ */
+
+ public C1Square product (
+ final C1Cartesian c1)
+ {
+ return null == c1 ? null : new C1Square (C1MatrixUtil.UnsafeProduct (c1Grid(), c1));
+ }
}
diff --git a/src/main/java/org/drip/numerical/complex/C1Util.java b/src/main/java/org/drip/numerical/complex/C1Util.java
index 050e2de75cc..1caf5cce70e 100644
--- a/src/main/java/org/drip/numerical/complex/C1Util.java
+++ b/src/main/java/org/drip/numerical/complex/C1Util.java
@@ -428,43 +428,6 @@ public static final double UnsafeDotProduct (
return a.real() * e.real() + a.imaginary() + a.imaginary();
}
- /**
- * Determinant of the Input Matrix. Unsafe Methods do not validate the Input Arguments, so use
- * caution in applying these Methods
- *
- * @param c1Grid Grid of C1 Instances
- *
- * @return The Determinant
- */
-
- public static final double UnsafeDeterminant (
- final C1Cartesian[][] c1Grid)
- {
- if (1 == c1Grid.length) {
- return Math.sqrt (c1Grid[0][0].modulus());
- }
-
- if (2 == c1Grid.length) {
- return Math.sqrt (
- C1Util.UnsafeDotProduct (c1Grid[0][0], c1Grid[1][1]) -
- C1Util.UnsafeDotProduct (c1Grid[0][1], c1Grid[1][0])
- );
- }
-
- int slimSize = c1Grid.length - 1;
-
- C1Cartesian[][] c1GridNew = new C1Cartesian[slimSize][slimSize];
-
- for (int i = 0; i < slimSize; ++i) {
- for (int j = 0; j < slimSize; ++j) {
- c1GridNew[i][j] = c1Grid[i][j];
- }
- }
-
- return UnsafeDeterminant (c1GridNew) * c1Grid[slimSize][slimSize].l2Norm() -
- c1Grid[slimSize][slimSize].l2Norm() * c1Grid[slimSize][slimSize].l2Norm();
- }
-
/**
* Add the 2 Complex Numbers
*
@@ -645,25 +608,4 @@ public static final double DotProduct (
return UnsafeDotProduct (a, e);
}
-
- /**
- * Determinant of the Input Matrix
- *
- * @param c1Grid Grid of C1Cartesian Instances
- *
- * @return The Determinant
- *
- * @throws Exception Thrown if the Inputs are Invalid
- */
-
- public static final double Determinant (
- final C1Cartesian[][] c1Grid)
- throws Exception
- {
- if (null == c1Grid || 0 == c1Grid.length || 0 == c1Grid[0].length) {
- throw new Exception ("C1MatrixUtil::Determinant => Invalid Inputs");
- }
-
- return UnsafeDeterminant (c1Grid);
- }
}
diff --git a/src/main/java/org/drip/numerical/complex/UnitaryMatrix.java b/src/main/java/org/drip/numerical/complex/UnitaryMatrix.java
new file mode 100644
index 00000000000..d166120ec2f
--- /dev/null
+++ b/src/main/java/org/drip/numerical/complex/UnitaryMatrix.java
@@ -0,0 +1,153 @@
+
+package org.drip.numerical.complex;
+
+/*
+ * -*- 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.
+ */
+
+/**
+ * UnitaryMatrix implements the Unitary Matrix. The References are:
+ *
+ *