1. /* ssqcoupl.h by K.Tsuru */
  2. // since ver. 2.18
  3. /***************************************************************
  4. SN library
  5. Template class of square coupling method.
  6. It evaluates power series
  7. S_L = A_0 + A_1 * R + A_2 * R^2 + ...
  8. It can be used to evaluate a polynomial of SLong or SInteger
  9. e.g. radix conversion.
  10. This is a generalization of divide radix conversion
  11. of "SLong SInteger::DConvToDec() const;" in "simdcvdc.cpp".
  12. ***************************************************************/
  13. #ifndef SQUARE_COUPLING_TEMPLATE_H
  14. #define SQUARE_COUPLING_TEMPLATE_H
  15. template <class SqCType> class SquareCoupling {
  16. private:
  17. const SqCType ZERO;
  18. void abort(); // abort by syntax error
  19. void freeHalf(ulong from, ulong to); // free memory of disused elements.
  20. bool isOk;
  21. SqCType *A, R;
  22. ulong L, userL; // L/2 < userL =< L
  23. void setL(ulong s) {
  24. L = userL = s;
  25. if ( userL & (userL - 1) ) L = ceilpow2(userL); // L != 2^n It changes into 2^n.
  26. SCalcInfo::upToTerm = L;
  27. }
  28. SqCType element(ulong k) {
  29. return (k < userL) ? A[k] : ZERO;
  30. }
  31. public:
  32. // A function sets coefficients A[].
  33. // caution : The content of a[] is destroied.
  34. void setAR(SqCType *a, const SqCType& r, ulong size) {
  35. isOk = false; // reset for second usage
  36. A = a; R = r; setL(size);
  37. }
  38. SquareCoupling() : ZERO(0.0), isOk(false), L(0), userL(0) {}
  39. SquareCoupling(SqCType *a, const SqCType& r, ulong size)
  40. : ZERO(0.0), isOk(false), A(a), R(r) {
  41. setL(size);
  42. }
  43. virtual ~SquareCoupling(){}
  44. void putTogether();
  45. bool isOK() const { return isOk; }
  46. SqCType getValue(); //It returns the value of A[0].
  47. };
  48. /***************************************
  49. * Implementation of class SquareCoupling
  50. ****************************************/
  51. template <class SqCType> void SquareCoupling<SqCType> ::freeHalf(ulong from, ulong to) {
  52. for (ulong i = from; i < to; i++) A[i].SizeZero();
  53. }
  54. template <class SqCType> void SquareCoupling<SqCType>::abort() {
  55. R.SetError(R.SYNTAX_ERR, "class SquareCoupling", 1601);
  56. }
  57. template <class SqCType> void SquareCoupling<SqCType>::putTogether() {
  58. if (L == 0) abort();
  59. SqCType Q(R);
  60. // First step "element()" is used because A[i] (userL =< i < L) are undecided.
  61. #if 1
  62. ulong j, uj = userL;
  63. if (userL & 1) uj++;
  64. for ( j = 0; j < uj - 2; j += 2) A[j/2] = A[j+1] * Q + A[j];
  65. // here j == uj-2
  66. A[j/2] = element(j+1) * Q + element(j);
  67. j += 2;
  68. for ( ; j< L ; j += 2) A[j/2].SetZero();
  69. #else
  70. // simple version
  71. for (ulong i = 0; i < L; i += 2) A[i/2] = element(i+1) * Q + element(i);
  72. #endif
  73. ulong n = L / 2;
  74. freeHalf(n, userL);
  75. Q *= Q;
  76. while (1) {
  77. for (ulong i = 0; i < n ; i += 2) A[i/2] = A[i+1] * Q + A[i];
  78. n /= 2;
  79. freeHalf(n, 2 * n - 1);
  80. if (n == 1) break;
  81. Q *= Q;
  82. }
  83. isOk = true;
  84. }
  85. template <class SqCType> SqCType SquareCoupling<SqCType>::getValue() {
  86. if (!isOk) putTogether();
  87. return A[0];
  88. }
  89. #endif // SQUARE_COUPLING_TEMPLATE_H

ssqcoupl.h : last modifiled at 2016/09/04 14:21:36(2,960 bytes)
created at 2016/04/11 11:18:59
The creation time of this html file is 2017/10/11 16:07:52 (Wed Oct 11 16:07:52 2017).