xref: /petsc/src/sys/classes/random/interface/random.c (revision 811af0c4b09a35de4306c442f88bd09fdc09897d)
15c6c1daeSBarry Smith 
25c6c1daeSBarry Smith /*
35c6c1daeSBarry Smith     This file contains routines for interfacing to random number generators.
45c6c1daeSBarry Smith     This provides more than just an interface to some system random number
55c6c1daeSBarry Smith     generator:
65c6c1daeSBarry Smith 
75c6c1daeSBarry Smith     Numbers can be shuffled for use as random tuples
85c6c1daeSBarry Smith 
95c6c1daeSBarry Smith     Multiple random number generators may be used
105c6c1daeSBarry Smith 
115c6c1daeSBarry Smith     We are still not sure what interface we want here.  There should be
125c6c1daeSBarry Smith     one to reinitialize and set the seed.
135c6c1daeSBarry Smith  */
145c6c1daeSBarry Smith 
15d6cc7855SJacob Faibussowitsch #include <petsc/private/randomimpl.h> /*I "petscsys.h" I*/
165c6c1daeSBarry Smith 
175c6c1daeSBarry Smith /*@
185c6c1daeSBarry Smith    PetscRandomGetValue - Generates a random number.  Call this after first calling
19*811af0c4SBarry Smith    `PetscRandomCreate()`.
205c6c1daeSBarry Smith 
215c6c1daeSBarry Smith    Not Collective
225c6c1daeSBarry Smith 
2301d2d390SJose E. Roman    Input Parameter:
245c6c1daeSBarry Smith .  r  - the random number generator context
255c6c1daeSBarry Smith 
265c6c1daeSBarry Smith    Output Parameter:
275c6c1daeSBarry Smith .  val - the value
285c6c1daeSBarry Smith 
295c6c1daeSBarry Smith    Level: intermediate
305c6c1daeSBarry Smith 
315c6c1daeSBarry Smith    Notes:
32*811af0c4SBarry Smith    Use `VecSetRandom()` to set the elements of a vector to random numbers.
335c6c1daeSBarry Smith 
345c6c1daeSBarry Smith    When PETSc is compiled for complex numbers this returns a complex number with random real and complex parts.
35*811af0c4SBarry Smith    Use `PetscRandomGetValueReal()` to get a random real number.
365c6c1daeSBarry Smith 
37*811af0c4SBarry Smith    To get a complex number with only a random real part, first call `PetscRandomSetInterval()` with a equal
385c6c1daeSBarry Smith    low and high imaginary part. Similarly to get a complex number with only a random imaginary part call
39*811af0c4SBarry Smith    `PetscRandomSetInterval()` with a equal low and high real part.
405c6c1daeSBarry Smith 
415c6c1daeSBarry Smith    Example of Usage:
425c6c1daeSBarry Smith .vb
435c6c1daeSBarry Smith       PetscRandomCreate(PETSC_COMM_WORLD,&r);
445c6c1daeSBarry Smith       PetscRandomGetValue(r,&value1);
455c6c1daeSBarry Smith       PetscRandomGetValue(r,&value2);
465c6c1daeSBarry Smith       PetscRandomGetValue(r,&value3);
475c6c1daeSBarry Smith       PetscRandomDestroy(&r);
485c6c1daeSBarry Smith .ve
495c6c1daeSBarry Smith 
50*811af0c4SBarry Smith .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomDestroy()`, `VecSetRandom()`, `PetscRandomGetValueReal()`, `PetscRandomSetInterval()`
515c6c1daeSBarry Smith @*/
529371c9d4SSatish Balay PetscErrorCode PetscRandomGetValue(PetscRandom r, PetscScalar *val) {
535c6c1daeSBarry Smith   PetscFunctionBegin;
545c6c1daeSBarry Smith   PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1);
555c6c1daeSBarry Smith   PetscValidType(r, 1);
56dbbe0bcdSBarry Smith   if (!r->ops->getvalue) PetscUseTypeMethod(r, getvalues, 1, val);
57dbbe0bcdSBarry Smith   else PetscUseTypeMethod(r, getvalue, val);
589566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)r));
595c6c1daeSBarry Smith   PetscFunctionReturn(0);
605c6c1daeSBarry Smith }
615c6c1daeSBarry Smith 
625c6c1daeSBarry Smith /*@
63808ba619SStefano Zampini    PetscRandomGetValueReal - Generates a real random number.  Call this after first calling
64*811af0c4SBarry Smith    `PetscRandomCreate()`.
655c6c1daeSBarry Smith 
665c6c1daeSBarry Smith    Not Collective
675c6c1daeSBarry Smith 
6801d2d390SJose E. Roman    Input Parameter:
695c6c1daeSBarry Smith .  r  - the random number generator context
705c6c1daeSBarry Smith 
715c6c1daeSBarry Smith    Output Parameter:
725c6c1daeSBarry Smith .  val - the value
735c6c1daeSBarry Smith 
745c6c1daeSBarry Smith    Level: intermediate
755c6c1daeSBarry Smith 
76*811af0c4SBarry Smith    Note:
77*811af0c4SBarry Smith    Use `VecSetRandom()` to set the elements of a vector to random numbers.
785c6c1daeSBarry Smith 
795c6c1daeSBarry Smith    Example of Usage:
805c6c1daeSBarry Smith .vb
815c6c1daeSBarry Smith       PetscRandomCreate(PETSC_COMM_WORLD,&r);
825c6c1daeSBarry Smith       PetscRandomGetValueReal(r,&value1);
835c6c1daeSBarry Smith       PetscRandomGetValueReal(r,&value2);
845c6c1daeSBarry Smith       PetscRandomGetValueReal(r,&value3);
855c6c1daeSBarry Smith       PetscRandomDestroy(&r);
865c6c1daeSBarry Smith .ve
875c6c1daeSBarry Smith 
88*811af0c4SBarry Smith .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomDestroy()`, `VecSetRandom()`, `PetscRandomGetValue()`
895c6c1daeSBarry Smith @*/
909371c9d4SSatish Balay PetscErrorCode PetscRandomGetValueReal(PetscRandom r, PetscReal *val) {
915c6c1daeSBarry Smith   PetscFunctionBegin;
925c6c1daeSBarry Smith   PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1);
935c6c1daeSBarry Smith   PetscValidType(r, 1);
94dbbe0bcdSBarry Smith   if (!r->ops->getvaluereal) PetscUseTypeMethod(r, getvaluesreal, 1, val);
95dbbe0bcdSBarry Smith   else PetscUseTypeMethod(r, getvaluereal, val);
969566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)r));
97808ba619SStefano Zampini   PetscFunctionReturn(0);
98808ba619SStefano Zampini }
99808ba619SStefano Zampini 
100808ba619SStefano Zampini /*@
101808ba619SStefano Zampini    PetscRandomGetValues - Generates a sequence of random numbers.  Call this after first calling
102*811af0c4SBarry Smith    `PetscRandomCreate()`.
103808ba619SStefano Zampini 
104808ba619SStefano Zampini    Not Collective
105808ba619SStefano Zampini 
10601d2d390SJose E. Roman    Input Parameters:
107808ba619SStefano Zampini +  r  - the random number generator context
108808ba619SStefano Zampini -  n  - number of random numbers to generate
109808ba619SStefano Zampini 
110808ba619SStefano Zampini    Output Parameter:
111808ba619SStefano Zampini .  val - the array to hold the values
112808ba619SStefano Zampini 
113808ba619SStefano Zampini    Level: intermediate
114808ba619SStefano Zampini 
115808ba619SStefano Zampini    Notes:
116*811af0c4SBarry Smith    Use `VecSetRandom()` to set the elements of a vector to random numbers.
117808ba619SStefano Zampini 
118808ba619SStefano Zampini    When PETSc is compiled for complex numbers this returns an array of complex numbers with random real and complex parts.
119*811af0c4SBarry Smith    Use `PetscRandomGetValuesReal()` to get an array of random real numbers.
120808ba619SStefano Zampini 
121*811af0c4SBarry Smith .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomDestroy()`, `VecSetRandom()`, `PetscRandomGetValue()`
122808ba619SStefano Zampini @*/
1239371c9d4SSatish Balay PetscErrorCode PetscRandomGetValues(PetscRandom r, PetscInt n, PetscScalar *val) {
124808ba619SStefano Zampini   PetscFunctionBegin;
125808ba619SStefano Zampini   PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1);
126808ba619SStefano Zampini   PetscValidType(r, 1);
127808ba619SStefano Zampini   if (!r->ops->getvalues) {
128808ba619SStefano Zampini     PetscInt i;
12948a46eb9SPierre Jolivet     for (i = 0; i < n; i++) PetscCall((*r->ops->getvalue)(r, val + i));
130dbbe0bcdSBarry Smith   } else PetscUseTypeMethod(r, getvalues, n, val);
1319566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)r));
132808ba619SStefano Zampini   PetscFunctionReturn(0);
133808ba619SStefano Zampini }
134808ba619SStefano Zampini 
135808ba619SStefano Zampini /*@
136808ba619SStefano Zampini    PetscRandomGetValuesReal - Generates a sequence of real random numbers.  Call this after first calling
137*811af0c4SBarry Smith    `PetscRandomCreate()`.
138808ba619SStefano Zampini 
139808ba619SStefano Zampini    Not Collective
140808ba619SStefano Zampini 
14101d2d390SJose E. Roman    Input Parameters:
142808ba619SStefano Zampini +  r  - the random number generator context
143808ba619SStefano Zampini -  n  - number of random numbers to generate
144808ba619SStefano Zampini 
145808ba619SStefano Zampini    Output Parameter:
146808ba619SStefano Zampini .  val - the array to hold the values
147808ba619SStefano Zampini 
148808ba619SStefano Zampini    Level: intermediate
149808ba619SStefano Zampini 
150*811af0c4SBarry Smith    Note:
151*811af0c4SBarry Smith    Use `VecSetRandom()` to set the elements of a vector to random numbers.
152808ba619SStefano Zampini 
153*811af0c4SBarry Smith .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomDestroy()`, `VecSetRandom()`, `PetscRandomGetValues()`
154808ba619SStefano Zampini @*/
1559371c9d4SSatish Balay PetscErrorCode PetscRandomGetValuesReal(PetscRandom r, PetscInt n, PetscReal *val) {
156808ba619SStefano Zampini   PetscFunctionBegin;
157808ba619SStefano Zampini   PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1);
158808ba619SStefano Zampini   PetscValidType(r, 1);
159808ba619SStefano Zampini   if (!r->ops->getvaluesreal) {
160808ba619SStefano Zampini     PetscInt i;
16148a46eb9SPierre Jolivet     for (i = 0; i < n; i++) PetscCall((*r->ops->getvaluereal)(r, val + i));
162dbbe0bcdSBarry Smith   } else PetscUseTypeMethod(r, getvaluesreal, n, val);
1639566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)r));
1645c6c1daeSBarry Smith   PetscFunctionReturn(0);
1655c6c1daeSBarry Smith }
1665c6c1daeSBarry Smith 
1675c6c1daeSBarry Smith /*@
1685c6c1daeSBarry Smith    PetscRandomGetInterval - Gets the interval over which the random numbers
169*811af0c4SBarry Smith    will be distributed.  By default, this interval is [0,1).
1705c6c1daeSBarry Smith 
1715c6c1daeSBarry Smith    Not collective
1725c6c1daeSBarry Smith 
173f899ff85SJose E. Roman    Input Parameter:
1745c6c1daeSBarry Smith .  r  - the random number generator context
1755c6c1daeSBarry Smith 
1765c6c1daeSBarry Smith    Output Parameters:
1775c6c1daeSBarry Smith +  low - The lower bound of the interval
1785c6c1daeSBarry Smith -  high - The upper bound of the interval
1795c6c1daeSBarry Smith 
1805c6c1daeSBarry Smith    Level: intermediate
1815c6c1daeSBarry Smith 
182*811af0c4SBarry Smith .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomSetInterval()`
1835c6c1daeSBarry Smith @*/
1849371c9d4SSatish Balay PetscErrorCode PetscRandomGetInterval(PetscRandom r, PetscScalar *low, PetscScalar *high) {
1855c6c1daeSBarry Smith   PetscFunctionBegin;
1865c6c1daeSBarry Smith   PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1);
1875c6c1daeSBarry Smith   if (low) {
1885c6c1daeSBarry Smith     PetscValidScalarPointer(low, 2);
1895c6c1daeSBarry Smith     *low = r->low;
1905c6c1daeSBarry Smith   }
1915c6c1daeSBarry Smith   if (high) {
1925c6c1daeSBarry Smith     PetscValidScalarPointer(high, 3);
1935c6c1daeSBarry Smith     *high = r->low + r->width;
1945c6c1daeSBarry Smith   }
1955c6c1daeSBarry Smith   PetscFunctionReturn(0);
1965c6c1daeSBarry Smith }
1975c6c1daeSBarry Smith 
1985c6c1daeSBarry Smith /*@
1995c6c1daeSBarry Smith    PetscRandomSetInterval - Sets the interval over which the random numbers
200*811af0c4SBarry Smith    will be distributed.  By default, this interval is [0,1).
2015c6c1daeSBarry Smith 
2025c6c1daeSBarry Smith    Not collective
2035c6c1daeSBarry Smith 
2045c6c1daeSBarry Smith    Input Parameters:
2055c6c1daeSBarry Smith +  r  - the random number generator context
2065c6c1daeSBarry Smith .  low - The lower bound of the interval
2075c6c1daeSBarry Smith -  high - The upper bound of the interval
2085c6c1daeSBarry Smith 
2095c6c1daeSBarry Smith    Level: intermediate
2105c6c1daeSBarry Smith 
21195452b02SPatrick Sanan    Notes:
21295452b02SPatrick Sanan     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.
213*811af0c4SBarry Smith 
2145c6c1daeSBarry 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.
2155c6c1daeSBarry Smith 
216db781477SPatrick Sanan .seealso: `PetscRandomCreate()`, `PetscRandomGetInterval()`
2175c6c1daeSBarry Smith @*/
2189371c9d4SSatish Balay PetscErrorCode PetscRandomSetInterval(PetscRandom r, PetscScalar low, PetscScalar high) {
2195c6c1daeSBarry Smith   PetscFunctionBegin;
2205c6c1daeSBarry Smith   PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1);
2215c6c1daeSBarry Smith #if defined(PETSC_USE_COMPLEX)
22208401ef6SPierre Jolivet   PetscCheck(PetscRealPart(low) <= PetscRealPart(high), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "only low <= high");
22308401ef6SPierre Jolivet   PetscCheck(PetscImaginaryPart(low) <= PetscImaginaryPart(high), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "only low <= high");
2245c6c1daeSBarry Smith #else
22508401ef6SPierre Jolivet   PetscCheck(low < high, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "only low <= high: Instead %g %g", (double)low, (double)high);
2265c6c1daeSBarry Smith #endif
2275c6c1daeSBarry Smith   r->low   = low;
2285c6c1daeSBarry Smith   r->width = high - low;
2295c6c1daeSBarry Smith   r->iset  = PETSC_TRUE;
2305c6c1daeSBarry Smith   PetscFunctionReturn(0);
2315c6c1daeSBarry Smith }
232