Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00014 #include <fvar.hpp>
00015
00016
00017
00018
00019 void imtqlx ( const dvector& _d, const dvector& _e, const dvector& _z );
00020
00025 double sign(const double x)
00026 {
00027 return x < 0.0 ? -1.0 : 1.0;
00028 }
00029
00036 void gauss_hermite (const dvector& _t,const dvector& _wts)
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 dvector t=(dvector&) _t;
00081 dvector wts=(dvector&) _wts;
00082
00083 if( t.indexmax()!=wts.indexmax() )
00084 {
00085 cerr << "Incompatible sizes in void "
00086 << "void gauss_hermite (const dvector& _t,const dvector& _wts)" << endl;
00087 ad_exit(-1);
00088 }
00089
00090 int lb = t.indexmin();
00091 int ub = t.indexmax();
00092
00093 dvector aj(lb,ub);
00094 dvector bj(lb,ub);
00095 double zemu;
00096 int i;
00097
00098
00099 zemu = 1.772453850905516;
00100 for ( i = lb; i <= ub; i++ )
00101 {
00102 aj(i) = 0.0;
00103 }
00104 for ( i = lb; i <= ub; i++ )
00105 {
00106 bj(i) = sqrt((i-lb+1)/2.0);
00107 }
00108
00109
00110 if ( zemu <= 0.0 )
00111 {
00112 cout << "\n";
00113 cout << "SGQF - Fatal error!\n";
00114 cout << " ZEMU <= 0.\n";
00115 exit ( 1 );
00116 }
00117
00118
00119 for ( i = lb; i <= ub; i++ )
00120 {
00121 t(i) = aj(i);
00122 }
00123 wts(lb) = sqrt ( zemu );
00124 for ( i = lb+1; i <= ub; i++ )
00125 {
00126 wts(i) = 0.0;
00127 }
00128
00129
00130 imtqlx ( t, bj, wts );
00131
00132 for ( i = lb; i <= ub; i++ )
00133 {
00134 wts(i) = wts(i) * wts(i);
00135 }
00136
00137 return;
00138 }
00139
00148 void gauss_legendre( double a, double b, const dvector& _t,
00149 const dvector& _wts )
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193 {
00194 dvector t=(dvector&) _t;
00195 dvector wts=(dvector&) _wts;
00196
00197 if( t.indexmax()!=wts.indexmax() )
00198 {
00199 cerr << "Incompatible sizes in void "
00200 "mygauss_legendre(double a, double b, const dvector& _t, const dvector& _wts)"
00201 << endl;
00202 ad_exit(-1);
00203 }
00204
00205 t.shift(0);
00206 wts.shift(0);
00207 int nt = t.indexmax() + 1;
00208 int ub = nt-1;
00209
00210 int i;
00211 int k;
00212 int l;
00213 double al;
00214 double ab;
00215 double abi;
00216 double abj;
00217 double be;
00218 double p;
00219 double shft;
00220 double slp;
00221 double temp;
00222 double tmp;
00223 double zemu;
00224
00225
00226 dvector aj(0,ub);
00227 dvector bj(0,ub);
00228
00229 ab = 0.0;
00230 zemu = 2.0 / ( ab + 1.0 );
00231 for ( i = 0; i < nt; i++ )
00232 {
00233 aj[i] = 0.0;
00234 }
00235 for ( i = 1; i <= nt; i++ )
00236 {
00237 abi = i + ab * ( i % 2 );
00238 abj = 2 * i + ab;
00239 bj[i-1] = sqrt ( abi * abi / ( abj * abj - 1.0 ) );
00240 }
00241
00242
00243 if ( zemu <= 0.0 )
00244 {
00245 cout << "\n";
00246 cout << "Fatal error!\n";
00247 cout << " ZEMU <= 0.\n";
00248 exit ( 1 );
00249 }
00250
00251
00252 for ( i = 0; i < nt; i++ )
00253 {
00254 t[i] = aj[i];
00255 }
00256 wts[0] = sqrt ( zemu );
00257 for ( i = 1; i < nt; i++ )
00258 {
00259 wts[i] = 0.0;
00260 }
00261
00262
00263 imtqlx (t, bj, wts );
00264
00265 for ( i = 0; i < nt; i++ )
00266 {
00267 wts[i] = wts[i] * wts[i];
00268 }
00269
00270
00271
00272 ivector mlt(0,ub);
00273 for ( i = 0; i < nt; i++ )
00274 {
00275 mlt[i] = 1;
00276 }
00277 ivector ndx(0,ub);
00278 for ( i = 0; i < nt; i++ )
00279 {
00280 ndx[i] = i + 1;
00281 }
00282
00283 dvector st(0,ub);
00284 dvector swts(0,ub);
00285
00286 temp = 3.0e-14;
00287 al = 0.0;
00288 be = 0.0;
00289 if ( fabs ( b - a ) <= temp )
00290 {
00291 cout << "\n";
00292 cout << "Fatal error!\n";
00293 cout << " |B - A| too small.\n";
00294 exit ( 1 );
00295 }
00296 shft = ( a + b ) / 2.0;
00297 slp = ( b - a ) / 2.0;
00298
00299 p = pow ( slp, al + be + 1.0 );
00300
00301 for ( k = 0; k < nt; k++ )
00302 {
00303 st[k] = shft + slp * t[k];
00304 l = abs ( ndx[k] );
00305
00306 if ( l != 0 )
00307 {
00308 tmp = p;
00309 for ( i = l - 1; i <= l - 1 + mlt[k] - 1; i++ )
00310 {
00311 swts[i] = wts[i] * tmp;
00312 tmp = tmp * slp;
00313 }
00314 }
00315 }
00316
00317 for(i=0;i<nt;i++)
00318 {
00319 t(i) = st(ub-i);
00320 wts(i) = swts(ub-i);
00321 }
00322
00323 return;
00324 }
00325
00331 void gauss_legendre(const dvector& _x, const dvector& _w)
00332 {
00333 gauss_legendre(0,1,_x,_w);
00334 }
00335
00343 void normalized_gauss_hermite(const dvector& _x, const dvector& _w)
00344 {
00345 dvector& x=(dvector&) _x;
00346 dvector& w=(dvector&) _w;
00347 gauss_hermite(x,w);
00348 w=elem_prod(w,exp(square(x)));
00349 x*=sqrt(2.0);
00350 w*=sqrt(2.0);
00351 }
00352
00359 void imtqlx( const dvector& _d, const dvector& _e, const dvector& _z )
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417 {
00418 dvector d=(dvector&) _d;
00419 dvector e=(dvector&) _e;
00420 dvector z=(dvector&) _z;
00421 if (d.indexmax()!=e.indexmax() || d.indexmax()!=z.indexmax() ||
00422 z.indexmax()!=e.indexmax() )
00423 {
00424 cerr << "Incompatible sizes in void "
00425 << "imtqlx ( const dvector& _d, const dvector& _e, const dvector& _z )"
00426 << endl;
00427 ad_exit(-1);
00428 }
00429
00430 int lb = d.indexmin();
00431 d.shift(0);
00432 e.shift(0);
00433 z.shift(0);
00434 int n = d.indexmax() + 1;
00435
00436 double b;
00437 double c;
00438 double f;
00439 double g;
00440 int i;
00441 int ii;
00442 int itn = 30;
00443 int j;
00444 int k;
00445 int l;
00446 int m;
00447 int mml;
00448 double p;
00449 double prec;
00450 double r;
00451 double s;
00452
00453 prec = 3.0e-14;
00454
00455 if ( n == 1 )
00456 {
00457 return;
00458 }
00459
00460 e[n-1] = 0.0;
00461
00462 for ( l = 1; l <= n; l++ )
00463 {
00464 j = 0;
00465 for ( ; ; )
00466 {
00467 for ( m = l; m <= n; m++ )
00468 {
00469 if ( m == n )
00470 {
00471 break;
00472 }
00473
00474 if ( fabs ( e[m-1] ) <= prec * ( fabs ( d[m-1] ) + fabs ( d[m] ) ) )
00475 {
00476 break;
00477 }
00478 }
00479 p = d[l-1];
00480 if ( m == l )
00481 {
00482 break;
00483 }
00484 if ( itn <= j )
00485 {
00486 cout << "\n";
00487 cout << "IMTQLX - Fatal error!\n";
00488 cout << " Iteration limit exceeded\n";
00489 exit ( 1 );
00490 }
00491 j = j + 1;
00492 g = ( d[l] - p ) / ( 2.0 * e[l-1] );
00493 r = sqrt ( g * g + 1.0 );
00494 g = d[m-1] - p + e[l-1] / ( g + fabs ( r ) * sign ( g ) );
00495 s = 1.0;
00496 c = 1.0;
00497 p = 0.0;
00498 mml = m - l;
00499
00500 for ( ii = 1; ii <= mml; ii++ )
00501 {
00502 i = m - ii;
00503 f = s * e[i-1];
00504 b = c * e[i-1];
00505
00506 if ( fabs ( g ) <= fabs ( f ) )
00507 {
00508 c = g / f;
00509 r = sqrt ( c * c + 1.0 );
00510 e[i] = f * r;
00511 s = 1.0 / r;
00512 c = c * s;
00513 }
00514 else
00515 {
00516 s = f / g;
00517 r = sqrt ( s * s + 1.0 );
00518 e[i] = g * r;
00519 c = 1.0 / r;
00520 s = s * c;
00521 }
00522 g = d[i] - p;
00523 r = ( d[i-1] - g ) * s + 2.0 * c * b;
00524 p = s * r;
00525 d[i] = g + p;
00526 g = c * r - b;
00527 f = z[i];
00528 z[i] = s * z[i-1] + c * f;
00529 z[i-1] = c * z[i-1] - s * f;
00530 }
00531 d[l-1] = d[l-1] - p;
00532 e[l-1] = g;
00533 e[m-1] = 0.0;
00534 }
00535 }
00536
00537 m = n;
00538
00539
00540 for ( ii = 2; ii <= m; ii++ )
00541 {
00542 i = ii - 1;
00543 k = i;
00544 p = d[i-1];
00545
00546 for ( j = ii; j <= n; j++ )
00547 {
00548 if ( d[j-1] > p )
00549 {
00550 k = j;
00551 p = d[j-1];
00552 }
00553 }
00554
00555 if ( k != i )
00556 {
00557 d[k-1] = d[i-1];
00558 d[i-1] = p;
00559 p = z[i-1];
00560 z[i-1] = z[k-1];
00561 z[k-1] = p;
00562 }
00563 }
00564
00565 d.shift(lb);
00566 e.shift(lb);
00567 z.shift(lb);
00568 return;
00569 }