C#, code sea picking shells (08) - Aitken (Aitken) step-by-step curve interpolation algorithm, "C# Numerical Calculation Algorithm Programming" source code upgrade and improved version

Aitken progressive linear interpolation method (Aitken successive linear interpolation method) is an interpolation method that can gradually increase in order. When using Lagrange interpolation polynomials to calculate function approximations, if the accuracy does not meet the requirements, you need to add interpolation nodes to improve the interpolation polynomials When the number of times is high, the original calculated results cannot be used and must be recalculated. This shortcoming can be overcome by Etkin's stepwise linear interpolation method. This algorithm is suitable for computing on a computer, and it has the characteristics of automatically selecting knots and comparing the accuracy step by step. The program is also relatively simple. Generally, the difference between the values ​​​​of two adjacent interpolation polynomials on the oblique knot meets the required accuracy as a sign of the termination of the large calculation process. .

 

Aitken Interpolation -- from Wolfram MathWorld Applied Mathematics Numerical Methods Approximation Theory Interpolation Aitken Interpolation An algorithm similar to Neville's algorithm for constructing the Lagrange interpolating polynomial

Aitken Interpolation - Applied Mathematics Numerical Methods Approximate Theoretical Interpolation from Wolfram MathWorld Aitken Interpolation A Lagrangian interpolation polynomial construction algorithm similar to Neville's algorithm.

AITKEN'S INTERPOLATION
Aitken's procedure yields systematically and successively better interpolation polynomials corresponding to successively higher order truncation of Newton's divided difference formula.

Aiken interpolation

The Aitken procedure systematically and continuously produces better interpolating polynomials, corresponding to successive higher-order truncations of Newton's difference formula.

using System;
using System.Drawing;
using System.Collections;
using System.Collections.Generic;

namespace Zhou.CSharp.Algorithm
{
    /// <summary>
    /// 插值计算类Interpolation.cs
    /// 作者:周长发
    /// 改编:深度混淆
    /// https://blog.csdn.net/beijinghorn
    /// </summary>
    public static partial class Interpolation
    {
        /// <summary>
        /// 埃特金不等距逐步插值
        /// </summary>
        /// <param name="x">一维数组,长度为n,存放给定的n个结点的值x(i),要求x(0)<x(1)<...<x(n-1)</param>
        /// <param name="y">一维数组,长度为n,存放给定的n个结点的函数值y(i),y(i) = f(x(i)), i=0,1,...,n-1</param>
        /// <param name="t">存放指定的插值点的x值</param>
        /// <param name="eps">控制精度参数</param>
        /// <returns>指定的查指点t的函数近似值y=f(t)</returns>
        public static double Aitken(double[] x, double[] y, double t, double eps)
        {
            int n = x.Length;
            double z = 0.0;
            // 特例处理
            if (n < 1)
            {
                return (z);
            }
            if (n == 1)
            {
                z = y[0];
                return (z);
            }

            // 开始插值
            int m = 10;
            if (m > n)
            {
                m = n;
            }
            int k;
            if (t <= x[0])
            {
                k = 1;
            }
            else if (t >= x[n - 1])
            {
                k = n;
            }
            else
            {
                k = 1;
                int j = n;
                int l = 0;
                while ((k - j != 1) && (k - j != -1))
                {
                    l = (k + j) / 2;
                    if (t < x[l - 1])
                    {
                        j = l;
                    }
                    else
                    {
                        k = l;
                    }
                }
                if (Math.Abs(t - x[l - 1]) > Math.Abs(t - x[j - 1]))
                {
                    k = j;
                }
            }

            double[] xx = new double[10];
            double[] yy = new double[10];
            {
                int j = 1;
                int l = 0;
                for (int i = 1; i <= m; i++)
                {
                    k = k + j * l;
                    if ((k < 1) || (k > n))
                    {
                        l = l + 1;
                        j = -j;
                        k = k + j * l;
                    }

                    xx[i - 1] = x[k - 1];
                    yy[i - 1] = y[k - 1];
                    l = l + 1;
                    j = -j;
                }
            }

            {
                int i = 0;
                do
                {
                    i = i + 1;
                    z = yy[i];

                    for (int j = 0; j <= i - 1; j++)
                    {
                        z = yy[j] + (t - xx[j]) * (yy[j] - z) / (xx[j] - xx[i]);
                    }
                    yy[i] = z;
                } while ((i != m - 1) && (Math.Abs(yy[i] - yy[i - 1]) > eps));
            }

            return (z);
        }

