/// <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));
        }
Ejemplo n.º 2
0
        /// <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);
        }
Ejemplo n.º 3
0
        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));
        }