Fermat
weyl.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2018, NVIDIA Corporation
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of NVIDIA Corporation nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
32 #pragma once
33 
34 #include <cugar/basic/types.h>
35 #include <limits.h>
36 
37 namespace cugar {
38 
47 class Weyl_sampler
54 {
55  public:
58  CUGAR_HOST_DEVICE CUGAR_FORCEINLINE Weyl_sampler() : m_dim( unsigned int(-1) ), m_r(0), m_i(1) {}
59 
64  CUGAR_HOST_DEVICE CUGAR_FORCEINLINE Weyl_sampler(unsigned int instance, unsigned int seed = 1) : m_dim( unsigned int(-1) ), m_r(seed), m_i(instance+1) {}
65 
68  CUGAR_HOST_DEVICE CUGAR_FORCEINLINE float sample()
69  {
70  next_dim();
71  //return cugar::mod( float(m_i) * m_r, 1.0f );
72  return cugar::mod( float(m_i) * (float(m_r) / float(UINT_MAX)), 1.0f );
73  // NOTE: The sequence of all multiples of an irrational number (m_r) is equidistributed modulo 1
74  }
75 
78  CUGAR_HOST_DEVICE CUGAR_FORCEINLINE float next() { return sample(); } // random number generator interface
79 
80  private:
81 
84  CUGAR_HOST_DEVICE CUGAR_FORCEINLINE void next_dim()
85  {
86  m_dim++;
87  //m_r = sqrtf( float(s_primes[m_dim]) );
88  m_r = m_r * 1103515245u + 12345u;
89  }
90 
91  unsigned int m_dim;
92  unsigned int m_r;
93  unsigned int m_i;
94 };
95 
104 {
105  public:
111  CUGAR_HOST_DEVICE CUGAR_FORCEINLINE Weyl_sampler_opt(unsigned int n_dims = 1, unsigned int instance = 0, float seed = 0.0f) :
112  m_dim( unsigned int(-1) ), m_seed(seed), m_i(instance+1), m_alpha(1.0f)
113  {
114  m_gamma = 1.0f / gamma(n_dims);
115  }
116 
119  CUGAR_HOST_DEVICE CUGAR_FORCEINLINE float sample()
120  {
121  next_dim();
122 
123  // NOTE: The sequence of all multiples of an irrational number (m_alpha) is equidistributed modulo 1
124  //
125 
126  #if 1 // higher precision
127  const double ia = double(m_seed) + double(m_i) * double(m_alpha);
128  return float(ia - floor(ia));
129  #else // single precision suffers for large values of m_i
130  const float ia = m_seed + float(m_i) * m_alpha;
131  return ia - floorf(ia);
132  #endif
133  }
134 
137  CUGAR_HOST_DEVICE CUGAR_FORCEINLINE float next() { return sample(); } // random number generator interface
138 
141  CUGAR_HOST_DEVICE CUGAR_FORCEINLINE unsigned int next_instance() { return ++m_i; }
142 
145  CUGAR_HOST_DEVICE CUGAR_FORCEINLINE unsigned int next_dim()
146  {
147  ++m_dim;
148 
149  //init_alpha();
150  m_alpha *= m_gamma; // faster, but lower precision for large m_dim
151  //m_alpha = fmodf( m_alpha, 1.0f );
152 
153  return m_dim;
154  }
155 
158  CUGAR_HOST_DEVICE CUGAR_FORCEINLINE void set_instance(unsigned int i) { m_i = i+1; }
159 
162  CUGAR_HOST_DEVICE CUGAR_FORCEINLINE void set_dim(unsigned int d) { m_dim = d-1; init_alpha(); }
163 
164 private:
165 
168  CUGAR_HOST_DEVICE CUGAR_FORCEINLINE void init_alpha()
169  {
170  m_alpha = powf( m_gamma, float(m_dim+1) );
171  //m_alpha = fmodf( m_alpha, 1.0f );
172  }
173 
176  CUGAR_HOST_DEVICE CUGAR_FORCEINLINE static float gamma(unsigned int d)
177  {
178  const float c_gamma[128] = {
179  1.6180339887f, 1.3247179572f, 1.2207440846f, 1.1673039783f,
180  1.1347241384f, 1.1127756843f, 1.0969815578f, 1.0850702455f,
181  1.0757660661f, 1.0682971889f, 1.0621691679f, 1.0570505752f,
182  1.0527109201f, 1.0489849348f, 1.0457510242f, 1.0429177323f,
183  1.0404149478f, 1.0381880194f, 1.0361937171f, 1.0343973961f,
184  1.0327709664f, 1.0312914125f, 1.0299396967f, 1.0286999355f,
185  1.0275587724f, 1.0265048941f, 1.0255286548f, 1.0246217791f,
186  1.0237771279f, 1.0229885089f, 1.0222505253f, 1.0215584519f,
187  1.0209081336f, 1.0202959021f, 1.0197185065f, 1.0191730558f,
188  1.0186569702f, 1.0181679403f, 1.0177038930f, 1.0172629613f,
189  1.0168434601f, 1.0164438641f, 1.0160627892f, 1.0156989769f,
190  1.0153512803f, 1.0150186517f, 1.0147001323f, 1.0143948430f,
191  1.0141019764f, 1.0138207892f, 1.0135505966f, 1.0132907659f,
192  1.0130407123f, 1.0127998942f, 1.0125678091f, 1.0123439905f,
193  1.0121280045f, 1.0119194469f, 1.0117179410f, 1.0115231351f,
194  1.0113347005f, 1.0111523296f, 1.0109757344f, 1.0108046448f,
195  1.0106388073f, 1.0104779837f, 1.0103219500f, 1.0101704953f,
196  1.0100234209f, 1.0098805397f, 1.0097416747f, 1.0096066589f,
197  1.0094753346f, 1.0093475523f, 1.0092231706f, 1.0091020557f,
198  1.0089840804f, 1.0088691242f, 1.0087570728f, 1.0086478173f,
199  1.0085412545f, 1.0084372859f, 1.0083358181f, 1.0082367617f,
200  1.0081400320f, 1.0080455479f, 1.0079532320f, 1.0078630105f,
201  1.0077748131f, 1.0076885723f, 1.0076042238f, 1.0075217059f,
202  1.0074409597f, 1.0073619287f, 1.0072845589f, 1.0072087984f,
203  1.0071345975f, 1.0070619086f, 1.0069906859f, 1.0069208854f,
204  1.0068524651f, 1.0067853844f, 1.0067196043f, 1.0066550873f,
205  1.0065917975f, 1.0065297001f, 1.0064687617f, 1.0064089503f,
206  1.0063502348f, 1.0062925853f, 1.0062359732f, 1.0061803706f,
207  1.0061257508f, 1.0060720880f, 1.0060193572f, 1.0059675344f,
208  1.0059165963f, 1.0058665204f, 1.0058172851f, 1.0057688693f,
209  1.0057212528f, 1.0056744159f, 1.0056283396f, 1.0055830056f,
210  1.0055383960f, 1.0054944937f, 1.0054512819f, 1.0054087445f
211  };
212 
213  if (d <= 128)
214  return c_gamma[d-1];
215  else
216  {
217  // use Newton-Raphson
218  double x = 1.0f;
219  for (uint32 i = 0; i < 20; ++i)
220  x = x - (pow(x,double(d+1))-x-1.f) / (double(d+1)*pow(x,double(d))-1.f);
221  return float(x);
222  }
223  }
224 
225  unsigned int m_dim;
226  unsigned int m_i;
227  float m_gamma;
228  float m_alpha;
229  float m_seed;
230 };
231 
235 } // namespace cugar
CUGAR_HOST_DEVICE CUGAR_FORCEINLINE void set_instance(unsigned int i)
Definition: weyl.h:158
CUGAR_HOST_DEVICE CUGAR_FORCEINLINE float next()
Definition: weyl.h:78
float CUGAR_HOST_DEVICE mod(const float x, const float m)
Definition: numbers.h:606
CUGAR_HOST_DEVICE CUGAR_FORCEINLINE Weyl_sampler()
Definition: weyl.h:58
Definition: weyl.h:103
CUGAR_HOST_DEVICE CUGAR_FORCEINLINE unsigned int next_instance()
Definition: weyl.h:141
CUGAR_HOST_DEVICE CUGAR_FORCEINLINE Weyl_sampler(unsigned int instance, unsigned int seed=1)
Definition: weyl.h:64
CUGAR_HOST_DEVICE CUGAR_FORCEINLINE float next()
Definition: weyl.h:137
Define a vector_view POD type and plain_view() for std::vector.
Definition: diff.h:38
CUGAR_HOST_DEVICE CUGAR_FORCEINLINE float sample()
Definition: weyl.h:68
CUGAR_HOST_DEVICE CUGAR_FORCEINLINE Weyl_sampler_opt(unsigned int n_dims=1, unsigned int instance=0, float seed=0.0f)
Definition: weyl.h:111
CUGAR_HOST_DEVICE CUGAR_FORCEINLINE void set_dim(unsigned int d)
Definition: weyl.h:162
CUGAR_HOST_DEVICE CUGAR_FORCEINLINE float sample()
Definition: weyl.h:119
CUGAR_HOST_DEVICE CUGAR_FORCEINLINE unsigned int next_dim()
Definition: weyl.h:145