/// <summary> /// This regression method is private and called in other regression methods </summary> /// <param name="xDataMatrix"> _nData x (_degree + 1) matrix whose low vector is (xData[i]^0, xData[i]^1, ..., xData[i]^{_degree}) </param> /// <param name="yDataVector"> the y-values </param> /// <param name="nData"> Number of data points </param> /// <param name="degree"> the degree </param> private LeastSquaresRegressionResult regress(DoubleMatrix xDataMatrix, DoubleArray yDataVector, int nData, int degree) { Decomposition <QRDecompositionResult> qrComm = new QRDecompositionCommons(); DecompositionResult decompResult = qrComm.apply(xDataMatrix); _qrResult = (QRDecompositionResult)decompResult; DoubleMatrix qMatrix = _qrResult.Q; DoubleMatrix rMatrix = _qrResult.R; double[] betas = backSubstitution(qMatrix, rMatrix, yDataVector, degree); double[] residuals = residualsSolver(xDataMatrix, betas, yDataVector); for (int i = 0; i < degree + 1; ++i) { ArgChecker.isFalse(double.IsNaN(betas[i]), "Input is too large or small"); } for (int i = 0; i < nData; ++i) { ArgChecker.isFalse(double.IsNaN(residuals[i]), "Input is too large or small"); } return(new LeastSquaresRegressionResult(betas, residuals, 0.0, null, 0.0, 0.0, null, null, true)); }
/// <summary> /// Decomposes an array of long numbers /// </summary> /// <param name="number">Numbers to test</param> /// <returns> /// All -> All decomposition values /// Common -> Only the decomposition values that were divisible by whole line /// </returns> private static DecompositionResult GetDecomposedArray(long[] number) { long[] clone = (long[])number.Clone(); DecompositionResult result = new DecompositionResult(); long prime = 2; while (clone.Any(x => x > 1)) { bool isDivisible = false; bool allDivisible = true; for (int i = 0; i < clone.Count(); i++) { long q = clone[i]; if (q % prime == 0) { isDivisible = true; q /= prime; } else { allDivisible = false; } clone[i] = q; } if (allDivisible) { result.Common.Add(prime); } if (isDivisible) { result.All.Add(prime); } else { prime = prime.NextPrime(); } } return(result); }
private GeneralizedLeastSquareResults <T> solveImp <T>(IList <T> x, IList <double> y, IList <double> sigma, IList <System.Func <T, double> > basisFunctions, int[] sizes, double[] lambda, int[] differenceOrder) { int dim = sizes.Length; int n = x.Count; int m = basisFunctions.Count; double[] b = new double[m]; double[] invSigmaSqr = new double[n]; //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[][] f = new double[m][n]; double[][] f = RectangularArrays.ReturnRectangularDoubleArray(m, n); int i, j, k; for (i = 0; i < n; i++) { double temp = sigma[i]; ArgChecker.isTrue(temp > 0, "sigma must be great than zero"); invSigmaSqr[i] = 1.0 / temp / temp; } for (i = 0; i < m; i++) { for (j = 0; j < n; j++) { f[i][j] = basisFunctions[i](x[j]); } } double sum; for (i = 0; i < m; i++) { sum = 0; for (k = 0; k < n; k++) { sum += y[k] * f[i][k] * invSigmaSqr[k]; } b[i] = sum; } DoubleArray mb = DoubleArray.copyOf(b); DoubleMatrix ma = getAMatrix(f, invSigmaSqr); for (i = 0; i < dim; i++) { if (lambda[i] > 0.0) { DoubleMatrix d = getDiffMatrix(sizes, differenceOrder[i], i); ma = (DoubleMatrix)_algebra.add(ma, _algebra.scale(d, lambda[i])); } } DecompositionResult decmp = _decomposition.apply(ma); DoubleArray w = decmp.solve(mb); DoubleMatrix covar = decmp.solve(DoubleMatrix.identity(m)); double chiSq = 0; for (i = 0; i < n; i++) { double temp = 0; for (k = 0; k < m; k++) { temp += w.get(k) * f[k][i]; } chiSq += FunctionUtils.square(y[i] - temp) * invSigmaSqr[i]; } return(new GeneralizedLeastSquareResults <T>(basisFunctions, chiSq, w, covar)); }
/// <summary> /// Computes the derivative of the three fitting parameters with respect to the SABR parameters. /// The computation requires some third order derivatives; they are computed by finite difference /// on the second order derivatives. /// Used to compute the derivative of the price with respect to the SABR parameters. /// </summary> /// <returns> the derivatives </returns> private double[][] computesParametersDerivativeSabr() { //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[][] result = new double[4][3]; double[][] result = RectangularArrays.ReturnRectangularDoubleArray(4, 3); if (Math.Abs(priceK[0]) < SMALL_PRICE && Math.Abs(priceK[1]) < SMALL_PRICE && Math.Abs(priceK[2]) < SMALL_PRICE) { // Implementation note: If value and its derivatives is too small, then parameters are such that the extrapolated price is "very small". return(result); } // Derivative of price with respect to SABR parameters. //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[][] pdSabr = new double[4][3]; // parameter SABR - equation double[][] pdSabr = RectangularArrays.ReturnRectangularDoubleArray(4, 3); // parameter SABR - equation double shift = 1.0E-5; double[] vD = new double[6]; //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[][] vD2 = new double[2][2]; double[][] vD2 = RectangularArrays.ReturnRectangularDoubleArray(2, 2); sabrFunction.volatilityAdjoint2(forward, cutOffStrike, timeToExpiry, sabrData, vD, vD2); for (int loopparam = 0; loopparam < 4; loopparam++) { int paramIndex = 2 + loopparam; Pair <ValueDerivatives, double[][]> pa2 = BlackFormulaRepository.priceAdjoint2(forward, cutOffStrike, timeToExpiry, volatilityK, true); double[] bsD = pa2.First.Derivatives.toArrayUnsafe(); double[][] bsD2 = pa2.Second; pdSabr[loopparam][0] = bsD[3] * vD[paramIndex]; double[] vDpP = new double[6]; //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[][] vD2pP = new double[2][2]; double[][] vD2pP = RectangularArrays.ReturnRectangularDoubleArray(2, 2); SabrFormulaData sabrDatapP; double param; double paramShift; switch (loopparam) { case 0: param = sabrData.Alpha; paramShift = param * shift; // Relative shift to cope with difference in order of magnitude. sabrDatapP = sabrData.withAlpha(param + paramShift); break; case 1: param = sabrData.Beta; paramShift = shift; // Absolute shift as usually 0 <= beta <= 1; beta can be zero, so relative shift is not possible. sabrDatapP = sabrData.withBeta(param + paramShift); break; case 2: param = sabrData.Rho; paramShift = shift; // Absolute shift as -1 <= rho <= 1; rho can be zero, so relative shift is not possible. sabrDatapP = sabrData.withRho(param + paramShift); break; default: param = sabrData.Nu; paramShift = shift; // nu can be zero, so relative shift is not possible. sabrDatapP = sabrData.withNu(param + paramShift); break; } sabrFunction.volatilityAdjoint2(forward, cutOffStrike, timeToExpiry, sabrDatapP, vDpP, vD2pP); double vD2Kp = (vDpP[1] - vD[1]) / paramShift; double vD3KKa = (vD2pP[1][1] - vD2[1][1]) / paramShift; pdSabr[loopparam][1] = (bsD2[1][2] + bsD2[2][2] * vD[1]) * vD[paramIndex] + bsD[3] * vD2Kp; Pair <ValueDerivatives, double[][]> pa2VP = BlackFormulaRepository.priceAdjoint2(forward, cutOffStrike, timeToExpiry, volatilityK * (1d + shift), true); double[][] bsD2VP = pa2VP.Second; double bsD3sss = (bsD2VP[2][2] - bsD2[2][2]) / (volatilityK * shift); double bsD3sKK = (bsD2VP[1][1] - bsD2[1][1]) / (volatilityK * shift); double bsD3ssK = (bsD2VP[2][1] - bsD2[2][1]) / (volatilityK * shift); pdSabr[loopparam][2] = (bsD3sKK + bsD3ssK * vD[1] + (bsD3ssK + bsD3sss * vD[1]) * vD[1] + bsD2[2][2] * vD2[1][1]) * vD[paramIndex] + 2 * (bsD2[2][1] + bsD2[2][2] * vD[1]) * vD2Kp + bsD[3] * vD3KKa; } // Derivative of f with respect to abc. //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[][] fD = new double[3][3]; // fD[i][j]: derivative with respect to jth variable of f_i double[][] fD = RectangularArrays.ReturnRectangularDoubleArray(3, 3); // fD[i][j]: derivative with respect to jth variable of f_i double f = priceK[0]; double fp = priceK[1]; double fpp = priceK[2]; fD[0][0] = f; fD[0][1] = f / cutOffStrike; fD[0][2] = fD[0][1] / cutOffStrike; fD[1][0] = fp; fD[1][1] = (fp - fD[0][1]) / cutOffStrike; fD[1][2] = (fp - 2 * fD[0][1]) / (cutOffStrike * cutOffStrike); fD[2][0] = fpp; fD[2][1] = (fpp + fD[0][2] * (2 * (mu + 1) + 2 * parameter[1] / cutOffStrike + 4 * parameter[2] / (cutOffStrike * cutOffStrike))) / cutOffStrike; fD[2][2] = (fpp + fD[0][2] * (2 * (2 * mu + 3) + 4 * parameter[1] / cutOffStrike + 8 * parameter[2] / (cutOffStrike * cutOffStrike))) / (cutOffStrike * cutOffStrike); DoubleMatrix fDmatrix = DoubleMatrix.ofUnsafe(fD); DecompositionResult decmp = SVD.apply(fDmatrix); for (int loopparam = 0; loopparam < 4; loopparam++) { result[loopparam] = decmp.solve(pdSabr[loopparam]); } return(result); }
/// <summary> /// Computes the derivative of the three fitting parameters with respect to the forward. /// The computation requires some third order derivatives; they are computed by finite /// difference on the second order derivatives. /// Used to compute the derivative of the price with respect to the forward. /// </summary> /// <returns> the derivatives </returns> private double[] computesParametersDerivativeForward() { if (Math.Abs(priceK[0]) < SMALL_PRICE && Math.Abs(priceK[1]) < SMALL_PRICE && Math.Abs(priceK[2]) < SMALL_PRICE) { // Implementation note: If value and its derivatives is too small, then parameters are such that the extrapolated price is "very small". return(new double[] { 0.0, 0.0, 0.0 }); } // Derivative of price with respect to forward. double[] pDF = new double[3]; double shift = 0.00001; double[] vD = new double[6]; //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[][] vD2 = new double[2][2]; double[][] vD2 = RectangularArrays.ReturnRectangularDoubleArray(2, 2); sabrFunction.volatilityAdjoint2(forward, cutOffStrike, timeToExpiry, sabrData, vD, vD2); Pair <ValueDerivatives, double[][]> pa2 = BlackFormulaRepository.priceAdjoint2(forward, cutOffStrike, timeToExpiry, volatilityK, true); double[] bsD = pa2.First.Derivatives.toArrayUnsafe(); double[][] bsD2 = pa2.Second; pDF[0] = bsD[0] + bsD[3] * vD[0]; pDF[1] = bsD2[0][1] + bsD2[2][0] * vD[1] + (bsD2[1][2] + bsD2[2][2] * vD[1]) * vD[0] + bsD[3] * vD2[1][0]; Pair <ValueDerivatives, double[][]> pa2KP = BlackFormulaRepository.priceAdjoint2(forward, cutOffStrike * (1 + shift), timeToExpiry, volatilityK, true); double[][] bsD2KP = pa2KP.Second; double bsD3FKK = (bsD2KP[1][0] - bsD2[1][0]) / (cutOffStrike * shift); Pair <ValueDerivatives, double[][]> pa2VP = BlackFormulaRepository.priceAdjoint2(forward, cutOffStrike, timeToExpiry, volatilityK * (1 + shift), true); double[][] bsD2VP = pa2VP.Second; double bsD3sss = (bsD2VP[2][2] - bsD2[2][2]) / (volatilityK * shift); double bsD3sFK = (bsD2VP[0][1] - bsD2[0][1]) / (volatilityK * shift); double bsD3sFs = (bsD2VP[0][2] - bsD2[0][2]) / (volatilityK * shift); double bsD3sKK = (bsD2VP[1][1] - bsD2[1][1]) / (volatilityK * shift); double bsD3ssK = (bsD2VP[2][1] - bsD2[2][1]) / (volatilityK * shift); double[] vDKP = new double[6]; //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[][] vD2KP = new double[2][2]; double[][] vD2KP = RectangularArrays.ReturnRectangularDoubleArray(2, 2); sabrFunction.volatilityAdjoint2(forward, cutOffStrike * (1 + shift), timeToExpiry, sabrData, vDKP, vD2KP); double vD3KKF = (vD2KP[1][0] - vD2[1][0]) / (cutOffStrike * shift); pDF[2] = bsD3FKK + bsD3sFK * vD[1] + (bsD3sFK + bsD3sFs * vD[1]) * vD[1] + bsD2[2][0] * vD2[1][1] + (bsD3sKK + bsD3ssK * vD[1] + (bsD3ssK + bsD3sss * vD[1]) * vD[1] + bsD2[2][2] * vD2[1][1]) * vD[0] + 2 * (bsD2[1][2] + bsD2[2][2] * vD[1]) * vD2[1][0] + bsD[3] * vD3KKF; // Derivative of f with respect to abc. //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[][] fD = new double[3][3]; // fD[i][j]: derivative with respect to jth variable of f_i double[][] fD = RectangularArrays.ReturnRectangularDoubleArray(3, 3); // fD[i][j]: derivative with respect to jth variable of f_i double f = priceK[0]; double fp = priceK[1]; double fpp = priceK[2]; fD[0][0] = f; fD[0][1] = f / cutOffStrike; fD[0][2] = fD[0][1] / cutOffStrike; fD[1][0] = fp; fD[1][1] = (fp - fD[0][1]) / cutOffStrike; fD[1][2] = (fp - 2 * fD[0][1]) / (cutOffStrike * cutOffStrike); fD[2][0] = fpp; fD[2][1] = (fpp + fD[0][2] * (2 * (mu + 1) + 2 * parameter[1] / cutOffStrike + 4 * parameter[2] / (cutOffStrike * cutOffStrike))) / cutOffStrike; fD[2][2] = (fpp + fD[0][2] * (2 * (2 * mu + 3) + 4 * parameter[1] / cutOffStrike + 8 * parameter[2] / (cutOffStrike * cutOffStrike))) / (cutOffStrike * cutOffStrike); DecompositionResult decmp = SVD.apply(DoubleMatrix.ofUnsafe(fD)); return(decmp.solve(pDF)); }