예제 #1
0
        /// <summary>
        /// Assume a tensor has been flattened to a vector as {A_{0,0}, A_{0,1},...._A_{0,m}, A_{1,0}, A_{1,1},...._A_{1,m},...,A_{n,0}, A_{n,1},...._A_{n,m}}
        /// (see <seealso cref="#flattenMatrix"/>) that is, the <b>last</b> index changes most rapidly.  This produces the sum of penalty matrices (or order given by k) with each scaled
        /// by lambda. </summary>
        /// <param name="numElements"> The range of each index. In the example above, this would be {n,m} </param>
        /// <param name="k"> The difference order for each dimension </param>
        /// <param name="lambda"> The scaling for each dimension </param>
        /// <returns>  A penalty matrix  </returns>
        public static DoubleMatrix getPenaltyMatrix(int[] numElements, int[] k, double[] lambda)
        {
            ArgChecker.notEmpty(numElements, "size");
            ArgChecker.notEmpty(k, "k");
            ArgChecker.notEmpty(lambda, "lambda");
            int dim = numElements.Length;

            ArgChecker.isTrue(dim == k.Length, "k different length to size");
            ArgChecker.isTrue(dim == lambda.Length, "lambda different lenght to size");

            DoubleMatrix p = (DoubleMatrix)MA.scale(getPenaltyMatrix(numElements, k[0], 0), lambda[0]);

            for (int i = 1; i < dim; i++)
            {
                DoubleMatrix temp = (DoubleMatrix)MA.scale(getPenaltyMatrix(numElements, k[i], i), lambda[i]);
                p = (DoubleMatrix)MA.add(p, temp);
            }
            return(p);
        }
        // jacobian indirect, merging groups
        private static DoubleMatrix jacobianIndirect(DoubleMatrix res, DoubleMatrix pDmCurrentMatrix, int nbTrades, int totalParamsGroup, int totalParamsPrevious, ImmutableList <CurveParameterSize> orderPrevious, ImmutableMap <CurveName, JacobianCalibrationMatrix> jacobiansPrevious)
        {
            if (totalParamsPrevious == 0)
            {
                return(DoubleMatrix.EMPTY);
            }
//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[][] nonDirect = new double[totalParamsGroup][totalParamsPrevious];
            double[][] nonDirect = RectangularArrays.ReturnRectangularDoubleArray(totalParamsGroup, totalParamsPrevious);
            for (int i = 0; i < nbTrades; i++)
            {
                Array.Copy(res.rowArray(i), 0, nonDirect[i], 0, totalParamsPrevious);
            }
            DoubleMatrix pDpPreviousMatrix = (DoubleMatrix)MATRIX_ALGEBRA.scale(MATRIX_ALGEBRA.multiply(pDmCurrentMatrix, DoubleMatrix.copyOf(nonDirect)), -1d);

            // all curves: order and size
            int[] startIndexBefore = new int[orderPrevious.size()];
            for (int i = 1; i < orderPrevious.size(); i++)
            {
                startIndexBefore[i] = startIndexBefore[i - 1] + orderPrevious.get(i - 1).ParameterCount;
            }
            // transition Matrix: all curves from previous groups
//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[][] transition = new double[totalParamsPrevious][totalParamsPrevious];
            double[][] transition = RectangularArrays.ReturnRectangularDoubleArray(totalParamsPrevious, totalParamsPrevious);
            for (int i = 0; i < orderPrevious.size(); i++)
            {
                int paramCountOuter = orderPrevious.get(i).ParameterCount;
                JacobianCalibrationMatrix thisInfo = jacobiansPrevious.get(orderPrevious.get(i).Name);
                DoubleMatrix thisMatrix            = thisInfo.JacobianMatrix;
                int          startIndexInner       = 0;
                for (int j = 0; j < orderPrevious.size(); j++)
                {
                    int paramCountInner = orderPrevious.get(j).ParameterCount;
                    if (thisInfo.containsCurve(orderPrevious.get(j).Name))
                    {     // If not, the matrix stay with 0
                        for (int k = 0; k < paramCountOuter; k++)
                        {
                            Array.Copy(thisMatrix.rowArray(k), startIndexInner, transition[startIndexBefore[i] + k], startIndexBefore[j], paramCountInner);
                        }
                    }
                    startIndexInner += paramCountInner;
                }
            }
            DoubleMatrix transitionMatrix = DoubleMatrix.copyOf(transition);

            return((DoubleMatrix)MATRIX_ALGEBRA.multiply(pDpPreviousMatrix, transitionMatrix));
        }
        public virtual void linearTest()
        {
            bool print = false;

            if (print)
            {
                Console.WriteLine("NonLinearLeastSquareWithPenaltyTest.linearTest");
            }
            int          nWeights  = 20;
            int          diffOrder = 2;
            double       lambda    = 100.0;
            DoubleMatrix penalty   = (DoubleMatrix)MA.scale(getPenaltyMatrix(nWeights, diffOrder), lambda);

            int[]    onIndex = new int[] { 1, 4, 11, 12, 15, 17 };
            double[] obs     = new double[] { 0, 1.0, 1.0, 1.0, 0.0, 0.0 };
            int      n       = onIndex.Length;

            System.Func <DoubleArray, DoubleArray> func = (DoubleArray x) =>
            {
                return(DoubleArray.of(n, i => x.get(onIndex[i])));
            };

            System.Func <DoubleArray, DoubleMatrix> jac = (DoubleArray x) =>
            {
                return(DoubleMatrix.of(n, nWeights, (i, j) => j == onIndex[i] ? 1d : 0d));
            };

            Well44497b  random = new Well44497b(0L);
            DoubleArray start  = DoubleArray.of(nWeights, i => random.NextDouble());

            LeastSquareWithPenaltyResults lsRes = NLLSWP.solve(DoubleArray.copyOf(obs), DoubleArray.filled(n, 0.01), func, jac, start, penalty);

            if (print)
            {
                Console.WriteLine("chi2: " + lsRes.ChiSq);
                Console.WriteLine(lsRes.FitParameters);
            }
            for (int i = 0; i < n; i++)
            {
                assertEquals(obs[i], lsRes.FitParameters.get(onIndex[i]), 0.01);
            }
            double expPen = 20.87912357454752;

            assertEquals(expPen, lsRes.Penalty, 1e-9);
        }
        private DoubleArray[] fdSenseCal(double[] xValues, double[] yValues, double[] xx)
        {
            int    nData = yValues.Length;
            double eps   = 1e-6;
            double scale = 0.5 / eps;

            DoubleArray[]             res  = new DoubleArray[nData];
            double[]                  temp = new double[nData];
            PiecewisePolynomialResult pp;

            for (int i = 0; i < nData; i++)
            {
                Array.Copy(yValues, 0, temp, 0, nData);
                temp[i] += eps;
                pp       = PCHIP.interpolate(xValues, temp);
                DoubleArray yUp = PPVAL.evaluate(pp, xx).row(0);
                temp[i] -= 2 * eps;
                pp       = PCHIP.interpolate(xValues, temp);
                DoubleArray yDown = PPVAL.evaluate(pp, xx).row(0);
                res[i] = (DoubleArray)MA.scale(MA.subtract(yUp, yDown), scale);
            }
            return(res);
        }
예제 #5
0
        private GeneralizedLeastSquareResults <T> solveImp <T>(IList <T> x, IList <double> y, IList <double> sigma, IList <System.Func <T, double> > basisFunctions, double lambda, int differenceOrder)
        {
            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 greater 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);

            if (lambda > 0.0)
            {
                DoubleMatrix d = getDiffMatrix(m, differenceOrder);
                ma = (DoubleMatrix)_algebra.add(ma, _algebra.scale(d, lambda));
            }

            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));
        }