Actual source code: randomc.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>
16: #include <petscviewer.h>
18: /* Logging support */
19: PetscClassId PETSC_RANDOM_CLASSID;
21: /*@C
22: PetscRandomDestroy - Destroys a context that has been formed by
23: PetscRandomCreate().
25: Collective on PetscRandom
27: Input Parameter:
28: . r - the random number generator context
30: Level: intermediate
32: .seealso: PetscRandomGetValue(), PetscRandomCreate(), VecSetRandom()
33: @*/
34: PetscErrorCode PetscRandomDestroy(PetscRandom *r)
35: {
36: if (!*r) return 0;
38: if (--((PetscObject)(*r))->refct > 0) {*r = NULL; return 0;}
39: if ((*r)->ops->destroy) {
40: (*(*r)->ops->destroy)(*r);
41: }
42: PetscHeaderDestroy(r);
43: return 0;
44: }
46: /*@C
47: PetscRandomGetSeed - Gets the random seed.
49: Not collective
51: Input Parameters:
52: . r - The random number generator context
54: Output Parameter:
55: . seed - The random seed
57: Level: intermediate
59: .seealso: PetscRandomCreate(), PetscRandomSetSeed(), PetscRandomSeed()
60: @*/
61: PetscErrorCode PetscRandomGetSeed(PetscRandom r,unsigned long *seed)
62: {
64: if (seed) {
66: *seed = r->seed;
67: }
68: return 0;
69: }
71: /*@C
72: PetscRandomSetSeed - Sets the random seed. You MUST call PetscRandomSeed() after this call to have the new seed used.
74: Not collective
76: Input Parameters:
77: + r - The random number generator context
78: - seed - The random seed
80: Level: intermediate
82: Usage:
83: PetscRandomSetSeed(r,a positive integer);
84: PetscRandomSeed(r); PetscRandomGetValue() will now start with the new seed.
86: PetscRandomSeed(r) without a call to PetscRandomSetSeed() re-initializes
87: the seed. The random numbers generated will be the same as before.
89: .seealso: PetscRandomCreate(), PetscRandomGetSeed(), PetscRandomSeed()
90: @*/
91: PetscErrorCode PetscRandomSetSeed(PetscRandom r,unsigned long seed)
92: {
94: r->seed = seed;
95: PetscInfo(NULL,"Setting seed to %d\n",(int)seed);
96: return 0;
97: }
99: /* ------------------------------------------------------------------- */
100: /*
101: PetscRandomSetTypeFromOptions_Private - Sets the type of random generator from user options. Defaults to type PETSCRAND48 or PETSCRAND.
103: Collective on PetscRandom
105: Input Parameter:
106: . rnd - The random number generator context
108: Level: intermediate
110: .seealso: PetscRandomSetFromOptions(), PetscRandomSetType()
111: */
112: static PetscErrorCode PetscRandomSetTypeFromOptions_Private(PetscOptionItems *PetscOptionsObject,PetscRandom rnd)
113: {
114: PetscBool opt;
115: const char *defaultType;
116: char typeName[256];
118: if (((PetscObject)rnd)->type_name) {
119: defaultType = ((PetscObject)rnd)->type_name;
120: } else {
121: defaultType = PETSCRANDER48;
122: }
124: PetscRandomRegisterAll();
125: PetscOptionsFList("-random_type","PetscRandom type","PetscRandomSetType",PetscRandomList,defaultType,typeName,256,&opt);
126: if (opt) {
127: PetscRandomSetType(rnd, typeName);
128: } else {
129: PetscRandomSetType(rnd, defaultType);
130: }
131: return 0;
132: }
134: /*@
135: PetscRandomSetFromOptions - Configures the random number generator from the options database.
137: Collective on PetscRandom
139: Input Parameter:
140: . rnd - The random number generator context
142: Options Database:
143: + -random_seed <integer> - provide a seed to the random number generater
144: - -random_no_imaginary_part - makes the imaginary part of the random number zero, this is useful when you want the
145: same code to produce the same result when run with real numbers or complex numbers for regression testing purposes
147: Notes:
148: To see all options, run your program with the -help option.
149: Must be called after PetscRandomCreate() but before the rnd is used.
151: Level: beginner
153: .seealso: PetscRandomCreate(), PetscRandomSetType()
154: @*/
155: PetscErrorCode PetscRandomSetFromOptions(PetscRandom rnd)
156: {
158: PetscBool set,noimaginary = PETSC_FALSE;
159: PetscInt seed;
163: PetscObjectOptionsBegin((PetscObject)rnd);
165: /* Handle PetscRandom type options */
166: PetscRandomSetTypeFromOptions_Private(PetscOptionsObject,rnd);
168: /* Handle specific random generator's options */
169: if (rnd->ops->setfromoptions) {
170: (*rnd->ops->setfromoptions)(PetscOptionsObject,rnd);
171: }
172: PetscOptionsInt("-random_seed","Seed to use to generate random numbers","PetscRandomSetSeed",0,&seed,&set);
173: if (set) {
174: PetscRandomSetSeed(rnd,(unsigned long int)seed);
175: PetscRandomSeed(rnd);
176: }
177: PetscOptionsBool("-random_no_imaginary_part","The imaginary part of the random number will be zero","PetscRandomSetInterval",noimaginary,&noimaginary,&set);
178: #if defined(PETSC_HAVE_COMPLEX)
179: if (set) {
180: if (noimaginary) {
181: PetscScalar low,high;
182: PetscRandomGetInterval(rnd,&low,&high);
183: low = low - PetscImaginaryPart(low);
184: high = high - PetscImaginaryPart(high);
185: PetscRandomSetInterval(rnd,low,high);
186: }
187: }
188: #endif
189: PetscOptionsEnd();
190: PetscRandomViewFromOptions(rnd,NULL, "-random_view");
191: return 0;
192: }
194: #if defined(PETSC_HAVE_SAWS)
195: #include <petscviewersaws.h>
196: #endif
198: /*@C
199: PetscRandomViewFromOptions - View from Options
201: Collective on PetscRandom
203: Input Parameters:
204: + A - the random number generator context
205: . obj - Optional object
206: - name - command line option
208: Level: intermediate
209: .seealso: PetscRandom, PetscRandomView, PetscObjectViewFromOptions(), PetscRandomCreate()
210: @*/
211: PetscErrorCode PetscRandomViewFromOptions(PetscRandom A,PetscObject obj,const char name[])
212: {
214: PetscObjectViewFromOptions((PetscObject)A,obj,name);
215: return 0;
216: }
218: /*@C
219: PetscRandomView - Views a random number generator object.
221: Collective on PetscRandom
223: Input Parameters:
224: + rnd - The random number generator context
225: - viewer - an optional visualization context
227: Notes:
228: The available visualization contexts include
229: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
230: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
231: output where only the first processor opens
232: the file. All other processors send their
233: data to the first processor to print.
235: You can change the format the vector is printed using the
236: option PetscViewerPushFormat().
238: Level: beginner
240: .seealso: PetscRealView(), PetscScalarView(), PetscIntView()
241: @*/
242: PetscErrorCode PetscRandomView(PetscRandom rnd,PetscViewer viewer)
243: {
244: PetscBool iascii;
245: #if defined(PETSC_HAVE_SAWS)
246: PetscBool issaws;
247: #endif
251: if (!viewer) {
252: PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)rnd),&viewer);
253: }
256: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
257: #if defined(PETSC_HAVE_SAWS)
258: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);
259: #endif
260: if (iascii) {
261: PetscMPIInt rank;
262: PetscObjectPrintClassNamePrefixType((PetscObject)rnd,viewer);
263: MPI_Comm_rank(PetscObjectComm((PetscObject)rnd),&rank);
264: PetscViewerASCIIPushSynchronized(viewer);
265: PetscViewerASCIISynchronizedPrintf(viewer,"[%d] Random type %s, seed %lu\n",rank,((PetscObject)rnd)->type_name,rnd->seed);
266: PetscViewerFlush(viewer);
267: PetscViewerASCIIPopSynchronized(viewer);
268: #if defined(PETSC_HAVE_SAWS)
269: } else if (issaws) {
270: PetscMPIInt rank;
271: const char *name;
273: PetscObjectGetName((PetscObject)rnd,&name);
274: MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
275: if (!((PetscObject)rnd)->amsmem && rank == 0) {
276: char dir[1024];
278: PetscObjectViewSAWs((PetscObject)rnd,viewer);
279: PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/Low",name);
280: PetscStackCallSAWs(SAWs_Register,(dir,&rnd->low,1,SAWs_READ,SAWs_DOUBLE));
281: }
282: #endif
283: }
284: return 0;
285: }
287: /*@
288: PetscRandomCreate - Creates a context for generating random numbers,
289: and initializes the random-number generator.
291: Collective
293: Input Parameters:
294: . comm - MPI communicator
296: Output Parameter:
297: . r - the random number generator context
299: Level: intermediate
301: Notes:
302: The random type has to be set by PetscRandomSetType().
304: This is only a primitive "parallel" random number generator, it should NOT
305: be used for sophisticated parallel Monte Carlo methods since it will very likely
306: not have the correct statistics across processors. You can provide your own
307: parallel generator using PetscRandomRegister();
309: If you create a PetscRandom() using PETSC_COMM_SELF on several processors then
310: the SAME random numbers will be generated on all those processors. Use PETSC_COMM_WORLD
311: or the appropriate parallel communicator to eliminate this issue.
313: Use VecSetRandom() to set the elements of a vector to random numbers.
315: Example of Usage:
316: .vb
317: PetscRandomCreate(PETSC_COMM_SELF,&r);
318: PetscRandomSetType(r,PETSCRAND48);
319: PetscRandomGetValue(r,&value1);
320: PetscRandomGetValueReal(r,&value2);
321: PetscRandomDestroy(&r);
322: .ve
324: .seealso: PetscRandomSetType(), PetscRandomGetValue(), PetscRandomGetValueReal(), PetscRandomSetInterval(),
325: PetscRandomDestroy(), VecSetRandom(), PetscRandomType
326: @*/
328: PetscErrorCode PetscRandomCreate(MPI_Comm comm,PetscRandom *r)
329: {
330: PetscRandom rr;
331: PetscMPIInt rank;
334: *r = NULL;
335: PetscRandomInitializePackage();
337: PetscHeaderCreate(rr,PETSC_RANDOM_CLASSID,"PetscRandom","Random number generator","Sys",comm,PetscRandomDestroy,PetscRandomView);
339: MPI_Comm_rank(comm,&rank);
341: rr->data = NULL;
342: rr->low = 0.0;
343: rr->width = 1.0;
344: rr->iset = PETSC_FALSE;
345: rr->seed = 0x12345678 + 76543*rank;
346: PetscRandomSetType(rr,PETSCRANDER48);
347: *r = rr;
348: return 0;
349: }
351: /*@
352: PetscRandomSeed - Seed the generator.
354: Not collective
356: Input Parameters:
357: . r - The random number generator context
359: Level: intermediate
361: Usage:
362: PetscRandomSetSeed(r,a positive integer);
363: PetscRandomSeed(r); PetscRandomGetValue() will now start with the new seed.
365: PetscRandomSeed(r) without a call to PetscRandomSetSeed() re-initializes
366: the seed. The random numbers generated will be the same as before.
368: .seealso: PetscRandomCreate(), PetscRandomGetSeed(), PetscRandomSetSeed()
369: @*/
370: PetscErrorCode PetscRandomSeed(PetscRandom r)
371: {
375: (*r->ops->seed)(r);
376: PetscObjectStateIncrease((PetscObject)r);
377: return 0;
378: }