Aceleración de convergencia de una secuencia por la transformación de Levin. Inicialice llamando al constructor con los argumentos nmax, un límite superior en el número de términos que se van a sumar, y epss, la precisión deseada. Luego realice llamadas sucesivas a la función siguiente, que devuelve la estimación actual del límite de la secuencia. El indicador cnvgd se establece cuando se detecta convergencia.
suma, la enésima suma parcial de la secuencia; omega, el enésimo resto estimado, generalmente de (5.3.19); y el parámetro beta, que normalmente debe establecerse en 1, pero a veces 0,5 funciona mejor. Se devuelve la estimación actual del límite de la secuencia.
usando Sistema;
namespace Legalsoft.Truffer
{ /// <summary> /// Aceleración de convergencia de una secuencia mediante la transformación de Levin. /// Inicialice llamando al constructor con los argumentos nmax, un límite superior en /// el número de términos que se van a sumar, y epss, la precisión deseada. Luego realice /// llamadas sucesivas a la función siguiente, que devuelve el valor actual estimación de /// el límite de la secuencia. El indicador cnvgd se establece cuando /// se detecta convergencia. /// </summary> clase pública Levin { doble privado[] número { get; colocar; } doble privado [] denom { get; colocar; } privado int n { obtener; colocar; }
privado int ncv { obtener; colocar; }
public bool cnvgd { obtener; colocar; }
privado doble pequeño { get; colocar; }
público doble grande { get; colocar; }
doble eps privado { get; colocar; }
último valor doble privado { get; colocar; }
pasos dobles privados { get; colocar; }
public Levin(int nmax, doble epss)
{ this.numer = nuevo doble[nmax]; this.denom = nuevo doble[nmax]; esto.n = 0; este.ncv = 0; this.cnvgd = falso; this.eps = epss; this.lastval = 0.0;
pequeño = float.MinValue * 10.0;
grande = doble.MaxValue;
}
/// <summary>
/// suma, la enésima suma parcial de la secuencia; omega, la enésima estimación del resto
/// wn, generalmente de (5.3.19); y el parámetro beta, que normalmente /// debería establecerse en 1, pero a veces 0,5 funciona mejor. Se devuelve la
estimación actual del límite /// de la secuencia. /// </summary> /// <param name="sum"></param> /// <param name="omega"></param> /// <param name="beta"></ param> /// <returns></returns> public double next(doble suma, doble omega, doble beta = 1.0) { doble término = 1.
número[n] = suma * denominación[n];
if (n > 0)
{ doble razón = (beta + n - 1) * término; for (int j = 1; j <= n; j++) { doble hecho = (n - j + beta) * término; número[n - j] = número[n - j + 1] - hecho * número[n - j]; denominación[n - j] = denominación[n - j + 1] - hecho * denominación[n - j]; término = término * relación; } } n++; doble val = Math.Abs(denom[0]) <pequeño? último valor: número[0] / denominación[0]; últimos pasos = Math.Abs(val - último valor);
if (últimos pasos <= eps)
{ ncv ++; } si (ncv >= 2) { cnvgd = verdadero; } retorno (último valor = valor); } } }