Числа один раз вычисляются и подставляются в код. Это же интерполяция, тут не существует возможности получить точное значение “с помощью карандаша и бумаги” за исключением случаев, когда исходная функция является полиномом степени не выше 3. Отсюда и “эпсилон”, появившейся при аппроксимации сплайном полинома пятой степени и колебательной функции.
Я посчитал, что обычные массивы начинающим могут быть более понятны, чем массив из кортежа, да и получить их проще. Вспомнил, что в при работе с графикой, например в полилинии, получать массив точек не всегда удобно.
И еще, поскольку библиотека будет содержать множество программ, часть из них будут использовать не только координаты точек и были мысли о некотором единообразии данных, посему также победили массивы.
Мы могли бы работать с понятием точки, если бы Вы ввели в ядро такой примитив и дали набор функций для манипулирования точками.
Сделал тест покомпактнее.
uses StudLib;
procedure TestSpline(x:real; F:real->real; S:Spline);
begin
var r1:=F(x);
var r2:=S.Value(x);
Assert(r1=r2,'Ожидалось '+r1+', получено '+r2);
end;
procedure TestSpline(x,y,eps:real; S:Spline);
begin
var r:=S.Value(x);
Assert(Abs(r-y)<=eps,'Ожидалось '+y+', получено '+r);
end;
begin
var n:=10;
var x:=ArrGen(n,i->real(i+1));
var y:=ArrGen(n,i->sqr(x[i])*x[i]);
var Sp:=new Spline(x,y); // создаем сплайн с заданными узлами интерполяции.
TestSpline(1,x->x*x*x,Sp); // левая точка
TestSpline(2.5,x->x*x*x,Sp); // внутри
TestSpline(10,x->x*x*x,Sp); // правая точка
//
y:=ArrGen(n,i->Power(x[i],5));
Sp:=new Spline(x,y);
TestSpline(1,1,real.Epsilon,Sp);
TestSpline(2.5,96.2230762150221,real.Epsilon,Sp);
TestSpline(10,94936.1745213549,1e-10,Sp);
//
y:=ArrGen(n,i->(3*Power(x[i],-4)-7*x[i])*sin(x[i]/0.7));
Sp:=new Spline(x,y);
TestSpline(1,-3.9596123054885,1e-14,Sp);
TestSpline(2.5,8.18890114377246,1e-14,Sp);
TestSpline(10,-579.522280926788,1e-12,Sp);
//
Writeln('Проверка завершена')
end.