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

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

                m_A = new double[] { s[0] };
                m_B = new double[] { s[1] };
                m_C = new double[] { s[2] };
                m_D = new double[] { 0 };
            }
            else if (m_X.Count == 4)
            {
                double[] s = MatrixLowLevel.Solve(new double[][] {
                    new double[] { 1, m_X[0], m_X[0] * m_X[0], m_X[0] * m_X[0] * m_X[0], m_Y[0] },
                    new double[] { 1, m_X[1], m_X[1] * m_X[1], m_X[1] * m_X[1] * m_X[1], m_Y[1] },
                    new double[] { 1, m_X[2], m_X[2] * m_X[2], m_X[2] * m_X[2] * m_X[2], m_Y[2] },
                    new double[] { 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 double[] { s[0] };
                m_B = new double[] { s[1] };
                m_C = new double[] { s[2] };
                m_D = new double[] { 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, double> 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]);

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

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

            for (int i = 0; i < N; ++i)
            {
                double[][] mt = new double[][] {
                    new double[] { 1, m_X[i], m_X[i] * m_X[i], m_X[i] * m_X[i] * m_X[i], m_Y[i] },
                    new double[] { 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 double[] { 0, 1, 2 * m_X[i], 3 * m_X[i] * m_X[i], s[i] },
                    new double[] { 0, 1, 2 * m_X[i + 1], 3 * m_X[i + 1] * m_X[i + 1], s[i + 1] },
                };

                double[] 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 double[] { double.NaN };

                m_Polynom = Polynom.NaN;

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

                m_Polynom = new Polynom(m_A);

                return;
            }

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

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

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

                double x = m_X[r];
                double 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 Polynom(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 double[] {1, double.NaN, 9, 16, 25, double.NaN});
        /// </summary>
        /// <param name="startAt">starting point</param>
        /// <param name="values">values (put double.NaN for abscent points)</param>
        /// <returns></returns>
        public static Polynom Reconstruct(int startAt, IEnumerable <double> values)
        {
            if (values is null)
            {
                throw new ArgumentNullException(nameof(values));
            }

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

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

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

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

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

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

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

                    v *= x;
                }
            }

            return(new Polynom(MatrixLowLevel.Solve(M)));

            //return OldInterpolation.InterpolatonPolynom(points, p => (p.x, p.y));
        }