Ejemplo n.º 1
0
        /// <summary>Gets informations of the current object as a specific <see cref="InfoOutput" /> instance.
        /// </summary>
        /// <param name="infoOutput">The <see cref="InfoOutput" /> object which is to be filled with informations concering the current instance.</param>
        /// <param name="categoryName">The name of the category, i.e. all informations will be added to these category.</param>
        public void FillInfoOutput(InfoOutput infoOutput, string categoryName = InfoOutput.GeneralCategoryName)
        {
            var infoOutputPackage = infoOutput.AcquirePackage(categoryName);

            infoOutputPackage.Add("Distribution", "Empirical");
            infoOutputPackage.Add("Sample Size", SampleSize);
            infoOutputPackage.Add("Mean", Mean);

            infoOutputPackage.Add("Minimum", Minimum);
            infoOutputPackage.Add("Maximum", Maximum);
            infoOutputPackage.Add("Media", Median);

            if (InfoOutputDetailLevel.IsAtLeastAsComprehensiveAs(InfoOutputDetailLevel.High) == true)
            {
                var sampleDataTable = new DataTable("Sample");
                sampleDataTable.Columns.Add("Value", typeof(double));
                foreach (var value in Sample)
                {
                    var row = sampleDataTable.NewRow();
                    row[0] = value;
                    sampleDataTable.Rows.Add(row);
                }
                infoOutputPackage.Add(sampleDataTable);
            }
            m_MomentCalculator.Value.FillInfoOutput(infoOutput, categoryName + ".Moments");
            m_DensityEstimator.FillInfoOutput(infoOutput, categoryName + ".Density");
        }
Ejemplo n.º 2
0
        /// <summary>Creates a 'n x r' matrix B such that B * B' is a correlation matrix and 'near' to the specified symmetric, normalized matrix of dimension n. A rank reduction will apply if r is strict less than n.
        /// </summary>
        /// <param name="rawCorrelationMatrix">The symmetric, normalized matrix where to find the 'nearest' correlation matrix.</param>
        /// <param name="state">The state of the operation in its <see cref="PseudoSqrtMatrixDecomposer.State"/> representation (output).</param>
        /// <param name="triangularMatrixType">A value indicating which part of <paramref name="rawCorrelationMatrix"/> to take into account.</param>
        /// <param name="outputEntries">This argument will be used to store the matrix entries of the resulting matrix B, i.e. the return value array points to this array if != <c>null</c>; otherwise a memory allocation will be done.</param>
        /// <param name="worksspaceContainer">A specific <see cref="PseudoSqrtMatrixDecomposer.WorkspaceContainer"/> object to reduce memory allocation; ignored if <c>null</c>.</param>
        /// <returns>A <see cref="DenseMatrix"/> object that represents a matrix B such that B * B' is the 'nearest' correlation matrix with respect to <paramref name="rawCorrelationMatrix"/>.</returns>
        /// <remarks>In general the return object does <b>not</b> represents the pseudo-root of <paramref name="rawCorrelationMatrix"/>, i.e. output of the Cholesky decomposition.
        /// <para>The parameters <paramref name="outputEntries"/>, <paramref name="worksspaceContainer"/> allows to avoid memory allocation and to re-use arrays if the calculation of correlation matrices will be done often.</para></remarks>
        public override DenseMatrix Create(DenseMatrix rawCorrelationMatrix, out State state, double[] outputEntries = null, PseudoSqrtMatrixDecomposer.WorkspaceContainer worksspaceContainer = null, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.LowerTriangularMatrix)
        {
            if (rawCorrelationMatrix.IsQuadratic == false)
            {
                throw new ArgumentException("rawCorrelationMatrix");
            }
            int n = rawCorrelationMatrix.RowCount;

            if ((outputEntries == null) || (outputEntries.Length < n * n))
            {
                outputEntries = new double[n * n];
            }
            var ws = worksspaceContainer as Workspace;

            if ((ws == null) || (ws.Dimension < n))
            {
                ws = new Workspace(n);
            }

            int m;

            BLAS.Level1.dcopy(n * n, rawCorrelationMatrix.Data, ws.data);
            LAPACK.EigenValues.Symmetric.driver_dsyevr(LapackEigenvalues.SymmetricGeneralJob.All, n, ws.data, out m, ws.eigenValues, outputEntries, ws.isuppz, ws.work, ws.iwork);
            var originalEigenValueDataTable = InfoOutputDetailLevel.IsAtLeastAsComprehensiveAs(InfoOutputDetailLevel.High) ? CreateDataTableWithEigenvalues("Eigenvalues.Original", m, ws.eigenValues) : null;

            int rank = n;
            int minNumberOfEigenvaluesToSetZero = n - Math.Min(MaximalRank ?? n, n);
            int i = 0;

            while ((i < minNumberOfEigenvaluesToSetZero) || (ws.eigenValues[i] < 0.0))
            {
                ws.eigenValues[i] = 0.0;
                i++;
                rank--;
            }
            var adjustedEigenValueDataTable = InfoOutputDetailLevel.IsAtLeastAsComprehensiveAs(InfoOutputDetailLevel.High) ? CreateDataTableWithEigenvalues("Eigenvalues.Adjusted", m, ws.eigenValues) : null;

            VectorUnit.Basics.Sqrt(n, ws.eigenValues); // calculate sqrt of eigenvalues only once, i.e. the array 'eigenValues' contains the sqrt of the eigenvalues!
            for (i = 0; i < n; i++)
            {
                var t_i = 0.0;
                for (int j = n - 1; j >= n - rank; j--)
                {
                    t_i += outputEntries[i + j * n] * outputEntries[i + j * n] * ws.eigenValues[j] * ws.eigenValues[j];
                    outputEntries[i + j * n] *= ws.eigenValues[j];
                }
                BLAS.Level1.dscal(rank, 1.0 / Math.Sqrt(t_i), outputEntries, -n, i + (n - 1) * n); // [i+j*n] *= 1/Math.Sqrt(tempValue) for j = n-1, ..., n-rank
            }

            /* The eigenvalues are in ascending order. Thefore the first (and not last) 'rank' columns of the eigenvectors are not required. Therefore we swap the relevant part  */
            BLAS.Level1.dscal(n * (n - rank), 0.0, outputEntries);
            BLAS.Level1.dswap(n * rank, outputEntries, 1, outputEntries, 1, n * (n - rank), 0);

            state = State.Create(rank, detailProperties: new[] { InfoOutputProperty.Create("Eigenvalues set to 0.0", n - rank) }, detailDataTables: new[] { originalEigenValueDataTable, adjustedEigenValueDataTable }, iterationsNeeded: 1, infoOutputDetailLevel: InfoOutputDetailLevel);
            return(new DenseMatrix(n, rank, outputEntries));
        }
