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