sobol_gold.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*
  2. * Copyright 1993-2009 NVIDIA Corporation. All rights reserved.
  3. *
  4. * NVIDIA Corporation and its licensors retain all intellectual property and
  5. * proprietary rights in and to this software and related documentation and
  6. * any modifications thereto. Any use, reproduction, disclosure, or distribution
  7. * of this software and related documentation without an express license
  8. * agreement from NVIDIA Corporation is strictly prohibited.
  9. *
  10. */
  11. /*
  12. * Portions Copyright (c) 1993-2009 NVIDIA Corporation. All rights reserved.
  13. * Portions Copyright (c) 2009 Mike Giles, Oxford University. All rights reserved.
  14. * Portions Copyright (c) 2008 Frances Y. Kuo and Stephen Joe. All rights reserved.
  15. *
  16. * Sobol Quasi-random Number Generator example
  17. *
  18. * Based on CUDA code submitted by Mike Giles, Oxford University, United Kingdom
  19. * http://people.maths.ox.ac.uk/~gilesm/
  20. *
  21. * and C code developed by Stephen Joe, University of Waikato, New Zealand
  22. * and Frances Kuo, University of New South Wales, Australia
  23. * http://web.maths.unsw.edu.au/~fkuo/sobol/
  24. *
  25. * For theoretical background see:
  26. *
  27. * P. Bratley and B.L. Fox.
  28. * Implementing Sobol's quasirandom sequence generator
  29. * http://portal.acm.org/citation.cfm?id=42288
  30. * ACM Trans. on Math. Software, 14(1):88-100, 1988
  31. *
  32. * S. Joe and F. Kuo.
  33. * Remark on algorithm 659: implementing Sobol's quasirandom sequence generator.
  34. * http://portal.acm.org/citation.cfm?id=641879
  35. * ACM Trans. on Math. Software, 29(1):49-57, 2003
  36. */
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. #include <math.h>
  40. #include <string.h>
  41. #include "sobol.h"
  42. #include "sobol_gold.h"
  43. #include "sobol_primitives.h"
  44. #define k_2powneg32 2.3283064E-10F
  45. // Create the direction numbers, based on the primitive polynomials.
  46. void initSobolDirectionVectors(int n_dimensions, unsigned int *directions)
  47. {
  48. unsigned int *v = directions;
  49. int dim;
  50. for (dim = 0 ; dim < n_dimensions ; dim++)
  51. {
  52. // First dimension is a special case
  53. if (dim == 0)
  54. {
  55. int i;
  56. for (i = 0 ; i < n_directions ; i++)
  57. {
  58. // All m's are 1
  59. v[i] = 1 << (31 - i);
  60. }
  61. }
  62. else
  63. {
  64. int d = sobol_primitives[dim].degree;
  65. // The first direction numbers (up to the degree of the polynomial)
  66. // are simply v[i] = m[i] / 2^i (stored in Q0.32 format)
  67. int i;
  68. for (i = 0 ; i < d ; i++)
  69. {
  70. v[i] = sobol_primitives[dim].m[i] << (31 - i);
  71. }
  72. // The remaining direction numbers are computed as described in
  73. // the Bratley and Fox paper.
  74. // v[i] = a[1]v[i-1] ^ a[2]v[i-2] ^ ... ^ a[v-1]v[i-d+1] ^ v[i-d] ^ v[i-d]/2^d
  75. for (i = d ; i < n_directions ; i++)
  76. {
  77. // First do the v[i-d] ^ v[i-d]/2^d part
  78. v[i] = v[i - d] ^ (v[i - d] >> d);
  79. // Now do the a[1]v[i-1] ^ a[2]v[i-2] ^ ... part
  80. // Note that the coefficients a[] are zero or one and for compactness in
  81. // the input tables they are stored as bits of a single integer. To extract
  82. // the relevant bit we use right shift and mask with 1.
  83. // For example, for a 10 degree polynomial there are ten useful bits in a,
  84. // so to get a[2] we need to right shift 7 times (to get the 8th bit into
  85. // the LSB) and then mask with 1.
  86. int j;
  87. for (j = 1 ; j < d ; j++)
  88. {
  89. v[i] ^= (((sobol_primitives[dim].a >> (d - 1 - j)) & 1) * v[i - j]);
  90. }
  91. }
  92. }
  93. v += n_directions;
  94. }
  95. }
  96. // Reference model for generating Sobol numbers on the host
  97. void sobolCPU(int n_vectors, int n_dimensions, unsigned int *directions, float *output)
  98. {
  99. unsigned int *v = directions;
  100. int d;
  101. for (d = 0 ; d < n_dimensions ; d++)
  102. {
  103. unsigned int X = 0;
  104. // x[0] is zero (in all dimensions)
  105. output[n_vectors * d] = 0.0;
  106. int i;
  107. for (i = 1 ; i < n_vectors ; i++)
  108. {
  109. // x[i] = x[i-1] ^ v[c]
  110. // where c is the index of the rightmost zero bit in i
  111. // minus 1 (since C arrays count from zero)
  112. // In the Bratley and Fox paper this is equation (**)
  113. X ^= v[ffs(~(i - 1)) - 1];
  114. output[i + n_vectors * d] = (float)X * k_2powneg32;
  115. }
  116. v += n_directions;
  117. }
  118. }