1 
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:
6 
7     Numbers can be shuffled for use as random tuples
8 
9     Multiple random number generators may be used
10 
11     We are still not sure what interface we want here.  There should be
12     one to reinitialize and set the seed.
13  */
14 
15 #include <../src/sys/classes/random/randomimpl.h>                              /*I "petscsys.h" I*/
16 
17 /*@
18    PetscRandomGetValue - Generates a random number.  Call this after first calling
19    PetscRandomCreate().
20 
21    Not Collective
22 
23    Intput Parameter:
24 .  r  - the random number generator context
25 
26    Output Parameter:
27 .  val - the value
28 
29    Level: intermediate
30 
31    Notes:
32    Use VecSetRandom() to set the elements of a vector to random numbers.
33 
34    When PETSc is compiled for complex numbers this returns a complex number with random real and complex parts.
35    Use PetscGetValueReal() to get a random real number.
36 
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.
40 
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
49 
50 .seealso: PetscRandomCreate(), PetscRandomDestroy(), VecSetRandom(), PetscRandomGetValueReal()
51 @*/
PetscRandomGetValue(PetscRandom r,PetscScalar * val)52 PetscErrorCode  PetscRandomGetValue(PetscRandom r,PetscScalar *val)
53 {
54   PetscErrorCode ierr;
55 
56   PetscFunctionBegin;
57   PetscValidHeaderSpecific(r,PETSC_RANDOM_CLASSID,1);
58   PetscValidIntPointer(val,2);
59   PetscValidType(r,1);
60 
61   ierr = (*r->ops->getvalue)(r,val);CHKERRQ(ierr);
62   ierr = PetscObjectStateIncrease((PetscObject)r);CHKERRQ(ierr);
63   PetscFunctionReturn(0);
64 }
65 
66 /*@
67    PetscRandomGetValueReal - Generates a purely real random number.  Call this after first calling
68    PetscRandomCreate().
69 
70    Not Collective
71 
72    Intput Parameter:
73 .  r  - the random number generator context
74 
75    Output Parameter:
76 .  val - the value
77 
78    Level: intermediate
79 
80    Notes:
81    Use VecSetRandom() to set the elements of a vector to random numbers.
82 
83    Example of Usage:
84 .vb
85       PetscRandomCreate(PETSC_COMM_WORLD,&r);
86       PetscRandomGetValueReal(r,&value1);
87       PetscRandomGetValueReal(r,&value2);
88       PetscRandomGetValueReal(r,&value3);
89       PetscRandomDestroy(&r);
90 .ve
91 
92 .seealso: PetscRandomCreate(), PetscRandomDestroy(), VecSetRandom(), PetscRandomGetValue()
93 @*/
PetscRandomGetValueReal(PetscRandom r,PetscReal * val)94 PetscErrorCode  PetscRandomGetValueReal(PetscRandom r,PetscReal *val)
95 {
96   PetscErrorCode ierr;
97 
98   PetscFunctionBegin;
99   PetscValidHeaderSpecific(r,PETSC_RANDOM_CLASSID,1);
100   PetscValidIntPointer(val,2);
101   PetscValidType(r,1);
102 
103   ierr = (*r->ops->getvaluereal)(r,val);CHKERRQ(ierr);
104   ierr = PetscObjectStateIncrease((PetscObject)r);CHKERRQ(ierr);
105   PetscFunctionReturn(0);
106 }
107 
108 /*@
109    PetscRandomGetInterval - Gets the interval over which the random numbers
110    will be randomly distributed.  By default, this interval is [0,1).
111 
112    Not collective
113 
114    Input Parameters:
115 .  r  - the random number generator context
116 
117    Output Parameters:
118 +  low - The lower bound of the interval
119 -  high - The upper bound of the interval
120 
121    Level: intermediate
122 
123 .seealso: PetscRandomCreate(), PetscRandomSetInterval()
124 @*/
PetscRandomGetInterval(PetscRandom r,PetscScalar * low,PetscScalar * high)125 PetscErrorCode  PetscRandomGetInterval(PetscRandom r,PetscScalar *low,PetscScalar *high)
126 {
127   PetscFunctionBegin;
128   PetscValidHeaderSpecific(r,PETSC_RANDOM_CLASSID,1);
129   if (low) {
130     PetscValidScalarPointer(low,2);
131     *low = r->low;
132   }
133   if (high) {
134     PetscValidScalarPointer(high,3);
135     *high = r->low+r->width;
136   }
137   PetscFunctionReturn(0);
138 }
139 
140 /*@
141    PetscRandomSetInterval - Sets the interval over which the random numbers
142    will be randomly distributed.  By default, this interval is [0,1).
143 
144    Not collective
145 
146    Input Parameters:
147 +  r  - the random number generator context
148 .  low - The lower bound of the interval
149 -  high - The upper bound of the interval
150 
151    Level: intermediate
152 
153    Notes:
154     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.
155     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.
156 
157 .seealso: PetscRandomCreate(), PetscRandomGetInterval()
158 @*/
PetscRandomSetInterval(PetscRandom r,PetscScalar low,PetscScalar high)159 PetscErrorCode  PetscRandomSetInterval(PetscRandom r,PetscScalar low,PetscScalar high)
160 {
161   PetscFunctionBegin;
162   PetscValidHeaderSpecific(r,PETSC_RANDOM_CLASSID,1);
163 #if defined(PETSC_USE_COMPLEX)
164   if (PetscRealPart(low) > PetscRealPart(high))           SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"only low <= high");
165   if (PetscImaginaryPart(low) > PetscImaginaryPart(high)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"only low <= high");
166 #else
167   if (low >= high) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"only low <= high: Instead %g %g",(double)low,(double)high);
168 #endif
169   r->low   = low;
170   r->width = high-low;
171   r->iset  = PETSC_TRUE;
172   PetscFunctionReturn(0);
173 }
174