Exemplo n.º 1
0
        public static (double[], double[], double[]) Solve(int N)
        {
            double h = 1.0 / N;

            double X(double i) => i * h;

            double[] f, c, a, b, y1, y2, y3;
            Progonka prg;

            //###################################################################################################################

            f    = new double[N + 1];
            f[0] = 1 + 5.0 / 4 * h;
            f[N] = h / 2 * (Sin(1) - 2 * Cos(1));
            for (int i = 1; i <= N - 1; i++)
            {
                f[i] = Sin(X(i)) - 2 * Cos(X(i));
            }

            c    = new double[N + 1];
            c[0] = 2.0 / h + 1 + h / 4;
            c[N] = -1.0 / h - Tan(1) - h / 2 * (1 - Tan(1));
            for (int i = 1; i <= N - 1; i++)
            {
                c[i] = -2 * (2 - X(i)) / h / h - X(i);
            }

            a        = new double[N];
            a[N - 1] = -1.0 / h;
            for (int i = 1; i <= N - 1; i++)
            {
                a[i - 1] = -(2 - X(i)) / h / h - 1.0 / 2 / h;
            }

            b    = new double[N];
            b[0] = 2.0 / h;
            for (int i = 1; i <= N - 1; i++)
            {
                b[i] = -(2 - X(i)) / h / h + 1.0 / 2 / h;
            }

            prg = new Progonka(a, c, b, f);
            prg.PerformProgonka();
            y1 = (double[])prg.y.Clone();
            //foreach (var i in y1) { Console.WriteLine(i); }

            //###################################################################################################################

            string k_str = "2 - x";
            string rev_k_str = "1.0/(2 - x)";
            string q_str = "x";
            string f_str = "2 * cos(x) - sin(x)";
            double hi0 = 1, hi1 = Tan(1), g0 = 1, g1 = 0, half = 1.0 / 2, fi_0, fi_N, d_0, d_N;

            double rev_k_int(double a, double b) => Log(Abs(a - 2) / Abs(b - 2));
            double q_str_int(double a, double b) => (b * b - a * a) / 2;
            double f_str_int(double a, double b) => (2 * Sin(b) + Cos(b) - 2 * Sin(a) - Cos(a));


            Func <double, double> a_i   = i => h / rev_k_int(X(i - 1), X(i));
            Func <double, double> d_i   = i => 1.0 / h * q_str_int(X(i - half), X(i + half));
            Func <double, double> phi_i = i => 1.0 / h * f_str_int(X(i - half), X(i + half));

            f = new double[N + 1];

            fi_0 = 2.0 / h * f_str_int(0, half * h);
            fi_N = 2.0 / h * f_str_int(1 - half * h, 1);

            f[0] = -(g0 + h / 2 * fi_0);
            f[N] = -(g1 + h / 2 * fi_N);
            for (int i = 1; i <= N - 1; i++)
            {
                f[i] = -phi_i(i);
            }

            c   = new double[N + 1];
            d_0 = 2.0 / h * q_str_int(0, half * h);
            d_N = 2.0 / h * q_str_int(1 - half * h, 1);


            c[0] = -a_i(1) / h - h / 2 * d_0 - hi0;
            c[N] = -a_i(N) / h - hi1 - h / 2 * d_N;
            for (int i = 1; i <= N - 1; i++)
            {
                c[i] = -a_i(i + 1) / h / h - a_i(i) / h / h - d_i(i);
            }

            a        = new double[N];
            a[N - 1] = -(a_i(N) / h);
            for (int i = 1; i <= N - 1; i++)
            {
                a[i - 1] = -(a_i(i) / h / h);
            }

            b    = new double[N];
            b[0] = -(a_i(1) / h);
            for (int i = 1; i <= N - 1; i++)
            {
                b[i] = -(a_i(i + 1) / h / h);
            }

            prg = new Progonka(a, c, b, f);
            prg.PerformProgonka();
            y2 = (double[])prg.y.Clone();

            //###################################################################################################################

            Func <Func <double, double>, double, double, double> intMid = (func, a, b) => func((a + b) / 2) * (b - a);

            double k_func(double x) => 2 - x;
            double q_func(double x) => x;
            double f_func(double x) => 2 * Cos(x) - Sin(x);

            a_i = i => 1.0 / h * (intMid(k_func, X(i - 1), X(i)) -
                                  intMid(x => q_func(x) * (X(i) - x) * (x - X(i - 1)), X(i - 1), X(i)));

            d_i = i => 1.0 / h / h * (intMid(x => q_func(x) * (x - X(i - 1)), X(i - 1), X(i)) +
                                      intMid(x => q_func(x) * (X(i + 1) - x), X(i), X(i + 1)));

            phi_i = i => 1.0 / h / h * (intMid(x => f_func(x) * (x - X(i - 1)), X(i - 1), X(i)) +
                                        intMid(x => f_func(x) * (X(i + 1) - x), X(i), X(i + 1)));

            f    = new double[N + 1];
            fi_0 = 2.0 / h / h * intMid(x => f_func(x) * (h - x), 0, h);
            fi_N = 2.0 / h / h * intMid(x => f_func(x) * (x - 1 + h), 1 - h, 1);
            f[0] = -(g0 + h / 2 * fi_0);
            f[N] = -(g1 + h / 2 * fi_N);
            for (int i = 1; i <= N - 1; i++)
            {
                f[i] = -phi_i(i);
            }

            c    = new double[N + 1];
            d_0  = 2.0 / h / h * intMid(x => q_func(x) * (h - x), 0, h);
            d_N  = 2.0 / h / h * intMid(x => q_func(x) * (x - 1 + h), 1 - h, 1);
            c[0] = -a_i(1) / h - h / 2 * d_0 - hi0;
            c[N] = -a_i(N) / h - hi1 - h / 2 * d_N;
            for (int i = 1; i <= N - 1; i++)
            {
                c[i] = -a_i(i + 1) / h / h - a_i(i) / h / h - d_i(i);
            }

            a        = new double[N];
            a[N - 1] = -(a_i(N) / h);
            for (int i = 1; i <= N - 1; i++)
            {
                a[i - 1] = -(a_i(i) / h / h);
            }

            b    = new double[N];
            b[0] = -(a_i(1) / h);
            for (int i = 1; i <= N - 1; i++)
            {
                b[i] = -(a_i(i + 1) / h / h);
            }

            prg = new Progonka(a, c, b, f);
            prg.PerformProgonka();
            y3 = (double[])prg.y.Clone();

            return(y1, y2, y3);
        }