Ejemplo n.º 3
0
        /// <summary>Creates a 'n x r' matrix B such that B * B' is a correlation matrix and 'near' to the specified symmetric, normalized matrix of dimension n. A rank reduction will apply if r is strict less than n.
        /// </summary>
        /// <param name="rawCorrelationMatrix">The symmetric, normalized matrix where to find the 'nearest' correlation matrix.</param>
        /// <param name="state">The state of the operation in its <see cref="PseudoSqrtMatrixDecomposer.State"/> representation (output).</param>
        /// <param name="triangularMatrixType">A value indicating which part of <paramref name="rawCorrelationMatrix"/> to take into account.</param>
        /// <param name="outputEntries">This argument will be used to store the matrix entries of the resulting matrix B, i.e. the return value array points to this array if != <c>null</c>; otherwise a memory allocation will be done.</param>
        /// <param name="worksspaceContainer">A specific <see cref="PseudoSqrtMatrixDecomposer.WorkspaceContainer"/> object to reduce memory allocation; ignored if <c>null</c>.</param>
        /// <returns>A <see cref="DenseMatrix"/> object that represents a matrix B such that B * B' is the 'nearest' correlation matrix with respect to <paramref name="rawCorrelationMatrix"/>.</returns>
        /// <remarks>In general the return object does <b>not</b> represents the pseudo-root of <paramref name="rawCorrelationMatrix"/>, i.e. output of the Cholesky decomposition.
        /// <para>The parameters <paramref name="outputEntries"/>, <paramref name="worksspaceContainer"/> allows to avoid memory allocation and to re-use arrays if the calculation of correlation matrices will be done often.</para></remarks>
        public override DenseMatrix Create(DenseMatrix rawCorrelationMatrix, out State state, double[] outputEntries = null, PseudoSqrtMatrixDecomposer.WorkspaceContainer worksspaceContainer = null, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.LowerTriangularMatrix)
        {
            if (rawCorrelationMatrix.IsQuadratic == false)
            {
                throw new ArgumentException("rawCorrelationMatrix");
            }
            int n = rawCorrelationMatrix.RowCount;

            var ws = worksspaceContainer as Workspace;

            if ((ws == null) || (ws.Dimension < n))
            {
                ws = new Workspace(n, this);
            }

            /* calculate an initial value for the optimizer:
             *   (i) Apply the EZN algorithm for the calculation of a matrix B_0 such that B_0 * B_0^t is near to the (raw) correlation matrix
             *   (ii) calculate angle parameters \theta such that B_0 = B(\theta).
             *  */
            State initState;
            var   initialAngleParameterMatrix = GetAngleParameter(m_InitialDecomposer.Create(rawCorrelationMatrix, out initState, outputEntries, ws.InitalDecomposerWorkspace, triangularMatrixType), ws.ArgMinData);

            /* prepare and apply optimization algorithm: */
            int rank = initState.Rank;

            if ((outputEntries == null) || (outputEntries.Length < n * n))
            {
                outputEntries = new double[n * rank];
            }

            var B            = new DenseMatrix(n, rank, outputEntries, createDeepCopyOfArgument: false);
            var C            = new DenseMatrix(n, n, ws.CorrelationMatrixData, createDeepCopyOfArgument: false);
            var optAlgorithm = m_MultiDimOptimizer.Create(n * (rank - 1));

            optAlgorithm.SetFunction(theta =>
            {
                GetParametricMatrix(theta, B);
                C.AddAssignment(B, B.T, beta: 0.0); // C = B * B^t

                VectorUnit.Basics.Sub(n * n, C.Data, rawCorrelationMatrix.Data, ws.TempDifferences);
                return(BLAS.Level1.dnrm2sq(n * n, ws.TempDifferences));
            });
            double minimum;
            var    optState = optAlgorithm.FindMinimum(ws.ArgMinData, out minimum);

            state = State.Create(rank, optState.IterationsNeeded, InfoOutputDetailLevel,
                                 Tuple.Create <string, IInfoOutputQueriable>("Initial.State", initState),
                                 Tuple.Create <string, IInfoOutputQueriable>("Final.Optimizer", optState),
                                 Tuple.Create <string, IInfoOutputQueriable>("Initial.Parameters", initialAngleParameterMatrix),
                                 InfoOutputDetailLevel.IsAtLeastAsComprehensiveAs(InfoOutputDetailLevel.High) ? Tuple.Create <string, IInfoOutputQueriable>("Final.Parameters", new DenseMatrix(n, rank, ws.ArgMinData, createDeepCopyOfArgument: false)) : null
                                 );

            GetParametricMatrix(ws.ArgMinData, B); // B should be already set to B(\theta^*), we just want to be sure that B is correct on exit
            return(B);
        }
