Professional Documents
Culture Documents
Algebraic Evaluations
All procedures in this chapter are class methods of the following Algebraic_eval
class.
package numal;
import numal.*;
A. pol
Procedure parameters:
double pol (n,x,a)
pol: given the value of p(x) above;
n: int; the degree of the polynomial;
x: double; the argument of the polynomial;
a: double a[0:n];
entry: the coefficients of the polynomial.
r=0.0;
for (; n>=0; n--) r=r*x+a[n];
return (r);
}
Procedure parameters:
void taypol (n,k,x,a)
n: int; the degree of the polynomial;
k: int; the first k terms of the above are to be calculated;
x: double; the argument of the polynomial;
a: double a[0:n];
entry: the coefficients of the polynomial;
exit: the j-th term xj*(j-th derivative)/j! is delivered in a[j], j=0,1,...,k≤n,
the other elements of a are generally altered.
if (x != 0.0) {
xj=1;
for (j=1; j<=n; j++) {
xj *= x;
a[j] *= xj;
}
aa=a[n];
nm1=n-1;
for (j=0; j<=k; j++) {
h=aa;
for (i=nm1; i>=j; i--) h = a[i] += h;
}
} else {
for (; k>=1; n--) a[k]=0;
}
}
Procedure parameters:
void norderpol (n,k,x,a)
n: int; the degree of the polynomial;
k: int; the first k normalized derivatives (j-th derivative / j factorial) are to be
calculated;
x: double; the argument of the polynomial;
a: double a[0:n];
entry: the coefficients of the polynomial;
exit: the j-th normalized derivative is delivered in a[j], j=0,1,...,k≤n, the
other elements of a are generally altered.
if (x != 0.0) {
double xx[] = new double[n+1];
xj=1;
for (j=1; j<=n; j++) {
xx[j] = xj *= x;
a[j] *= xj;
}
h=aa=a[n];
nm1=n-1;
for (i=nm1; i>=0; i--) h = a[i] += h;
for (j=1; j<=k; j++) {
h=aa;
for (i=nm1; i>=j; i--) h = a[i] += h;
a[j]=h/xx[j];
}
}
}
D. derpol
Procedure parameters:
void derpol (n,k,x,a)
n: int; the degree of the polynomial;
k: int; the first k derivatives are to be calculated;
x: double; the argument of the polynomial;
a: double a[0:n];
entry: the coefficients of the polynomial;
exit: the j-th derivative is delivered in a[j], j=0,1,...,k≤n, the other
elements of a are generally altered.
fac=1.0;
norderpol(n,k,x,a);
for (j=2; j<=k; j++) {
fac *= j;
a[j] *=fac;
}
}
A. ortpol
Procedure parameters:
if (n == 0) return (1.0);
r=x-b[0];
s=1.0;
l=n-1;
for (k=1; k<=l; k++) {
h=r;
r=(x-b[k])*r-c[k]*s;
s=h;
}
return (r);
}
B. ortpolsym
Procedure parameters:
double ortpolsym (n,x,c)
ortpolsym: given the value of the orthogonal polynomial in the above;
n: int; the degree of the polynomial;
x: double; the argument of the orthogonal polynomial;
c: double c[1:n-1];
entry: the recurrence coefficients of the polynomial.
if (n == 0) return (1.0);
r=x;
s=1.0;
l=n-1;
C. allortpol
Procedure parameters:
void allortpol (n,x,b,c,p)
n: int; the degree of the polynomial;
x: double; the argument of the orthogonal polynomial;
b,c: double b[0:n-1], c[1:n-1];
entry: the recurrence coefficients of the polynomial;
p: double p[0:n];
exit: p[k] contains, for the argument, the value of the k-th orthogonal
polynomial as defined by the recurrence coefficients.
public static void allortpol(int n, double x, double b[], double c[], double p[])
{
int k,k1;
double r,s,h;
if (n == 0) {
p[0]=1.0;
return;
}
r=p[1]=x-b[0];
s=p[0]=1.0;
k=1;
for (k1=2; k1<=n; k1++) {
h=r;
p[k1]=r=(x-b[k])*r-c[k]*s;
s=h;
k=k1;
}
}
Given the ck and x, evaluates the sequence of polynomials pk(x) for k=0,...,n, where
p0(x) = 1, p1(x) = x,
pk+1(x) = xpk(x) - ckpk-1(x), k=1,...,n-1.
Procedure parameters:
void allortpolsym (n,x,c,p)
n: int; the degree of the polynomial;
x: double; the argument of the orthogonal polynomial;
c: double c[1:n-1];
entry: the recurrence coefficients of the polynomial;
p: double p[0:n];
exit: p[k] contains, for the argument, the value of the k-th orthogonal
polynomial as defined by the recurrence coefficients.
if (n == 0) {
p[0]=1.0;
return;
}
r=p[1]=x;
s=p[0]=1.0;
for (k=2; k<=n; k++) {
h=r;
p[k]=r=x*r-c[k-1]*s;
s=h;
}
}
E. sumortpol
Procedure parameters:
double sumortpol (n,x,b,c,a)
sumortpol: given the value of the sum s in the above;
public static double sumortpol(int n, double x, double b[], double c[], double a[])
{
int k;
double h,r,s;
if (n == 0) return (a[0]);
r=a[n];
s=0.0;
for (k=n-1; k>=1; k--) {
h=r;
r=a[k]+(x-b[k])*r+s;
s = -c[k]*h;
}
return (a[0]+(x-b[0])*r+s);
}
F. sumortpolsym
Procedure parameters:
double sumortpolsym (n,x,c,a)
sumortpolsym: given the value of the sum s in the above;
n: int; the degree of the polynomial;
x: double; the argument of the orthogonal polynomial;
c: double c[1:n-1];
entry: the recurrence coefficients of the polynomial;
a: double a[0:n];
entry: the values of ak in the above.
A. chepolsum
Procedure parameters:
double chepolsum (n,x,a)
chepolsum: given the value of the Chebyshev sum S in the above;
n: int; the degree of the polynomial represented by the Chebyshev sum,
n≥0;
x: double; the argument of the Chebyshev polynomials, x≤1;
a: double a[0:n];
entry: a[k] is the coefficient of the Chebyshev polynomial of degree k,
0≤k≤n.
if (n == 0) return (a[0]);
if (n == 1) return (a[0]+a[1]*x);
B. oddchepolsum
Given the ai and x, uses the Clenshaw or generalized Horner algorithm [Cle62] to
evaluate a sum of Chebyshev polynomials of odd degree
n
S = ∑ ai T2i +1 ( x) ;
i=0
the Ti being Chebyshev polynomials.
Procedure parameters:
double oddchepolsum (n,x,a)
oddchepolsum: given the value of the Chebyshev sum S in the above;
n: int; the degree of the polynomial represented by the Chebyshev
sum is 2n+1, n≥0;
x: double; the argument of the Chebyshev polynomials, x≤1;
a: double a[0:n];
entry: a[k] is the coefficient of the Chebyshev polynomial of
degree 2k+1, 0≤k≤n.
if (n == 0) return (x*a[0]);
if (n == 1) return (x*(a[0]+a[1]*(4.0*x*x-3.0)));
y=4.0*x*x-2.0;
r=a[n];
h=a[n-1]+r*y;
for (k=n-2; k>=0; k--) {
s=r;
r=h;
h=a[k]+r*y-s;
}
return (x*(h-r));
}
Computes the value of the Chebyshev polynomial Tn(x) by use of the recursion
[St72]
T0(x) = 1, T1(x) = x,
Ti(x) = 2xTi-1(x) - Ti-2(x), i=2,...,n.
Procedure parameters:
double chepol (n,x)
chepol: given the value of the Chebyshev polynomial of the first kind, Tn(x)
above;
n: int; the degree of the polynomial, n≥0;
x: double; the argument of the Chebyshev polynomial, x≤1.
if (n == 0) return (1.0);
if (n == 1) return (x);
t2=x;
t1=1.0;
x2=x+x;
h=0.0;
for (i=2; i<=n; i++) {
h=x2*t2-t1;
t1=t2;
t2=h;;
}
return (h);
}
D. allchepol
Computes the values of the Chebyshev polynomials Ti(x), i=1,...,n, by use of the
recursion [St72]
T0(x) = 1, T1(x) = x,
Ti(x) = 2xTi-1(x) - Ti-2(x), i=2,...,n.
Procedure parameters:
void allchepol (n,x,t)
n: int; the degree of the last polynomial, n≥0;
x: double; the argument of the Chebyshev polynomials, x≤1;
t: double t[0:n];
exit: the value of the Chebyshev polynomial of the first kind of degree k,
for the argument x, is delivered in t[k], k=0,...,n.
if (n == 0) {
t[0]=1.0;
return;
}
if (n == 1) {
t[0]=1.0;
t[1]=x;
return;
}
t[0]=t1=1.0;
t[1]=t2=x;
x2=x+x;
for (i=2; i<=n; i++) {
t[i]=h=x2*t2-t1;
t1=t2;
t2=h;;
}
}
A. sinser
c=Math.cos(theta);
if (c < -0.5) {
temp=Math.cos(theta/2.0);
lambda=4.0*temp*temp;
un=dun=0.0;
for (k=n; k>=1; k--) {
dun=lambda*un-dun+b[k];
un=dun-un;
}
} else {
if (c > 0.5) {
temp=Math.sin(theta/2.0);
lambda = -4.0*temp*temp;
un=dun=0.0;
for (k=n; k>=1; k--) {
dun += lambda*un+b[k];
un += dun;
}
} else {
cc=c+c;
un=un1=0.0;
for (k=n; k>=1; k--) {
h=cc*un-un1+b[k];
un1=un;
un=h;
}
}
}
return (un*Math.sin(theta));
}
Procedure parameters:
double cosser (n,theta,a)
cosser: given the value of the cosine series, value of s above;
n: int;
entry: the degree of the trigonometric polynomial;
theta: double;
entry: the argument of the cosine series;
a: double a[0:n];
entry: the coefficients of the cosine series.
c=Math.cos(theta);
if (c < -0.5) {
temp=Math.cos(theta/2.0);
lambda=4.0*temp*temp;
un=dun=0.0;
for (k=n; k>=0; k--) {
un=dun-un;
dun=lambda*un-dun+a[k];
}
return (dun-lambda/2.0*un);
} else {
if (c > 0.5) {
temp=Math.sin(theta/2.0);
lambda = -4.0*temp*temp;
un=dun=0.0;
for (k=n; k>=0; k--) {
un += dun;
dun += lambda*un+a[k];
}
return (dun-lambda/2.0*un);
} else {
cc=c+c;
C. fouser
Procedure parameters:
double fouser (n,theta,a)
fouser: given the value of the fourier series, value of s above;
n: int;
entry: the degree of the trigonometric polynomial;
theta: double;
entry: the argument of the fourier series;
a: double a[0:n];
entry: the coefficients of the (finite) fourier series.
c=Math.cos(theta);
if (c < -0.5) {
c2=Math.cos(theta/2.0);
lambda=4.0*c2*c2;
un=dun=0.0;
for (k=n; k>=0; k--) {
un=dun-un;
dun=lambda*un-dun+a[k];
}
return (dun+2.0*c2*(Math.sin(theta/2.0)-c2)*un);
} else {
if (c > 0.5) {
D. fouser1
Procedure parameters:
double fouser1 (n,theta,a,b)
fouser1: given the value of the fourier series, value of s above;
n: int;
entry: the degree of the trigonometric polynomial;
theta: double;
entry: the argument of the fourier series;
a,b: double a[0:n], b[1:n];
entry: the coefficients of the (finite) fourier series,
with ak coefficient of cos(k*θ), k=0,...,n,
and bk coefficient of sin(k*θ), k=1,...,n.
public static double fouser1(int n, double theta, double a[], double b[])
{
int i;
double r,s,h,co,si;
E. fouser2
Procedure parameters:
double fouser2 (n,theta,a,b)
fouser2: given the value of the fourier series, value of s above;
n: int;
entry: the degree of the trigonometric polynomial;
theta: double;
entry: the argument of the fourier series;
a,b: double a[0:n], b[1:n];
entry: the coefficients of the (finite) fourier series,
with ak coefficient of cos(k*θ), k=0,...,n,
and bk coefficient of sin(k*θ), k=1,...,n.
public static double fouser2(int n, double theta, double a[], double b[])
{
return (cosser(n,theta,a)+sinser(n,theta,b));
}
F. comfouser
Procedure parameters:
void comfouser (n,theta,a,rr,ri)
n: int;
entry: the degree of the polynomial in eiθ;
theta: double;
entry: the argument of the fourier series;
a: double a[0:n];
entry: the real coefficients in the series;
rr,ri: double rr[0:0], ri[0:0];
exit: the real part and the imaginary part of s above are delivered in rr[0]
and ri[0], respectively.
public static void comfouser(int n, double theta, double a[], double rr[],
double ri[])
{
int k;
double c,cc,lambda,h,dun,un,un1,temp;
c=Math.cos(theta);
if (c < -0.5) {
temp=Math.cos(theta/2.0);
lambda=4.0*temp*temp;
un=dun=0.0;
for (k=n; k>=0; k--) {
un=dun-un;
dun=lambda*un-dun+a[k];
}
rr[0]=dun-lambda/2.0*un;
} else {
if (c > 0.5) {
temp=Math.sin(theta/2.0);
lambda = -4.0*temp*temp;
un=dun=0.0;
for (k=n; k>=0; k--) {
un += dun;
dun += lambda*un+a[k];
}
rr[0]=dun-lambda/2.0*un;
} else {
cc=c+c;
un=un1=0.0;
for (k=n; k>=1; k--) {
h=cc*un-un1+a[k];
un1=un;
G. comfouser1
Procedure parameters:
void comfouser1 (n,theta,ar,ai,rr,ri)
n: int;
entry: the degree of the polynomial in eiθ;
theta: double;
entry: the argument of the fourier series;
ar,ai: double ar[0:n], ai[0:n];
entry: the real part and the imaginary part of the complex coefficients in
the series must be given in arrays ar and ai, respectively;
rr,ri: double rr[0:0], ri[0:0];
exit: the real part and the imaginary part of s above are delivered in rr[0]
and ri[0], respectively.
public static void comfouser1(int n, double theta, double ar[], double ai[],
double rr[], double ri[])
{
int k;
double h,hr,hi,co,si;
hr=hi=0.0;
co=Math.cos(theta);
si=Math.sin(theta);
for (k=n; k>=1; k--) {
h=co*hr-si*hi+ar[k];
hi=co*hi+si*hr+ai[k];
hr=h;
}
rr[0]=co*hr-si*hi+ar[0];
ri[0]=co*hi+si*hr+ai[0];
}
Procedure parameters:
void comfouser2 (n,theta,ar,ai,rr,ri)
n: int;
entry: the degree of the polynomial in eiθ;
theta: double;
entry: the argument of the fourier series;
ar,ai: double ar[0:n], ai[0:n];
entry: the real part and the imaginary part of the complex coefficients in
the series must be given in arrays ar and ai, respectively;
rr,ri: double rr[0:0], ri[0:0];
exit: the real part and the imaginary part of s above are delivered in rr[0]
and ri[0], respectively.
Remark: For the evaluation of a finite fourier series two algorithms are used:
(a) the Horner scheme in the procedure fouser1, and (b) a combination of
the Clenshaw algorithm [Ge69, Lu69, St72] and the modification of
Reinsch [Re67, St72] in the procedures sinser, cosser, fouser, and
fouser2. A modification of the idea of Newbery is not implemented
because of the introduction of sine (cosine) terms in a cosine (sine) series
and the inefficiency of the algorithm [N73]. For the evaluation of a finite
complex fourier series, two algorithms, in real arithmetic, are used:
(a) the Horner scheme in the procedure comfouser1, and (b) a
combination of the Clenshaw algorithm and the modification of Reinsch
in procedures comfouser and comfouser2. The Horner scheme is
implemented because of the simplicity of the algorithm (although this
algorithm is less efficient than the Goertzel-Watt-Clenshaw-Reinsch
algorithm) and the stable nature of orthogonal transformations. A
combination of the algorithm of Goertzel-Watt-Clensaw and the
modification of Reinsch is implemented because of the efficiency of the
Goertzel-Watt-Clensaw algorithm and the stability of the modification of
Reinsch, especially for small values of the argument. An upper bound for
the error growth is given by a linear function of the degree for both
implemented algorithms.
public static void comfouser2(int n, double theta, double ar[], double ai[],
double rr[], double ri[])
{
double car[] = new double[1];
comfouser(n,theta,ar,car,sar);
comfouser(n,theta,ai,cai,sai);
rr[0]=car[0]-sai[0];
ri[0]=cai[0]+sar[0];
}
jfrac
Procedure parameters:
double jfrac (n,a,b)
jfrac: delivers the value of the terminating continued fraction, the value of Cn
above;
n: int; the upper index of the arrays a and b;
a,b: double a[1:n],b[0:n]; the elements of the continued fraction, ai and bi above.
d=0.0;
for (i=n; i>=1; i--) d=a[i]/(b[i]+d);
return (d+b[0]);
}
A. polchs
∑ak x k = ∑ bk Tk (x) ;
k =0 k =0
the Tk(x) being Chebyshev polynomials.
Procedure parameters:
void polchs (n,a)
n: int; the degree of the polynomial;
a: double a[0:n];
entry: the coefficients of the power sum;
exit: the coefficients of the Chebyshev sum.
if (n > 1) {
twopow=2;
for (k=1; k<=n-2; k++) {
a[k] /= twopow;
twopow *= 2;
}
a[n-1]=2.0*a[n-1]/twopow;
a[n] /= twopow;
a[n-2] += a[n];
for (k=n-2; k>=1; k--) {
a[k-1] += a[k+1];
a[k]=2.0*a[k]+a[k+2];
for (l=k+1; l<=n-2; l++) a[l] += a[l+2];
}
}
}
∑ bk Tk ( x) = ∑ ak x k ;
k =0 k =0
the Tk(x) being Chebyshev polynomials.
Procedure parameters:
void chspol (n,a)
n: int; the degree of the polynomial;
a: double a[0:n];
entry: the coefficients of the Chebyshev sum;
exit: the coefficients of the power sum.
if (n > 1) {
for (k=0; k<=n-2; k++) {
for (l=n-2; l>=k; l--) a[l] -= a[l+2];
a[k+1] /= 2.0;
}
twopow=2;
for (k=1; k<=n-2; k++) {
a[k] *= twopow;
twopow *= 2;
}
a[n-1] *= twopow;
a[n] *= twopow;
}
}
C. polshtchs
∑ ak x k = ∑ bk S k (x) ;
k =0 k =0
the Sk(x) being shifted Chebyshev polynomials defined by Sk(x)=Tk(2x-1),
Tk(x) being a Chebyshev polynomial.
Procedure parameters:
D. shtchspol
∑ bk S k ( x) = ∑ ak x k ;
k =0 k =0
the Sk(x) being shifted Chebyshev polynomials defined by Sk(x)=Tk(2x-1), and
Tk(x) being a Chebyshev polynomial.
Procedure parameters:
void shtchspol (n,a)
n: int; the degree of the polynomial;
a: double a[0:n];
entry: the coefficients of the shifted Chebyshev sum;
exit: the coefficients of the power sum.
E. grnnew
Procedure parameters:
void grnnew (n,x,a)
n: int; the degree of the polynomial;
x: double x[0:n-1];
entry: the interpolation points, values of xv above;
a: double a[0:n];
entry: the coefficients of the power sum;
exit: the coefficients of the Newton sum, values of δj above.
F. newgrn
Given the coefficients δjf(x0), together with the values of the arguments xi from
which they are formed, in the truncated Newton interpolation series
n
j −1
f n ( x) = ∑ ∏ ( x − xυ ) δ j f ( x0 )
j =0 υ =0
computes the coefficients ci, i=0,...,n, in the equivalent polynomial form
n
f n (x) = ∑ ci x i .
i=0
Procedure parameters:
void newgrn (n,x,a)
n: int; the degree of the polynomial;
x: double x[0:n-1];
entry: the interpolation points, values of xi above;
a: double a[0:n];
entry: the coefficients of the Newton sum, values of δjf(x0);
exit: the coefficients of the power sum, values of ci above.
G. lintfmpol
Procedure parameters:
void lintfmpol (p,q,n,a)
p,q: double;
entry: defining the linear transformation of the independent variable
x=py+q; p=0 gives the value of the polynomial with argument q;
n: int; the degree of the polynomial;
a: double a[0:n];
entry: the coefficients of the power sum in x, values of ai above;
exit: the coefficients of the power sum in y, values of bj above.
norderpol(n,n,q,a);
ppower=p;
for (k=1; k<=n; k++) {
intchs
∫ f(x)dx = ∑ b j T j ( x)
0 j=1
are derived.
Procedure parameters:
void intchs (n,a,b)
n: int; the degree of the polynomial represented by the Chebyshev series;
a,b: double a[0:n], b[1:n+1];
entry: the coefficients of the Chebyshev series, values of aj above;
exit: the coefficients of the integral Chebyshev series, values of bj
above.
if (n == 0) {
b[1]=a[0];
return;
}
if (n == 1) {
b[2]=a[1]/4.0;
b[1]=a[0];
return;
}
h=a[n];