You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Connected.Components/Components/Chart/Interpolation/SplineInterpolator.cs

84 lines
2.9 KiB

2 years ago
namespace Connected.Components;
public abstract class SplineInterpolator : ILineInterpolator
{
protected Matrix m;
protected MatrixSolver gauss;
protected readonly int n;
protected double[] a, b, c, d, h;
public double[] GivenYs { get; set; }
public double[] GivenXs { get; set; }
public double[] InterpolatedXs { get; set; }
public double[] InterpolatedYs { get; set; }
public bool InterpolationRequired { get; set; } = true;
public SplineInterpolator(double[] xs, double[] ys, int resolution = 10)
{
if (xs is null || ys is null)
throw new ArgumentException("xs and ys cannot be null");
if (xs.Length != ys.Length)
throw new ArgumentException("xs and ys must have the same length");
if (xs.Length < 4)
throw new ArgumentException("xs and ys must have a length of 4 or greater");
if (resolution < 1)
throw new ArgumentException("resolution must be 1 or greater");
GivenXs = xs;
GivenYs = ys;
n = xs.Length;
InterpolatedXs = new double[n * resolution];
InterpolatedYs = new double[n * resolution];
}
public void Interpolate()
{
int resolution = InterpolatedXs.Length / n;
for (int i = 0; i < h.Length; i++)
{
for (int k = 0; k < resolution; k++)
{
double deltaX = (double)k / resolution * h[i];
double termA = a[i];
double termB = b[i] * deltaX;
double termC = c[i] * deltaX * deltaX;
double termD = d[i] * deltaX * deltaX * deltaX;
int interpolatedIndex = i * resolution + k;
InterpolatedXs[interpolatedIndex] = deltaX + GivenXs[i];
InterpolatedYs[interpolatedIndex] = termA + termB + termC + termD;
}
}
// After interpolation the last several values of the interpolated arrays
// contain uninitialized data. This section identifies the values which are
// populated with values and copies just the useful data into new arrays.
int pointsToKeep = resolution * (n - 1) + 1;
double[] interpolatedXsCopy = new double[pointsToKeep];
double[] interpolatedYsCopy = new double[pointsToKeep];
Array.Copy(InterpolatedXs, 0, interpolatedXsCopy, 0, pointsToKeep - 1);
Array.Copy(InterpolatedYs, 0, interpolatedYsCopy, 0, pointsToKeep - 1);
InterpolatedXs = interpolatedXsCopy;
InterpolatedYs = interpolatedYsCopy;
InterpolatedXs[pointsToKeep - 1] = GivenXs[n - 1];
InterpolatedYs[pointsToKeep - 1] = GivenYs[n - 1];
}
public double Integrate()
{
double integral = 0;
for (int i = 0; i < h.Length; i++)
{
double termA = a[i] * h[i];
double termB = b[i] * Math.Pow(h[i], 2) / 2.0;
double termC = c[i] * Math.Pow(h[i], 3) / 3.0;
double termD = d[i] * Math.Pow(h[i], 4) / 4.0;
integral += termA + termB + termC + termD;
}
return integral;
}
}