Date: 2013-07-02T14:38:34+00:00

Actual source code: randomc.c
petsc-3.4.2 2013-07-02

      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>                              /*I "petscsys.h" I*/
     16: #include <petscviewer.h>

     18: /* Logging support */
     19: PetscClassId PETSC_RANDOM_CLASSID;

     23: /*@
     24:    PetscRandomDestroy - Destroys a context that has been formed by
     25:    PetscRandomCreate().

     27:    Collective on PetscRandom

     29:    Intput Parameter:
     30: .  r  - the random number generator context

     32:    Level: intermediate

     34: .seealso: PetscRandomGetValue(), PetscRandomCreate(), VecSetRandom()
     35: @*/
     36: PetscErrorCode  PetscRandomDestroy(PetscRandom *r)
     37: {

     41:   if (!*r) return(0);
     43:   if (--((PetscObject)(*r))->refct > 0) {*r = 0; return(0);}
     44:   PetscHeaderDestroy(r);
     45:   return(0);
     46: }

     51: /*@
     52:    PetscRandomGetSeed - Gets the random seed.

     54:    Not collective

     56:    Input Parameters:
     57: .  r - The random number generator context

     59:    Output Parameter:
     60: .  seed - The random seed

     62:    Level: intermediate

     64:    Concepts: random numbers^seed

     66: .seealso: PetscRandomCreate(), PetscRandomSetSeed(), PetscRandomSeed()
     67: @*/
     68: PetscErrorCode  PetscRandomGetSeed(PetscRandom r,unsigned long *seed)
     69: {
     72:   if (seed) {
     74:     *seed = r->seed;
     75:   }
     76:   return(0);
     77: }

     81: /*@
     82:    PetscRandomSetSeed - Sets the random seed. You MUST call PetscRandomSeed() after this call to have the new seed used.

     84:    Not collective

     86:    Input Parameters:
     87: +  r  - The random number generator context
     88: -  seed - The random seed

     90:    Level: intermediate

     92:    Usage:
     93:       PetscRandomSetSeed(r,a positive integer);
     94:       PetscRandomSeed(r);  PetscRandomGetValue() will now start with the new seed.

     96:       PetscRandomSeed(r) without a call to PetscRandomSetSeed() re-initializes
     97:         the seed. The random numbers generated will be the same as before.

     99:    Concepts: random numbers^seed

    101: .seealso: PetscRandomCreate(), PetscRandomGetSeed(), PetscRandomSeed()
    102: @*/
    103: PetscErrorCode  PetscRandomSetSeed(PetscRandom r,unsigned long seed)
    104: {

    109:   r->seed = seed;
    110:   PetscInfo1(NULL,"Setting seed to %d\n",(int)seed);
    111:   return(0);
    112: }

    114: /* ------------------------------------------------------------------- */
    117: /*
    118:   PetscRandomSetTypeFromOptions_Private - Sets the type of random generator from user options. Defaults to type PETSCRAND48 or PETSCRAND.

    120:   Collective on PetscRandom

    122:   Input Parameter:
    123: . rnd - The random number generator context

    125:   Level: intermediate

    127: .keywords: PetscRandom, set, options, database, type
    128: .seealso: PetscRandomSetFromOptions(), PetscRandomSetType()
    129: */
    130: static PetscErrorCode PetscRandomSetTypeFromOptions_Private(PetscRandom rnd)
    131: {
    132:   PetscBool      opt;
    133:   const char     *defaultType;
    134:   char           typeName[256];

    138:   if (((PetscObject)rnd)->type_name) {
    139:     defaultType = ((PetscObject)rnd)->type_name;
    140:   } else {
    141: #if defined(PETSC_HAVE_DRAND48)
    142:     defaultType = PETSCRAND48;
    143: #elif defined(PETSC_HAVE_RAND)
    144:     defaultType = PETSCRAND;
    145: #endif
    146:   }

    148:   if (!PetscRandomRegisterAllCalled) {PetscRandomRegisterAll();}
    149:   PetscOptionsList("-random_type","PetscRandom type","PetscRandomSetType",PetscRandomList,defaultType,typeName,256,&opt);
    150:   if (opt) {
    151:     PetscRandomSetType(rnd, typeName);
    152:   } else {
    153:     PetscRandomSetType(rnd, defaultType);
    154:   }
    155:   return(0);
    156: }

    160: /*@
    161:   PetscRandomSetFromOptions - Configures the random number generator from the options database.

    163:   Collective on PetscRandom

    165:   Input Parameter:
    166: . rnd - The random number generator context

    168:   Options Database:
    169: .  -random_seed <integer> - provide a seed to the random number generater

    171:   Notes:  To see all options, run your program with the -help option.
    172:           Must be called after PetscRandomCreate() but before the rnd is used.

    174:   Level: beginner

    176: .keywords: PetscRandom, set, options, database
    177: .seealso: PetscRandomCreate(), PetscRandomSetType()
    178: @*/
    179: PetscErrorCode  PetscRandomSetFromOptions(PetscRandom rnd)
    180: {
    182:   PetscBool      set;
    183:   PetscInt       seed;

    188:   PetscObjectOptionsBegin((PetscObject)rnd);

    190:   /* Handle PetscRandom type options */
    191:   PetscRandomSetTypeFromOptions_Private(rnd);

    193:   /* Handle specific random generator's options */
    194:   if (rnd->ops->setfromoptions) {
    195:     (*rnd->ops->setfromoptions)(rnd);
    196:   }
    197:   PetscOptionsInt("-random_seed","Seed to use to generate random numbers","PetscRandomSetSeed",0,&seed,&set);
    198:   if (set) {
    199:     PetscRandomSetSeed(rnd,(unsigned long int)seed);
    200:     PetscRandomSeed(rnd);
    201:   }
    202:   PetscOptionsEnd();
    203:   PetscRandomViewFromOptions(rnd,NULL, "-random_view");
    204:   return(0);
    205: }

    207: #if defined(PETSC_HAVE_AMS)
    208: #include <petscviewerams.h>
    209: #endif
    212: /*@C
    213:    PetscRandomView - Views a random number generator object.

    215:    Collective on PetscRandom

    217:    Input Parameters:
    218: +  rnd - The random number generator context
    219: -  viewer - an optional visualization context

    221:    Notes:
    222:    The available visualization contexts include
    223: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
    224: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
    225:          output where only the first processor opens
    226:          the file.  All other processors send their
    227:          data to the first processor to print.

    229:    You can change the format the vector is printed using the
    230:    option PetscViewerSetFormat().

    232:    Level: beginner

    234: .seealso:  PetscRealView(), PetscScalarView(), PetscIntView()
    235: @*/
    236: PetscErrorCode  PetscRandomView(PetscRandom rnd,PetscViewer viewer)
    237: {
    239:   PetscBool      iascii;
    240: #if defined(PETSC_HAVE_AMS)
    241:   PetscBool      isams;
    242: #endif

    247:   if (!viewer) {
    248:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)rnd),&viewer);
    249:   }
    252:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    253: #if defined(PETSC_HAVE_AMS)
    254:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERAMS,&isams);
    255: #endif
    256:   if (iascii) {
    257:     PetscMPIInt rank;
    258:     MPI_Comm_rank(PetscObjectComm((PetscObject)rnd),&rank);
    259:     PetscViewerASCIISynchronizedAllow(viewer,PETSC_TRUE);
    260:     PetscViewerASCIISynchronizedPrintf(viewer,"[%D] Random type %s, seed %D\n",rank,((PetscObject)rnd)->type_name,rnd->seed);
    261:     PetscViewerFlush(viewer);
    262:     PetscViewerASCIISynchronizedAllow(viewer,PETSC_FALSE);
    263: #if defined(PETSC_HAVE_AMS)
    264:   } else if (isams) {
    265:     if (((PetscObject)rnd)->amsmem == -1) {
    266:       PetscObjectViewAMS((PetscObject)rnd,viewer);
    267:       PetscStackCallAMS(AMS_Memory_add_field,(((PetscObject)rnd)->amsmem,"Low",&rnd->low,1,AMS_DOUBLE,AMS_READ,AMS_COMMON,AMS_REDUCT_UNDEF));
    268:     }
    269: #endif
    270:   }
    271:   return(0);
    272: }

    274: #undef  __FUNCT__
    276: /*
    277:   PetscRandomViewFromOptions - This function visualizes the type and the seed of the generated random numbers based upon user options.

    279:   Collective on PetscRandom

    281:   Input Parameters:
    282: + rnd   - The random number generator context
    283: . prefix - prefix to use for viewing, or NULL to use prefix of 'rnd'
    284: - optionname - option to activate viewing

    286:   Level: intermediate

    288: .keywords: PetscRandom, view, options, database
    289: .seealso: PetscRandomSetFromOptions()
    290: */
    291: PetscErrorCode  PetscRandomViewFromOptions(PetscRandom rnd, const char prefix[], const char optionname[])
    292: {
    293:   PetscBool         flg;
    294:   PetscViewer       viewer;
    295:   PetscErrorCode    ierr;
    296:   PetscViewerFormat format;

    299:   if (prefix) {
    300:     PetscOptionsGetViewer(PetscObjectComm((PetscObject)rnd),prefix,optionname,&viewer,&format,&flg);
    301:   } else {
    302:     PetscOptionsGetViewer(PetscObjectComm((PetscObject)rnd),((PetscObject)rnd)->prefix,optionname,&viewer,&format,&flg);
    303:   }
    304:   if (flg) {
    305:     PetscViewerPushFormat(viewer,format);
    306:     PetscRandomView(rnd,viewer);
    307:     PetscViewerPopFormat(viewer);
    308:     PetscViewerDestroy(&viewer);
    309:   }
    310:   return(0);
    311: }

    315: /*@
    316:    PetscRandomCreate - Creates a context for generating random numbers,
    317:    and initializes the random-number generator.

    319:    Collective on MPI_Comm

    321:    Input Parameters:
    322: +  comm - MPI communicator

    324:    Output Parameter:
    325: .  r  - the random number generator context

    327:    Level: intermediate

    329:    Notes:
    330:    The random type has to be set by PetscRandomSetType().

    332:    This is only a primative "parallel" random number generator, it should NOT
    333:    be used for sophisticated parallel Monte Carlo methods since it will very likely
    334:    not have the correct statistics across processors. You can provide your own
    335:    parallel generator using PetscRandomRegister();

    337:    If you create a PetscRandom() using PETSC_COMM_SELF on several processors then
    338:    the SAME random numbers will be generated on all those processors. Use PETSC_COMM_WORLD
    339:    or the appropriate parallel communicator to eliminate this issue.

    341:    Use VecSetRandom() to set the elements of a vector to random numbers.

    343:    Example of Usage:
    344: .vb
    345:       PetscRandomCreate(PETSC_COMM_SELF,&r);
    346:       PetscRandomSetType(r,PETSCRAND48);
    347:       PetscRandomGetValue(r,&value1);
    348:       PetscRandomGetValueReal(r,&value2);
    349:       PetscRandomDestroy(&r);
    350: .ve

    352:    Concepts: random numbers^creating

    354: .seealso: PetscRandomSetType(), PetscRandomGetValue(), PetscRandomGetValueReal(), PetscRandomSetInterval(),
    355:           PetscRandomDestroy(), VecSetRandom(), PetscRandomType
    356: @*/

    358: PetscErrorCode  PetscRandomCreate(MPI_Comm comm,PetscRandom *r)
    359: {
    360:   PetscRandom    rr;
    362:   PetscMPIInt    rank;

    366:   *r = NULL;
    367: #if !defined(PETSC_USE_DYNAMIC_LIBRARIES)
    368:   PetscRandomInitializePackage();
    369: #endif

    371:   PetscHeaderCreate(rr,_p_PetscRandom,struct _PetscRandomOps,PETSC_RANDOM_CLASSID,"PetscRandom","Random number generator","Sys",comm,PetscRandomDestroy,0);

    373:   MPI_Comm_rank(comm,&rank);

    375:   rr->data  = NULL;
    376:   rr->low   = 0.0;
    377:   rr->width = 1.0;
    378:   rr->iset  = PETSC_FALSE;
    379:   rr->seed  = 0x12345678 + 76543*rank;
    380:   *r = rr;
    381:   return(0);
    382: }

    386: /*@
    387:    PetscRandomSeed - Seed the generator.

    389:    Not collective

    391:    Input Parameters:
    392: .  r - The random number generator context

    394:    Level: intermediate

    396:    Usage:
    397:       PetscRandomSetSeed(r,a positive integer);
    398:       PetscRandomSeed(r);  PetscRandomGetValue() will now start with the new seed.

    400:       PetscRandomSeed(r) without a call to PetscRandomSetSeed() re-initializes
    401:         the seed. The random numbers generated will be the same as before.

    403:    Concepts: random numbers^seed

    405: .seealso: PetscRandomCreate(), PetscRandomGetSeed(), PetscRandomSetSeed()
    406: @*/
    407: PetscErrorCode  PetscRandomSeed(PetscRandom r)
    408: {

    415:   (*r->ops->seed)(r);
    416:   PetscObjectStateIncrease((PetscObject)r);
    417:   return(0);
    418: }