Actual source code: randomc.c
petsc-3.6.1 2015-08-06
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(PetscOptions *PetscOptionsObject,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: PetscRandomRegisterAll();
149: PetscOptionsFList("-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(PetscOptionsObject,rnd);
193: /* Handle specific random generator's options */
194: if (rnd->ops->setfromoptions) {
195: (*rnd->ops->setfromoptions)(PetscOptionsObject,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_SAWS)
208: #include <petscviewersaws.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_SAWS)
241: PetscBool issaws;
242: #endif
247: if (!viewer) {
248: PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)rnd),&viewer);
249: }
252: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
253: #if defined(PETSC_HAVE_SAWS)
254: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);
255: #endif
256: if (iascii) {
257: PetscMPIInt rank;
258: PetscObjectPrintClassNamePrefixType((PetscObject)rnd,viewer);
259: MPI_Comm_rank(PetscObjectComm((PetscObject)rnd),&rank);
260: PetscViewerASCIISynchronizedAllow(viewer,PETSC_TRUE);
261: PetscViewerASCIISynchronizedPrintf(viewer,"[%D] Random type %s, seed %D\n",rank,((PetscObject)rnd)->type_name,rnd->seed);
262: PetscViewerFlush(viewer);
263: PetscViewerASCIISynchronizedAllow(viewer,PETSC_FALSE);
264: #if defined(PETSC_HAVE_SAWS)
265: } else if (issaws) {
266: PetscMPIInt rank;
267: const char *name;
269: PetscObjectGetName((PetscObject)rnd,&name);
270: MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
271: if (!((PetscObject)rnd)->amsmem && !rank) {
272: char dir[1024];
274: PetscObjectViewSAWs((PetscObject)rnd,viewer);
275: PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/Low",name);
276: PetscStackCallSAWs(SAWs_Register,(dir,&rnd->low,1,SAWs_READ,SAWs_DOUBLE));
277: }
278: #endif
279: }
280: return(0);
281: }
285: /*@
286: PetscRandomCreate - Creates a context for generating random numbers,
287: and initializes the random-number generator.
289: Collective on MPI_Comm
291: Input Parameters:
292: + comm - MPI communicator
294: Output Parameter:
295: . r - the random number generator context
297: Level: intermediate
299: Notes:
300: The random type has to be set by PetscRandomSetType().
302: This is only a primative "parallel" random number generator, it should NOT
303: be used for sophisticated parallel Monte Carlo methods since it will very likely
304: not have the correct statistics across processors. You can provide your own
305: parallel generator using PetscRandomRegister();
307: If you create a PetscRandom() using PETSC_COMM_SELF on several processors then
308: the SAME random numbers will be generated on all those processors. Use PETSC_COMM_WORLD
309: or the appropriate parallel communicator to eliminate this issue.
311: Use VecSetRandom() to set the elements of a vector to random numbers.
313: Example of Usage:
314: .vb
315: PetscRandomCreate(PETSC_COMM_SELF,&r);
316: PetscRandomSetType(r,PETSCRAND48);
317: PetscRandomGetValue(r,&value1);
318: PetscRandomGetValueReal(r,&value2);
319: PetscRandomDestroy(&r);
320: .ve
322: Concepts: random numbers^creating
324: .seealso: PetscRandomSetType(), PetscRandomGetValue(), PetscRandomGetValueReal(), PetscRandomSetInterval(),
325: PetscRandomDestroy(), VecSetRandom(), PetscRandomType
326: @*/
328: PetscErrorCode PetscRandomCreate(MPI_Comm comm,PetscRandom *r)
329: {
330: PetscRandom rr;
332: PetscMPIInt rank;
336: *r = NULL;
337: PetscRandomInitializePackage();
339: PetscHeaderCreate(rr,PETSC_RANDOM_CLASSID,"PetscRandom","Random number generator","Sys",comm,PetscRandomDestroy,NULL);
341: MPI_Comm_rank(comm,&rank);
343: rr->data = NULL;
344: rr->low = 0.0;
345: rr->width = 1.0;
346: rr->iset = PETSC_FALSE;
347: rr->seed = 0x12345678 + 76543*rank;
348: *r = rr;
349: return(0);
350: }
354: /*@
355: PetscRandomSeed - Seed the generator.
357: Not collective
359: Input Parameters:
360: . r - The random number generator context
362: Level: intermediate
364: Usage:
365: PetscRandomSetSeed(r,a positive integer);
366: PetscRandomSeed(r); PetscRandomGetValue() will now start with the new seed.
368: PetscRandomSeed(r) without a call to PetscRandomSetSeed() re-initializes
369: the seed. The random numbers generated will be the same as before.
371: Concepts: random numbers^seed
373: .seealso: PetscRandomCreate(), PetscRandomGetSeed(), PetscRandomSetSeed()
374: @*/
375: PetscErrorCode PetscRandomSeed(PetscRandom r)
376: {
383: (*r->ops->seed)(r);
384: PetscObjectStateIncrease((PetscObject)r);
385: return(0);
386: }