Actual source code: randomc.c
petsc-3.3-p7 2013-05-11
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/random/randomimpl.h> /*I "petscsys.h" I*/
16: #if defined (PETSC_HAVE_STDLIB_H)
17: #include <stdlib.h>
18: #endif
20: /* Logging support */
21: PetscClassId PETSC_RANDOM_CLASSID;
25: /*@
26: PetscRandomDestroy - Destroys a context that has been formed by
27: PetscRandomCreate().
29: Collective on PetscRandom
31: Intput Parameter:
32: . r - the random number generator context
34: Level: intermediate
36: .seealso: PetscRandomGetValue(), PetscRandomCreate(), VecSetRandom()
37: @*/
38: PetscErrorCode PetscRandomDestroy(PetscRandom *r)
39: {
42: if (!*r) return(0);
44: if (--((PetscObject)(*r))->refct > 0) {*r = 0; return(0);}
45: PetscHeaderDestroy(r);
46: return(0);
47: }
52: /*@
53: PetscRandomGetSeed - Gets the random seed.
55: Not collective
57: Input Parameters:
58: . r - The random number generator context
60: Output Parameter:
61: . seed - The random seed
63: Level: intermediate
65: Concepts: random numbers^seed
67: .seealso: PetscRandomCreate(), PetscRandomSetSeed(), PetscRandomSeed()
68: @*/
69: PetscErrorCode PetscRandomGetSeed(PetscRandom r,unsigned long *seed)
70: {
73: if (seed) {
75: *seed = r->seed;
76: }
77: return(0);
78: }
82: /*@
83: PetscRandomSetSeed - Sets the random seed. You MUST call PetscRandomSeed() after this call to have the new seed used.
85: Not collective
87: Input Parameters:
88: + r - The random number generator context
89: - seed - The random seed
91: Level: intermediate
93: Usage:
94: PetscRandomSetSeed(r,a positive integer);
95: PetscRandomSeed(r); PetscRandomGetValue() will now start with the new seed.
97: PetscRandomSeed(r) without a call to PetscRandomSetSeed() re-initializes
98: the seed. The random numbers generated will be the same as before.
100: Concepts: random numbers^seed
102: .seealso: PetscRandomCreate(), PetscRandomGetSeed(), PetscRandomSeed()
103: @*/
104: PetscErrorCode PetscRandomSetSeed(PetscRandom r,unsigned long seed)
105: {
110: r->seed = seed;
111: PetscInfo1(PETSC_NULL,"Setting seed to %d\n",(int)seed);
112: return(0);
113: }
115: /* ------------------------------------------------------------------- */
118: /*
119: PetscRandomSetTypeFromOptions_Private - Sets the type of random generator from user options. Defaults to type PETSCRAND48 or PETSCRAND.
121: Collective on PetscRandom
123: Input Parameter:
124: . rnd - The random number generator context
126: Level: intermediate
128: .keywords: PetscRandom, set, options, database, type
129: .seealso: PetscRandomSetFromOptions(), PetscRandomSetType()
130: */
131: static PetscErrorCode PetscRandomSetTypeFromOptions_Private(PetscRandom rnd)
132: {
133: PetscBool opt;
134: const char *defaultType;
135: char typeName[256];
139: if (((PetscObject)rnd)->type_name) {
140: defaultType = ((PetscObject)rnd)->type_name;
141: } else {
142: #if defined(PETSC_HAVE_DRAND48)
143: defaultType = PETSCRAND48;
144: #elif defined(PETSC_HAVE_RAND)
145: defaultType = PETSCRAND;
146: #endif
147: }
149: if (!PetscRandomRegisterAllCalled) {PetscRandomRegisterAll(PETSC_NULL);}
150: PetscOptionsList("-random_type","PetscRandom type","PetscRandomSetType",PetscRandomList,defaultType,typeName,256,&opt);
151: if (opt) {
152: PetscRandomSetType(rnd, typeName);
153: } else {
154: PetscRandomSetType(rnd, defaultType);
155: }
156: return(0);
157: }
161: /*@
162: PetscRandomSetFromOptions - Configures the random number generator from the options database.
164: Collective on PetscRandom
166: Input Parameter:
167: . rnd - The random number generator context
169: Options Database:
170: . -random_seed <integer> - provide a seed to the random number generater
172: Notes: To see all options, run your program with the -help option.
173: Must be called after PetscRandomCreate() but before the rnd is used.
175: Level: beginner
177: .keywords: PetscRandom, set, options, database
178: .seealso: PetscRandomCreate(), PetscRandomSetType()
179: @*/
180: PetscErrorCode PetscRandomSetFromOptions(PetscRandom rnd)
181: {
183: PetscBool set;
184: PetscInt seed;
189: PetscObjectOptionsBegin((PetscObject)rnd);
191: /* Handle PetscRandom type options */
192: PetscRandomSetTypeFromOptions_Private(rnd);
194: /* Handle specific random generator's options */
195: if (rnd->ops->setfromoptions) {
196: (*rnd->ops->setfromoptions)(rnd);
197: }
198: PetscOptionsInt("-random_seed","Seed to use to generate random numbers","PetscRandomSetSeed",0,&seed,&set);
199: if (set) {
200: PetscRandomSetSeed(rnd,(unsigned long int)seed);
201: PetscRandomSeed(rnd);
202: }
203: PetscOptionsEnd();
204: PetscRandomViewFromOptions(rnd, ((PetscObject)rnd)->name);
205: return(0);
206: }
210: /*@C
211: PetscRandomView - Views a random number generator object.
213: Collective on PetscRandom
215: Input Parameters:
216: + rnd - The random number generator context
217: - viewer - an optional visualization context
219: Notes:
220: The available visualization contexts include
221: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
222: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
223: output where only the first processor opens
224: the file. All other processors send their
225: data to the first processor to print.
227: You can change the format the vector is printed using the
228: option PetscViewerSetFormat().
230: Level: beginner
232: .seealso: PetscRealView(), PetscScalarView(), PetscIntView()
233: @*/
234: PetscErrorCode PetscRandomView(PetscRandom rnd,PetscViewer viewer)
235: {
236: PetscErrorCode ierr;
237: PetscBool iascii;
242: if (!viewer) {
243: PetscViewerASCIIGetStdout(((PetscObject)rnd)->comm,&viewer);
244: }
247: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
248: if (iascii) {
249: PetscMPIInt rank;
250: MPI_Comm_rank(((PetscObject)rnd)->comm,&rank);
251: PetscViewerASCIISynchronizedAllow(viewer,PETSC_TRUE);
252: PetscViewerASCIISynchronizedPrintf(viewer,"[%D] Random type %s, seed %D\n",rank,((PetscObject)rnd)->type_name,rnd->seed);
253: PetscViewerFlush(viewer);
254: PetscViewerASCIISynchronizedAllow(viewer,PETSC_FALSE);
255: } else {
256: const char *tname;
257: PetscObjectGetName((PetscObject)viewer,&tname);
258: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported for this object",tname);
259: }
260: return(0);
261: }
263: #undef __FUNCT__
265: /*@
266: PetscRandomViewFromOptions - This function visualizes the type and the seed of the generated random numbers based upon user options.
268: Collective on PetscRandom
270: Input Parameters:
271: . rnd - The random number generator context
272: . title - The title
274: Level: intermediate
276: .keywords: PetscRandom, view, options, database
277: .seealso: PetscRandomSetFromOptions()
278: @*/
279: PetscErrorCode PetscRandomViewFromOptions(PetscRandom rnd, char *title)
280: {
281: PetscBool opt = PETSC_FALSE;
282: PetscViewer viewer;
283: char typeName[1024];
284: char fileName[PETSC_MAX_PATH_LEN];
285: size_t len;
286:
290: PetscOptionsGetBool(((PetscObject)rnd)->prefix, "-random_view", &opt,PETSC_NULL);
291: if (opt) {
292: PetscOptionsGetString(((PetscObject)rnd)->prefix, "-random_view", typeName, 1024, &opt);
293: PetscStrlen(typeName, &len);
294: if (len > 0) {
295: PetscViewerCreate(((PetscObject)rnd)->comm, &viewer);
296: PetscViewerSetType(viewer, typeName);
297: PetscOptionsGetString(((PetscObject)rnd)->prefix, "-random_view_file", fileName, 1024, &opt);
298: if (opt) {
299: PetscViewerFileSetName(viewer, fileName);
300: } else {
301: PetscViewerFileSetName(viewer, ((PetscObject)rnd)->name);
302: }
303: PetscRandomView(rnd, viewer);
304: PetscViewerFlush(viewer);
305: PetscViewerDestroy(&viewer);
306: } else {
307: PetscViewer viewer;
308: PetscViewerASCIIGetStdout(((PetscObject)rnd)->comm,&viewer);
309: PetscRandomView(rnd, viewer);
310: }
311: }
312: return(0);
313: }
315: #if defined(PETSC_HAVE_AMS)
318: static PetscErrorCode PetscRandomPublish_Petsc(PetscObject obj)
319: {
320: PetscRandom rand = (PetscRandom) obj;
324: AMS_Memory_add_field(obj->amem,"Low",&rand->low,1,AMS_DOUBLE,AMS_READ,AMS_COMMON,AMS_REDUCT_UNDEF);
325: return(0);
326: }
327: #endif
331: /*@
332: PetscRandomCreate - Creates a context for generating random numbers,
333: and initializes the random-number generator.
335: Collective on MPI_Comm
337: Input Parameters:
338: + comm - MPI communicator
340: Output Parameter:
341: . r - the random number generator context
343: Level: intermediate
345: Notes:
346: The random type has to be set by PetscRandomSetType().
348: This is only a primative "parallel" random number generator, it should NOT
349: be used for sophisticated parallel Monte Carlo methods since it will very likely
350: not have the correct statistics across processors. You can provide your own
351: parallel generator using PetscRandomRegister();
353: If you create a PetscRandom() using PETSC_COMM_SELF on several processors then
354: the SAME random numbers will be generated on all those processors. Use PETSC_COMM_WORLD
355: or the appropriate parallel communicator to eliminate this issue.
357: Use VecSetRandom() to set the elements of a vector to random numbers.
359: Example of Usage:
360: .vb
361: PetscRandomCreate(PETSC_COMM_SELF,&r);
362: PetscRandomSetType(r,PETSCRAND48);
363: PetscRandomGetValue(r,&value1);
364: PetscRandomGetValueReal(r,&value2);
365: PetscRandomDestroy(&r);
366: .ve
368: Concepts: random numbers^creating
370: .seealso: PetscRandomSetType(), PetscRandomGetValue(), PetscRandomGetValueReal(), PetscRandomSetInterval(),
371: PetscRandomDestroy(), VecSetRandom(), PetscRandomType
372: @*/
374: PetscErrorCode PetscRandomCreate(MPI_Comm comm,PetscRandom *r)
375: {
376: PetscRandom rr;
378: PetscMPIInt rank;
382: *r = PETSC_NULL;
383: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
384: PetscRandomInitializePackage(PETSC_NULL);
385: #endif
387: PetscHeaderCreate(rr,_p_PetscRandom,struct _PetscRandomOps,PETSC_RANDOM_CLASSID,-1,"PetscRandom","Random number generator","Sys",comm,PetscRandomDestroy,0);
389: MPI_Comm_rank(comm,&rank);
390: rr->data = PETSC_NULL;
391: rr->low = 0.0;
392: rr->width = 1.0;
393: rr->iset = PETSC_FALSE;
394: rr->seed = 0x12345678 + 76543*rank;
395: #if defined(PETSC_HAVE_AMS)
396: ((PetscObject)rr)->bops->publish = PetscRandomPublish_Petsc;
397: #endif
398: *r = rr;
399: return(0);
400: }
404: /*@
405: PetscRandomSeed - Seed the generator.
407: Not collective
409: Input Parameters:
410: . r - The random number generator context
412: Level: intermediate
414: Usage:
415: PetscRandomSetSeed(r,a positive integer);
416: PetscRandomSeed(r); PetscRandomGetValue() will now start with the new seed.
418: PetscRandomSeed(r) without a call to PetscRandomSetSeed() re-initializes
419: the seed. The random numbers generated will be the same as before.
421: Concepts: random numbers^seed
423: .seealso: PetscRandomCreate(), PetscRandomGetSeed(), PetscRandomSetSeed()
424: @*/
425: PetscErrorCode PetscRandomSeed(PetscRandom r)
426: {
433: (*r->ops->seed)(r);
434: PetscObjectStateIncrease((PetscObject)r);
435: return(0);
436: }