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