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