示例#1
0
        /// <summary>
        /// Create a random symmetric sparse matrix.
        /// </summary>
        /// <param name="size">The size of the matrix.</param>
        /// <param name="density">The density (between 0.0 and 1.0).</param>
        /// <param name="definite">If true, the matrix will be positive semi-definite.</param>
        /// <param name="random">The random source.</param>
        /// <returns>Random sparse matrix.</returns>
        public static SparseMatrix RandomSymmetric(int size, double density, bool definite, Random random)
        {
            // Total number of non-zeros.
            int nz = (int)Math.Max(size * size * density, 1d);

            var C = new CoordinateStorage <double>(size, size, nz);

            int m = nz / 2;

            var norm = new double[size];

            for (int k = 0; k < m; k++)
            {
                int i = (int)Math.Min(random.NextDouble() * size, size - 1);
                int j = (int)Math.Min(random.NextDouble() * size, size - 1);

                if (i == j)
                {
                    // Skip diagonal.
                    continue;
                }

                // Fill only lower part.
                if (i < j)
                {
                    int temp = i;
                    i = j;
                    j = temp;
                }

                var value = random.NextDouble();

                norm[i] += Math.Abs(value);
                norm[j] += Math.Abs(value);

                C.At(i, j, value);
            }

            // Fill diagonal.
            for (int i = 0; i < size; i++)
            {
                double value = random.NextDouble();

                if (definite)
                {
                    // Make the matrix diagonally dominant.
                    value = (value + 1.0) * (norm[i] + 1.0);
                }

                C.At(i, i, value);
            }

            var A = SparseMatrix.OfIndexed(C);

            return((SparseMatrix)A.Add(A.Transpose()));
        }
示例#2
0
        /// <summary>
        /// Get the 1D Laplacian matrix (with Dirichlet boundary conditions).
        /// </summary>
        /// <param name="nx">Grid size.</param>
        /// <param name="eigenvalues">Vector to store eigenvalues (optional).</param>
        /// <returns>Laplacian sparse matrix.</returns>
        public static CompressedColumnStorage <double> Laplacian(int nx, double[] eigenvalues = null)
        {
            if (nx == 1)
            {
                // Handle special case n = 1.
                var A = new CoordinateStorage <double>(nx, nx, 1);

                A.At(0, 0, 2.0);

                return(SparseMatrix.OfIndexed(A));
            }

            var C = new CoordinateStorage <double>(nx, nx, 3 * nx);

            for (int i = 0; i < nx; i++)
            {
                C.At(i, i, 2.0);

                if (i == 0)
                {
                    C.At(i, i + 1, -1.0);
                }
                else if (i == (nx - 1))
                {
                    C.At(i, i - 1, -1.0);
                }
                else
                {
                    C.At(i, i - 1, -1.0);
                    C.At(i, i + 1, -1.0);
                }
            }

            if (eigenvalues != null)
            {
                // Compute eigenvalues.
                int count = Math.Min(nx, eigenvalues.Length);

                var eigs = new double[nx];

                for (int i = 0; i < count; i++)
                {
                    eigs[i] = 4 * Math.Pow(Math.Sin((i + 1) * Math.PI / (2 * (nx + 1))), 2);
                }

                Array.Sort(eigs);

                for (int i = 0; i < count; ++i)
                {
                    eigenvalues[i] = eigs[i];
                }
            }

            return(SparseMatrix.OfIndexed(C));
        }
示例#3
0
        /// <summary>
        /// Create a random sparse matrix.
        /// </summary>
        /// <param name="rows">The number of rows.</param>
        /// <param name="columns">The number of columns.</param>
        /// <param name="density">The density (between 0.0 and 1.0).</param>
        /// <param name="random">The random source.</param>
        /// <returns>Random sparse matrix.</returns>
        public static SparseMatrix Random(int rows, int columns, double density, Random random)
        {
            // Number of non-zeros per row.
            int nz = (int)Math.Max(columns * density, 1d);

            var C = new CoordinateStorage <double>(rows, columns, rows * nz);

            for (int i = 0; i < rows; i++)
            {
                // Ensure non-zero diagonal.
                C.At(i, i, random.NextDouble() - 0.5);

                for (int j = 0; j < nz; j++)
                {
                    int k = Math.Min(columns - 1, (int)(random.NextDouble() * columns));

                    C.At(i, k, random.NextDouble());
                }
            }

            return(SparseMatrix.OfIndexed(C) as SparseMatrix);
        }