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 <../src/sys/classes/random/randomimpl.h> /*I "petscsys.h" I*/ 16 #if defined(PETSC_HAVE_STDLIB_H) 17 #include <stdlib.h> 18 #endif 19 20 #undef __FUNCT__ 21 #define __FUNCT__ "PetscRandomGetValue" 22 /*@ 23 PetscRandomGetValue - Generates a random number. Call this after first calling 24 PetscRandomCreate(). 25 26 Not Collective 27 28 Intput Parameter: 29 . r - the random number generator context 30 31 Output Parameter: 32 . val - the value 33 34 Level: intermediate 35 36 Notes: 37 Use VecSetRandom() to set the elements of a vector to random numbers. 38 39 When PETSc is compiled for complex numbers this returns a complex number with random real and complex parts. 40 Use PetscGetValueReal() to get a random real number. 41 42 To get a complex number with only a random real part, first call PetscRandomSetInterval() with a equal 43 low and high imaginary part. Similarly to get a complex number with only a random imaginary part call 44 PetscRandomSetInterval() with a equal low and high real part. 45 46 Example of Usage: 47 .vb 48 PetscRandomCreate(PETSC_COMM_WORLD,&r); 49 PetscRandomGetValue(r,&value1); 50 PetscRandomGetValue(r,&value2); 51 PetscRandomGetValue(r,&value3); 52 PetscRandomDestroy(&r); 53 .ve 54 55 Concepts: random numbers^getting 56 57 .seealso: PetscRandomCreate(), PetscRandomDestroy(), VecSetRandom(), PetscRandomGetValueReal() 58 @*/ 59 PetscErrorCode PetscRandomGetValue(PetscRandom r,PetscScalar *val) 60 { 61 PetscErrorCode ierr; 62 63 PetscFunctionBegin; 64 PetscValidHeaderSpecific(r,PETSC_RANDOM_CLASSID,1); 65 PetscValidIntPointer(val,2); 66 PetscValidType(r,1); 67 68 ierr = (*r->ops->getvalue)(r,val);CHKERRQ(ierr); 69 ierr = PetscObjectStateIncrease((PetscObject)r);CHKERRQ(ierr); 70 PetscFunctionReturn(0); 71 } 72 73 #undef __FUNCT__ 74 #define __FUNCT__ "PetscRandomGetValueReal" 75 /*@ 76 PetscRandomGetValueReal - Generates a purely real random number. Call this after first calling 77 PetscRandomCreate(). 78 79 Not Collective 80 81 Intput Parameter: 82 . r - the random number generator context 83 84 Output Parameter: 85 . val - the value 86 87 Level: intermediate 88 89 Notes: 90 Use VecSetRandom() to set the elements of a vector to random numbers. 91 92 Example of Usage: 93 .vb 94 PetscRandomCreate(PETSC_COMM_WORLD,&r); 95 PetscRandomGetValueReal(r,&value1); 96 PetscRandomGetValueReal(r,&value2); 97 PetscRandomGetValueReal(r,&value3); 98 PetscRandomDestroy(&r); 99 .ve 100 101 Concepts: random numbers^getting 102 103 .seealso: PetscRandomCreate(), PetscRandomDestroy(), VecSetRandom(), PetscRandomGetValue() 104 @*/ 105 PetscErrorCode PetscRandomGetValueReal(PetscRandom r,PetscReal *val) 106 { 107 PetscErrorCode ierr; 108 109 PetscFunctionBegin; 110 PetscValidHeaderSpecific(r,PETSC_RANDOM_CLASSID,1); 111 PetscValidIntPointer(val,2); 112 PetscValidType(r,1); 113 114 ierr = (*r->ops->getvaluereal)(r,val);CHKERRQ(ierr); 115 ierr = PetscObjectStateIncrease((PetscObject)r);CHKERRQ(ierr); 116 PetscFunctionReturn(0); 117 } 118 119 #undef __FUNCT__ 120 #define __FUNCT__ "PetscRandomGetInterval" 121 /*@ 122 PetscRandomGetInterval - Gets the interval over which the random numbers 123 will be randomly distributed. By default, this interval is [0,1). 124 125 Not collective 126 127 Input Parameters: 128 . r - the random number generator context 129 130 Output Parameters: 131 + low - The lower bound of the interval 132 - high - The upper bound of the interval 133 134 Level: intermediate 135 136 Concepts: random numbers^range 137 138 .seealso: PetscRandomCreate(), PetscRandomSetInterval() 139 @*/ 140 PetscErrorCode PetscRandomGetInterval(PetscRandom r,PetscScalar *low,PetscScalar *high) 141 { 142 PetscFunctionBegin; 143 PetscValidHeaderSpecific(r,PETSC_RANDOM_CLASSID,1); 144 if (low) { 145 PetscValidScalarPointer(low,2); 146 *low = r->low; 147 } 148 if (high) { 149 PetscValidScalarPointer(high,3); 150 *high = r->low+r->width; 151 } 152 PetscFunctionReturn(0); 153 } 154 155 #undef __FUNCT__ 156 #define __FUNCT__ "PetscRandomSetInterval" 157 /*@ 158 PetscRandomSetInterval - Sets the interval over which the random numbers 159 will be randomly distributed. By default, this interval is [0,1). 160 161 Not collective 162 163 Input Parameters: 164 + r - the random number generator context 165 . low - The lower bound of the interval 166 - high - The upper bound of the interval 167 168 Level: intermediate 169 170 Notes: 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. 171 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. 172 173 Concepts: random numbers^range 174 175 .seealso: PetscRandomCreate(), PetscRandomGetInterval() 176 @*/ 177 PetscErrorCode PetscRandomSetInterval(PetscRandom r,PetscScalar low,PetscScalar high) 178 { 179 PetscFunctionBegin; 180 PetscValidHeaderSpecific(r,PETSC_RANDOM_CLASSID,1); 181 #if defined(PETSC_USE_COMPLEX) 182 if (PetscRealPart(low) > PetscRealPart(high)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"only low < high"); 183 if (PetscImaginaryPart(low) > PetscImaginaryPart(high)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"only low < high"); 184 #else 185 if (low >= high) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"only low < high: Instead %G %G",low,high); 186 #endif 187 r->low = low; 188 r->width = high-low; 189 r->iset = PETSC_TRUE; 190 PetscFunctionReturn(0); 191 } 192