Ejemplo n.º 4
0
        /// <summary>Creates a 'n x r' matrix B such that B * B' is a correlation matrix and 'near' to the specified symmetric, normalized matrix of dimension n. A rank reduction will apply if r is strict less than n.
        /// </summary>
        /// <param name="rawCorrelationMatrix">The symmetric, normalized matrix where to find the 'nearest' correlation matrix.</param>
        /// <param name="state">The state of the operation in its <see cref="PseudoSqrtMatrixDecomposer.State"/> representation (output).</param>
        /// <param name="triangularMatrixType">A value indicating which part of <paramref name="rawCorrelationMatrix"/> to take into account.</param>
        /// <param name="outputEntries">This argument will be used to store the matrix entries of the resulting matrix B, i.e. the return value array points to this array if != <c>null</c>; otherwise a memory allocation will be done.</param>
        /// <param name="worksspaceContainer">A specific <see cref="PseudoSqrtMatrixDecomposer.WorkspaceContainer"/> object to reduce memory allocation; ignored if <c>null</c>.</param>
        /// <returns>A <see cref="DenseMatrix"/> object that represents a matrix B such that B * B' is the 'nearest' correlation matrix with respect to <paramref name="rawCorrelationMatrix"/>.</returns>
        /// <remarks>In general the return object does <b>not</b> represents the pseudo-root of <paramref name="rawCorrelationMatrix"/>, i.e. output of the Cholesky decomposition.
        /// <para>The parameters <paramref name="outputEntries"/>, <paramref name="worksspaceContainer"/> allows to avoid memory allocation and to re-use arrays if the calculation of correlation matrices will be done often.</para></remarks>
        public override DenseMatrix Create(DenseMatrix rawCorrelationMatrix, out State state, double[] outputEntries = null, WorkspaceContainer worksspaceContainer = null, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.LowerTriangularMatrix)
        {
            if (rawCorrelationMatrix.IsQuadratic == false)
            {
                throw new ArgumentException("rawCorrelationMatrix");
            }
            int n = rawCorrelationMatrix.RowCount;

            if ((outputEntries == null) || (outputEntries.Length < n * n))
            {
                outputEntries = new double[n * n];
            }
            var ws = worksspaceContainer as Workspace;

            if ((ws == null) || (ws.Dimension < n))
            {
                ws = new Workspace(n);
            }

            /* calculate an initial value for the EZI approach, i.e. apply the Eigenvalue zeroing (without normalization): */
            int initialRank;

            BLAS.Level1.dcopy(n * n, rawCorrelationMatrix.Data, ws.p);
            f1(n, ws.p, 0, ws, outputEntries, out initialRank);

            var detailDataTables = new List <DataTable>();

            if (InfoOutputDetailLevel.IsAtLeastAsComprehensiveAs(InfoOutputDetailLevel.High))
            {
                detailDataTables.Add(CreateDataTableWithEigenvalues("Eigenvalues.Adjusted[0]", initialRank, ws.eigenValues));
            }

            BLAS.Level3.dgemm(n, n, n, 1.0, outputEntries, outputEntries, 0.0, ws.p, transposeB: BLAS.MatrixTransposeState.Transpose);

            BLAS.Level1.dcopy(n * n, ws.p, ws.q);
            int minNumberOfEigenvaluesToSetZero = n - Math.Min(MaximalRank ?? n, initialRank);

            var a    = 1.0;
            int rank = initialRank;

            for (int k = 1; k < AbortCondition.MaxIterations; k++)
            {
                f1(n, ws.q, minNumberOfEigenvaluesToSetZero, ws, outputEntries, out rank);
                if (InfoOutputDetailLevel.IsAtLeastAsComprehensiveAs(InfoOutputDetailLevel.Full))
                {
                    detailDataTables.Add(CreateDataTableWithEigenvalues(String.Format("Eigenvalues.Adjusted[{0}", k), rank, ws.eigenValues));
                }

                BLAS.Level3.dgemm(n, n, n, 1.0, outputEntries, outputEntries, 0.0, ws.q, transposeB: BLAS.MatrixTransposeState.Transpose);

                /* normalize the correlation matrix, i.e. calculate <q> */
                for (int i = 0; i < n; i++)
                {
                    var t_i = 0.0;
                    for (int j = n - 1; j >= n - rank; j--)
                    {
                        t_i += outputEntries[i + j * n] * outputEntries[i + j * n];
                    }
                    BLAS.Level1.dscal(rank, 1.0 / Math.Sqrt(t_i), outputEntries, -n, i + (n - 1) * n); // [i+j*n] *= 1/Math.Sqrt(t_i) for j = n-1, ..., n-rank
                }
                BLAS.Level3.dgemm(n, n, n, 1.0, outputEntries, outputEntries, 0.0, ws.qNormalized, transposeB: BLAS.MatrixTransposeState.Transpose);

                if (AbortCondition.IsSatisfied(n, ws.p, ws.q, ws.qNormalized, ref a) == true)
                {
                    /* The eigenvalues are in ascending order. Thefore the first (and not last) 'rank' columns of the eigenvectors are not required. Therefore we swap the relevant part: */
                    BLAS.Level1.dswap(n * rank, outputEntries, 1, outputEntries, 1, n * (n - rank), 0);
                    state = State.Create(rank, new InfoOutputProperty[] { InfoOutputProperty.Create("Eigenvalues set to 0.0", n - rank) }, detailDataTables, iterationsNeeded: k, infoOutputDetailLevel: InfoOutputDetailLevel);
                    return(new DenseMatrix(n, rank, outputEntries));
                }

                BLAS.Level1.dcopy(n * n, ws.q, ws.p); // set p := q
                for (int j = 0; j < n; j++)
                {
                    ws.q[j * n + j] = 1.0;
                }
            }

            /* The eigenvalues are in ascending order. Thefore the first (and not last) 'rank' columns of the eigenvectors are not required. Therefore we swap the relevant part: */
            BLAS.Level1.dswap(n * rank, outputEntries, 1, outputEntries, 1, n * (n - rank), 0);

            state = State.Create(rank, new InfoOutputProperty[] { InfoOutputProperty.Create("Number of EigenValues set to 0.0", n - rank) }, detailDataTables, AbortCondition.MaxIterations, infoOutputDetailLevel: InfoOutputDetailLevel);
            return(new DenseMatrix(n, rank, outputEntries));
        }