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(PETSC_SUCCESS); 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(PETSC_SUCCESS); 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 PetscErrorCode (*const getvalue)(PetscRandom, PetscScalar *) = r->ops->getvalue; 132 133 for (PetscInt i = 0; i < n; ++i) PetscCall(getvalue(r, val + i)); 134 } else PetscUseTypeMethod(r, getvalues, n, val); 135 PetscCall(PetscObjectStateIncrease((PetscObject)r)); 136 PetscFunctionReturn(PETSC_SUCCESS); 137 } 138 139 /*@ 140 PetscRandomGetValuesReal - Generates a sequence of real random numbers. Call this after first calling 141 `PetscRandomCreate()`. 142 143 Not Collective 144 145 Input Parameters: 146 + r - the random number generator context 147 - n - number of random numbers to generate 148 149 Output Parameter: 150 . val - the array to hold the values 151 152 Level: intermediate 153 154 Note: 155 Use `VecSetRandom()` to set the elements of a vector to random numbers. 156 157 .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomDestroy()`, `VecSetRandom()`, `PetscRandomGetValues()` 158 @*/ 159 PetscErrorCode PetscRandomGetValuesReal(PetscRandom r, PetscInt n, PetscReal *val) 160 { 161 PetscFunctionBegin; 162 PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1); 163 PetscValidType(r, 1); 164 if (!r->ops->getvaluesreal) { 165 PetscInt i; 166 for (i = 0; i < n; i++) PetscCall((*r->ops->getvaluereal)(r, val + i)); 167 } else PetscUseTypeMethod(r, getvaluesreal, n, val); 168 PetscCall(PetscObjectStateIncrease((PetscObject)r)); 169 PetscFunctionReturn(PETSC_SUCCESS); 170 } 171 172 /*@ 173 PetscRandomGetInterval - Gets the interval over which the random numbers 174 will be distributed. By default, this interval is [0,1). 175 176 Not Collective 177 178 Input Parameter: 179 . r - the random number generator context 180 181 Output Parameters: 182 + low - The lower bound of the interval 183 - high - The upper bound of the interval 184 185 Level: intermediate 186 187 .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomSetInterval()` 188 @*/ 189 PetscErrorCode PetscRandomGetInterval(PetscRandom r, PetscScalar *low, PetscScalar *high) 190 { 191 PetscFunctionBegin; 192 PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1); 193 if (low) { 194 PetscAssertPointer(low, 2); 195 *low = r->low; 196 } 197 if (high) { 198 PetscAssertPointer(high, 3); 199 *high = r->low + r->width; 200 } 201 PetscFunctionReturn(PETSC_SUCCESS); 202 } 203 204 /*@ 205 PetscRandomSetInterval - Sets the interval over which the random numbers 206 will be distributed. By default, this interval is [0,1). 207 208 Not Collective 209 210 Input Parameters: 211 + r - the random number generator context 212 . low - The lower bound of the interval 213 - high - The upper bound of the interval 214 215 Level: intermediate 216 217 Notes: 218 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 220 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 222 .seealso: `PetscRandomCreate()`, `PetscRandomGetInterval()` 223 @*/ 224 PetscErrorCode PetscRandomSetInterval(PetscRandom r, PetscScalar low, PetscScalar high) 225 { 226 PetscFunctionBegin; 227 PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1); 228 #if defined(PETSC_USE_COMPLEX) 229 PetscCheck(PetscRealPart(low) <= PetscRealPart(high), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "only low <= high"); 230 PetscCheck(PetscImaginaryPart(low) <= PetscImaginaryPart(high), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "only low <= high"); 231 #else 232 PetscCheck(low < high, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "only low <= high: Instead %g %g", (double)low, (double)high); 233 #endif 234 r->low = low; 235 r->width = high - low; 236 r->iset = PETSC_TRUE; 237 PetscFunctionReturn(PETSC_SUCCESS); 238 } 239