Nektar++
Vmath.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: Vmath.cpp
4//
5// For more information, please see: http://www.nektar.info
6//
7// The MIT License
8//
9// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10// Department of Aeronautics, Imperial College London (UK), and Scientific
11// Computing and Imaging Institute, University of Utah (USA).
12//
13// Permission is hereby granted, free of charge, to any person obtaining a
14// copy of this software and associated documentation files (the "Software"),
15// to deal in the Software without restriction, including without limitation
16// the rights to use, copy, modify, merge, publish, distribute, sublicense,
17// and/or sell copies of the Software, and to permit persons to whom the
18// Software is furnished to do so, subject to the following conditions:
19//
20// The above copyright notice and this permission notice shall be included
21// in all copies or substantial portions of the Software.
22//
23// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29// DEALINGS IN THE SOFTWARE.
30//
31// Description: Collection of templated functions for vector mathematics
32//
33///////////////////////////////////////////////////////////////////////////////
34
36
37namespace Vmath
38{
39
40#define IM1 2147483563
41#define IM2 2147483399
42#define AM (1.0 / IM1)
43#define IMM1 (IM1 - 1)
44#define IA1 40014
45#define IA2 40692
46#define IQ1 53668
47#define IQ2 52774
48#define IR1 12211
49#define IR2 3791
50#define NTAB 32
51#define NDIV (1 + IMM1 / NTAB)
52#define EPS 1.2e-7
53#define RNMX (1.0 - EPS)
54
55/// \brief Generates a number from ~Normal(0,1)
56template <class T> T ran2(long *idum)
57/* ------------------------------------------------------------------------- *
58 * Ran2 from NR 2e. Returns a uniform random deviate between 0.0 &
59 * 1.0 (exclusive of endpoints). Call with idum a negative integer to
60 * initialize; thereafter, do not alter idum between successive
61 * deviates in a sequence. RNMX should approximate the largest
62 * floating value that is less than 1.
63 * ------------------------------------------------------------------------- */
64{
65 int j;
66 long k;
67 static long idum2 = 123456789;
68 static long iy = 0;
69 static long iv[NTAB];
70 T temp;
71
72 if (*idum <= 0)
73 {
74 if (-(*idum) < 1)
75 {
76 *idum = 1;
77 }
78 else
79 {
80 *idum = -(*idum);
81 }
82 idum2 = (*idum);
83 for (j = NTAB + 7; j >= 0; j--)
84 {
85 k = (*idum) / IQ1;
86 *idum = IA1 * (*idum - k * IQ1) - k * IR1;
87 if (*idum < 0)
88 {
89 *idum += IM1;
90 }
91 if (j < NTAB)
92 {
93 iv[j] = *idum;
94 }
95 }
96 iy = iv[0];
97 }
98
99 k = (*idum) / IQ1;
100 *idum = IA1 * (*idum - k * IQ1) - k * IR1;
101 if (*idum < 0)
102 {
103 *idum += IM1;
104 }
105
106 k = idum2 / IQ2;
107 idum2 = IA2 * (idum2 - k * IQ2) - k * IR2;
108 if (idum2 < 0)
109 {
110 idum2 += IM2;
111 }
112
113 j = iy / NDIV;
114 iy = iv[j] - idum2;
115 iv[j] = *idum;
116 if (iy < 1)
117 {
118 iy += IMM1;
119 }
120
121 if ((temp = AM * iy) > RNMX)
122 {
123 return RNMX;
124 }
125 else
126 {
127 return temp;
128 }
129}
130
131#undef IM1
132#undef IM2
133#undef AM
134#undef IMM1
135#undef IA1
136#undef IA2
137#undef IQ1
138#undef IQ2
139#undef IR1
140#undef IR2
141#undef NTAB
142#undef NDIV
143#undef EPS
144#undef RNMX
145
146#ifdef NEKTAR_USE_THREAD_SAFETY
147static std::mutex mutex;
148#endif
150template LIB_UTILITIES_EXPORT Nektar::NekSingle ran2(long *idum);
151
152/// \brief Fills a vector with white noise.
153template <class T>
154void FillWhiteNoise(int n, const T eps, T *x, const int incx, int outseed)
155{
156#ifdef NEKTAR_USE_THREAD_SAFETY
157 // Protect the static vars here and in ran2
158 std::scoped_lock l(mutex);
159#endif
160
161 // Define static variables for generating random numbers
162 static int iset = 0;
163 static T gset;
164 static long seed = 0;
165
166 // Bypass seed if outseed was specified
167 if (outseed != 9999)
168 {
169 seed = long(outseed);
170 }
171
172 while (n--)
173 {
174 T fac, rsq, v1, v2;
175
176 if (iset == 0)
177 {
178 do
179 {
180 v1 = 2.0 * ran2<T>(&seed) - 1.0;
181 v2 = 2.0 * ran2<T>(&seed) - 1.0;
182 rsq = v1 * v1 + v2 * v2;
183 } while (rsq >= 1.0 || rsq == 0.0);
184 fac = sqrt(-2.0 * log(rsq) / rsq);
185 gset = v1 * fac;
186 iset = 1;
187 *x = eps * v2 * fac;
188 }
189 else
190 {
191 iset = 0;
192 *x = eps * gset;
193 }
194 x += incx;
195 }
196}
198 const Nektar::NekDouble eps,
200 const int incx, int outseed);
202 const Nektar::NekSingle eps,
204 const int incx, int outseed);
205
206} // namespace Vmath
#define LIB_UTILITIES_EXPORT
#define NTAB
Definition: Vmath.cpp:50
#define IA2
Definition: Vmath.cpp:45
#define IR2
Definition: Vmath.cpp:49
#define NDIV
Definition: Vmath.cpp:51
#define IA1
Definition: Vmath.cpp:44
#define IM1
Definition: Vmath.cpp:40
#define IR1
Definition: Vmath.cpp:48
#define IMM1
Definition: Vmath.cpp:43
#define IQ1
Definition: Vmath.cpp:46
#define RNMX
Definition: Vmath.cpp:53
#define IQ2
Definition: Vmath.cpp:47
#define AM
Definition: Vmath.cpp:42
#define IM2
Definition: Vmath.cpp:41
double NekDouble
Definition: Vmath.cpp:38
T ran2(long *idum)
Generates a number from ~Normal(0,1)
Definition: Vmath.cpp:56
void FillWhiteNoise(int n, const T eps, T *x, const int incx, int outseed)
Fills a vector with white noise.
Definition: Vmath.cpp:154
scalarT< T > log(scalarT< T > in)
Definition: scalar.hpp:303
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:294