00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
00041
00042
00049 #ifdef _MSC_VER
00050 #include "winmath.h"
00051 #endif
00052
00053
00054 namespace Intrepid {
00055
00057 #define INTREPID_POLYLIB_STOP 50
00058
00060 #define INTREPID_POLYLIB_POLYNOMIAL_DEFLATION 0
00061
00062 #ifdef INTREPID_POLYLIB_POLYNOMIAL_DEFLATION
00064 #define jacobz(n,z,alpha,beta) Jacobz(n,z,alpha,beta)
00065 #else
00067 #define jacobz(n,z,alpha,beta) JacZeros(n,z,alpha,beta)
00068 #endif
00069
00070
00071 template <class Scalar>
00072 void IntrepidPolylib::zwgj (Scalar *z, Scalar *w, const int np, const Scalar alpha, const Scalar beta){
00073 register int i;
00074 Scalar fac, one = 1.0, two = 2.0, apb = alpha + beta;
00075
00076 IntrepidPolylib::jacobz (np,z,alpha,beta);
00077 IntrepidPolylib::jacobd (np,z,w,np,alpha,beta);
00078
00079 fac = std::pow(two,apb + one)*IntrepidPolylib::gammaF(alpha + np + one)*IntrepidPolylib::gammaF(beta + np + one);
00080 fac /= IntrepidPolylib::gammaF((Scalar)(np + one))*IntrepidPolylib::gammaF(apb + np + one);
00081
00082 for(i = 0; i < np; ++i) w[i] = fac/(w[i]*w[i]*(one-z[i]*z[i]));
00083
00084 return;
00085 }
00086
00087
00088 template <class Scalar>
00089 void IntrepidPolylib::zwgrjm(Scalar *z, Scalar *w, const int np, const Scalar alpha, const Scalar beta){
00090
00091 if(np == 1){
00092 z[0] = 0.0;
00093 w[0] = 2.0;
00094 }
00095 else{
00096 register int i;
00097 Scalar fac, one = 1.0, two = 2.0, apb = alpha + beta;
00098
00099 z[0] = -one;
00100 IntrepidPolylib::jacobz (np-1,z+1,alpha,beta+1);
00101 IntrepidPolylib::jacobfd (np,z,w,(Scalar*)0,np-1,alpha,beta);
00102
00103 fac = std::pow(two,apb)*IntrepidPolylib::gammaF(alpha + np)*IntrepidPolylib::gammaF(beta + np);
00104 fac /= IntrepidPolylib::gammaF((Scalar)np)*(beta + np)*IntrepidPolylib::gammaF(apb + np + 1);
00105
00106 for(i = 0; i < np; ++i) w[i] = fac*(1-z[i])/(w[i]*w[i]);
00107 w[0] *= (beta + one);
00108 }
00109
00110 return;
00111 }
00112
00113
00114 template <class Scalar>
00115 void IntrepidPolylib::zwgrjp(Scalar *z, Scalar *w, const int np, const Scalar alpha, const Scalar beta){
00116
00117 if(np == 1){
00118 z[0] = 0.0;
00119 w[0] = 2.0;
00120 }
00121 else{
00122 register int i;
00123 Scalar fac, one = 1.0, two = 2.0, apb = alpha + beta;
00124
00125 IntrepidPolylib::jacobz (np-1,z,alpha+1,beta);
00126 z[np-1] = one;
00127 IntrepidPolylib::jacobfd (np,z,w,(Scalar*)0,np-1,alpha,beta);
00128
00129 fac = std::pow(two,apb)*IntrepidPolylib::gammaF(alpha + np)*IntrepidPolylib::gammaF(beta + np);
00130 fac /= IntrepidPolylib::gammaF((Scalar)np)*(alpha + np)*IntrepidPolylib::gammaF(apb + np + 1);
00131
00132 for(i = 0; i < np; ++i) w[i] = fac*(1+z[i])/(w[i]*w[i]);
00133 w[np-1] *= (alpha + one);
00134 }
00135
00136 return;
00137 }
00138
00139
00140 template <class Scalar>
00141 void IntrepidPolylib::zwglj(Scalar *z, Scalar *w, const int np, const Scalar alpha, const Scalar beta){
00142
00143 if( np == 1 ){
00144 z[0] = 0.0;
00145 w[0] = 2.0;
00146 }
00147 else{
00148 register int i;
00149 Scalar fac, one = 1.0, apb = alpha + beta, two = 2.0;
00150
00151 z[0] = -one;
00152 z[np-1] = one;
00153 IntrepidPolylib::jacobz (np-2,z + 1,alpha + one,beta + one);
00154 IntrepidPolylib::jacobfd (np,z,w,(Scalar*)0,np-1,alpha,beta);
00155
00156 fac = std::pow(two,apb + 1)*IntrepidPolylib::gammaF(alpha + np)*IntrepidPolylib::gammaF(beta + np);
00157 fac /= (np-1)*IntrepidPolylib::gammaF((Scalar)np)*IntrepidPolylib::gammaF(alpha + beta + np + one);
00158
00159 for(i = 0; i < np; ++i) w[i] = fac/(w[i]*w[i]);
00160 w[0] *= (beta + one);
00161 w[np-1] *= (alpha + one);
00162 }
00163
00164 return;
00165 }
00166
00167
00168 template <class Scalar>
00169 void IntrepidPolylib::Dgj(Scalar *D, const Scalar *z, const int np, const Scalar alpha, const Scalar beta)
00170 {
00171
00172 Scalar one = 1.0, two = 2.0;
00173
00174 if (np <= 0){
00175 D[0] = 0.0;
00176 }
00177 else{
00178 register int i,j;
00179 Scalar *pd;
00180
00181 pd = (Scalar *)malloc(np*sizeof(Scalar));
00182 IntrepidPolylib::jacobd(np,z,pd,np,alpha,beta);
00183
00184 for (i = 0; i < np; i++){
00185 for (j = 0; j < np; j++){
00186
00187 if (i != j)
00188
00189 D[i*np+j] = pd[i]/(pd[j]*(z[i]-z[j]));
00190 else
00191 D[i*np+j] = (alpha - beta + (alpha + beta + two)*z[j])/
00192 (two*(one - z[j]*z[j]));
00193 }
00194 }
00195 free(pd);
00196 }
00197 return;
00198 }
00199
00200
00201 template <class Scalar>
00202 void IntrepidPolylib::Dgrjm(Scalar *D, const Scalar *z, const int np, const Scalar alpha, const Scalar beta)
00203 {
00204
00205 if (np <= 0){
00206 D[0] = 0.0;
00207 }
00208 else{
00209 register int i, j;
00210 Scalar one = 1.0, two = 2.0;
00211 Scalar *pd;
00212
00213 pd = (Scalar *)malloc(np*sizeof(Scalar));
00214
00215 pd[0] = std::pow(-one,np-1)*IntrepidPolylib::gammaF((Scalar)np+beta+one);
00216 pd[0] /= IntrepidPolylib::gammaF((Scalar)np)*IntrepidPolylib::gammaF(beta+two);
00217 IntrepidPolylib::jacobd(np-1,z+1,pd+1,np-1,alpha,beta+1);
00218 for(i = 1; i < np; ++i) pd[i] *= (1+z[i]);
00219
00220 for (i = 0; i < np; i++) {
00221 for (j = 0; j < np; j++){
00222 if (i != j)
00223
00224 D[i*np+j] = pd[i]/(pd[j]*(z[i]-z[j]));
00225 else {
00226 if(j == 0)
00227 D[i*np+j] = -(np + alpha + beta + one)*(np - one)/
00228 (two*(beta + two));
00229 else
00230 D[i*np+j] = (alpha - beta + one + (alpha + beta + one)*z[j])/
00231 (two*(one - z[j]*z[j]));
00232 }
00233 }
00234 }
00235 free(pd);
00236 }
00237 return;
00238 }
00239
00240
00241 template <class Scalar>
00242 void IntrepidPolylib::Dgrjp(Scalar *D, const Scalar *z, const int np, const Scalar alpha, const Scalar beta)
00243 {
00244
00245 if (np <= 0){
00246 D[0] = 0.0;
00247 }
00248 else{
00249 register int i, j;
00250 Scalar one = 1.0, two = 2.0;
00251 Scalar *pd;
00252
00253 pd = (Scalar *)malloc(np*sizeof(Scalar));
00254
00255
00256 IntrepidPolylib::jacobd(np-1,z,pd,np-1,alpha+1,beta);
00257 for(i = 0; i < np-1; ++i) pd[i] *= (1-z[i]);
00258 pd[np-1] = -IntrepidPolylib::gammaF((Scalar)np+alpha+one);
00259 pd[np-1] /= IntrepidPolylib::gammaF((Scalar)np)*IntrepidPolylib::gammaF(alpha+two);
00260
00261 for (i = 0; i < np; i++) {
00262 for (j = 0; j < np; j++){
00263 if (i != j)
00264
00265 D[i*np+j] = pd[i]/(pd[j]*(z[i]-z[j]));
00266 else {
00267 if(j == np-1)
00268 D[i*np+j] = (np + alpha + beta + one)*(np - one)/
00269 (two*(alpha + two));
00270 else
00271 D[i*np+j] = (alpha - beta - one + (alpha + beta + one)*z[j])/
00272 (two*(one - z[j]*z[j]));
00273 }
00274 }
00275 }
00276 free(pd);
00277 }
00278 return;
00279 }
00280
00281
00282 template <class Scalar>
00283 void IntrepidPolylib::Dglj(Scalar *D, const Scalar *z, const int np, const Scalar alpha, const Scalar beta)
00284 {
00285
00286 if (np <= 0){
00287 D[0] = 0.0;
00288 }
00289 else{
00290 register int i, j;
00291 Scalar one = 1.0, two = 2.0;
00292 Scalar *pd;
00293
00294 pd = (Scalar *)malloc(np*sizeof(Scalar));
00295
00296 pd[0] = two*std::pow(-one,np)*IntrepidPolylib::gammaF((Scalar)np + beta);
00297 pd[0] /= IntrepidPolylib::gammaF((Scalar)np - one)*IntrepidPolylib::gammaF(beta + two);
00298 IntrepidPolylib::jacobd(np-2,z+1,pd+1,np-2,alpha+1,beta+1);
00299 for(i = 1; i < np-1; ++i) pd[i] *= (one-z[i]*z[i]);
00300 pd[np-1] = -two*IntrepidPolylib::gammaF((Scalar)np + alpha);
00301 pd[np-1] /= IntrepidPolylib::gammaF((Scalar)np - one)*IntrepidPolylib::gammaF(alpha + two);
00302
00303 for (i = 0; i < np; i++) {
00304 for (j = 0; j < np; j++){
00305 if (i != j)
00306
00307 D[i*np+j] = pd[i]/(pd[j]*(z[i]-z[j]));
00308 else {
00309 if (j == 0)
00310 D[i*np+j] = (alpha - (np-1)*(np + alpha + beta))/(two*(beta+ two));
00311 else if (j == np-1)
00312 D[i*np+j] =-(beta - (np-1)*(np + alpha + beta))/(two*(alpha+ two));
00313 else
00314 D[i*np+j] = (alpha - beta + (alpha + beta)*z[j])/
00315 (two*(one - z[j]*z[j]));
00316 }
00317 }
00318 }
00319 free(pd);
00320 }
00321 return;
00322 }
00323
00324
00325 template <class Scalar>
00326 Scalar IntrepidPolylib::hgj (const int i, const Scalar z, const Scalar *zgj,
00327 const int np, const Scalar alpha, const Scalar beta)
00328 {
00329
00330 Scalar zi, dz, p, pd, h;
00331
00332 zi = *(zgj+i);
00333 dz = z - zi;
00334 if (std::abs(dz) < INTREPID_TOL) return 1.0;
00335
00336 IntrepidPolylib::jacobd (1, &zi, &pd , np, alpha, beta);
00337 IntrepidPolylib::jacobfd(1, &z , &p, (Scalar*)0 , np, alpha, beta);
00338 h = p/(pd*dz);
00339
00340 return h;
00341 }
00342
00343
00344 template <class Scalar>
00345 Scalar IntrepidPolylib::hgrjm (const int i, const Scalar z, const Scalar *zgrj,
00346 const int np, const Scalar alpha, const Scalar beta)
00347 {
00348
00349 Scalar zi, dz, p, pd, h;
00350
00351 zi = *(zgrj+i);
00352 dz = z - zi;
00353 if (std::abs(dz) < INTREPID_TOL) return 1.0;
00354
00355 IntrepidPolylib::jacobfd (1, &zi, &p , (Scalar*)0, np-1, alpha, beta + 1);
00356
00357 IntrepidPolylib::jacobd (1, &zi, &pd, np-1, alpha, beta + 1);
00358 h = (1.0 + zi)*pd + p;
00359 IntrepidPolylib::jacobfd (1, &z, &p, (Scalar*)0, np-1, alpha, beta + 1);
00360 h = (1.0 + z )*p/(h*dz);
00361
00362 return h;
00363 }
00364
00365
00366 template <class Scalar>
00367 Scalar IntrepidPolylib::hgrjp (const int i, const Scalar z, const Scalar *zgrj,
00368 const int np, const Scalar alpha, const Scalar beta)
00369 {
00370
00371 Scalar zi, dz, p, pd, h;
00372
00373 zi = *(zgrj+i);
00374 dz = z - zi;
00375 if (std::abs(dz) < INTREPID_TOL) return 1.0;
00376
00377 IntrepidPolylib::jacobfd (1, &zi, &p , (Scalar*)0, np-1, alpha+1, beta );
00378
00379 IntrepidPolylib::jacobd (1, &zi, &pd, np-1, alpha+1, beta );
00380 h = (1.0 - zi)*pd - p;
00381 IntrepidPolylib::jacobfd (1, &z, &p, (Scalar*)0, np-1, alpha+1, beta);
00382 h = (1.0 - z )*p/(h*dz);
00383
00384 return h;
00385 }
00386
00387
00388 template <class Scalar>
00389 Scalar IntrepidPolylib::hglj (const int i, const Scalar z, const Scalar *zglj,
00390 const int np, const Scalar alpha, const Scalar beta)
00391 {
00392 Scalar one = 1., two = 2.;
00393 Scalar zi, dz, p, pd, h;
00394
00395 zi = *(zglj+i);
00396 dz = z - zi;
00397 if (std::abs(dz) < INTREPID_TOL) return 1.0;
00398
00399 IntrepidPolylib::jacobfd(1, &zi, &p , (Scalar*)0, np-2, alpha + one, beta + one);
00400
00401 IntrepidPolylib::jacobd (1, &zi, &pd, np-2, alpha + one, beta + one);
00402 h = (one - zi*zi)*pd - two*zi*p;
00403 IntrepidPolylib::jacobfd(1, &z, &p, (Scalar*)0, np-2, alpha + one, beta + one);
00404 h = (one - z*z)*p/(h*dz);
00405
00406 return h;
00407 }
00408
00409
00410 template <class Scalar>
00411 void IntrepidPolylib::Imgj(Scalar *im, const Scalar *zgj, const Scalar *zm, const int nz,
00412 const int mz, const Scalar alpha, const Scalar beta){
00413 Scalar zp;
00414 register int i, j;
00415
00416
00417 for (i = 0; i < mz; ++i) {
00418 zp = zm[i];
00419 for (j = 0; j < nz; ++j) {
00420 im[i*nz+j] = IntrepidPolylib::hgj(j, zp, zgj, nz, alpha, beta);
00421 }
00422 }
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434 return;
00435 }
00436
00437
00438 template <class Scalar>
00439 void IntrepidPolylib::Imgrjm(Scalar *im, const Scalar *zgrj, const Scalar *zm, const int nz,
00440 const int mz, const Scalar alpha, const Scalar beta)
00441 {
00442 Scalar zp;
00443 register int i, j;
00444
00445 for (i = 0; i < mz; i++) {
00446 zp = zm[i];
00447 for (j = 0; j < nz; j++) {
00448 im[i*nz+j] = IntrepidPolylib::hgrjm(j, zp, zgrj, nz, alpha, beta);
00449 }
00450 }
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462 return;
00463 }
00464
00465
00466 template <class Scalar>
00467 void IntrepidPolylib::Imgrjp(Scalar *im, const Scalar *zgrj, const Scalar *zm, const int nz,
00468 const int mz, const Scalar alpha, const Scalar beta)
00469 {
00470 Scalar zp;
00471 register int i, j;
00472
00473 for (i = 0; i < mz; i++) {
00474 zp = zm[i];
00475 for (j = 0; j < nz; j++) {
00476 im [i*nz+j] = IntrepidPolylib::hgrjp(j, zp, zgrj, nz, alpha, beta);
00477 }
00478 }
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490 return;
00491 }
00492
00493
00494 template <class Scalar>
00495 void IntrepidPolylib::Imglj(Scalar *im, const Scalar *zglj, const Scalar *zm, const int nz,
00496 const int mz, const Scalar alpha, const Scalar beta)
00497 {
00498 Scalar zp;
00499 register int i, j;
00500
00501 for (i = 0; i < mz; i++) {
00502 zp = zm[i];
00503 for (j = 0; j < nz; j++) {
00504 im[i*nz+j] = IntrepidPolylib::hglj(j, zp, zglj, nz, alpha, beta);
00505 }
00506 }
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518 return;
00519 }
00520
00521
00522 template <class Scalar>
00523 void IntrepidPolylib::jacobfd(const int np, const Scalar *z, Scalar *poly_in, Scalar *polyd,
00524 const int n, const Scalar alpha, const Scalar beta){
00525 register int i;
00526 Scalar zero = 0.0, one = 1.0, two = 2.0;
00527
00528 if(!np)
00529 return;
00530
00531 if(n == 0){
00532 if(poly_in)
00533 for(i = 0; i < np; ++i)
00534 poly_in[i] = one;
00535 if(polyd)
00536 for(i = 0; i < np; ++i)
00537 polyd[i] = zero;
00538 }
00539 else if (n == 1){
00540 if(poly_in)
00541 for(i = 0; i < np; ++i)
00542 poly_in[i] = 0.5*(alpha - beta + (alpha + beta + two)*z[i]);
00543 if(polyd)
00544 for(i = 0; i < np; ++i)
00545 polyd[i] = 0.5*(alpha + beta + two);
00546 }
00547 else{
00548 register int k;
00549 Scalar a1,a2,a3,a4;
00550 Scalar two = 2.0, apb = alpha + beta;
00551 Scalar *poly, *polyn1,*polyn2;
00552
00553 if(poly_in){
00554 polyn1 = (Scalar *)malloc(2*np*sizeof(Scalar));
00555 polyn2 = polyn1+np;
00556 poly = poly_in;
00557 }
00558 else{
00559 polyn1 = (Scalar *)malloc(3*np*sizeof(Scalar));
00560 polyn2 = polyn1+np;
00561 poly = polyn2+np;
00562 }
00563
00564 for(i = 0; i < np; ++i){
00565 polyn2[i] = one;
00566 polyn1[i] = 0.5*(alpha - beta + (alpha + beta + two)*z[i]);
00567 }
00568
00569 for(k = 2; k <= n; ++k){
00570 a1 = two*k*(k + apb)*(two*k + apb - two);
00571 a2 = (two*k + apb - one)*(alpha*alpha - beta*beta);
00572 a3 = (two*k + apb - two)*(two*k + apb - one)*(two*k + apb);
00573 a4 = two*(k + alpha - one)*(k + beta - one)*(two*k + apb);
00574
00575 a2 /= a1;
00576 a3 /= a1;
00577 a4 /= a1;
00578
00579 for(i = 0; i < np; ++i){
00580 poly [i] = (a2 + a3*z[i])*polyn1[i] - a4*polyn2[i];
00581 polyn2[i] = polyn1[i];
00582 polyn1[i] = poly [i];
00583 }
00584 }
00585
00586 if(polyd){
00587 a1 = n*(alpha - beta);
00588 a2 = n*(two*n + alpha + beta);
00589 a3 = two*(n + alpha)*(n + beta);
00590 a4 = (two*n + alpha + beta);
00591 a1 /= a4; a2 /= a4; a3 /= a4;
00592
00593
00594 for(i = 0; i < np; ++i){
00595 polyd[i] = (a1- a2*z[i])*poly[i] + a3*polyn2[i];
00596 polyd[i] /= (one - z[i]*z[i]);
00597 }
00598 }
00599
00600 free(polyn1);
00601 }
00602
00603 return;
00604 }
00605
00606
00607 template <class Scalar>
00608 void IntrepidPolylib::jacobd(const int np, const Scalar *z, Scalar *polyd, const int n,
00609 const Scalar alpha, const Scalar beta)
00610 {
00611 register int i;
00612 Scalar one = 1.0;
00613 if(n == 0)
00614 for(i = 0; i < np; ++i) polyd[i] = 0.0;
00615 else{
00616
00617 IntrepidPolylib::jacobfd(np,z,polyd,(Scalar*)0,n-1,alpha+one,beta+one);
00618 for(i = 0; i < np; ++i) polyd[i] *= 0.5*(alpha + beta + (Scalar)n + one);
00619 }
00620 return;
00621 }
00622
00623
00624 template <class Scalar>
00625 void IntrepidPolylib::Jacobz(const int n, Scalar *z, const Scalar alpha, const Scalar beta){
00626 register int i,j,k;
00627 Scalar dth = M_PI/(2.0*(Scalar)n);
00628 Scalar poly,pder,rlast=0.0;
00629 Scalar sum,delr,r;
00630 Scalar one = 1.0, two = 2.0;
00631
00632 if(!n)
00633 return;
00634
00635 for(k = 0; k < n; ++k){
00636 r = -std::cos((two*(Scalar)k + one) * dth);
00637 if(k) r = 0.5*(r + rlast);
00638
00639 for(j = 1; j < INTREPID_POLYLIB_STOP; ++j){
00640 IntrepidPolylib::jacobfd(1,&r,&poly, &pder, n, alpha, beta);
00641
00642 for(i = 0, sum = 0.0; i < k; ++i) sum += one/(r - z[i]);
00643
00644 delr = -poly / (pder - sum * poly);
00645 r += delr;
00646 if( std::abs(delr) < INTREPID_TOL ) break;
00647 }
00648 z[k] = r;
00649 rlast = r;
00650 }
00651 return;
00652 }
00653
00654
00655 template <class Scalar>
00656 void IntrepidPolylib::JacZeros(const int n, Scalar *a, const Scalar alpha, const Scalar beta){
00657 int i;
00658 Scalar apb, apbi,a2b2;
00659 Scalar *b;
00660
00661 if(!n)
00662 return;
00663
00664 b = (Scalar *) malloc(n*sizeof(Scalar));
00665
00666
00667 apb = alpha + beta;
00668 apbi = 2.0 + apb;
00669
00670 b[n-1] = std::pow(2.0,apb+1.0)*IntrepidPolylib::gammaF(alpha+1.0)*IntrepidPolylib::gammaF(beta+1.0)/gammaF(apbi);
00671 a[0] = (beta-alpha)/apbi;
00672 b[0] = std::sqrt(4.0*(1.0+alpha)*(1.0+beta)/((apbi+1.0)*apbi*apbi));
00673
00674 a2b2 = beta*beta-alpha*alpha;
00675 for(i = 1; i < n-1; ++i){
00676 apbi = 2.0*(i+1) + apb;
00677 a[i] = a2b2/((apbi-2.0)*apbi);
00678 b[i] = std::sqrt(4.0*(i+1)*(i+1+alpha)*(i+1+beta)*(i+1+apb)/
00679 ((apbi*apbi-1)*apbi*apbi));
00680 }
00681
00682 apbi = 2.0*n + apb;
00683
00684 if (n>1) a[n-1] = a2b2/((apbi-2.0)*apbi);
00685
00686
00687 IntrepidPolylib::TriQL(n, a, b);
00688
00689 free(b);
00690 return;
00691 }
00692
00693
00694 template <class Scalar>
00695 void IntrepidPolylib::TriQL(const int n, Scalar *d,Scalar *e) {
00696 int m,l,iter,i,k;
00697 Scalar s,r,p,g,f,dd,c,b;
00698
00699 for (l=0;l<n;l++) {
00700 iter=0;
00701 do {
00702 for (m=l;m<n-1;m++) {
00703 dd=std::abs(d[m])+std::abs(d[m+1]);
00704 if (std::abs(e[m])+dd == dd) break;
00705 }
00706 if (m != l) {
00707 if (iter++ == 50){
00708 TEST_FOR_EXCEPTION((1),
00709 std::runtime_error,
00710 ">>> ERROR (IntrepidPolylib): Too many iterations in TQLI.");
00711 }
00712 g=(d[l+1]-d[l])/(2.0*e[l]);
00713 r=std::sqrt((g*g)+1.0);
00714
00715 g=d[m]-d[l]+e[l]/(g+((g)<0 ? -std::abs(r) : std::abs(r)));
00716 s=c=1.0;
00717 p=0.0;
00718 for (i=m-1;i>=l;i--) {
00719 f=s*e[i];
00720 b=c*e[i];
00721 if (std::abs(f) >= std::abs(g)) {
00722 c=g/f;
00723 r=std::sqrt((c*c)+1.0);
00724 e[i+1]=f*r;
00725 c *= (s=1.0/r);
00726 } else {
00727 s=f/g;
00728 r=std::sqrt((s*s)+1.0);
00729 e[i+1]=g*r;
00730 s *= (c=1.0/r);
00731 }
00732 g=d[i+1]-p;
00733 r=(d[i]-g)*s+2.0*c*b;
00734 p=s*r;
00735 d[i+1]=g+p;
00736 g=c*r-b;
00737 }
00738 d[l]=d[l]-p;
00739 e[l]=g;
00740 e[m]=0.0;
00741 }
00742 } while (m != l);
00743 }
00744
00745
00746 for(i = 0; i < n-1; ++i){
00747 k = i;
00748 p = d[i];
00749 for(l = i+1; l < n; ++l)
00750 if (d[l] < p) {
00751 k = l;
00752 p = d[l];
00753 }
00754 d[k] = d[i];
00755 d[i] = p;
00756 }
00757 }
00758
00759
00760 template <class Scalar>
00761 Scalar IntrepidPolylib::gammaF(const Scalar x){
00762 Scalar gamma = 1.0;
00763
00764 if (x == -0.5) gamma = -2.0*std::sqrt(M_PI);
00765 else if (!x) return gamma;
00766 else if ((x-(int)x) == 0.5){
00767 int n = (int) x;
00768 Scalar tmp = x;
00769
00770 gamma = std::sqrt(M_PI);
00771 while(n--){
00772 tmp -= 1.0;
00773 gamma *= tmp;
00774 }
00775 }
00776 else if ((x-(int)x) == 0.0){
00777 int n = (int) x;
00778 Scalar tmp = x;
00779
00780 while(--n){
00781 tmp -= 1.0;
00782 gamma *= tmp;
00783 }
00784 }
00785 else
00786 TEST_FOR_EXCEPTION((1),
00787 std::invalid_argument,
00788 ">>> ERROR (IntrepidPolylib): Argument is not of integer or half order.");
00789 return gamma;
00790 }
00791
00792 }
00793