Summary
uses StudLib;
procedure TestSpline(x:real; F:real->real; eps:real; S:Spline);
// eps - абсолютная погрешность в процентах
begin
  var r1:=F(x);
  var r2:=S.Value(x);
  var Msg:='F('+x+')='+r1+', получено '+r2;
  Assert(Abs((r1-r2)/r1)<=eps/100,Msg);
end;
procedure TestZeroin(s:string; a,b:real; F:real->real; root,eps:real);
// root - точное значение корня
// eps - относительная погрешность значения корня
begin
  var x:=Zeroin(a,b,F,eps);
  var Msg:=s+': корень: '+x+', ожидалось '+root;
  Assert(Abs(x-root)<=eps,Msg);
end;
begin
  
  var f:real->real:=x->x*x*x;
  var pp:=Partition(1.0,10.0,9).Select(x->new Point(x,f(x))).ToArray;
  var Sp:=new Spline(pp); // создаем сплайн с заданными узлами интерполяции.
  TestSpline(1,f,1e-15,Sp); // левая точка
  TestSpline(1.25,f,1e-15,Sp); // внутри
  TestSpline(2.5,f,1e-15,Sp); // внутри
  TestSpline(7.2,f,1e-15,Sp); // внутри
  TestSpline(10,f,1e-5,Sp); // правая точка
  //
  f:=x->Power(x,4);
  pp:=Partition(1.0,10.0,9).Select(x->new Point(x,f(x))).ToArray;
  Sp:=new Spline(pp);
  TestSpline(1.28,f,32,Sp); // 32% у края... надо исходный шаг мельче
  TestSpline(2.5,f,0.8,Sp); // 0.8%
  TestSpline(5.1,f,0.005,Sp); // 0.005%
  TestSpline(9.7,f,0.01,Sp); // 0.01%
  //
  pp:=Partition(1.0,10.0,36).Select(x->new Point(x,f(x))).ToArray;
  Sp:=new Spline(pp);
  TestSpline(1.28,f,0.03,Sp); // 0.03%
  TestSpline(1.1,f,0.24,Sp); // 0.24%
  TestSpline(1.03,f,0.18,Sp); // 0.18%
  //
  f:=x->(3*x-8)/(8*x-4.1);
  pp:=Partition(1.0,10.0,18).Select(x->new Point(x,f(x))).ToArray;
  Sp:=new Spline(pp);
  TestSpline(1.1,f,4.8,Sp); // 4.8%
  TestSpline(2.6,f,5.8,Sp); // 5.8%
  TestSpline(5.9,f,0.001,Sp); // <0.001%
  TestSpline(9.9,f,0.001,Sp); // <0.001% 
  //
  Writeln('Проверка Spline завершена');
  //
  f:=x->x*(x*x-2)-5; // классика
  // Точное решeние по формуле Кардано 2.094551481542326591482386540579...
  var root:=(Power(5+Sqrt(643/27),1/3)+Power(5-Sqrt(643/27),1/3))/Power(2,1/3);
  TestZeroin('Zeroin1',2,3,f,root,1e-15);
  //
  f:=x->Power((12-2*x)/(x-1),1/3)+Power((x-1)/(12-2*x),1/3)-2.5;
  root:=2;
  TestZeroin('Zeroin2',1.01,3.5,f,root,1e-15); // разрыв при х=1
  //
  root:=97/17;
  TestZeroin('Zeroin3',3,5.99,f,root,1e-15); // разрыв при х=6
  //
  f:=x->3*Sin(x)+4*Cos(x)-5;
  root:=2*ArcTan(1/3);
  TestZeroin('Zeroin4',-1,1,f,root,1e-8);
  //
  Writeln('Проверка Zeroin завершена')
  //
end.