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