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