Ejemplo n.º 1
0
            /// <summary>
            /// Решение задачи Штурма-Лиувилля
            /// </summary>
            /// <param name="g">Функция внутри второй производной</param>
            /// <param name="h">Функция при первой производной</param>
            /// <param name="s">Функция при искомой функции</param>
            /// <param name="f">Свободная функция</param>
            /// <param name="a">Начало отрезка</param>
            /// <param name="b">Конец отрезка</param>
            /// <param name="N">Число шагов</param>
            /// <param name="A"></param>
            /// <param name="B"></param>
            /// <param name="C"></param>
            /// <param name="D"></param>
            /// <param name="A1"></param>
            /// <param name="B1"></param>
            /// <param name="C1"></param>
            /// <param name="D1"></param>
            /// <returns></returns>
            public static NetFunc SchLiuQu(Func <double, double> g, Func <double, double> h, Func <double, double> s, Func <double, double> f, out double nevaska, double a = 0, double b = 10, int N = 50, double A = 1, double B = 1, double D = 1, double A1 = 1, double B1 = 1, double D1 = 1, bool firstkind = true)
            {
                double[] hn = new double[N + 1], fn = new double[N + 1], sn = new double[N + 1], tn = new double[N + 1], an = new double[N + 1], bn = new double[N + 1], cn = new double[N + 1], dn = new double[N + 1];
                double   t  = (b - a) / N;

                for (int i = 0; i < N + 1; i++)
                {
                    double arg = a + i * t;
                    tn[i] = arg;
                    hn[i] = h(arg);
                    fn[i] = f(arg);
                    sn[i] = s(arg);
                    an[i] = (g(arg - t / 2) / t - hn[i] / 2) / t;
                    cn[i] = (g(arg + t / 2) / t + hn[i] / 2) / t;
                    bn[i] = an[i] + cn[i] - sn[i]; //поставил sn вместо hn
                                                   //bn[i] = (g(arg + t / 2) - g(arg - t / 2)) / t / t - sn[i];
                    dn[i] = fn[i];
                }

                double k1 = 0, k2 = 0;

                if (firstkind)
                {
                    bn[0] = A / t - B; cn[0] = A / t; dn[0] = D;
                    an[N] = -A1 / t; bn[N] = -A1 / t - B1; dn[N] = D1;
                }
                else
                {
                    bn[0] = 3 * A / 2 / t - B; cn[0] = 2 * A / t; k1 = -A / 2 / t;
                    bn[N] = -3 * A1 / 2 / t - B1; an[N] = -2 * A1 / t; k2 = A1 / 2 / t;
                }

                dn[0] = D;
                dn[N] = D1;

                SLAU S = new SLAU(N + 1);

                S.A[0, 0]     = -bn[0];
                S.A[0, 1]     = cn[0]; S.A[0, 2] = k1;
                S.A[N, N - 1] = an[N]; S.A[N, N - 2] = k2;
                S.A[N, N]     = -bn[N];
                S.b[0]        = dn[0]; S.b[N] = dn[N];
                for (int i = 1; i < N; i++)
                {
                    S.A[i, 0 + i - 1] = an[i];
                    S.A[i, 1 + i - 1] = -bn[i];
                    S.A[i, 2 + i - 1] = cn[i];
                    S.b[i]            = dn[i];
                }

                S.Show(); "".Show();

                double c1 = S.A[0, 2] / S.A[1, 2], c2 = S.A[N, N - 2] / S.A[N - 1, N - 2];

                for (int i = 0; i < 3; i++)
                {
                    S.A[0, i]     -= S.A[1, i] * c1;
                    S.A[N, N - i] -= S.A[N - 1, N - i] * c2;
                }
                S.b[0] -= S.b[1] * c1; S.b[N] -= S.b[N - 1] * c2;

                //S.Show(); "".Show();

                S.ProRace(); S.Show(); nevaska = S.Nevaska;

                NetFunc res = new NetFunc();

                for (int i = 0; i < N + 1; i++)
                {
                    res.Add(new Point(tn[i], S.x[i]));
                }
                return(res);
            }
