C#、数値計算 - チェビシェフ近似法(チェビシェフ近似)の計算方法とソースプログラム

システムを使用する;

namespace Legalsoft.Truffer
{     /// <summary>     /// チェビシェフ近似     /// </summary>     public class Chebyshev     {         private int n { get; セット; プライベート         int m {取得; セット; プライベート         ダブル[] c {取得; セット; プライベート         ダブルa {取得; セット; プライベート         ダブルb {取得; セット; }









        public Chebyshev(double[] cc, double aa, double bb)
        {             this.n = cc.Length;             これ.m = n;             this.c = Globals.CopyFrom(cc);             this.a = aa;             これ.b = bb;         }





        public Chebyshev(double[] d)
        {             this.n = d.Length;             これ.m = n;             this.c = 新しい double[n];             this.a = -1.0;             this.b = 1.0;




            c[n - 1] = d[n - 1];
            c[n - 2] = 2.0 * d[n - 2];
            for (int j = n - 3; j >= 0; j--)
            {                 c[j] = 2.0 * d[j] + c[j + 2];                 for (int i = j + 1; i < n - 2; i++)                 {                     c[i] = (c[i] + c[i + 2]) / 2;                 c                 [n - 2] /= 2;                 c[n - 1] /= 2;             } }         /         *         public Chebyshev(UniVarRealValueFun func, double aa, double bb)         {             new this(func, aa, bb, 50);         }         */         /// <概要>
















        /// チェビシェフのルーチンの Polycof の逆: /// 多項式係数 d[0..n - 1] の配列を指定して
        、同等のチェビシェフ オブジェクトを構築します。
        /// </summary>
        /// <param name="func"></param>
        /// <param name="aa"></param>
        /// <param name="bb"></ param>
        /// <param name="nn"></param>
        public Chebyshev(UniVarRealValueFun func, double aa, double bb, int nn = 50)
        {             this.n = nn;             これ.m = nn;             this.c = 新しい double[n];             this.a = aa;             これ.b = bb;




            double[] f = 新しい double[n];
            ダブル bma = 0.5 * (b - a);
            ダブル bpa = 0.5 * (b + a);
            for (int k = 0; k < n; k++)
            {                 double y = Math.Cos(Math.PI * (k + 0.5) / n);                 f[k] = func.funk(y * bma + bpa);             ダブル             ファク = 2.0 / n;             for (int j = 0; j < n; j++)             {                 double sum = 0.0;                 for (int k = 0; k < n; k++)                 {                     sum += f[k] * Math.Cos(Math.PI * j * (k + 0.5) / n);                 c [                 j] = fac * 合計;












            }
        }

        public double eval(double x, int m)
        {             double d = 0.0;             ダブル dd = 0.0;

            if ((x - a) * (x - b) > 0.0)
            {                 throw new Exception("x が Chebyshev::eval の範囲内にありません");             double             y = (2.0 * x - a - b) / (b - a);             ダブル y2 = 2.0 * (y);             for (int j = m - 1; j > 0; j--)             {                 double sv = d;                 d = y2 * d - dd + c[j];                 dd = SV;             y * d - dd + 0.5 * c[0] を返します             。         }











        public double[] getc()
        {             return c;         }

        /// <summary> ///         同じ範囲 [a, b] にわたる既存の関数
        の導関数を近似する新しいチェビシェフ オブジェクトを返します。 ///         /// </summary>         /// <returns></returns>         public チェビシェフ デリバティブ()         {             double[] cder = new double[n];             cder[n - 1] = 0.0;             cder[n - 2] = 2 * (n - 1) * c[n - 1];             for (int j = n - 2; j > 0; j--)             {                 cder[j - 1] = cder[j + 1] + 2 * j * c[j];             ダブルコン             = 2.0 / (b - a);             for (int j = 0; j < n; j++)             {















                cder[j] *= con;             新しいチェビシェフ(cder, a, b)を返します
            。         }

        /// <summary> ///         同じ範囲 [a, b] にわたる既存の関数
        の不定積分を近似する新しい Chebyshev オブジェクトを返します。 ///
/// 積分の定数は、
        積分が a で消えるように設定されます。
        /// </summary>
        /// <returns></returns>
        public Chebyshevintegral()
        {             double sum = 0.0;             ダブルファク = 1.0;             double[] cint = 新しい double[n];             ダブルコン = 0.25 * (b - a);             for (int j = 1; j < n - 1; j++)             {                 cint[j] = con * (c[j - 1] - c[j + 1]) / j;







                合計 += fac * cint[j];
                fac = -fac;
            cint[n - 1] = con * c [
            n - 2] / (n - 1);
            合計 += fac * cint[n - 1];
            ベルト[0] = 2.0 * 合計;
            新しいチェビシェフ(cint, a, b)を返します;
        }

        /// <summary>
        /// チェビシェフ フィットからの多項式係数。係数配列
        /// c[0..n-1] を指定すると、このルーチンは次のような係数配列 d[0..n-1] を返します。
        /// sum(k= 0, n-1)dky^k = sum(k= 0, n-1)Tk(y)-c0/2。この方法は Clenshaw の
        /// recursion(5.8.11) ですが、現在は算術ではなく代数的に適用されています。
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public double[] Polycofs(int m)
        {             double[] d = new double[ m];             double[] dd = 新しい double[m];             for (int j = 0; j < m; j++)             {




                d[j] = 0.0;
                dd[j] = 0.0;
            d
            [0] = c[m - 1];
            for (int j = m - 2; j > 0; j--)
            {                 for (int k = m - j; k > 0; k--)                 {                     double s1v = d[k];                     d[k] = 2.0 * d[k - 1] - dd[k];                     dd[k] = s1v;                 ダブル                 s2v = d[0];                 d[0] = -dd[0] + c[j];                 dd[0] = s2v;             }             for (int j = m - 1; j > 0; j--)             {                 d[j] = d[j - 1] - dd[j];













            d [
            0] = -dd[0] + 0.5 * c[0];
            dを返します。
        }

        public int setm(double thresh)
        {             while (m > 1 && Math.Abs​​(c[m - 1]) < thresh)             {                 m--;             m を返し             ます。         }





        public double get(double x)
        {             return eval(x, m);         }

        public double[] Polycofs()
        {             return Polycofs(m);         }

        public static void pcshft(double a, double b, double[] d)
        {             int n = d.Length;             ダブル cnst = 2.0 / (b - a);             ダブルファク = cnst;             for (int j = 1; j < n; j++)             {                 d[j] *= fac;                 fac *= cnst;             cnst             = 0.5 * (a + b);             for (int j = 0; j <= n - 2; j++)             {                 for (int k = n - 2; k >= j; k--)                 {                     d[k] -= cnst * d[k + 1] ;                 }         }             }
















        public static void ipcshft(double a, double b, double[] d)
        {             pcshft(-(2.0 + b + a) / (b - a), (2.0 - b - a) / (b - a), d) ;         }

    }
}
 

おすすめ

転載: blog.csdn.net/beijinghorn/article/details/132367859