/// <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 SparseMatrix Laplacian(int nx, DenseVector eigenvalues = null)
        {
            if (nx == 1)
            {
                // Handle special case n = 1.
                var A = new SparseMatrix(nx, nx);

                A.At(0, 0, 2.0);

                return(A);
            }

            var C = new CoordinateStorage <Complex>(nx, 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.Count);

                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.At(i, eigs[i]);
                }
            }

            return((SparseMatrix)C.ToSparseMatrix());
        }
        /// <summary>
        /// Get the 2D Laplacian matrix (with Dirichlet boundary conditions).
        /// </summary>
        /// <param name="nx">Number of elements in x direction.</param>
        /// <param name="ny">Number of elements in y direction.</param>
        /// <param name="eigenvalues">Vector to store eigenvalues (optional).</param>
        /// <returns>Laplacian sparse matrix.</returns>
        public static SparseMatrix Laplacian(int nx, int ny, DenseVector eigenvalues = null)
        {
            var Ix = Eye(nx);
            var Iy = Eye(ny);

            var Dx = Laplacian(nx);
            var Dy = Laplacian(ny);

            if (eigenvalues != null)
            {
                // Compute eigenvalues.
                int count = Math.Min(nx * ny, eigenvalues.Count);
                int index = 0;

                var eigs = new double[nx * ny];

                double ax, ay;

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

                Array.Sort(eigs);

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

            return((SparseMatrix)(Kron(Iy, Dx).FastAdd(Kron(Dy, Ix))));
        }