legendre_rule.cpp 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515
  1. # include <cstdlib>
  2. # include <cmath>
  3. # include <iostream>
  4. # include <fstream>
  5. # include <iomanip>
  6. # include <ctime>
  7. # include <cstring>
  8. # include <cassert>
  9. # include <legendre_rule.hpp>
  10. //using namespace std;
  11. //****************************************************************************80
  12. /*
  13. int main ( int argc, char *argv[] )
  14. // ***************************************************************************80
  15. //
  16. // Purpose:
  17. //
  18. // MAIN is the main program for LEGENDRE_RULE.
  19. //
  20. // Discussion:
  21. //
  22. // This program computes a standard Gauss-Legendre quadrature rule
  23. // and writes it to a file.
  24. //
  25. // The user specifies:
  26. // * the ORDER (number of points) in the rule
  27. // * A, the left endpoint;
  28. // * B, the right endpoint;
  29. // * FILENAME, the root name of the output files.
  30. //
  31. // Licensing:
  32. //
  33. // This code is distributed under the GNU LGPL license.
  34. //
  35. // Modified:
  36. //
  37. // 23 February 2010
  38. //
  39. // Author:
  40. //
  41. // John Burkardt
  42. //
  43. {
  44. double a;
  45. double alpha;
  46. double b;
  47. double beta;
  48. string filename;
  49. int kind;
  50. int order;
  51. double *r;
  52. double *w;
  53. double *x;
  54. timestamp ( );
  55. std::cout << "\n";
  56. std::cout << "LEGENDRE_RULE\n";
  57. std::cout << " C++ version\n";
  58. std::cout << "\n";
  59. std::cout << " Compiled on " << __DATE__ << " at " << __TIME__ << ".\n";
  60. std::cout << "\n";
  61. std::cout << " Compute a Gauss-Legendre rule for approximating\n";
  62. std::cout << "\n";
  63. std::cout << " Integral ( A <= x <= B ) f(x) dx\n";
  64. std::cout << "\n";
  65. std::cout << " of order ORDER.\n";
  66. std::cout << "\n";
  67. std::cout << " The user specifies ORDER, A, B and FILENAME.\n";
  68. std::cout << "\n";
  69. std::cout << " Order is the number of points.\n";
  70. std::cout << "\n";
  71. std::cout << " A is the left endpoint.\n";
  72. std::cout << "\n";
  73. std::cout << " B is the right endpoint.\n";
  74. std::cout << "\n";
  75. std::cout << " FILENAME is used to generate 3 files:\n";
  76. std::cout << "\n";
  77. std::cout << " filename_w.txt - the weight file\n";
  78. std::cout << " filename_x.txt - the abscissa file.\n";
  79. std::cout << " filename_r.txt - the region file.\n";
  80. //
  81. // Initialize parameters;
  82. //
  83. alpha = 0.0;
  84. beta = 0.0;
  85. //
  86. // Get ORDER.
  87. //
  88. if ( 1 < argc )
  89. {
  90. order = atoi ( argv[1] );
  91. }
  92. else
  93. {
  94. std::cout << "\n";
  95. std::cout << " Enter the value of ORDER (1 or greater)\n";
  96. cin >> order;
  97. }
  98. //
  99. // Get A.
  100. //
  101. if ( 2 < argc )
  102. {
  103. a = atof ( argv[2] );
  104. }
  105. else
  106. {
  107. std::cout << "\n";
  108. std::cout << " Enter the value of A:\n";
  109. cin >> a;
  110. }
  111. //
  112. // Get B.
  113. //
  114. if ( 3 < argc )
  115. {
  116. b = atof ( argv[3] );
  117. }
  118. else
  119. {
  120. std::cout << "\n";
  121. std::cout << " Enter the value of B:\n";
  122. cin >> b;
  123. }
  124. //
  125. // Get FILENAME:
  126. //
  127. if ( 4 < argc )
  128. {
  129. filename = argv[4];
  130. }
  131. else
  132. {
  133. std::cout << "\n";
  134. std::cout << " Enter FILENAME, the \"root name\" of the quadrature files).\n";
  135. cin >> filename;
  136. }
  137. //
  138. // Input summary.
  139. //
  140. std::cout << "\n";
  141. std::cout << " ORDER = " << order << "\n";
  142. std::cout << " A = " << a << "\n";
  143. std::cout << " B = " << b << "\n";
  144. std::cout << " FILENAME = \"" << filename << "\".\n";
  145. //
  146. // Construct the rule.
  147. //
  148. w = new double[order];
  149. x = new double[order];
  150. kind = 1;
  151. cgqf ( order, kind, alpha, beta, a, b, x, w );
  152. //
  153. // Write the rule.
  154. //
  155. r = new double[2];
  156. r[0] = a;
  157. r[1] = b;
  158. rule_write ( order, filename, x, w, r );
  159. //
  160. // Terminate.
  161. //
  162. delete [] r;
  163. delete [] w;
  164. delete [] x;
  165. std::cout << "\n";
  166. std::cout << "LEGENDRE_RULE:\n";
  167. std::cout << " Normal end of execution.\n";
  168. std::cout << "\n";
  169. timestamp ( );
  170. return 0;
  171. }*/
  172. //****************************************************************************80
  173. void cdgqf ( int nt, int kind, double alpha, double beta, double t[],
  174. double wts[] )
  175. //****************************************************************************80
  176. //
  177. // Purpose:
  178. //
  179. // CDGQF computes a Gauss quadrature formula with default A, B and simple knots.
  180. //
  181. // Discussion:
  182. //
  183. // This routine computes all the knots and weights of a Gauss quadrature
  184. // formula with a classical weight function with default values for A and B,
  185. // and only simple knots.
  186. //
  187. // There are no moments checks and no printing is done.
  188. //
  189. // Use routine EIQFS to evaluate a quadrature computed by CGQFS.
  190. //
  191. // Licensing:
  192. //
  193. // This code is distributed under the GNU LGPL license.
  194. //
  195. // Modified:
  196. //
  197. // 08 January 2010
  198. //
  199. // Author:
  200. //
  201. // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky.
  202. // C++ version by John Burkardt.
  203. //
  204. // Reference:
  205. //
  206. // Sylvan Elhay, Jaroslav Kautsky,
  207. // Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of
  208. // Interpolatory Quadrature,
  209. // ACM Transactions on Mathematical Software,
  210. // Volume 13, Number 4, December 1987, pages 399-415.
  211. //
  212. // Parameters:
  213. //
  214. // Input, int NT, the number of knots.
  215. //
  216. // Input, int KIND, the rule.
  217. // 1, Legendre, (a,b) 1.0
  218. // 2, Chebyshev Type 1, (a,b) ((b-x)*(x-a))^(-0.5)
  219. // 3, Gegenbauer, (a,b) ((b-x)*(x-a))^alpha
  220. // 4, Jacobi, (a,b) (b-x)^alpha*(x-a)^beta
  221. // 5, Generalized Laguerre, (a,inf) (x-a)^alpha*exp(-b*(x-a))
  222. // 6, Generalized Hermite, (-inf,inf) |x-a|^alpha*exp(-b*(x-a)^2)
  223. // 7, Exponential, (a,b) |x-(a+b)/2.0|^alpha
  224. // 8, Rational, (a,inf) (x-a)^alpha*(x+b)^beta
  225. //
  226. // Input, double ALPHA, the value of Alpha, if needed.
  227. //
  228. // Input, double BETA, the value of Beta, if needed.
  229. //
  230. // Output, double T[NT], the knots.
  231. //
  232. // Output, double WTS[NT], the weights.
  233. //
  234. {
  235. double *aj;
  236. double *bj;
  237. double zemu;
  238. parchk ( kind, 2 * nt, alpha, beta );
  239. //
  240. // Get the Jacobi matrix and zero-th moment.
  241. //
  242. aj = new double[nt];
  243. bj = new double[nt];
  244. zemu = class_matrix ( kind, nt, alpha, beta, aj, bj );
  245. //
  246. // Compute the knots and weights.
  247. //
  248. sgqf ( nt, aj, bj, zemu, t, wts );
  249. delete [] aj;
  250. delete [] bj;
  251. return;
  252. }
  253. //****************************************************************************80
  254. void cgqf ( int nt, int kind, double alpha, double beta, double a, double b,
  255. double t[], double wts[] )
  256. //****************************************************************************80
  257. //
  258. // Purpose:
  259. //
  260. // CGQF computes knots and weights of a Gauss quadrature formula.
  261. //
  262. // Discussion:
  263. //
  264. // The user may specify the interval (A,B).
  265. //
  266. // Only simple knots are produced.
  267. //
  268. // Use routine EIQFS to evaluate this quadrature formula.
  269. //
  270. // Licensing:
  271. //
  272. // This code is distributed under the GNU LGPL license.
  273. //
  274. // Modified:
  275. //
  276. // 16 February 2010
  277. //
  278. // Author:
  279. //
  280. // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky.
  281. // C++ version by John Burkardt.
  282. //
  283. // Reference:
  284. //
  285. // Sylvan Elhay, Jaroslav Kautsky,
  286. // Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of
  287. // Interpolatory Quadrature,
  288. // ACM Transactions on Mathematical Software,
  289. // Volume 13, Number 4, December 1987, pages 399-415.
  290. //
  291. // Parameters:
  292. //
  293. // Input, int NT, the number of knots.
  294. //
  295. // Input, int KIND, the rule.
  296. // 1, Legendre, (a,b) 1.0
  297. // 2, Chebyshev Type 1, (a,b) ((b-x)*(x-a))^-0.5)
  298. // 3, Gegenbauer, (a,b) ((b-x)*(x-a))^alpha
  299. // 4, Jacobi, (a,b) (b-x)^alpha*(x-a)^beta
  300. // 5, Generalized Laguerre, (a,+oo) (x-a)^alpha*exp(-b*(x-a))
  301. // 6, Generalized Hermite, (-oo,+oo) |x-a|^alpha*exp(-b*(x-a)^2)
  302. // 7, Exponential, (a,b) |x-(a+b)/2.0|^alpha
  303. // 8, Rational, (a,+oo) (x-a)^alpha*(x+b)^beta
  304. // 9, Chebyshev Type 2, (a,b) ((b-x)*(x-a))^(+0.5)
  305. //
  306. // Input, double ALPHA, the value of Alpha, if needed.
  307. //
  308. // Input, double BETA, the value of Beta, if needed.
  309. //
  310. // Input, double A, B, the interval endpoints, or
  311. // other parameters.
  312. //
  313. // Output, double T[NT], the knots.
  314. //
  315. // Output, double WTS[NT], the weights.
  316. //
  317. {
  318. int i;
  319. int *mlt;
  320. int *ndx;
  321. //
  322. // Compute the Gauss quadrature formula for default values of A and B.
  323. //
  324. cdgqf ( nt, kind, alpha, beta, t, wts );
  325. //
  326. // Prepare to scale the quadrature formula to other weight function with
  327. // valid A and B.
  328. //
  329. mlt = new int[nt];
  330. for ( i = 0; i < nt; i++ )
  331. {
  332. mlt[i] = 1;
  333. }
  334. ndx = new int[nt];
  335. for ( i = 0; i < nt; i++ )
  336. {
  337. ndx[i] = i + 1;
  338. }
  339. scqf ( nt, t, mlt, wts, nt, ndx, wts, t, kind, alpha, beta, a, b );
  340. delete [] mlt;
  341. delete [] ndx;
  342. return;
  343. }
  344. //****************************************************************************80
  345. double class_matrix ( int kind, int m, double alpha, double beta, double aj[],
  346. double bj[] )
  347. //****************************************************************************80
  348. //
  349. // Purpose:
  350. //
  351. // CLASS_MATRIX computes the Jacobi matrix for a quadrature rule.
  352. //
  353. // Discussion:
  354. //
  355. // This routine computes the diagonal AJ and sub-diagonal BJ
  356. // elements of the order M tridiagonal symmetric Jacobi matrix
  357. // associated with the polynomials orthogonal with respect to
  358. // the weight function specified by KIND.
  359. //
  360. // For weight functions 1-7, M elements are defined in BJ even
  361. // though only M-1 are needed. For weight function 8, BJ(M) is
  362. // set to zero.
  363. //
  364. // The zero-th moment of the weight function is returned in ZEMU.
  365. //
  366. // Licensing:
  367. //
  368. // This code is distributed under the GNU LGPL license.
  369. //
  370. // Modified:
  371. //
  372. // 08 January 2010
  373. //
  374. // Author:
  375. //
  376. // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky.
  377. // C++ version by John Burkardt.
  378. //
  379. // Reference:
  380. //
  381. // Sylvan Elhay, Jaroslav Kautsky,
  382. // Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of
  383. // Interpolatory Quadrature,
  384. // ACM Transactions on Mathematical Software,
  385. // Volume 13, Number 4, December 1987, pages 399-415.
  386. //
  387. // Parameters:
  388. //
  389. // Input, int KIND, the rule.
  390. // 1, Legendre, (a,b) 1.0
  391. // 2, Chebyshev Type 1, (a,b) ((b-x)*(x-a))^(-0.5)
  392. // 3, Gegenbauer, (a,b) ((b-x)*(x-a))^alpha
  393. // 4, Jacobi, (a,b) (b-x)^alpha*(x-a)^beta
  394. // 5, Generalized Laguerre, (a,inf) (x-a)^alpha*exp(-b*(x-a))
  395. // 6, Generalized Hermite, (-inf,inf) |x-a|^alpha*exp(-b*(x-a)^2)
  396. // 7, Exponential, (a,b) |x-(a+b)/2.0|^alpha
  397. // 8, Rational, (a,inf) (x-a)^alpha*(x+b)^beta
  398. //
  399. // Input, int M, the order of the Jacobi matrix.
  400. //
  401. // Input, double ALPHA, the value of Alpha, if needed.
  402. //
  403. // Input, double BETA, the value of Beta, if needed.
  404. //
  405. // Output, double AJ[M], BJ[M], the diagonal and subdiagonal
  406. // of the Jacobi matrix.
  407. //
  408. // Output, double CLASS_MATRIX, the zero-th moment.
  409. //
  410. {
  411. double a2b2;
  412. double ab;
  413. double aba;
  414. double abi;
  415. double abj;
  416. double abti;
  417. double apone;
  418. int i;
  419. double pi = 3.14159265358979323846264338327950;
  420. double zemu=0;
  421. parchk ( kind, 2 * m - 1, alpha, beta );
  422. /*
  423. double temp = r8_epsilon ( );
  424. double temp2 = 0.5;
  425. if ( 500.0 * temp < r8_abs ( pow ( tgamma ( temp2 ), 2 ) - pi ) )
  426. {
  427. std::cout << "\n";
  428. std::cout << "CLASS_MATRIX - Fatal error!\n";
  429. std::cout << " Gamma function does not match machine parameters.\n";
  430. exit ( 1 );
  431. }
  432. */
  433. if ( kind == 1 )
  434. {
  435. ab = 0.0;
  436. zemu = 2.0 / ( ab + 1.0 );
  437. for ( i = 0; i < m; i++ )
  438. {
  439. aj[i] = 0.0;
  440. }
  441. for ( i = 1; i <= m; i++ )
  442. {
  443. abi = i + ab * ( i % 2 );
  444. abj = 2 * i + ab;
  445. bj[i-1] = sqrt ( abi * abi / ( abj * abj - 1.0 ) );
  446. }
  447. }
  448. else if ( kind == 2 )
  449. {
  450. zemu = pi;
  451. for ( i = 0; i < m; i++ )
  452. {
  453. aj[i] = 0.0;
  454. }
  455. bj[0] = sqrt ( 0.5 );
  456. for ( i = 1; i < m; i++ )
  457. {
  458. bj[i] = 0.5;
  459. }
  460. }
  461. else if ( kind == 3 )
  462. {
  463. ab = alpha * 2.0;
  464. zemu = pow ( 2.0, ab + 1.0 ) * pow ( tgamma ( alpha + 1.0 ), 2 )
  465. / tgamma ( ab + 2.0 );
  466. for ( i = 0; i < m; i++ )
  467. {
  468. aj[i] = 0.0;
  469. }
  470. bj[0] = sqrt ( 1.0 / ( 2.0 * alpha + 3.0 ) );
  471. for ( i = 2; i <= m; i++ )
  472. {
  473. bj[i-1] = sqrt ( i * ( i + ab ) / ( 4.0 * pow ( i + alpha, 2 ) - 1.0 ) );
  474. }
  475. }
  476. else if ( kind == 4 )
  477. {
  478. ab = alpha + beta;
  479. abi = 2.0 + ab;
  480. zemu = pow ( 2.0, ab + 1.0 ) * tgamma ( alpha + 1.0 )
  481. * tgamma ( beta + 1.0 ) / tgamma ( abi );
  482. aj[0] = ( beta - alpha ) / abi;
  483. bj[0] = sqrt ( 4.0 * ( 1.0 + alpha ) * ( 1.0 + beta )
  484. / ( ( abi + 1.0 ) * abi * abi ) );
  485. a2b2 = beta * beta - alpha * alpha;
  486. for ( i = 2; i <= m; i++ )
  487. {
  488. abi = 2.0 * i + ab;
  489. aj[i-1] = a2b2 / ( ( abi - 2.0 ) * abi );
  490. abi = abi * abi;
  491. bj[i-1] = sqrt ( 4.0 * i * ( i + alpha ) * ( i + beta ) * ( i + ab )
  492. / ( ( abi - 1.0 ) * abi ) );
  493. }
  494. }
  495. else if ( kind == 5 )
  496. {
  497. zemu = tgamma ( alpha + 1.0 );
  498. for ( i = 1; i <= m; i++ )
  499. {
  500. aj[i-1] = 2.0 * i - 1.0 + alpha;
  501. bj[i-1] = sqrt ( i * ( i + alpha ) );
  502. }
  503. }
  504. else if ( kind == 6 )
  505. {
  506. zemu = tgamma ( ( alpha + 1.0 ) / 2.0 );
  507. for ( i = 0; i < m; i++ )
  508. {
  509. aj[i] = 0.0;
  510. }
  511. for ( i = 1; i <= m; i++ )
  512. {
  513. bj[i-1] = sqrt ( ( i + alpha * ( i % 2 ) ) / 2.0 );
  514. }
  515. }
  516. else if ( kind == 7 )
  517. {
  518. ab = alpha;
  519. zemu = 2.0 / ( ab + 1.0 );
  520. for ( i = 0; i < m; i++ )
  521. {
  522. aj[i] = 0.0;
  523. }
  524. for ( i = 1; i <= m; i++ )
  525. {
  526. abi = i + ab * ( i % 2 );
  527. abj = 2 * i + ab;
  528. bj[i-1] = sqrt ( abi * abi / ( abj * abj - 1.0 ) );
  529. }
  530. }
  531. else if ( kind == 8 )
  532. {
  533. ab = alpha + beta;
  534. zemu = tgamma ( alpha + 1.0 ) * tgamma ( - ( ab + 1.0 ) )
  535. / tgamma ( - beta );
  536. apone = alpha + 1.0;
  537. aba = ab * apone;
  538. aj[0] = - apone / ( ab + 2.0 );
  539. bj[0] = - aj[0] * ( beta + 1.0 ) / ( ab + 2.0 ) / ( ab + 3.0 );
  540. for ( i = 2; i <= m; i++ )
  541. {
  542. abti = ab + 2.0 * i;
  543. aj[i-1] = aba + 2.0 * ( ab + i ) * ( i - 1 );
  544. aj[i-1] = - aj[i-1] / abti / ( abti - 2.0 );
  545. }
  546. for ( i = 2; i <= m - 1; i++ )
  547. {
  548. abti = ab + 2.0 * i;
  549. bj[i-1] = i * ( alpha + i ) / ( abti - 1.0 ) * ( beta + i )
  550. / ( abti * abti ) * ( ab + i ) / ( abti + 1.0 );
  551. }
  552. bj[m-1] = 0.0;
  553. for ( i = 0; i < m; i++ )
  554. {
  555. bj[i] = sqrt ( bj[i] );
  556. }
  557. }
  558. return zemu;
  559. }
  560. //****************************************************************************80
  561. void imtqlx ( int n, double d[], double e[], double z[] )
  562. //****************************************************************************80
  563. //
  564. // Purpose:
  565. //
  566. // IMTQLX diagonalizes a symmetric tridiagonal matrix.
  567. //
  568. // Discussion:
  569. //
  570. // This routine is a slightly modified version of the EISPACK routine to
  571. // perform the implicit QL algorithm on a symmetric tridiagonal matrix.
  572. //
  573. // The authors thank the authors of EISPACK for permission to use this
  574. // routine.
  575. //
  576. // It has been modified to produce the product Q' * Z, where Z is an input
  577. // vector and Q is the orthogonal matrix diagonalizing the input matrix.
  578. // The changes consist (essentialy) of applying the orthogonal transformations
  579. // directly to Z as they are generated.
  580. //
  581. // Licensing:
  582. //
  583. // This code is distributed under the GNU LGPL license.
  584. //
  585. // Modified:
  586. //
  587. // 08 January 2010
  588. //
  589. // Author:
  590. //
  591. // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky.
  592. // C++ version by John Burkardt.
  593. //
  594. // Reference:
  595. //
  596. // Sylvan Elhay, Jaroslav Kautsky,
  597. // Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of
  598. // Interpolatory Quadrature,
  599. // ACM Transactions on Mathematical Software,
  600. // Volume 13, Number 4, December 1987, pages 399-415.
  601. //
  602. // Roger Martin, James Wilkinson,
  603. // The Implicit QL Algorithm,
  604. // Numerische Mathematik,
  605. // Volume 12, Number 5, December 1968, pages 377-383.
  606. //
  607. // Parameters:
  608. //
  609. // Input, int N, the order of the matrix.
  610. //
  611. // Input/output, double D(N), the diagonal entries of the matrix.
  612. // On output, the information in D has been overwritten.
  613. //
  614. // Input/output, double E(N), the subdiagonal entries of the
  615. // matrix, in entries E(1) through E(N-1). On output, the information in
  616. // E has been overwritten.
  617. //
  618. // Input/output, double Z(N). On input, a vector. On output,
  619. // the value of Q' * Z, where Q is the matrix that diagonalizes the
  620. // input symmetric tridiagonal matrix.
  621. //
  622. {
  623. double b;
  624. double c;
  625. double f;
  626. double g;
  627. int i;
  628. int ii;
  629. int itn = 30;
  630. int j;
  631. int k;
  632. int l;
  633. int m=0;
  634. int mml;
  635. double p;
  636. double prec;
  637. double r;
  638. double s;
  639. prec = r8_epsilon ( );
  640. if ( n == 1 )
  641. {
  642. return;
  643. }
  644. e[n-1] = 0.0;
  645. for ( l = 1; l <= n; l++ )
  646. {
  647. j = 0;
  648. for ( ; ; )
  649. {
  650. for ( m = l; m <= n; m++ )
  651. {
  652. if ( m == n )
  653. {
  654. break;
  655. }
  656. if ( r8_abs ( e[m-1] ) <= prec * ( r8_abs ( d[m-1] ) + r8_abs ( d[m] ) ) )
  657. {
  658. break;
  659. }
  660. }
  661. p = d[l-1];
  662. if ( m == l )
  663. {
  664. break;
  665. }
  666. if ( itn <= j )
  667. {
  668. std::cout << "\n";
  669. std::cout << "IMTQLX - Fatal error!\n";
  670. std::cout << " Iteration limit exceeded\n";
  671. exit ( 1 );
  672. }
  673. j = j + 1;
  674. g = ( d[l] - p ) / ( 2.0 * e[l-1] );
  675. r = sqrt ( g * g + 1.0 );
  676. g = d[m-1] - p + e[l-1] / ( g + r8_abs ( r ) * r8_sign ( g ) );
  677. s = 1.0;
  678. c = 1.0;
  679. p = 0.0;
  680. mml = m - l;
  681. for ( ii = 1; ii <= mml; ii++ )
  682. {
  683. i = m - ii;
  684. f = s * e[i-1];
  685. b = c * e[i-1];
  686. if ( r8_abs ( g ) <= r8_abs ( f ) )
  687. {
  688. c = g / f;
  689. r = sqrt ( c * c + 1.0 );
  690. e[i] = f * r;
  691. s = 1.0 / r;
  692. c = c * s;
  693. }
  694. else
  695. {
  696. s = f / g;
  697. r = sqrt ( s * s + 1.0 );
  698. e[i] = g * r;
  699. c = 1.0 / r;
  700. s = s * c;
  701. }
  702. g = d[i] - p;
  703. r = ( d[i-1] - g ) * s + 2.0 * c * b;
  704. p = s * r;
  705. d[i] = g + p;
  706. g = c * r - b;
  707. f = z[i];
  708. z[i] = s * z[i-1] + c * f;
  709. z[i-1] = c * z[i-1] - s * f;
  710. }
  711. d[l-1] = d[l-1] - p;
  712. e[l-1] = g;
  713. e[m-1] = 0.0;
  714. }
  715. }
  716. //
  717. // Sorting.
  718. //
  719. for ( ii = 2; ii <= m; ii++ )
  720. {
  721. i = ii - 1;
  722. k = i;
  723. p = d[i-1];
  724. for ( j = ii; j <= n; j++ )
  725. {
  726. if ( d[j-1] < p )
  727. {
  728. k = j;
  729. p = d[j-1];
  730. }
  731. }
  732. if ( k != i )
  733. {
  734. d[k-1] = d[i-1];
  735. d[i-1] = p;
  736. p = z[i-1];
  737. z[i-1] = z[k-1];
  738. z[k-1] = p;
  739. }
  740. }
  741. return;
  742. }
  743. //****************************************************************************80
  744. void parchk ( int kind, int m, double alpha, double beta )
  745. //****************************************************************************80
  746. //
  747. // Purpose:
  748. //
  749. // PARCHK checks parameters ALPHA and BETA for classical weight functions.
  750. //
  751. // Licensing:
  752. //
  753. // This code is distributed under the GNU LGPL license.
  754. //
  755. // Modified:
  756. //
  757. // 07 January 2010
  758. //
  759. // Author:
  760. //
  761. // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky.
  762. // C++ version by John Burkardt.
  763. //
  764. // Reference:
  765. //
  766. // Sylvan Elhay, Jaroslav Kautsky,
  767. // Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of
  768. // Interpolatory Quadrature,
  769. // ACM Transactions on Mathematical Software,
  770. // Volume 13, Number 4, December 1987, pages 399-415.
  771. //
  772. // Parameters:
  773. //
  774. // Input, int KIND, the rule.
  775. // 1, Legendre, (a,b) 1.0
  776. // 2, Chebyshev Type 1, (a,b) ((b-x)*(x-a))^(-0.5)
  777. // 3, Gegenbauer, (a,b) ((b-x)*(x-a))^alpha
  778. // 4, Jacobi, (a,b) (b-x)^alpha*(x-a)^beta
  779. // 5, Generalized Laguerre, (a,inf) (x-a)^alpha*exp(-b*(x-a))
  780. // 6, Generalized Hermite, (-inf,inf) |x-a|^alpha*exp(-b*(x-a)^2)
  781. // 7, Exponential, (a,b) |x-(a+b)/2.0|^alpha
  782. // 8, Rational, (a,inf) (x-a)^alpha*(x+b)^beta
  783. //
  784. // Input, int M, the order of the highest moment to
  785. // be calculated. This value is only needed when KIND = 8.
  786. //
  787. // Input, double ALPHA, BETA, the parameters, if required
  788. // by the value of KIND.
  789. //
  790. {
  791. double tmp;
  792. if ( kind <= 0 )
  793. {
  794. std::cout << "\n";
  795. std::cout << "PARCHK - Fatal error!\n";
  796. std::cout << " KIND <= 0.\n";
  797. exit ( 1 );
  798. }
  799. //
  800. // Check ALPHA for Gegenbauer, Jacobi, Laguerre, Hermite, Exponential.
  801. //
  802. if ( 3 <= kind && alpha <= -1.0 )
  803. {
  804. std::cout << "\n";
  805. std::cout << "PARCHK - Fatal error!\n";
  806. std::cout << " 3 <= KIND and ALPHA <= -1.\n";
  807. exit ( 1 );
  808. }
  809. //
  810. // Check BETA for Jacobi.
  811. //
  812. if ( kind == 4 && beta <= -1.0 )
  813. {
  814. std::cout << "\n";
  815. std::cout << "PARCHK - Fatal error!\n";
  816. std::cout << " KIND == 4 and BETA <= -1.0.\n";
  817. exit ( 1 );
  818. }
  819. //
  820. // Check ALPHA and BETA for rational.
  821. //
  822. if ( kind == 8 )
  823. {
  824. tmp = alpha + beta + m + 1.0;
  825. if ( 0.0 <= tmp || tmp <= beta )
  826. {
  827. std::cout << "\n";
  828. std::cout << "PARCHK - Fatal error!\n";
  829. std::cout << " KIND == 8 but condition on ALPHA and BETA fails.\n";
  830. exit ( 1 );
  831. }
  832. }
  833. return;
  834. }
  835. //****************************************************************************80
  836. double r8_abs ( double x )
  837. //****************************************************************************80
  838. //
  839. // Purpose:
  840. //
  841. // R8_ABS returns the absolute value of an R8.
  842. //
  843. // Licensing:
  844. //
  845. // This code is distributed under the GNU LGPL license.
  846. //
  847. // Modified:
  848. //
  849. // 14 November 2006
  850. //
  851. // Author:
  852. //
  853. // John Burkardt
  854. //
  855. // Parameters:
  856. //
  857. // Input, double X, the quantity whose absolute value is desired.
  858. //
  859. // Output, double R8_ABS, the absolute value of X.
  860. //
  861. {
  862. double value;
  863. if ( 0.0 <= x )
  864. {
  865. value = x;
  866. }
  867. else
  868. {
  869. value = - x;
  870. }
  871. return value;
  872. }
  873. //****************************************************************************80
  874. double r8_epsilon ( )
  875. //****************************************************************************80
  876. //
  877. // Purpose:
  878. //
  879. // R8_EPSILON returns the R8 roundoff unit.
  880. //
  881. // Discussion:
  882. //
  883. // The roundoff unit is a number R which is a power of 2 with the
  884. // property that, to the precision of the computer's arithmetic,
  885. // 1 < 1 + R
  886. // but
  887. // 1 = ( 1 + R / 2 )
  888. //
  889. // Licensing:
  890. //
  891. // This code is distributed under the GNU LGPL license.
  892. //
  893. // Modified:
  894. //
  895. // 01 July 2004
  896. //
  897. // Author:
  898. //
  899. // John Burkardt
  900. //
  901. // Parameters:
  902. //
  903. // Output, double R8_EPSILON, the R8 round-off unit.
  904. //
  905. {
  906. double value;
  907. value = 1.0;
  908. while ( 1.0 < ( double ) ( 1.0 + value ) )
  909. {
  910. value = value / 2.0;
  911. }
  912. value = 2.0 * value;
  913. return value;
  914. }
  915. //****************************************************************************80
  916. double r8_sign ( double x )
  917. //****************************************************************************80
  918. //
  919. // Purpose:
  920. //
  921. // R8_SIGN returns the sign of an R8.
  922. //
  923. // Licensing:
  924. //
  925. // This code is distributed under the GNU LGPL license.
  926. //
  927. // Modified:
  928. //
  929. // 18 October 2004
  930. //
  931. // Author:
  932. //
  933. // John Burkardt
  934. //
  935. // Parameters:
  936. //
  937. // Input, double X, the number whose sign is desired.
  938. //
  939. // Output, double R8_SIGN, the sign of X.
  940. //
  941. {
  942. double value;
  943. if ( x < 0.0 )
  944. {
  945. value = -1.0;
  946. }
  947. else
  948. {
  949. value = 1.0;
  950. }
  951. return value;
  952. }
  953. //****************************************************************************80
  954. void r8mat_write ( std::string output_filename, int m, int n, double table[] )
  955. //****************************************************************************80
  956. //
  957. // Purpose:
  958. //
  959. // R8MAT_WRITE writes an R8MAT file with no header.
  960. //
  961. // Licensing:
  962. //
  963. // This code is distributed under the GNU LGPL license.
  964. //
  965. // Modified:
  966. //
  967. // 29 June 2009
  968. //
  969. // Author:
  970. //
  971. // John Burkardt
  972. //
  973. // Parameters:
  974. //
  975. // Input, string OUTPUT_FILENAME, the output filename.
  976. //
  977. // Input, int M, the spatial dimension.
  978. //
  979. // Input, int N, the number of points.
  980. //
  981. // Input, double TABLE[M*N], the table data.
  982. //
  983. {
  984. int i;
  985. int j;
  986. std::ofstream output;
  987. //
  988. // Open the file.
  989. //
  990. output.open ( output_filename.c_str ( ) );
  991. if ( !output )
  992. {
  993. std::cerr << "\n";
  994. std::cerr << "R8MAT_WRITE - Fatal error!\n";
  995. std::cerr << " Could not open the output file.\n";
  996. return;
  997. }
  998. //
  999. // Write the data.
  1000. //
  1001. for ( j = 0; j < n; j++ )
  1002. {
  1003. for ( i = 0; i < m; i++ )
  1004. {
  1005. output << " " << std::setw(24) << std::setprecision(16) << table[i+j*m];
  1006. }
  1007. output << "\n";
  1008. }
  1009. //
  1010. // Close the file.
  1011. //
  1012. output.close ( );
  1013. return;
  1014. }
  1015. //****************************************************************************80
  1016. void rule_write ( int order, std::string filename, double x[], double w[],
  1017. double r[] )
  1018. //****************************************************************************80
  1019. //
  1020. // Purpose:
  1021. //
  1022. // RULE_WRITE writes a quadrature rule to three files.
  1023. //
  1024. // Licensing:
  1025. //
  1026. // This code is distributed under the GNU LGPL license.
  1027. //
  1028. // Modified:
  1029. //
  1030. // 18 February 2010
  1031. //
  1032. // Author:
  1033. //
  1034. // John Burkardt
  1035. //
  1036. // Parameters:
  1037. //
  1038. // Input, int ORDER, the order of the rule.
  1039. //
  1040. // Input, double A, the left endpoint.
  1041. //
  1042. // Input, double B, the right endpoint.
  1043. //
  1044. // Input, string FILENAME, specifies the output filenames.
  1045. // "filename_w.txt", "filename_x.txt", "filename_r.txt"
  1046. // defining weights, abscissas, and region.
  1047. //
  1048. {
  1049. std::string filename_r;
  1050. std::string filename_w;
  1051. std::string filename_x;
  1052. filename_w = filename + "_w.txt";
  1053. filename_x = filename + "_x.txt";
  1054. filename_r = filename + "_r.txt";
  1055. std::cout << "\n";
  1056. std::cout << " Creating quadrature files.\n";
  1057. std::cout << "\n";
  1058. std::cout << " Root file name is \"" << filename << "\".\n";
  1059. std::cout << "\n";
  1060. std::cout << " Weight file will be \"" << filename_w << "\".\n";
  1061. std::cout << " Abscissa file will be \"" << filename_x << "\".\n";
  1062. std::cout << " Region file will be \"" << filename_r << "\".\n";
  1063. r8mat_write ( filename_w, 1, order, w );
  1064. r8mat_write ( filename_x, 1, order, x );
  1065. r8mat_write ( filename_r, 1, 2, r );
  1066. return;
  1067. }
  1068. //****************************************************************************80
  1069. void scqf ( int nt, double t[], int mlt[], double wts[], int nwts, int ndx[],
  1070. double swts[], double st[], int kind, double alpha, double beta, double a,
  1071. double b )
  1072. //****************************************************************************80
  1073. //
  1074. // Purpose:
  1075. //
  1076. // SCQF scales a quadrature formula to a nonstandard interval.
  1077. //
  1078. // Discussion:
  1079. //
  1080. // The arrays WTS and SWTS may coincide.
  1081. //
  1082. // The arrays T and ST may coincide.
  1083. //
  1084. // Licensing:
  1085. //
  1086. // This code is distributed under the GNU LGPL license.
  1087. //
  1088. // Modified:
  1089. //
  1090. // 16 February 2010
  1091. //
  1092. // Author:
  1093. //
  1094. // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky.
  1095. // C++ version by John Burkardt.
  1096. //
  1097. // Reference:
  1098. //
  1099. // Sylvan Elhay, Jaroslav Kautsky,
  1100. // Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of
  1101. // Interpolatory Quadrature,
  1102. // ACM Transactions on Mathematical Software,
  1103. // Volume 13, Number 4, December 1987, pages 399-415.
  1104. //
  1105. // Parameters:
  1106. //
  1107. // Input, int NT, the number of knots.
  1108. //
  1109. // Input, double T[NT], the original knots.
  1110. //
  1111. // Input, int MLT[NT], the multiplicity of the knots.
  1112. //
  1113. // Input, double WTS[NWTS], the weights.
  1114. //
  1115. // Input, int NWTS, the number of weights.
  1116. //
  1117. // Input, int NDX[NT], used to index the array WTS.
  1118. // For more details see the comments in CAWIQ.
  1119. //
  1120. // Output, double SWTS[NWTS], the scaled weights.
  1121. //
  1122. // Output, double ST[NT], the scaled knots.
  1123. //
  1124. // Input, int KIND, the rule.
  1125. // 1, Legendre, (a,b) 1.0
  1126. // 2, Chebyshev Type 1, (a,b) ((b-x)*(x-a))^(-0.5)
  1127. // 3, Gegenbauer, (a,b) ((b-x)*(x-a))^alpha
  1128. // 4, Jacobi, (a,b) (b-x)^alpha*(x-a)^beta
  1129. // 5, Generalized Laguerre, (a,+oo) (x-a)^alpha*exp(-b*(x-a))
  1130. // 6, Generalized Hermite, (-oo,+oo) |x-a|^alpha*exp(-b*(x-a)^2)
  1131. // 7, Exponential, (a,b) |x-(a+b)/2.0|^alpha
  1132. // 8, Rational, (a,+oo) (x-a)^alpha*(x+b)^beta
  1133. // 9, Chebyshev Type 2, (a,b) ((b-x)*(x-a))^(+0.5)
  1134. //
  1135. // Input, double ALPHA, the value of Alpha, if needed.
  1136. //
  1137. // Input, double BETA, the value of Beta, if needed.
  1138. //
  1139. // Input, double A, B, the interval endpoints.
  1140. //
  1141. {
  1142. double al=0;
  1143. double be=0;
  1144. int i;
  1145. int k;
  1146. int l;
  1147. double p;
  1148. double shft=0;
  1149. double slp=0;
  1150. double temp;
  1151. double tmp;
  1152. temp = r8_epsilon ( );
  1153. parchk ( kind, 1, alpha, beta );
  1154. if ( kind == 1 )
  1155. {
  1156. al = 0.0;
  1157. be = 0.0;
  1158. if ( r8_abs ( b - a ) <= temp )
  1159. {
  1160. std::cout << "\n";
  1161. std::cout << "SCQF - Fatal error!\n";
  1162. std::cout << " |B - A| too small.\n";
  1163. exit ( 1 );
  1164. }
  1165. shft = ( a + b ) / 2.0;
  1166. slp = ( b - a ) / 2.0;
  1167. }
  1168. else if ( kind == 2 )
  1169. {
  1170. al = -0.5;
  1171. be = -0.5;
  1172. if ( r8_abs ( b - a ) <= temp )
  1173. {
  1174. std::cout << "\n";
  1175. std::cout << "SCQF - Fatal error!\n";
  1176. std::cout << " |B - A| too small.\n";
  1177. exit ( 1 );
  1178. }
  1179. shft = ( a + b ) / 2.0;
  1180. slp = ( b - a ) / 2.0;
  1181. }
  1182. else if ( kind == 3 )
  1183. {
  1184. al = alpha;
  1185. be = alpha;
  1186. if ( r8_abs ( b - a ) <= temp )
  1187. {
  1188. std::cout << "\n";
  1189. std::cout << "SCQF - Fatal error!\n";
  1190. std::cout << " |B - A| too small.\n";
  1191. exit ( 1 );
  1192. }
  1193. shft = ( a + b ) / 2.0;
  1194. slp = ( b - a ) / 2.0;
  1195. }
  1196. else if ( kind == 4 )
  1197. {
  1198. al = alpha;
  1199. be = beta;
  1200. if ( r8_abs ( b - a ) <= temp )
  1201. {
  1202. std::cout << "\n";
  1203. std::cout << "SCQF - Fatal error!\n";
  1204. std::cout << " |B - A| too small.\n";
  1205. exit ( 1 );
  1206. }
  1207. shft = ( a + b ) / 2.0;
  1208. slp = ( b - a ) / 2.0;
  1209. }
  1210. else if ( kind == 5 )
  1211. {
  1212. if ( b <= 0.0 )
  1213. {
  1214. std::cout << "\n";
  1215. std::cout << "SCQF - Fatal error!\n";
  1216. std::cout << " B <= 0\n";
  1217. exit ( 1 );
  1218. }
  1219. shft = a;
  1220. slp = 1.0 / b;
  1221. al = alpha;
  1222. be = 0.0;
  1223. }
  1224. else if ( kind == 6 )
  1225. {
  1226. if ( b <= 0.0 )
  1227. {
  1228. std::cout << "\n";
  1229. std::cout << "SCQF - Fatal error!\n";
  1230. std::cout << " B <= 0.\n";
  1231. exit ( 1 );
  1232. }
  1233. shft = a;
  1234. slp = 1.0 / sqrt ( b );
  1235. al = alpha;
  1236. be = 0.0;
  1237. }
  1238. else if ( kind == 7 )
  1239. {
  1240. al = alpha;
  1241. be = 0.0;
  1242. if ( r8_abs ( b - a ) <= temp )
  1243. {
  1244. std::cout << "\n";
  1245. std::cout << "SCQF - Fatal error!\n";
  1246. std::cout << " |B - A| too small.\n";
  1247. exit ( 1 );
  1248. }
  1249. shft = ( a + b ) / 2.0;
  1250. slp = ( b - a ) / 2.0;
  1251. }
  1252. else if ( kind == 8 )
  1253. {
  1254. if ( a + b <= 0.0 )
  1255. {
  1256. std::cout << "\n";
  1257. std::cout << "SCQF - Fatal error!\n";
  1258. std::cout << " A + B <= 0.\n";
  1259. exit ( 1 );
  1260. }
  1261. shft = a;
  1262. slp = a + b;
  1263. al = alpha;
  1264. be = beta;
  1265. }
  1266. else if ( kind == 9 )
  1267. {
  1268. al = 0.5;
  1269. be = 0.5;
  1270. if ( r8_abs ( b - a ) <= temp )
  1271. {
  1272. std::cout << "\n";
  1273. std::cout << "SCQF - Fatal error!\n";
  1274. std::cout << " |B - A| too small.\n";
  1275. exit ( 1 );
  1276. }
  1277. shft = ( a + b ) / 2.0;
  1278. slp = ( b - a ) / 2.0;
  1279. }
  1280. p = pow ( slp, al + be + 1.0 );
  1281. for ( k = 0; k < nt; k++ )
  1282. {
  1283. st[k] = shft + slp * t[k];
  1284. l = abs ( ndx[k] );
  1285. if ( l != 0 )
  1286. {
  1287. tmp = p;
  1288. for ( i = l - 1; i <= l - 1 + mlt[k] - 1; i++ )
  1289. {
  1290. swts[i] = wts[i] * tmp;
  1291. tmp = tmp * slp;
  1292. }
  1293. }
  1294. }
  1295. return;
  1296. }
  1297. //****************************************************************************80
  1298. void sgqf ( int nt, double aj[], double bj[], double zemu, double t[],
  1299. double wts[] )
  1300. //****************************************************************************80
  1301. //
  1302. // Purpose:
  1303. //
  1304. // SGQF computes knots and weights of a Gauss Quadrature formula.
  1305. //
  1306. // Discussion:
  1307. //
  1308. // This routine computes all the knots and weights of a Gauss quadrature
  1309. // formula with simple knots from the Jacobi matrix and the zero-th
  1310. // moment of the weight function, using the Golub-Welsch technique.
  1311. //
  1312. // Licensing:
  1313. //
  1314. // This code is distributed under the GNU LGPL license.
  1315. //
  1316. // Modified:
  1317. //
  1318. // 08 January 2010
  1319. //
  1320. // Author:
  1321. //
  1322. // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky.
  1323. // C++ version by John Burkardt.
  1324. //
  1325. // Reference:
  1326. //
  1327. // Sylvan Elhay, Jaroslav Kautsky,
  1328. // Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of
  1329. // Interpolatory Quadrature,
  1330. // ACM Transactions on Mathematical Software,
  1331. // Volume 13, Number 4, December 1987, pages 399-415.
  1332. //
  1333. // Parameters:
  1334. //
  1335. // Input, int NT, the number of knots.
  1336. //
  1337. // Input, double AJ[NT], the diagonal of the Jacobi matrix.
  1338. //
  1339. // Input/output, double BJ[NT], the subdiagonal of the Jacobi
  1340. // matrix, in entries 1 through NT-1. On output, BJ has been overwritten.
  1341. //
  1342. // Input, double ZEMU, the zero-th moment of the weight function.
  1343. //
  1344. // Output, double T[NT], the knots.
  1345. //
  1346. // Output, double WTS[NT], the weights.
  1347. //
  1348. {
  1349. int i;
  1350. //
  1351. // Exit if the zero-th moment is not positive.
  1352. //
  1353. if ( zemu <= 0.0 )
  1354. {
  1355. std::cout << "\n";
  1356. std::cout << "SGQF - Fatal error!\n";
  1357. std::cout << " ZEMU <= 0.\n";
  1358. exit ( 1 );
  1359. }
  1360. //
  1361. // Set up vectors for IMTQLX.
  1362. //
  1363. for ( i = 0; i < nt; i++ )
  1364. {
  1365. t[i] = aj[i];
  1366. }
  1367. wts[0] = sqrt ( zemu );
  1368. for ( i = 1; i < nt; i++ )
  1369. {
  1370. wts[i] = 0.0;
  1371. }
  1372. //
  1373. // Diagonalize the Jacobi matrix.
  1374. //
  1375. imtqlx ( nt, t, bj, wts );
  1376. for ( i = 0; i < nt; i++ )
  1377. {
  1378. wts[i] = wts[i] * wts[i];
  1379. }
  1380. return;
  1381. }
  1382. //****************************************************************************80
  1383. void timestamp ( )
  1384. //****************************************************************************80
  1385. //
  1386. // Purpose:
  1387. //
  1388. // TIMESTAMP prints the current YMDHMS date as a time stamp.
  1389. //
  1390. // Example:
  1391. //
  1392. // 31 May 2001 09:45:54 AM
  1393. //
  1394. // Licensing:
  1395. //
  1396. // This code is distributed under the GNU LGPL license.
  1397. //
  1398. // Modified:
  1399. //
  1400. // 08 July 2009
  1401. //
  1402. // Author:
  1403. //
  1404. // John Burkardt
  1405. //
  1406. // Parameters:
  1407. //
  1408. // None
  1409. //
  1410. {
  1411. # define TIME_SIZE 40
  1412. static char time_buffer[TIME_SIZE];
  1413. const struct std::tm *tm_ptr;
  1414. size_t len;
  1415. std::time_t now;
  1416. now = std::time ( NULL );
  1417. tm_ptr = std::localtime ( &now );
  1418. len = std::strftime ( time_buffer, TIME_SIZE, "%d %B %Y %I:%M:%S %p", tm_ptr );
  1419. assert(len>0);
  1420. std::cout << time_buffer << "\n";
  1421. return;
  1422. # undef TIME_SIZE
  1423. }