Ejemplo n.º 2
0
            /// <summary>
            /// Решение уравнения теплопроводности явной либо неявной схемой
            /// </summary>
            /// <param name="f">Свободная фунция из уравнения</param>
            /// <param name="f1">Функция из первого краевого условия</param>
            /// <param name="f2">Функция из второго краевого условия</param>
            /// <param name="u0">Функция из начальных условий</param>
            /// <param name="u">Искомая функция (нужна для вычисления точности самого решения)</param>
            /// <param name="a">Коэффициент при второй производной</param>
            /// <param name="A1"></param>
            /// <param name="B1"></param>
            /// <param name="A2"></param>
            /// <param name="B2"></param>
            /// <param name="x0">Начало отрезка по пространству</param>
            /// <param name="X">Конец отрезка по пространству</param>
            /// <param name="t0">Начало отрезка по времени</param>
            /// <param name="T">Конец отрезка по времени</param>
            /// <param name="xcount">Число шагов по пространству</param>
            /// <param name="tcount">Число шагов по времени</param>
            /// <param name="accuracy">Выводимая точность</param>
            /// <param name="explict">Использовать явную схему либо нет</param>
            /// <returns></returns>
            public static List <NetFunc> TU(DRealFunc f, Func <double, double> f1, Func <double, double> f2, Func <double, double> u0, DRealFunc u, double a, double A1, double B1, double A2, double B2, double x0, double X, double t0, double T, int xcount, int tcount, out double accuracy, bool explict = true, bool thirdkind = true)
            {
                List <NetFunc> res = new List <NetFunc>();
                double         h   = (X - x0) / (xcount - 1);
                double         tau = (T - t0) / (tcount - 1);

                double[] x     = new double[xcount], t = new double[tcount];
                double[] value = new double[xcount];

                for (int i = 0; i < xcount; i++)
                {
                    x[i] = x0 + i * h;
                }
                for (int i = 0; i < tcount; i++)
                {
                    t[i] = t0 + i * tau;
                }

                for (int i = 0; i < xcount; i++)
                {
                    value[i] = u0(x[i]);
                }
                res.Add(new NetFunc(x, value));

                double th = tau / h / h;
                double h1 = A1 + h * B1, h2 = A2 + h * B2; //(h1*h1.Reverse()).Show();

                if (explict)
                {
                    for (int i = 1; i < tcount; i++)
                    {
                        for (int j = 1; j < xcount - 1; j++)
                        {
                            value[j] = res[i - 1].Values[j] + a * th * (res[i - 1].Values[j - 1] - 2 * res[i - 1].Values[j] + res[i - 1].Values[j + 1]) + tau * f(t[i /*-1*/], x[j]);
                        }
                        if (thirdkind)
                        {
                            value[0]          = (A1 * value[1] + h * f1(t[i])) / h1;
                            value[xcount - 1] = (A2 * value[xcount - 2] + h * f2(t[i])) / h2;
                        }
                        else
                        {
                            value[0]          = f1(t[i]) / B1;
                            value[xcount - 1] = f2(t[i]) / B2;
                        }

                        res.Add(new NetFunc(x, value));
                        //new Vectors (res.Last().Values).Show();
                    }
                }
                else
                {
                    SLAU s = new SLAU(xcount);

                    for (int i = 1; i < tcount; i++)
                    {
                        if (thirdkind)
                        {
                            s.A[0, 0] = h1; s.A[0, 1] = -A1; s.b[0] = h * f1(t[i]);
                            s.A[xcount - 1, xcount - 1] = h2; s.A[xcount - 1, xcount - 2] = -A2; s.b[xcount - 1] = h * f2(t[i]);
                        }
                        else
                        {
                            s.A[0, 0] = B1; s.b[0] = f1(t[i]);
                            s.A[xcount - 1, xcount - 1] = B2; s.b[xcount - 1] = f2(t[i]);
                        }


                        for (int j = 1; j < xcount - 1; j++)
                        {
                            s.A[j, j - 2 + 1] = -a * th;
                            s.A[j, j - 2 + 2] = a * 2 * th + 1;
                            s.A[j, j - 2 + 3] = -a * th;
                            s.b[j]            = res[i - 1].Values[j - 2 + 2] + tau * f(t[i /*-1*/], x[j]);
                        }

                        s.ProRace();
                        // "".Show();
                        //s.Show();
                        value = s.x;
                        res.Add(new NetFunc(x, value));
                    }
                }

                accuracy     = 0;
                double[,] ac = new double[tcount, xcount];
                for (int i = 0; i < t.Length; i++)
                {
                    for (int j = 0; j < x.Length; j++)
                    {
                        ac[i, j] = Math.Abs(u(t[i], x[j]) - res[i].Values[j]);
                    }
                }
                accuracy = new Matrix(ac).Max;

                return(res);
            }
