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