Document 10534340

advertisement
291194828
5/28/2016
The Lagrange Polynomial (Press
Chapter 3)
If we know a function at N distinct data
points and if we require that the polynomial
approximation pn(x) be equal to f(x) at all N points.
The N constants in the expansion
pN 1 ( x) 
i  N 1
 cx
i 0
i
i
(0.1)
are uniquely determined by the N equations
c0  c1 x1  c2 x12  c3 x13 
 cN 1 x1N 1  f1
c0  c1 x2  c2 x22  c3 x23 
 cN 1 x2N 1  f 2
c0  c1 x3  c2 x32  c3 x33 
 cN 1 x3N 1  f 3
c0  c1 x4  c2 x42  c3 x43 
 cN 1 x4N 1  f 4
(0.2)
1/3
N
N
k 1
k 1
pn ( x)   f k Lk  x    f  xk  Lk  x  (0.4)
Note
L  x 
pn ( x) N
(0.5)
  f  xk  k
x
x
k 1
This depends on x only through the Lk(x) terms. At
x = xk, the L’s are equal to zero except for the one
multiplying fk which is equal to 1. Thus pn(x) goes
through all of the data points and is explicitly of
order N-1.
Equation (0.4) is the solution to the problem
leading to (0.2). Note that (0.4) does not explicitly
give us the coefficients c0 through cN-1. This is a
drawback.
The coding for (0.5) and higher derivatives
along with a practical example is in
..\wsteve\FDERS\The Lagrange Polynomial.htm
...
c0  c1 xN  c2 xN2  c3 xN3 
 cN 1 xNN 1  f N
This implies that there is one and only one
polynomial of degree N-1 which passes through the
N data points, we can write the Lagrange
polynomial which accomplishes this almost by
inspection. The Lagrange polynomials are defined
with respect to x and the data abscissa xk and xj as
jN
Lk  x   
j 1
j k
 x  x
x  x 
j
j
k  1,
Coding the Lagrange Polynomial
A quotation from our text “It is not terribly
wrong to implement the Lagrange formula
straightforwardly, but it is not terribly right either”1
gives fair warning that a few extra computer steps
are involved in coding the above in directly and that
many people will say that it lacks elegance. It is
very easy and also easy to debug. In fortran
for/lagrange.for -- for\LAGRANGE.ZIP
, N (0.3)
k
One term is always left out of the product that
covers N values in which x always appears once.
Thus it is easy to see that Lk is a polynomial of
degree N-1 and that sums of the Lk values times
constants will also be of degree N-1.
The value of Lk(xmk) where xmk is any of
the data points other than the k’th one will have a
x  x 
zero in the numerator for the j=m term m m so
 xm  xk 
NL =
C***
C***
C***
that Lk(xmk)=0.
The value of Lk(xm=k) is quite different.
Each term in the product is of the form
 x j  xm   1 and by construction the dangerous
 x j  xk 
