public void SolveGETest()
        {
            const int N = 50;
            var       a = new SparseDoubleMatrix(N, N);

            for (int i = 0; i < N; i++)
            {
                a[i, i] = 1;
            }
            // Apply random rotations around each pair of axes. This will keep det(A) ~ 1
            var rand = new Random();

            for (int i = 0; i < N; i++)
            {
                for (int j = i + 1; j < N; j++)
                {
                    double angle = rand.NextDouble() * 2 * Math.PI;
                    var    r     = new SparseDoubleMatrix(N, N);
                    for (int k = 0; k < N; k++)
                    {
                        r[k, k] = 1;
                    }
                    r[i, i] = r[j, j] = Math.Cos(angle);
                    r[i, j] = Math.Sin(angle);
                    r[j, i] = -Math.Sin(angle);
                    a       = a * r;
                }
            }

            var ainit = a.Clone();
            // Generate random vector
            var b = new DoubleVector(N);

            for (int i = 0; i < N; i++)
            {
                b[i] = rand.NextDouble();
            }

            var binit = b.Clone();
            // Solve system
            var solver = new GaussianEliminationSolver();
            var sw     = new Stopwatch();

            sw.Start();
            var x = solver.SolveDestructive(a, b.GetInternalData());

            sw.Stop();
            Trace.WriteLine("Gaussian elimination took: " + sw.ElapsedTicks);
            // Put solution into system
            var b2 = ainit * x;

            // Verify result is the same
            Assert.IsTrue(VectorMath.LInfinityNorm(binit, b2) < 1e-6);
        }
        public void TextBanded01()
        {
            var rnd = new Random(642332);

            for (int testRuns = 0; testRuns < 1000; ++testRuns)
            {
                for (int N = 11; N <= 13; ++N)                                                        // for even and odd matrix dimensions
                {
                    for (int lowerBandwidth = 0; lowerBandwidth <= (N + 1) / 2; ++lowerBandwidth)     // for all lower bandwidths
                    {
                        for (int upperBandwidth = 0; upperBandwidth <= (N + 1) / 2; ++upperBandwidth) // for all upper bandwidths
                        {
                            var A = new DoubleMatrix(N, N);

                            for (int i = 0; i < N; ++i)
                            {
                                int start = Math.Max(0, i - lowerBandwidth);
                                int end   = Math.Min(N, i + upperBandwidth + 1);

                                for (int j = start; j < end; ++j)
                                {
                                    A[i, j] = rnd.Next(1, 99);
                                }
                            }
                            var x = new DoubleVector(N);

                            for (int i = 0; i < N; ++i)
                            {
                                x[i] = rnd.Next(-99, 99);
                            }

                            var b = A * x;

                            // now do gaussian elimination

                            var solver = new GaussianEliminationSolver();

                            var xr = new double[N];

                            solver.SolveDestructiveBanded(A, lowerBandwidth, upperBandwidth, b.GetInternalData(), xr);

                            // compare result
                            for (int i = 0; i < N; ++i)
                            {
                                Assert.AreEqual(x[i], xr[i], 1E-6);
                            }
                        }
                    }
                }
            }
        }