codekingpro/portable-devtools
114k
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#ifndef __CUDACC_RTC__
61#include <math.h>
62#endif // __CUDACC_RTC__
63#include <nv/target>
64
65#include "curand_mrg32k3a.h"
66#include "curand_mtgp32_kernel.h"
67#include "curand_philox4x32_x.h"
68#include "curand_normal_static.h"
69
70QUALIFIERS float2 _curand_box_muller(unsigned int x, unsigned int y)
71{
72 float2 result;
73 float u = x * CURAND_2POW32_INV + (CURAND_2POW32_INV/2);
74 float v = y * CURAND_2POW32_INV_2PI + (CURAND_2POW32_INV_2PI/2);
75 float s;
76NV_IF_ELSE_TARGET(NV_IS_DEVICE,
77 s = sqrtf(-2.0f * logf(u));
78 __sincosf(v, &result.x, &result.y);
79,
80 s = sqrtf(-2.0f * logf(u));
81 result.x = sinf(v);
82 result.y = cosf(v);
83)
84 result.x *= s;
85 result.y *= s;
86 return result;
87}
88
89QUALIFIERS float2 curand_box_muller_mrg(curandStateMRG32k3a_t * state)
90{
91 float x, y;
92 x = curand_uniform(state);
93 y = curand_uniform(state) * CURAND_2PI;
94 float2 result;
95 float s;
96NV_IF_ELSE_TARGET(NV_IS_DEVICE,
97 s = sqrtf(-2.0f * logf(x));
98 __sincosf(y, &result.x, &result.y);
99,
100 s = sqrtf(-2.0f * logf(x));
101 result.x = sinf(y);
102 result.y = cosf(y);
103)
104 result.x *= s;
105 result.y *= s;
106 return result;
107}
108
109QUALIFIERS double2
110_curand_box_muller_double(unsigned int x0, unsigned int x1,
111 unsigned int y0, unsigned int y1)
112{
113 double2 result;
114 unsigned long long zx = (unsigned long long)x0 ^
115 ((unsigned long long)x1 << (53 - 32));
116 double u = zx * CURAND_2POW53_INV_DOUBLE + (CURAND_2POW53_INV_DOUBLE/2.0);
117 unsigned long long zy = (unsigned long long)y0 ^
118 ((unsigned long long)y1 << (53 - 32));
119 double v = zy * (CURAND_2POW53_INV_DOUBLE*2.0) + CURAND_2POW53_INV_DOUBLE;
120 double s = sqrt(-2.0 * log(u));
121
122NV_IF_ELSE_TARGET(NV_IS_DEVICE,
123 sincospi(v, &result.x, &result.y);
124,
125 result.x = sin(v*CURAND_PI_DOUBLE);
126 result.y = cos(v*CURAND_PI_DOUBLE);
127)
128 result.x *= s;
129 result.y *= s;
130
131 return result;
132}
133
134QUALIFIERS double2
135curand_box_muller_mrg_double(curandStateMRG32k3a_t * state)
136{
137 double x, y;
138 double2 result;
139 x = curand_uniform_double(state);
140 y = curand_uniform_double(state) * 2.0;
141
142 double s = sqrt(-2.0 * log(x));
143NV_IF_ELSE_TARGET(NV_IS_DEVICE,
144 sincospi(y, &result.x, &result.y);
145,
146 result.x = sin(y*CURAND_PI_DOUBLE);
147 result.y = cos(y*CURAND_PI_DOUBLE);
148)
149 result.x *= s;
150 result.y *= s;
151 return result;
152}
153
154template <typename R>
155QUALIFIERS float2 curand_box_muller(R *state)
156{
157 float2 result;
158 unsigned int x = curand(state);
159 unsigned int y = curand(state);
160 result = _curand_box_muller(x, y);
161 return result;
162}
163
164template <typename R>
165QUALIFIERS float4 curand_box_muller4(R *state)
166{
167 float4 result;
168 float2 _result;
169 uint4 x = curand4(state);
170 //unsigned int y = curand(state);
171 _result = _curand_box_muller(x.x, x.y);
172 result.x = _result.x;
173 result.y = _result.y;
174 _result = _curand_box_muller(x.z, x.w);
175 result.z = _result.x;
176 result.w = _result.y;
177 return result;
178}
179
180template <typename R>
181QUALIFIERS double2 curand_box_muller_double(R *state)
182{
183 double2 result;
184 unsigned int x0 = curand(state);
185 unsigned int x1 = curand(state);
186 unsigned int y0 = curand(state);
187 unsigned int y1 = curand(state);
188 result = _curand_box_muller_double(x0, x1, y0, y1);
189 return result;
190}
191
192template <typename R>
193QUALIFIERS double2 curand_box_muller2_double(R *state)
194{
195 double2 result;
196 uint4 _x;
197 _x = curand4(state);
198 result = _curand_box_muller_double(_x.x, _x.y, _x.z, _x.w);
199 return result;
200}
201
202
203template <typename R>
204QUALIFIERS double4 curand_box_muller4_double(R *state)
205{
206 double4 result;
207 double2 _res1;
208 double2 _res2;
209 uint4 _x;
210 uint4 _y;
211 _x = curand4(state);
212 _y = curand4(state);
213 _res1 = _curand_box_muller_double(_x.x, _x.y, _x.z, _x.w);
214 _res2 = _curand_box_muller_double(_y.x, _y.y, _y.z, _y.w);
215 result.x = _res1.x;
216 result.y = _res1.y;
217 result.z = _res2.x;
218 result.w = _res2.y;
219 return result;
220}
221
222//QUALIFIERS float _curand_normal_icdf(unsigned int x)
223//{
224//#if __CUDA_ARCH__ > 0 || defined(HOST_HAVE_ERFCINVF)
225// float s = CURAND_SQRT2;
226// // Mirror to avoid loss of precision
227// if(x > 0x80000000UL) {
228// x = 0xffffffffUL - x;
229// s = -s;
230// }
231// float p = x * CURAND_2POW32_INV + (CURAND_2POW32_INV/2.0f);
232// // p is in (0, 0.5], 2p is in (0, 1]
233// return s * erfcinvf(2.0f * p);
234//#else
235// x++; //suppress warnings
236// return 0.0f;
237//#endif
238//}
239//
240//QUALIFIERS float _curand_normal_icdf(unsigned long long x)
241//{
242//#if __CUDA_ARCH__ > 0 || defined(HOST_HAVE_ERFCINVF)
243// unsigned int t = (unsigned int)(x >> 32);
244// float s = CURAND_SQRT2;
245// // Mirror to avoid loss of precision
246// if(t > 0x80000000UL) {
247// t = 0xffffffffUL - t;
248// s = -s;
249// }
250// float p = t * CURAND_2POW32_INV + (CURAND_2POW32_INV/2.0f);
251// // p is in (0, 0.5], 2p is in (0, 1]
252// return s * erfcinvf(2.0f * p);
253//#else
254// x++;
255// return 0.0f;
256//#endif
257//}
258//
259//QUALIFIERS double _curand_normal_icdf_double(unsigned int x)
260//{
261//#if __CUDA_ARCH__ > 0 || defined(HOST_HAVE_ERFCINVF)
262// double s = CURAND_SQRT2_DOUBLE;
263// // Mirror to avoid loss of precision
264// if(x > 0x80000000UL) {
265// x = 0xffffffffUL - x;
266// s = -s;
267// }
268// double p = x * CURAND_2POW32_INV_DOUBLE + (CURAND_2POW32_INV_DOUBLE/2.0);
269// // p is in (0, 0.5], 2p is in (0, 1]
270// return s * erfcinv(2.0 * p);
271//#else
272// x++;
273// return 0.0;
274//#endif
275//}
276//
277//QUALIFIERS double _curand_normal_icdf_double(unsigned long long x)
278//{
279//#if __CUDA_ARCH__ > 0 || defined(HOST_HAVE_ERFCINVF)
280// double s = CURAND_SQRT2_DOUBLE;
281// x >>= 11;
282// // Mirror to avoid loss of precision
283// if(x > 0x10000000000000UL) {
284// x = 0x1fffffffffffffUL - x;
285// s = -s;
286// }
287// double p = x * CURAND_2POW53_INV_DOUBLE + (CURAND_2POW53_INV_DOUBLE/2.0);
288// // p is in (0, 0.5], 2p is in (0, 1]
289// return s * erfcinv(2.0 * p);
290//#else
291// x++;
292// return 0.0;
293//#endif
294//}
295//
296
297/**
298 * \brief Return a normally distributed float from an XORWOW generator.
299 *
300 * Return a single normally distributed float with mean \p 0.0f and
301 * standard deviation \p 1.0f from the XORWOW generator in \p state,
302 * increment position of generator by one.
303 *
304 * The implementation uses a Box-Muller transform to generate two
305 * normally distributed results, then returns them one at a time.
306 * See ::curand_normal2() for a more efficient version that returns
307 * both results at once.
308 *
309 * \param state - Pointer to state to update
310 *
311 * \return Normally distributed float with mean \p 0.0f and standard deviation \p 1.0f
312 */
313QUALIFIERS float curand_normal(curandStateXORWOW_t *state)
314{
315 if(state->boxmuller_flag != EXTRA_FLAG_NORMAL) {
316 unsigned int x, y;
317 x = curand(state);
318 y = curand(state);
319 float2 v = _curand_box_muller(x, y);
320 state->boxmuller_extra = v.y;
321 state->boxmuller_flag = EXTRA_FLAG_NORMAL;
322 return v.x;
323 }
324 state->boxmuller_flag = 0;
325 return state->boxmuller_extra;
326}
327
328/**
329 * \brief Return a normally distributed float from an Philox4_32_10 generator.
330 *
331 * Return a single normally distributed float with mean \p 0.0f and
332 * standard deviation \p 1.0f from the Philox4_32_10 generator in \p state,
333 * increment position of generator by one.
334 *
335 * The implementation uses a Box-Muller transform to generate two
336 * normally distributed results, then returns them one at a time.
337 * See ::curand_normal2() for a more efficient version that returns
338 * both results at once.
339 *
340 * \param state - Pointer to state to update
341 *
342 * \return Normally distributed float with mean \p 0.0f and standard deviation \p 1.0f
343 */
344
345QUALIFIERS float curand_normal(curandStatePhilox4_32_10_t *state)
346{
347 if(state->boxmuller_flag != EXTRA_FLAG_NORMAL) {
348 unsigned int x, y;
349 x = curand(state);
350 y = curand(state);
351 float2 v = _curand_box_muller(x, y);
352 state->boxmuller_extra = v.y;
353 state->boxmuller_flag = EXTRA_FLAG_NORMAL;
354 return v.x;
355 }
356 state->boxmuller_flag = 0;
357 return state->boxmuller_extra;
358}
359
360
361
362/**
363 * \brief Return a normally distributed float from an MRG32k3a generator.
364 *
365 * Return a single normally distributed float with mean \p 0.0f and
366 * standard deviation \p 1.0f from the MRG32k3a generator in \p state,
367 * increment position of generator by one.
368 *
369 * The implementation uses a Box-Muller transform to generate two
370 * normally distributed results, then returns them one at a time.
371 * See ::curand_normal2() for a more efficient version that returns
372 * both results at once.
373 *
374 * \param state - Pointer to state to update
375 *
376 * \return Normally distributed float with mean \p 0.0f and standard deviation \p 1.0f
377 */
378QUALIFIERS float curand_normal(curandStateMRG32k3a_t *state)
379{
380 if(state->boxmuller_flag != EXTRA_FLAG_NORMAL) {
381 float2 v = curand_box_muller_mrg(state);
382 state->boxmuller_extra = v.y;
383 state->boxmuller_flag = EXTRA_FLAG_NORMAL;
384 return v.x;
385 }
386 state->boxmuller_flag = 0;
387 return state->boxmuller_extra;
388}
389
390/**
391 * \brief Return two normally distributed floats from an XORWOW generator.
392 *
393 * Return two normally distributed floats with mean \p 0.0f and
394 * standard deviation \p 1.0f from the XORWOW generator in \p state,
395 * increment position of generator by two.
396 *
397 * The implementation uses a Box-Muller transform to generate two
398 * normally distributed results.
399 *
400 * \param state - Pointer to state to update
401 *
402 * \return Normally distributed float2 where each element is from a
403 * distribution with mean \p 0.0f and standard deviation \p 1.0f
404 */
405QUALIFIERS float2 curand_normal2(curandStateXORWOW_t *state)
406{
407 return curand_box_muller(state);
408}
409/**
410 * \brief Return two normally distributed floats from an Philox4_32_10 generator.
411 *
412 * Return two normally distributed floats with mean \p 0.0f and
413 * standard deviation \p 1.0f from the Philox4_32_10 generator in \p state,
414 * increment position of generator by two.
415 *
416 * The implementation uses a Box-Muller transform to generate two
417 * normally distributed results.
418 *
419 * \param state - Pointer to state to update
420 *
421 * \return Normally distributed float2 where each element is from a
422 * distribution with mean \p 0.0f and standard deviation \p 1.0f
423 */
424QUALIFIERS float2 curand_normal2(curandStatePhilox4_32_10_t *state)
425{
426 return curand_box_muller(state);
427}
428
429/**
430 * \brief Return four normally distributed floats from an Philox4_32_10 generator.
431 *
432 * Return four normally distributed floats with mean \p 0.0f and
433 * standard deviation \p 1.0f from the Philox4_32_10 generator in \p state,
434 * increment position of generator by four.
435 *
436 * The implementation uses a Box-Muller transform to generate two
437 * normally distributed results.
438 *
439 * \param state - Pointer to state to update
440 *
441 * \return Normally distributed float2 where each element is from a
442 * distribution with mean \p 0.0f and standard deviation \p 1.0f
443 */
444QUALIFIERS float4 curand_normal4(curandStatePhilox4_32_10_t *state)
445{
446 return curand_box_muller4(state);
447}
448
449
450
451/**
452 * \brief Return two normally distributed floats from an MRG32k3a generator.
453 *
454 * Return two normally distributed floats with mean \p 0.0f and
455 * standard deviation \p 1.0f from the MRG32k3a generator in \p state,
456 * increment position of generator by two.
457 *
458 * The implementation uses a Box-Muller transform to generate two
459 * normally distributed results.
460 *
461 * \param state - Pointer to state to update
462 *
463 * \return Normally distributed float2 where each element is from a
464 * distribution with mean \p 0.0f and standard deviation \p 1.0f
465 */
466QUALIFIERS float2 curand_normal2(curandStateMRG32k3a_t *state)
467{
468 return curand_box_muller_mrg(state);
469}
470
471/**
472 * \brief Return a normally distributed float from a MTGP32 generator.
473 *
474 * Return a single normally distributed float with mean \p 0.0f and
475 * standard deviation \p 1.0f from the MTGP32 generator in \p state,
476 * increment position of generator.
477 *
478 * The implementation uses the inverse cumulative distribution function
479 * to generate normally distributed results.
480 *
481 * \param state - Pointer to state to update
482 *
483 * \return Normally distributed float with mean \p 0.0f and standard deviation \p 1.0f
484 */
485QUALIFIERS float curand_normal(curandStateMtgp32_t *state)
486{
487 return _curand_normal_icdf(curand(state));
488}
489/**
490 * \brief Return a normally distributed float from a Sobol32 generator.
491 *
492 * Return a single normally distributed float with mean \p 0.0f and
493 * standard deviation \p 1.0f from the Sobol32 generator in \p state,
494 * increment position of generator by one.
495 *
496 * The implementation uses the inverse cumulative distribution function
497 * to generate normally distributed results.
498 *
499 * \param state - Pointer to state to update
500 *
501 * \return Normally distributed float with mean \p 0.0f and standard deviation \p 1.0f
502 */
503QUALIFIERS float curand_normal(curandStateSobol32_t *state)
504{
505 return _curand_normal_icdf(curand(state));
506}
507
508/**
509 * \brief Return a normally distributed float from a scrambled Sobol32 generator.
510 *
511 * Return a single normally distributed float with mean \p 0.0f and
512 * standard deviation \p 1.0f from the scrambled Sobol32 generator in \p state,
513 * increment position of generator by one.
514 *
515 * The implementation uses the inverse cumulative distribution function
516 * to generate normally distributed results.
517 *
518 * \param state - Pointer to state to update
519 *
520 * \return Normally distributed float with mean \p 0.0f and standard deviation \p 1.0f
521 */
522QUALIFIERS float curand_normal(curandStateScrambledSobol32_t *state)
523{
524 return _curand_normal_icdf(curand(state));
525}
526
527/**
528 * \brief Return a normally distributed float from a Sobol64 generator.
529 *
530 * Return a single normally distributed float with mean \p 0.0f and
531 * standard deviation \p 1.0f from the Sobol64 generator in \p state,
532 * increment position of generator by one.
533 *
534 * The implementation uses the inverse cumulative distribution function
535 * to generate normally distributed results.
536 *
537 * \param state - Pointer to state to update
538 *
539 * \return Normally distributed float with mean \p 0.0f and standard deviation \p 1.0f
540 */
541QUALIFIERS float curand_normal(curandStateSobol64_t *state)
542{
543 return _curand_normal_icdf(curand(state));
544}
545
546/**
547 * \brief Return a normally distributed float from a scrambled Sobol64 generator.
548 *
549 * Return a single normally distributed float with mean \p 0.0f and
550 * standard deviation \p 1.0f from the scrambled Sobol64 generator in \p state,
551 * increment position of generator by one.
552 *
553 * The implementation uses the inverse cumulative distribution function
554 * to generate normally distributed results.
555 *
556 * \param state - Pointer to state to update
557 *
558 * \return Normally distributed float with mean \p 0.0f and standard deviation \p 1.0f
559 */
560QUALIFIERS float curand_normal(curandStateScrambledSobol64_t *state)
561{
562 return _curand_normal_icdf(curand(state));
563}
564
565/**
566 * \brief Return a normally distributed double from an XORWOW generator.
567 *
568 * Return a single normally distributed double with mean \p 0.0 and
569 * standard deviation \p 1.0 from the XORWOW generator in \p state,
570 * increment position of generator.
571 *
572 * The implementation uses a Box-Muller transform to generate two
573 * normally distributed results, then returns them one at a time.
574 * See ::curand_normal2_double() for a more efficient version that returns
575 * both results at once.
576 *
577 * \param state - Pointer to state to update
578 *
579 * \return Normally distributed double with mean \p 0.0 and standard deviation \p 1.0
580 */
581QUALIFIERS double curand_normal_double(curandStateXORWOW_t *state)
582{
583 if(state->boxmuller_flag_double != EXTRA_FLAG_NORMAL) {
584 unsigned int x0, x1, y0, y1;
585 x0 = curand(state);
586 x1 = curand(state);
587 y0 = curand(state);
588 y1 = curand(state);
589 double2 v = _curand_box_muller_double(x0, x1, y0, y1);
590 state->boxmuller_extra_double = v.y;
591 state->boxmuller_flag_double = EXTRA_FLAG_NORMAL;
592 return v.x;
593 }
594 state->boxmuller_flag_double = 0;
595 return state->boxmuller_extra_double;
596}
597
598/**
599 * \brief Return a normally distributed double from an Philox4_32_10 generator.
600 *
601 * Return a single normally distributed double with mean \p 0.0 and
602 * standard deviation \p 1.0 from the Philox4_32_10 generator in \p state,
603 * increment position of generator.
604 *
605 * The implementation uses a Box-Muller transform to generate two
606 * normally distributed results, then returns them one at a time.
607 * See ::curand_normal2_double() for a more efficient version that returns
608 * both results at once.
609 *
610 * \param state - Pointer to state to update
611 *
612 * \return Normally distributed double with mean \p 0.0 and standard deviation \p 1.0
613 */
614
615QUALIFIERS double curand_normal_double(curandStatePhilox4_32_10_t *state)
616{
617 if(state->boxmuller_flag_double != EXTRA_FLAG_NORMAL) {
618 uint4 _x;
619 _x = curand4(state);
620 double2 v = _curand_box_muller_double(_x.x, _x.y, _x.z, _x.w);
621 state->boxmuller_extra_double = v.y;
622 state->boxmuller_flag_double = EXTRA_FLAG_NORMAL;
623 return v.x;
624 }
625 state->boxmuller_flag_double = 0;
626 return state->boxmuller_extra_double;
627}
628
629
630/**
631 * \brief Return a normally distributed double from an MRG32k3a generator.
632 *
633 * Return a single normally distributed double with mean \p 0.0 and
634 * standard deviation \p 1.0 from the XORWOW generator in \p state,
635 * increment position of generator.
636 *
637 * The implementation uses a Box-Muller transform to generate two
638 * normally distributed results, then returns them one at a time.
639 * See ::curand_normal2_double() for a more efficient version that returns
640 * both results at once.
641 *
642 * \param state - Pointer to state to update
643 *
644 * \return Normally distributed double with mean \p 0.0 and standard deviation \p 1.0
645 */
646QUALIFIERS double curand_normal_double(curandStateMRG32k3a_t *state)
647{
648 if(state->boxmuller_flag_double != EXTRA_FLAG_NORMAL) {
649 double2 v = curand_box_muller_mrg_double(state);
650 state->boxmuller_extra_double = v.y;
651 state->boxmuller_flag_double = EXTRA_FLAG_NORMAL;
652 return v.x;
653 }
654 state->boxmuller_flag_double = 0;
655 return state->boxmuller_extra_double;
656}
657
658/**
659 * \brief Return two normally distributed doubles from an XORWOW generator.
660 *
661 * Return two normally distributed doubles with mean \p 0.0 and
662 * standard deviation \p 1.0 from the XORWOW generator in \p state,
663 * increment position of generator by 2.
664 *
665 * The implementation uses a Box-Muller transform to generate two
666 * normally distributed results.
667 *
668 * \param state - Pointer to state to update
669 *
670 * \return Normally distributed double2 where each element is from a
671 * distribution with mean \p 0.0 and standard deviation \p 1.0
672 */
673QUALIFIERS double2 curand_normal2_double(curandStateXORWOW_t *state)
674{
675 return curand_box_muller_double(state);
676}
677
678/**
679 * \brief Return two normally distributed doubles from an Philox4_32_10 generator.
680 *
681 * Return two normally distributed doubles with mean \p 0.0 and
682 * standard deviation \p 1.0 from the Philox4_32_10 generator in \p state,
683 * increment position of generator by 2.
684 *
685 * The implementation uses a Box-Muller transform to generate two
686 * normally distributed results.
687 *
688 * \param state - Pointer to state to update
689 *
690 * \return Normally distributed double2 where each element is from a
691 * distribution with mean \p 0.0 and standard deviation \p 1.0
692 */
693QUALIFIERS double2 curand_normal2_double(curandStatePhilox4_32_10_t *state)
694{
695 uint4 _x;
696 double2 result;
697
698 _x = curand4(state);
699 double2 v1 = _curand_box_muller_double(_x.x, _x.y, _x.z, _x.w);
700 result.x = v1.x;
701 result.y = v1.y;
702
703 return result;
704}
705
706 // not a part of API
707QUALIFIERS double4 curand_normal4_double(curandStatePhilox4_32_10_t *state)
708{
709 uint4 _x;
710 uint4 _y;
711 double4 result;
712
713 _x = curand4(state);
714 _y = curand4(state);
715 double2 v1 = _curand_box_muller_double(_x.x, _x.y, _x.z, _x.w);
716 double2 v2 = _curand_box_muller_double(_y.x, _y.y, _y.z, _y.w);
717 result.x = v1.x;
718 result.y = v1.y;
719 result.z = v2.x;
720 result.w = v2.y;
721
722 return result;
723}
724
725
726/**
727 * \brief Return two normally distributed doubles from an MRG32k3a generator.
728 *
729 * Return two normally distributed doubles with mean \p 0.0 and
730 * standard deviation \p 1.0 from the MRG32k3a generator in \p state,
731 * increment position of generator.
732 *
733 * The implementation uses a Box-Muller transform to generate two
734 * normally distributed results.
735 *
736 * \param state - Pointer to state to update
737 *
738 * \return Normally distributed double2 where each element is from a
739 * distribution with mean \p 0.0 and standard deviation \p 1.0
740 */
741QUALIFIERS double2 curand_normal2_double(curandStateMRG32k3a_t *state)
742{
743 return curand_box_muller_mrg_double(state);
744}
745
746/**
747 * \brief Return a normally distributed double from an MTGP32 generator.
748 *
749 * Return a single normally distributed double with mean \p 0.0 and
750 * standard deviation \p 1.0 from the MTGP32 generator in \p state,
751 * increment position of generator.
752 *
753 * The implementation uses the inverse cumulative distribution function
754 * to generate normally distributed results.
755 *
756 * \param state - Pointer to state to update
757 *
758 * \return Normally distributed double with mean \p 0.0 and standard deviation \p 1.0
759 */
760QUALIFIERS double curand_normal_double(curandStateMtgp32_t *state)
761{
762 return _curand_normal_icdf_double(curand(state));
763}
764
765/**
766 * \brief Return a normally distributed double from an Sobol32 generator.
767 *
768 * Return a single normally distributed double with mean \p 0.0 and
769 * standard deviation \p 1.0 from the Sobol32 generator in \p state,
770 * increment position of generator by one.
771 *
772 * The implementation uses the inverse cumulative distribution function
773 * to generate normally distributed results.
774 *
775 * \param state - Pointer to state to update
776 *
777 * \return Normally distributed double with mean \p 0.0 and standard deviation \p 1.0
778 */
779QUALIFIERS double curand_normal_double(curandStateSobol32_t *state)
780{
781 return _curand_normal_icdf_double(curand(state));
782}
783
784/**
785 * \brief Return a normally distributed double from a scrambled Sobol32 generator.
786 *
787 * Return a single normally distributed double with mean \p 0.0 and
788 * standard deviation \p 1.0 from the scrambled Sobol32 generator in \p state,
789 * increment position of generator by one.
790 *
791 * The implementation uses the inverse cumulative distribution function
792 * to generate normally distributed results.
793 *
794 * \param state - Pointer to state to update
795 *
796 * \return Normally distributed double with mean \p 0.0 and standard deviation \p 1.0
797 */
798QUALIFIERS double curand_normal_double(curandStateScrambledSobol32_t *state)
799{
800 return _curand_normal_icdf_double(curand(state));
801}
802
803/**
804 * \brief Return a normally distributed double from a Sobol64 generator.
805 *
806 * Return a single normally distributed double with mean \p 0.0 and
807 * standard deviation \p 1.0 from the Sobol64 generator in \p state,
808 * increment position of generator by one.
809 *
810 * The implementation uses the inverse cumulative distribution function
811 * to generate normally distributed results.
812 *
813 * \param state - Pointer to state to update
814 *
815 * \return Normally distributed double with mean \p 0.0 and standard deviation \p 1.0
816 */
817QUALIFIERS double curand_normal_double(curandStateSobol64_t *state)
818{
819 return _curand_normal_icdf_double(curand(state));
820}
821
822/**
823 * \brief Return a normally distributed double from a scrambled Sobol64 generator.
824 *
825 * Return a single normally distributed double with mean \p 0.0 and
826 * standard deviation \p 1.0 from the scrambled Sobol64 generator in \p state,
827 * increment position of generator by one.
828 *
829 * The implementation uses the inverse cumulative distribution function
830 * to generate normally distributed results.
831 *
832 * \param state - Pointer to state to update
833 *
834 * \return Normally distributed double with mean \p 0.0 and standard deviation \p 1.0
835 */
836QUALIFIERS double curand_normal_double(curandStateScrambledSobol64_t *state)
837{
838 return _curand_normal_icdf_double(curand(state));
839}
840#endif // !defined(CURAND_NORMAL_H_)
841 