예제 #1
0
        private bool CoreBuildSpecial()
        {
            if (m_X.Count > 4)
            {
                return(false);
            }

            if (m_X.Count == 0)
            {
                m_A = new BigRational[] { BigRational.NaN };
                m_B = new BigRational[] { 0 };
                m_C = new BigRational[] { 0 };
                m_D = new BigRational[] { 0 };
            }
            else if (m_X.Count == 1)
            {
                m_A = new BigRational[] { m_Y[0] };
                m_B = new BigRational[] { 0 };
                m_C = new BigRational[] { 0 };
                m_D = new BigRational[] { 0 };
            }
            else if (m_X.Count == 2)
            {
                m_A = new BigRational[] { (m_Y[0] * m_X[1] - m_Y[1] * m_X[0]) / (m_X[1] - m_X[0]) };
                m_B = new BigRational[] { (m_Y[1] - m_Y[0]) / (m_X[1] - m_X[0]) };
                m_C = new BigRational[] { 0 };
                m_D = new BigRational[] { 0 };
            }
            else if (m_X.Count == 3)
            {
                BigRational[] s = MatrixLowLevel.Solve(new BigRational[][] {
                    new BigRational[] { 1, m_X[0], m_X[0] * m_X[0], m_Y[0] },
                    new BigRational[] { 1, m_X[1], m_X[1] * m_X[1], m_Y[1] },
                    new BigRational[] { 1, m_X[2], m_X[2] * m_X[2], m_Y[2] },
                });

                m_A = new BigRational[] { s[0] };
                m_B = new BigRational[] { s[1] };
                m_C = new BigRational[] { s[2] };
                m_D = new BigRational[] { 0 };
            }
            else if (m_X.Count == 4)
            {
                BigRational[] s = MatrixLowLevel.Solve(new BigRational[][] {
                    new BigRational[] { 1, m_X[0], m_X[0] * m_X[0], m_X[0] * m_X[0] * m_X[0], m_Y[0] },
                    new BigRational[] { 1, m_X[1], m_X[1] * m_X[1], m_X[1] * m_X[1] * m_X[1], m_Y[1] },
                    new BigRational[] { 1, m_X[2], m_X[2] * m_X[2], m_X[2] * m_X[2] * m_X[2], m_Y[2] },
                    new BigRational[] { 1, m_X[3], m_X[3] * m_X[3], m_X[3] * m_X[3] * m_X[3], m_Y[3] },
                });

                m_A = new BigRational[] { s[0] };
                m_B = new BigRational[] { s[1] };
                m_C = new BigRational[] { s[2] };
                m_D = new BigRational[] { s[3] };
            }

            return(true);
        }
예제 #2
0
        // http://web.snauka.ru/issues/2015/05/53846
        // https://en.wikipedia.org/wiki/Akima_spline
        private void CoreBuild()
        {
            if (CoreBuildSpecial())
            {
                return;
            }

            int N = m_X.Count - 1;

            Dictionary <int, BigRational> m = new();

            for (int i = 0; i < N; ++i)
            {
                m.Add(i, (m_Y[i + 1] - m_Y[i]) / (m_X[i + 1] - m_X[i]));
            }

            m.Add(-2, 3 * m[0] - 2 * m[1]);
            m.Add(-1, 2 * m[0] - 2 * m[1]);
            m.Add(N, 2 * m[N - 1] - 2 * m[N - 2]);
            m.Add(N + 1, 3 * m[N - 1] - 2 * m[N - 2]);

            BigRational[] s = new BigRational[N + 1];

            for (int i = 0; i <= N; ++i)
            {
                s[i] = ((m[i + 1] - m[i]).Abs() * m[i - 1] +
                        (m[i - 1] - m[i - 2]).Abs() * m[i]) /
                       ((m[i + 1] - m[i]).Abs() + (m[i - 1] - m[i - 2]).Abs());
            }

            for (int i = 0; i < N; ++i)
            {
                BigRational[][] mt = new BigRational[][] {
                    new BigRational[] { 1, m_X[i], m_X[i] * m_X[i], m_X[i] * m_X[i] * m_X[i], m_Y[i] },
                    new BigRational[] { 1, m_X[i + 1], m_X[i + 1] * m_X[i + 1], m_X[i + 1] * m_X[i + 1] * m_X[i + 1], m_Y[i + 1] },
                    new BigRational[] { 0, 1, 2 * m_X[i], 3 * m_X[i] * m_X[i], s[i] },
                    new BigRational[] { 0, 1, 2 * m_X[i + 1], 3 * m_X[i + 1] * m_X[i + 1], s[i + 1] },
                };

                BigRational[] z = MatrixLowLevel.Solve(mt);

                m_A[i] = z[0];
                m_B[i] = z[1];
                m_C[i] = z[2];
                m_D[i] = z[3];
            }
        }
예제 #3
0
        private void CoreBuild()
        {
            if (m_X.Count == 0)
            {
                m_A = new BigRational[] { BigRational.NaN };

                m_Polynom = RationalPolynom.NaN;

                return;
            }
            else if (m_X.Count == 1)
            {
                m_A = new BigRational[] { m_Y[0] };

                m_Polynom = new RationalPolynom(m_A);

                return;
            }

            BigRational[][] M = new BigRational[m_Y.Count][];

            for (int r = 0; r < M.Length; ++r)
            {
                BigRational[] row = new BigRational[M.Length + 1];

                row[M.Length] = m_Y[r];

                BigRational x = m_X[r];
                BigRational v = 1;

                for (int i = 0; i < M.Length; ++i)
                {
                    row[i] = v;

                    v *= x;
                }

                M[r] = row;
            }

            m_A       = MatrixLowLevel.Solve(M);
            m_Polynom = new RationalPolynom(m_A);
        }
예제 #4
0
        /// <summary>
        /// Reconstruct polynom from its values
        /// for P(0) = 1, P(1) = ?, P(2) = 9, P(3) = 16, P(4) = 25, P(5) = ?
        /// var result = Reconstruct(0, new BigRational[] {1, BigRational.NaN, 9, 16, 25, BigRational.NaN});
        /// </summary>
        /// <param name="startAt">starting point</param>
        /// <param name="values">values (put BigRational.NaN for abscent points)</param>
        /// <returns></returns>
        public static RationalPolynom Reconstruct(int startAt, IEnumerable <BigRational> values)
        {
            if (values is null)
            {
                throw new ArgumentNullException(nameof(values));
            }

            var points = values
                         .Select((v, i) => (x: (BigRational)i + startAt, y: v))
                         .Where(item => !item.y.IsNaN)
                         .ToArray();

            if (points.Length == 0)
            {
                return(NaN);
            }

            BigRational[][] M = new BigRational[points.Length][];

            for (int r = 0; r < M.Length; ++r)
            {
                BigRational[] row = new BigRational[M.Length + 1];
                M[r] = row;

                row[M.Length] = points[r].y;

                BigRational x = points[r].x;
                BigRational v = 1;

                for (int c = 0; c < M.Length; ++c)
                {
                    row[c] = v;

                    v *= x;
                }
            }

            return(new RationalPolynom(MatrixLowLevel.Solve(M)));
        }