Main Page   File List   File Members  

polylib.c

Go to the documentation of this file.
00001 #include <stdlib.h>
00002 #include <sys/types.h>
00003 #include <stdio.h>
00004 #include <float.h>
00005 #include <math.h>
00006 #include "polylib.h"
00007 #include <float.h>
00008 #define STOP  30 
00009 #define EPS   100*DBL_EPSILON
00010 #define sign(a,b) ((b)<0 ? -fabs(a) : fabs(a))
00011 
00012 /*
00013 LIBRARY ROUTINES FOR ORTHOGONAL POLYNOMIAL CALCULUS AND INTERPOLATION
00014 
00015   Spencer Sherwin
00016   Aeronautics, Imperial College London
00017   
00018   Based on codes by Einar Ronquist and Ron Henderson
00019 
00020   Abbreviations
00021   - z    -   Set of collocation/quadrature points
00022   - w    -   Set of quadrature weights
00023   - D    -   Derivative matrix
00024   - h    -   Lagrange Interpolant
00025   - I    -   Interpolation matrix
00026   - g    -   Gauss
00027   - gr   -   Gauss-Radau
00028   - gl   -   Gauss-Lobatto
00029   - j    -   Jacobi
00030   - l    -   Legendre  (Jacobi with alpha = beta =  0.0)
00031   - c    -   Chebychev (Jacobi with alpha = beta = -0.5)
00032   - m    -   point at minus 1 in Radau rules
00033   - p    -   point at plus  1 in Radau rules
00034 
00035   -----------------------------------------------------------------------
00036                          M A I N     R O U T I N E S
00037   -----------------------------------------------------------------------
00038 
00039   Points and Weights:
00040 
00041   zwgj        Compute Gauss-Jacobi         points and weights
00042   zwgrjm      Compute Gauss-Radau-Jacobi   points and weights (z=-1)
00043   zwgrjp      Compute Gauss-Radau-Jacobi   points and weights (z= 1)
00044   zwglj       Compute Gauss-Lobatto-Jacobi points and weights
00045 
00046   Derivative Matrices:
00047 
00048   Dgj         Compute Gauss-Jacobi         derivative matrix
00049   Dgrjm       Compute Gauss-Radau-Jacobi   derivative matrix (z=-1)
00050   Dgrjp       Compute Gauss-Radau-Jacobi   derivative matrix (z= 1)
00051   Dglj        Compute Gauss-Lobatto-Jacobi derivative matrix
00052 
00053   Lagrange Interpolants:
00054 
00055   hgj         Compute Gauss-Jacobi         Lagrange interpolants
00056   hgrjm       Compute Gauss-Radau-Jacobi   Lagrange interpolants (z=-1)
00057   hgrjp       Compute Gauss-Radau-Jacobi   Lagrange interpolants (z= 1)
00058   hglj        Compute Gauss-Lobatto-Jacobi Lagrange interpolants
00059 
00060   Interpolation Operators:
00061 
00062   Imgj        Compute interpolation operator gj->m
00063   Imgrjm      Compute interpolation operator grj->m (z=-1)
00064   Imgrjp      Compute interpolation operator grj->m (z= 1)
00065   Imglj       Compute interpolation operator glj->m
00066 
00067   Polynomial Evaluation:
00068 
00069   jacobfd     Returns value and derivative of Jacobi poly. at point z
00070   jacobd      Returns derivative of Jacobi poly. at point z (valid at z=-1,1)
00071 
00072   -----------------------------------------------------------------------
00073                      L O C A L      R O U T I N E S
00074   -----------------------------------------------------------------------
00075 
00076   jacobz      Returns Jacobi polynomial zeros
00077   gammaf      Gamma function for integer values and halves
00078 
00079   -----------------------------------------------------------------------
00080                          M A C R O S
00081   -----------------------------------------------------------------------
00082   
00083   Legendre  polynomial alpha = beta = 0
00084   Chebychev polynomial alpha = beta = -0.5
00085 
00086   Points and Weights:
00087 
00088   zwgl        Compute Gauss-Legendre          points and weights
00089   zwgrlm      Compute Gauss-Radau-Legendre    points and weights (z=-1)
00090   zwgrlp      Compute Gauss-Radau-Legendre    points and weights (z=+1)
00091   zwgll       Compute Gauss-Lobatto-Legendre  points and weights
00092 
00093   zwgc        Compute Gauss-Chebychev         points and weights
00094   zwgrcm      Compute Gauss-Radau-Chebychev   points and weights (z=-1)
00095   zwgrcp      Compute Gauss-Radau-Chebychev   points and weights (z=+1)
00096   zwglc       Compute Gauss-Lobatto-Chebychev points and weights
00097 
00098   Derivative Operators:
00099 
00100   Dgl         Compute Gauss-Legendre          derivative matrix
00101   Dgrlm       Compute Gauss-Radau-Legendre    derivative matrix (z=-1)
00102   Dgrlp       Compute Gauss-Radau-Legendre    derivative matrix (z=+1)
00103   Dgll        Compute Gauss-Lobatto-Legendre  derivative matrix
00104 
00105   Dgc         Compute Gauss-Chebychev         derivative matrix
00106   Dgrcm       Compute Gauss-Radau-Chebychev   derivative matrix (z=-1)
00107   Dgrcp       Compute Gauss-Radau-Chebychev   derivative matrix (z=+1)
00108   Dglc        Compute Gauss-Lobatto-Chebychev derivative matrix
00109 
00110   Lagrangian Interpolants:
00111 
00112   hgl         Compute Gauss-Legendre          Lagrange interpolants
00113   hgrlm       Compute Gauss-Radau-Legendre    Lagrange interpolants (z=-1)
00114   hgrlp       Compute Gauss-Radau-Legendre    Lagrange interpolants (z=+1)
00115   hgll        Compute Gauss-Lobatto-Legendre  Lagrange interpolants
00116 
00117   hgc         Compute Gauss-Chebychev         Lagrange interpolants
00118   hgrcm       Compute Gauss-Radau-Chebychev   Lagrange interpolants (z=-1)
00119   hgrcp       Compute Gauss-Radau-Chebychev   Lagrange interpolants (z=+1)
00120   hglc        Compute Gauss-Lobatto-Chebychev Lagrange interpolants
00121 
00122   Interpolation Operators:
00123 
00124   Imgl        Compute interpolation operator gl->m
00125   Imgrlm      Compute interpolation operator grl->m (z=-1)
00126   Imgrlp      Compute interpolation operator grl->m (z=+1)
00127   Imgll       Compute interpolation operator gll->m
00128 
00129   Imgc        Compute interpolation operator gc->m
00130   Imgrcm      Compute interpolation operator grc->m (z=-1)
00131   Imgrcp      Compute interpolation operator grc->m (z=+1)
00132   Imglc       Compute interpolation operator glc->m
00133 
00134   ------------------------------------------------------------------------
00135 
00136   Useful references:
00137 
00138   - [1] Gabor Szego: Orthogonal Polynomials, American Mathematical Society,
00139       Providence, Rhode Island, 1939.
00140   - [2] Abramowitz \& Stegun: Handbook of Mathematical Functions,
00141       Dover, New York, 1972.
00142   - [3] Canuto, Hussaini, Quarteroni \& Zang: Spectral Methods in Fluid
00143       Dynamics, Springer-Verlag, 1988.
00144   - [4] Ghizzetti \& Ossicini: Quadrature Formulae, Academic Press, 1970.
00145   - [5] Karniadakis \& Sherwin: Spectral/hp element methods for CFD, 1999
00146 
00147 
00148   NOTES
00149   -----
00150   (1) All routines are double precision.  
00151   (2) All array subscripts start from zero, i.e. vector[0..N-1] 
00152 */
00153 
00154 #ifdef __cplusplus
00155 namespace polylib {
00156 #endif
00157 
00158 
00159 #if 0 
00160 
00161 #define jacobz(n,z,alpha,beta) Jacobz(n,z,alpha,beta)
00162 #else
00163 
00164 #define jacobz(n,z,alpha,beta) JacZeros(n,z,alpha,beta)
00165 #endif
00166 
00167 
00168 
00169 /* local functions */
00170 static void   Jacobz   (int n, double *z, double alpha, double beta);
00171 static void   JacZeros (int n, double *a, double alpha, double beta);
00172 static void   TriQL    (int n, double *d, double *e);
00173 
00174 static double gammaF (double);
00175 
00186 void zwgj (double *z, double *w, int np, double alpha, double beta){
00187   register int i;
00188   double fac, one = 1.0, two = 2.0, apb = alpha + beta;
00189 
00190   jacobz (np,z,alpha,beta);
00191   jacobd (np,z,w,np,alpha,beta);
00192 
00193   fac  = pow(two,apb + one)*gammaF(alpha + np + one)*gammaF(beta + np + one);
00194   fac /= gammaF(np + one)*gammaF(apb + np + one);
00195   
00196   for(i = 0; i < np; ++i) w[i] = fac/(w[i]*w[i]*(one-z[i]*z[i]));
00197   
00198   return;
00199 }
00200 
00201 
00212 void zwgrjm(double *z, double *w, int np, double alpha, double beta){
00213 
00214   if(np == 1){
00215     z[0] = 0.0;
00216     w[0] = 2.0;
00217   }
00218   else{
00219     register int i;
00220     double fac, one = 1.0, two = 2.0, apb = alpha + beta;
00221     
00222     z[0] = -one;
00223     jacobz  (np-1,z+1,alpha,beta+1);
00224     jacobfd (np,z,w,NULL,np-1,alpha,beta);
00225     
00226     fac  = pow(two,apb)*gammaF(alpha + np)*gammaF(beta + np);
00227     fac /= gammaF(np)*(beta + np)*gammaF(apb + np + 1);
00228 
00229     for(i = 0; i < np; ++i) w[i] = fac*(1-z[i])/(w[i]*w[i]);
00230     w[0] *= (beta + one);
00231   }
00232 
00233   return;
00234 }
00235 
00236 
00248 void zwgrjp(double *z, double *w, int np, double alpha, double beta){
00249 
00250   if(np == 1){
00251     z[0] = 0.0;
00252     w[0] = 2.0;
00253   }
00254   else{
00255     register int i;
00256     double fac, one = 1.0, two = 2.0, apb = alpha + beta;
00257     
00258     jacobz  (np-1,z,alpha+1,beta);
00259     z[np-1] = one;
00260     jacobfd (np,z,w,NULL,np-1,alpha,beta);
00261     
00262     fac  = pow(two,apb)*gammaF(alpha + np)*gammaF(beta + np);
00263     fac /= gammaF(np)*(alpha + np)*gammaF(apb + np + 1);
00264 
00265     for(i = 0; i < np; ++i) w[i] = fac*(1+z[i])/(w[i]*w[i]);
00266     w[np-1] *= (alpha + one);
00267   }
00268 
00269   return;
00270 }
00271 
00272 
00282 void zwglj(double *z, double *w, int np, double alpha, double beta){
00283 
00284   if( np == 1 ){
00285     z[0] = 0.0;
00286     w[0] = 2.0;
00287   }
00288   else{
00289     register int i;
00290     double   fac, one = 1.0, apb = alpha + beta, two = 2.0;
00291   
00292     z[0]    = -one;
00293     z[np-1] =  one;
00294     jacobz  (np-2,z + 1,alpha + one,beta + one); 
00295     jacobfd (np,z,w,NULL,np-1,alpha,beta);
00296 
00297     fac  = pow(two,apb + 1)*gammaF(alpha + np)*gammaF(beta + np);
00298     fac /= (np-1)*gammaF(np)*gammaF(alpha + beta + np + one);
00299     
00300     for(i = 0; i < np; ++i) w[i] = fac/(w[i]*w[i]);
00301     w[0]    *= (beta  + one);
00302     w[np-1] *= (alpha + one);
00303   }
00304       
00305   return;
00306 }
00307 
00308 
00321 void Dgj(double *D, double *Dt, double *z, int np,double alpha, double beta){
00322 
00323   double one = 1.0, two = 2.0;
00324 
00325   if (np <= 0){
00326     D[0] = Dt[0] = 0.0;
00327   }
00328   else{
00329     register int i,j; 
00330     double *pd;
00331     
00332     pd = (double *)malloc(np*sizeof(double));
00333     jacobd(np,z,pd,np,alpha,beta);
00334     
00335     for (i = 0; i < np; i++){
00336       for (j = 0; j < np; j++){
00337 
00338   if (i != j) 
00339     D[i*np+j] = pd[i]/(pd[j]*(z[i]-z[j]));
00340   else    
00341     D[i*np+j] = (alpha - beta + (alpha + beta + two)*z[i])/
00342          (two*(one - z[i]*z[i]));
00343 
00344   Dt[j*np+i] = D[i*np+j];
00345       }
00346     }
00347     free(pd);
00348   }
00349   return;
00350 }
00351 
00352 
00365 void Dgrjm(double *D, double *Dt, double *z, int np,
00366      double alpha, double beta){
00367 
00368   if (np <= 0){
00369     D[0] = Dt[0] = 0.0;
00370   }
00371   else{
00372     register int i, j; 
00373     double   one = 1.0, two = 2.0;
00374     double   *pd;
00375 
00376     pd  = (double *)malloc(np*sizeof(double));
00377 
00378     pd[0] = pow(-one,np-1)*gammaF(np+beta+one);
00379     pd[0] /= gammaF(np)*gammaF(beta+two);
00380     jacobd(np-1,z+1,pd+1,np-1,alpha,beta+1);
00381     for(i = 1; i < np; ++i) pd[i] *= (1+z[i]);
00382 
00383     for (i = 0; i < np; i++)
00384       for (j = 0; j < np; j++){
00385   if (i != j) 
00386     D[i*np+j] = pd[i]/(pd[j]*(z[i]-z[j]));
00387   else { 
00388     if(i == 0)
00389       D[i*np+j] = -(np + alpha + beta + one)*(np - one)/
00390         (two*(beta + two));
00391     else
00392       D[i*np+j] = (alpha - beta + one + (alpha + beta + one)*z[i])/
00393         (two*(one - z[i]*z[i]));
00394   }
00395   
00396   Dt[j*np+i] = D[i*np+j];
00397       }
00398     free(pd);
00399   }
00400 
00401   return;
00402 }
00403 
00404 
00417 void Dgrjp(double *D, double *Dt, double *z, int np,
00418      double alpha, double beta){
00419 
00420   if (np <= 0){
00421     D[0] = Dt[0] = 0.0;
00422   }
00423   else{
00424     register int i, j; 
00425     double   one = 1.0, two = 2.0;
00426     double   *pd;
00427 
00428     pd  = (double *)malloc(np*sizeof(double));
00429 
00430 
00431     jacobd(np-1,z,pd,np-1,alpha+1,beta);
00432     for(i = 0; i < np-1; ++i) pd[i] *= (1-z[i]);
00433     pd[np-1] = -gammaF(np+alpha+one);
00434     pd[np-1] /= gammaF(np)*gammaF(alpha+two);
00435 
00436     for (i = 0; i < np; i++)
00437       for (j = 0; j < np; j++){
00438   if (i != j) 
00439     D[i*np+j] = pd[i]/(pd[j]*(z[i]-z[j]));
00440   else { 
00441     if(i == np-1)
00442       D[i*np+j] = (np + alpha + beta + one)*(np - one)/
00443         (two*(alpha + two));
00444     else
00445       D[i*np+j] = (alpha - beta - one + (alpha + beta + one)*z[i])/
00446         (two*(one - z[i]*z[i]));
00447   }
00448   
00449   Dt[j*np+i] = D[i*np+j];
00450       }
00451     free(pd);
00452   }
00453 
00454   return;
00455 }
00456 
00469 void Dglj(double *D, double *Dt, double *z, int np,
00470     double alpha, double beta){
00471      
00472   if (np <= 0){
00473     D[0] = Dt[0] = 0.0;
00474   }
00475   else{
00476     register int i, j; 
00477     double   one = 1.0, two = 2.0;
00478     double   *pd;
00479 
00480     pd  = (double *)malloc(np*sizeof(double));
00481 
00482     pd[0]  = two*pow(-one,np)*gammaF(np + beta);
00483     pd[0] /= gammaF(np - one)*gammaF(beta + two);
00484     jacobd(np-2,z+1,pd+1,np-2,alpha+1,beta+1);
00485     for(i = 1; i < np-1; ++i) pd[i] *= (one-z[i]*z[i]);
00486     pd[np-1]  = -two*gammaF(np + alpha);
00487     pd[np-1] /= gammaF(np - one)*gammaF(alpha + two);
00488 
00489     for (i = 0; i < np; i++)
00490       for (j = 0; j < np; j++){
00491   if (i != j) 
00492     D[i*np+j] = pd[i]/(pd[j]*(z[i]-z[j]));
00493   else { 
00494     if      (i == 0)
00495       D[i*np+j] = (alpha - (np-1)*(np + alpha + beta))/(two*(beta+ two));
00496     else if (i == np-1)
00497       D[i*np+j] =-(beta - (np-1)*(np + alpha + beta))/(two*(alpha+ two));
00498     else
00499       D[i*np+j] = (alpha - beta + (alpha + beta)*z[i])/
00500                           (two*(one - z[i]*z[i]));
00501   }
00502   
00503   Dt[j*np+i] = D[i*np+j];
00504       }
00505     free(pd);
00506   }
00507 
00508   return;
00509 }
00510 
00511 
00532 double hgj (int i, double z, double *zgj, int np, double alpha, double beta)
00533 {
00534 
00535   double zi, dz, p, pd, h;
00536 
00537   zi  = *(zgj+i);
00538   dz  = z - zi;
00539   if (fabs(dz) < EPS) return 1.0;
00540 
00541   jacobd (1, &zi, &pd , np, alpha, beta);
00542   jacobfd(1, &z , &p, NULL , np, alpha, beta);
00543   h = p/(pd*dz);
00544 
00545   return h;
00546 }
00547 
00569 double hgrjm (int i, double z, double *zgrj, int np, double alpha, double beta)
00570 {
00571 
00572   double zi, dz, p, pd, h;
00573 
00574   zi  = *(zgrj+i);
00575   dz  = z - zi;
00576   if (fabs(dz) < EPS) return 1.0;
00577 
00578   jacobfd (1, &zi, &p , NULL, np-1, alpha, beta + 1);
00579   // need to use this routine in caes zi = -1 or 1
00580   jacobd  (1, &zi, &pd, np-1, alpha, beta + 1);
00581   h = (1.0 + zi)*pd + p;
00582   jacobfd (1, &z, &p, NULL,  np-1, alpha, beta + 1);
00583   h = (1.0 + z )*p/(h*dz);
00584 
00585   return h;
00586 }
00587 
00588 
00610 double hgrjp (int i, double z, double *zgrj, int np, double alpha, double beta)
00611 {
00612 
00613   double zi, dz, p, pd, h;
00614 
00615   zi  = *(zgrj+i);
00616   dz  = z - zi;
00617   if (fabs(dz) < EPS) return 1.0;
00618 
00619   jacobfd (1, &zi, &p , NULL, np-1, alpha+1, beta );
00620   // need to use this routine in caes z = -1 or 1
00621   jacobd  (1, &zi, &pd, np-1, alpha+1, beta );
00622   h = (1.0 - zi)*pd - p;
00623   jacobfd (1, &z, &p, NULL,  np-1, alpha+1, beta);
00624   h = (1.0 - z )*p/(h*dz);
00625 
00626   return h;
00627 }
00628 
00629 
00651 double hglj (int i, double z, double *zglj, int np, double alpha, double beta)
00652 {
00653   double one = 1., two = 2.;
00654   double zi, dz, p, pd, h;
00655 
00656   zi  = *(zglj+i);
00657   dz  = z - zi;
00658   if (fabs(dz) < EPS) return 1.0;
00659 
00660   jacobfd(1, &zi, &p , NULL, np-2, alpha + one, beta + one);
00661   // need to use this routine in caes z = -1 or 1
00662   jacobd (1, &zi, &pd, np-2, alpha + one, beta + one);
00663   h = (one - zi*zi)*pd - two*zi*p;
00664   jacobfd(1, &z, &p, NULL, np-2, alpha + one, beta + one);
00665   h = (one - z*z)*p/(h*dz);
00666 
00667   return h;
00668 }
00669 
00670 
00684 void Imgj(double *im,double *zgj, double *zm, int nz, int mz,
00685     double alpha, double beta){
00686   double zp;
00687   register int i, j;
00688 
00689   for (i = 0; i < mz; ++i) {
00690     zp = zm[i];
00691     for (j = 0; j < nz; ++j)
00692       im [i*nz+j] = hgj(j, zp, zgj, nz, alpha, beta);
00693   }
00694   
00695   return;
00696 }
00697 
00711 void Imgrjm(double *im,double *zgrj, double *zm, int nz, int mz,
00712      double alpha, double beta){
00713   double zp;
00714   register int i, j;
00715 
00716   for (i = 0; i < mz; i++) {
00717     zp = zm[i];
00718     for (j = 0; j < nz; j++)
00719       im [i*nz+j] = hgrjm(j, zp, zgrj, nz, alpha, beta);
00720   }
00721   
00722   return;
00723 }
00724 
00738 void Imgrjp(double *im,double *zgrj, double *zm, int nz, int mz,
00739      double alpha, double beta){
00740   double zp;
00741   register int i, j;
00742 
00743   for (i = 0; i < mz; i++) {
00744     zp = zm[i];
00745     for (j = 0; j < nz; j++)
00746       im [i*nz+j] = hgrjp(j, zp, zgrj, nz, alpha, beta);
00747   }
00748   
00749   return;
00750 }
00751 
00752 
00766 void Imglj(double *im, double *zglj, double *zm, int nz, int mz,
00767      double alpha, double beta)
00768 {
00769   double zp;
00770   register int i, j;
00771   
00772   for (i = 0; i < mz; i++) {
00773     zp = zm[i];
00774     for (j = 0; j < nz; j++)
00775       im[i*nz+j] = hglj(j, zp, zglj, nz, alpha, beta);
00776   }
00777   
00778   return;
00779 }
00780 
00821 void jacobfd(int np, double *z, double *poly_in, double *polyd, int n, 
00822        double alpha, double beta){
00823   register int i;
00824   double  zero = 0.0, one = 1.0, two = 2.0;
00825 
00826   if(!np)
00827     return;
00828 
00829   if(n == 0){
00830     if(poly_in)
00831       for(i = 0; i < np; ++i) 
00832   poly_in[i] = one;
00833     if(polyd)
00834       for(i = 0; i < np; ++i) 
00835   polyd[i] = zero; 
00836   }
00837   else if (n == 1){
00838     if(poly_in)
00839       for(i = 0; i < np; ++i) 
00840   poly_in[i] = 0.5*(alpha - beta + (alpha + beta + two)*z[i]);
00841     if(polyd)
00842       for(i = 0; i < np; ++i) 
00843   polyd[i] = 0.5*(alpha + beta + two);
00844   }
00845   else{
00846     register int k;
00847     double   a1,a2,a3,a4;
00848     double   two = 2.0, apb = alpha + beta;
00849     double   *poly, *polyn1,*polyn2;
00850     
00851     if(poly_in){ // switch for case of no poynomial function return
00852       polyn1 = (double *)malloc(2*np*sizeof(double));
00853       polyn2 = polyn1+np; 
00854       poly   = poly_in;
00855     }
00856     else{
00857       polyn1 = (double *)malloc(3*np*sizeof(double));
00858       polyn2 = polyn1+np; 
00859       poly   = polyn2+np;      
00860     }
00861 
00862     for(i = 0; i < np; ++i){
00863       polyn2[i] = one;
00864       polyn1[i] = 0.5*(alpha - beta + (alpha + beta + two)*z[i]);
00865     }
00866     
00867     for(k = 2; k <= n; ++k){
00868       a1 =  two*k*(k + apb)*(two*k + apb - two);
00869       a2 = (two*k + apb - one)*(alpha*alpha - beta*beta);
00870       a3 = (two*k + apb - two)*(two*k + apb - one)*(two*k + apb);
00871       a4 =  two*(k + alpha - one)*(k + beta - one)*(two*k + apb);
00872       
00873       a2 /= a1;
00874       a3 /= a1;
00875       a4 /= a1;
00876   
00877       for(i = 0; i < np; ++i){
00878   poly  [i] = (a2 + a3*z[i])*polyn1[i] - a4*polyn2[i];
00879   polyn2[i] = polyn1[i];
00880   polyn1[i] = poly  [i];
00881       }
00882     }
00883     
00884     if(polyd){
00885       a1 = n*(alpha - beta);
00886       a2 = n*(two*n + alpha + beta);
00887       a3 = two*(n + alpha)*(n + beta);
00888       a4 = (two*n + alpha + beta);
00889       a1 /= a4;  a2 /= a4;   a3 /= a4;
00890 
00891       // note polyn2 points to polyn1 at end of poly iterations
00892       for(i = 0; i < np; ++i){
00893   polyd[i]  = (a1- a2*z[i])*poly[i] + a3*polyn2[i];
00894   polyd[i] /= (one - z[i]*z[i]);
00895       }
00896     }
00897     
00898     free(polyn1);
00899   }
00900   
00901   return;
00902 }
00903 
00904 
00921 void jacobd(int np, double *z, double *polyd, int n, double alpha, double beta)
00922 {
00923   register int i;
00924   double one = 1.0;
00925   if(n == 0)
00926     for(i = 0; i < np; ++i) polyd[i] = 0.0;
00927   else{
00928     //jacobf(np,z,polyd,n-1,alpha+one,beta+one);
00929     jacobfd(np,z,polyd,NULL,n-1,alpha+one,beta+one);
00930     for(i = 0; i < np; ++i) polyd[i] *= 0.5*(alpha + beta + (double)n + one);
00931   }
00932   return;
00933 }
00934 
00935 
00947 static double gammaF(double x){
00948   double gamma = 1.0;
00949   
00950   if     (x == -0.5) gamma = -2.0*sqrt(M_PI);
00951   else if (!x) return gamma;
00952   else if ((x-(int)x) == 0.5){ 
00953     int n = (int) x;
00954     double tmp = x;
00955 
00956     gamma = sqrt(M_PI);
00957     while(n--){
00958       tmp   -= 1.0;
00959       gamma *= tmp;
00960     }
00961   }
00962   else if ((x-(int)x) == 0.0){
00963     int n = (int) x;
00964     double tmp = x;
00965 
00966     while(--n){
00967       tmp   -= 1.0;
00968       gamma *= tmp;
00969     }
00970   }  
00971   else
00972     fprintf(stderr,"%lf is not of integer or half order\n",x);
00973   return gamma;
00974 }
00975     
00984 static void Jacobz(int n, double *z, double alpha, double beta){
00985   register int i,j,k;
00986   double   dth = M_PI/(2.0*(double)n);
00987   double   poly,pder,rlast=0.0;
00988   double   sum,delr,r;
00989   double one = 1.0, two = 2.0;
00990   
00991   if(!n)
00992     return;
00993   
00994   for(k = 0; k < n; ++k){
00995     r = -cos((two*(double)k + one) * dth);
00996     if(k) r = 0.5*(r + rlast);
00997     
00998     for(j = 1; j < STOP; ++j){
00999       jacobfd(1,&r,&poly, &pder, n, alpha, beta);
01000       
01001       for(i = 0, sum = 0.0; i < k; ++i) sum += one/(r - z[i]);
01002       
01003       delr = -poly / (pder - sum * poly);
01004       r   += delr;
01005       if( fabs(delr) < EPS ) break;
01006     }
01007     z[k]  = r;
01008     rlast = r;
01009   }
01010   return;
01011 }
01012 
01013 
01038 static void JacZeros(int n, double *a, double alpha, double beta){
01039   int i;
01040   double apb, apbi,a2b2;
01041   double *b;
01042 
01043   b = (double *) malloc(n*sizeof(double));
01044   
01045   // generate normalised terms 
01046   apb  = alpha + beta;
01047   apbi = 2.0 + apb;
01048 
01049   b[n-1] = pow(2.0,apb+1.0)*gammaF(alpha+1.0)*gammaF(beta+1.0)/gammaF(apbi);
01050   a[0]   = (beta-alpha)/apbi;
01051   b[0]   = sqrt(4.0*(1.0+alpha)*(1.0+beta)/((apbi+1.0)*apbi*apbi));
01052 
01053   a2b2 = beta*beta-alpha*alpha;
01054   for(i = 1; i < n-1; ++i){
01055     apbi = 2.0*(i+1) + apb;
01056     a[i] = a2b2/((apbi-2.0)*apbi);
01057     b[i] = sqrt(4.0*(i+1)*(i+1+alpha)*(i+1+beta)*(i+1+apb)/
01058     ((apbi*apbi-1)*apbi*apbi));
01059   }
01060 
01061   apbi   = 2.0*n + apb;
01062   a[n-1] = a2b2/((apbi-2.0)*apbi);
01063   
01064   // find eigenvalues 
01065   TriQL(n, a, b);
01066 
01067   free(b);
01068   return;
01069 }
01070 
01071 
01096 static void TriQL(int n, double *d,double *e){
01097   int m,l,iter,i,k;
01098   double s,r,p,g,f,dd,c,b;
01099   
01100   for (l=0;l<n;l++) {
01101     iter=0;
01102     do {
01103       for (m=l;m<n-1;m++) {
01104   dd=fabs(d[m])+fabs(d[m+1]);
01105   if (fabs(e[m])+dd == dd) break;
01106       }
01107       if (m != l) {
01108   if (iter++ == STOP){
01109     fprintf(stderr,"triQL: Too many iterations in TQLI");
01110     exit(1);
01111   }
01112   g=(d[l+1]-d[l])/(2.0*e[l]);
01113   r=sqrt((g*g)+1.0);
01114   g=d[m]-d[l]+e[l]/(g+sign(r,g));
01115   s=c=1.0;
01116   p=0.0;
01117   for (i=m-1;i>=l;i--) {
01118     f=s*e[i];
01119     b=c*e[i];
01120     if (fabs(f) >= fabs(g)) {
01121       c=g/f;
01122       r=sqrt((c*c)+1.0);
01123       e[i+1]=f*r;
01124       c *= (s=1.0/r);
01125     } else {
01126       s=f/g;
01127       r=sqrt((s*s)+1.0);
01128       e[i+1]=g*r;
01129       s *= (c=1.0/r);
01130     }
01131     g=d[i+1]-p;
01132     r=(d[i]-g)*s+2.0*c*b;
01133     p=s*r;
01134     d[i+1]=g+p;
01135     g=c*r-b;
01136   }
01137   d[l]=d[l]-p;
01138   e[l]=g;
01139   e[m]=0.0;
01140       }
01141     } while (m != l);
01142   }
01143 
01144   // order eigenvalues
01145   for(i = 0; i < n-1; ++i){ 
01146     k = i;
01147     p = d[i];
01148     for(l = i+1; l < n; ++l)
01149       if (d[l] < p) {
01150   k = l;
01151   p = d[l];
01152       }
01153     d[k] = d[i]; 
01154     d[i] = p;
01155   }
01156 }
01157 
01158 
01159 
01160 #ifdef __cplusplus
01161 } // end of namespace
01162 #endif

Generated on Sun Jul 13 22:18:36 2003 for Polylib by doxygen1.3