OSDN Git Service

CUDA
[eos/hostdependX86LINUX64.git] / util / X86LINUX64 / cuda-6.5 / include / curand_normal.h
1
2  /* Copyright 2010-2014 NVIDIA Corporation.  All rights reserved.
3   *
4   * NOTICE TO LICENSEE:
5   *
6   * The source code and/or documentation ("Licensed Deliverables") are
7   * subject to NVIDIA intellectual property rights under U.S. and
8   * international Copyright laws.
9   *
10   * The Licensed Deliverables contained herein are PROPRIETARY and
11   * CONFIDENTIAL to NVIDIA and are being provided under the terms and
12   * conditions of a form of NVIDIA software license agreement by and
13   * between NVIDIA and Licensee ("License Agreement") or electronically
14   * accepted by Licensee.  Notwithstanding any terms or conditions to
15   * the contrary in the License Agreement, reproduction or disclosure
16   * of the Licensed Deliverables to any third party without the express
17   * written consent of NVIDIA is prohibited.
18   *
19   * NOTWITHSTANDING ANY TERMS OR CONDITIONS TO THE CONTRARY IN THE
20   * LICENSE AGREEMENT, NVIDIA MAKES NO REPRESENTATION ABOUT THE
21   * SUITABILITY OF THESE LICENSED DELIVERABLES FOR ANY PURPOSE.  THEY ARE
22   * PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.
23   * NVIDIA DISCLAIMS ALL WARRANTIES WITH REGARD TO THESE LICENSED
24   * DELIVERABLES, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY,
25   * NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE.
26   * NOTWITHSTANDING ANY TERMS OR CONDITIONS TO THE CONTRARY IN THE
27   * LICENSE AGREEMENT, IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY
28   * SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY
29   * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
30   * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
31   * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
32   * OF THESE LICENSED DELIVERABLES.
33   *
34   * U.S. Government End Users.  These Licensed Deliverables are a
35   * "commercial item" as that term is defined at 48 C.F.R. 2.101 (OCT
36   * 1995), consisting of "commercial computer software" and "commercial
37   * computer software documentation" as such terms are used in 48
38   * C.F.R. 12.212 (SEPT 1995) and are provided to the U.S. Government
39   * only as a commercial end item.  Consistent with 48 C.F.R.12.212 and
40   * 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), all
41   * U.S. Government End Users acquire the Licensed Deliverables with
42   * only those rights set forth herein.
43   *
44   * Any use of the Licensed Deliverables in individual and commercial
45   * software must include, in the user documentation and internal
46   * comments to the code, the above Disclaimer and U.S. Government End
47   * Users Notice.
48   */
49
50
51 #if !defined(CURAND_NORMAL_H_)
52 #define CURAND_NORMAL_H_
53
54 /**
55  * \defgroup DEVICE Device API
56  *
57  * @{
58  */
59
60 #include "curand_mrg32k3a.h"
61 #include "curand_mtgp32_kernel.h"
62 #include <math.h>
63
64 #include "curand_philox4x32_x.h" 
65 #include "curand_normal_static.h"
66
67 QUALIFIERS float2 _curand_box_muller(unsigned int x, unsigned int y)
68 {
69     float2 result;
70     float u = x * CURAND_2POW32_INV + (CURAND_2POW32_INV/2);
71     float v = y * CURAND_2POW32_INV_2PI + (CURAND_2POW32_INV_2PI/2);
72 #if __CUDA_ARCH__ > 0
73     float s = sqrtf(-2.0f * logf(u));
74     __sincosf(v, &result.x, &result.y);
75 #else
76     float s = sqrtf(-2.0f * logf(u));
77     result.x = sinf(v);
78     result.y = cosf(v);
79 #endif
80     result.x *= s;
81     result.y *= s; 
82     return result;
83 }
84
85 QUALIFIERS float2 curand_box_muller_mrg(curandStateMRG32k3a_t * state)
86 {        
87     float x, y;
88     x = curand_uniform(state);
89     y = curand_uniform(state) * CURAND_2PI;
90     float2 result;
91 #if __CUDA_ARCH__ > 0
92     float s = sqrtf(-2.0f * logf(x));
93     __sincosf(y, &result.x, &result.y);
94 #else
95     float s = sqrtf(-2.0f * logf(x));
96     result.x = sinf(y);
97     result.y = cosf(y);
98 #endif
99     result.x *= s;
100     result.y *= s;
101     return result;
102 }
103
104 QUALIFIERS double2 
105 _curand_box_muller_double(unsigned int x0, unsigned int x1, 
106                           unsigned int y0, unsigned int y1)
107 {
108     double2 result;
109     unsigned long long zx = (unsigned long long)x0 ^ 
110         ((unsigned long long)x1 << (53 - 32));
111     double u = zx * CURAND_2POW53_INV_DOUBLE + (CURAND_2POW53_INV_DOUBLE/2.0);
112     unsigned long long zy = (unsigned long long)y0 ^ 
113         ((unsigned long long)y1 << (53 - 32));
114     double v = zy * (CURAND_2POW53_INV_DOUBLE*2.0) + CURAND_2POW53_INV_DOUBLE;
115     double s = sqrt(-2.0 * log(u));
116     
117 #if __CUDA_ARCH__ > 0
118     sincospi(v, &result.x, &result.y);
119 #else 
120     result.x = sin(v*CURAND_PI_DOUBLE);
121     result.y = cos(v*CURAND_PI_DOUBLE);
122 #endif    
123     result.x *= s;
124     result.y *= s;
125
126     return result;
127 }
128
129 QUALIFIERS double2 
130 curand_box_muller_mrg_double(curandStateMRG32k3a_t * state) 
131 {
132     double x, y;
133     double2 result;    
134     x = curand_uniform_double(state);
135     y = curand_uniform_double(state) * 2.0;
136
137     double s = sqrt(-2.0 * log(x));
138 #if __CUDA_ARCH__ > 0
139     sincospi(y, &result.x, &result.y);
140 #else
141     result.x = sin(y*CURAND_PI_DOUBLE);
142     result.y = cos(y*CURAND_PI_DOUBLE);
143 #endif   
144     result.x *= s;
145     result.y *= s;
146     return result;
147 }
148
149 template <typename R>
150 QUALIFIERS float2 curand_box_muller(R *state)
151 {
152     float2 result;
153     unsigned int x = curand(state);
154     unsigned int y = curand(state);
155     result = _curand_box_muller(x, y);
156     return result;
157 }
158
159 template <typename R>
160 QUALIFIERS float4 curand_box_muller4(R *state)
161 {
162     float4 result;
163     float2 _result;
164     uint4 x = curand4(state);
165     //unsigned int y = curand(state);
166     _result = _curand_box_muller(x.x, x.y);
167     result.x = _result.x;
168     result.y = _result.y;
169     _result = _curand_box_muller(x.z, x.w);
170     result.z = _result.x;
171     result.w = _result.y;
172     return result;
173 }
174
175 template <typename R>
176 QUALIFIERS double2 curand_box_muller_double(R *state)
177 {
178     double2 result;
179     unsigned int x0 = curand(state);
180     unsigned int x1 = curand(state);
181     unsigned int y0 = curand(state);
182     unsigned int y1 = curand(state);
183     result = _curand_box_muller_double(x0, x1, y0, y1);
184     return result;
185 }
186
187 template <typename R>
188 QUALIFIERS double2 curand_box_muller2_double(R *state)
189 {
190     double2 result;
191     uint4 _x;
192     _x = curand4(state);
193     result = _curand_box_muller_double(_x.x, _x.y, _x.z, _x.w);
194     return result;
195 }
196
197
198 template <typename R>
199 QUALIFIERS double4 curand_box_muller4_double(R *state)
200 {
201     double4 result;
202     double2 _res1;
203     double2 _res2;
204     uint4 _x;
205     uint4 _y;
206     _x = curand4(state);
207     _y = curand4(state);
208     _res1 = _curand_box_muller_double(_x.x, _x.y, _x.z, _x.w);
209     _res2 = _curand_box_muller_double(_y.x, _y.y, _y.z, _y.w);
210     result.x = _res1.x;
211     result.y = _res1.y;
212     result.z = _res2.x;
213     result.w = _res2.y;
214     return result;
215 }
216
217 //QUALIFIERS float _curand_normal_icdf(unsigned int x)
218 //{
219 //#if __CUDA_ARCH__ > 0 || defined(HOST_HAVE_ERFCINVF)
220 //    float s = CURAND_SQRT2;
221 //    // Mirror to avoid loss of precision
222 //    if(x > 0x80000000UL) {
223 //        x = 0xffffffffUL - x;
224 //        s = -s;
225 //    }
226 //    float p = x * CURAND_2POW32_INV + (CURAND_2POW32_INV/2.0f);
227 //    // p is in (0, 0.5], 2p is in (0, 1]
228 //    return s * erfcinvf(2.0f * p);
229 //#else
230 //    x++;    //suppress warnings
231 //    return 0.0f;
232 //#endif
233 //}
234 //
235 //QUALIFIERS float _curand_normal_icdf(unsigned long long x)
236 //{
237 //#if __CUDA_ARCH__ > 0 || defined(HOST_HAVE_ERFCINVF)
238 //    unsigned int t = (unsigned int)(x >> 32);
239 //    float s = CURAND_SQRT2;
240 //    // Mirror to avoid loss of precision
241 //    if(t > 0x80000000UL) {
242 //        t = 0xffffffffUL - t;
243 //        s = -s;
244 //    }
245 //    float p = t * CURAND_2POW32_INV + (CURAND_2POW32_INV/2.0f);
246 //    // p is in (0, 0.5], 2p is in (0, 1]
247 //    return s * erfcinvf(2.0f * p);
248 //#else
249 //    x++;
250 //    return 0.0f;
251 //#endif
252 //}
253 //
254 //QUALIFIERS double _curand_normal_icdf_double(unsigned int x)
255 //{
256 //#if __CUDA_ARCH__ > 0 || defined(HOST_HAVE_ERFCINVF)
257 //    double s = CURAND_SQRT2_DOUBLE;
258 //    // Mirror to avoid loss of precision
259 //    if(x > 0x80000000UL) {
260 //        x = 0xffffffffUL - x;
261 //        s = -s;
262 //    }
263 //    double p = x * CURAND_2POW32_INV_DOUBLE + (CURAND_2POW32_INV_DOUBLE/2.0);
264 //    // p is in (0, 0.5], 2p is in (0, 1]
265 //    return s * erfcinv(2.0 * p);
266 //#else
267 //    x++;
268 //    return 0.0;
269 //#endif
270 //}
271 //
272 //QUALIFIERS double _curand_normal_icdf_double(unsigned long long x)
273 //{
274 //#if __CUDA_ARCH__ > 0 || defined(HOST_HAVE_ERFCINVF)
275 //    double s = CURAND_SQRT2_DOUBLE;
276 //    x >>= 11;
277 //    // Mirror to avoid loss of precision
278 //    if(x > 0x10000000000000UL) {
279 //        x = 0x1fffffffffffffUL - x;
280 //        s = -s;
281 //    }
282 //    double p = x * CURAND_2POW53_INV_DOUBLE + (CURAND_2POW53_INV_DOUBLE/2.0);
283 //    // p is in (0, 0.5], 2p is in (0, 1]
284 //    return s * erfcinv(2.0 * p);
285 //#else
286 //    x++;
287 //    return 0.0;
288 //#endif
289 //}
290 // 
291
292 /**
293  * \brief Return a normally distributed float from an XORWOW generator.
294  *
295  * Return a single normally distributed float with mean \p 0.0f and
296  * standard deviation \p 1.0f from the XORWOW generator in \p state,
297  * increment position of generator by one.
298  *
299  * The implementation uses a Box-Muller transform to generate two
300  * normally distributed results, then returns them one at a time.
301  * See ::curand_normal2() for a more efficient version that returns
302  * both results at once.
303  *
304  * \param state - Pointer to state to update
305  *
306  * \return Normally distributed float with mean \p 0.0f and standard deviation \p 1.0f
307  */
308 QUALIFIERS float curand_normal(curandStateXORWOW_t *state)
309 {
310     if(state->boxmuller_flag != EXTRA_FLAG_NORMAL) {
311         unsigned int x, y;
312         x = curand(state);
313         y = curand(state);
314         float2 v = _curand_box_muller(x, y);
315         state->boxmuller_extra = v.y;
316         state->boxmuller_flag = EXTRA_FLAG_NORMAL;
317         return v.x;
318     }
319     state->boxmuller_flag = 0;
320     return state->boxmuller_extra;
321 }
322
323 /**
324  * \brief Return a normally distributed float from an Philox4_32_10 generator.
325  *
326  * Return a single normally distributed float with mean \p 0.0f and
327  * standard deviation \p 1.0f from the Philox4_32_10 generator in \p state,
328  * increment position of generator by one.
329  *
330  * The implementation uses a Box-Muller transform to generate two
331  * normally distributed results, then returns them one at a time.
332  * See ::curand_normal2() for a more efficient version that returns
333  * both results at once.
334  *
335  * \param state - Pointer to state to update
336  *
337  * \return Normally distributed float with mean \p 0.0f and standard deviation \p 1.0f
338  */
339
340 QUALIFIERS float curand_normal(curandStatePhilox4_32_10_t *state)
341 {
342     if(state->boxmuller_flag != EXTRA_FLAG_NORMAL) {
343         unsigned int x, y;
344         x = curand(state);
345         y = curand(state);
346         float2 v = _curand_box_muller(x, y);
347         state->boxmuller_extra = v.y;
348         state->boxmuller_flag = EXTRA_FLAG_NORMAL;
349         return v.x;
350     }
351     state->boxmuller_flag = 0;
352     return state->boxmuller_extra;
353 }
354
355
356
357 /**
358  * \brief Return a normally distributed float from an MRG32k3a generator.
359  *
360  * Return a single normally distributed float with mean \p 0.0f and
361  * standard deviation \p 1.0f from the MRG32k3a generator in \p state,
362  * increment position of generator by one.
363  *
364  * The implementation uses a Box-Muller transform to generate two
365  * normally distributed results, then returns them one at a time.
366  * See ::curand_normal2() for a more efficient version that returns
367  * both results at once.
368  *
369  * \param state - Pointer to state to update
370  *
371  * \return Normally distributed float with mean \p 0.0f and standard deviation \p 1.0f
372  */
373 QUALIFIERS float curand_normal(curandStateMRG32k3a_t *state)
374 {
375     if(state->boxmuller_flag != EXTRA_FLAG_NORMAL) {
376         float2 v = curand_box_muller_mrg(state);
377         state->boxmuller_extra = v.y;
378         state->boxmuller_flag = EXTRA_FLAG_NORMAL;
379         return v.x;
380     }
381     state->boxmuller_flag = 0;
382     return state->boxmuller_extra;
383 }
384
385 /**
386  * \brief Return two normally distributed floats from an XORWOW generator.
387  *
388  * Return two normally distributed floats with mean \p 0.0f and
389  * standard deviation \p 1.0f from the XORWOW generator in \p state,
390  * increment position of generator by two.
391  *
392  * The implementation uses a Box-Muller transform to generate two
393  * normally distributed results.
394  *
395  * \param state - Pointer to state to update
396  *
397  * \return Normally distributed float2 where each element is from a
398  * distribution with mean \p 0.0f and standard deviation \p 1.0f
399  */
400 QUALIFIERS float2 curand_normal2(curandStateXORWOW_t *state)
401 {
402     return curand_box_muller(state);
403 }
404 /**
405  * \brief Return two normally distributed floats from an Philox4_32_10 generator.
406  *
407  * Return two normally distributed floats with mean \p 0.0f and
408  * standard deviation \p 1.0f from the Philox4_32_10 generator in \p state,
409  * increment position of generator by two.
410  *
411  * The implementation uses a Box-Muller transform to generate two
412  * normally distributed results.
413  *
414  * \param state - Pointer to state to update
415  *
416  * \return Normally distributed float2 where each element is from a
417  * distribution with mean \p 0.0f and standard deviation \p 1.0f
418  */
419 QUALIFIERS float2 curand_normal2(curandStatePhilox4_32_10_t *state)
420 {
421     return curand_box_muller(state);
422 }
423
424 /**
425  * \brief Return four normally distributed floats from an Philox4_32_10 generator.
426  *
427  * Return four normally distributed floats with mean \p 0.0f and
428  * standard deviation \p 1.0f from the Philox4_32_10 generator in \p state,
429  * increment position of generator by four.
430  *
431  * The implementation uses a Box-Muller transform to generate two
432  * normally distributed results.
433  *
434  * \param state - Pointer to state to update
435  *
436  * \return Normally distributed float2 where each element is from a
437  * distribution with mean \p 0.0f and standard deviation \p 1.0f
438  */
439 QUALIFIERS float4 curand_normal4(curandStatePhilox4_32_10_t *state)
440 {
441     return curand_box_muller4(state);
442 }
443
444
445
446 /**
447  * \brief Return two normally distributed floats from an MRG32k3a generator.
448  *
449  * Return two normally distributed floats with mean \p 0.0f and
450  * standard deviation \p 1.0f from the MRG32k3a generator in \p state,
451  * increment position of generator by two.
452  *
453  * The implementation uses a Box-Muller transform to generate two
454  * normally distributed results.
455  *
456  * \param state - Pointer to state to update
457  *
458  * \return Normally distributed float2 where each element is from a
459  * distribution with mean \p 0.0f and standard deviation \p 1.0f
460  */
461 QUALIFIERS float2 curand_normal2(curandStateMRG32k3a_t *state)
462 {
463     return curand_box_muller_mrg(state);
464 }
465
466 /**
467  * \brief Return a normally distributed float from a MTGP32 generator.
468  *
469  * Return a single normally distributed float with mean \p 0.0f and
470  * standard deviation \p 1.0f from the MTGP32 generator in \p state,
471  * increment position of generator.
472  *
473  * The implementation uses the inverse cumulative distribution function
474  * to generate normally distributed results.
475  *
476  * \param state - Pointer to state to update
477  *
478  * \return Normally distributed float with mean \p 0.0f and standard deviation \p 1.0f
479  */
480 QUALIFIERS float curand_normal(curandStateMtgp32_t *state)
481 {
482     return _curand_normal_icdf(curand(state));
483 }
484 /**
485  * \brief Return a normally distributed float from a Sobol32 generator.
486  *
487  * Return a single normally distributed float with mean \p 0.0f and
488  * standard deviation \p 1.0f from the Sobol32 generator in \p state,
489  * increment position of generator by one.
490  *
491  * The implementation uses the inverse cumulative distribution function
492  * to generate normally distributed results.
493  *
494  * \param state - Pointer to state to update
495  *
496  * \return Normally distributed float with mean \p 0.0f and standard deviation \p 1.0f
497  */
498 QUALIFIERS float curand_normal(curandStateSobol32_t *state)
499 {
500     return _curand_normal_icdf(curand(state));
501 }
502
503 /**
504  * \brief Return a normally distributed float from a scrambled Sobol32 generator.
505  *
506  * Return a single normally distributed float with mean \p 0.0f and
507  * standard deviation \p 1.0f from the scrambled Sobol32 generator in \p state,
508  * increment position of generator by one.
509  *
510  * The implementation uses the inverse cumulative distribution function
511  * to generate normally distributed results.
512  *
513  * \param state - Pointer to state to update
514  *
515  * \return Normally distributed float with mean \p 0.0f and standard deviation \p 1.0f
516  */
517 QUALIFIERS float curand_normal(curandStateScrambledSobol32_t *state)
518 {
519     return _curand_normal_icdf(curand(state));
520 }
521
522 /**
523  * \brief Return a normally distributed float from a Sobol64 generator.
524  *
525  * Return a single normally distributed float with mean \p 0.0f and
526  * standard deviation \p 1.0f from the Sobol64 generator in \p state,
527  * increment position of generator by one.
528  *
529  * The implementation uses the inverse cumulative distribution function
530  * to generate normally distributed results.
531  *
532  * \param state - Pointer to state to update
533  *
534  * \return Normally distributed float with mean \p 0.0f and standard deviation \p 1.0f
535  */
536 QUALIFIERS float curand_normal(curandStateSobol64_t *state)
537 {
538     return _curand_normal_icdf(curand(state));
539 }
540
541 /**
542  * \brief Return a normally distributed float from a scrambled Sobol64 generator.
543  *
544  * Return a single normally distributed float with mean \p 0.0f and
545  * standard deviation \p 1.0f from the scrambled Sobol64 generator in \p state,
546  * increment position of generator by one.
547  *
548  * The implementation uses the inverse cumulative distribution function
549  * to generate normally distributed results.
550  *
551  * \param state - Pointer to state to update
552  *
553  * \return Normally distributed float with mean \p 0.0f and standard deviation \p 1.0f
554  */
555 QUALIFIERS float curand_normal(curandStateScrambledSobol64_t *state)
556 {
557     return _curand_normal_icdf(curand(state));
558 }
559
560 /**
561  * \brief Return a normally distributed double from an XORWOW generator.
562  *
563  * Return a single normally distributed double with mean \p 0.0 and
564  * standard deviation \p 1.0 from the XORWOW generator in \p state,
565  * increment position of generator.
566  *
567  * The implementation uses a Box-Muller transform to generate two
568  * normally distributed results, then returns them one at a time.
569  * See ::curand_normal2_double() for a more efficient version that returns
570  * both results at once.
571  *
572  * \param state - Pointer to state to update
573  *
574  * \return Normally distributed double with mean \p 0.0 and standard deviation \p 1.0
575  */
576 QUALIFIERS double curand_normal_double(curandStateXORWOW_t *state)
577 {
578     if(state->boxmuller_flag_double != EXTRA_FLAG_NORMAL) {
579         unsigned int x0, x1, y0, y1;
580         x0 = curand(state);
581         x1 = curand(state);
582         y0 = curand(state);
583         y1 = curand(state);
584         double2 v = _curand_box_muller_double(x0, x1, y0, y1);
585         state->boxmuller_extra_double = v.y;
586         state->boxmuller_flag_double = EXTRA_FLAG_NORMAL;
587         return v.x;
588     }
589     state->boxmuller_flag_double = 0;
590     return state->boxmuller_extra_double;
591 }
592
593 /**
594  * \brief Return a normally distributed double from an Philox4_32_10 generator.
595  *
596  * Return a single normally distributed double with mean \p 0.0 and
597  * standard deviation \p 1.0 from the Philox4_32_10 generator in \p state,
598  * increment position of generator.
599  *
600  * The implementation uses a Box-Muller transform to generate two
601  * normally distributed results, then returns them one at a time.
602  * See ::curand_normal2_double() for a more efficient version that returns
603  * both results at once.
604  *
605  * \param state - Pointer to state to update
606  *
607  * \return Normally distributed double with mean \p 0.0 and standard deviation \p 1.0
608  */
609
610 QUALIFIERS double curand_normal_double(curandStatePhilox4_32_10_t *state)
611 {
612     if(state->boxmuller_flag_double != EXTRA_FLAG_NORMAL) {
613         uint4 _x;
614         _x = curand4(state);
615         double2 v = _curand_box_muller_double(_x.x, _x.y, _x.z, _x.w);
616         state->boxmuller_extra_double = v.y;
617         state->boxmuller_flag_double = EXTRA_FLAG_NORMAL;
618         return v.x;
619     }
620     state->boxmuller_flag_double = 0;
621     return state->boxmuller_extra_double;
622 }
623
624
625 /**
626  * \brief Return a normally distributed double from an MRG32k3a generator.
627  *
628  * Return a single normally distributed double with mean \p 0.0 and
629  * standard deviation \p 1.0 from the XORWOW generator in \p state,
630  * increment position of generator.
631  *
632  * The implementation uses a Box-Muller transform to generate two
633  * normally distributed results, then returns them one at a time.
634  * See ::curand_normal2_double() for a more efficient version that returns
635  * both results at once.
636  *
637  * \param state - Pointer to state to update
638  *
639  * \return Normally distributed double with mean \p 0.0 and standard deviation \p 1.0
640  */
641 QUALIFIERS double curand_normal_double(curandStateMRG32k3a_t *state)
642 {
643     if(state->boxmuller_flag_double != EXTRA_FLAG_NORMAL) {
644         double2 v = curand_box_muller_mrg_double(state);
645         state->boxmuller_extra_double = v.y;
646         state->boxmuller_flag_double = EXTRA_FLAG_NORMAL;
647         return v.x;
648     }
649     state->boxmuller_flag_double = 0;
650     return state->boxmuller_extra_double;
651 }
652
653 /**
654  * \brief Return two normally distributed doubles from an XORWOW generator.
655  *
656  * Return two normally distributed doubles with mean \p 0.0 and
657  * standard deviation \p 1.0 from the XORWOW generator in \p state,
658  * increment position of generator by 2.
659  *
660  * The implementation uses a Box-Muller transform to generate two
661  * normally distributed results.
662  *
663  * \param state - Pointer to state to update
664  *
665  * \return Normally distributed double2 where each element is from a
666  * distribution with mean \p 0.0 and standard deviation \p 1.0
667  */
668 QUALIFIERS double2 curand_normal2_double(curandStateXORWOW_t *state)
669 {
670     return curand_box_muller_double(state);
671 }
672
673 /**
674  * \brief Return two normally distributed doubles from an Philox4_32_10 generator.
675  *
676  * Return two normally distributed doubles with mean \p 0.0 and
677  * standard deviation \p 1.0 from the Philox4_32_10 generator in \p state,
678  * increment position of generator by 2.
679  *
680  * The implementation uses a Box-Muller transform to generate two
681  * normally distributed results.
682  *
683  * \param state - Pointer to state to update
684  *
685  * \return Normally distributed double2 where each element is from a
686  * distribution with mean \p 0.0 and standard deviation \p 1.0
687  */
688 QUALIFIERS double2 curand_normal2_double(curandStatePhilox4_32_10_t *state)
689 {
690     uint4 _x;
691     double2 result;
692
693     _x = curand4(state);
694     double2 v1 = _curand_box_muller_double(_x.x, _x.y, _x.z, _x.w);
695     result.x = v1.x;
696     result.y = v1.y;
697
698     return result;
699 }
700
701  // not a part of API
702 QUALIFIERS double4 curand_normal4_double(curandStatePhilox4_32_10_t *state)
703 {
704     uint4 _x;
705     uint4 _y;
706     double4 result;
707
708     _x = curand4(state);
709     _y = curand4(state);
710     double2 v1 = _curand_box_muller_double(_x.x, _x.y, _x.z, _x.w);
711     double2 v2 = _curand_box_muller_double(_y.x, _y.y, _y.z, _y.w);
712     result.x = v1.x;
713     result.y = v1.y;
714     result.z = v2.x;
715     result.w = v2.y;
716
717     return result;
718 }
719
720
721 /**
722  * \brief Return two normally distributed doubles from an MRG32k3a generator.
723  *
724  * Return two normally distributed doubles with mean \p 0.0 and
725  * standard deviation \p 1.0 from the MRG32k3a generator in \p state,
726  * increment position of generator.
727  *
728  * The implementation uses a Box-Muller transform to generate two
729  * normally distributed results.
730  *
731  * \param state - Pointer to state to update
732  *
733  * \return Normally distributed double2 where each element is from a
734  * distribution with mean \p 0.0 and standard deviation \p 1.0
735  */
736 QUALIFIERS double2 curand_normal2_double(curandStateMRG32k3a_t *state)
737 {
738     return curand_box_muller_mrg_double(state);
739 }
740
741 /**
742  * \brief Return a normally distributed double from an MTGP32 generator.
743  *
744  * Return a single normally distributed double with mean \p 0.0 and
745  * standard deviation \p 1.0 from the MTGP32 generator in \p state,
746  * increment position of generator.
747  *
748  * The implementation uses the inverse cumulative distribution function
749  * to generate normally distributed results.
750  *
751  * \param state - Pointer to state to update
752  *
753  * \return Normally distributed double with mean \p 0.0 and standard deviation \p 1.0
754  */
755 QUALIFIERS double curand_normal_double(curandStateMtgp32_t *state)
756 {
757     return _curand_normal_icdf_double(curand(state));
758 }
759
760 /**
761  * \brief Return a normally distributed double from an Sobol32 generator.
762  *
763  * Return a single normally distributed double with mean \p 0.0 and
764  * standard deviation \p 1.0 from the Sobol32 generator in \p state,
765  * increment position of generator by one.
766  *
767  * The implementation uses the inverse cumulative distribution function
768  * to generate normally distributed results.
769  *
770  * \param state - Pointer to state to update
771  *
772  * \return Normally distributed double with mean \p 0.0 and standard deviation \p 1.0
773  */
774 QUALIFIERS double curand_normal_double(curandStateSobol32_t *state)
775 {
776     return _curand_normal_icdf_double(curand(state));
777 }
778
779 /**
780  * \brief Return a normally distributed double from a scrambled Sobol32 generator.
781  *
782  * Return a single normally distributed double with mean \p 0.0 and
783  * standard deviation \p 1.0 from the scrambled Sobol32 generator in \p state,
784  * increment position of generator by one.
785  *
786  * The implementation uses the inverse cumulative distribution function
787  * to generate normally distributed results.
788  *
789  * \param state - Pointer to state to update
790  *
791  * \return Normally distributed double with mean \p 0.0 and standard deviation \p 1.0
792  */
793 QUALIFIERS double curand_normal_double(curandStateScrambledSobol32_t *state)
794 {
795     return _curand_normal_icdf_double(curand(state));
796 }
797
798 /**
799  * \brief Return a normally distributed double from a Sobol64 generator.
800  *
801  * Return a single normally distributed double with mean \p 0.0 and
802  * standard deviation \p 1.0 from the Sobol64 generator in \p state,
803  * increment position of generator by one.
804  *
805  * The implementation uses the inverse cumulative distribution function
806  * to generate normally distributed results.
807  *
808  * \param state - Pointer to state to update
809  *
810  * \return Normally distributed double with mean \p 0.0 and standard deviation \p 1.0
811  */
812 QUALIFIERS double curand_normal_double(curandStateSobol64_t *state)
813 {
814     return _curand_normal_icdf_double(curand(state));
815 }
816
817 /**
818  * \brief Return a normally distributed double from a scrambled Sobol64 generator.
819  *
820  * Return a single normally distributed double with mean \p 0.0 and
821  * standard deviation \p 1.0 from the scrambled Sobol64 generator in \p state,
822  * increment position of generator by one.
823  *
824  * The implementation uses the inverse cumulative distribution function
825  * to generate normally distributed results.
826  *
827  * \param state - Pointer to state to update
828  *
829  * \return Normally distributed double with mean \p 0.0 and standard deviation \p 1.0
830  */
831 QUALIFIERS double curand_normal_double(curandStateScrambledSobol64_t *state)
832 {
833     return _curand_normal_icdf_double(curand(state));
834 }
835 #endif // !defined(CURAND_NORMAL_H_)