| 544 | |
| 545 | template <Precision PR> |
| 546 | void GenerateTwiddleTable(const std::vector<size_t> &radices, std::string &twStr) |
| 547 | { |
| 548 | const double TWO_PI = -6.283185307179586476925286766559; |
| 549 | |
| 550 | // Make sure the radices vector sums up to N |
| 551 | size_t sz = 1; |
| 552 | for(std::vector<size_t>::const_iterator i = radices.begin(); |
| 553 | i != radices.end(); i++) |
| 554 | { |
| 555 | sz *= (*i); |
| 556 | } |
| 557 | assert(sz == N); |
| 558 | |
| 559 | // Generate the table |
| 560 | size_t L = 1; |
| 561 | size_t nt = 0; |
| 562 | for(std::vector<size_t>::const_iterator i = radices.begin(); |
| 563 | i != radices.end(); i++) |
| 564 | { |
| 565 | size_t radix = *i; |
| 566 | |
| 567 | L *= radix; |
| 568 | |
| 569 | // Twiddle factors |
| 570 | for(size_t k=0; k<(L/radix); k++) |
| 571 | { |
| 572 | double theta = TWO_PI * ((double)k)/((double)L); |
| 573 | |
| 574 | for(size_t j=1; j<radix; j++) |
| 575 | { |
| 576 | double c = cos(((double)j) * theta); |
| 577 | double s = sin(((double)j) * theta); |
| 578 | |
| 579 | //if (fabs(c) < 1.0E-12) c = 0.0; |
| 580 | //if (fabs(s) < 1.0E-12) s = 0.0; |
| 581 | |
| 582 | wc[nt] = c; |
| 583 | ws[nt++] = s; |
| 584 | } |
| 585 | } |
| 586 | } |
| 587 | |
| 588 | std::string sfx = FloatSuffix<PR>(); |
| 589 | |
| 590 | // Stringize the table |
| 591 | std::stringstream ss; |
| 592 | ss.imbue(std::locale("C")); |
| 593 | ss.precision(34); |
| 594 | for(size_t i = 0; i < (N-1); i++) |
| 595 | { |
| 596 | ss << "("; ss << RegBaseType<PR>(2); ss << ")("; |
| 597 | ss << std::scientific << wc[i] << sfx << ", "; |
| 598 | ss << std::scientific << ws[i] << sfx << "),\n"; |
| 599 | } |
| 600 | twStr += ss.str(); |
| 601 | } |
| 602 | }; |
| 603 |
nothing calls this directly
no outgoing calls
no test coverage detected