/// <summary> /// Compute $A^T A$, where A is a matrix. </summary> /// <param name="a"> The matrix </param> /// <returns> The result of $A^T A$ </returns> public virtual DoubleMatrix matrixTransposeMultiplyMatrix(DoubleMatrix a) { ArgChecker.notNull(a, "a"); int n = a.rowCount(); int m = a.columnCount(); //JAVA TO C# CONVERTER NOTE: The following call to the 'RectangularArrays' helper class reproduces the rectangular array initialization that is automatic in Java: //ORIGINAL LINE: double[][] data = new double[m][m]; double[][] data = RectangularArrays.ReturnRectangularDoubleArray(m, m); for (int i = 0; i < m; i++) { double sum = 0d; for (int k = 0; k < n; k++) { sum += a.get(k, i) * a.get(k, i); } data[i][i] = sum; for (int j = i + 1; j < m; j++) { sum = 0d; for (int k = 0; k < n; k++) { sum += a.get(k, i) * a.get(k, j); } data[i][j] = sum; data[j][i] = sum; } } return(DoubleMatrix.ofUnsafe(data)); }
//------------------------------------------------------------------------- private double[] weights(double forward, double strike, double[] strikes, double timeToExpiry, double atmVol) { //JAVA TO C# CONVERTER NOTE: The following call to the 'RectangularArrays' helper class reproduces the rectangular array initialization that is automatic in Java: //ORIGINAL LINE: double[][] mat = new double[3][3]; double[][] mat = RectangularArrays.ReturnRectangularDoubleArray(3, 3); double[] vec = new double[3]; for (int i = 0; i < 3; ++i) { mat[0][i] = BlackFormulaRepository.vega(forward, strikes[i], timeToExpiry, atmVol); mat[1][i] = BlackFormulaRepository.vanna(forward, strikes[i], timeToExpiry, atmVol); mat[2][i] = BlackFormulaRepository.volga(forward, strikes[i], timeToExpiry, atmVol); } vec[0] = BlackFormulaRepository.vega(forward, strike, timeToExpiry, atmVol); vec[1] = BlackFormulaRepository.vanna(forward, strike, timeToExpiry, atmVol); vec[2] = BlackFormulaRepository.volga(forward, strike, timeToExpiry, atmVol); DecompositionResult res = SVD.apply(DoubleMatrix.ofUnsafe(mat)); return(res.solve(vec)); }
/// <summary> /// Returns the Kronecker product of two matrices. If $\mathbf{A}$ is an $m /// \times n$ matrix and $\mathbf{B}$ is a $p \times q$ matrix, then the /// Kronecker product $A \otimes B$ is an $mp \times nq$ matrix with elements /// $$ /// \begin{align*} /// A \otimes B &= /// \begin{pmatrix} /// a_{11}\mathbf{B} & \cdots & a_{1n}\mathbf{B} \\ /// \vdots & \ddots & \vdots \\ /// a_{m1}\mathbf{B} & \cdots & a_{mn}\mathbf{B} /// \end{pmatrix}\\ /// &= /// \begin{pmatrix} /// a_{11}b_{11} & a_{11}b_{12} & \cdots & a_{11}b_{1q} & \cdots & a_{1n}b_{11} & a_{1n}b_{12} & \cdots & a_{1n}b_{1q}\\ /// a_{11}b_{21} & a_{11}b_{22} & \cdots & a_{11}b_{2q} & \cdots & a_{1n}b_{21} & a_{1n}b_{22} & \cdots & a_{1n}b_{2q} \\ /// \vdots & \vdots & \ddots & \vdots & \cdots & \vdots & \vdots & \ddots & \cdots \\ /// a_{11}b_{p1} & a_{11}b_{p2} & \cdots & a_{11}b_{pq} & \cdots & a_{1n}b_{p1} & a_{1n}b_{p2} & \cdots & a_{1n}b_{pq} \\ /// \vdots & \vdots & & \vdots & \ddots & \vdots & \vdots & & \cdots \\ /// a_{m1}b_{11} & a_{m1}b_{12} & \cdots & a_{m1}b_{1q} & \cdots & a_{mn}b_{11} & a_{mn}b_{12} & \cdots & a_{mn}b_{1q} \\ /// a_{m1}b_{21} & a_{m1}b_{22} & \cdots & a_{m1}b_{2q} & \cdots & a_{mn}b_{21} & a_{mn}b_{22} & \cdots & a_{mn}b_{2q} \\ /// \vdots & \vdots & \ddots & \vdots & \cdots & \vdots & \vdots & \ddots & \cdots \\ /// a_{m1}b_{p1} & a_{m1}b_{p2} & \cdots & a_{m1}b_{pq} & \cdots & a_{mn}b_{p1} & a_{mn}b_{p2} & \cdots & a_{mn}b_{pq} /// \end{pmatrix} /// \end{align*} /// $$ </summary> /// <param name="m1"> The first matrix, not null. This matrix must be a <seealso cref="DoubleMatrix"/>. </param> /// <param name="m2"> The second matrix, not null. This matrix must be a <seealso cref="DoubleMatrix"/>. </param> /// <returns> The Kronecker product </returns> public virtual Matrix kroneckerProduct(Matrix m1, Matrix m2) { ArgChecker.notNull(m1, "m1"); ArgChecker.notNull(m2, "m2"); if (m1 is DoubleMatrix && m2 is DoubleMatrix) { DoubleMatrix matrix1 = (DoubleMatrix)m1; DoubleMatrix matrix2 = (DoubleMatrix)m2; int aRows = matrix1.rowCount(); int aCols = matrix1.columnCount(); int bRows = matrix2.rowCount(); int bCols = matrix2.columnCount(); int rRows = aRows * bRows; int rCols = aCols * bCols; //JAVA TO C# CONVERTER NOTE: The following call to the 'RectangularArrays' helper class reproduces the rectangular array initialization that is automatic in Java: //ORIGINAL LINE: double[][] res = new double[rRows][rCols]; double[][] res = RectangularArrays.ReturnRectangularDoubleArray(rRows, rCols); for (int i = 0; i < aRows; i++) { for (int j = 0; j < aCols; j++) { double t = matrix1.get(i, j); if (t != 0.0) { for (int k = 0; k < bRows; k++) { for (int l = 0; l < bCols; l++) { res[i * bRows + k][j * bCols + l] = t * matrix2.get(k, l); } } } } } return(DoubleMatrix.ofUnsafe(res)); } throw new System.ArgumentException("Can only calculate the Kronecker product of two DoubleMatrix."); }
public virtual void test_volatilities() { BlackFxOptionSmileVolatilitiesSpecification @base = BlackFxOptionSmileVolatilitiesSpecification.builder().name(VOL_NAME).currencyPair(EUR_GBP).dayCount(ACT_360).nodes(NODES).timeInterpolator(PCHIP).strikeInterpolator(PCHIP).build(); LocalDate date = LocalDate.of(2017, 9, 25); ZonedDateTime dateTime = date.atStartOfDay().atZone(ZoneId.of("Europe/London")); DoubleArray parameters = DoubleArray.of(0.05, -0.05, 0.15, 0.25, 0.1, -0.1); BlackFxOptionSmileVolatilities computed = @base.volatilities(dateTime, parameters, REF_DATA); LocalDate spotDate = SPOT_OFFSET.adjust(dateTime.toLocalDate(), REF_DATA); DaysAdjustment expOffset = DaysAdjustment.ofBusinessDays(-2, TA_LO); DoubleArray expiries = DoubleArray.of(ACT_360.relativeYearFraction(date, expOffset.adjust(BUS_ADJ.adjust(spotDate.plus(Tenor.TENOR_3M), REF_DATA), REF_DATA)), ACT_360.relativeYearFraction(date, expOffset.adjust(BUS_ADJ.adjust(spotDate.plus(Tenor.TENOR_1Y), REF_DATA), REF_DATA))); SmileDeltaTermStructure smiles = InterpolatedStrikeSmileDeltaTermStructure.of(expiries, DoubleArray.of(0.1), DoubleArray.of(0.25, 0.15), DoubleMatrix.ofUnsafe(new double[][] { new double[] { -0.1 }, new double[] { -0.05 } }), DoubleMatrix.ofUnsafe(new double[][] { new double[] { 0.1 }, new double[] { 0.05 } }), ACT_360, PCHIP, FLAT, FLAT, PCHIP, FLAT, FLAT); BlackFxOptionSmileVolatilities expected = BlackFxOptionSmileVolatilities.of(VOL_NAME, EUR_GBP, dateTime, smiles); assertEquals(computed, expected); }
/// <summary> /// Unwraps a matrix. /// </summary> /// <param name="x"> a Commons matrix </param> /// <returns> an OG 2-D matrix of doubles </returns> public static DoubleMatrix unwrap(RealMatrix x) { ArgChecker.notNull(x, "x"); return(DoubleMatrix.ofUnsafe(x.Data)); }