Ejemplo n.º 3
0
        /// <summary>
        /// Интерполяция кубическими сплайнами дефекта 1 по массиву точек
        /// </summary>
        /// <param name="P"></param>
        /// <param name="a">Граничное условие в начале отрезка</param>
        /// <param name="b">Граничное условие в конце отрезка</param>
        /// <param name="is0outcut">Должен ли сплайн равняться 0 вне отрезка задания</param>
        /// <returns></returns>
        public static Func <double, double> CubeSpline(Point[] P, double a = 0, double b = 0, bool is0outcut = false)
        {
            int n = P.Length - 1;//записать в новую переменную для облегчения

            double[] h = new double[n + 1];
            double[] y = new double[n + 1];

            hmax = P[1].x - P[0].x;

            for (int i = 1; i <= n; i++)
            {
                h[i] = P[i].x - P[i - 1].x;//Заполнение массива длин отрезков
                if (h[i] > hmax)
                {
                    hmax = h[i];
                }
                y[i] = P[i].y - P[i - 1].y;
            }

            //создание, заполнение и решение системы с трёхдиагональной матрицей
            SLAU S = new SLAU(n + 1);

            S.A[0, 0]     = -4.0 / h[1]; S.A[0, 1] = -2.0 / h[1]; S.b[0] = -6.0 * y[1] / (h[1] * h[1]) + a;
            S.A[n, n - 1] = 2.0 / h[n]; S.A[n, n] = 4.0 / h[n]; S.b[n] = 6.0 * y[n] / (h[n] * h[n]) + b;
            for (int i = 1; i <= n - 1; i++)
            {
                S.A[i, i - 1] = 1.0 / h[i];
                S.A[i, i]     = 2 * (1.0 / h[i] + 1.0 / h[i + 1]);
                S.A[i, i + 1] = 1.0 / h[i + 1];
                S.b[i]        = 3 * (y[i] / h[i] / h[i] + y[i + 1] / h[i + 1] / h[i + 1]);
            }
            //S.b[0] = a;
            //S.b[n] = b;
            S.ProRace();
            syst = S;
            //S.Show();

            //создание и заполнение массива полиномов
            Polynom[] mas = new Polynom[n + 1];
            Polynom.SplinePol = new string[n];
            for (int i = 1; i <= n; i++)
            {
                Polynom p1, p2, p3, p4;
                p1               = (new Polynom(1, P[i].x, P[i].x)) * (2 * new Polynom(P[i - 1].x) + h[i]) / Math.Pow(h[i], 3) * P[i - 1].y;
                p2               = (new Polynom(1, P[i - 1].x, P[i - 1].x)) * (-2 * new Polynom(P[i].x) + h[i]) / Math.Pow(h[i], 3) * P[i].y;
                p3               = (new Polynom(1, P[i].x, P[i].x)) * (new Polynom(P[i - 1].x)) / Math.Pow(h[i], 2) * S.x[i - 1];
                p4               = (new Polynom(1, P[i - 1].x, P[i - 1].x)) * (new Polynom(P[i].x)) / Math.Pow(h[i], 2) * S.x[i];
                mas[i]           = p1 + p2 + p3 + p4;
                SplinePol[i - 1] = String.Format("[{0};{1}]: {2}", P[i - 1].x, P[i].x, mas[i].ToString());
                //mas[i].Show();
            }
            //mas[0] = mas[1];mas[n + 1] = mas[n];

            //создание производных сплайна
            Polynom[] mas1 = new Polynom[n + 1], mas2 = new Polynom[n + 1];
            for (int i = 1; i <= n; i++)
            {
                mas1[i] = mas[i] | 1;
                mas2[i] = mas1[i] | 1;
            }
            DSpline = (double x) =>
            {
                if (x <= P[1].x)
                {
                    return(mas1[1].Value(x));
                }
                if (x >= P[n].x)
                {
                    return(mas1[n].Value(x));
                }
                int i = 1;
                while (x > P[i].x)
                {
                    i++;
                }
                return(mas1[i].Value(x));
            };
            D2Spline = (double x) =>
            {
                if (x <= P[1].x)
                {
                    return(mas2[1].Value(x));
                }
                if (x >= P[n].x)
                {
                    return(mas2[n].Value(x));
                }
                int i = 1;
                while (x > P[i].x)
                {
                    i++;
                }
                return(mas2[i].Value(x));
            };

            //создание общей функции и вывод
            return((double x) =>
            {
                if (x <= P[1].x)
                {
                    return (is0outcut) ? 0 : mas[1].Value(x);
                }
                if (x >= P[n].x)
                {
                    return (is0outcut) ? 0 : mas[n].Value(x);
                }
                int i = 1;
                //while (x > P[i].x) i++;
                int i1 = 1, i2 = n;
                //реализация бинарного поиска
                while (i2 - i1 != 1)
                {
                    int tmp = Expendator.Average(i1, i2);
                    if (x > P[tmp].x)
                    {
                        i1 = tmp;
                    }
                    else
                    {
                        i2 = tmp;
                    }
                }
                i = i2;
                return mas[i].Value(x);
            });
        }