Actual source code: random.c

petsc-main 2021-04-20
Report Typos and Errors

  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:

  7:     Numbers can be shuffled for use as random tuples

  9:     Multiple random number generators may be used

 11:     We are still not sure what interface we want here.  There should be
 12:     one to reinitialize and set the seed.
 13:  */

 15: #include <../src/sys/classes/random/randomimpl.h>

 17: /*@
 18:    PetscRandomGetValue - Generates a random number.  Call this after first calling
 19:    PetscRandomCreate().

 21:    Not Collective

 23:    Intput Parameter:
 24: .  r  - the random number generator context

 26:    Output Parameter:
 27: .  val - the value

 29:    Level: intermediate

 31:    Notes:
 32:    Use VecSetRandom() to set the elements of a vector to random numbers.

 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.

 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.

 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

 50: .seealso: PetscRandomCreate(), PetscRandomDestroy(), VecSetRandom(), PetscRandomGetValueReal()
 51: @*/
 52: PetscErrorCode  PetscRandomGetValue(PetscRandom r,PetscScalar *val)
 53: {

 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:     (*r->ops->getvalues)(r,1,val);
 62:   } else {
 63:     (*r->ops->getvalue)(r,val);
 64:   }
 65:   PetscObjectStateIncrease((PetscObject)r);
 66:   return(0);
 67: }

 69: /*@
 70:    PetscRandomGetValueReal - Generates a real random number.  Call this after first calling
 71:    PetscRandomCreate().

 73:    Not Collective

 75:    Intput Parameter:
 76: .  r  - the random number generator context

 78:    Output Parameter:
 79: .  val - the value

 81:    Level: intermediate

 83:    Notes:
 84:    Use VecSetRandom() to set the elements of a vector to random numbers.

 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

 95: .seealso: PetscRandomCreate(), PetscRandomDestroy(), VecSetRandom(), PetscRandomGetValue()
 96: @*/
 97: PetscErrorCode  PetscRandomGetValueReal(PetscRandom r,PetscReal *val)
 98: {

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:     (*r->ops->getvaluesreal)(r,1,val);
107:   } else {
108:     (*r->ops->getvaluereal)(r,val);
109:   }
110:   PetscObjectStateIncrease((PetscObject)r);
111:   return(0);
112: }

114: /*@
115:    PetscRandomGetValues - Generates a sequence of random numbers.  Call this after first calling
116:    PetscRandomCreate().

118:    Not Collective

120:    Intput Parameter:
121: +  r  - the random number generator context
122: -  n  - number of random numbers to generate

124:    Output Parameter:
125: .  val - the array to hold the values

127:    Level: intermediate

129:    Notes:
130:    Use VecSetRandom() to set the elements of a vector to random numbers.

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.

135: .seealso: PetscRandomCreate(), PetscRandomDestroy(), VecSetRandom(), PetscRandomGetValue()
136: @*/
137: PetscErrorCode  PetscRandomGetValues(PetscRandom r, PetscInt n, PetscScalar *val)
138: {

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:       (*r->ops->getvalue)(r,val+i);
149:     }
150:   } else {
151:     (*r->ops->getvalues)(r,n,val);
152:   }
153:   PetscObjectStateIncrease((PetscObject)r);
154:   return(0);
155: }

157: /*@
158:    PetscRandomGetValuesReal - Generates a sequence of real random numbers.  Call this after first calling
159:    PetscRandomCreate().

161:    Not Collective

163:    Intput Parameter:
164: +  r  - the random number generator context
165: -  n  - number of random numbers to generate

167:    Output Parameter:
168: .  val - the array to hold the values

170:    Level: intermediate

172:    Notes:
173:    Use VecSetRandom() to set the elements of a vector to random numbers.

175: .seealso: PetscRandomCreate(), PetscRandomDestroy(), VecSetRandom(), PetscRandomGetValues()
176: @*/
177: PetscErrorCode  PetscRandomGetValuesReal(PetscRandom r, PetscInt n, PetscReal *val)
178: {

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:       (*r->ops->getvaluereal)(r,val+i);
189:     }
190:   } else {
191:     (*r->ops->getvaluesreal)(r,n,val);
192:   }
193:   PetscObjectStateIncrease((PetscObject)r);
194:   return(0);
195: }

197: /*@
198:    PetscRandomGetInterval - Gets the interval over which the random numbers
199:    will be randomly distributed.  By default, this interval is [0,1).

201:    Not collective

203:    Input Parameters:
204: .  r  - the random number generator context

206:    Output Parameters:
207: +  low - The lower bound of the interval
208: -  high - The upper bound of the interval

210:    Level: intermediate

212: .seealso: PetscRandomCreate(), PetscRandomSetInterval()
213: @*/
214: PetscErrorCode  PetscRandomGetInterval(PetscRandom r,PetscScalar *low,PetscScalar *high)
215: {
218:   if (low) {
220:     *low = r->low;
221:   }
222:   if (high) {
224:     *high = r->low+r->width;
225:   }
226:   return(0);
227: }

229: /*@
230:    PetscRandomSetInterval - Sets the interval over which the random numbers
231:    will be randomly distributed.  By default, this interval is [0,1).

233:    Not collective

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

240:    Level: intermediate

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.

246: .seealso: PetscRandomCreate(), PetscRandomGetInterval()
247: @*/
248: PetscErrorCode  PetscRandomSetInterval(PetscRandom r,PetscScalar low,PetscScalar high)
249: {
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:   return(0);
262: }