123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112# 1 "src/base/maths/owl_maths_interpolate.ml"(*
* OWL - OCaml Scientific and Engineering Computing
* Copyright (c) 2016-2020 Liang Wang <liang.wang@cl.cam.ac.uk>
*)(** Interpolation and Extrapolation *)letpolintxsysx=letn=Array.lengthxsinletm=Array.lengthysinleterror()=lets=Printf.sprintf"polint requires that xs and ys have the same length, but xs length is %i \
whereas ys length is %i"nminOwl_exception.INVALID_ARGUMENTsinOwl_exception.verify(m=n)error;letc=Array.copyysinletd=Array.copyysinletns=ref0inletdy=ref0.inletdif=ref(abs_float(x-.xs.(0)))infori=0ton-1doletdift=abs_float(x-.xs.(i))inifdift<!difthen(ns:=i;dif:=dift)done;lety=refys.(!ns)inns:=!ns-1;form=0ton-2dofori=0ton-m-2doletho=xs.(i)-.xinlethp=xs.(i+m+1)-.xinletw=c.(i+1)-.d.(i)inletden=ho-.hpinassert(den<>0.);letden=w/.deninc.(i)<-ho*.den;d.(i)<-hp*.dendone;if(2*!ns)+2<n-m-1thendy:=c.(!ns+1)else(dy:=d.(!ns);ns:=!ns-1);y:=!y+.!dydone;!y,!dy(* TODO: not tested yet *)letratintxsysx=letn=Array.lengthxsinletm=Array.lengthysinleterror()=lets=Printf.sprintf"ratint requires that xs and ys have the same length, but xs length is %i \
whereas ys length is %i"nminOwl_exception.INVALID_ARGUMENTsinOwl_exception.verify(m=n)error;letc=Array.copyysinletd=Array.copyysinlethh=ref(abs_float(x-.xs.(0)))inlety=ref0.inletdy=ref0.inletns=ref0inleteps=1e-25intryfori=0tondoleth=abs_float(x-.xs.(i))inifh=0.then(y:=ys.(i);dy:=0.;raiseOwl_exception.FOUND)elseifh<!hhthen(ns:=i;hh:=h;c.(i)<-ys.(i);d.(i)<-ys.(i)+.eps)done;y:=ys.(!ns);ns:=!ns-1;form=1ton-1dofori=1ton-mdoletw=c.(i)-.d.(i-1)inleth=xs.(i+m-1)-.xinlett=(xs.(i-1)-.x)*.d.(i-1)/.hinletdd=t-.c.(i)inifdd=0.thenfailwith"Has a pole";letdd=w/.ddind.(i-1)<-c.(i)*.dd;c.(i-1)<-t*.dddonedone;!y,!dywith|Owl_exception.FOUND->!y,!dy|e->raisee