Exemplo n.º 2
0
        public static double[,] Solve(double tau)
        {
            double h  = 0.05;
            int    N2 = (int)Round(1 / tau),
                   N1 = (int)Round(1 / h);

            double x(double i) => i * h > 1 ? throw new Exception("out of grid") : i * h;
            double t(double j) => j * tau > 1 ? throw new Exception("out of grid") : j * tau;
            double mu(double t) => (t - 1) * Exp(-t);
            double phi(double x, double t) => - (x + t * t) * Exp(-x * t);

            double[] f, c, a, b, res;
            double[,] y = new double[N2 + 1, N1 + 1];
            Progonka prg;

            for (int i = 0; i <= N1; i++)
            {
                y[0, i] = 1;
            }
            for (int j = 0; j <= N2; j++)
            {
                y[j, 0] = 1;
            }

            res = new double[N1 + 1];
            f   = new double[N1 + 1];
            c   = new double[N1 + 1];
            a   = new double[N1];
            b   = new double[N1];
            for (int j = 0; j <= N2 - 1; j++)
            {
                Array.Clear(f, 0, f.Length);
                Array.Clear(c, 0, c.Length);
                Array.Clear(a, 0, a.Length);
                Array.Clear(b, 0, b.Length);

                c[0]  = 1;
                c[N1] = 1.0 / h + 1 + h / 2 / tau;
                for (int i = 1; i <= N1 - 1; i++)
                {
                    c[i] = 1.0 / tau + 2.0 / h / h;
                }

                a[N1 - 1] = 1.0 / h;
                for (int i = 1; i <= N1 - 1; i++)
                {
                    a[i - 1] = 1.0 / h / h;
                }

                b[0] = 0;
                for (int i = 1; i <= N1 - 1; i++)
                {
                    b[i] = 1.0 / h / h;
                }

                f[0]  = 1;
                f[N1] = -mu(t(j + 1)) + h / 2 / tau * y[j, N1] + h / 2 * phi(1, t(j + 1));
                for (int i = 1; i <= N1 - 1; i++)
                {
                    f[i] = phi(x(i), t(j)) + y[j, i] / tau;
                }

                prg = new Progonka(a, c, b, f);
                prg.PerformProgonka();
                for (int i = 0; i <= N1; i++)
                {
                    y[j + 1, i] = prg.y[i];
                }
            }
            return(y);
        }