using System;
namespace Legalsoft.Truffer
{
///
/// Abstract base class used by all interpolation routines in this chapter.
/// Only the routine interp is called directly by the user.
///
public abstract class Base_interp
{
public int n { get; set; }
public int mm { get; set; }
public int jsav { get; set; }
public int cor { get; set; }
public int dj { get; set; }
public double[] xx { get; set; }
public double[] yy { get; set; }
///
/// Set up for interpolating on a table of x's and y's of length m. Normally
/// called by a derived class, not by the user.
///
///
///
///
public Base_interp(double[] x, double y, int m)
{
this.n = x.Length;
this.mm = m;
this.jsav = 0;
this.cor = 0;
this.xx = x;
this.yy = new double[x.Length];
for (int i = 0; i < yy.Length; i++)
{
yy[i] = y;
}
dj = Math.Max(1, (int)Math.Pow((double)n, 0.25));
}
public double interp(double x)
{
int jlo = (cor != 0) ? hunt(x) : locate(x);
return rawinterp(jlo, x);
}
///
/// Given a value x, return a value j such that x is (insofar as possible)
/// centered in the subrange xx[j..j + mm - 1], where xx is the stored pointer.
/// The values in xx must be monotonic, either increasing or decreasing.
/// The returned value is not less than 0, nor greater than n-1.
///
///
///
///
public int locate(double x)
{
if (n < 2 || mm < 2 || mm > n)
{
throw new Exception("locate size error");
}
bool ascnd = (xx[n - 1] >= xx[0]);
int jl = 0;
int ju = n - 1;
while (ju - jl > 1)
{
int jm = (ju + jl) >> 1;
if (x >= xx[jm] == ascnd)
{
jl = jm;
}
else
{
ju = jm;
}
}
cor = Math.Abs(jl - jsav) > dj ? 0 : 1;
jsav = jl;
return Math.Max(0, Math.Min(n - mm, jl - ((mm - 2) >> 1)));
}
///
/// Given a value x, return a value j such that x is (insofar as possible)
/// centered in the subrange xx[j..j + mm - 1], where xx is the stored pointer.
/// The values in xx must be monotonic, either increasing or decreasing.
/// The returned value is not less than 0, nor greater than n-1.
///
///
///
///
public int hunt(double x)
{
int jl = jsav;
int inc = 1;
if (n < 2 || mm < 2 || mm > n)
{
throw new Exception("hunt size error");
}
bool ascnd = (xx[n - 1] >= xx[0]);
int ju;
if (jl < 0 || jl > n - 1)
{
jl = 0;
ju = n - 1;
}
else
{
if (x >= xx[jl] == ascnd)
{
for (; ; )
{
ju = jl + inc;
if (ju >= n - 1)
{
ju = n - 1;
break;
}
else if (x < xx[ju] == ascnd)
{
break;
}
else
{
jl = ju;
inc += inc;
}
}
}
else
{
ju = jl;
for (; ; )
{
jl = jl - inc;
if (jl <= 0)
{
jl = 0;
break;
}
else if (x >= xx[jl] == ascnd)
{
break;
}
else
{
ju = jl;
inc += inc;
}
}
}
}
while (ju - jl > 1)
{
int jm = (ju + jl) >> 1;
if (x >= xx[jm] == ascnd)
{
jl = jm;
}
else
{
ju = jm;
}
}
cor = Math.Abs(jl - jsav) > dj ? 0 : 1;
jsav = jl;
return Math.Max(0, Math.Min(n - mm, jl - ((mm - 2) >> 1)));
}
public abstract double rawinterp(int jlo, double x);
}
}
using System;
namespace Legalsoft.Truffer
{
///
/// Abstract base class used by all interpolation routines in this chapter.
/// Only the routine interp is called directly by the user.
///
public abstract class Base_interp
{
public int n { get; set; }
public int mm { get; set; }
public int jsav { get; set; }
public int cor { get; set; }
public int dj { get; set; }
public double[] xx { get; set; }
public double[] yy { get; set; }
///
/// Set up for interpolating on a table of x's and y's of length m. Normally
/// called by a derived class, not by the user.
///
///
///
///
public Base_interp(double[] x, double y, int m)
{
this.n = x.Length;
this.mm = m;
this.jsav = 0;
this.cor = 0;
this.xx = x;
this.yy = new double[x.Length];
for (int i = 0; i < yy.Length; i++)
{
yy[i] = y;
}
dj = Math.Max(1, (int)Math.Pow((double)n, 0.25));
}
public double interp(double x)
{
int jlo = (cor != 0) ? hunt(x) : locate(x);
return rawinterp(jlo, x);
}
///
/// Given a value x, return a value j such that x is (insofar as possible)
/// centered in the subrange xx[j..j + mm - 1], where xx is the stored pointer.
/// The values in xx must be monotonic, either increasing or decreasing.
/// The returned value is not less than 0, nor greater than n-1.
///
///
///
///
public int locate(double x)
{
if (n < 2 || mm < 2 || mm > n)
{
throw new Exception("locate size error");
}
bool ascnd = (xx[n - 1] >= xx[0]);
int jl = 0;
int ju = n - 1;
while (ju - jl > 1)
{
int jm = (ju + jl) >> 1;
if (x >= xx[jm] == ascnd)
{
jl = jm;
}
else
{
ju = jm;
}
}
cor = Math.Abs(jl - jsav) > dj ? 0 : 1;
jsav = jl;
return Math.Max(0, Math.Min(n - mm, jl - ((mm - 2) >> 1)));
}
///
/// Given a value x, return a value j such that x is (insofar as possible)
/// centered in the subrange xx[j..j + mm - 1], where xx is the stored pointer.
/// The values in xx must be monotonic, either increasing or decreasing.
/// The returned value is not less than 0, nor greater than n-1.
///
///
///
///
public int hunt(double x)
{
int jl = jsav;
int inc = 1;
if (n < 2 || mm < 2 || mm > n)
{
throw new Exception("hunt size error");
}
bool ascnd = (xx[n - 1] >= xx[0]);
int ju;
if (jl < 0 || jl > n - 1)
{
jl = 0;
ju = n - 1;
}
else
{
if (x >= xx[jl] == ascnd)
{
for (; ; )
{
ju = jl + inc;
if (ju >= n - 1)
{
ju = n - 1;
break;
}
else if (x < xx[ju] == ascnd)
{
break;
}
else
{
jl = ju;
inc += inc;
}
}
}
else
{
ju = jl;
for (; ; )
{
jl = jl - inc;
if (jl <= 0)
{
jl = 0;
break;
}
else if (x >= xx[jl] == ascnd)
{
break;
}
else
{
ju = jl;
inc += inc;
}
}
}
}
while (ju - jl > 1)
{
int jm = (ju + jl) >> 1;
if (x >= xx[jm] == ascnd)
{
jl = jm;
}
else
{
ju = jm;
}
}
cor = Math.Abs(jl - jsav) > dj ? 0 : 1;
jsav = jl;
return Math.Max(0, Math.Min(n - mm, jl - ((mm - 2) >> 1)));
}
public abstract double rawinterp(int jlo, double x);
}
}