1 /*
2 This file contains routines for interfacing to random number generators.
3 This provides more than just an interface to some system random number
4 generator:
5
6 Numbers can be shuffled for use as random tuples
7
8 Multiple random number generators may be used
9
10 We are still not sure what interface we want here. There should be
11 one to reinitialize and set the seed.
12 */
13
14 #include <petsc/private/randomimpl.h> /*I "petscsys.h" I*/
15
16 /*@
17 PetscRandomGetValue - Generates a random number. Call this after first calling
18 `PetscRandomCreate()`.
19
20 Not Collective
21
22 Input Parameter:
23 . r - the random number generator context
24
25 Output Parameter:
26 . val - the value
27
28 Level: intermediate
29
30 Notes:
31 Use `VecSetRandom()` to set the elements of a vector to random numbers.
32
33 When PETSc is compiled for complex numbers this returns a complex number with random real and complex parts.
34 Use `PetscRandomGetValueReal()` to get a random real number.
35
36 To get a complex number with only a random real part, first call `PetscRandomSetInterval()` with a equal
37 low and high imaginary part. Similarly to get a complex number with only a random imaginary part call
38 `PetscRandomSetInterval()` with a equal low and high real part.
39
40 Example of Usage:
41 .vb
42 PetscRandomCreate(PETSC_COMM_WORLD,&r);
43 PetscRandomGetValue(r,&value1);
44 PetscRandomGetValue(r,&value2);
45 PetscRandomGetValue(r,&value3);
46 PetscRandomDestroy(&r);
47 .ve
48
49 .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomDestroy()`, `VecSetRandom()`, `PetscRandomGetValueReal()`, `PetscRandomSetInterval()`
50 @*/
PetscRandomGetValue(PetscRandom r,PetscScalar * val)51 PetscErrorCode PetscRandomGetValue(PetscRandom r, PetscScalar *val)
52 {
53 PetscFunctionBegin;
54 PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1);
55 PetscValidType(r, 1);
56 if (!r->ops->getvalue) PetscUseTypeMethod(r, getvalues, 1, val);
57 else PetscUseTypeMethod(r, getvalue, val);
58 PetscCall(PetscObjectStateIncrease((PetscObject)r));
59 PetscFunctionReturn(PETSC_SUCCESS);
60 }
61
62 /*@
63 PetscRandomGetValueReal - Generates a real random number. Call this after first calling
64 `PetscRandomCreate()`.
65
66 Not Collective
67
68 Input Parameter:
69 . r - the random number generator context
70
71 Output Parameter:
72 . val - the value
73
74 Level: intermediate
75
76 Note:
77 Use `VecSetRandom()` to set the elements of a vector to random numbers.
78
79 Example of Usage:
80 .vb
81 PetscRandomCreate(PETSC_COMM_WORLD,&r);
82 PetscRandomGetValueReal(r,&value1);
83 PetscRandomGetValueReal(r,&value2);
84 PetscRandomGetValueReal(r,&value3);
85 PetscRandomDestroy(&r);
86 .ve
87
88 .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomDestroy()`, `VecSetRandom()`, `PetscRandomGetValue()`
89 @*/
PetscRandomGetValueReal(PetscRandom r,PetscReal * val)90 PetscErrorCode PetscRandomGetValueReal(PetscRandom r, PetscReal *val)
91 {
92 PetscFunctionBegin;
93 PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1);
94 PetscValidType(r, 1);
95 if (!r->ops->getvaluereal) PetscUseTypeMethod(r, getvaluesreal, 1, val);
96 else PetscUseTypeMethod(r, getvaluereal, val);
97 PetscCall(PetscObjectStateIncrease((PetscObject)r));
98 PetscFunctionReturn(PETSC_SUCCESS);
99 }
100
101 /*@
102 PetscRandomGetValues - Generates a sequence of random numbers. Call this after first calling
103 `PetscRandomCreate()`.
104
105 Not Collective
106
107 Input Parameters:
108 + r - the random number generator context
109 - n - number of random numbers to generate
110
111 Output Parameter:
112 . val - the array to hold the values
113
114 Level: intermediate
115
116 Notes:
117 Use `VecSetRandom()` to set the elements of a vector to random numbers.
118
119 When PETSc is compiled for complex numbers this returns an array of complex numbers with random real and complex parts.
120 Use `PetscRandomGetValuesReal()` to get an array of random real numbers.
121
122 .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomDestroy()`, `VecSetRandom()`, `PetscRandomGetValue()`
123 @*/
PetscRandomGetValues(PetscRandom r,PetscInt n,PetscScalar * val)124 PetscErrorCode PetscRandomGetValues(PetscRandom r, PetscInt n, PetscScalar *val)
125 {
126 PetscFunctionBegin;
127 PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1);
128 PetscValidType(r, 1);
129 if (!r->ops->getvalues) {
130 PetscErrorCode (*const getvalue)(PetscRandom, PetscScalar *) = r->ops->getvalue;
131
132 for (PetscInt i = 0; i < n; ++i) PetscCall(getvalue(r, val + i));
133 } else PetscUseTypeMethod(r, getvalues, n, val);
134 PetscCall(PetscObjectStateIncrease((PetscObject)r));
135 PetscFunctionReturn(PETSC_SUCCESS);
136 }
137
138 /*@
139 PetscRandomGetValuesReal - Generates a sequence of real random numbers. Call this after first calling
140 `PetscRandomCreate()`.
141
142 Not Collective
143
144 Input Parameters:
145 + r - the random number generator context
146 - n - number of random numbers to generate
147
148 Output Parameter:
149 . val - the array to hold the values
150
151 Level: intermediate
152
153 Note:
154 Use `VecSetRandom()` to set the elements of a vector to random numbers.
155
156 .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomDestroy()`, `VecSetRandom()`, `PetscRandomGetValues()`
157 @*/
PetscRandomGetValuesReal(PetscRandom r,PetscInt n,PetscReal * val)158 PetscErrorCode PetscRandomGetValuesReal(PetscRandom r, PetscInt n, PetscReal *val)
159 {
160 PetscFunctionBegin;
161 PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1);
162 PetscValidType(r, 1);
163 if (!r->ops->getvaluesreal) {
164 PetscInt i;
165 for (i = 0; i < n; i++) PetscUseTypeMethod(r, getvaluereal, val + i);
166 } else PetscUseTypeMethod(r, getvaluesreal, n, val);
167 PetscCall(PetscObjectStateIncrease((PetscObject)r));
168 PetscFunctionReturn(PETSC_SUCCESS);
169 }
170
171 /*@
172 PetscRandomGetInterval - Gets the interval over which the random numbers
173 will be distributed. By default, this interval is [0,1).
174
175 Not Collective
176
177 Input Parameter:
178 . r - the random number generator context
179
180 Output Parameters:
181 + low - The lower bound of the interval
182 - high - The upper bound of the interval
183
184 Level: intermediate
185
186 .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomSetInterval()`
187 @*/
PetscRandomGetInterval(PetscRandom r,PetscScalar * low,PetscScalar * high)188 PetscErrorCode PetscRandomGetInterval(PetscRandom r, PetscScalar *low, PetscScalar *high)
189 {
190 PetscFunctionBegin;
191 PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1);
192 if (low) {
193 PetscAssertPointer(low, 2);
194 *low = r->low;
195 }
196 if (high) {
197 PetscAssertPointer(high, 3);
198 *high = r->low + r->width;
199 }
200 PetscFunctionReturn(PETSC_SUCCESS);
201 }
202
203 /*@
204 PetscRandomSetInterval - Sets the interval over which the random numbers
205 will be distributed. By default, this interval is [0,1).
206
207 Not Collective
208
209 Input Parameters:
210 + r - the random number generator context
211 . low - The lower bound of the interval
212 - high - The upper bound of the interval
213
214 Level: intermediate
215
216 Notes:
217 for complex numbers either the real part or the imaginary part of high must be greater than its low part; or both of them can be greater.
218
219 If the real or imaginary part of low and high are the same then that value is always returned in the real or imaginary part.
220
221 .seealso: `PetscRandomCreate()`, `PetscRandomGetInterval()`
222 @*/
PetscRandomSetInterval(PetscRandom r,PetscScalar low,PetscScalar high)223 PetscErrorCode PetscRandomSetInterval(PetscRandom r, PetscScalar low, PetscScalar high)
224 {
225 PetscFunctionBegin;
226 PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1);
227 #if defined(PETSC_USE_COMPLEX)
228 PetscCheck(PetscRealPart(low) <= PetscRealPart(high), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "only low <= high");
229 PetscCheck(PetscImaginaryPart(low) <= PetscImaginaryPart(high), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "only low <= high");
230 #else
231 PetscCheck(low < high, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "only low <= high: Instead %g %g", (double)low, (double)high);
232 #endif
233 r->low = low;
234 r->width = high - low;
235 r->iset = PETSC_TRUE;
236 PetscFunctionReturn(PETSC_SUCCESS);
237 }
238