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