term with xj=xk has been left out so that Lk(xm=k)=1.
Thus the polynomial desired is
FUNCTION POLYL(NL,NDAT,X,XDAT,FDAT)
IMPLICIT REAL*8 (A-H,O-Z)
DIMENSION XDAT(*),FDAT(*)
DIMENSION ALAG(24)
IF(NL.GT.24)THEN
PRINT*,' FROM POLYL ALAG DIMENSION EXCEEDED
',NL
NL=24
READ(*,*)ITEST
ENDIF
CALL LOCATE(X,XDAT,NDAT,JB)
JB is such that XP(JB)<X<XP(JB+1)
MOVE BACK (NL-2)/2 IF POSSIBLE
MOVE BACK TO LEAVE NL+JB=NDAT
JB=MIN(JB,NDAT-NL)
JB=MAX(0,JB-1-(NL-2)/2)
CALL UELAG(NL,JB,X,ALAG,XDAT)
POLYL=0
DO I=1,NL
POLYL=POLYL+ALAG(I)*FDAT(I+JB)
ENDDO
RETURN
END
SUBROUTINE UELAG(NL,JB,X,ALAG,XDAT)
IMPLICIT REAL*8 (A-H,O-Z)
DIMENSION ALAG(NL),XDAT(*)
DO M=1,NL
1
Numerical Recipes in C, W.H. Press, S.A. Teukolsky, W.T.
Vetterling, B.P. Flannery, Cambridge, New York 1992 p. 108
291194828
5/28/2016
ALAG(M)=1.D0
DO J=1,NL
IF(J.NE.M)THEN
FACT=(X-XDAT(J+JB))/(XDAT(M+JB)XDAT(J+JB))
ALAG(M)=ALAG(M)*FACT
ENDIF
ENDDO
ENDDO
RETURN
END
cpp\CTLAG.ZIP
02/07/2005 16:20 CTLAG.WPJ
02/08/2005 05:08 TLAG.C
double laglo(double x)
{static int nc=0, ndat;
static double xp[137],dp[137];
FILE *fp;
if(nc == 0)
{nc=1;
fp = fopen("loren.out","r");
if(fp == NULL)
{printf(" cannot open file loren.out \n");
return 0.0;}
ndat=0;
redbeg:
if(fscanf(fp, "%lg %lg", &xp[ndat],&dp[ndat])!= EOF)
{/*printf("The line read was: %lg %g\n",
xp[ndat],dp[ndat]);*/
ndat = ndat+1;
if(ndat <= 137) goto redbeg;
else
{printf(" from laglo ndat > 137, enter to continue ");
scanf(" \n");}}
fclose(fp);
ndat=ndat-1;}
return bpolyl(4,ndat,x,xp,dp);}
void main(void)
{double xi[502],fi[502],err[502];
int np=500,ndo=2,i,ibli,itest;
/* double x,test;
double x=1.99,test; */
FILE *fp;
/* test=laglo(x);
printf(" x, TEST =%lg %lg \n",x,test);
return; */
fp=fopen("blic.out","w");
if(fp ==NULL){printf(" cannot open bli.out file\n");
scanf(" %d ",&itest);
return;}
printf(" enter the beginning and ending x values \n");
scanf(" %lg %lg",&xi[0],&xi[1]);
printf(" xi[0] %lg xi[1] %lg \n",xi[0],xi[1]);
/* for(i=0;i<=np;i++)
{x=-4+i*(xi[1]-xi[0])/np;
test=laglo(x);
fprintf(fp,"%14.6lg %14.6lg\n",x,test);} */
2/3
ibli=bli(xi,fi,err,np,ndo,laglo);
/* printf(" after bli xi[0] = %lg \n",xi[0]); */
for(i=0;i<=ibli;i++)fprintf(fp,"%14.6lg %14.6lg\n",xi[i],fi[i]);
fclose(fp);
return;}
02/08/2005 05:08 BLI.C  tbli.c in cpp\cbli.zip
04/19/2003 20:13 LOCATE.C
02/08/2005 05:00 LAGRANGE.C
#include <stdio.h>
int locate(double x,double r[],int n);
void uelag(int nl,int jb,double x,double alag[],double xdat[])
{int m,j;
double fact;
for (m = 0; m < nl; ++m)
{alag[m] = 1.;
for (j = 0; j < nl; ++j)
{if (j != m)
{fact = (x - xdat[j+jb]) / (xdat[m+jb] - xdat[j+jb]);
/* printf(" from uelag fact = %lg \n",fact); */
alag[m] = alag[m] * fact;}}}
return;}
double bpolyl(int nl,int ndat,double x,double xdat[],double
fdat[])
{int i,jb;
double ret_val;
double alag[24];
if(nl > 24)
{printf(" from polyl alag dimension exceeded nl = %d
\n",nl);
nl = 24;
scanf(" \n");}
jb = locate(x,xdat,ndat);
if(jb > ndat - nl)jb = ndat - nl;
jb=jb-(nl-2)/2;
if(jb < -1 ) jb = -1;
uelag(nl,jb,x,alag,xdat);
ret_val = 0.;
for (i = 0; i < nl; ++i)
{ret_val += alag[i] * fdat[i+jb];}
return ret_val;}
01/31/2005 15:12 LOREN.OUT
02/07/2005 16:20 CTLAG.TGT
291194828
5/28/2016
The one change from defaults is to switch from full
debugging information to line number information.
#include <stdio.h>
#include <math.h>
These are needed for all files in Watcom, not for
most other compilers.
double bpolyl(int nl,int ndat,double x,double xdat[],double
fdat[]);
int bli(double xi[],double fi[],double err[],int np,
int ndo, double (*fext)(double));
/* #include "d:\cpp\bli.c"  see tbli.c in
cpp\cbli.zip
#include "d:\cpp\lagrange.c"
#include "d:\cpp\locate.c" */
These are commented out here, they are needed
for other compilers.
Derivatives
See ..\Derivatives\Lagrange.docx
Code that gives interpolated value and its derivative
is in uelagwd.zip.
3/3
Download