MiniTensor Version of the Day
Loading...
Searching...
No Matches
MiniTensor_MatrixFunctions.h
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// MiniTensor Package
4//
5// Copyright 2016 NTESS and the MiniTensor contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#if !defined(MiniTensor_MatrixFunctions_h)
11#define MiniTensor_MatrixFunctions_h
12
13// Matrix functions: exp, log, sqrt families and BCH.
15#include "MiniTensor_Inverse.h"
16#include "MiniTensor_Norms.h"
17
18namespace minitensor {
19
22
27template <typename T, Index N> Tensor<T, N> exp(Tensor<T, N> const &A);
28
33template<typename T, Index N>
35Tensor<T, N>
36exp_taylor(Tensor<T, N> const & A);
37
43template <typename T, Index N> Tensor<T, N> exp_pade(Tensor<T, N> const &A);
44
49template<typename T, Index N>
51Tensor<T, N>
52exp_sym(Tensor<T, N> const & A);
53
58template<typename T, Index N>
60Tensor<T, N>
61exp_eig_sym(Tensor<T, N> const & A);
62
67template<typename T, Index N>
69Tensor<T, N>
70log(Tensor<T, N> const & A);
71
76template<typename T, Index N>
78Tensor<T, N>
79log_taylor(Tensor<T, N> const & A);
80
86template<typename T, Index N>
88Tensor<T, N>
89log_gregory(Tensor<T, N> const & A);
90
97template<typename T, Index N>
98Tensor<T, N>
99log_schur(Tensor<T, N> const & A);
100
105template<typename T, Index N>
107Tensor<T, N>
108log_sym(Tensor<T, N> const & A);
109
114template<typename T, Index N>
116Tensor<T, N>
117log_eig_sym(Tensor<T, N> const & A);
118
125template<typename T, Index N>
127Tensor<T, N>
128bch(Tensor<T, N> const & v, Tensor<T, N> const & r);
129
137template<typename T, Index N>
139Tensor<T, N>
140binary_powering(Tensor<T, N> const & A, Index const exponent);
141
142//
143// Exponential map
144//
145template <typename T, Index N> Tensor<T, N> exp(Tensor<T, N> const &A) {
146 return exp_pade(A);
147}
148
149//
150// R^N exponential map by Taylor series, radius of convergence is infinity
151// \param A tensor
152// \return \f$ \exp A \f$
153//
154template<typename T, Index N>
156Tensor<T, N>
158{
159 Index const
160 max_iter = 128;
161
162 T const
163 tol = machine_epsilon<T>();
164
165 Index const
166 dimension = A.get_dimension();
167
169 term = identity<T, N>(dimension);
170
171 // Relative error taken wrt to the first term, which is I and norm = 1
172 T
173 relative_error = 1.0;
174
176 B = term;
177
178 Index
179 k = 0;
180
181 while (relative_error > tol && k < max_iter) {
182 term = static_cast<T>(1.0 / (k + 1.0)) * term * A;
183 B = B + term;
184 relative_error = norm_1(term);
185 ++k;
186 }
187
188 return B;
189}
190
191namespace impl {
192
193//
194// Scaling parameter theta for scaling and squaring exponential.
195//
196template<typename T>
198T
199scaling_squaring_theta(Index const order)
200{
201 assert(order > 0 && order < 22);
202
203 T const theta[] =
204 {
205 0.0e-0, 3.7e-8, 5.3e-4, 1.5e-2, 8.5e-2, 2.5e-1, 5.4e-1, 9.5e-1,
206 1.5e-0, 2.1e-0, 2.8e-0, 3.6e-0, 4.5e-0, 5.4e-0, 6.3e-0, 7.3e-0,
207 8.4e-0, 9.4e-0, 1.1e+1, 1.2e+1, 1.3e+1, 1.4e+1
208 };
209
210 return theta[order];
211}
212
213//
214// Polynomial coefficients for Padé approximants.
215//
216template<typename T>
218T
219polynomial_coefficient(Index const order, Index const index)
220{
221 assert(index <= order);
222
223 T
224 c = 0.0;
225
226 switch (order) {
227
228 default:
229 MT_ERROR_EXIT("Wrong order in Pade' polynomial coefficient: ");
230 break;
231
232 case 3:
233 {
234 T const
235 b[] = {120.0, 60.0, 12.0, 1.0};
236
237 c = b[index];
238 }
239 break;
240
241 case 5:
242 {
243 T const
244 b[] = {30240.0, 15120.0, 3360.0, 420.0, 30.0, 1.0};
245
246 c = b[index];
247 }
248 break;
249
250 case 7:
251 {
252 T const
253 b[] = {17297280.0, 8648640.0, 1995840.0, 277200.0, 25200.0, 1512.0,
254 56.0, 1.0};
255
256 c = b[index];
257 }
258 break;
259
260 case 9:
261 {
262 T const
263 b[] = {17643225600.0, 8821612800.0, 2075673600.0, 302702400.0,
264 30270240.0, 2162160.0, 110880.0, 3960.0, 90.0, 1.0};
265
266 c = b[index];
267 }
268 break;
269
270 case 13:
271 {
272 T const
273 b[] = {64764752532480000.0, 32382376266240000.0, 7771770303897600.0,
274 1187353796428800.0, 129060195264000.0, 10559470521600.0,
275 670442572800.0, 33522128640.0, 1323241920.0, 40840800.0,
276 960960.0, 16380.0, 182.0, 1.0};
277
278 c = b[index];
279 }
280 break;
281
282 }
283
284 return c;
285}
286
287//
288// Padé approximant polynomial odd and even terms.
289//
290template <typename T, Index N>
291std::pair<Tensor<T, N>, Tensor<T, N>>
292pade_polynomial_terms(Tensor<T, N> const &A, Index const order) {
293 Index const
294 dimension = A.get_dimension();
295
296 Tensor<T, N>
297 B = identity<T, N>(dimension);
298
299 Tensor<T, N>
300 U = polynomial_coefficient<Real>(order, 1) * B;
301
302 Tensor<T, N>
303 V = polynomial_coefficient<Real>(order, 0) * B;
304
305 Tensor<T, N> const
306 A2 = A * A;
307
308 for (Index i = 3; i <= order; i += 2) {
309
310 B = B * A2;
311
312 Tensor<T, N> const
313 O = polynomial_coefficient<Real>(order, i) * B;
314
315 Tensor<T, N> const
316 E = polynomial_coefficient<Real>(order, i - 1) * B;
317
318 U += O;
319
320 V += E;
321
322 }
323
324 U = A * U;
325
326 return std::make_pair(U, V);
327}
328
329//
330// Coefficients for Padé approximants.
331//
332template<typename T>
334T
335pade_coefficients(Index const n)
336{
337 T const c[] = {
338 1.100343044625278e-05, 1.818617533662554e-03, 1.620628479501567e-02, 5.387353263138127e-02, 1.135280226762866e-01,
339 1.866286061354130e-01, 2.642960831111435e-01, 3.402172331985299e-01, 4.108235000556820e-01, 4.745521256007768e-01,
340 5.310667521178455e-01, 5.806887133441684e-01, 6.240414344012918e-01, 6.618482563071411e-01, 6.948266172489354e-01,
341 7.236382701437292e-01, 7.488702930926310e-01, 7.710320825151814e-01, 7.905600074925671e-01, 8.078252198050853e-01,
342 8.231422814010787e-01, 8.367774696147783e-01, 8.489562661576765e-01, 8.598698723737197e-01, 8.696807597657327e-01,
343 8.785273397512191e-01, 8.865278635527148e-01, 8.937836659824918e-01, 9.003818585631236e-01, 9.063975647545747e-01,
344 9.118957765024351e-01, 9.169328985287867e-01, 9.215580354375991e-01, 9.258140669835052e-01, 9.297385486977516e-01,
345 9.333644683151422e-01, 9.367208829050256e-01, 9.398334570841484e-01, 9.427249190039424e-01, 9.454154478075423e-01,
346 9.479230038146050e-01, 9.502636107090112e-01, 9.524515973891873e-01, 9.544998058228285e-01, 9.564197701703862e-01,
347 9.582218715590143e-01, 9.599154721638511e-01, 9.615090316568806e-01, 9.630102085912245e-01, 9.644259488813590e-01,
348 9.657625632018019e-01, 9.670257948457799e-01, 9.682208793510226e-01, 9.693525970039069e-01, 9.704253191689650e-01,
349 9.714430492527785e-01, 9.724094589950460e-01, 9.733279206814576e-01, 9.742015357899175e-01, 9.750331605111618e-01,
350 9.758254285248543e-01, 9.765807713611383e-01, 9.773014366339591e-01, 9.779895043950849e-01};
351 return c[n];
352}
353
354template<typename T>
356T
357gauss_legendre_abscissae(Index const m, Index const n)
358{
359 T x = 0.0;
360 switch (m) {
361 default: break;
362 case 1: {
363 T const c[] = {0.0};
364 x = c[n];
365 } break;
366 case 2: {
367 T const c[] = {-0.5773502691896257645, 0.5773502691896257645};
368 x = c[n];
369 } break;
370
371 case 3: {
372 T const c[] = {0, -0.774596669241483377, 0.774596669241483377};
373 x = c[n];
374 } break;
375
376 case 4: {
377 T const c[] = {-0.3399810435848562648, 0.3399810435848562648, -0.8611363115940525752, 0.8611363115940525752};
378 x = c[n];
379 } break;
380
381 case 5: {
382 T const c[] = {0, -0.5384693101056830910, 0.5384693101056830910, -0.9061798459386639927, 0.9061798459386639927};
383 x = c[n];
384 } break;
385
386 case 6: {
387 T const c[] = {
388 0.6612093864662645136613995950199,
389 -0.6612093864662645136613995950199,
390 -0.2386191860831969086305017216807,
391 0.2386191860831969086305017216807,
392 -0.9324695142031520278123015544939,
393 0.9324695142031520278123015544939};
394 x = c[n];
395 } break;
396
397 case 7: {
398 T const c[] = {
399 0,
400 0.4058451513773971669066064120769,
401 -0.4058451513773971669066064120769,
402 -0.7415311855993944398638647732807,
403 0.7415311855993944398638647732807,
404 -0.949107912342758524526189684047851,
405 0.949107912342758524526189684047851};
406 x = c[n];
407 } break;
408
409 case 8: {
410 T const c[] = {
411 -0.1834346424956498049394761423601,
412 0.1834346424956498049394761423601,
413 -0.5255324099163289858177390491892,
414 0.5255324099163289858177390491892,
415 -0.7966664774136267395915539364758,
416 0.7966664774136267395915539364758,
417 -0.960289856497536231683560868569472,
418 0.960289856497536231683560868569472};
419 x = c[n];
420 } break;
421
422 case 9: {
423 T const c[] = {
424 0,
425 -0.8360311073266357942994297880697,
426 0.8360311073266357942994297880697,
427 -0.9681602395076260898355762029036,
428 0.9681602395076260898355762029036,
429 -0.3242534234038089290385380146433,
430 0.3242534234038089290385380146433,
431 -0.6133714327005903973087020393414,
432 0.6133714327005903973087020393414};
433 x = c[n];
434 } break;
435
436 case 10: {
437 T const c[] = {
438 -0.1488743389816312108,
439 0.1488743389816312108,
440 -0.4333953941292471907,
441 0.4333953941292471907,
442 -0.6794095682990244062,
443 0.6794095682990244062,
444 -0.8650633666889845107,
445 0.8650633666889845107,
446 -0.9739065285171717200,
447 0.9739065285171717200};
448 x = c[n];
449 } break;
450
451 case 11: {
452 T const c[] = {
453 0,
454 -0.2695431559523449723,
455 0.2695431559523449723,
456 -0.5190961292068118159,
457 0.5190961292068118159,
458 -0.7301520055740493240,
459 0.7301520055740493240,
460 -0.8870625997680952990,
461 0.8870625997680952990,
462 -0.978228658146056992,
463 0.978228658146056992};
464 x = c[n];
465 } break;
466
467 case 12: {
468 T const c[] = {
469 -0.125233408511468915,
470 0.125233408511468915,
471 -0.3678314989981801937,
472 0.3678314989981801937,
473 -0.5873179542866174472,
474 0.5873179542866174472,
475 -0.7699026741943046870,
476 0.7699026741943046870,
477 -0.9041172563704748566,
478 0.9041172563704748566,
479 -0.981560634246719250,
480 0.981560634246719250};
481 x = c[n];
482 } break;
483
484 case 13: {
485 T const c[] = {
486 0,
487 -0.2304583159551347940,
488 0.2304583159551347940,
489 -0.4484927510364468528,
490 0.4484927510364468528,
491 -0.6423493394403402206,
492 0.6423493394403402206,
493 -0.8015780907333099127,
494 0.8015780907333099127,
495 -0.917598399222977965,
496 0.917598399222977965,
497 -0.9841830547185881494,
498 0.9841830547185881494};
499 x = c[n];
500 } break;
501
502 case 14: {
503 T const c[] = {
504 -0.1080549487073436620,
505 0.1080549487073436620,
506 -0.3191123689278897604,
507 0.3191123689278897604,
508 -0.5152486363581540919,
509 0.5152486363581540919,
510 -0.6872929048116854701,
511 0.6872929048116854701,
512 -0.8272013150697649931,
513 0.8272013150697649931,
514 -0.9284348836635735173,
515 0.9284348836635735173,
516 -0.9862838086968123388,
517 0.9862838086968123388};
518 x = c[n];
519 } break;
520
521 case 15: {
522 T const c[] = {
523 0,
524 -0.2011940939974345223,
525 0.2011940939974345223,
526 -0.3941513470775633698,
527 0.3941513470775633698,
528 -0.5709721726085388475,
529 0.5709721726085388475,
530 -0.724417731360170047,
531 0.724417731360170047,
532 -0.8482065834104272162,
533 0.8482065834104272162,
534 -0.9372733924007059043,
535 0.9372733924007059043,
536 -0.9879925180204854284,
537 0.9879925180204854284};
538 x = c[n];
539 } break;
540
541 case 16: {
542 T const c[] = {
543 -0.0950125098376374401,
544 0.0950125098376374401,
545 -0.2816035507792589132,
546 0.2816035507792589132,
547 -0.4580167776572273863,
548 0.4580167776572273863,
549 -0.6178762444026437484,
550 0.6178762444026437484,
551 -0.7554044083550030338,
552 0.7554044083550030338,
553 -0.8656312023878317438,
554 0.8656312023878317438,
555 -0.9445750230732325760,
556 0.9445750230732325760,
557 -0.9894009349916499325,
558 0.9894009349916499325};
559 x = c[n];
560 } break;
561
562 case 17: {
563 T const c[] = {
564 0,
565 -0.1784841814958478558,
566 0.1784841814958478558,
567 -0.3512317634538763152,
568 0.3512317634538763152,
569 -0.5126905370864769678,
570 0.5126905370864769678,
571 -0.6576711592166907658,
572 0.6576711592166907658,
573 -0.7815140038968014069,
574 0.7815140038968014069,
575 -0.8802391537269859021,
576 0.8802391537269859021,
577 -0.9506755217687677612,
578 0.9506755217687677612,
579 -0.9905754753144173356,
580 0.9905754753144173356};
581 x = c[n];
582 } break;
583
584 case 18: {
585 T const c[] = {
586 -0.0847750130417353012,
587 0.0847750130417353012,
588 -0.2518862256915055095,
589 0.2518862256915055095,
590 -0.4117511614628426460,
591 0.4117511614628426460,
592 -0.5597708310739475346,
593 0.5597708310739475346,
594 -0.6916870430603532078,
595 0.6916870430603532078,
596 -0.8037049589725231156,
597 0.8037049589725231156,
598 -0.8926024664975557392,
599 0.8926024664975557392,
600 -0.9558239495713977551,
601 0.9558239495713977551,
602 -0.9915651684209309467,
603 0.9915651684209309467};
604 x = c[n];
605 } break;
606
607 case 19: {
608 T const c[] = {
609 0,
610 -0.1603586456402253758,
611 0.1603586456402253758,
612 -0.3165640999636298319,
613 0.3165640999636298319,
614 -0.4645707413759609457,
615 0.4645707413759609457,
616 -0.6005453046616810234,
617 0.6005453046616810234,
618 -0.7209661773352293786,
619 0.7209661773352293786,
620 -0.8227146565371428249,
621 0.8227146565371428249,
622 -0.9031559036148179016,
623 0.9031559036148179016,
624 -0.9602081521348300308,
625 0.9602081521348300308,
626 -0.9924068438435844031,
627 0.9924068438435844031};
628 x = c[n];
629 } break;
630
631 case 20: {
632 T const c[] = {-0.0765265211334973337, 0.0765265211334973337, -0.2277858511416450780, 0.2277858511416450780,
633 -0.3737060887154195606, 0.3737060887154195606, -0.5108670019508270980, 0.5108670019508270980,
634 -0.6360536807265150254, 0.6360536807265150254, -0.7463319064601507926, 0.7463319064601507926,
635 -0.8391169718222188233, 0.8391169718222188233, -0.9122344282513259058, 0.9122344282513259058,
636 -0.9639719272779137912, 0.9639719272779137912, -0.9931285991850949247, 0.9931285991850949247};
637 x = c[n];
638 } break;
639
640 case 21: {
641 T const c[] = {
642 0,
643 -0.1455618541608950909,
644 0.1455618541608950909,
645 -0.2880213168024010966,
646 0.2880213168024010966,
647 -0.4243421202074387835,
648 0.4243421202074387835,
649 -0.5516188358872198070,
650 0.5516188358872198070,
651 -0.6671388041974123193,
652 0.6671388041974123193,
653 -0.7684399634756779086,
654 0.7684399634756779086,
655 -0.8533633645833172836,
656 0.8533633645833172836,
657 -0.920099334150400828,
658 0.920099334150400828,
659 -0.9672268385663062943,
660 0.9672268385663062943,
661 -0.9937521706203895002,
662 0.9937521706203895002};
663 x = c[n];
664 } break;
665
666 case 22: {
667 T const c[] = {-0.0697392733197222212, 0.0697392733197222212, -0.2078604266882212854, 0.2078604266882212854,
668 -0.3419358208920842251, 0.3419358208920842251, -0.4693558379867570264, 0.4693558379867570264,
669 -0.5876404035069115929, 0.5876404035069115929, -0.6944872631866827800, 0.6944872631866827800,
670 -0.7878168059792081620, 0.7878168059792081620, -0.8658125777203001365, 0.8658125777203001365,
671 -0.9269567721871740005, 0.9269567721871740005, -0.970060497835428727, 0.970060497835428727,
672 -0.9942945854823992920, 0.9942945854823992920};
673 x = c[n];
674 } break;
675
676 case 23: {
677 T const c[] = {
678 0,
679 -0.133256824298466110,
680 0.133256824298466110,
681 -0.2641356809703449305,
682 0.2641356809703449305,
683 -0.3903010380302908314,
684 0.3903010380302908314,
685 -0.5095014778460075496,
686 0.5095014778460075496,
687 -0.6196098757636461563,
688 0.6196098757636461563,
689 -0.7186613631319501944,
690 0.7186613631319501944,
691 -0.8048884016188398921,
692 0.8048884016188398921,
693 -0.8767523582704416673,
694 0.8767523582704416673,
695 -0.9329710868260161023,
696 0.9329710868260161023,
697 -0.9725424712181152319,
698 0.9725424712181152319,
699 -0.994769334997552123,
700 0.994769334997552123};
701 x = c[n];
702 } break;
703
704 case 24: {
705 T const c[] = {-0.0640568928626056260, 0.0640568928626056260, -0.1911188674736163091, 0.1911188674736163091,
706 -0.3150426796961633743, 0.3150426796961633743, -0.4337935076260451384, 0.4337935076260451384,
707 -0.5454214713888395356, 0.5454214713888395356, -0.6480936519369755692, 0.6480936519369755692,
708 -0.7401241915785543642, 0.7401241915785543642, -0.8200019859739029219, 0.8200019859739029219,
709 -0.8864155270044010342, 0.8864155270044010342, -0.9382745520027327585, 0.9382745520027327585,
710 -0.9747285559713094981, 0.9747285559713094981, -0.9951872199970213601, 0.9951872199970213601};
711 x = c[n];
712 } break;
713
714 case 25: {
715 T const c[] = {
716 0,
717 -0.1228646926107103963,
718 0.1228646926107103963,
719 -0.2438668837209884320,
720 0.2438668837209884320,
721 -0.3611723058093878377,
722 0.3611723058093878377,
723 -0.4730027314457149605,
724 0.4730027314457149605,
725 -0.5776629302412229677,
726 0.5776629302412229677,
727 -0.6735663684734683644,
728 0.6735663684734683644,
729 -0.759259263037357630,
730 0.759259263037357630,
731 -0.8334426287608340014,
732 0.8334426287608340014,
733 -0.8949919978782753688,
734 0.8949919978782753688,
735 -0.9429745712289743394,
736 0.9429745712289743394,
737 -0.9766639214595175114,
738 0.9766639214595175114,
739 -0.9955569697904980979,
740 0.9955569697904980979};
741 x = c[n];
742 } break;
743
744 case 26: {
745 T const c[] = {-0.0592300934293132070, 0.0592300934293132070, -0.1768588203568901839, 0.1768588203568901839,
746 -0.2920048394859568951, 0.2920048394859568951, -0.4030517551234863064, 0.4030517551234863064,
747 -0.5084407148245057176, 0.5084407148245057176, -0.6066922930176180632, 0.6066922930176180632,
748 -0.6964272604199572648, 0.6964272604199572648, -0.7763859488206788561, 0.7763859488206788561,
749 -0.8454459427884980187, 0.8454459427884980187, -0.9026378619843070742, 0.9026378619843070742,
750 -0.9471590666617142501, 0.9471590666617142501, -0.978385445956470991, 0.978385445956470991,
751 -0.9958857011456169290, 0.9958857011456169290};
752 x = c[n];
753 } break;
754
755 case 27: {
756 T const c[] = {
757 0,
758 -0.1139725856095299669,
759 0.1139725856095299669,
760 -0.2264593654395368588,
761 0.2264593654395368588,
762 -0.3359939036385088997,
763 0.3359939036385088997,
764 -0.441148251750026880,
765 0.441148251750026880,
766 -0.5405515645794568949,
767 0.5405515645794568949,
768 -0.6329079719464951409,
769 0.6329079719464951409,
770 -0.7170134737394236992,
771 0.7170134737394236992,
772 -0.7917716390705082271,
773 0.7917716390705082271,
774 -0.8562079080182944903,
775 0.8562079080182944903,
776 -0.9094823206774911043,
777 0.9094823206774911043,
778 -0.9509005578147050068,
779 0.9509005578147050068,
780 -0.9799234759615012228,
781 0.9799234759615012228,
782 -0.9961792628889885669,
783 0.9961792628889885669};
784 x = c[n];
785 } break;
786
787 case 28: {
788 T const c[] = {-0.0550792898840342704, 0.0550792898840342704, -0.1645692821333807712, 0.1645692821333807712,
789 -0.2720616276351780776, 0.2720616276351780776, -0.3762515160890787102, 0.3762515160890787102,
790 -0.4758742249551182610, 0.4758742249551182610, -0.5697204718114017193, 0.5697204718114017193,
791 -0.6566510940388649612, 0.6566510940388649612, -0.7356108780136317720, 0.7356108780136317720,
792 -0.8056413709171791714, 0.8056413709171791714, -0.8658925225743950489, 0.8658925225743950489,
793 -0.9156330263921320738, 0.9156330263921320738, -0.9542592806289381972, 0.9542592806289381972,
794 -0.9813031653708727536, 0.9813031653708727536, -0.996442497573954449, 0.996442497573954449};
795 x = c[n];
796 } break;
797
798 case 29: {
799 T const c[] = {
800 0,
801 -0.1062782301326792301,
802 0.1062782301326792301,
803 -0.211352286166001074,
804 0.211352286166001074,
805 -0.3140316378676399349,
806 0.3140316378676399349,
807 -0.4131528881740086638,
808 0.4131528881740086638,
809 -0.5075929551242276421,
810 0.5075929551242276421,
811 -0.596281797138227820,
812 0.596281797138227820,
813 -0.6782145376026865151,
814 0.6782145376026865151,
815 -0.7524628517344771339,
816 0.7524628517344771339,
817 -0.8181854876152524449,
818 0.8181854876152524449,
819 -0.8746378049201027904,
820 0.8746378049201027904,
821 -0.9211802329530587850,
822 0.9211802329530587850,
823 -0.9572855957780877257,
824 0.9572855957780877257,
825 -0.9825455052614131748,
826 0.9825455052614131748,
827 -0.9966794422605965861,
828 0.9966794422605965861};
829 x = c[n];
830 } break;
831
832 case 30: {
833 T const c[] = {-0.0514718425553176958, 0.0514718425553176958, -0.1538699136085835469, 0.1538699136085835469,
834 -0.2546369261678898464, 0.2546369261678898464, -0.3527047255308781134, 0.3527047255308781134,
835 -0.4470337695380891767, 0.4470337695380891767, -0.5366241481420198992, 0.5366241481420198992,
836 -0.6205261829892428611, 0.6205261829892428611, -0.697850494793315796, 0.697850494793315796,
837 -0.7677774321048261949, 0.7677774321048261949, -0.8295657623827683974, 0.8295657623827683974,
838 -0.8825605357920526815, 0.8825605357920526815, -0.926200047429274325, 0.926200047429274325,
839 -0.960021864968307512, 0.960021864968307512, -0.9836681232797472099, 0.9836681232797472099,
840 -0.9968934840746495402, 0.9968934840746495402};
841 x = c[n];
842 } break;
843
844 case 31: {
845 T const c[] = {
846 0,
847 -0.0995553121523415203,
848 0.0995553121523415203,
849 -0.1981211993355706287,
850 0.1981211993355706287,
851 -0.294718069981701616,
852 0.294718069981701616,
853 -0.3883859016082329430,
854 0.3883859016082329430,
855 -0.4781937820449024804,
856 0.4781937820449024804,
857 -0.563249161407149262,
858 0.563249161407149262,
859 -0.6427067229242603461,
860 0.6427067229242603461,
861 -0.7157767845868532839,
862 0.7157767845868532839,
863 -0.781733148416624940,
864 0.781733148416624940,
865 -0.8399203201462673400,
866 0.8399203201462673400,
867 -0.8897600299482710433,
868 0.8897600299482710433,
869 -0.9307569978966481649,
870 0.9307569978966481649,
871 -0.9625039250929496617,
872 0.9625039250929496617,
873 -0.9846859096651524840,
874 0.9846859096651524840,
875 -0.9970874818194770740,
876 0.9970874818194770740};
877 x = c[n];
878 } break;
879
880 case 32: {
881 T const c[] = {-0.0483076656877383162, 0.0483076656877383162, -0.1444719615827964934, 0.1444719615827964934,
882 -0.2392873622521370745, 0.2392873622521370745, -0.3318686022821276497, 0.3318686022821276497,
883 -0.4213512761306353453, 0.4213512761306353453, -0.5068999089322293900, 0.5068999089322293900,
884 -0.5877157572407623290, 0.5877157572407623290, -0.6630442669302152009, 0.6630442669302152009,
885 -0.732182118740289680, 0.732182118740289680, -0.7944837959679424069, 0.7944837959679424069,
886 -0.849367613732569970, 0.849367613732569970, -0.8963211557660521239, 0.8963211557660521239,
887 -0.9349060759377396891, 0.9349060759377396891, -0.9647622555875064307, 0.9647622555875064307,
888 -0.9856115115452683354, 0.9856115115452683354, -0.9972638618494815635, 0.9972638618494815635};
889 x = c[n];
890 } break;
891
892 case 33: {
893 T const c[] = {
894 0,
895 -0.0936310658547333856,
896 0.0936310658547333856,
897 -0.1864392988279915723,
898 0.1864392988279915723,
899 -0.2776090971524970294,
900 0.2776090971524970294,
901 -0.3663392577480733410,
902 0.3663392577480733410,
903 -0.4518500172724506957,
904 0.4518500172724506957,
905 -0.5333899047863476435,
906 0.5333899047863476435,
907 -0.6102423458363790273,
908 0.6102423458363790273,
909 -0.6817319599697427862,
910 0.6817319599697427862,
911 -0.7472304964495621578,
912 0.7472304964495621578,
913 -0.8061623562741665897,
914 0.8061623562741665897,
915 -0.8580096526765040646,
916 0.8580096526765040646,
917 -0.9023167677434335830,
918 0.9023167677434335830,
919 -0.9386943726111683503,
920 0.9386943726111683503,
921 -0.9668229096899927689,
922 0.9668229096899927689,
923 -0.9864557262306424881,
924 0.9864557262306424881,
925 -0.9974246942464552172,
926 0.9974246942464552172};
927 x = c[n];
928 } break;
929
930 case 34: {
931 T const c[] = {-0.0455098219531025427, 0.0455098219531025427, -0.1361523572591829758, 0.1361523572591829758,
932 -0.2256666916164494838, 0.2256666916164494838, -0.3133110813394632474, 0.3133110813394632474,
933 -0.3983592777586459406, 0.3983592777586459406, -0.4801065451903270341, 0.4801065451903270341,
934 -0.5578755006697466427, 0.5578755006697466427, -0.6310217270805285453, 0.6310217270805285453,
935 -0.6989391132162629079, 0.6989391132162629079, -0.7610648766298730141, 0.7610648766298730141,
936 -0.8168842279009336645, 0.8168842279009336645, -0.8659346383345644692, 0.8659346383345644692,
937 -0.9078096777183244688, 0.9078096777183244688, -0.9421623974051070916, 0.9421623974051070916,
938 -0.9687082625333442817, 0.9687082625333442817, -0.9872278164063094850, 0.9872278164063094850,
939 -0.9975717537908419192, 0.9975717537908419192};
940 x = c[n];
941 } break;
942
943 case 35: {
944 T const c[] = {
945 0,
946 -0.0883713432756592636,
947 0.0883713432756592636,
948 -0.1760510611659895699,
949 0.1760510611659895699,
950 -0.2623529412092960579,
951 0.2623529412092960579,
952 -0.3466015544308139458,
953 0.3466015544308139458,
954 -0.4281375415178142541,
955 0.4281375415178142541,
956 -0.5063227732414886150,
957 0.5063227732414886150,
958 -0.5805453447497645099,
959 0.5805453447497645099,
960 -0.650224364665890388,
961 0.650224364665890388,
962 -0.7148145015566287832,
963 0.7148145015566287832,
964 -0.7738102522869125552,
965 0.7738102522869125552,
966 -0.8267498990922254068,
967 0.8267498990922254068,
968 -0.8732191250252223315,
969 0.8732191250252223315,
970 -0.9128542613593176144,
971 0.9128542613593176144,
972 -0.9453451482078273295,
973 0.9453451482078273295,
974 -0.9704376160392298332,
975 0.9704376160392298332,
976 -0.9879357644438514980,
977 0.9879357644438514980,
978 -0.997706569099600297,
979 0.997706569099600297};
980 x = c[n];
981 } break;
982
983 case 36: {
984 T const c[] = {-0.0430181984737086072, 0.0430181984737086072, -0.128736103809384788, 0.128736103809384788,
985 -0.2135008923168655789, 0.2135008923168655789, -0.2966849953440282705, 0.2966849953440282705,
986 -0.3776725471196892163, 0.3776725471196892163, -0.455863944433420267, 0.455863944433420267,
987 -0.5306802859262451616, 0.5306802859262451616, -0.6015676581359805350, 0.6015676581359805350,
988 -0.6680012365855210620, 0.6680012365855210620, -0.7294891715935565820, 0.7294891715935565820,
989 -0.785576230132206512, 0.785576230132206512, -0.8358471669924753064, 0.8358471669924753064,
990 -0.8799298008903971319, 0.8799298008903971319, -0.9174977745156590660, 0.9174977745156590660,
991 -0.9482729843995075452, 0.9482729843995075452, -0.972027691049697949, 0.972027691049697949,
992 -0.9885864789022122380, 0.9885864789022122380, -0.9978304624840858361, 0.9978304624840858361};
993 x = c[n];
994 } break;
995
996 case 37: {
997 T const c[] = {
998 0,
999 -0.0836704089547699019,
1000 0.0836704089547699019,
1001 -0.1667539302398519769,
1002 0.1667539302398519769,
1003 -0.248667792791365758,
1004 0.248667792791365758,
1005 -0.3288374298837069994,
1006 0.3288374298837069994,
1007 -0.4067005093183261101,
1008 0.4067005093183261101,
1009 -0.4817108778032055541,
1010 0.4817108778032055541,
1011 -0.5533423918615817812,
1012 0.5533423918615817812,
1013 -0.6210926084089244831,
1014 0.6210926084089244831,
1015 -0.6844863091309593574,
1016 0.6844863091309593574,
1017 -0.7430788339819652625,
1018 0.7430788339819652625,
1019 -0.7964592005099022933,
1020 0.7964592005099022933,
1021 -0.8442529873405559679,
1022 0.8442529873405559679,
1023 -0.8861249621554860789,
1024 0.8861249621554860789,
1025 -0.9217814374124637426,
1026 0.9217814374124637426,
1027 -0.950972343262094821,
1028 0.950972343262094821,
1029 -0.9734930300564857443,
1030 0.9734930300564857443,
1031 -0.9891859632143191866,
1032 0.9891859632143191866,
1033 -0.9979445824779136489,
1034 0.9979445824779136489};
1035 x = c[n];
1036 } break;
1037
1038 case 38: {
1039 T const c[] = {-0.0407851479045782399, 0.0407851479045782399, -0.1220840253378674198, 0.1220840253378674198,
1040 -0.2025704538921167032, 0.2025704538921167032, -0.2817088097901652613, 0.2817088097901652613,
1041 -0.3589724404794350132, 0.3589724404794350132, -0.4338471694323764843, 0.4338471694323764843,
1042 -0.5058347179279311032, 0.5058347179279311032, -0.5744560210478070811, 0.5744560210478070811,
1043 -0.639254415829681707, 0.639254415829681707, -0.6997986803791843559, 0.6997986803791843559,
1044 -0.7556859037539706807, 0.7556859037539706807, -0.8065441676053168155, 0.8065441676053168155,
1045 -0.8520350219323621888, 0.8520350219323621888, -0.8918557390046322167, 0.8918557390046322167,
1046 -0.9257413320485843968, 0.9257413320485843968, -0.953466330933529595, 0.953466330933529595,
1047 -0.9748463285901535076, 0.9748463285901535076, -0.9897394542663855719, 0.9897394542663855719,
1048 -0.9980499305356876198, 0.9980499305356876198};
1049 x = c[n];
1050 } break;
1051
1052 case 39: {
1053 T const c[] = {
1054 0,
1055 -0.0794438046087554775,
1056 0.0794438046087554775,
1057 -0.1583853399978377999,
1058 0.1583853399978377999,
1059 -0.2363255124618357673,
1060 0.2363255124618357673,
1061 -0.3127715592481859225,
1062 0.3127715592481859225,
1063 -0.3872401639715614558,
1064 0.3872401639715614558,
1065 -0.4592605123091360486,
1066 0.4592605123091360486,
1067 -0.5283772686604374738,
1068 0.5283772686604374738,
1069 -0.5941534549572779886,
1070 0.5941534549572779886,
1071 -0.6561732134320109107,
1072 0.6561732134320109107,
1073 -0.7140444358945346791,
1074 0.7140444358945346791,
1075 -0.76740124293106349,
1076 0.76740124293106349,
1077 -0.8159062974301431043,
1078 0.8159062974301431043,
1079 -0.8592529379999061539,
1080 0.8592529379999061539,
1081 -0.8971671192929928878,
1082 0.8971671192929928878,
1083 -0.929409148486738229,
1084 0.929409148486738229,
1085 -0.9557752123246522771,
1086 0.9557752123246522771,
1087 -0.9760987093334710538,
1088 0.9760987093334710538,
1089 -0.9902515368546859836,
1090 0.9902515368546859836,
1091 -0.9981473830664329060,
1092 0.9981473830664329060};
1093 x = c[n];
1094 } break;
1095
1096 case 40: {
1097 T const c[] = {-0.0387724175060508219, 0.0387724175060508219, -0.1160840706752552084, 0.1160840706752552084,
1098 -0.1926975807013710997, 0.1926975807013710997, -0.2681521850072536811, 0.2681521850072536811,
1099 -0.3419940908257584730, 0.3419940908257584730, -0.4137792043716050015, 0.4137792043716050015,
1100 -0.4830758016861787129, 0.4830758016861787129, -0.5494671250951282020, 0.5494671250951282020,
1101 -0.6125538896679802379, 0.6125538896679802379, -0.6719566846141795483, 0.6719566846141795483,
1102 -0.727318255189927103, 0.727318255189927103, -0.7783056514265193876, 0.7783056514265193876,
1103 -0.8246122308333116631, 0.8246122308333116631, -0.8659595032122595038, 0.8659595032122595038,
1104 -0.9020988069688742967, 0.9020988069688742967, -0.9328128082786765333, 0.9328128082786765333,
1105 -0.9579168192137916558, 0.9579168192137916558, -0.9772599499837742626, 0.9772599499837742626,
1106 -0.9907262386994570064, 0.9907262386994570064, -0.998237709710559200, 0.998237709710559200};
1107 x = c[n];
1108 } break;
1109
1110 case 41: {
1111 T const c[] = {
1112 0,
1113 -0.0756232589891629969,
1114 0.0756232589891629969,
1115 -0.1508133548639921635,
1116 0.1508133548639921635,
1117 -0.2251396056334227756,
1118 0.2251396056334227756,
1119 -0.298176277341824865,
1120 0.298176277341824865,
1121 -0.3695050226404814414,
1122 0.3695050226404814414,
1123 -0.4387172770514070885,
1124 0.4387172770514070885,
1125 -0.5054165991994060327,
1126 0.5054165991994060327,
1127 -0.569220941610215869,
1128 0.569220941610215869,
1129 -0.629764839072196320,
1130 0.629764839072196320,
1131 -0.6867015020349512895,
1132 0.6867015020349512895,
1133 -0.7397048030699261810,
1134 0.7397048030699261810,
1135 -0.7884711450474093727,
1136 0.7884711450474093727,
1137 -0.8327212004013613312,
1138 0.8327212004013613312,
1139 -0.8722015116924414088,
1140 0.8722015116924414088,
1141 -0.9066859447581011729,
1142 0.9066859447581011729,
1143 -0.935976987497853825,
1144 0.935976987497853825,
1145 -0.9599068917303462260,
1146 0.9599068917303462260,
1147 -0.9783386735610833844,
1148 0.9783386735610833844,
1149 -0.9911671096990163082,
1150 0.9911671096990163082,
1151 -0.9983215885747714415,
1152 0.9983215885747714415};
1153 x = c[n];
1154 } break;
1155
1156 case 42: {
1157 T const c[] = {-0.036948943165351775, 0.036948943165351775, -0.1106450272085198683, 0.1106450272085198683,
1158 -0.1837368065648545508, 0.1837368065648545508, -0.2558250793428790839, 0.2558250793428790839,
1159 -0.3265161244654115121, 0.3265161244654115121, -0.3954238520429750576, 0.3954238520429750576,
1160 -0.4621719120704219297, 0.4621719120704219297, -0.5263957499311922875, 0.5263957499311922875,
1161 -0.5877445974851093228, 0.5877445974851093228, -0.6458833888692478339, 0.6458833888692478339,
1162 -0.700494590556171213, 0.700494590556171213, -0.7512799356894804895, 0.7512799356894804895,
1163 -0.7979620532554874132, 0.7979620532554874132, -0.8402859832618169009, 0.8402859832618169009,
1164 -0.8780205698121727427, 0.8780205698121727427, -0.9109597249041274525, 0.9109597249041274525,
1165 -0.9389235573549881785, 0.9389235573549881785, -0.9617593653382044887, 0.9617593653382044887,
1166 -0.979342508063748193, 0.979342508063748193, -0.9915772883408609197, 0.9915772883408609197,
1167 -0.9983996189900624150, 0.9983996189900624150};
1168 x = c[n];
1169 } break;
1170
1171 case 43: {
1172 T const c[] = {
1173 0,
1174 -0.0721529908745862354,
1175 0.0721529908745862354,
1176 -0.1439298095107133107,
1177 0.1439298095107133107,
1178 -0.2149562448605182090,
1179 0.2149562448605182090,
1180 -0.2848619980329136271,
1181 0.2848619980329136271,
1182 -0.3532826128643038066,
1183 0.3532826128643038066,
1184 -0.4198613760292692524,
1185 0.4198613760292692524,
1186 -0.4842511767857347240,
1187 0.4842511767857347240,
1188 -0.5461163166600847191,
1189 0.5461163166600847191,
1190 -0.605134259639600935,
1191 0.605134259639600935,
1192 -0.6609973137514981331,
1193 0.6609973137514981331,
1194 -0.713414235268957054,
1195 0.713414235268957054,
1196 -0.7621117471949551214,
1197 0.7621117471949551214,
1198 -0.8068359641369386352,
1199 0.8068359641369386352,
1200 -0.8473537162093150489,
1201 0.8473537162093150489,
1202 -0.8834537652186168633,
1203 0.8834537652186168633,
1204 -0.914947907206138729,
1205 0.914947907206138729,
1206 -0.9416719568476378618,
1207 0.9416719568476378618,
1208 -0.9634866130140799934,
1209 0.9634866130140799934,
1210 -0.9802782209802553315,
1211 0.9802782209802553315,
1212 -0.9919595575932441464,
1213 0.9919595575932441464,
1214 -0.9984723322425077135,
1215 0.9984723322425077135};
1216 x = c[n];
1217 } break;
1218
1219 case 44: {
1220 T const c[] = {-0.0352892369641353590, 0.0352892369641353590, -0.105691901708653247, 0.105691901708653247,
1221 -0.1755680147755167857, 0.1755680147755167857, -0.2445694569282012515, 0.2445694569282012515,
1222 -0.3123524665027858122, 0.3123524665027858122, -0.3785793520147071325, 0.3785793520147071325,
1223 -0.4429201745254114838, 0.4429201745254114838, -0.5050543913882023179, 0.5050543913882023179,
1224 -0.5646724531854707684, 0.5646724531854707684, -0.6214773459035758478, 0.6214773459035758478,
1225 -0.6751860706661223653, 0.6751860706661223653, -0.7255310536607170026, 0.7255310536607170026,
1226 -0.7722614792487558990, 0.7722614792487558990, -0.8151445396451350104, 0.8151445396451350104,
1227 -0.8539665950047103787, 0.8539665950047103787, -0.8885342382860432023, 0.8885342382860432023,
1228 -0.91867525998417577, 0.91867525998417577, -0.9442395091181940992, 0.9442395091181940992,
1229 -0.9650996504224931393, 0.9650996504224931393, -0.9811518330779139666, 0.9811518330779139666,
1230 -0.9923163921385158084, 0.9923163921385158084, -0.9985402006367742249, 0.9985402006367742249};
1231 x = c[n];
1232 } break;
1233
1234 case 45: {
1235 T const c[] = {
1236 0,
1237 -0.0689869801631441724,
1238 0.0689869801631441724,
1239 -0.1376452059832530287,
1240 0.1376452059832530287,
1241 -0.2056474897832637457,
1242 0.2056474897832637457,
1243 -0.2726697697523775606,
1244 0.2726697697523775606,
1245 -0.338392654250602161,
1246 0.338392654250602161,
1247 -0.4025029438585419140,
1248 0.4025029438585419140,
1249 -0.4646951239196350985,
1250 0.4646951239196350985,
1251 -0.5246728204629160670,
1252 0.5246728204629160670,
1253 -0.5821502125693531866,
1254 0.5821502125693531866,
1255 -0.6368533944532233592,
1256 0.6368533944532233592,
1257 -0.6885216807712005252,
1258 0.6885216807712005252,
1259 -0.7369088489454903526,
1260 0.7369088489454903526,
1261 -0.7817843125939062913,
1262 0.7817843125939062913,
1263 -0.8229342205020863370,
1264 0.8229342205020863370,
1265 -0.8601624759606642253,
1266 0.8601624759606642253,
1267 -0.8932916717532417384,
1268 0.8932916717532417384,
1269 -0.9221639367190003880,
1270 0.9221639367190003880,
1271 -0.9466416909956290617,
1272 0.9466416909956290617,
1273 -0.9666083103968946047,
1274 0.9666083103968946047,
1275 -0.9819687150345405682,
1276 0.9819687150345405682,
1277 -0.992649998447203741,
1278 0.992649998447203741,
1279 -0.9986036451819366381,
1280 0.9986036451819366381};
1281 x = c[n];
1282 } break;
1283
1284 case 46: {
1285 T const c[] = {-0.0337721900160520415, 0.0337721900160520415, -0.101162475305584239, 0.101162475305584239,
1286 -0.1680911794671035286, 0.1680911794671035286, -0.2342529222062697686, 0.2342529222062697686,
1287 -0.29934582270187001, 0.29934582270187001, -0.3630728770209957101, 0.3630728770209957101,
1288 -0.4251433132828283973, 0.4251433132828283973, -0.4852739183881646627, 0.4852739183881646627,
1289 -0.5431903302618026352, 0.5431903302618026352, -0.598628289712715153, 0.598628289712715153,
1290 -0.6513348462019977151, 0.6513348462019977151, -0.7010695120204056975, 0.7010695120204056975,
1291 -0.747605359615666054, 0.747605359615666054, -0.7907300570752742551, 0.7907300570752742551,
1292 -0.830246837066066053, 0.830246837066066053, -0.8659753948668580629, 0.8659753948668580629,
1293 -0.8977527115339419657, 0.8977527115339419657, -0.9254337988067539509, 0.9254337988067539509,
1294 -0.9488923634460897956, 0.9488923634460897956, -0.9680213918539919427, 0.9680213918539919427,
1295 -0.9827336698041668634, 0.9827336698041668634, -0.9929623489061743640, 0.9929623489061743640,
1296 -0.9986630421338179811, 0.9986630421338179811};
1297 x = c[n];
1298 } break;
1299
1300 case 47: {
1301 T const c[] = {
1302 0,
1303 -0.0660869239163556751,
1304 0.0660869239163556751,
1305 -0.1318848665545148970,
1306 0.1318848665545148970,
1307 -0.1971061102791118079,
1308 0.1971061102791118079,
1309 -0.2614654592149745703,
1310 0.2614654592149745703,
1311 -0.3246814863377359022,
1312 0.3246814863377359022,
1313 -0.3864777640846671395,
1314 0.3864777640846671395,
1315 -0.4465840731048557027,
1316 0.4465840731048557027,
1317 -0.5047375838635779197,
1318 0.5047375838635779197,
1319 -0.5606840059346641944,
1320 0.5606840059346641944,
1321 -0.6141786999563736085,
1322 0.6141786999563736085,
1323 -0.6649877473903327291,
1324 0.6649877473903327291,
1325 -0.7128889734090643016,
1326 0.7128889734090643016,
1327 -0.7576729184454386335,
1328 0.7576729184454386335,
1329 -0.7991437541677419429,
1330 0.7991437541677419429,
1331 -0.8371201398999021212,
1332 0.8371201398999021212,
1333 -0.8714360157968963169,
1334 0.8714360157968963169,
1335 -0.9019413294385253568,
1336 0.9019413294385253568,
1337 -0.9285026930123606481,
1338 0.9285026930123606481,
1339 -0.9510039692577084425,
1340 0.9510039692577084425,
1341 -0.9693467873265644971,
1342 0.9693467873265644971,
1343 -0.9834510030716237087,
1344 0.9834510030716237087,
1345 -0.9932552109877686346,
1346 0.9932552109877686346,
1347 -0.998718728584212109,
1348 0.998718728584212109};
1349 x = c[n];
1350 } break;
1351
1352 case 48: {
1353 T const c[] = {-0.0323801709628693620, 0.0323801709628693620, -0.097004699209462698, 0.097004699209462698,
1354 -0.1612223560688917180, 0.1612223560688917180, -0.2247637903946890612, 0.2247637903946890612,
1355 -0.287362487355455576, 0.287362487355455576, -0.3487558862921607381, 0.3487558862921607381,
1356 -0.4086864819907167299, 0.4086864819907167299, -0.4669029047509584045, 0.4669029047509584045,
1357 -0.5231609747222330336, 0.5231609747222330336, -0.5772247260839727038, 0.5772247260839727038,
1358 -0.6288673967765136239, 0.6288673967765136239, -0.677872379632663905, 0.677872379632663905,
1359 -0.7240341309238146546, 0.7240341309238146546, -0.7671590325157403392, 0.7671590325157403392,
1360 -0.8070662040294426270, 0.8070662040294426270, -0.8435882616243935307, 0.8435882616243935307,
1361 -0.8765720202742478859, 0.8765720202742478859, -0.9058791367155696728, 0.9058791367155696728,
1362 -0.9313866907065543331, 0.9313866907065543331, -0.9529877031604308607, 0.9529877031604308607,
1363 -0.9705915925462472504, 0.9705915925462472504, -0.9841245837228268577, 0.9841245837228268577,
1364 -0.9935301722663507575, 0.9935301722663507575, -0.9987710072524261186, 0.9987710072524261186};
1365 x = c[n];
1366 } break;
1367
1368 case 49: {
1369 T const c[] = {
1370 0,
1371 -0.0634206849826867860,
1372 0.0634206849826867860,
1373 -0.1265859972696720510,
1374 0.1265859972696720510,
1375 -0.189241592461813586,
1376 0.189241592461813586,
1377 -0.2511351786125772735,
1378 0.2511351786125772735,
1379 -0.3120175321197487622,
1380 0.3120175321197487622,
1381 -0.3716435012622848888,
1382 0.3716435012622848888,
1383 -0.4297729933415765246,
1384 0.4297729933415765246,
1385 -0.4861719414524920421,
1386 0.4861719414524920421,
1387 -0.5406132469917260665,
1388 0.5406132469917260665,
1389 -0.5928776941089007124,
1390 0.5928776941089007124,
1391 -0.642754832419237664,
1392 0.642754832419237664,
1393 -0.6900438244251321135,
1394 0.6900438244251321135,
1395 -0.7345542542374026962,
1396 0.7345542542374026962,
1397 -0.7761068943454466350,
1398 0.7761068943454466350,
1399 -0.8145344273598554315,
1400 0.8145344273598554315,
1401 -0.8496821198441657010,
1402 0.8496821198441657010,
1403 -0.8814084455730089100,
1404 0.8814084455730089100,
1405 -0.9095856558280732852,
1406 0.9095856558280732852,
1407 -0.934100294755810149,
1408 0.934100294755810149,
1409 -0.9548536586741372335,
1410 0.9548536586741372335,
1411 -0.9717622009015553801,
1412 0.9717622009015553801,
1413 -0.9847578959142130043,
1414 0.9847578959142130043,
1415 -0.9937886619441677907,
1416 0.9937886619441677907,
1417 -0.9988201506066353793,
1418 0.9988201506066353793};
1419 x = c[n];
1420 } break;
1421
1422 case 50: {
1423 T const c[] = {-0.0310983383271888761, 0.0310983383271888761, -0.0931747015600861408, 0.0931747015600861408,
1424 -0.1548905899981459020, 0.1548905899981459020, -0.2160072368760417568, 0.2160072368760417568,
1425 -0.2762881937795319903, 0.2762881937795319903, -0.3355002454194373568, 0.3355002454194373568,
1426 -0.3934143118975651273, 0.3934143118975651273, -0.4498063349740387891, 0.4498063349740387891,
1427 -0.504458144907464201, 0.504458144907464201, -0.5571583045146500543, 0.5571583045146500543,
1428 -0.6077029271849502391, 0.6077029271849502391, -0.6558964656854393607, 0.6558964656854393607,
1429 -0.701552468706822251, 0.701552468706822251, -0.7444943022260685382, 0.7444943022260685382,
1430 -0.7845558329003992639, 0.7845558329003992639, -0.8215820708593359483, 0.8215820708593359483,
1431 -0.8554297694299460846, 0.8554297694299460846, -0.8859679795236130486, 0.8859679795236130486,
1432 -0.9130785566557918930, 0.9130785566557918930, -0.9366566189448779337, 0.9366566189448779337,
1433 -0.9566109552428079429, 0.9566109552428079429, -0.9728643851066920737, 0.9728643851066920737,
1434 -0.9853540840480058823, 0.9853540840480058823, -0.9940319694320907125, 0.9940319694320907125,
1435 -0.9988664044200710501, 0.9988664044200710501};
1436 x = c[n];
1437 } break;
1438
1439 case 51: {
1440 T const c[] = {
1441 0,
1442 -0.0609611001505787247,
1443 0.0609611001505787247,
1444 -0.121695421018888766,
1445 0.121695421018888766,
1446 -0.1819770269570775453,
1447 0.1819770269570775453,
1448 -0.2415816664477987038,
1449 0.2415816664477987038,
1450 -0.3002876063353319395,
1451 0.3002876063353319395,
1452 -0.3578764566884095097,
1453 0.3578764566884095097,
1454 -0.4141339832263038779,
1455 0.4141339832263038779,
1456 -0.4688509042860410636,
1457 0.4688509042860410636,
1458 -0.521823669366185842,
1459 0.521823669366185842,
1460 -0.5728552163513038365,
1461 0.5728552163513038365,
1462 -0.6217557046007232737,
1463 0.6217557046007232737,
1464 -0.6683432211753700868,
1465 0.6683432211753700868,
1466 -0.7124444575770366445,
1467 0.7124444575770366445,
1468 -0.7538953544853755257,
1469 0.7538953544853755257,
1470 -0.79254171209938120,
1471 0.79254171209938120,
1472 -0.8282397638230648328,
1473 0.8282397638230648328,
1474 -0.8608567111822923714,
1475 0.8608567111822923714,
1476 -0.8902712180295273032,
1477 0.8902712180295273032,
1478 -0.9163738623097802308,
1479 0.9163738623097802308,
1480 -0.9390675440029623834,
1481 0.9390675440029623834,
1482 -0.9582678486139081945,
1483 0.9582678486139081945,
1484 -0.9739033680193238672,
1485 0.9739033680193238672,
1486 -0.9859159917359029965,
1487 0.9859159917359029965,
1488 -0.9942612604367525746,
1489 0.9942612604367525746,
1490 -0.9989099908489034951,
1491 0.9989099908489034951};
1492 x = c[n];
1493 } break;
1494
1495 case 52: {
1496 T const c[] = {-0.0299141097973387660, 0.0299141097973387660, -0.089635244648900565, 0.089635244648900565,
1497 -0.1490355086069491804, 0.1490355086069491804, -0.2079022641563660596, 0.2079022641563660596,
1498 -0.2660247836050018274, 0.2660247836050018274, -0.3231950034348078255, 0.3231950034348078255,
1499 -0.3792082691160936692, 0.3792082691160936692, -0.4338640677187616703, 0.4338640677187616703,
1500 -0.4869667456980960777, 0.4869667456980960777, -0.5383262092858274383, 0.5383262092858274383,
1501 -0.5877586049795790699, 0.5877586049795790699, -0.6350869776952459242, 0.6350869776952459242,
1502 -0.6801419042271677020, 0.6801419042271677020, -0.7227620997499831936, 0.7227620997499831936,
1503 -0.7627949951937449602, 0.7627949951937449602, -0.800097283430468324, 0.800097283430468324,
1504 -0.8345354323267345349, 0.8345354323267345349, -0.8659861628460675852, 0.8659861628460675852,
1505 -0.8943368905344953225, 0.8943368905344953225, -0.9194861289164245398, 0.9194861289164245398,
1506 -0.9413438536413590568, 0.9413438536413590568, -0.9598318269330865525, 0.9598318269330865525,
1507 -0.9748838842217445031, 0.9748838842217445031, -0.9864461956515498406, 0.9864461956515498406,
1508 -0.9944775909292160292, 0.9944775909292160292, -0.9989511111039502780, 0.9989511111039502780};
1509 x = c[n];
1510 } break;
1511
1512 case 53: {
1513 T const c[] = {
1514 0,
1515 -0.058685054300259465,
1516 0.058685054300259465,
1517 -0.1171678090719551501,
1518 0.1171678090719551501,
1519 -0.1752466621553257507,
1520 0.1752466621553257507,
1521 -0.232721403724272593,
1522 0.232721403724272593,
1523 -0.289393906451626206,
1524 0.289393906451626206,
1525 -0.3450688084957223566,
1526 0.3450688084957223566,
1527 -0.3995541869539529773,
1528 0.3995541869539529773,
1529 -0.4526622194618457913,
1530 0.4526622194618457913,
1531 -0.5042098316571334370,
1532 0.5042098316571334370,
1533 -0.5540193282770678810,
1534 0.5540193282770678810,
1535 -0.6019190057137693274,
1536 0.6019190057137693274,
1537 -0.6477437439165100687,
1538 0.6477437439165100687,
1539 -0.6913355756013667235,
1540 0.6913355756013667235,
1541 -0.7325442308075102537,
1542 0.7325442308075102537,
1543 -0.7712276549255323078,
1544 0.7712276549255323078,
1545 -0.807252498416895478,
1546 0.807252498416895478,
1547 -0.8404945765458013754,
1548 0.8404945765458013754,
1549 -0.8708392975582413516,
1550 0.8708392975582413516,
1551 -0.8981820578754266259,
1552 0.8981820578754266259,
1553 -0.9224286030428121282,
1554 0.9224286030428121282,
1555 -0.9434953534644418790,
1556 0.9434953534644418790,
1557 -0.9613096946231363323,
1558 0.9613096946231363323,
1559 -0.9758102337149845816,
1560 0.9758102337149845816,
1561 -0.9869470350233715217,
1562 0.9869470350233715217,
1563 -0.9946819193080070786,
1564 0.9946819193080070786,
1565 -0.9989899477763282271,
1566 0.9989899477763282271};
1567 x = c[n];
1568 } break;
1569
1570 case 54: {
1571 T const c[] = {-0.0288167481993417776, 0.0288167481993417776, -0.086354518263248215, 0.086354518263248215,
1572 -0.1436054273162561539, 0.1436054273162561539, -0.2003792936062135697, 0.2003792936062135697,
1573 -0.2564875200699973000, 0.2564875200699973000, -0.3117437208344682288, 0.3117437208344682288,
1574 -0.3659643403721911819, 0.3659643403721911819, -0.418969263255204528, 0.418969263255204528,
1575 -0.4705824124813822836, 0.4705824124813822836, -0.5206323343859330733, 0.5206323343859330733,
1576 -0.5689527681952094297, 0.5689527681952094297, -0.6153831983311273707, 0.6153831983311273707,
1577 -0.6597693876319831246, 0.6597693876319831246, -0.7019638897191729193, 0.7019638897191729193,
1578 -0.7418265388091843162, 0.7418265388091843162, -0.7792249153462540215, 0.7792249153462540215,
1579 -0.8140347859135678354, 0.8140347859135678354, -0.8461405159707729494, 0.8461405159707729494,
1580 -0.8754354540655689394, 0.8754354540655689394, -0.901822286284701580, 0.901822286284701580,
1581 -0.9252133598666514862, 0.9252133598666514862, -0.9455309751649958537, 0.9455309751649958537,
1582 -0.9627076457859235832, 0.9627076457859235832, -0.9766863288579032372, 0.9766863288579032372,
1583 -0.9874206373973435585, 0.9874206373973435585, -0.9948751170183388849, 0.9948751170183388849,
1584 -0.9990266668673409838, 0.9990266668673409838};
1585 x = c[n];
1586 } break;
1587
1588 case 55: {
1589 T const c[] = {
1590 0,
1591 -0.0565727538183367763,
1592 0.0565727538183367763,
1593 -0.1129642880593292665,
1594 0.1129642880593292665,
1595 -0.1689939636468732082,
1596 0.1689939636468732082,
1597 -0.2244823006478454834,
1598 0.2244823006478454834,
1599 -0.2792515532008065385,
1600 0.2792515532008065385,
1601 -0.3331262788900238851,
1602 0.3331262788900238851,
1603 -0.3859339007409794297,
1604 0.3859339007409794297,
1605 -0.4375052600371745918,
1606 0.4375052600371745918,
1607 -0.4876751581874740972,
1608 0.4876751581874740972,
1609 -0.5362828859083432967,
1610 0.5362828859083432967,
1611 -0.5831727380260321029,
1612 0.5831727380260321029,
1613 -0.6281945122499281400,
1614 0.6281945122499281400,
1615 -0.6712039903198263957,
1616 0.6712039903198263957,
1617 -0.7120633999866378389,
1618 0.7120633999866378389,
1619 -0.7506418563480219086,
1620 0.7506418563480219086,
1621 -0.7868157811276223658,
1622 0.7868157811276223658,
1623 -0.8204692985593209124,
1624 0.8204692985593209124,
1625 -0.8514946066171544714,
1626 0.8514946066171544714,
1627 -0.8797923224198955060,
1628 0.8797923224198955060,
1629 -0.905271800744000025,
1630 0.905271800744000025,
1631 -0.9278514247207916968,
1632 0.9278514247207916968,
1633 -0.9474588680412107418,
1634 0.9474588680412107418,
1635 -0.9640313285931351987,
1636 0.9640313285931351987,
1637 -0.9775157355039892088,
1638 0.9775157355039892088,
1639 -0.9878689411988891985,
1640 0.9878689411988891985,
1641 -0.9950579778474118750,
1642 0.9950579778474118750,
1643 -0.9990614195648185414,
1644 0.9990614195648185414};
1645 x = c[n];
1646 } break;
1647
1648 case 56: {
1649 T const c[] = {-0.0277970352872754370, 0.0277970352872754370, -0.0833051868224353744, 0.0833051868224353744,
1650 -0.1385558468103762420, 0.1385558468103762420, -0.1933782386352752582, 0.1933782386352752582,
1651 -0.2476029094343372039, 0.2476029094343372039, -0.3010622538672206690, 0.3010622538672206690,
1652 -0.3535910321749545209, 0.3535910321749545209, -0.405026880927091278, 0.405026880927091278,
1653 -0.455210814878459578, 0.455210814878459578, -0.5039877183843817141, 0.5039877183843817141,
1654 -0.5512068248555346187, 0.5512068248555346187, -0.5967221827706633201, 0.5967221827706633201,
1655 -0.6403931068070068942, 0.6403931068070068942, -0.6820846126944704555, 0.6820846126944704555,
1656 -0.7216678344501880835, 0.7216678344501880835, -0.7590204227051289022, 0.7590204227051289022,
1657 -0.7940269228938664980, 0.7940269228938664980, -0.8265791321428816516, 0.8265791321428816516,
1658 -0.8565764337627486354, 0.8565764337627486354, -0.8839261083278275407, 0.8839261083278275407,
1659 -0.9085436204206554908, 0.9085436204206554908, -0.9303528802474963005, 0.9303528802474963005,
1660 -0.9492864795619626356, 0.9492864795619626356, -0.9652859019054901836, 0.9652859019054901836,
1661 -0.9783017091402563833, 0.9783017091402563833, -0.9882937155401615110, 0.9882937155401615110,
1662 -0.9952312260810697472, 0.9952312260810697472, -0.999094343801465584, 0.999094343801465584};
1663 x = c[n];
1664 } break;
1665
1666 case 57: {
1667 T const c[] = {
1668 0,
1669 -0.0546071510016468242,
1670 0.0546071510016468242,
1671 -0.1090513328087878009,
1672 0.1090513328087878009,
1673 -0.1631700625912642510,
1674 0.1631700625912642510,
1675 -0.2168018287961240364,
1676 0.2168018287961240364,
1677 -0.2697865731618387657,
1678 0.2697865731618387657,
1679 -0.3219661683953786405,
1680 0.3219661683953786405,
1681 -0.3731848900865944585,
1682 0.3731848900865944585,
1683 -0.4232898814515639509,
1684 0.4232898814515639509,
1685 -0.4721316095179757095,
1686 0.4721316095179757095,
1687 -0.5195643113911876063,
1688 0.5195643113911876063,
1689 -0.5654464292692367590,
1690 0.5654464292692367590,
1691 -0.6096410329087153654,
1692 0.6096410329087153654,
1693 -0.6520162282809768912,
1694 0.6520162282809768912,
1695 -0.692445551199517739,
1696 0.692445551199517739,
1697 -0.7308083447445233228,
1698 0.7308083447445233228,
1699 -0.7669901193594501954,
1700 0.7669901193594501954,
1701 -0.8008828945472182420,
1702 0.8008828945472182420,
1703 -0.8323855211504391208,
1704 0.8323855211504391208,
1705 -0.8614039832620469447,
1706 0.8614039832620469447,
1707 -0.8878516788822213295,
1708 0.8878516788822213295,
1709 -0.9116496785213912127,
1710 0.9116496785213912127,
1711 -0.9327269610671016961,
1712 0.9327269610671016961,
1713 -0.9510206264478767419,
1714 0.9510206264478767419,
1715 -0.9664760851718866791,
1716 0.9664760851718866791,
1717 -0.9790472267094687137,
1718 0.9790472267094687137,
1719 -0.9886965776502220488,
1720 0.9886965776502220488,
1721 -0.9953955236784303111,
1722 0.9953955236784303111,
1723 -0.9991255656252628505,
1724 0.9991255656252628505};
1725 x = c[n];
1726 } break;
1727
1728 case 58: {
1729 T const c[] = {-0.0268470123659423558, 0.0268470123659423558, -0.0804636302141427293, 0.0804636302141427293,
1730 -0.1338482505954668570, 0.1338482505954668570, -0.1868469518357613213, 0.1868469518357613213,
1731 -0.2393069249661534544, 0.2393069249661534544, -0.2910769143111091895, 0.2910769143111091895,
1732 -0.3420076535979952612, 0.3420076535979952612, -0.3919522963307531503, 0.3919522963307531503,
1733 -0.4407668391868395651, 0.4407668391868395651, -0.4883105372167184636, 0.4883105372167184636,
1734 -0.5344463096488475863, 0.5344463096488475863, -0.5790411351302250304, 0.5790411351302250304,
1735 -0.6219664352630791110, 0.6219664352630791110, -0.6630984453321252664, 0.6630984453321252664,
1736 -0.7023185711539081134, 0.7023185711539081134, -0.7395137310200422678, 0.7395137310200422678,
1737 -0.7745766817496527452, 0.7745766817496527452, -0.8074063279130881410, 0.8074063279130881410,
1738 -0.8379080133393733163, 0.8379080133393733163, -0.8659937940748074792, 0.8659937940748074792,
1739 -0.8915826920220301763, 0.8915826920220301763, -0.9146009285643525406, 0.9146009285643525406,
1740 -0.9349821375882593484, 0.9349821375882593484, -0.9526675575188690914, 0.9526675575188690914,
1741 -0.9676062025029240901, 0.9676062025029240901, -0.9797550146943503091, 0.9797550146943503091,
1742 -0.9890790082484426364, 0.9890790082484426364, -0.9955514765972909026, 0.9955514765972909026,
1743 -0.999155200407386606, 0.999155200407386606};
1744 x = c[n];
1745 } break;
1746
1747 case 59: {
1748 T const c[] = {
1749 0,
1750 -0.0527734840883100039,
1751 0.0527734840883100039,
1752 -0.1053998790163441438,
1753 0.1053998790163441438,
1754 -0.1577325055878579681,
1755 0.1577325055878579681,
1756 -0.2096255033920365449,
1757 0.2096255033920365449,
1758 -0.260934237342811711,
1759 0.260934237342811711,
1760 -0.3115157008030137003,
1761 0.3115157008030137003,
1762 -0.3612289141697948099,
1763 0.3612289141697948099,
1764 -0.4099353178104189667,
1765 0.4099353178104189667,
1766 -0.4574991582532666902,
1767 0.4574991582532666902,
1768 -0.5037878665577179787,
1769 0.5037878665577179787,
1770 -0.5486724278083963843,
1771 0.5486724278083963843,
1772 -0.5920277407040301444,
1773 0.5920277407040301444,
1774 -0.6337329662388500975,
1775 0.6337329662388500975,
1776 -0.6736718645049372270,
1777 0.6736718645049372270,
1778 -0.7117331186771977315,
1779 0.7117331186771977315,
1780 -0.747810645278640231,
1781 0.747810645278640231,
1782 -0.7818038898623609056,
1783 0.7818038898623609056,
1784 -0.8136181072882115714,
1785 0.8136181072882115714,
1786 -0.8431646258168722014,
1787 0.8431646258168722014,
1788 -0.8703610942928822609,
1789 0.8703610942928822609,
1790 -0.895131711743472085,
1791 0.895131711743472085,
1792 -0.9174074387881552813,
1793 0.9174074387881552813,
1794 -0.9371261903534538594,
1795 0.9371261903534538594,
1796 -0.9542330093769510558,
1797 0.9542330093769510558,
1798 -0.9686802216817815313,
1799 0.9686802216817815313,
1800 -0.9804275739567156884,
1801 0.9804275739567156884,
1802 -0.9894423651337309317,
1803 0.9894423651337309317,
1804 -0.995699640383245964,
1805 0.995699640383245964,
1806 -0.999183353909294683,
1807 0.999183353909294683};
1808 x = c[n];
1809 } break;
1810
1811 case 60: {
1812 T const c[] = {-0.0259597723012477985, 0.0259597723012477985, -0.0778093339495365694, 0.0778093339495365694,
1813 -0.1294491353969450031, 0.1294491353969450031, -0.1807399648734254172, 0.1807399648734254172,
1814 -0.2315435513760293380, 0.2315435513760293380, -0.2817229374232616916, 0.2817229374232616916,
1815 -0.3311428482684481942, 0.3311428482684481942, -0.3796700565767979771, 0.3796700565767979771,
1816 -0.4271737415830783893, 0.4271737415830783893, -0.4735258417617071111, 0.4735258417617071111,
1817 -0.5186014000585697474, 0.5186014000585697474, -0.562278900753944539, 0.562278900753944539,
1818 -0.6044405970485103634, 0.6044405970485103634, -0.6449728284894770678, 0.6449728284894770678,
1819 -0.6837663273813554372, 0.6837663273813554372, -0.7207165133557303994, 0.7207165133557303994,
1820 -0.7557237753065856868, 0.7557237753065856868, -0.7886937399322640545, 0.7886937399322640545,
1821 -0.8195375261621457593, 0.8195375261621457593, -0.8481719847859296324, 0.8481719847859296324,
1822 -0.8745199226468983151, 0.8745199226468983151, -0.8985103108100459419, 0.8985103108100459419,
1823 -0.9200784761776275528, 0.9200784761776275528, -0.9391662761164232494, 0.9391662761164232494,
1824 -0.9557222558399961073, 0.9557222558399961073, -0.9697017887650527337, 0.9697017887650527337,
1825 -0.9810672017525981856, 0.9810672017525981856, -0.9897878952222217173, 0.9897878952222217173,
1826 -0.9958405251188381738, 0.9958405251188381738, -0.9992101232274360220, 0.9992101232274360220};
1827 x = c[n];
1828 } break;
1829
1830 case 61: {
1831 T const c[] = {
1832 0,
1833 -0.0510589067079743493,
1834 0.0510589067079743493,
1835 -0.1019846065622740689,
1836 0.1019846065622740689,
1837 -0.1526442402308153005,
1838 0.1526442402308153005,
1839 -0.2029056425180584992,
1840 0.2029056425180584992,
1841 -0.2526376871690534958,
1842 0.2526376871690534958,
1843 -0.3017106289630307126,
1844 0.3017106289630307126,
1845 -0.3499964422040668345,
1846 0.3499964422040668345,
1847 -0.3973691547257566091,
1848 0.3973691547257566091,
1849 -0.4437051765385316019,
1850 0.4437051765385316019,
1851 -0.4888836222622521188,
1852 0.4888836222622521188,
1853 -0.5327866265029252656,
1854 0.5327866265029252656,
1855 -0.5752996513508306186,
1856 0.5752996513508306186,
1857 -0.6163117851979217247,
1858 0.6163117851979217247,
1859 -0.6557160320950708716,
1860 0.6557160320950708716,
1861 -0.6934095908944911554,
1862 0.6934095908944911554,
1863 -0.7292941234494651096,
1864 0.7292941234494651096,
1865 -0.7632760111723121971,
1866 0.7632760111723121971,
1867 -0.7952665992823596491,
1868 0.7952665992823596491,
1869 -0.8251824281086599506,
1870 0.8251824281086599506,
1871 -0.8529454508476634455,
1872 0.8529454508476634455,
1873 -0.8784832372148810324,
1874 0.8784832372148810324,
1875 -0.901729162474001170,
1876 0.901729162474001170,
1877 -0.9226225813829552612,
1878 0.9226225813829552612,
1879 -0.9411089866813611474,
1880 0.9411089866813611474,
1881 -0.9571401519129840913,
1882 0.9571401519129840913,
1883 -0.9706742588331829082,
1884 0.9706742588331829082,
1885 -0.9816760112840370796,
1886 0.9816760112840370796,
1887 -0.9901167452325170509,
1888 0.9901167452325170509,
1889 -0.9959745998151202342,
1890 0.9959745998151202342,
1891 -0.9992355976313634717,
1892 0.9992355976313634717};
1893 x = c[n];
1894 } break;
1895
1896 case 62: {
1897 T const c[] = {-0.0251292914218206147, 0.0251292914218206147, -0.0753243954962343327, 0.0753243954962343327,
1898 -0.1253292236158968086, 0.1253292236158968086, -0.175017459249015628, 0.175017459249015628,
1899 -0.2242635856041655316, 0.2242635856041655316, -0.2729432026967263431, 0.2729432026967263431,
1900 -0.3209333415941940040, 0.3209333415941940040, -0.3681127750465645296, 0.3681127750465645296,
1901 -0.4143623237171260481, 0.4143623237171260481, -0.4595651572401133952, 0.4595651572401133952,
1902 -0.5036070893447559559, 0.5036070893447559559, -0.5463768663002510958, 0.5463768663002510958,
1903 -0.5877664479530873380, 0.5877664479530873380, -0.6276712806468851807, 0.6276712806468851807,
1904 -0.665990561335479446, 0.665990561335479446, -0.7026274922222970551, 0.7026274922222970551,
1905 -0.7374895252831567498, 0.7374895252831567498, -0.7704885960554193189, 0.7704885960554193189,
1906 -0.8015413461039763715, 0.8015413461039763715, -0.8305693336040048513, 0.8305693336040048513,
1907 -0.8574992315120709228, 0.8574992315120709228, -0.882263012831897363, 0.882263012831897363,
1908 -0.9047981225210934657, 0.9047981225210934657, -0.9250476356362037552, 0.9250476356362037552,
1909 -0.9429604013923285038, 0.9429604013923285038, -0.95849117297392709, 0.95849117297392709,
1910 -0.9716007233716518064, 0.9716007233716518064, -0.9822559490972366494, 0.9822559490972366494,
1911 -0.9904299711892903524, 0.9904299711892903524, -0.9961022963162671328, 0.9961022963162671328,
1912 -0.9992598593087770296, 0.9992598593087770296};
1913 x = c[n];
1914 } break;
1915
1916 case 63: {
1917 T const c[] = {
1918 0,
1919 -0.0494521871161596272,
1920 0.0494521871161596272,
1921 -0.0987833564469452795,
1922 0.0987833564469452795,
1923 -0.1478727863578719685,
1924 0.1478727863578719685,
1925 -0.1966003467915066845,
1926 0.1966003467915066845,
1927 -0.2448467932459533627,
1928 0.2448467932459533627,
1929 -0.2924940585862514400,
1930 0.2924940585862514400,
1931 -0.3394255419745844024,
1932 0.3394255419745844024,
1933 -0.385526394212247892,
1934 0.385526394212247892,
1935 -0.4306837987951116006,
1936 0.4306837987951116006,
1937 -0.4747872479948043999,
1938 0.4747872479948043999,
1939 -0.5177288132900332481,
1940 0.5177288132900332481,
1941 -0.5594034094862850132,
1942 0.5594034094862850132,
1943 -0.5997090518776252357,
1944 0.5997090518776252357,
1945 -0.6385471058213653850,
1946 0.6385471058213653850,
1947 -0.6758225281149860901,
1948 0.6758225281149860901,
1949 -0.7114440995848458078,
1950 0.7114440995848458078,
1951 -0.7453246483178474178,
1952 0.7453246483178474178,
1953 -0.7773812629903723355,
1954 0.7773812629903723355,
1955 -0.8075354957734567600,
1956 0.8075354957734567600,
1957 -0.8357135543195028434,
1958 0.8357135543195028434,
1959 -0.8618464823641237195,
1960 0.8618464823641237195,
1961 -0.8858703285078534262,
1962 0.8858703285078534262,
1963 -0.907726302778531558,
1964 0.907726302778531558,
1965 -0.9273609206218432054,
1966 0.9273609206218432054,
1967 -0.9447261340410098029,
1968 0.9447261340410098029,
1969 -0.959779449758941927,
1970 0.959779449758941927,
1971 -0.9724840346975700228,
1972 0.9724840346975700228,
1973 -0.9828088105937272348,
1974 0.9828088105937272348,
1975 -0.9907285468921894668,
1976 0.9907285468921894668,
1977 -0.996224012777970108,
1978 0.996224012777970108,
1979 -0.9992829840291237803,
1980 0.9992829840291237803};
1981 x = c[n];
1982 } break;
1983
1984 case 64: {
1985 T const c[] = {-0.0243502926634244325, 0.0243502926634244325, -0.0729931217877990394, 0.0729931217877990394,
1986 -0.1214628192961205544, 0.1214628192961205544, -0.1696444204239928180, 0.1696444204239928180,
1987 -0.217423643740007084, 0.217423643740007084, -0.2646871622087674163, 0.2646871622087674163,
1988 -0.3113228719902109561, 0.3113228719902109561, -0.357220158337668115, 0.357220158337668115,
1989 -0.4022701579639916036, 0.4022701579639916036, -0.4463660172534640879, 0.4463660172534640879,
1990 -0.4894031457070529574, 0.4894031457070529574, -0.531279464019894545, 0.531279464019894545,
1991 -0.5718956462026340342, 0.5718956462026340342, -0.6111553551723932502, 0.6111553551723932502,
1992 -0.6489654712546573398, 0.6489654712546573398, -0.6852363130542332425, 0.6852363130542332425,
1993 -0.7198818501716108268, 0.7198818501716108268, -0.7528199072605318966, 0.7528199072605318966,
1994 -0.7839723589433414076, 0.7839723589433414076, -0.8132653151227975597, 0.8132653151227975597,
1995 -0.840629296252580362, 0.840629296252580362, -0.8659993981540928197, 0.8659993981540928197,
1996 -0.8893154459951141058, 0.8893154459951141058, -0.9105221370785028057, 0.9105221370785028057,
1997 -0.9295691721319395758, 0.9295691721319395758, -0.9464113748584028160, 0.9464113748584028160,
1998 -0.9610087996520537189, 0.9610087996520537189, -0.9733268277899109637, 0.9733268277899109637,
1999 -0.9833362538846259569, 0.9833362538846259569, -0.9910133714767443207, 0.9910133714767443207,
2000 -0.9963401167719552793, 0.9963401167719552793, -0.9993050417357721394, 0.9993050417357721394};
2001 x = c[n];
2002 } break;
2003 }
2004 return x;
2005}
2006
2007template<typename T>
2009T
2010gauss_legendre_weights(Index const m, Index const n)
2011{
2012 T x = 0.0;
2013 switch (m) {
2014 default: break;
2015 case 1: {
2016 T const c[] = {2.000000000000000000};
2017 x = c[n];
2018 } break;
2019 case 2: {
2020 T const c[] = {1.000000000000000000, 1.000000000000000000};
2021 x = c[n];
2022 } break;
2023
2024 case 3: {
2025 T const c[] = {0.8888888888888888888, 0.5555555555555555555, 0.5555555555555555555};
2026 x = c[n];
2027 } break;
2028
2029 case 4: {
2030 T const c[] = {0.6521451548625461426, 0.6521451548625461426, 0.3478548451374538573, 0.3478548451374538573};
2031 x = c[n];
2032 } break;
2033
2034 case 5: {
2035 T const c[] = {
2036 0.5688888888888888888,
2037 0.4786286704993664680,
2038 0.4786286704993664680,
2039 0.2369268850561890875,
2040 0.2369268850561890875};
2041 x = c[n];
2042 } break;
2043
2044 case 6: {
2045 T const c[] = {
2046 0.3607615730481386075698335138377,
2047 0.3607615730481386075698335138377,
2048 0.4679139345726910473898703439895,
2049 0.4679139345726910473898703439895,
2050 0.1713244923791703450402961421727,
2051 0.1713244923791703450402961421727};
2052 x = c[n];
2053 } break;
2054
2055 case 7: {
2056 T const c[] = {
2057 0.4179591836734693877,
2058 0.3818300505051189449503697754889,
2059 0.3818300505051189449503697754889,
2060 0.2797053914892766679014677714237,
2061 0.2797053914892766679014677714237,
2062 0.1294849661688696932706114326790,
2063 0.1294849661688696932706114326790};
2064 x = c[n];
2065 } break;
2066
2067 case 8: {
2068 T const c[] = {
2069 0.3626837833783619829651504492771,
2070 0.3626837833783619829651504492771,
2071 0.3137066458778872873379622019866,
2072 0.3137066458778872873379622019866,
2073 0.2223810344533744705443559944262,
2074 0.2223810344533744705443559944262,
2075 0.1012285362903762591525313543099,
2076 0.1012285362903762591525313543099};
2077 x = c[n];
2078 } break;
2079
2080 case 9: {
2081 T const c[] = {
2082 0.3302393550012597631,
2083 0.1806481606948574040584720312429,
2084 0.1806481606948574040584720312429,
2085 0.081274388361574411971892158110523,
2086 0.081274388361574411971892158110523,
2087 0.3123470770400028400686304065844,
2088 0.3123470770400028400686304065844,
2089 0.2606106964029354623187428694186,
2090 0.2606106964029354623187428694186};
2091 x = c[n];
2092 } break;
2093
2094 case 10: {
2095 T const c[] = {
2096 0.295524224714752870,
2097 0.295524224714752870,
2098 0.2692667193099963550,
2099 0.2692667193099963550,
2100 0.2190863625159820439,
2101 0.2190863625159820439,
2102 0.1494513491505805931,
2103 0.1494513491505805931,
2104 0.066671344308688137,
2105 0.066671344308688137};
2106 x = c[n];
2107 } break;
2108
2109 case 11: {
2110 T const c[] = {
2111 0.2729250867779006307,
2112 0.2628045445102466621,
2113 0.2628045445102466621,
2114 0.2331937645919904799,
2115 0.2331937645919904799,
2116 0.1862902109277342514,
2117 0.1862902109277342514,
2118 0.1255803694649046246,
2119 0.1255803694649046246,
2120 0.0556685671161736664,
2121 0.0556685671161736664};
2122 x = c[n];
2123 } break;
2124
2125 case 12: {
2126 T const c[] = {
2127 0.2491470458134027850,
2128 0.2491470458134027850,
2129 0.2334925365383548087,
2130 0.2334925365383548087,
2131 0.203167426723065921,
2132 0.203167426723065921,
2133 0.1600783285433462263,
2134 0.1600783285433462263,
2135 0.1069393259953184309,
2136 0.1069393259953184309,
2137 0.0471753363865118271,
2138 0.0471753363865118271};
2139 x = c[n];
2140 } break;
2141
2142 case 13: {
2143 T const c[] = {
2144 0.2325515532308739101,
2145 0.2262831802628972384,
2146 0.2262831802628972384,
2147 0.2078160475368885023,
2148 0.2078160475368885023,
2149 0.1781459807619457382,
2150 0.1781459807619457382,
2151 0.138873510219787238,
2152 0.138873510219787238,
2153 0.0921214998377284479,
2154 0.0921214998377284479,
2155 0.0404840047653158795,
2156 0.0404840047653158795};
2157 x = c[n];
2158 } break;
2159
2160 case 14: {
2161 T const c[] = {
2162 0.215263853463157790,
2163 0.215263853463157790,
2164 0.2051984637212956039,
2165 0.2051984637212956039,
2166 0.1855383974779378137,
2167 0.1855383974779378137,
2168 0.1572031671581935345,
2169 0.1572031671581935345,
2170 0.1215185706879031846,
2171 0.1215185706879031846,
2172 0.0801580871597602098,
2173 0.0801580871597602098,
2174 0.0351194603317518630,
2175 0.0351194603317518630};
2176 x = c[n];
2177 } break;
2178
2179 case 15: {
2180 T const c[] = {
2181 0.2025782419255612728,
2182 0.1984314853271115764,
2183 0.1984314853271115764,
2184 0.1861610000155622110,
2185 0.1861610000155622110,
2186 0.1662692058169939335,
2187 0.1662692058169939335,
2188 0.1395706779261543144,
2189 0.1395706779261543144,
2190 0.1071592204671719350,
2191 0.1071592204671719350,
2192 0.0703660474881081247,
2193 0.0703660474881081247,
2194 0.0307532419961172683,
2195 0.0307532419961172683};
2196 x = c[n];
2197 } break;
2198
2199 case 16: {
2200 T const c[] = {
2201 0.1894506104550684962,
2202 0.1894506104550684962,
2203 0.1826034150449235888,
2204 0.1826034150449235888,
2205 0.1691565193950025381,
2206 0.1691565193950025381,
2207 0.1495959888165767320,
2208 0.1495959888165767320,
2209 0.1246289712555338720,
2210 0.1246289712555338720,
2211 0.0951585116824927848,
2212 0.0951585116824927848,
2213 0.0622535239386478928,
2214 0.0622535239386478928,
2215 0.0271524594117540948,
2216 0.0271524594117540948};
2217 x = c[n];
2218 } break;
2219
2220 case 17: {
2221 T const c[] = {
2222 0.1794464703562065254,
2223 0.1765627053669926463,
2224 0.1765627053669926463,
2225 0.1680041021564500445,
2226 0.1680041021564500445,
2227 0.154045761076810288,
2228 0.154045761076810288,
2229 0.1351363684685254732,
2230 0.1351363684685254732,
2231 0.1118838471934039710,
2232 0.1118838471934039710,
2233 0.0850361483171791808,
2234 0.0850361483171791808,
2235 0.055459529373987201,
2236 0.055459529373987201,
2237 0.0241483028685479319,
2238 0.0241483028685479319};
2239 x = c[n];
2240 } break;
2241
2242 case 18: {
2243 T const c[] = {
2244 0.1691423829631435918,
2245 0.1691423829631435918,
2246 0.1642764837458327229,
2247 0.1642764837458327229,
2248 0.1546846751262652449,
2249 0.1546846751262652449,
2250 0.1406429146706506512,
2251 0.1406429146706506512,
2252 0.1225552067114784601,
2253 0.1225552067114784601,
2254 0.1009420441062871655,
2255 0.1009420441062871655,
2256 0.0764257302548890565,
2257 0.0764257302548890565,
2258 0.0497145488949697964,
2259 0.0497145488949697964,
2260 0.0216160135264833103,
2261 0.0216160135264833103};
2262 x = c[n];
2263 } break;
2264
2265 case 19: {
2266 T const c[] = {
2267 0.1610544498487836959,
2268 0.1589688433939543476,
2269 0.1589688433939543476,
2270 0.1527660420658596667,
2271 0.1527660420658596667,
2272 0.1426067021736066117,
2273 0.1426067021736066117,
2274 0.1287539625393362276,
2275 0.1287539625393362276,
2276 0.1115666455473339947,
2277 0.1115666455473339947,
2278 0.0914900216224499994,
2279 0.0914900216224499994,
2280 0.0690445427376412265,
2281 0.0690445427376412265,
2282 0.0448142267656996003,
2283 0.0448142267656996003,
2284 0.0194617882297264770,
2285 0.0194617882297264770};
2286 x = c[n];
2287 } break;
2288
2289 case 20: {
2290 T const c[] = {0.1527533871307258506, 0.1527533871307258506, 0.1491729864726037467, 0.1491729864726037467,
2291 0.1420961093183820513, 0.1420961093183820513, 0.131688638449176626, 0.131688638449176626,
2292 0.1181945319615184173, 0.1181945319615184173, 0.1019301198172404350, 0.1019301198172404350,
2293 0.0832767415767047487, 0.0832767415767047487, 0.0626720483341090635, 0.0626720483341090635,
2294 0.0406014298003869413, 0.0406014298003869413, 0.017614007139152118, 0.017614007139152118};
2295 x = c[n];
2296 } break;
2297
2298 case 21: {
2299 T const c[] = {0.1460811336496904271, 0.1445244039899700590, 0.1445244039899700590, 0.1398873947910731547,
2300 0.1398873947910731547, 0.1322689386333374617, 0.1322689386333374617, 0.12183141605372853,
2301 0.12183141605372853, 0.1087972991671483776, 0.1087972991671483776, 0.0934444234560338615,
2302 0.0934444234560338615, 0.0761001136283793020, 0.0761001136283793020, 0.0571344254268572082,
2303 0.0571344254268572082, 0.0369537897708524937, 0.0369537897708524937, 0.0160172282577743333,
2304 0.0160172282577743333};
2305 x = c[n];
2306 } break;
2307
2308 case 22: {
2309 T const c[] = {0.139251872855631993, 0.139251872855631993, 0.1365414983460151713, 0.1365414983460151713,
2310 0.1311735047870623707, 0.1311735047870623707, 0.1232523768105124242, 0.1232523768105124242,
2311 0.1129322960805392183, 0.1129322960805392183, 0.1004141444428809649, 0.1004141444428809649,
2312 0.0859416062170677274, 0.0859416062170677274, 0.0697964684245204880, 0.0697964684245204880,
2313 0.0522933351526832859, 0.0522933351526832859, 0.0337749015848141547, 0.0337749015848141547,
2314 0.0146279952982722006, 0.0146279952982722006};
2315 x = c[n];
2316 } break;
2317
2318 case 23: {
2319 T const c[] = {0.1336545721861061753, 0.1324620394046966173, 0.1324620394046966173, 0.1289057221880821499,
2320 0.1289057221880821499, 0.1230490843067295304, 0.1230490843067295304, 0.1149966402224113649,
2321 0.1149966402224113649, 0.1048920914645414100, 0.1048920914645414100, 0.0929157660600351474,
2322 0.0929157660600351474, 0.0792814117767189549, 0.0792814117767189549, 0.0642324214085258521,
2323 0.0642324214085258521, 0.0480376717310846685, 0.0480376717310846685, 0.0309880058569794443,
2324 0.0309880058569794443, 0.0134118594871417720, 0.0134118594871417720};
2325 x = c[n];
2326 } break;
2327
2328 case 24: {
2329 T const c[] = {0.1279381953467521569, 0.1279381953467521569, 0.1258374563468282961, 0.1258374563468282961,
2330 0.1216704729278033912, 0.1216704729278033912, 0.1155056680537256013, 0.1155056680537256013,
2331 0.107444270115965634, 0.107444270115965634, 0.097618652104113888, 0.097618652104113888,
2332 0.0861901615319532759, 0.0861901615319532759, 0.0733464814110803057, 0.0733464814110803057,
2333 0.0592985849154367807, 0.0592985849154367807, 0.0442774388174198061, 0.0442774388174198061,
2334 0.0285313886289336631, 0.0285313886289336631, 0.0123412297999871995, 0.0123412297999871995};
2335 x = c[n];
2336 } break;
2337
2338 case 25: {
2339 T const c[] = {0.1231760537267154512, 0.1222424429903100416, 0.1222424429903100416, 0.1194557635357847722,
2340 0.1194557635357847722, 0.1148582591457116483, 0.1148582591457116483, 0.1085196244742636531,
2341 0.1085196244742636531, 0.1005359490670506442, 0.1005359490670506442, 0.0910282619829636498,
2342 0.0910282619829636498, 0.0801407003350010180, 0.0801407003350010180, 0.0680383338123569172,
2343 0.0680383338123569172, 0.0549046959758351919, 0.0549046959758351919, 0.0409391567013063126,
2344 0.0409391567013063126, 0.0263549866150321372, 0.0263549866150321372, 0.0113937985010262879,
2345 0.0113937985010262879};
2346 x = c[n];
2347 } break;
2348
2349 case 26: {
2350 T const c[] = {0.1183214152792622765, 0.1183214152792622765, 0.116660443485296582, 0.116660443485296582,
2351 0.1133618165463196665, 0.1133618165463196665, 0.1084718405285765906, 0.1084718405285765906,
2352 0.102059161094425423, 0.102059161094425423, 0.0942138003559141484, 0.0942138003559141484,
2353 0.0850458943134852392, 0.0850458943134852392, 0.0746841497656597458, 0.0746841497656597458,
2354 0.0632740463295748355, 0.0632740463295748355, 0.0509758252971478119, 0.0509758252971478119,
2355 0.0379623832943627639, 0.0379623832943627639, 0.0244178510926319087, 0.0244178510926319087,
2356 0.010551372617343007, 0.010551372617343007};
2357 x = c[n];
2358 } break;
2359
2360 case 27: {
2361 T const c[] = {0.1142208673789569890, 0.1134763461089651486, 0.1134763461089651486, 0.1112524883568451926,
2362 0.1112524883568451926, 0.107578285788533187, 0.107578285788533187, 0.1025016378177457986,
2363 0.1025016378177457986, 0.0960887273700285075, 0.0960887273700285075, 0.0884231585437569501,
2364 0.0884231585437569501, 0.0796048677730577712, 0.0796048677730577712, 0.0697488237662455929,
2365 0.0697488237662455929, 0.058983536859833599, 0.058983536859833599, 0.0474494125206150627,
2366 0.0474494125206150627, 0.0352970537574197110, 0.0352970537574197110, 0.0226862315961806231,
2367 0.0226862315961806231, 0.0097989960512943602, 0.0097989960512943602};
2368 x = c[n];
2369 } break;
2370
2371 case 28: {
2372 T const c[] = {0.1100470130164751962, 0.1100470130164751962, 0.108711192258294135, 0.108711192258294135,
2373 0.1060557659228464179, 0.1060557659228464179, 0.1021129675780607698, 0.1021129675780607698,
2374 0.0969306579979299158, 0.0969306579979299158, 0.0905717443930328409, 0.0905717443930328409,
2375 0.08311341722890121, 0.08311341722890121, 0.0746462142345687790, 0.0746462142345687790,
2376 0.0652729239669995957, 0.0652729239669995957, 0.0551073456757167454, 0.0551073456757167454,
2377 0.0442729347590042278, 0.0442729347590042278, 0.0329014277823043799, 0.0329014277823043799,
2378 0.0211321125927712597, 0.0211321125927712597, 0.009124282593094517, 0.009124282593094517};
2379 x = c[n];
2380 } break;
2381
2382 case 29: {
2383 T const c[] = {0.1064793817183142442, 0.1058761550973209414, 0.1058761550973209414, 0.1040733100777293739,
2384 0.1040733100777293739, 0.1010912737599149661, 0.1010912737599149661, 0.0969638340944086063,
2385 0.0969638340944086063, 0.091737757139258763, 0.091737757139258763, 0.0854722573661725275,
2386 0.0854722573661725275, 0.0782383271357637838, 0.0782383271357637838, 0.0701179332550512785,
2387 0.0701179332550512785, 0.0612030906570791385, 0.0612030906570791385, 0.051594826902497923,
2388 0.051594826902497923, 0.0414020625186828361, 0.0414020625186828361, 0.0307404922020936226,
2389 0.0307404922020936226, 0.0197320850561227059, 0.0197320850561227059, 0.0085169038787464096,
2390 0.0085169038787464096};
2391 x = c[n];
2392 } break;
2393
2394 case 30: {
2395 T const c[] = {0.1028526528935588403, 0.1028526528935588403, 0.1017623897484055045, 0.1017623897484055045,
2396 0.09959342058679526, 0.09959342058679526, 0.0963687371746442596, 0.0963687371746442596,
2397 0.0921225222377861287, 0.0921225222377861287, 0.0868997872010829798, 0.0868997872010829798,
2398 0.0807558952294202153, 0.0807558952294202153, 0.073755974737705206, 0.073755974737705206,
2399 0.0659742298821804951, 0.0659742298821804951, 0.0574931562176190664, 0.0574931562176190664,
2400 0.0484026728305940529, 0.0484026728305940529, 0.0387991925696270495, 0.0387991925696270495,
2401 0.0287847078833233693, 0.0287847078833233693, 0.0184664683110909591, 0.0184664683110909591,
2402 0.0079681924961666056, 0.0079681924961666056};
2403 x = c[n];
2404 } break;
2405
2406 case 31: {
2407 T const c[] = {0.099720544793426451, 0.0992250112266723078, 0.0992250112266723078, 0.0977433353863287250,
2408 0.0977433353863287250, 0.0952902429123195128, 0.0952902429123195128, 0.0918901138936414782,
2409 0.0918901138936414782, 0.0875767406084778761, 0.0875767406084778761, 0.0823929917615892639,
2410 0.0823929917615892639, 0.0763903865987766164, 0.0763903865987766164, 0.0696285832354103661,
2411 0.0696285832354103661, 0.0621747865610284269, 0.0621747865610284269, 0.0541030824249168537,
2412 0.0541030824249168537, 0.0454937075272011029, 0.0454937075272011029, 0.0364322739123854640,
2413 0.0364322739123854640, 0.0270090191849794218, 0.0270090191849794218, 0.0173186207903105824,
2414 0.0173186207903105824, 0.007470831579248775, 0.007470831579248775};
2415 x = c[n];
2416 } break;
2417
2418 case 32: {
2419 T const c[] = {0.0965400885147278005, 0.0965400885147278005, 0.0956387200792748594, 0.0956387200792748594,
2420 0.0938443990808045656, 0.0938443990808045656, 0.0911738786957638847, 0.0911738786957638847,
2421 0.0876520930044038111, 0.0876520930044038111, 0.0833119242269467552, 0.0833119242269467552,
2422 0.078193895787070306, 0.078193895787070306, 0.0723457941088485062, 0.0723457941088485062,
2423 0.0658222227763618468, 0.0658222227763618468, 0.0586840934785355471, 0.0586840934785355471,
2424 0.0509980592623761761, 0.0509980592623761761, 0.0428358980222266806, 0.0428358980222266806,
2425 0.0342738629130214331, 0.0342738629130214331, 0.0253920653092620594, 0.0253920653092620594,
2426 0.0162743947309056706, 0.0162743947309056706, 0.0070186100094700966, 0.0070186100094700966};
2427 x = c[n];
2428 } break;
2429
2430 case 33: {
2431 T const c[] = {0.0937684461602099965, 0.093356426065596116, 0.093356426065596116, 0.0921239866433168462,
2432 0.0921239866433168462, 0.0900819586606385772, 0.0900819586606385772, 0.0872482876188443376,
2433 0.0872482876188443376, 0.0836478760670387076, 0.0836478760670387076, 0.0793123647948867383,
2434 0.0793123647948867383, 0.0742798548439541493, 0.0742798548439541493, 0.0685945728186567128,
2435 0.0685945728186567128, 0.0623064825303174800, 0.0623064825303174800, 0.0554708466316635612,
2436 0.0554708466316635612, 0.0481477428187116956, 0.0481477428187116956, 0.0404015413316695915,
2437 0.0404015413316695915, 0.0323003586323289532, 0.0323003586323289532, 0.0239155481017494803,
2438 0.0239155481017494803, 0.0153217015129346761, 0.0153217015129346761, 0.0066062278475873780,
2439 0.0066062278475873780};
2440 x = c[n];
2441 } break;
2442
2443 case 34: {
2444 T const c[] = {0.0909567403302598736, 0.0909567403302598736, 0.0902030443706407295, 0.0902030443706407295,
2445 0.0887018978356938692, 0.0887018978356938692, 0.0864657397470357497, 0.0864657397470357497,
2446 0.0835130996998456551, 0.0835130996998456551, 0.0798684443397718447, 0.0798684443397718447,
2447 0.0755619746600319312, 0.0755619746600319312, 0.0706293758142557249, 0.0706293758142557249,
2448 0.0651115215540764113, 0.0651115215540764113, 0.059054135827524493, 0.059054135827524493,
2449 0.0525074145726781061, 0.0525074145726781061, 0.045525611523353272, 0.045525611523353272,
2450 0.038166593796387516, 0.038166593796387516, 0.0304913806384461318, 0.0304913806384461318,
2451 0.0225637219854949700, 0.0225637219854949700, 0.014450162748595035, 0.014450162748595035,
2452 0.0062291405559086847, 0.0062291405559086847};
2453 x = c[n];
2454 } break;
2455
2456 case 35: {
2457 T const c[] = {0.0884867949071042906, 0.0881405304302754629, 0.0881405304302754629, 0.0871044469971835342,
2458 0.0871044469971835342, 0.0853866533920991252, 0.0853866533920991252, 0.0830005937288565883,
2459 0.0830005937288565883, 0.0799649422423242629, 0.0799649422423242629, 0.0763034571554420535,
2460 0.0763034571554420535, 0.0720447947725600646, 0.0720447947725600646, 0.0672222852690869039,
2461 0.0672222852690869039, 0.0618736719660801888, 0.0618736719660801888, 0.0560408162123701285,
2462 0.0560408162123701285, 0.0497693704013535298, 0.0497693704013535298, 0.0431084223261702187,
2463 0.0431084223261702187, 0.0361101158634633805, 0.0361101158634633805, 0.0288292601088942540,
2464 0.0288292601088942540, 0.0213229799114835808, 0.0213229799114835808, 0.0136508283483614922,
2465 0.0136508283483614922, 0.0058834334204430849, 0.0058834334204430849};
2466 x = c[n];
2467 } break;
2468
2469 case 36: {
2470 T const c[] = {0.0859832756703947474, 0.0859832756703947474, 0.0853466857393386274, 0.0853466857393386274,
2471 0.0840782189796619349, 0.0840782189796619349, 0.0821872667043397095, 0.0821872667043397095,
2472 0.0796878289120716019, 0.0796878289120716019, 0.07659841064587067, 0.07659841064587067,
2473 0.0729418850056530613, 0.0729418850056530613, 0.0687453238357364426, 0.0687453238357364426,
2474 0.0640397973550154895, 0.0640397973550154895, 0.0588601442453248173, 0.0588601442453248173,
2475 0.0532447139777599190, 0.0532447139777599190, 0.047235083490265978, 0.047235083490265978,
2476 0.0408757509236448954, 0.0408757509236448954, 0.0342138107703072299, 0.0342138107703072299,
2477 0.027298621498568779, 0.027298621498568779, 0.0201815152977354715, 0.0201815152977354715,
2478 0.0129159472840655744, 0.0129159472840655744, 0.0055657196642450453, 0.0055657196642450453};
2479 x = c[n];
2480 } break;
2481
2482 case 37: {
2483 T const c[] = {0.0837683609931389047, 0.083474573625862787, 0.083474573625862787, 0.082595272236437250,
2484 0.082595272236437250, 0.0811366245084650305, 0.0811366245084650305, 0.0791088618375293807,
2485 0.0791088618375293807, 0.0765262075705292378, 0.0765262075705292378, 0.073406777248488172,
2486 0.073406777248488172, 0.0697724515557003448, 0.0697724515557003448, 0.0656487228727512494,
2487 0.0656487228727512494, 0.061064516523225986, 0.061064516523225986, 0.0560519879982749178,
2488 0.0560519879982749178, 0.05064629765482460, 0.05064629765482460, 0.0448853646624371666,
2489 0.0448853646624371666, 0.0388096025019345444, 0.0388096025019345444, 0.0324616398475214810,
2490 0.0324616398475214810, 0.0258860369905589335, 0.0258860369905589335, 0.0191290444890839660,
2491 0.0191290444890839660, 0.0122387801003075565, 0.0122387801003075565, 0.0052730572794979393,
2492 0.0052730572794979393};
2493 x = c[n];
2494 } break;
2495
2496 case 38: {
2497 T const c[] = {0.0815250292803857866, 0.0815250292803857866, 0.0809824937705971006, 0.0809824937705971006,
2498 0.0799010332435278215, 0.0799010332435278215, 0.0782878446582109480, 0.0782878446582109480,
2499 0.0761536635484463960, 0.0761536635484463960, 0.0735126925847434571, 0.0735126925847434571,
2500 0.0703825070668989547, 0.0703825070668989547, 0.0667839379791404119, 0.0667839379791404119,
2501 0.062740933392133054, 0.062740933392133054, 0.0582803991469972060, 0.0582803991469972060,
2502 0.0534320199103323199, 0.0534320199103323199, 0.0482280618607586833, 0.0482280618607586833,
2503 0.0427031585046744342, 0.0427031585046744342, 0.0368940815940247381, 0.0368940815940247381,
2504 0.0308395005451750546, 0.0308395005451750546, 0.0245797397382323758, 0.0245797397382323758,
2505 0.0181565777096132368, 0.0181565777096132368, 0.0116134447164686741, 0.0116134447164686741,
2506 0.0050028807496393456, 0.0050028807496393456};
2507 x = c[n];
2508 } break;
2509
2510 case 39: {
2511 T const c[] = {0.0795276221394428524, 0.0792762225683684710, 0.0792762225683684710, 0.0785236132873711767,
2512 0.0785236132873711767, 0.0772745525446820167, 0.0772745525446820167, 0.075536937322836057,
2513 0.075536937322836057, 0.0733217534142686173, 0.0733217534142686173, 0.0706430059706087607,
2514 0.0706430059706087607, 0.0675176309662312653, 0.0675176309662312653, 0.0639653881386823889,
2515 0.0639653881386823889, 0.0600087360885961495, 0.0600087360885961495, 0.0556726903409162999,
2516 0.0556726903409162999, 0.05098466529212940, 0.05098466529212940, 0.0459743011089166318,
2517 0.0459743011089166318, 0.040673276847933843, 0.040673276847933843, 0.0351151114981313307,
2518 0.0351151114981313307, 0.0293349559839033785, 0.0293349559839033785, 0.023369384832178164,
2519 0.023369384832178164, 0.0172562290937249190, 0.0172562290937249190, 0.0110347889391645942,
2520 0.0110347889391645942, 0.0047529446916351013, 0.0047529446916351013};
2521 x = c[n];
2522 } break;
2523
2524 case 40: {
2525 T const c[] = {0.0775059479784248112, 0.0775059479784248112, 0.0770398181642479655, 0.0770398181642479655,
2526 0.0761103619006262423, 0.0761103619006262423, 0.0747231690579682642, 0.0747231690579682642,
2527 0.0728865823958040590, 0.0728865823958040590, 0.0706116473912867796, 0.0706116473912867796,
2528 0.0679120458152339038, 0.0679120458152339038, 0.0648040134566010380, 0.0648040134566010380,
2529 0.0613062424929289391, 0.0613062424929289391, 0.0574397690993915513, 0.0574397690993915513,
2530 0.0532278469839368243, 0.0532278469839368243, 0.0486958076350722320, 0.0486958076350722320,
2531 0.0438709081856732719, 0.0438709081856732719, 0.03878216797447201, 0.03878216797447201,
2532 0.0334601952825478473, 0.0334601952825478473, 0.0279370069800234010, 0.0279370069800234010,
2533 0.0222458491941669572, 0.0222458491941669572, 0.0164210583819078887, 0.0164210583819078887,
2534 0.0104982845311528136, 0.0104982845311528136, 0.004521277098533191, 0.004521277098533191};
2535 x = c[n];
2536 } break;
2537
2538 case 41: {
2539 T const c[] = {0.0756955356472983723, 0.0754787470927158240, 0.0754787470927158240, 0.0748296231762215518,
2540 0.0748296231762215518, 0.0737518820272234699, 0.0737518820272234699, 0.0722516968610230733,
2541 0.0722516968610230733, 0.0703376606208174974, 0.0703376606208174974, 0.0680207367608767667,
2542 0.0680207367608767667, 0.065314196453527410, 0.065314196453527410, 0.0622335425809663164,
2543 0.0622335425809663164, 0.0587964209498719449, 0.0587964209498719449, 0.0550225192425787418,
2544 0.0550225192425787418, 0.0509334542946174947, 0.0509334542946174947, 0.0465526483690143420,
2545 0.0465526483690143420, 0.0419051951959096894, 0.0419051951959096894, 0.0370177167035079884,
2546 0.0370177167035079884, 0.0319182117316992817, 0.0319182117316992817, 0.0266358992071104454,
2547 0.0266358992071104454, 0.0212010633687795530, 0.0212010633687795530, 0.0156449384078185885,
2548 0.0156449384078185885, 0.009999938773905945, 0.009999938773905945, 0.0043061403581648876,
2549 0.0043061403581648876};
2550 x = c[n];
2551 } break;
2552
2553 case 42: {
2554 T const c[] = {0.0738642342321728799, 0.0738642342321728799, 0.073460813453467528, 0.073460813453467528,
2555 0.0726561752438041048, 0.0726561752438041048, 0.0714547142651709829, 0.0714547142651709829,
2556 0.0698629924925941597, 0.0698629924925941597, 0.0678897033765219448, 0.0678897033765219448,
2557 0.0655456243649089789, 0.0655456243649089789, 0.0628435580450025764, 0.0628435580450025764,
2558 0.0597982622275866543, 0.0597982622275866543, 0.0564263693580183816, 0.0564263693580183816,
2559 0.0527462956991740703, 0.0527462956991740703, 0.0487781407928032450, 0.0487781407928032450,
2560 0.04454357777196587, 0.04454357777196587, 0.0400657351806922617, 0.0400657351806922617,
2561 0.03536907109759211, 0.03536907109759211, 0.0304792406996034683, 0.0304792406996034683,
2562 0.0254229595261130478, 0.0254229595261130478, 0.0202278695690526447, 0.0202278695690526447,
2563 0.01492244369735749, 0.01492244369735749, 0.0095362203017485024, 0.0095362203017485024,
2564 0.0041059986046490846, 0.0041059986046490846};
2565 x = c[n];
2566 } break;
2567
2568 case 43: {
2569 T const c[] = {0.0722157516937989879, 0.0720275019714219743, 0.0720275019714219743, 0.0714637342525141412,
2570 0.0714637342525141412, 0.0705273877650850281, 0.0705273877650850281, 0.0692233441936566842,
2571 0.0692233441936566842, 0.0675584022293651691, 0.0675584022293651691, 0.0655412421263227974,
2572 0.0655412421263227974, 0.0631823804493961123, 0.0631823804493961123, 0.0604941152499912945,
2573 0.0604941152499912945, 0.0574904619569105194, 0.0574904619569105194, 0.0541870803188817868,
2574 0.0541870803188817868, 0.0506011927843901565, 0.0506011927843901565, 0.0467514947543465800,
2575 0.0467514947543465800, 0.0426580571979820837, 0.0426580571979820837, 0.0383422221941326575,
2576 0.0383422221941326575, 0.0338264920868602923, 0.0338264920868602923, 0.029134413261498494,
2577 0.029134413261498494, 0.0242904566138388159, 0.0242904566138388159, 0.0193199014236839003,
2578 0.0193199014236839003, 0.0142487564315764861, 0.0142487564315764861, 0.0091039966374014033,
2579 0.0091039966374014033, 0.0039194902538441272, 0.0039194902538441272};
2580 x = c[n];
2581 } break;
2582
2583 case 44: {
2584 T const c[] = {0.0705491577893540688, 0.0705491577893540688, 0.0701976854735582125, 0.0701976854735582125,
2585 0.0694964918615725780, 0.0694964918615725780, 0.0684490702693666609, 0.0684490702693666609,
2586 0.0670606389062936523, 0.0670606389062936523, 0.0653381148791814349, 0.0653381148791814349,
2587 0.0632900797332038549, 0.0632900797332038549, 0.0609267367015619680, 0.0609267367015619680,
2588 0.0582598598775954953, 0.0582598598775954953, 0.0553027355637280525, 0.0553027355637280525,
2589 0.0520700960917044618, 0.0520700960917044618, 0.0485780464483520375, 0.0485780464483520375,
2590 0.0448439840819700314, 0.0448439840819700314, 0.0408865123103462189, 0.0408865123103462189,
2591 0.0367253478138088736, 0.0367253478138088736, 0.0323812228120698208, 0.0323812228120698208,
2592 0.0278757828212810100, 0.0278757828212810100, 0.0232314819020192106, 0.0232314819020192106,
2593 0.0184714817368147491, 0.0184714817368147491, 0.0136195867555799855, 0.0136195867555799855,
2594 0.008700481367524844, 0.008700481367524844, 0.0037454048031127775, 0.0037454048031127775};
2595 x = c[n];
2596 } break;
2597
2598 case 45: {
2599 T const c[] = {0.0690418248292320201, 0.0688773169776613228, 0.0688773169776613228, 0.0683845773786696745,
2600 0.0683845773786696745, 0.067565954163607536, 0.067565954163607536, 0.0664253484498425280,
2601 0.0664253484498425280, 0.0649681957507234308, 0.0649681957507234308, 0.0632014400738199377,
2602 0.0632014400738199377, 0.0611335008310665225, 0.0611335008310665225, 0.0587742327188417385,
2603 0.0587742327188417385, 0.056134878759786476, 0.056134878759786476, 0.0532280167312689519,
2604 0.0532280167312689519, 0.0500674992379520297, 0.0500674992379520297, 0.0466683877183733652,
2605 0.0466683877183733652, 0.043046880709164971, 0.043046880709164971, 0.0392202367293024475,
2606 0.0392202367293024475, 0.0352066922016090162, 0.0352066922016090162, 0.0310253749345154671,
2607 0.0310253749345154671, 0.0266962139675776648, 0.0266962139675776648, 0.0222398475505787323,
2608 0.0222398475505787323, 0.0176775352579375906, 0.0176775352579375906, 0.0130311049915827843,
2609 0.0130311049915827843, 0.0083231892962182416, 0.0083231892962182416, 0.003582663155283558,
2610 0.003582663155283558};
2611 x = c[n];
2612 } break;
2613
2614 case 46: {
2615 T const c[] = {0.0675186858490364588, 0.0675186858490364588, 0.0672106136006781758, 0.0672106136006781758,
2616 0.0665958747684548873, 0.0665958747684548873, 0.0656772742677812073, 0.0656772742677812073,
2617 0.0644590034671390695, 0.0644590034671390695, 0.0629466210643945081, 0.0629466210643945081,
2618 0.0611470277246504810, 0.0611470277246504810, 0.0590684345955463148, 0.0590684345955463148,
2619 0.0567203258439912358, 0.0567203258439912358, 0.054113415385856754, 0.054113415385856754,
2620 0.0512595980071430213, 0.0512595980071430213, 0.048171895101712200, 0.048171895101712200,
2621 0.044864395277318126, 0.044864395277318126, 0.0413521901096787297, 0.0413521901096787297,
2622 0.0376513053573860713, 0.0376513053573860713, 0.033778627999106896, 0.033778627999106896,
2623 0.0297518295522027557, 0.0297518295522027557, 0.0255892863971300106, 0.0255892863971300106,
2624 0.0213099987541365010, 0.0213099987541365010, 0.0169335140078362380, 0.0169335140078362380,
2625 0.0124798837709886842, 0.0124798837709886842, 0.0079698982297246224, 0.0079698982297246224,
2626 0.0034303008681070482, 0.0034303008681070482};
2627 x = c[n];
2628 } break;
2629
2630 case 47: {
2631 T const c[] = {0.0661351296236554796, 0.0659905335888104745, 0.0659905335888104745, 0.0655573777665497402,
2632 0.0655573777665497402, 0.0648375562389457267, 0.0648375562389457267, 0.0638342166057170306,
2633 0.0638342166057170306, 0.0625517462209216626, 0.0625517462209216626, 0.0609957530087396453,
2634 0.0609957530087396453, 0.0591730409423388759, 0.0591730409423388759, 0.0570915802932315402,
2635 0.0570915802932315402, 0.0547604727815302259, 0.0547604727815302259, 0.0521899117800571448,
2636 0.0521899117800571448, 0.0493911377473611696, 0.0493911377473611696, 0.0463763890865059112,
2637 0.0463763890865059112, 0.0431588486484795382, 0.0431588486484795382, 0.0397525861225310037,
2638 0.0397525861225310037, 0.0361724965841749516, 0.0361724965841749516, 0.0324342355151847567,
2639 0.0324342355151847567, 0.0285541507006433865, 0.0285541507006433865, 0.0245492116596588185,
2640 0.0245492116596588185, 0.0204369381476684276, 0.0204369381476684276, 0.0162353331464330596,
2641 0.0162353331464330596, 0.0119628484643123209, 0.0119628484643123209, 0.0076386162958488336,
2642 0.0076386162958488336, 0.0032874538425280148, 0.0032874538425280148};
2643 x = c[n];
2644 } break;
2645
2646 case 48: {
2647 T const c[] = {0.0647376968126839225, 0.0647376968126839225, 0.0644661644359500822, 0.0644661644359500822,
2648 0.0639242385846481866, 0.0639242385846481866, 0.063114192286254025, 0.063114192286254025,
2649 0.0620394231598926639, 0.0620394231598926639, 0.060704439165893880, 0.060704439165893880,
2650 0.0591148396983956357, 0.0591148396983956357, 0.0572772921004032157, 0.0572772921004032157,
2651 0.0551995036999841628, 0.0551995036999841628, 0.0528901894851936670, 0.0528901894851936670,
2652 0.0503590355538544749, 0.0503590355538544749, 0.0476166584924904748, 0.0476166584924904748,
2653 0.04467456085669428, 0.04467456085669428, 0.0415450829434647492, 0.0415450829434647492,
2654 0.0382413510658307063, 0.0382413510658307063, 0.0347772225647704388, 0.0347772225647704388,
2655 0.0311672278327980889, 0.0311672278327980889, 0.0274265097083569482, 0.0274265097083569482,
2656 0.0235707608393243791, 0.0235707608393243791, 0.0196161604573555278, 0.0196161604573555278,
2657 0.0155793157229438487, 0.0155793157229438487, 0.0114772345792345394, 0.0114772345792345394,
2658 0.0073275539012762621, 0.0073275539012762621, 0.0031533460523058386, 0.0031533460523058386};
2659 x = c[n];
2660 } break;
2661
2662 case 49: {
2663 T const c[] = {0.0634632814047905977, 0.0633355092964917485, 0.0633355092964917485, 0.0629527074651956994,
2664 0.0629527074651956994, 0.0623164173200572674, 0.0623164173200572674, 0.0614292009791929362,
2665 0.0614292009791929362, 0.0602946309531520173, 0.0602946309531520173, 0.058917275760027266,
2666 0.058917275760027266, 0.0573026815301874754, 0.0573026815301874754, 0.0554573496748035886,
2667 0.0554573496748035886, 0.0533887107082589685, 0.0533887107082589685, 0.0511050943301445906,
2668 0.0511050943301445906, 0.0486156958878282402, 0.0486156958878282402, 0.0459305393555958535,
2669 0.0459305393555958535, 0.0430604369812595979, 0.0430604369812595979, 0.0400169457663730213,
2670 0.0400169457663730213, 0.0368123209630006898, 0.0368123209630006898, 0.0334594667916221743,
2671 0.0334594667916221743, 0.0299718846205838253, 0.0299718846205838253, 0.0263636189270660169,
2672 0.0263636189270660169, 0.0226492015874466764, 0.0226492015874466764, 0.0188435958530894584,
2673 0.0188435958530894584, 0.014962144935624651, 0.014962144935624651, 0.0110205510315935804,
2674 0.0110205510315935804, 0.0070350995900864514, 0.0070350995900864514, 0.0030272789889229050,
2675 0.0030272789889229050};
2676 x = c[n];
2677 } break;
2678
2679 case 50: {
2680 T const c[] = {0.0621766166553472623, 0.0621766166553472623, 0.0619360674206832433, 0.0619360674206832433,
2681 0.0614558995903166637, 0.0614558995903166637, 0.0607379708417702160, 0.0607379708417702160,
2682 0.0597850587042654575, 0.0597850587042654575, 0.0586008498132224458, 0.0586008498132224458,
2683 0.0571899256477283837, 0.0571899256477283837, 0.0555577448062125176, 0.0555577448062125176,
2684 0.0537106218889962465, 0.0537106218889962465, 0.051655703069581138, 0.051655703069581138,
2685 0.0494009384494663149, 0.0494009384494663149, 0.04695505130394843, 0.04695505130394843,
2686 0.0443275043388032754, 0.0443275043388032754, 0.0415284630901476974, 0.0415284630901476974,
2687 0.038568756612587675, 0.038568756612587675, 0.0354598356151461541, 0.0354598356151461541,
2688 0.0322137282235780166, 0.0322137282235780166, 0.0288429935805351980, 0.0288429935805351980,
2689 0.0253606735700123904, 0.0253606735700123904, 0.021780243170124792, 0.021780243170124792,
2690 0.0181155607134893903, 0.0181155607134893903, 0.0143808227614855744, 0.0143808227614855744,
2691 0.0105905483836509692, 0.0105905483836509692, 0.0067597991957454015, 0.0067597991957454015,
2692 0.0029086225531551409, 0.0029086225531551409};
2693 x = c[n];
2694 } break;
2695
2696 case 51: {
2697 T const c[] = {0.0609989248412058801, 0.0608854648448563438, 0.0608854648448563438, 0.0605455069347377951,
2698 0.0605455069347377951, 0.0599803157775032520, 0.0599803157775032520, 0.0591919939229615437,
2699 0.0591919939229615437, 0.0581834739825921405, 0.0581834739825921405, 0.0569585077202586621,
2700 0.0569585077202586621, 0.0555216520957386930, 0.0555216520957386930, 0.0538782523130455614,
2701 0.0538782523130455614, 0.0520344219366970875, 0.0520344219366970875, 0.0499970201500574097,
2702 0.0499970201500574097, 0.0477736262406231019, 0.0477736262406231019, 0.0453725114076500687,
2703 0.0453725114076500687, 0.0428026079978800866, 0.0428026079978800866, 0.0400734762854964531,
2704 0.0400734762854964531, 0.0371952689232602928, 0.0371952689232602928, 0.0341786932041883362,
2705 0.0341786932041883362, 0.0310349712901600084, 0.0310349712901600084, 0.0277757985941624771,
2706 0.0277757985941624771, 0.0244133005737814342, 0.0244133005737814342, 0.0209599884017032105,
2707 0.0209599884017032105, 0.0174287147234010522, 0.0174287147234010522, 0.0138326340064778222,
2708 0.0138326340064778222, 0.0101851912978217299, 0.0101851912978217299, 0.0065003377832526002,
2709 0.0065003377832526002, 0.0027968071710898955, 0.0027968071710898955};
2710 x = c[n];
2711 } break;
2712
2713 case 52: {
2714 T const c[] = {0.0598103657452918602, 0.0598103657452918602, 0.0595962601712481582, 0.0595962601712481582,
2715 0.0591688154660429703, 0.0591688154660429703, 0.0585295617718138685, 0.0585295617718138685,
2716 0.0576807874525268276, 0.0576807874525268276, 0.0566255309023685971, 0.0566255309023685971,
2717 0.0553675696693026525, 0.0553675696693026525, 0.0539114069327572647, 0.0539114069327572647,
2718 0.0522622553839069930, 0.0522622553839069930, 0.0504260185663423772, 0.0504260185663423772,
2719 0.0484092697440748968, 0.0484092697440748968, 0.046219228372784793, 0.046219228372784793,
2720 0.0438637342590004079, 0.0438637342590004079, 0.0413512195005602716, 0.0413512195005602716,
2721 0.0386906783104239789, 0.0386906783104239789, 0.0358916348350972329, 0.0358916348350972329,
2722 0.0329641090897187979, 0.0329641090897187979, 0.0299185811471439466, 0.0299185811471439466,
2723 0.0267659537465040134, 0.0267659537465040134, 0.0235175135539844615, 0.0235175135539844615,
2724 0.0201848915079807922, 0.0201848915079807922, 0.0167800233963007356, 0.0167800233963007356,
2725 0.0133151149823409606, 0.0133151149823409606, 0.0098026345794627520, 0.0098026345794627520,
2726 0.0062555239629732768, 0.0062555239629732768, 0.0026913169500471111, 0.0026913169500471111};
2727 x = c[n];
2728 } break;
2729
2730 case 53: {
2731 T const c[] = {0.0587187941511643645, 0.0586175862327202633, 0.0586175862327202633, 0.0583143113622560075,
2732 0.0583143113622560075, 0.0578100149917131963, 0.0578100149917131963, 0.0571064355362671917,
2733 0.0571064355362671917, 0.0562059983817397098, 0.0562059983817397098, 0.0551118075239335990,
2734 0.0551118075239335990, 0.0538276348687310290, 0.0538276348687310290, 0.052357907229872718,
2735 0.052357907229872718, 0.0507076910692927152, 0.0507076910692927152, 0.0488826750326991404,
2736 0.0488826750326991404, 0.0468891503407503140, 0.0468891503407503140, 0.0447339891036728102,
2737 0.0447339891036728102, 0.0424246206345200135, 0.0424246206345200135, 0.0399690058435403821,
2738 0.0399690058435403821, 0.0373756098034829156, 0.0373756098034829156, 0.0346533725835342379,
2739 0.0346533725835342379, 0.0318116784590193230, 0.0318116784590193230, 0.0288603236178237362,
2740 0.0288603236178237362, 0.0258094825107575177, 0.0258094825107575177, 0.0226696730570702083,
2741 0.0226696730570702083, 0.0194517211076368953, 0.0194517211076368953, 0.016166725256687463,
2742 0.016166725256687463, 0.0128260261442403791, 0.0128260261442403791, 0.0094412022849403443,
2743 0.0094412022849403443, 0.0060242762269486732, 0.0060242762269486732, 0.0025916837205670318,
2744 0.0025916837205670318};
2745 x = c[n];
2746 } break;
2747
2748 case 54: {
2749 T const c[] = {0.0576175367071470246, 0.0576175367071470246, 0.0574261370541121148, 0.0574261370541121148,
2750 0.0570439735587945985, 0.0570439735587945985, 0.0564723157306259650, 0.0564723157306259650,
2751 0.0557130625605899876, 0.0557130625605899876, 0.0547687362130579863, 0.0547687362130579863,
2752 0.0536424736475536112, 0.0536424736475536112, 0.0523380161982987446, 0.0523380161982987446,
2753 0.0508596971461881443, 0.0508596971461881443, 0.0492124273245288860, 0.0492124273245288860,
2754 0.0474016788064449910, 0.0474016788064449910, 0.0454334667282767139, 0.0454334667282767139,
2755 0.0433143293095970154, 0.0433143293095970154, 0.0410513061366449742, 0.0410513061366449742,
2756 0.0386519147821025168, 0.0386519147821025168, 0.0361241258403835525, 0.0361241258403835525,
2757 0.0334763364643726457, 0.0334763364643726457, 0.030717342497870676, 0.030717342497870676,
2758 0.0278563093105958702, 0.0278563093105958702, 0.0249027414672087730, 0.0249027414672087730,
2759 0.0218664514228530859, 0.0218664514228530859, 0.0187575276214693779, 0.0187575276214693779,
2760 0.015586303035924131, 0.015586303035924131, 0.0123633281288476441, 0.0123633281288476441,
2761 0.0090993694555093969, 0.0090993694555093969, 0.0058056110152399848, 0.0058056110152399848,
2762 0.0024974818357615857, 0.0024974818357615857};
2763 x = c[n];
2764 } break;
2765
2766 case 55: {
2767 T const c[] = {0.0566029764445604254, 0.056512318249772001, 0.056512318249772001, 0.0562406340710843680,
2768 0.0562406340710843680, 0.0557887941952840871, 0.0557887941952840871, 0.055158246002508687,
2769 0.055158246002508687, 0.054351009329911102, 0.054351009329911102, 0.0533696700016054727,
2770 0.0533696700016054727, 0.052217371545632084, 0.052217371545632084, 0.0508978051244939792,
2771 0.0508978051244939792, 0.049415197711551739, 0.049415197711551739, 0.0477742985512006955,
2772 0.0477742985512006955, 0.0459803639462838381, 0.0459803639462838381, 0.0440391404216065898,
2773 0.0440391404216065898, 0.041956846317718762, 0.041956846317718762, 0.0397401518743371796,
2774 0.0397401518743371796, 0.0373961578679655452, 0.0373961578679655452, 0.0349323728735898874,
2775 0.0349323728735898874, 0.0323566892261858316, 0.0323566892261858316, 0.0296773577651610412,
2776 0.0296773577651610412, 0.0269029614563962706, 0.0269029614563962706, 0.0240423880097256220,
2777 0.0240423880097256220, 0.0211048016680164541, 0.0211048016680164541, 0.0180996145207290624,
2778 0.0180996145207290624, 0.0150364583335117882, 0.0150364583335117882, 0.0119251607198486121,
2779 0.0119251607198486121, 0.0087757461070585281, 0.0087757461070585281, 0.0055986322665607673,
2780 0.0055986322665607673, 0.0024083236199797888, 0.0024083236199797888};
2781 x = c[n];
2782 } break;
2783
2784 case 56: {
2785 T const c[] = {0.0555797463065143958, 0.0555797463065143958, 0.0554079525032451232, 0.0554079525032451232,
2786 0.0550648959017624257, 0.0550648959017624257, 0.0545516368708894210, 0.0545516368708894210,
2787 0.0538697618657144857, 0.0538697618657144857, 0.0530213785240107639, 0.0530213785240107639,
2788 0.0520091091517413998, 0.0520091091517413998, 0.0508360826177984805, 0.0508360826177984805,
2789 0.0495059246830475789, 0.0495059246830475789, 0.0480227467936002581, 0.0480227467936002581,
2790 0.0463911333730018967, 0.0463911333730018967, 0.0446161276526922832, 0.0446161276526922832,
2791 0.0427032160846670865, 0.0427032160846670865, 0.0406583113847445178, 0.0406583113847445178,
2792 0.0384877342592476624, 0.0384877342592476624, 0.0361981938723151860, 0.0361981938723151860,
2793 0.0337967671156117612, 0.0337967671156117612, 0.0312908767473104478, 0.0312908767473104478,
2794 0.0286882684738227417, 0.0286882684738227417, 0.0259969870583919521, 0.0259969870583919521,
2795 0.023225351562565316, 0.023225351562565316, 0.0203819298824025726, 0.0203819298824025726,
2796 0.0174755129114009465, 0.0174755129114009465, 0.0145150892780214718, 0.0145150892780214718,
2797 0.0115098243403833821, 0.0115098243403833821, 0.0084690631633078876, 0.0084690631633078876,
2798 0.005402522246015337, 0.005402522246015337, 0.0023238553757732155, 0.0023238553757732155};
2799 x = c[n];
2800 } break;
2801
2802 case 57: {
2803 T const c[] = {0.0546343287565840240, 0.0545528036047618864, 0.0545528036047618864, 0.0543084714524986431,
2804 0.0543084714524986431, 0.0539020614832985746, 0.0539020614832985746, 0.0533347865848191584,
2805 0.0533347865848191584, 0.052608339729177432, 0.052608339729177432, 0.0517248889205178247,
2806 0.0517248889205178247, 0.0506870707249274086, 0.0506870707249274086, 0.0494979824020196789,
2807 0.0494979824020196789, 0.0481611726616877512, 0.0481611726616877512, 0.0466806310736415037,
2808 0.0466806310736415037, 0.0450607761613811577, 0.0450607761613811577, 0.043306442216215196,
2809 0.043306442216215196, 0.0414228648708011103, 0.0414228648708011103, 0.0394156654754801140,
2810 0.0394156654754801140, 0.0372908343244173173, 0.0372908343244173173, 0.0350547127823126175,
2811 0.0350547127823126175, 0.032713974366371568, 0.032713974366371568, 0.0302756048426939994,
2812 0.0302756048426939994, 0.0277468814021801923, 0.0277468814021801923, 0.0251353509909181226,
2813 0.0251353509909181226, 0.0224488078907764380, 0.0224488078907764380, 0.0196952706994885203,
2814 0.0196952706994885203, 0.0168829590234415490, 0.0168829590234415490, 0.0140202707907535561,
2815 0.0140202707907535561, 0.0111157637323359901, 0.0111157637323359901, 0.0081781600678212326,
2816 0.0081781600678212326, 0.0052165334747187793, 0.0052165334747187793, 0.0022437538722506629,
2817 0.0022437538722506629};
2818 x = c[n];
2819 } break;
2820
2821 case 58: {
2822 T const c[] = {0.0536811198633348488, 0.0536811198633348488, 0.0535263433040582521, 0.0535263433040582521,
2823 0.0532172364465790141, 0.0532172364465790141, 0.0527546905263708334, 0.0527546905263708334,
2824 0.052140039183669818, 0.052140039183669818, 0.0513750546182857254, 0.0513750546182857254,
2825 0.050461942479953125, 0.050461942479953125, 0.049403335508962392, 0.049403335508962392,
2826 0.0482022859454177484, 0.0482022859454177484, 0.0468622567290263469, 0.0468622567290263469,
2827 0.0453871115148198025, 0.0453871115148198025, 0.0437811035336402510, 0.0437811035336402510,
2828 0.0420488633295821259, 0.0420488633295821259, 0.0401953854098677968, 0.0401953854098677968,
2829 0.0382260138458584332, 0.0382260138458584332, 0.0361464268670872705, 0.0361464268670872705,
2830 0.0339626204934160107, 0.0339626204934160107, 0.0316808912538093273, 0.0316808912538093273,
2831 0.0293078180441604907, 0.0293078180441604907, 0.0268502431819818684, 0.0268502431819818684,
2832 0.0243152527249639525, 0.0243152527249639525, 0.0217101561401462357, 0.0217101561401462357,
2833 0.0190424654618934086, 0.0190424654618934086, 0.0163198742349709650, 0.0163198742349709650,
2834 0.0135502371129888121, 0.0135502371129888121, 0.0107415535328787741, 0.0107415535328787741,
2835 0.007901973849998674, 0.007901973849998674, 0.0050399816126502430, 0.0050399816126502430,
2836 0.0021677232496274499, 0.0021677232496274499};
2837 x = c[n];
2838 } break;
2839
2840 case 59: {
2841 T const c[] = {0.0527980126219904214, 0.0527244338591279319, 0.0527244338591279319, 0.0525039026478287390,
2842 0.0525039026478287390, 0.0521370336483753913, 0.0521370336483753913, 0.0516248493908914821,
2843 0.0516248493908914821, 0.0509687774253939168, 0.0509687774253939168, 0.0501706463429969028,
2844 0.0501706463429969028, 0.0492326806793619857, 0.0492326806793619857, 0.0481574947146064403,
2845 0.0481574947146064403, 0.0469480851869620191, 0.0469480851869620191, 0.045607822940509769,
2846 0.045607822940509769, 0.0441404435302973806, 0.0441404435302973806, 0.0425500368110676386,
2847 0.0425500368110676386, 0.0408410355386867076, 0.0408410355386867076, 0.039018203016160009,
2848 0.039018203016160009, 0.03708661981887092, 0.03708661981887092, 0.0350516696364001087,
2849 0.0350516696364001087, 0.0329190242710452777, 0.0329190242710452777, 0.030694627836111683,
2850 0.030694627836111683, 0.0283846802005347979, 0.0283846802005347979, 0.0259956197312985001,
2851 0.0259956197312985001, 0.023534105393713363, 0.023534105393713363, 0.0210069982884371873,
2852 0.0210069982884371873, 0.0184213427536100293, 0.0184213427536100293, 0.0157843473130814661,
2853 0.0157843473130814661, 0.0131033663063451910, 0.0131033663063451910, 0.0103858855009958621,
2854 0.0103858855009958621, 0.0076395294534875751, 0.0076395294534875751, 0.004872239168265284,
2855 0.004872239168265284, 0.0020954922845412234, 0.0020954922845412234};
2856 x = c[n];
2857 } break;
2858
2859 case 60: {
2860 T const c[] = {0.05190787763122063, 0.05190787763122063, 0.0517679431749101875, 0.0517679431749101875,
2861 0.051488451500980933, 0.051488451500980933, 0.0510701560698556274, 0.0510701560698556274,
2862 0.0505141845325093745, 0.0505141845325093745, 0.0498220356905501810, 0.0498220356905501810,
2863 0.0489955754557568353, 0.0489955754557568353, 0.0480370318199711809, 0.0480370318199711809,
2864 0.046948988848912204, 0.046948988848912204, 0.0457343797161144866, 0.0457343797161144866,
2865 0.0443964787957871133, 0.0443964787957871133, 0.0429388928359356419, 0.0429388928359356419,
2866 0.0413655512355847556, 0.0413655512355847556, 0.0396806954523807994, 0.0396806954523807994,
2867 0.0378888675692434440, 0.0378888675692434440, 0.0359948980510845030, 0.0359948980510845030,
2868 0.0340038927249464228, 0.0340038927249464228, 0.0319212190192963289, 0.0319212190192963289,
2869 0.0297524915007889452, 0.0297524915007889452, 0.0275035567499247916, 0.0275035567499247916,
2870 0.025180477621521248, 0.025180477621521248, 0.0227895169439978198, 0.0227895169439978198,
2871 0.0203371207294572867, 0.0203371207294572867, 0.0178299010142077202, 0.0178299010142077202,
2872 0.0152746185967847993, 0.0152746185967847993, 0.0126781664768159601, 0.0126781664768159601,
2873 0.0100475571822879843, 0.0100475571822879843, 0.0073899311633454555, 0.0073899311633454555,
2874 0.0047127299269535686, 0.0047127299269535686, 0.0020268119688737584, 0.0020268119688737584};
2875 x = c[n];
2876 } break;
2877
2878 case 61: {
2879 T const c[] = {0.0510811194407862179, 0.0510144870386972635, 0.0510144870386972635, 0.0508147636688183432,
2880 0.0508147636688183432, 0.0504824703867974046, 0.0504824703867974046, 0.0500184741081782534,
2881 0.0500184741081782534, 0.0494239853467355899, 0.0494239853467355899, 0.0487005550564115260,
2882 0.0487005550564115260, 0.0478500705850956071, 0.0478500705850956071, 0.0468747507508090659,
2883 0.0468747507508090659, 0.0457771400531459593, 0.0457771400531459593, 0.0445601020350834882,
2884 0.0445601020350834882, 0.0432268118124960979, 0.0432268118124960979, 0.0417807477908884920,
2885 0.0417807477908884920, 0.0402256825909982473, 0.0402256825909982473, 0.0385656732070081727,
2886 0.0385656732070081727, 0.0368050504231548173, 0.0368050504231548173, 0.0349484075165333510,
2887 0.0349484075165333510, 0.0330005882759074106, 0.0330005882759074106, 0.0309666743683973948,
2888 0.0309666743683973948, 0.0288519720881834015, 0.0288519720881834015, 0.026661998524150889,
2889 0.026661998524150889, 0.0244024671875442029, 0.0244024671875442029, 0.0220792731483190440,
2890 0.0220792731483190440, 0.019698477746101181, 0.019698477746101181, 0.0172662929876137435,
2891 0.0172662929876137435, 0.0147890658849379145, 0.0147890658849379145, 0.0122732635078121046,
2892 0.0122732635078121046, 0.0097254618303561337, 0.0097254618303561337, 0.0071523549917490895,
2893 0.0071523549917490895, 0.0045609240060124171, 0.0045609240060124171, 0.0019614533616702826,
2894 0.0019614533616702826};
2895 x = c[n];
2896 } break;
2897
2898 case 62: {
2899 T const c[] = {0.0502480003752562816, 0.0502480003752562816, 0.0501210695690432880, 0.0501210695690432880,
2900 0.0498675285949523942, 0.0498675285949523942, 0.0494880179196992925, 0.0494880179196992925,
2901 0.0489834962205178371, 0.0489834962205178371, 0.0483552379634776728, 0.0483552379634776728,
2902 0.0476048301841012322, 0.0476048301841012322, 0.0467341684784155248, 0.0467341684784155248,
2903 0.0457454522145701807, 0.0457454522145701807, 0.0446411789771244142, 0.0446411789771244142,
2904 0.0434241382580474195, 0.0434241382580474195, 0.0420974044103850966, 0.0420974044103850966,
2905 0.0406643288824174409, 0.0406643288824174409, 0.0391285317519630841, 0.0391285317519630841,
2906 0.0374938925822800299, 0.0374938925822800299, 0.0357645406227681412, 0.0357645406227681412,
2907 0.0339448443794105450, 0.0339448443794105450, 0.0320394005816246781, 0.0320394005816246781,
2908 0.0300530225739898700, 0.0300530225739898700, 0.0279907281633146375, 0.0279907281633146375,
2909 0.025857726954024698, 0.025857726954024698, 0.0236594072086827925, 0.0236594072086827925,
2910 0.021401322277669968, 0.021401322277669968, 0.0190891766585731987, 0.0190891766585731987,
2911 0.0167288117901773162, 0.0167288117901773162, 0.0143261918238065177, 0.0143261918238065177,
2912 0.0118873901170105019, 0.0118873901170105019, 0.0094185794284203876, 0.0094185794284203876,
2913 0.0069260419018309608, 0.0069260419018309608, 0.0044163334569309048, 0.0044163334569309048,
2914 0.0018992056795136904, 0.0018992056795136904};
2915 x = c[n];
2916 } break;
2917
2918 case 63: {
2919 T const c[] = {0.0494723666239310208, 0.0494118330399181789, 0.0494118330399181789, 0.0492303804237475607,
2920 0.0492303804237475607, 0.0489284528205119899, 0.0489284528205119899, 0.0485067890978838478,
2921 0.0485067890978838478, 0.0479664211379951314, 0.0479664211379951314, 0.0473086713122689190,
2922 0.0473086713122689190, 0.0465351492453836965, 0.0465351492453836965, 0.0456477478762926086,
2923 0.0456477478762926086, 0.0446486388259413953, 0.0446486388259413953, 0.0435402670830275907,
2924 0.0435402670830275907, 0.042325345020815822, 0.042325345020815822, 0.0410068457596663986,
2925 0.0410068457596663986, 0.0395879958915440939, 0.0395879958915440939, 0.0380722675843495567,
2926 0.0380722675843495567, 0.0364633700854572896, 0.0364633700854572896, 0.0347652406453558776,
2927 0.0347652406453558776, 0.0329820348837793417, 0.0329820348837793417, 0.0311181166222198175,
2928 0.0311181166222198175, 0.029178047208280526, 0.029178047208280526, 0.0271665743590979332,
2929 0.0271665743590979332, 0.0250886205533449866, 0.0250886205533449866, 0.0229492710048899331,
2930 0.0229492710048899331, 0.0207537612580390907, 0.0207537612580390907, 0.018507464460161270,
2931 0.018507464460161270, 0.016215878410338338, 0.016215878410338338, 0.0138846126161156108,
2932 0.0138846126161156108, 0.011519376076880041, 0.011519376076880041, 0.0091259686763266563,
2933 0.0091259686763266563, 0.0067102917659601362, 0.0067102917659601362, 0.0042785083468637618,
2934 0.0042785083468637618, 0.001839874595577084, 0.001839874595577084};
2935 x = c[n];
2936 } break;
2937
2938 case 64: {
2939 T const c[] = {0.0486909570091397203, 0.0486909570091397203, 0.0485754674415034269, 0.0485754674415034269,
2940 0.048344762234802957, 0.048344762234802957, 0.0479993885964583077, 0.0479993885964583077,
2941 0.0475401657148303086, 0.0475401657148303086, 0.0469681828162100173, 0.0469681828162100173,
2942 0.0462847965813144172, 0.0462847965813144172, 0.0454916279274181444, 0.0454916279274181444,
2943 0.0445905581637565630, 0.0445905581637565630, 0.0435837245293234533, 0.0435837245293234533,
2944 0.0424735151236535890, 0.0424735151236535890, 0.0412625632426235286, 0.0412625632426235286,
2945 0.0399537411327203413, 0.0399537411327203413, 0.0385501531786156291, 0.0385501531786156291,
2946 0.0370551285402400460, 0.0370551285402400460, 0.0354722132568823838, 0.0354722132568823838,
2947 0.0338051618371416093, 0.0338051618371416093, 0.032057928354851553, 0.032057928354851553,
2948 0.030234657072402478, 0.030234657072402478, 0.0283396726142594832, 0.0283396726142594832,
2949 0.0263774697150546586, 0.0263774697150546586, 0.0243527025687108733, 0.0243527025687108733,
2950 0.0222701738083832541, 0.0222701738083832541, 0.0201348231535302093, 0.0201348231535302093,
2951 0.0179517157756973430, 0.0179517157756973430, 0.0157260304760247193, 0.0157260304760247193,
2952 0.0134630478967186425, 0.0134630478967186425, 0.011168139460131128, 0.011168139460131128,
2953 0.0088467598263639477, 0.0088467598263639477, 0.0065044579689783628, 0.0065044579689783628,
2954 0.0041470332605624676, 0.0041470332605624676, 0.0017832807216964329, 0.0017832807216964329};
2955 x = c[n];
2956 } break;
2957 }
2958 return x;
2959}
2960
2961} // namespace impl
2962
2963//
2964// Compute a non-negative integer power of a tensor by binary manipulation.
2965//
2966template<typename T, Index N>
2968Tensor<T, N>
2969binary_powering(Tensor<T, N> const & A, Index const exponent)
2970{
2971 if (exponent == 0) return eye<T, N>(A.get_dimension());
2972
2973 Index const
2974 rightmost_bit = 1;
2975
2976 Index const
2977 number_digits = INDEX_SIZE;
2978
2979 Index const
2980 leftmost_bit = rightmost_bit << (number_digits - 1);
2981
2982 Index
2983 t = 0;
2984
2985 for (Index j = 0; j < number_digits; ++j) {
2986
2987 if (((exponent << j) & leftmost_bit) != 0) {
2988
2989 t = number_digits - j - 1;
2990 break;
2991
2992 }
2993
2994 }
2995
2997 P = A;
2998
2999 Index
3000 i = 0;
3001
3002 Index
3003 m = exponent;
3004
3005 while ((m & rightmost_bit) == 0) {
3006 P = P * P;
3007 ++i;
3008 m = m >> 1;
3009 }
3010
3012 X = P;
3013
3014 for (Index j = i + 1; j <= t; ++j) {
3015 P = P * P;
3016
3017 if (((exponent >> j) & rightmost_bit) != 0) {
3018 X = X * P;
3019 }
3020 }
3021
3022 return X;
3023}
3024
3025//
3026// Exponential map by squaring and scaling and Padé approximants.
3027// See algorithm 10.20 in Functions of Matrices, N.J. Higham, SIAM, 2008.
3028// \param A tensor
3029// \return \f$ \exp A \f$
3030//
3031// Padé truncation-order thresholds of Al-Mohy and Higham, A New Scaling
3032// and Squaring Algorithm for the Matrix Exponential, SIAM J. Matrix Anal.
3033// Appl. 31(3), 2009, Table 3.1. The value for order 13 is their revised
3034// choice that also accounts for rounding in the squaring phase.
3038template<typename T>
3040T
3042{
3043 switch (order) {
3044 default: MT_ERROR_EXIT("Unsupported Pade order for expm."); break;
3045 case 3: return 1.495585217958292e-02;
3046 case 5: return 2.539398330063230e-01;
3047 case 7: return 9.504178996162932e-01;
3048 case 9: return 2.097847961257068e+00;
3049 case 13: return 4.25;
3050 }
3051 return 0.0;
3052}
3053
3054// Rounding-error correction term of Al-Mohy and Higham (2009), Eq. (5.1):
3055// number of extra squarings needed so that the truncation bound remains
3056// valid when the Padé numerator is evaluated in floating point. Zero for
3057// all but the most nonnormal arguments.
3061template<Index N>
3062Index
3063expm_ell(Tensor<Real, N> const & A, Index const m)
3064{
3065 Index const
3066 dimension = A.get_dimension();
3067
3068 Real const
3069 norm_A = norm_1(A);
3070
3071 if (norm_A == 0.0) return 0;
3072
3073 // 1 / |c_{2m+1}| = binomial(2m, m) * (2m+1)! (few-digit accuracy is
3074 // all the base-2 logarithm below requires)
3075 Real
3076 factorial = 1.0;
3077
3078 for (Index i = 2; i <= 2 * m + 1; ++i) {
3079 factorial *= static_cast<Real>(i);
3080 }
3081
3082 Real
3083 binomial = 1.0;
3084
3085 for (Index i = 1; i <= m; ++i) {
3086 binomial = binomial * static_cast<Real>(m + i) / static_cast<Real>(i);
3087 }
3088
3089 Real const
3090 c_recip = binomial * factorial;
3091
3092 Real const
3093 u_half = 0.5 * machine_epsilon<Real>();
3094
3095 // conservative bound alpha <= norm(A)^(2m) / c_recip: when it is
3096 // already below the unit roundoff (in particular whenever norm(A) is
3097 // within the 2005 norm-based threshold) no correction is needed and
3098 // the matrix powers below are skipped
3099 if (std::pow(norm_A, 2.0 * static_cast<Real>(m)) / c_recip <= u_half) {
3100 return 0;
3101 }
3102
3103 // norm of |A|^(2m+1), elementwise absolute value, by binary powering
3105 P(dimension);
3106
3107 for (Index i = 0; i < dimension; ++i) {
3108 for (Index j = 0; j < dimension; ++j) {
3109 P(i, j) = std::abs(A(i, j));
3110 }
3111 }
3112
3113 Tensor<Real, N> const
3114 Q = binary_powering(P, 2 * m + 1);
3115
3116 Real const
3117 alpha = norm_1(Q) / (norm_A * c_recip);
3118
3119 if (alpha == 0.0) return 0;
3120
3121 int const
3122 extra = static_cast<int>(
3123 std::ceil(std::log2(alpha / u_half) / (2.0 * static_cast<Real>(m))));
3124
3125 return extra > 0 ? static_cast<Index>(extra) : 0;
3126}
3127
3128template <typename T, Index N> Tensor<T, N> exp_pade(Tensor<T, N> const &A) {
3129 // Scaling and squaring with diagonal Padé approximants and the
3130 // parameter selection of Al-Mohy and Higham (2009). Their theta_m
3131 // thresholds satisfy theta_m^(2m) / c_recip(m) <= u, so whenever
3132 // norm(A) <= theta_m both the eta_m test (eta_m <= norm) and the
3133 // vanishing of the expm_ell correction are guaranteed: for such
3134 // arguments selecting the order directly from norm(A) is exact
3135 // short-circuit evaluation of the full algorithm at a fraction of the
3136 // cost. The norm(A^p)^(1/p) analysis, which prevents overscaling of
3137 // nonnormal arguments, runs only when norm(A) > theta_13.
3138 Index const
3139 dimension = A.get_dimension();
3140
3141 Real const
3142 norm = Sacado::ScalarValue<T>::eval(norm_1(A));
3143
3144 Index
3145 order = 13;
3146
3147 Index const
3148 orders[] = {3, 5, 7, 9, 13};
3149
3150 for (Index i = 0; i < 5; ++i) {
3151 if (norm <= scaling_squaring_theta_ah09<Real>(orders[i])) {
3152 order = orders[i];
3153 break;
3154 }
3155 }
3156
3157 Real
3158 eta_5 = 0.0;
3159
3160 bool const
3161 scaling_needed = norm > scaling_squaring_theta_ah09<Real>(13);
3162
3163 bool
3164 use_ell = false;
3165
3167 Ar(dimension);
3168
3169 if (scaling_needed) {
3170 // Double-precision value copy for parameter selection only; carries
3171 // no derivative information.
3172 for (Index i = 0; i < dimension; ++i) {
3173 for (Index j = 0; j < dimension; ++j) {
3174 Ar(i, j) = Sacado::ScalarValue<T>::eval(A(i, j));
3175 }
3176 }
3177 Tensor<Real, N> const A2r = Ar * Ar;
3178 Tensor<Real, N> const A4r = A2r * A2r;
3179 Tensor<Real, N> const A6r = A2r * A4r;
3180 Tensor<Real, N> const A8r = A4r * A4r;
3181 Real const d6 = std::pow(norm_1(A6r), 1.0 / 6.0);
3182 Real const d8 = std::pow(norm_1(A8r), 1.0 / 8.0);
3183 Real const d10 = std::pow(norm_1(A4r * A6r), 1.0 / 10.0);
3184 Real const eta_3 = std::max(d6, d8);
3185 Real const eta_4 = std::max(d8, d10);
3186 eta_5 = std::min(eta_3, eta_4);
3187 use_ell = true;
3188 }
3189
3191 B;
3192
3193 if (order < 13) {
3194
3196 U;
3197
3199 V;
3200
3201 std::tie(U, V) = impl::pade_polynomial_terms(A, order);
3202
3203 // The Pade denominator V - U = q_m(A) is diagonally dominant and
3204 // well conditioned for norm(A) within the theta thresholds, so the
3205 // inexpensive adjugate inverse is safe here.
3206 B = inverse(V - U) * (U + V);
3207
3208 } else {
3209
3210 Real const
3211 theta_highest = scaling_squaring_theta_ah09<Real>(13);
3212
3213 int
3214 signed_power = 0;
3215
3216 if (eta_5 > 0.0) {
3217 signed_power = static_cast<int>(
3218 std::ceil(std::log2(eta_5 / theta_highest)));
3219 if (signed_power < 0) signed_power = 0;
3220 }
3221
3222 // rounding correction on the scaled argument (needed only when the
3223 // alpha-based scaling was used; the norm-based bounds make it zero)
3224 if (use_ell) {
3225 Real
3226 scale_r = 1.0;
3227 for (int j = 0; j < signed_power; ++j) {
3228 scale_r /= 2.0;
3229 }
3230 signed_power += static_cast<int>(expm_ell(scale_r * Ar, 13));
3231 }
3232
3233 Index const
3234 power_two = signed_power > 0 ? static_cast<Index>(signed_power) : 0;
3235
3236 Real
3237 scale = 1.0;
3238
3239 for (Index j = 0; j < power_two; ++j) {
3240 scale /= 2.0;
3241 }
3242
3243 Tensor<T, N> const
3244 I = identity<T, N>(dimension);
3245
3246 Tensor<T, N> const
3247 A1 = scale * A;
3248
3249 Tensor<T, N> const
3250 A2 = A1 * A1;
3251
3252 Tensor<T, N> const
3253 A4 = A2 * A2;
3254
3255 Tensor<T, N> const
3256 A6 = A2 * A4;
3257
3258 Real const b0 = impl::polynomial_coefficient<Real>(order, 0);
3259 Real const b1 = impl::polynomial_coefficient<Real>(order, 1);
3260 Real const b2 = impl::polynomial_coefficient<Real>(order, 2);
3261 Real const b3 = impl::polynomial_coefficient<Real>(order, 3);
3262 Real const b4 = impl::polynomial_coefficient<Real>(order, 4);
3263 Real const b5 = impl::polynomial_coefficient<Real>(order, 5);
3264 Real const b6 = impl::polynomial_coefficient<Real>(order, 6);
3265 Real const b7 = impl::polynomial_coefficient<Real>(order, 7);
3266 Real const b8 = impl::polynomial_coefficient<Real>(order, 8);
3267 Real const b9 = impl::polynomial_coefficient<Real>(order, 9);
3268 Real const b10 = impl::polynomial_coefficient<Real>(order, 10);
3269 Real const b11 = impl::polynomial_coefficient<Real>(order, 11);
3270 Real const b12 = impl::polynomial_coefficient<Real>(order, 12);
3271 Real const b13 = impl::polynomial_coefficient<Real>(order, 13);
3272
3273 Tensor<T, N> const
3274 U = A1 * (
3275 (A6 * (b13 * A6 + b11 * A4 + b9 * A2) +
3276 b7 * A6 + b5 * A4 + b3 * A2 + b1 * I));
3277
3278 Tensor<T, N> const
3279 V = A6 * (b12 * A6 + b10 * A4 + b8 * A2) +
3280 b6 * A6 + b4 * A4 + b2 * A2 + b0 * I;
3281
3282 Tensor<T, N> const
3283 R = inverse(V - U) * (U + V);
3284
3285 Index const
3286 exponent = (1U << power_two);
3287
3288 B = binary_powering(R, exponent);
3289
3290 }
3291
3292 return B;
3293}
3294
3295//
3296// Logarithmic map by Taylor series.
3297//
3298template<typename T, Index N>
3300Tensor<T, N>
3302{
3303 Index const
3304 max_iter = 128;
3305
3306 T const
3307 tol = machine_epsilon<T>();
3308
3309 T const
3310 norm_tensor = norm_1(A);
3311
3312 Index const
3313 dimension = A.get_dimension();
3314
3315 Tensor<T, N> const
3316 A_minus_I = A - identity<T, N>(dimension);
3317
3319 term = A_minus_I;
3320
3321 T
3322 norm_term = norm_1(term);
3323
3324 T
3325 relative_error = norm_term / norm_tensor;
3326
3328 B = term;
3329
3330 Index
3331 k = 1;
3332
3333 while (relative_error > tol && k <= max_iter) {
3334 term = static_cast<T>(- (k / (k + 1.0))) * term * A_minus_I;
3335 B = B + term;
3336 norm_term = norm_1(term);
3337 relative_error = norm_term / norm_tensor;
3338 ++k;
3339 }
3340
3341 return B;
3342}
3343
3344//
3345// Logarithmic map.
3346//
3347template<typename T, Index N>
3349Tensor<T, N>
3351{
3352 return log_pade(A);
3353}
3354
3355//
3356// Logarithmic map by Gregory series.
3357//
3358template<typename T, Index N>
3360Tensor<T, N>
3362{
3363 Index const
3364 max_iter = 8192;
3365
3366 T const
3367 tol = machine_epsilon<T>();
3368
3369 T const
3370 norm_tensor = norm_1(A);
3371
3372 Index const
3373 dimension = A.get_dimension();
3374
3375 Tensor<T, N> const
3376 I_minus_A = identity<T, N>(dimension) - A;
3377
3378 Tensor<T, N> const
3379 I_plus_A = identity<T, N>(dimension) + A;
3380
3382 term = I_minus_A * inverse(I_plus_A);
3383
3384 T
3385 norm_term = norm_1(term);
3386
3387 T
3388 relative_error = norm_term / norm_tensor;
3389
3390 Tensor<T, N> const
3391 C = term * term;
3392
3394 B = term;
3395
3396 Index
3397 k = 1;
3398
3399 while (relative_error > tol && k <= max_iter + 1) {
3400 term = static_cast<T>((2 * k - 1.0) / (2 * k + 1.0)) * term * C;
3401 B = B + term;
3402 norm_term = norm_1(term);
3403 relative_error = norm_term / norm_tensor;
3404 ++k;
3405 }
3406
3407 B = - 2.0 * B;
3408
3409 return B;
3410}
3411
3412// Matrix square root by product form of Denman-Beavers iteration.
3419template<typename T, Index N>
3421Tensor<T, N>
3422sqrt_dbp(Tensor<T, N> const & A, int& k)
3423{
3424 auto const dimension = A.get_dimension();
3425 auto const eps = machine_epsilon<T>();
3426 auto const tol = 0.5 * std::sqrt(dimension) * eps;
3427 auto const I = identity<T, N>(dimension);
3428 auto const max_iter = 32;
3429 auto X = A;
3430 auto M = A;
3431 auto scale = true;
3432 k = 0;
3433 while (k++ < max_iter) {
3434 if (scale == true) {
3435 auto const d = abs(det(M));
3436 auto const d2 = std::sqrt(d);
3437 auto const d6 = cbrt(d2);
3438 auto const g = 1.0 / d6;
3439 // For ill-conditioned M the expanded determinant can cancel to zero
3440 // (or overflow), which would make g non-finite and flood the iteration
3441 // with Inf/NaN. The scaling only accelerates convergence, so it is
3442 // safe to skip it in that case.
3443 if (Sacado::ScalarValue<T>::eval(d) > 0.0 &&
3444 std::isfinite(Sacado::ScalarValue<T>::eval(g))) {
3445 X *= g;
3446 M *= g * g;
3447 }
3448 }
3449 auto const Y = X;
3450 auto const L = inverse_full_pivot(M);
3451 X = 0.5 * X * (I + L);
3452 M = 0.5 * (I + 0.5 * (M + L));
3453 auto const error = norm(M - I);
3454 auto const diff = norm(X - Y) / norm(X);
3455 scale = diff >= 0.01;
3456 if (error <= tol) break;
3457 }
3458 return X;
3459}
3460
3461// Tensor square root
3465template<typename T, Index N>
3467Tensor<T, N>
3469{
3470 int k = 0;
3471 return sqrt_dbp(A, k);
3472}
3473
3474// Logarithmic map by Padé approximant and partial fractions
3478template<typename T, Index N>
3480Tensor<T, N>
3481log_pade_pf(Tensor<T, N> const & A, Index const n)
3482{
3483 auto const dimension = A.get_dimension();
3484 auto const I = identity<T, N>(dimension);
3485 auto X = 0.0 * A;
3486 for (Index i = 0; i < n; ++i) {
3487 auto const x = 0.5 * (1.0 + impl::gauss_legendre_abscissae<T>(n, i));
3488 auto const w = 0.5 * impl::gauss_legendre_weights<T>(n, i);
3489 auto const B = I + x * A;
3490 X += w * A * inverse_full_pivot(B);
3491 }
3492 return X;
3493}
3494
3495// Logarithmic map by inverse scaling and squaring and Padé approximants
3499template<typename T, Index N>
3501Tensor<T, N>
3503{
3504 auto const dimension = A.get_dimension();
3505 auto const I = identity<T, N>(dimension);
3506 auto const c15 = impl::pade_coefficients<T>(15);
3507 auto X = A;
3508 auto i = 5;
3509 auto j = 0;
3510 auto k = 0;
3511 auto m = 0;
3512 while (true) {
3513 auto const diff = norm_1(X - I);
3514 if (diff <= c15) {
3515 auto p = 2;
3516 while (impl::pade_coefficients<T>(p) <= diff && p < 16) {
3517 ++p;
3518 }
3519 auto q = 2;
3520 while (impl::pade_coefficients<T>(q) <= diff / 2.0 && q < 16) {
3521 ++q;
3522 }
3523 if ((2 * (p - q) / 3) < i || ++j == 2) {
3524 m = p + 1;
3525 break;
3526 }
3527 }
3528 X = sqrt_dbp(X, i);
3529 ++k;
3530 }
3531 X = (1U << k) * log_pade_pf(X - I, m);
3532 return X;
3533}
3534
3535namespace impl {
3536
3537// Givens pair (c, s) with G = [c, -s; s, c] such that G [a; b] = [r; 0].
3538template<typename T>
3540std::pair<T, T>
3541givens_zero(T const & a, T const & b)
3542{
3543 T const r = std::sqrt(a * a + b * b);
3544 if (Sacado::ScalarValue<T>::eval(r) == 0.0) {
3545 return std::make_pair(T(1.0), T(0.0));
3546 }
3547 return std::make_pair(a / r, -b / r);
3548}
3549
3550// Standardize the 2x2 diagonal block of S at rows/columns (p, p+1) by an
3551// orthogonal similarity applied to all of S and accumulated into Q:
3552// afterwards the block is upper triangular (real eigenvalues, S(p+1,p)
3553// set exactly to zero) or has equal diagonal entries and off-diagonal
3554// entries of opposite sign (complex conjugate pair), as in LAPACK dlanv2.
3555template<typename T, Index N>
3556void
3557schur_standardize_2x2(Tensor<T, N> & S, Tensor<T, N> & Q, Index const p)
3558{
3559 Index const q = p + 1;
3560
3561 T const a = S(p, p);
3562 T const b = S(p, q);
3563 T const c = S(q, p);
3564 T const d = S(q, q);
3565
3566 if (Sacado::ScalarValue<T>::eval(std::abs(c)) == 0.0) {
3567 S(q, p) = 0.0;
3568 return;
3569 }
3570
3571 T const half_diff = 0.5 * (a - d);
3572 T const disc = half_diff * half_diff + b * c;
3573
3574 T cs, sn;
3575
3576 if (Sacado::ScalarValue<T>::eval(disc) >= 0.0) {
3577 // Real eigenvalues: rotate the eigenvector of the larger-|z| root
3578 // onto the first coordinate axis.
3579 T const root = std::sqrt(disc);
3580 T const z = Sacado::ScalarValue<T>::eval(half_diff) >= 0.0 ?
3581 T(half_diff + root) : T(half_diff - root);
3582 std::tie(cs, sn) = givens_zero(z, c);
3583 givens_left(cs, sn, p, q, S);
3584 givens_right(cs, sn, p, q, S);
3585 givens_right(cs, sn, p, q, Q);
3586 S(q, p) = 0.0;
3587 } else {
3588 // Complex pair: rotate so the diagonal entries are equal.
3589 T const theta = 0.5 * std::atan2(a - d, b + c);
3590 cs = std::cos(theta);
3591 sn = std::sin(theta);
3592 givens_left(cs, sn, p, q, S);
3593 givens_right(cs, sn, p, q, S);
3594 givens_right(cs, sn, p, q, Q);
3595 T const m = 0.5 * (S(p, p) + S(q, q));
3596 S(p, p) = m;
3597 S(q, q) = m;
3598 }
3599}
3600
3601// Real Schur decomposition A = Q S Q^T for dimension <= 3: S is upper
3602// quasi-triangular with 1x1 blocks and standardized 2x2 blocks (complex
3603// conjugate eigenvalue pairs), Q is orthogonal. Hessenberg reduction by a
3604// Givens rotation followed by Francis double-shift QR iteration.
3605template<typename T, Index N>
3606std::pair<Tensor<T, N>, Tensor<T, N>>
3607schur_real_small(Tensor<T, N> const & A)
3608{
3609 Index const
3610 dimension = A.get_dimension();
3611
3612 Tensor<T, N>
3613 S = A;
3614
3615 Tensor<T, N>
3616 Q = identity<T, N>(dimension);
3617
3618 if (dimension == 1) {
3619 return std::make_pair(Q, S);
3620 }
3621
3622 if (dimension == 2) {
3623 schur_standardize_2x2(S, Q, 0);
3624 return std::make_pair(Q, S);
3625 }
3626
3627 // dimension == 3
3628
3629 // Hessenberg: zero S(2,0) with a rotation in the (1,2) plane.
3630 {
3631 auto const cs_sn = givens_zero(S(1, 0), S(2, 0));
3632 givens_left(cs_sn.first, cs_sn.second, 1, 2, S);
3633 givens_right(cs_sn.first, cs_sn.second, 1, 2, S);
3634 givens_right(cs_sn.first, cs_sn.second, 1, 2, Q);
3635 S(2, 0) = 0.0;
3636 }
3637
3638 Real const
3639 eps = machine_epsilon<Real>();
3640
3641 Index const
3642 max_iter = 64;
3643
3644 for (Index iter = 0; iter < max_iter; ++iter) {
3645
3646 Real const h00 = std::abs(Sacado::ScalarValue<T>::eval(S(0, 0)));
3647 Real const h11 = std::abs(Sacado::ScalarValue<T>::eval(S(1, 1)));
3648 Real const h22 = std::abs(Sacado::ScalarValue<T>::eval(S(2, 2)));
3649 Real const h10 = std::abs(Sacado::ScalarValue<T>::eval(S(1, 0)));
3650 Real const h21 = std::abs(Sacado::ScalarValue<T>::eval(S(2, 1)));
3651
3652 if (h10 <= eps * (h00 + h11)) {
3653 // leading 1x1 deflated; standardize the trailing 2x2
3654 S(1, 0) = 0.0;
3655 schur_standardize_2x2(S, Q, 1);
3656 return std::make_pair(Q, S);
3657 }
3658
3659 if (h21 <= eps * (h11 + h22)) {
3660 // trailing 1x1 deflated; standardize the leading 2x2
3661 S(2, 1) = 0.0;
3662 schur_standardize_2x2(S, Q, 0);
3663 return std::make_pair(Q, S);
3664 }
3665
3666 // Francis double-shift step: first column of (S - l1 I)(S - l2 I)
3667 // with l1, l2 the eigenvalues of the trailing 2x2 block, written in
3668 // the classical difference form so that clustered eigenvalues (for
3669 // example A near the identity, where the column is O(eps^2) but the
3670 // naive expansion sums O(1) terms) do not lose the shift direction to
3671 // cancellation. Every 12th iteration perturb the shift to escape
3672 // stagnation.
3673 T x, y, z;
3674
3675 if (iter > 0 && iter % 12 == 0) {
3676 T const shift = std::abs(S(2, 1)) + std::abs(S(1, 0));
3677 T const tr = 2.0 * shift;
3678 T const dt = shift * shift;
3679 x = S(0, 0) * S(0, 0) + S(0, 1) * S(1, 0) - tr * S(0, 0) + dt;
3680 y = S(1, 0) * (S(0, 0) + S(1, 1) - tr);
3681 z = S(1, 0) * S(2, 1);
3682 } else {
3683 x = (S(0, 0) - S(1, 1)) * (S(0, 0) - S(2, 2)) -
3684 S(1, 2) * S(2, 1) + S(0, 1) * S(1, 0);
3685 y = S(1, 0) * (S(0, 0) - S(2, 2));
3686 z = S(1, 0) * S(2, 1);
3687 }
3688
3689 // Two rotations mapping (x, y, z) onto e1
3690 auto const g1 = givens_zero(y, z);
3691 T const y1 = g1.first * y - g1.second * z;
3692 auto const g2 = givens_zero(x, y1);
3693
3694 givens_left(g1.first, g1.second, 1, 2, S);
3695 givens_right(g1.first, g1.second, 1, 2, S);
3696 givens_right(g1.first, g1.second, 1, 2, Q);
3697
3698 givens_left(g2.first, g2.second, 0, 1, S);
3699 givens_right(g2.first, g2.second, 0, 1, S);
3700 givens_right(g2.first, g2.second, 0, 1, Q);
3701
3702 // Restore Hessenberg form: zero the bulge S(2,0)
3703 auto const g3 = givens_zero(S(1, 0), S(2, 0));
3704 givens_left(g3.first, g3.second, 1, 2, S);
3705 givens_right(g3.first, g3.second, 1, 2, S);
3706 givens_right(g3.first, g3.second, 1, 2, Q);
3707 S(2, 0) = 0.0;
3708 }
3709
3710 MT_ERROR_EXIT("Schur QR iteration failed to converge.");
3711 return std::make_pair(Q, S);
3712}
3713
3714// Principal square root of an upper quasi-triangular S (dimension <= 3)
3715// with standardized 2x2 blocks and spectrum off the closed negative real
3716// axis. 1x1 blocks: scalar square root. 2x2 blocks [m, b; c, m], bc < 0:
3717// closed form sqrt(B) = (B + delta I) / tau with delta = sqrt(det B) and
3718// tau = sqrt(tr B + 2 delta). Off-diagonal blocks from the Sylvester
3719// equations of U^2 = S.
3720template<typename T, Index N>
3721Tensor<T, N>
3722sqrt_quasi_triu(Tensor<T, N> const & S)
3723{
3724 Index const
3725 dimension = S.get_dimension();
3726
3727 Tensor<T, N>
3728 U(dimension, Filler::ZEROS);
3729
3730 // block structure from exact subdiagonal zeros
3731 Index
3732 blocks[3];
3733
3734 Index
3735 starts[3];
3736
3737 Index
3738 num_blocks = 0;
3739
3740 for (Index i = 0; i < dimension;) {
3741 bool const two = (i + 1 < dimension) &&
3742 (Sacado::ScalarValue<T>::eval(S(i + 1, i)) != 0.0);
3743 starts[num_blocks] = i;
3744 blocks[num_blocks] = two ? 2 : 1;
3745 ++num_blocks;
3746 i += two ? 2 : 1;
3747 }
3748
3749 // diagonal blocks
3750 for (Index b = 0; b < num_blocks; ++b) {
3751 Index const i = starts[b];
3752 if (blocks[b] == 1) {
3753 U(i, i) = std::sqrt(S(i, i));
3754 } else {
3755 T const m = S(i, i);
3756 T const delta =
3757 std::sqrt(m * m - S(i, i + 1) * S(i + 1, i));
3758 T const tau = std::sqrt(m + m + delta + delta);
3759 U(i, i) = (m + delta) / tau;
3760 U(i + 1, i + 1) = U(i, i);
3761 U(i, i + 1) = S(i, i + 1) / tau;
3762 U(i + 1, i) = S(i + 1, i) / tau;
3763 }
3764 }
3765
3766 // off-diagonal blocks, nearest first
3767 for (Index gap = 1; gap < num_blocks; ++gap) {
3768 for (Index b = 0; b + gap < num_blocks; ++b) {
3769 Index const bi = b;
3770 Index const bj = b + gap;
3771 Index const i = starts[bi];
3772 Index const j = starts[bj];
3773 // right-hand side: S_ij - sum_k U_ik U_kj over blocks strictly
3774 // between bi and bj
3775 T rhs[2][2] = {{T(0.0), T(0.0)}, {T(0.0), T(0.0)}};
3776 for (Index r = 0; r < blocks[bi]; ++r) {
3777 for (Index c = 0; c < blocks[bj]; ++c) {
3778 rhs[r][c] = S(i + r, j + c);
3779 }
3780 }
3781 for (Index bk = bi + 1; bk < bj; ++bk) {
3782 Index const k = starts[bk];
3783 for (Index r = 0; r < blocks[bi]; ++r) {
3784 for (Index c = 0; c < blocks[bj]; ++c) {
3785 for (Index kk = 0; kk < blocks[bk]; ++kk) {
3786 rhs[r][c] -= U(i + r, k + kk) * U(k + kk, j + c);
3787 }
3788 }
3789 }
3790 }
3791 // solve U_ii X + X U_jj = rhs
3792 if (blocks[bi] == 1 && blocks[bj] == 1) {
3793 U(i, j) = rhs[0][0] / (U(i, i) + U(j, j));
3794 } else if (blocks[bi] == 2 && blocks[bj] == 1) {
3795 // (U_ii + u_jj I) x = rhs (2x2 solve)
3796 T const a00 = U(i, i) + U(j, j);
3797 T const a01 = U(i, i + 1);
3798 T const a10 = U(i + 1, i);
3799 T const a11 = U(i + 1, i + 1) + U(j, j);
3800 T const det = a00 * a11 - a01 * a10;
3801 U(i, j) = (rhs[0][0] * a11 - a01 * rhs[1][0]) / det;
3802 U(i + 1, j) = (a00 * rhs[1][0] - a10 * rhs[0][0]) / det;
3803 } else {
3804 // x (U_jj + u_ii I) = rhs (1x2 row solve)
3805 T const a00 = U(j, j) + U(i, i);
3806 T const a01 = U(j, j + 1);
3807 T const a10 = U(j + 1, j);
3808 T const a11 = U(j + 1, j + 1) + U(i, i);
3809 T const det = a00 * a11 - a01 * a10;
3810 U(i, j) = (rhs[0][0] * a11 - rhs[0][1] * a10) / det;
3811 U(i, j + 1) = (rhs[0][1] * a00 - rhs[0][0] * a01) / det;
3812 }
3813 }
3814 }
3815
3816 return U;
3817}
3818
3819} // namespace impl
3820
3821//
3822// Logarithmic map by real Schur decomposition and inverse scaling and
3823// squaring on the quasi-triangular factor, in the spirit of Al-Mohy and
3824// Higham, Improved Inverse Scaling and Squaring Algorithms for the
3825// Matrix Logarithm, SIAM J. Sci. Comput. 34(4), 2012. Dimension <= 3.
3826//
3827template<typename T, Index N>
3828Tensor<T, N>
3830{
3831 Index const
3832 dimension = A.get_dimension();
3833
3835 Q(dimension);
3836
3838 R(dimension);
3839
3840 std::tie(Q, R) = impl::schur_real_small(A);
3841
3842 // The principal logarithm requires the spectrum off the closed
3843 // negative real axis; real eigenvalues appear as 1x1 diagonal blocks.
3844 for (Index i = 0; i < dimension; ++i) {
3845 bool const in_block =
3846 (i + 1 < dimension &&
3847 Sacado::ScalarValue<T>::eval(R(i + 1, i)) != 0.0) ||
3848 (i > 0 && Sacado::ScalarValue<T>::eval(R(i, i - 1)) != 0.0);
3849 if (!in_block && Sacado::ScalarValue<T>::eval(R(i, i)) <= 0.0) {
3850 MT_ERROR_EXIT("Non-positive real eigenvalue: principal log undefined.");
3851 }
3852 }
3853
3854 // Inverse scaling and squaring on R with exact quasi-triangular square
3855 // roots; degree selection as in log_iss.
3856 auto const
3857 I = identity<T, N>(dimension);
3858
3859 auto const
3860 c15 = impl::pade_coefficients<Real>(15);
3861
3863 X = R;
3864
3865 auto j = 0;
3866 auto k = 0;
3867 auto m = 0;
3868
3869 while (true) {
3870 Real const
3871 diff = Sacado::ScalarValue<T>::eval(norm_1(X - I));
3872 if (diff <= c15) {
3873 auto p = 2;
3874 while (impl::pade_coefficients<Real>(p) <= diff && p < 16) {
3875 ++p;
3876 }
3877 auto q = 2;
3878 while (impl::pade_coefficients<Real>(q) <= diff / 2.0 && q < 16) {
3879 ++q;
3880 }
3881 // an exact triangular square root is cheap: take another one only
3882 // if it reduces the Pade degree meaningfully
3883 if (p - q < 3 || ++j == 2) {
3884 m = p + 1;
3885 break;
3886 }
3887 }
3888 X = impl::sqrt_quasi_triu(X);
3889 ++k;
3890 }
3891
3893 L = (1U << k) * log_pade_pf(X - I, m);
3894
3895 // Recompute the diagonal blocks of log R exactly from the eigenvalues
3896 // (Al-Mohy-Higham refinement): 1x1 blocks are scalar logs; for a
3897 // standardized 2x2 block [m, b; c, m] with eigenvalues m +/- i mu,
3898 // mu = sqrt(-b c), the log is l I + (theta / mu) K with
3899 // l = log(sqrt(m^2 + mu^2)), theta = atan2(mu, m), K = [0, b; c, 0].
3900 for (Index i = 0; i < dimension;) {
3901 bool const two = (i + 1 < dimension) &&
3902 (Sacado::ScalarValue<T>::eval(R(i + 1, i)) != 0.0);
3903 if (!two) {
3904 L(i, i) = std::log(R(i, i));
3905 i += 1;
3906 } else {
3907 T const mm = R(i, i);
3908 T const mu = std::sqrt(-R(i, i + 1) * R(i + 1, i));
3909 T const ell = 0.5 * std::log(mm * mm + mu * mu);
3910 T const theta = std::atan2(mu, mm);
3911 T const factor = theta / mu;
3912 L(i, i) = ell;
3913 L(i + 1, i + 1) = ell;
3914 L(i, i + 1) = R(i, i + 1) * factor;
3915 L(i + 1, i) = R(i + 1, i) * factor;
3916 i += 2;
3917 }
3918 }
3919
3920 return dot(Q, dot_t(L, Q));
3921}
3922
3923//
3924// Logarithmic map by squaring and scaling and Padé approximants.
3925// See algorithm 11.10 in Functions of Matrices, N.J. Higham, SIAM, 2008.
3926// \param A tensor
3927// \return \f$ \log A \f$
3928//
3933template<typename T, Index N>
3935Tensor<T, N>
3937{
3938 Index const
3939 dimension = A.get_dimension();
3940
3941 if (dimension <= 3) {
3942
3943 // Near the identity no square roots are needed: evaluate the Padé
3944 // approximant directly on A - I, which is computed exactly. This
3945 // path preserves the relative accuracy of small logarithms, which
3946 // any similarity-based method loses to the ~eps*norm(A) rounding of
3947 // the transformation itself.
3948 Tensor<T, N> const
3949 W = A - identity<T, N>(dimension);
3950
3951 Real const
3952 diff = Sacado::ScalarValue<T>::eval(norm_1(W));
3953
3954 if (diff <= impl::pade_coefficients<Real>(15)) {
3955 auto p = 2;
3956 while (impl::pade_coefficients<Real>(p) <= diff && p < 16) {
3957 ++p;
3958 }
3959 return log_pade_pf(W, p + 1);
3960 }
3961
3962 // Away from the identity: Schur-based inverse scaling and squaring.
3963 return log_schur(A);
3964 }
3965
3966 return log_iss(A);
3967}
3968
3969//
3970// Logarithmic map for symmetric tensor.
3971//
3972template<typename T, Index N>
3974Tensor<T, N>
3976{
3977 return log_eig_sym(A);
3978}
3979
3980//
3981// Logarithmic map for symmetric tensor using eigenvalue decomposition.
3982//
3983template<typename T, Index N>
3985Tensor<T, N>
3987{
3988 Index const
3989 dimension = A.get_dimension();
3990
3992 V(dimension);
3993
3995 D(dimension);
3996
3997 std::tie(V, D) = eig_sym(A);
3998
3999 for (Index i = 0; i < dimension; ++i) {
4000 if (D(i, i) < T(0)) {
4001 MT_ERROR_EXIT("Non-SPD input: negative eigenvalue.");
4002 }
4003 D(i, i) = std::log(D(i, i));
4004 }
4005
4006 Tensor<T, N> const
4007 B = dot_t(dot(V, D), V);
4008
4009 return B;
4010}
4011
4012//
4013// Exponential map for symmetric tensor.
4014//
4015template<typename T, Index N>
4017Tensor<T, N>
4019{
4020 return exp_eig_sym(A);
4021}
4022
4023//
4024// Exponential map for symmetric tensor using eigenvalue decomposition.
4025//
4026template<typename T, Index N>
4028Tensor<T, N>
4030{
4031 Index const
4032 dimension = A.get_dimension();
4033
4035 V(dimension);
4036
4038 D(dimension);
4039
4040 std::tie(V, D) = eig_sym(A);
4041
4042 for (Index i = 0; i < dimension; ++i) {
4043 D(i, i) = std::exp(D(i, i));
4044 }
4045
4046 Tensor<T, N> const
4047 B = dot_t(dot(V, D), V);
4048
4049 return B;
4050}
4051
4052//
4053// R^N logarithmic map using BCH expansion (4 terms)
4054// \param x tensor
4055// \param y tensor
4056// \return Baker-Campbell-Hausdorff series up to 4 terms
4057//
4058template<typename T, Index N>
4060Tensor<T, N>
4061bch(Tensor<T, N> const & x, Tensor<T, N> const & y)
4062{
4063 return
4064 // first order term
4065 x + y
4066 +
4067 // second order term
4068 0.5*(x*y - y*x)
4069 +
4070 // third order term
4071 1.0/12.0 *
4072 (x*x*y - 2.0*x*y*x + x*y*y + y*x*x - 2.0*y*x*y + y*y*x)
4073 +
4074 // fourth order term
4075 1.0/24.0 *
4076 (x*x*y*y - 2.0*x*y*x*y + 2.0*y*x*y*x - y*y*x*x);
4077}
4078
4080} // namespace minitensor
4081
4082#endif // MiniTensor_MatrixFunctions_h
#define KOKKOS_INLINE_FUNCTION
#define MT_ERROR_EXIT(...)
KOKKOS_INLINE_FUNCTION Index get_dimension() const
KOKKOS_INLINE_FUNCTION Matrix< typename Promote< S, T >::type, M, N > dot_t(Matrix< S, M, P > const &A, Matrix< T, N, P > const &B)
KOKKOS_INLINE_FUNCTION void scale(TensorBase< R, SR > const &A, S const &s, TensorBase< T, ST > &B)
KOKKOS_INLINE_FUNCTION Vector< typename Promote< S, T >::type, M > dot(Matrix< T, M, N > const &A, Vector< S, N > const &u)
std::pair< Tensor< T, N >, Tensor< T, N > > eig_sym(Tensor< T, N > const &A)
KOKKOS_INLINE_FUNCTION void givens_right(T const &c, T const &s, Index i, Index k, Tensor< T, N > &A)
KOKKOS_INLINE_FUNCTION void givens_left(T const &c, T const &s, Index i, Index k, Tensor< T, N > &A)
KOKKOS_INLINE_FUNCTION Tensor< T, N > inverse_full_pivot(Tensor< T, N > const &A)
KOKKOS_INLINE_FUNCTION Tensor< T, N > inverse(Tensor< T, N > const &A)
KOKKOS_INLINE_FUNCTION T scaling_squaring_theta_ah09(Index const order)
KOKKOS_INLINE_FUNCTION Tensor< T, N > sqrt_dbp(Tensor< T, N > const &A, int &k)
KOKKOS_INLINE_FUNCTION Tensor< T, N > log_gregory(Tensor< T, N > const &A)
Tensor< T, N > log_schur(Tensor< T, N > const &A)
Index expm_ell(Tensor< Real, N > const &A, Index const m)
KOKKOS_INLINE_FUNCTION Tensor< T, N > sqrt(Tensor< T, N > const &A)
KOKKOS_INLINE_FUNCTION Tensor< T, N > log_iss(Tensor< T, N > const &A)
KOKKOS_INLINE_FUNCTION Tensor< T, N > exp_sym(Tensor< T, N > const &A)
KOKKOS_INLINE_FUNCTION Tensor< T, N > log_pade_pf(Tensor< T, N > const &A, Index const n)
KOKKOS_INLINE_FUNCTION Tensor< T, N > log_taylor(Tensor< T, N > const &A)
KOKKOS_INLINE_FUNCTION Tensor< T, N > log(Tensor< T, N > const &A)
KOKKOS_INLINE_FUNCTION Tensor< T, N > exp_taylor(Tensor< T, N > const &A)
KOKKOS_INLINE_FUNCTION Tensor< T, N > binary_powering(Tensor< T, N > const &A, Index const exponent)
KOKKOS_INLINE_FUNCTION Tensor< T, N > bch(Tensor< T, N > const &v, Tensor< T, N > const &r)
KOKKOS_INLINE_FUNCTION Tensor< T, N > log_pade(Tensor< T, N > const &A)
Tensor< T, N > exp_pade(Tensor< T, N > const &A)
KOKKOS_INLINE_FUNCTION Tensor< T, N > log_eig_sym(Tensor< T, N > const &A)
KOKKOS_INLINE_FUNCTION Tensor< T, N > log_sym(Tensor< T, N > const &A)
Tensor< T, N > exp(Tensor< T, N > const &A)
KOKKOS_INLINE_FUNCTION Tensor< T, N > exp_eig_sym(Tensor< T, N > const &A)
KOKKOS_INLINE_FUNCTION T norm(Tensor< T, N > const &A)
KOKKOS_INLINE_FUNCTION T det(Tensor< T, N > const &A)
KOKKOS_INLINE_FUNCTION T norm_1(Tensor< T, N > const &A)
double Real
Floating point type.
uint32_t Index
Indexing type.
constexpr Index INDEX_SIZE
KOKKOS_INLINE_FUNCTION Sacado::ScalarType< T >::type tau()
KOKKOS_INLINE_FUNCTION T abs(T const &a)