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