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
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
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
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
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
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
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){
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
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
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
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
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
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 }
01162 #endif