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; } }