xref: /petsc/src/sys/classes/random/interface/random.c (revision fe998a80077c9ee0917a39496df43fc256e1b478)
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 #undef __FUNCT__
18 #define __FUNCT__ "PetscRandomGetValue"
19 /*@
20    PetscRandomGetValue - Generates a random number.  Call this after first calling
21    PetscRandomCreate().
22 
23    Not Collective
24 
25    Intput Parameter:
26 .  r  - the random number generator context
27 
28    Output Parameter:
29 .  val - the value
30 
31    Level: intermediate
32 
33    Notes:
34    Use VecSetRandom() to set the elements of a vector to random numbers.
35 
36    When PETSc is compiled for complex numbers this returns a complex number with random real and complex parts.
37    Use PetscGetValueReal() to get a random real number.
38 
39    To get a complex number with only a random real part, first call PetscRandomSetInterval() with a equal
40    low and high imaginary part. Similarly to get a complex number with only a random imaginary part call
41    PetscRandomSetInterval() with a equal low and high real part.
42 
43    Example of Usage:
44 .vb
45       PetscRandomCreate(PETSC_COMM_WORLD,&r);
46       PetscRandomGetValue(r,&value1);
47       PetscRandomGetValue(r,&value2);
48       PetscRandomGetValue(r,&value3);
49       PetscRandomDestroy(&r);
50 .ve
51 
52    Concepts: random numbers^getting
53 
54 .seealso: PetscRandomCreate(), PetscRandomDestroy(), VecSetRandom(), PetscRandomGetValueReal()
55 @*/
56 PetscErrorCode  PetscRandomGetValue(PetscRandom r,PetscScalar *val)
57 {
58   PetscErrorCode ierr;
59 
60   PetscFunctionBegin;
61   PetscValidHeaderSpecific(r,PETSC_RANDOM_CLASSID,1);
62   PetscValidIntPointer(val,2);
63   PetscValidType(r,1);
64 
65   ierr = (*r->ops->getvalue)(r,val);CHKERRQ(ierr);
66   ierr = PetscObjectStateIncrease((PetscObject)r);CHKERRQ(ierr);
67   PetscFunctionReturn(0);
68 }
69 
70 #undef __FUNCT__
71 #define __FUNCT__ "PetscRandomGetValueReal"
72 /*@
73    PetscRandomGetValueReal - Generates a purely real random number.  Call this after first calling
74    PetscRandomCreate().
75 
76    Not Collective
77 
78    Intput Parameter:
79 .  r  - the random number generator context
80 
81    Output Parameter:
82 .  val - the value
83 
84    Level: intermediate
85 
86    Notes:
87    Use VecSetRandom() to set the elements of a vector to random numbers.
88 
89    Example of Usage:
90 .vb
91       PetscRandomCreate(PETSC_COMM_WORLD,&r);
92       PetscRandomGetValueReal(r,&value1);
93       PetscRandomGetValueReal(r,&value2);
94       PetscRandomGetValueReal(r,&value3);
95       PetscRandomDestroy(&r);
96 .ve
97 
98    Concepts: random numbers^getting
99 
100 .seealso: PetscRandomCreate(), PetscRandomDestroy(), VecSetRandom(), PetscRandomGetValue()
101 @*/
102 PetscErrorCode  PetscRandomGetValueReal(PetscRandom r,PetscReal *val)
103 {
104   PetscErrorCode ierr;
105 
106   PetscFunctionBegin;
107   PetscValidHeaderSpecific(r,PETSC_RANDOM_CLASSID,1);
108   PetscValidIntPointer(val,2);
109   PetscValidType(r,1);
110 
111   ierr = (*r->ops->getvaluereal)(r,val);CHKERRQ(ierr);
112   ierr = PetscObjectStateIncrease((PetscObject)r);CHKERRQ(ierr);
113   PetscFunctionReturn(0);
114 }
115 
116 #undef __FUNCT__
117 #define __FUNCT__ "PetscRandomGetInterval"
118 /*@
119    PetscRandomGetInterval - Gets the interval over which the random numbers
120    will be randomly distributed.  By default, this interval is [0,1).
121 
122    Not collective
123 
124    Input Parameters:
125 .  r  - the random number generator context
126 
127    Output Parameters:
128 +  low - The lower bound of the interval
129 -  high - The upper bound of the interval
130 
131    Level: intermediate
132 
133    Concepts: random numbers^range
134 
135 .seealso: PetscRandomCreate(), PetscRandomSetInterval()
136 @*/
137 PetscErrorCode  PetscRandomGetInterval(PetscRandom r,PetscScalar *low,PetscScalar *high)
138 {
139   PetscFunctionBegin;
140   PetscValidHeaderSpecific(r,PETSC_RANDOM_CLASSID,1);
141   if (low) {
142     PetscValidScalarPointer(low,2);
143     *low = r->low;
144   }
145   if (high) {
146     PetscValidScalarPointer(high,3);
147     *high = r->low+r->width;
148   }
149   PetscFunctionReturn(0);
150 }
151 
152 #undef __FUNCT__
153 #define __FUNCT__ "PetscRandomSetInterval"
154 /*@
155    PetscRandomSetInterval - Sets the interval over which the random numbers
156    will be randomly distributed.  By default, this interval is [0,1).
157 
158    Not collective
159 
160    Input Parameters:
161 +  r  - the random number generator context
162 .  low - The lower bound of the interval
163 -  high - The upper bound of the interval
164 
165    Level: intermediate
166 
167    Notes: 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.
168     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.
169 
170    Concepts: random numbers^range
171 
172 .seealso: PetscRandomCreate(), PetscRandomGetInterval()
173 @*/
174 PetscErrorCode  PetscRandomSetInterval(PetscRandom r,PetscScalar low,PetscScalar high)
175 {
176   PetscFunctionBegin;
177   PetscValidHeaderSpecific(r,PETSC_RANDOM_CLASSID,1);
178 #if defined(PETSC_USE_COMPLEX)
179   if (PetscRealPart(low) > PetscRealPart(high))           SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"only low < high");
180   if (PetscImaginaryPart(low) > PetscImaginaryPart(high)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"only low < high");
181 #else
182   if (low >= high) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"only low < high: Instead %g %g",(double)low,(double)high);
183 #endif
184   r->low   = low;
185   r->width = high-low;
186   r->iset  = PETSC_TRUE;
187   PetscFunctionReturn(0);
188 }
189