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 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(0); 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 @*/ 90 PetscErrorCode PetscRandomGetValueReal(PetscRandom r, PetscReal *val) { 91 PetscFunctionBegin; 92 PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1); 93 PetscValidType(r, 1); 94 if (!r->ops->getvaluereal) PetscUseTypeMethod(r, getvaluesreal, 1, val); 95 else PetscUseTypeMethod(r, getvaluereal, val); 96 PetscCall(PetscObjectStateIncrease((PetscObject)r)); 97 PetscFunctionReturn(0); 98 } 99 100 /*@ 101 PetscRandomGetValues - Generates a sequence of random numbers. Call this after first calling 102 `PetscRandomCreate()`. 103 104 Not Collective 105 106 Input Parameters: 107 + r - the random number generator context 108 - n - number of random numbers to generate 109 110 Output Parameter: 111 . val - the array to hold the values 112 113 Level: intermediate 114 115 Notes: 116 Use `VecSetRandom()` to set the elements of a vector to random numbers. 117 118 When PETSc is compiled for complex numbers this returns an array of complex numbers with random real and complex parts. 119 Use `PetscRandomGetValuesReal()` to get an array of random real numbers. 120 121 .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomDestroy()`, `VecSetRandom()`, `PetscRandomGetValue()` 122 @*/ 123 PetscErrorCode PetscRandomGetValues(PetscRandom r, PetscInt n, PetscScalar *val) { 124 PetscFunctionBegin; 125 PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1); 126 PetscValidType(r, 1); 127 if (!r->ops->getvalues) { 128 PetscInt i; 129 for (i = 0; i < n; i++) PetscCall((*r->ops->getvalue)(r, val + i)); 130 } else PetscUseTypeMethod(r, getvalues, n, val); 131 PetscCall(PetscObjectStateIncrease((PetscObject)r)); 132 PetscFunctionReturn(0); 133 } 134 135 /*@ 136 PetscRandomGetValuesReal - Generates a sequence of real random numbers. Call this after first calling 137 `PetscRandomCreate()`. 138 139 Not Collective 140 141 Input Parameters: 142 + r - the random number generator context 143 - n - number of random numbers to generate 144 145 Output Parameter: 146 . val - the array to hold the values 147 148 Level: intermediate 149 150 Note: 151 Use `VecSetRandom()` to set the elements of a vector to random numbers. 152 153 .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomDestroy()`, `VecSetRandom()`, `PetscRandomGetValues()` 154 @*/ 155 PetscErrorCode PetscRandomGetValuesReal(PetscRandom r, PetscInt n, PetscReal *val) { 156 PetscFunctionBegin; 157 PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1); 158 PetscValidType(r, 1); 159 if (!r->ops->getvaluesreal) { 160 PetscInt i; 161 for (i = 0; i < n; i++) PetscCall((*r->ops->getvaluereal)(r, val + i)); 162 } else PetscUseTypeMethod(r, getvaluesreal, n, val); 163 PetscCall(PetscObjectStateIncrease((PetscObject)r)); 164 PetscFunctionReturn(0); 165 } 166 167 /*@ 168 PetscRandomGetInterval - Gets the interval over which the random numbers 169 will be distributed. By default, this interval is [0,1). 170 171 Not collective 172 173 Input Parameter: 174 . r - the random number generator context 175 176 Output Parameters: 177 + low - The lower bound of the interval 178 - high - The upper bound of the interval 179 180 Level: intermediate 181 182 .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomSetInterval()` 183 @*/ 184 PetscErrorCode PetscRandomGetInterval(PetscRandom r, PetscScalar *low, PetscScalar *high) { 185 PetscFunctionBegin; 186 PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1); 187 if (low) { 188 PetscValidScalarPointer(low, 2); 189 *low = r->low; 190 } 191 if (high) { 192 PetscValidScalarPointer(high, 3); 193 *high = r->low + r->width; 194 } 195 PetscFunctionReturn(0); 196 } 197 198 /*@ 199 PetscRandomSetInterval - Sets the interval over which the random numbers 200 will be distributed. By default, this interval is [0,1). 201 202 Not collective 203 204 Input Parameters: 205 + r - the random number generator context 206 . low - The lower bound of the interval 207 - high - The upper bound of the interval 208 209 Level: intermediate 210 211 Notes: 212 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. 213 214 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. 215 216 .seealso: `PetscRandomCreate()`, `PetscRandomGetInterval()` 217 @*/ 218 PetscErrorCode PetscRandomSetInterval(PetscRandom r, PetscScalar low, PetscScalar high) { 219 PetscFunctionBegin; 220 PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1); 221 #if defined(PETSC_USE_COMPLEX) 222 PetscCheck(PetscRealPart(low) <= PetscRealPart(high), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "only low <= high"); 223 PetscCheck(PetscImaginaryPart(low) <= PetscImaginaryPart(high), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "only low <= high"); 224 #else 225 PetscCheck(low < high, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "only low <= high: Instead %g %g", (double)low, (double)high); 226 #endif 227 r->low = low; 228 r->width = high - low; 229 r->iset = PETSC_TRUE; 230 PetscFunctionReturn(0); 231 } 232