1 2 /* 3 This file contains routines for interfacing to random number generators. 4 This provides more than just an interface to some system random number 5 generator: 6 7 Numbers can be shuffled for use as random tuples 8 9 Multiple random number generators may be used 10 11 We are still not sure what interface we want here. There should be 12 one to reinitialize and set the seed. 13 */ 14 15 #include <petsc/private/randomimpl.h> /*I "petscsys.h" I*/ 16 17 /*@ 18 PetscRandomGetValue - Generates a random number. Call this after first calling 19 `PetscRandomCreate()`. 20 21 Not Collective 22 23 Input Parameter: 24 . r - the random number generator context 25 26 Output Parameter: 27 . val - the value 28 29 Level: intermediate 30 31 Notes: 32 Use `VecSetRandom()` to set the elements of a vector to random numbers. 33 34 When PETSc is compiled for complex numbers this returns a complex number with random real and complex parts. 35 Use `PetscRandomGetValueReal()` to get a random real number. 36 37 To get a complex number with only a random real part, first call `PetscRandomSetInterval()` with a equal 38 low and high imaginary part. Similarly to get a complex number with only a random imaginary part call 39 `PetscRandomSetInterval()` with a equal low and high real part. 40 41 Example of Usage: 42 .vb 43 PetscRandomCreate(PETSC_COMM_WORLD,&r); 44 PetscRandomGetValue(r,&value1); 45 PetscRandomGetValue(r,&value2); 46 PetscRandomGetValue(r,&value3); 47 PetscRandomDestroy(&r); 48 .ve 49 50 .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomDestroy()`, `VecSetRandom()`, `PetscRandomGetValueReal()`, `PetscRandomSetInterval()` 51 @*/ 52 PetscErrorCode PetscRandomGetValue(PetscRandom r, PetscScalar *val) 53 { 54 PetscFunctionBegin; 55 PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1); 56 PetscValidType(r, 1); 57 if (!r->ops->getvalue) PetscUseTypeMethod(r, getvalues, 1, val); 58 else PetscUseTypeMethod(r, getvalue, val); 59 PetscCall(PetscObjectStateIncrease((PetscObject)r)); 60 PetscFunctionReturn(0); 61 } 62 63 /*@ 64 PetscRandomGetValueReal - Generates a real random number. Call this after first calling 65 `PetscRandomCreate()`. 66 67 Not Collective 68 69 Input Parameter: 70 . r - the random number generator context 71 72 Output Parameter: 73 . val - the value 74 75 Level: intermediate 76 77 Note: 78 Use `VecSetRandom()` to set the elements of a vector to random numbers. 79 80 Example of Usage: 81 .vb 82 PetscRandomCreate(PETSC_COMM_WORLD,&r); 83 PetscRandomGetValueReal(r,&value1); 84 PetscRandomGetValueReal(r,&value2); 85 PetscRandomGetValueReal(r,&value3); 86 PetscRandomDestroy(&r); 87 .ve 88 89 .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomDestroy()`, `VecSetRandom()`, `PetscRandomGetValue()` 90 @*/ 91 PetscErrorCode PetscRandomGetValueReal(PetscRandom r, PetscReal *val) 92 { 93 PetscFunctionBegin; 94 PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1); 95 PetscValidType(r, 1); 96 if (!r->ops->getvaluereal) PetscUseTypeMethod(r, getvaluesreal, 1, val); 97 else PetscUseTypeMethod(r, getvaluereal, val); 98 PetscCall(PetscObjectStateIncrease((PetscObject)r)); 99 PetscFunctionReturn(0); 100 } 101 102 /*@ 103 PetscRandomGetValues - Generates a sequence of random numbers. Call this after first calling 104 `PetscRandomCreate()`. 105 106 Not Collective 107 108 Input Parameters: 109 + r - the random number generator context 110 - n - number of random numbers to generate 111 112 Output Parameter: 113 . val - the array to hold the values 114 115 Level: intermediate 116 117 Notes: 118 Use `VecSetRandom()` to set the elements of a vector to random numbers. 119 120 When PETSc is compiled for complex numbers this returns an array of complex numbers with random real and complex parts. 121 Use `PetscRandomGetValuesReal()` to get an array of random real numbers. 122 123 .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomDestroy()`, `VecSetRandom()`, `PetscRandomGetValue()` 124 @*/ 125 PetscErrorCode PetscRandomGetValues(PetscRandom r, PetscInt n, PetscScalar *val) 126 { 127 PetscFunctionBegin; 128 PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1); 129 PetscValidType(r, 1); 130 if (!r->ops->getvalues) { 131 PetscInt i; 132 for (i = 0; i < n; i++) PetscCall((*r->ops->getvalue)(r, val + i)); 133 } else PetscUseTypeMethod(r, getvalues, n, val); 134 PetscCall(PetscObjectStateIncrease((PetscObject)r)); 135 PetscFunctionReturn(0); 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 @*/ 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++) PetscCall((*r->ops->getvaluereal)(r, val + i)); 166 } else PetscUseTypeMethod(r, getvaluesreal, n, val); 167 PetscCall(PetscObjectStateIncrease((PetscObject)r)); 168 PetscFunctionReturn(0); 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 @*/ 188 PetscErrorCode PetscRandomGetInterval(PetscRandom r, PetscScalar *low, PetscScalar *high) 189 { 190 PetscFunctionBegin; 191 PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1); 192 if (low) { 193 PetscValidScalarPointer(low, 2); 194 *low = r->low; 195 } 196 if (high) { 197 PetscValidScalarPointer(high, 3); 198 *high = r->low + r->width; 199 } 200 PetscFunctionReturn(0); 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 @*/ 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(0); 237 } 238