"""Original finite sampled trapezoids; exact paired-grid contract."""
from fractions import Fraction as F
import numpy as np
import json,math
def area(xs,ys):
 if type(xs) is not list or type(ys) is not list or not 2<=len(xs)<=16 or len(xs)!=len(ys) or any(type(z) not in [int,F] or abs(z)>100 for z in xs+ys):raise ValueError('equal bounded exact sequences length2..16')
 x=list(map(F,xs));y=list(map(F,ys));parts=[(x[i+1]-x[i])*(y[i]+y[i+1])/2 for i in range(len(x)-1)]
 return sum(parts,F(0)),parts
def demo():
 rows=[]
 for n in [2,4]:
  x=[F(i,n) for i in range(n+1)];y=[v*v for v in x];v,parts=area(x,y);actual=float(np.trapezoid([float(z) for z in y],x=[float(z) for z in x]));assert abs(actual-float(v))<1e-12
  rows.append({'subintervals':n,'x':[str(z) for z in x],'y':[str(z) for z in y],'signed_parts':[str(z) for z in parts],'exact_trapezoid':str(v),'actual_numpy_trapezoid':actual,'analytic_integral':str(F(1,3)),'error_exact':str(v-F(1,3))})
 assert rows[0]['exact_trapezoid']=='3/8' and rows[1]['exact_trapezoid']=='11/32'
 samples=[([F(0),F(1,4),F(1)],[F(0),F(1,16),F(1)]),([F(0),F(1),F(1,2)],[F(0),F(1),F(1,4)]),([F(1),F(1,2),F(0)],[F(1),F(1,4),F(0)])]
 extra=[]
 for x,y in samples:
  a,p=area(x,y);back,_=area(list(reversed(x)),list(reversed(y)));assert back==-a
  # Independent integrate each connecting line y=m*x+c analytically.
  independent=F(0)
  for i in range(len(x)-1):
   if x[i+1]==x[i]:continue
   m=(y[i+1]-y[i])/(x[i+1]-x[i]);c=y[i]-m*x[i];independent+=m*(x[i+1]**2-x[i]**2)/2+c*(x[i+1]-x[i])
  assert independent==a
  actual=float(np.trapezoid([float(z) for z in y],x=[float(z) for z in x]));assert abs(actual-float(a))<1e-12
  extra.append({'x':[str(z) for z in x],'y':[str(z) for z in y],'parts':[str(z) for z in p],'area':str(a),'reversed_pairs_area':str(back),'line_antiderivative_oracle_equal':True,'numpy':actual})
 rejected=[]
 for x,y in [([],[]),([0,1],[0]),([0,True],[0,1]),([0,float('nan')],[0,1])]:
  try:area(x,y)
  except ValueError:rejected.append([repr(x),repr(y)])
  else:raise AssertionError('expected rejection')
 return {'numpy_version':np.__version__,'quadratic_uniform_grids':rows,'nonuniform_unsorted_reversed_cases':extra,'order_contract':'paired x/y sequence retained, no hidden sorting; signed integration along path','units':'x units times y units','rejected':rejected,'scope':'piecewise-linear approximation of sampled data, not exact integral of unknown function or ROC curve'}
if __name__=='__main__':print(json.dumps(demo(),ensure_ascii=True,indent=2))
