1 文本格式
using System;
namespace Legalsoft.Truffer
{
/// <summary>
/// Convergence acceleration of a sequence by the Levin transformation.
/// Initialize by calling the constructor with arguments nmax, an upper bound on
/// the number of terms to be summed, and epss, the desired accuracy.Then make
/// successive calls to the function next, which returns the current estimate of
/// the limit of the sequence.The flag cnvgd is set when convergence is
/// detected.
/// </summary>
public class Levin
{
private double[] numer { get; set; }
private double[] denom { get; set; }
private int n { get; set; }
private int ncv { get; set; }
public bool cnvgd { get; set; }
private double small { get; set; }
public double big { get; set; }
private double eps { get; set; }
private double lastval { get; set; }
private double lasteps { get; set; }
public Levin(int nmax, double epss)
{
this.numer = new double[nmax];
this.denom = new double[nmax];
this.n = 0;
this.ncv = 0;
this.cnvgd = false;
this.eps = epss;
this.lastval = 0.0;
small = float.MinValue * 10.0;
big = double.MaxValue;
}
/// <summary>
/// sum, the nth partial sum of the sequence; omega, the nth remainder estimate
/// wn , usually from(5.3.19); and the parameter beta, which should usually be
/// set to 1, but sometimes 0.5 works better.The current estimate of the limit
/// of the sequence is returned.
/// </summary>
/// <param name="sum"></param>
/// <param name="omega"></param>
/// <param name="beta"></param>
/// <returns></returns>
public double next(double sum, double omega, double beta = 1.0)
{
double term = 1.0 / (beta + n);
denom[n] = term / omega;
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 (lasteps <= eps)
{
ncv++;
}
if (ncv >= 2)
{
cnvgd = true;
}
return (lastval = val);
}
}
}
2 代码格式
using System;
namespace Legalsoft.Truffer
{
/// <summary>
/// Convergence acceleration of a sequence by the Levin transformation.
/// Initialize by calling the constructor with arguments nmax, an upper bound on
/// the number of terms to be summed, and epss, the desired accuracy.Then make
/// successive calls to the function next, which returns the current estimate of
/// the limit of the sequence.The flag cnvgd is set when convergence is
/// detected.
/// </summary>
public class Levin
{
private double[] numer { get; set; }
private double[] denom { get; set; }
private int n { get; set; }
private int ncv { get; set; }
public bool cnvgd { get; set; }
private double small { get; set; }
public double big { get; set; }
private double eps { get; set; }
private double lastval { get; set; }
private double lasteps { get; set; }
public Levin(int nmax, double epss)
{
this.numer = new double[nmax];
this.denom = new double[nmax];
this.n = 0;
this.ncv = 0;
this.cnvgd = false;
this.eps = epss;
this.lastval = 0.0;
small = float.MinValue * 10.0;
big = double.MaxValue;
}
/// <summary>
/// sum, the nth partial sum of the sequence; omega, the nth remainder estimate
/// wn , usually from(5.3.19); and the parameter beta, which should usually be
/// set to 1, but sometimes 0.5 works better.The current estimate of the limit
/// of the sequence is returned.
/// </summary>
/// <param name="sum"></param>
/// <param name="omega"></param>
/// <param name="beta"></param>
/// <returns></returns>
public double next(double sum, double omega, double beta = 1.0)
{
double term = 1.0 / (beta + n);
denom[n] = term / omega;
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 (lasteps <= eps)
{
ncv++;
}
if (ncv >= 2)
{
cnvgd = true;
}
return (lastval = val);
}
}
}