예제 #1
0
        public void DotTest()
        {
            var xf = new[] { 1.0f, 1.0f, 1.0f };
            var yf = new[] { 1.0f, 1.0f, 1.0f };
            var xd = new[] { 1.0, 1.0, 1.0 };
            var yd = new[] { 1.0, 1.0, 1.0 };

            Assert.AreEqual(3.0f, Blas1.dot(3, xf, 1, yf, 1));
            Assert.AreEqual(3.0, Blas1.dot(3, xd, 1, yd, 1));
        }
예제 #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}");
            }
        }