Thiele's interpolation formula

From Rosetta Code
Revision as of 07:38, 2 October 2010 by rosettacode>NevilleDNZ (foundation page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Task
Thiele's interpolation formula
You are encouraged to solve this task according to the task description, using any language you may know.
This page uses content from Wikipedia. The original article was at Thiele's_interpolation_formula. The list of authors can be seen in the page history. As with Rosetta Code, the text of Wikipedia is available under the GNU FDL. (See links for details on variance)

In mathematics, Thiele's interpolation formula is an interpolation formula for a function f(•) of a single variable, due to the Danish mathematician Thorvald Nicolai Thiele. It is expressed as a continued fraction, where ρ represents the reciprocal difference:

Demonstrate Thiele's interpolation function by:

  1. Building a trig table of values of the trig function sin, cos and tan for x from 0 to 1.55;
  2. Using columns from this table - define an inverse for each trig function;
  3. Finally: demonstrate the following well known trigonometric identities:
    • 6 × sin-1 ½ = π
    • 3 × cos-1 ½ = π
    • 4 × tan-1 1 = π

ALGOL 68

Works with: ALGOL 68 version Revision 1 - except the Currying (aka partial parametrisation) in test block is a proposal for ALGOL 68 Rev2
Works with: ALGOL 68G version Any - tested with release 1.18.0-9h.tiny - Currying is supported.

<lang algol68>PROC raise exception = ([]STRING msg)VOID: ( putf(stand error,("Exception:", $" "g$, msg, $l$)); stop );

  1. The MODE of lx and ly here should really be a UNION of "something REAL",

"something COMPLex", and "something SYMBOLIC" ... #

PROC thiele=([]REAL lx,ly, REAL x) REAL: BEGIN

 []REAL xx=lx[@1],yy=ly[@1];
 INT n=UPB xx;
 IF UPB yy=n THEN
  1. Assuming that the values of xx are distinct ... #
   [0:n-1,1:n]REAL p;
   p[0,]:=yy[];
   FOR i TO n-1 DO p[1,i]:=(xx[i]-xx[1+i])/(p[0,i]-p[0,1+i]) OD;
   FOR i FROM 2 TO n-1 DO
     FOR j TO n-i DO
       p[i,j]:=(xx[j]-xx[j+i])/(p[i-1,j]-p[i-1,j+1])+p[i-2,j+1]
     OD
   OD;
   REAL a:=0;
   FOR i FROM n-1 BY -1 TO 2 DO a:=(x-xx[i])/(p[i,1]-p[i-2,1]+a) OD;
   yy[1]+(x-xx[1])/(p[1,1]+a)
 ELSE
   raise exception(("Unequal length arrays supplied: ",whole(UPB xx,0)," NE ",whole(UPB yy,0))); SKIP
 FI

END;

test:(

 FORMAT real fmt = $g(0,real width-2)$;
 REAL lwb x=0, upb x=1.55, delta x = 0.05; 
 [0:ENTIER ((upb x-lwb x)/delta x)]STRUCT(REAL x, sin x, cos x, tan x) trig table;
 PROC init trig table = VOID: 
   FOR i FROM LWB trig table TO UPB trig table DO 
     REAL x = lwb x+i*delta x; 
     trig table[i]:=(x, sin(x), cos(x), tan(x))
   OD;
 init trig table;
  1. Curry the thiele function to create matching inverse trigonometric functions #
 PROC (REAL)REAL inv sin = thiele(sin x OF trig table, x OF trig table,),
                 inv cos = thiele(cos x OF trig table, x OF trig table,),
                 inv tan = thiele(tan x OF trig table, x OF trig table,);
 printf(($"pi estimate using "g" interpolation: "f(real fmt)l$, 
   "sin", 6*inv sin(1/2),
   "cos", 3*inv cos(1/2),
   "tan", 4*inv tan(1)
 ))

)</lang> Output:

pi estimate using sin interpolation: 3.1415926535898
pi estimate using cos interpolation: 3.1415926535898
pi estimate using tan interpolation: 3.1415926535898