zufall.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #include<stdio.h>
  2. #include<math.h>
  3. #include"zufall.h"
  4. /*-
  5. * portable lagged Fibonacci series uniform random number generator with
  6. * "lags" -273 und -607:
  7. *
  8. * t = u(i-273)+buff(i-607) (floating pt.)
  9. * u(i) = t - float(int(t))
  10. *
  11. * W.P. Petersen, IPS, ETH Zuerich, 19 Mar. 92
  12. */
  13. struct klotz0 klotz0_1;
  14. struct klotz1 klotz1_1;
  15. int zufall(int n, double *a)
  16. {
  17. static int buffsz = 607;
  18. int left, aptr, bptr, aptr0, i, k, q, nn, vl, qq, k273, k607;
  19. double t;
  20. extern struct klotz0 klotz0_1;
  21. --a;
  22. aptr = 0;
  23. nn = n;
  24. L1:
  25. if (nn <= 0)
  26. return 0;
  27. q = (nn - 1) / 607; /* factor nn = q*607 + r */
  28. left = buffsz - klotz0_1.ptr;
  29. if (q <= 1) { /* only one or fewer full segments */
  30. if (nn < left) {
  31. for (i = 1; i <= nn; ++i)
  32. a[i + aptr] = klotz0_1.buff[klotz0_1.ptr + i - 1];
  33. klotz0_1.ptr += nn;
  34. return 0;
  35. }
  36. else {
  37. for (i = 1; i <= left; ++i)
  38. a[i + aptr] = klotz0_1.buff[klotz0_1.ptr + i - 1];
  39. klotz0_1.ptr = 0;
  40. aptr += left;
  41. nn -= left;
  42. /* buff -> buff case */
  43. vl = 273;
  44. k273 = 334;
  45. k607 = 0;
  46. for (k = 1; k <= 3; ++k) {
  47. /* dir$ ivdep */
  48. /* vdir nodep */
  49. /* VOCL LOOP, TEMP(t), NOVREC(buff) */
  50. for (i = 1; i <= vl; ++i) {
  51. t = klotz0_1.buff[k273 + i - 1] + klotz0_1.buff[k607 + i -
  52. 1];
  53. klotz0_1.buff[k607 + i - 1] = t - (float)((int)t);
  54. }
  55. k607 += vl;
  56. k273 += vl;
  57. vl = 167;
  58. if (k == 1) {
  59. k273 = 0;
  60. }
  61. }
  62. goto L1;
  63. }
  64. }
  65. else {
  66. /* more than 1 full segment */
  67. for (i = 1; i <= left; ++i)
  68. a[i + aptr] = klotz0_1.buff[klotz0_1.ptr + i - 1];
  69. nn -= left;
  70. klotz0_1.ptr = 0;
  71. aptr += left;
  72. /* buff -> a(aptr0) */
  73. vl = 273;
  74. k273 = 334;
  75. k607 = 0;
  76. for (k = 1; k <= 3; ++k) {
  77. if (k == 1) {
  78. /* VOCL LOOP, TEMP(t) */
  79. for (i = 1; i <= vl; ++i) {
  80. t = klotz0_1.buff[k273 + i - 1] + klotz0_1.buff[k607 + i -
  81. 1];
  82. a[aptr + i] = t - (float)((int)t);
  83. }
  84. k273 = aptr;
  85. k607 += vl;
  86. aptr += vl;
  87. vl = 167;
  88. }
  89. else {
  90. /* dir$ ivdep */
  91. /* vdir nodep */
  92. /* VOCL LOOP, TEMP(t) */
  93. for (i = 1; i <= vl; ++i) {
  94. t = a[k273 + i] + klotz0_1.buff[k607 + i - 1];
  95. a[aptr + i] = t - (float)((int)t);
  96. }
  97. k607 += vl;
  98. k273 += vl;
  99. aptr += vl;
  100. }
  101. }
  102. nn += -607;
  103. /* a(aptr-607) -> a(aptr) for last of the q-1 segments */
  104. aptr0 = aptr - 607;
  105. vl = 607;
  106. /* vdir novector */
  107. for (qq = 1; qq <= q - 2; ++qq) {
  108. k273 = aptr0 + 334;
  109. /* dir$ ivdep */
  110. /* vdir nodep */
  111. /* VOCL LOOP, TEMP(t), NOVREC(a) */
  112. for (i = 1; i <= vl; ++i) {
  113. t = a[k273 + i] + a[aptr0 + i];
  114. a[aptr + i] = t - (float)((int)t);
  115. }
  116. nn += -607;
  117. aptr += vl;
  118. aptr0 += vl;
  119. }
  120. /* a(aptr0) -> buff, last segment before residual */
  121. vl = 273;
  122. k273 = aptr0 + 334;
  123. k607 = aptr0;
  124. bptr = 0;
  125. for (k = 1; k <= 3; ++k) {
  126. if (k == 1) {
  127. /* VOCL LOOP, TEMP(t) */
  128. for (i = 1; i <= vl; ++i) {
  129. t = a[k273 + i] + a[k607 + i];
  130. klotz0_1.buff[bptr + i - 1] = t - (double)((int)t);
  131. }
  132. k273 = 0;
  133. k607 += vl;
  134. bptr += vl;
  135. vl = 167;
  136. }
  137. else {
  138. /* dir$ ivdep */
  139. /* vdir nodep */
  140. /* VOCL LOOP, TEMP(t), NOVREC(buff) */
  141. for (i = 1; i <= vl; ++i) {
  142. t = klotz0_1.buff[k273 + i - 1] + a[k607 + i];
  143. klotz0_1.buff[bptr + i - 1] = t - (float)((int)t);
  144. }
  145. k607 += vl;
  146. k273 += vl;
  147. bptr += vl;
  148. }
  149. }
  150. goto L1;
  151. }
  152. } /* zufall */