Пример #1
0
        public static double Det(MatrixExpression a)
        {
            var m = a.Evaluate();

            if (a is MatrixInput)
            {
                m = Copy(m);
            }
            var ipiv = Pool.Int.Rent(m.Rows);

            ThrowHelper.Check(Lapack.getrf(Layout.ColMajor, m.Rows, m.Rows, m.Array, m.Rows, ipiv));
            Pool.Int.Return(ipiv);
            double r = m[0, 0];

            for (int i = 1; i < m.Rows; i++)
            {
                r *= m[i, i];
            }
            m.Dispose();
            return(-r);
        }
Пример #2
0
        private static void Main()
        {
            CompareTimeDot(10);
            CompareTimeDot(100);
            CompareTimeDot(100000);

            CompareTimeLU();

            void CompareTimeDot(int size)
            {
                var sw = new Stopwatch();

                (var x, var y) = GenerateVector();
                WriteLine($"Calc dot product by raw C# : size = {size}");
                sw.Reset();
                var res = 0.0;

                for (var i = 0; i < LoopDot; i++)
                {
                    sw.Start();
                    res = Dot(x, y);
                    sw.Stop();
                }
                WriteLine($"Result : {res}\tTime : {sw.Elapsed / (double) LoopDot}");

                WriteLine($"Calc dot product by BLAS : size = {size}");
                sw.Reset();
                for (var i = 0; i < LoopDot; i++)
                {
                    sw.Start();
                    res = Blas1.dot(size, x, 1, y, 1);
                    sw.Stop();
                }
                WriteLine($"Result : {res}\tTime : {sw.Elapsed / (double) LoopDot}\n");

                (double[] x, double[] y) GenerateVector()
                {
                    x = new double[size];
                    y = new double[size];
                    for (var i = 0; i < size; i++)
                    {
                        x[i] = 1.0;
                        y[i] = 1.0;
                    }
                    return(x, y);
                }
            }

            void CompareTimeLU()
            {
                const int    M     = 49;
                const int    N     = M * M;
                const double h     = 1.0 / (M + 1);
                const double Heat  = 4.0;
                var          aBase = new double[N * N];
                var          bBase = new double[N];
                var          ipiv  = new int[N];

                for (var i = 1; i <= M; i++)
                {
                    for (var j = 1; j <= M; j++)
                    {
                        var k = (j - 1) * M + i - 1;
                        aBase[k * N + k] = 4.0 / (h * h);
                        if (i > 1)
                        {
                            var kl = k - 1;
                            aBase[kl * N + k] = -1.0 / (h * h);
                        }
                        if (i < M)
                        {
                            var kr = k + 1;
                            aBase[kr * N + k] = -1.0 / (h * h);
                        }
                        if (j > 1)
                        {
                            var kd = k - M;
                            aBase[kd * N + k] = -1.0 / (h * h);
                        }
                        if (j < M)
                        {
                            var ku = k + M;
                            aBase[ku * N + k] = -1.0 / (h * h);
                        }
                        bBase[k] = Heat;
                    }
                }

                var sw = new Stopwatch();

                WriteLine("Calc Poisson eq by raw C#");
                sw.Reset();
                var res = new double[bBase.Length];

                for (var i = 0; i < LoopLU; i++)
                {
                    Blas1.copy(aBase.Length, aBase, 1, out var a, 1);
                    Blas1.copy(bBase.Length, bBase, 1, out var b, 1);
                    sw.Start();
                    Decomp(N, N, a, ipiv);
                    Solve(N, N, a, b, ipiv);
                    sw.Stop();
                    if (i == LoopLU - 1)
                    {
                        Blas1.copy(b.Length, b, 1, res, 1);
                    }
                }
                WriteLine($"Result : {res[((M + 1) / 2 - 1) * M + M + 1]}\tTime : {sw.Elapsed / (double) LoopLU}");

                WriteLine("Calc Poisson eq by LAPACK");
                sw.Reset();
                for (var i = 0; i < LoopLU; i++)
                {
                    Blas1.copy(aBase.Length, aBase, 1, out var a, 1);
                    Blas1.copy(bBase.Length, bBase, 1, out var b, 1);
                    sw.Start();
                    Lapack.getrf(LapackLayout.RowMajor, N, N, a, N, ipiv);
                    Lapack.getrs(LapackLayout.RowMajor, LapackTranspose.NoTrans, N, 1, a, N, ipiv, b, 1);
                    sw.Stop();
                    if (i == LoopLU - 1)
                    {
                        Blas1.copy(b.Length, b, 1, res, 1);
                    }
                }
                WriteLine($"Result : {res[((M + 1) / 2 - 1) * M + M + 1]}\tTime : {sw.Elapsed / (double) LoopLU}");
            }
        }