public static CubicSplain CreateCubicSpline(List <double> x_s,
                                                    List <double> y_s)
        {
            List <double> h = new List <double>();
            List <double> b = new List <double>();
            List <double> v = new List <double>();
            List <double> u = new List <double>();

            for (int i = 0; i < x_s.Count - 1; ++i)
            {
                h.Add(x_s[i + 1] - x_s[i]);
                b.Add((y_s[i + 1] - y_s[i]) / h.Last());
            }

            for (int i = 1; i < x_s.Count - 1; ++i)
            {
                v.Add(2.0 * (h[i - 1] + h[i]));
                u.Add(6.0 * (b[i] - b[i - 1]));
            }

            //выбрать только внутренние значения, игнорим первую и последнюю
            List <double> sliced_h =
                h.Skip(1).Take(h.Count - 2).ToList();

            var result = SolveTridiagonal(sliced_h, v, sliced_h, u);

            //первая производная точки равны 0
            List <double> z = new List <double>();

            z.Add(0.0);
            z = z.Concat(result).ToList();
            z.Add(0.0);

            List <CubicSection> sections = new List <CubicSection>();

            for (int i = 0; i < z.Count - 1; ++i)
            {
                double cBegin = z[i + 1] / (6.0 * h[i]);
                double cEnd   = z[i] / (6.0 * h[i]);
                double lBegin = y_s[i + 1] / h[i] - z[i + 1] * h[i] / 6.0;
                double lEnd   = y_s[i] / h[i] - h[i] * z[i] / 6.0;
                double tBegin = x_s[i];
                double tEnd   = x_s[i + 1];
                sections.Add(new CubicSection(cBegin,
                                              cEnd,
                                              lBegin,
                                              lEnd,
                                              tBegin,
                                              tEnd));
            }

            CubicSplain cubicSplain = new CubicSplain(x_s,
                                                      sections);

            return(cubicSplain);
        }
        public static CubicSplain CreateCubicSplineSecond(List <double> x_s,
                                                          List <double> y_s)
        {
            int n = x_s.Count;

            List <double> h = new List <double>();
            List <double> b = new List <double>();
            List <double> v = new List <double>();
            List <double> u = new List <double>();

            for (int i = 0; i < n - 1; ++i)
            {
                h.Add(x_s[i + 1] - x_s[i]);
                b.Add((y_s[i + 1] - y_s[i]) / h.Last());
            }

            for (int i = 1; i < n - 1; ++i)
            {
                v.Add(2.0 * (h[i - 1] + h[i]));
                u.Add(6.0 * (b[i] - b[i - 1]));
            }

            v[0]           = 1.5 * h[0] + 2.0 * h[1];
            v[v.Count - 1] = 1.5 * h[h.Count() - 2] + 2.0 * h[h.Count() - 1];
            u[0]           = u[0] - 3.0 * b[0];
            u[u.Count - 1] = u[u.Count() - 1] + 3.0 * b.Last();

            List <double> sliced_h = h.Skip(1).Take(h.Count() - 2).ToList();
            List <double> res      = SolveTridiagonal(sliced_h, v, sliced_h, u);
            List <double> z        = new List <double>();

            z.Add(0.5 * (6.0 * b.First() / h.First() - res.First()));
            z = z.Concat(res).ToList();
            z.Add(-0.5 * (6.0 * b.Last() / h.Last() + res.Last()));

            List <CubicSection> sections = new List <CubicSection>();

            for (int i = 0; i < z.Count() - 1; ++i)
            {
                double cBegin = z[i + 1] / (6.0 * h[i]);
                double cEnd   = z[i] / (6.0 * h[i]);
                double lBegin = y_s[i + 1] / h[i] - z[i + 1] * h[i] / 6.0;
                double lEnd   = y_s[i] / h[i] - h[i] * z[i] / 6.0;
                double tBegin = x_s[i];
                double tEnd   = x_s[i + 1];

                CubicSection cubicSection = new CubicSection(cBegin,
                                                             cEnd,
                                                             lBegin,
                                                             lEnd,
                                                             tBegin,
                                                             tEnd);

                sections.Add(cubicSection);
            }

            CubicSplain cubicSplain = new CubicSplain(x_s,
                                                      sections);

            return(cubicSplain);
        }