Accélération de convergence d'une séquence par la transformation de Levin. Initialisez en appelant le constructeur avec les arguments nmax, une borne supérieure sur le nombre de termes à additionner, et epss, la précision souhaitée. Effectuez ensuite des appels successifs à la fonction next, qui renvoie l'estimation actuelle de la limite de la séquence. l'indicateur cnvgd est défini lorsque la convergence est détectée.
sum, la nième somme partielle de la séquence ; oméga, le nième reste estimé, généralement à partir de (5.3.19) ; et le paramètre bêta, qui doit généralement être réglé sur 1, mais parfois 0,5 fonctionne mieux. L'estimation actuelle de la limite de la séquence est renvoyée.
utiliser le système ;
namespace Legalsoft.Truffer
{ /// <summary> /// Accélération de convergence d'une séquence par la transformation de Levin. /// Initialisez en appelant le constructeur avec les arguments nmax, une borne supérieure sur /// le nombre de termes à additionner, et epss, la précision souhaitée. Puis faites /// des appels successifs à la fonction next, qui renvoie le courant estimation de /// la limite de la séquence. Le flag cnvgd est positionné lorsque la convergence est /// détectée. /// </summary> public class Levin { private double[] numer { get; ensemble; } privé double[] denom {get; ensemble; } privé int n { obtenir ; ensemble; }
privé int ncv { obtenir ; ensemble; }
public bool cnvgd { obtenir ; ensemble; }
privé double petit { get; ensemble; }
public double gros { obtenir ; ensemble; }
double eps privé { obtenir ; ensemble; }
privé double lastval {get; ensemble; }
doubles pas privés { get; ensemble; }
public Levin(int nmax, double epss)
{ this.numer = new double[nmax]; this.denom = nouveau double[nmax]; ceci.n = 0; ceci.ncv = 0 ; this.cnvgd = faux ; ceci.eps = epss ; this.lastval = 0,0 ;
petit = float.MinValue * 10,0 ;
grand = double.MaxValue ;
}
/// <summary>
/// sum, la nième somme partielle de la séquence ; omega, la nième estimation du reste
/// wn , généralement à partir de (5.3.19) ; et le paramètre bêta, qui devrait généralement être
/// défini sur 1, mais parfois 0,5 fonctionne mieux. L'estimation actuelle de la limite
/// de la séquence est renvoyée.
/// </summary>
/// <param name="sum"></param>
/// <param name="omega"></param>
/// <param name="beta"></ param>
/// <returns></returns>
public double next(double somme, double oméga, double bêta = 1.0)
{ double terme = 1. 0 / (bêta + n) ; denom[n] = terme / oméga ;
numer[n] = sum * denom[n];
if (n > 0)
{
double ratio = (beta + n - 1) * term;
for (int j = 1; j <= n; j++)
{
double fact = (n - j + beta) * term;
numer[n - j] = numer[n - j + 1] - fact * numer[n - j];
denom[n - j] = denom[n - j + 1] - fact * denom[n - j];
term = term * ratio;
}
}
n++;
double val = Math.Abs(denom[0]) < small ? lastval : numer[0] / denom[0];
lasteps = Math.Abs(val - lastval);
if (derniers pas <= eps)
{ ncv ++ ; } si ( ncv >= 2 ) { cnvgd = true ; } return ( lastval = val ) ; } } }