Actual source code: random.c
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:
6: Numbers can be shuffled for use as random tuples
8: Multiple random number generators may be used
10: We are still not sure what interface we want here. There should be
11: one to reinitialize and set the seed.
12: */
14: #include <petsc/private/randomimpl.h>
16: /*@
17: PetscRandomGetValue - Generates a random number. Call this after first calling
18: `PetscRandomCreate()`.
20: Not Collective
22: Input Parameter:
23: . r - the random number generator context
25: Output Parameter:
26: . val - the value
28: Level: intermediate
30: Notes:
31: Use `VecSetRandom()` to set the elements of a vector to random numbers.
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.
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.
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
49: .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomDestroy()`, `VecSetRandom()`, `PetscRandomGetValueReal()`, `PetscRandomSetInterval()`
50: @*/
51: PetscErrorCode PetscRandomGetValue(PetscRandom r, PetscScalar *val)
52: {
53: PetscFunctionBegin;
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: }
62: /*@
63: PetscRandomGetValueReal - Generates a real random number. Call this after first calling
64: `PetscRandomCreate()`.
66: Not Collective
68: Input Parameter:
69: . r - the random number generator context
71: Output Parameter:
72: . val - the value
74: Level: intermediate
76: Note:
77: Use `VecSetRandom()` to set the elements of a vector to random numbers.
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
88: .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomDestroy()`, `VecSetRandom()`, `PetscRandomGetValue()`
89: @*/
90: PetscErrorCode PetscRandomGetValueReal(PetscRandom r, PetscReal *val)
91: {
92: PetscFunctionBegin;
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: }
101: /*@
102: PetscRandomGetValues - Generates a sequence of random numbers. Call this after first calling
103: `PetscRandomCreate()`.
105: Not Collective
107: Input Parameters:
108: + r - the random number generator context
109: - n - number of random numbers to generate
111: Output Parameter:
112: . val - the array to hold the values
114: Level: intermediate
116: Notes:
117: Use `VecSetRandom()` to set the elements of a vector to random numbers.
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.
122: .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomDestroy()`, `VecSetRandom()`, `PetscRandomGetValue()`
123: @*/
124: PetscErrorCode PetscRandomGetValues(PetscRandom r, PetscInt n, PetscScalar *val)
125: {
126: PetscFunctionBegin;
129: if (!r->ops->getvalues) {
130: PetscErrorCode (*const getvalue)(PetscRandom, PetscScalar *) = r->ops->getvalue;
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: }
138: /*@
139: PetscRandomGetValuesReal - Generates a sequence of real random numbers. Call this after first calling
140: `PetscRandomCreate()`.
142: Not Collective
144: Input Parameters:
145: + r - the random number generator context
146: - n - number of random numbers to generate
148: Output Parameter:
149: . val - the array to hold the values
151: Level: intermediate
153: Note:
154: Use `VecSetRandom()` to set the elements of a vector to random numbers.
156: .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomDestroy()`, `VecSetRandom()`, `PetscRandomGetValues()`
157: @*/
158: PetscErrorCode PetscRandomGetValuesReal(PetscRandom r, PetscInt n, PetscReal *val)
159: {
160: PetscFunctionBegin;
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: }
171: /*@
172: PetscRandomGetInterval - Gets the interval over which the random numbers
173: will be distributed. By default, this interval is [0,1).
175: Not Collective
177: Input Parameter:
178: . r - the random number generator context
180: Output Parameters:
181: + low - The lower bound of the interval
182: - high - The upper bound of the interval
184: Level: intermediate
186: .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomSetInterval()`
187: @*/
188: PetscErrorCode PetscRandomGetInterval(PetscRandom r, PetscScalar *low, PetscScalar *high)
189: {
190: PetscFunctionBegin;
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: }
203: /*@
204: PetscRandomSetInterval - Sets the interval over which the random numbers
205: will be distributed. By default, this interval is [0,1).
207: Not Collective
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
214: Level: intermediate
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.
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.
221: .seealso: `PetscRandomCreate()`, `PetscRandomGetInterval()`
222: @*/
223: PetscErrorCode PetscRandomSetInterval(PetscRandom r, PetscScalar low, PetscScalar high)
224: {
225: PetscFunctionBegin;
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: }