        /// <summary>
        /// 埃特金等距逐步插值
        /// (使用非等距插值的方法)
        /// </summary>
        /// <param name="x0">存放等距n个结点中第一个结点的值</param>
        /// <param name="step">等距结点的步长</param>
        /// <param name="y">一维数组,长度为n,存放给定的n个结点的函数值y(i),y(i) = f(x(i)), i=0,1,...,n-1</param>
        /// <param name="t">存放指定的插值点的x值</param>
        /// <param name="eps">精算精度</param>
        /// <returns>指定的查指点t的函数近似值y=f(t)</returns>
        public static double Aitken(double x0, double step, double[] y, double t, double eps)
        {
            double[] x = new double[y.Length];
            for (int i = 0; i < y.Length; i++, x0 += step)
            {
                x[i] = x0;
            }
            return Aitken(x, y, t, eps);
        }

#if __OLD__
        /// <summary>
        /// 埃特金等距逐步插值
        /// </summary>
        /// <param name="x0">等距n个结点中第一个结点的值</param>
        /// <param name="step">等距结点的步长</param>
        /// <param name="y">一维数组,长度为n,存放给定的n个结点的函数值y(i),y(i) = f(x(i)), i=0,1,...,n-1</param>
        /// <param name="t">存放指定的插值点的x值</param>
        /// <param name="eps">控制精度参数</param>
        /// <returns>指定的查指点t的函数近似值y=f(t)</returns>
        /// <returns></returns>
        public static double Aitken(double x0, double step, double[] y, double t, double eps)
        {
            int n = y.Length;
            double z = 0.0;

            // 特例处理
            if (n < 1)
            {
                return (z);
            }
            else if (n == 1)
            {
                z = y[0];
                return (z);
            }

            // 开始插值
            int m = 10;
            if (m > n)
            {
                m = n;
            }
            int k = 0;
            if (t <= x0)
            {
                k = 1;
            }
            else if (t >= x0 + (n - 1) * step)
            {
                k = n;
            }
            else
            {
                k = 1;
                int j = n;
                int w = 0;
                while ((k - j != 1) && (k - j != -1))
                {
                    w = (k + j) / 2;
                    if (t < x0 + (w - 1) * step)
                    {
                        j = w;
                    }
                    else
                    {
                        k = w;
                    }
                }
                if (Math.Abs(t - (x0 + (w - 1) * step)) > Math.Abs(t - (x0 + (j - 1) * step)))
                {
                    k = j;
                }
            }

            double[] xx = new double[10];
            double[] yy = new double[10];
            {
                int j = 1;
                int w = 0;
                for (int i = 1; i <= m; i++)
                {
                    k = k + j * w;
                    if ((k < 1) || (k > n))
                    {
                        w = w + 1;
                        j = -j;
                        k = k + j * w;
                    }

                    xx[i - 1] = x0 + (k - 1) * step;
                    yy[i - 1] = y[k - 1];
                    w = w + 1;
                    j = -j;
                }
            }
            {
                int i = 0;
                do
                {
                    i = i + 1;
                    z = yy[i];
                    for (int j = 0; j <= i - 1; j++)
                    {
                        z = yy[j] + (t - xx[j]) * (yy[j] - z) / (xx[j] - xx[i]);
                    }
                    yy[i] = z;
                } while ((i != m - 1) && (Math.Abs(yy[i] - yy[i - 1]) > eps));
            }
            return (z);
        }
#endif
    }
}

POWER BY 315SOFT.COM

For extended methods such as calculation based on coordinate points, calculation of interpolation curves from point sets, please refer to " Lagrangian Interpolation Algorithm and Its Expansion "

Guess you like

Origin blog.csdn.net/beijinghorn/article/details/129829882