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