Date: 2022-03-04T17:37:04+00:00

Actual source code: random.c

      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 <petsc/private/randomimpl.h>

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

     21:    Not Collective

     23:    Input 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:    Input 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:    Input Parameters:
    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:    Input Parameters:
    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 Parameter:
    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: }