xref: /petsc/src/sys/classes/random/interface/random.c (revision 1845a3b3cc898b5f1bae566a250aa1584f69f955)
15c6c1daeSBarry Smith /*
25c6c1daeSBarry Smith     This file contains routines for interfacing to random number generators.
35c6c1daeSBarry Smith     This provides more than just an interface to some system random number
45c6c1daeSBarry Smith     generator:
55c6c1daeSBarry Smith 
65c6c1daeSBarry Smith     Numbers can be shuffled for use as random tuples
75c6c1daeSBarry Smith 
85c6c1daeSBarry Smith     Multiple random number generators may be used
95c6c1daeSBarry Smith 
105c6c1daeSBarry Smith     We are still not sure what interface we want here.  There should be
115c6c1daeSBarry Smith     one to reinitialize and set the seed.
125c6c1daeSBarry Smith  */
135c6c1daeSBarry Smith 
14d6cc7855SJacob Faibussowitsch #include <petsc/private/randomimpl.h> /*I "petscsys.h" I*/
155c6c1daeSBarry Smith 
165c6c1daeSBarry Smith /*@
175c6c1daeSBarry Smith   PetscRandomGetValue - Generates a random number.  Call this after first calling
18811af0c4SBarry Smith   `PetscRandomCreate()`.
195c6c1daeSBarry Smith 
205c6c1daeSBarry Smith   Not Collective
215c6c1daeSBarry Smith 
2201d2d390SJose E. Roman   Input Parameter:
235c6c1daeSBarry Smith . r - the random number generator context
245c6c1daeSBarry Smith 
255c6c1daeSBarry Smith   Output Parameter:
265c6c1daeSBarry Smith . val - the value
275c6c1daeSBarry Smith 
285c6c1daeSBarry Smith   Level: intermediate
295c6c1daeSBarry Smith 
305c6c1daeSBarry Smith   Notes:
31811af0c4SBarry Smith   Use `VecSetRandom()` to set the elements of a vector to random numbers.
325c6c1daeSBarry Smith 
335c6c1daeSBarry Smith   When PETSc is compiled for complex numbers this returns a complex number with random real and complex parts.
34811af0c4SBarry Smith   Use `PetscRandomGetValueReal()` to get a random real number.
355c6c1daeSBarry Smith 
36811af0c4SBarry Smith   To get a complex number with only a random real part, first call `PetscRandomSetInterval()` with a equal
375c6c1daeSBarry Smith   low and high imaginary part. Similarly to get a complex number with only a random imaginary part call
38811af0c4SBarry Smith   `PetscRandomSetInterval()` with a equal low and high real part.
395c6c1daeSBarry Smith 
405c6c1daeSBarry Smith   Example of Usage:
415c6c1daeSBarry Smith .vb
425c6c1daeSBarry Smith       PetscRandomCreate(PETSC_COMM_WORLD,&r);
435c6c1daeSBarry Smith       PetscRandomGetValue(r,&value1);
445c6c1daeSBarry Smith       PetscRandomGetValue(r,&value2);
455c6c1daeSBarry Smith       PetscRandomGetValue(r,&value3);
465c6c1daeSBarry Smith       PetscRandomDestroy(&r);
475c6c1daeSBarry Smith .ve
485c6c1daeSBarry Smith 
49811af0c4SBarry Smith .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomDestroy()`, `VecSetRandom()`, `PetscRandomGetValueReal()`, `PetscRandomSetInterval()`
505c6c1daeSBarry Smith @*/
PetscRandomGetValue(PetscRandom r,PetscScalar * val)51d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscRandomGetValue(PetscRandom r, PetscScalar *val)
52d71ae5a4SJacob Faibussowitsch {
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));
593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
605c6c1daeSBarry Smith }
615c6c1daeSBarry Smith 
625c6c1daeSBarry Smith /*@
63808ba619SStefano Zampini   PetscRandomGetValueReal - Generates a real random number.  Call this after first calling
64811af0c4SBarry 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 
76811af0c4SBarry Smith   Note:
77811af0c4SBarry 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 
88811af0c4SBarry Smith .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomDestroy()`, `VecSetRandom()`, `PetscRandomGetValue()`
895c6c1daeSBarry Smith @*/
PetscRandomGetValueReal(PetscRandom r,PetscReal * val)90d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscRandomGetValueReal(PetscRandom r, PetscReal *val)
91d71ae5a4SJacob Faibussowitsch {
925c6c1daeSBarry Smith   PetscFunctionBegin;
935c6c1daeSBarry Smith   PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1);
945c6c1daeSBarry Smith   PetscValidType(r, 1);
95dbbe0bcdSBarry Smith   if (!r->ops->getvaluereal) PetscUseTypeMethod(r, getvaluesreal, 1, val);
96dbbe0bcdSBarry Smith   else PetscUseTypeMethod(r, getvaluereal, val);
979566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)r));
983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
99808ba619SStefano Zampini }
100808ba619SStefano Zampini 
101808ba619SStefano Zampini /*@
102808ba619SStefano Zampini   PetscRandomGetValues - Generates a sequence of random numbers.  Call this after first calling
103811af0c4SBarry Smith   `PetscRandomCreate()`.
104808ba619SStefano Zampini 
105808ba619SStefano Zampini   Not Collective
106808ba619SStefano Zampini 
10701d2d390SJose E. Roman   Input Parameters:
108808ba619SStefano Zampini + r - the random number generator context
109808ba619SStefano Zampini - n - number of random numbers to generate
110808ba619SStefano Zampini 
111808ba619SStefano Zampini   Output Parameter:
112808ba619SStefano Zampini . val - the array to hold the values
113808ba619SStefano Zampini 
114808ba619SStefano Zampini   Level: intermediate
115808ba619SStefano Zampini 
116808ba619SStefano Zampini   Notes:
117811af0c4SBarry Smith   Use `VecSetRandom()` to set the elements of a vector to random numbers.
118808ba619SStefano Zampini 
119808ba619SStefano Zampini   When PETSc is compiled for complex numbers this returns an array of complex numbers with random real and complex parts.
120811af0c4SBarry Smith   Use `PetscRandomGetValuesReal()` to get an array of random real numbers.
121808ba619SStefano Zampini 
122811af0c4SBarry Smith .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomDestroy()`, `VecSetRandom()`, `PetscRandomGetValue()`
123808ba619SStefano Zampini @*/
PetscRandomGetValues(PetscRandom r,PetscInt n,PetscScalar * val)124d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscRandomGetValues(PetscRandom r, PetscInt n, PetscScalar *val)
125d71ae5a4SJacob Faibussowitsch {
126808ba619SStefano Zampini   PetscFunctionBegin;
127808ba619SStefano Zampini   PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1);
128808ba619SStefano Zampini   PetscValidType(r, 1);
129808ba619SStefano Zampini   if (!r->ops->getvalues) {
13088ba4fe4SJacob Faibussowitsch     PetscErrorCode (*const getvalue)(PetscRandom, PetscScalar *) = r->ops->getvalue;
13188ba4fe4SJacob Faibussowitsch 
13288ba4fe4SJacob Faibussowitsch     for (PetscInt i = 0; i < n; ++i) PetscCall(getvalue(r, val + i));
133dbbe0bcdSBarry Smith   } else PetscUseTypeMethod(r, getvalues, n, val);
1349566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)r));
1353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
136808ba619SStefano Zampini }
137808ba619SStefano Zampini 
138808ba619SStefano Zampini /*@
139808ba619SStefano Zampini   PetscRandomGetValuesReal - Generates a sequence of real random numbers.  Call this after first calling
140811af0c4SBarry Smith   `PetscRandomCreate()`.
141808ba619SStefano Zampini 
142808ba619SStefano Zampini   Not Collective
143808ba619SStefano Zampini 
14401d2d390SJose E. Roman   Input Parameters:
145808ba619SStefano Zampini + r - the random number generator context
146808ba619SStefano Zampini - n - number of random numbers to generate
147808ba619SStefano Zampini 
148808ba619SStefano Zampini   Output Parameter:
149808ba619SStefano Zampini . val - the array to hold the values
150808ba619SStefano Zampini 
151808ba619SStefano Zampini   Level: intermediate
152808ba619SStefano Zampini 
153811af0c4SBarry Smith   Note:
154811af0c4SBarry Smith   Use `VecSetRandom()` to set the elements of a vector to random numbers.
155808ba619SStefano Zampini 
156811af0c4SBarry Smith .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomDestroy()`, `VecSetRandom()`, `PetscRandomGetValues()`
157808ba619SStefano Zampini @*/
PetscRandomGetValuesReal(PetscRandom r,PetscInt n,PetscReal * val)158d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscRandomGetValuesReal(PetscRandom r, PetscInt n, PetscReal *val)
159d71ae5a4SJacob Faibussowitsch {
160808ba619SStefano Zampini   PetscFunctionBegin;
161808ba619SStefano Zampini   PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1);
162808ba619SStefano Zampini   PetscValidType(r, 1);
163808ba619SStefano Zampini   if (!r->ops->getvaluesreal) {
164808ba619SStefano Zampini     PetscInt i;
165*9927e4dfSBarry Smith     for (i = 0; i < n; i++) PetscUseTypeMethod(r, getvaluereal, val + i);
166dbbe0bcdSBarry Smith   } else PetscUseTypeMethod(r, getvaluesreal, n, val);
1679566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)r));
1683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1695c6c1daeSBarry Smith }
1705c6c1daeSBarry Smith 
1715c6c1daeSBarry Smith /*@
1725c6c1daeSBarry Smith   PetscRandomGetInterval - Gets the interval over which the random numbers
173811af0c4SBarry Smith   will be distributed.  By default, this interval is [0,1).
1745c6c1daeSBarry Smith 
17520f4b53cSBarry Smith   Not Collective
1765c6c1daeSBarry Smith 
177f899ff85SJose E. Roman   Input Parameter:
1785c6c1daeSBarry Smith . r - the random number generator context
1795c6c1daeSBarry Smith 
1805c6c1daeSBarry Smith   Output Parameters:
1815c6c1daeSBarry Smith + low  - The lower bound of the interval
1825c6c1daeSBarry Smith - high - The upper bound of the interval
1835c6c1daeSBarry Smith 
1845c6c1daeSBarry Smith   Level: intermediate
1855c6c1daeSBarry Smith 
186811af0c4SBarry Smith .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomSetInterval()`
1875c6c1daeSBarry Smith @*/
PetscRandomGetInterval(PetscRandom r,PetscScalar * low,PetscScalar * high)188d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscRandomGetInterval(PetscRandom r, PetscScalar *low, PetscScalar *high)
189d71ae5a4SJacob Faibussowitsch {
1905c6c1daeSBarry Smith   PetscFunctionBegin;
1915c6c1daeSBarry Smith   PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1);
1925c6c1daeSBarry Smith   if (low) {
1934f572ea9SToby Isaac     PetscAssertPointer(low, 2);
1945c6c1daeSBarry Smith     *low = r->low;
1955c6c1daeSBarry Smith   }
1965c6c1daeSBarry Smith   if (high) {
1974f572ea9SToby Isaac     PetscAssertPointer(high, 3);
1985c6c1daeSBarry Smith     *high = r->low + r->width;
1995c6c1daeSBarry Smith   }
2003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2015c6c1daeSBarry Smith }
2025c6c1daeSBarry Smith 
2035c6c1daeSBarry Smith /*@
2045c6c1daeSBarry Smith   PetscRandomSetInterval - Sets the interval over which the random numbers
205811af0c4SBarry Smith   will be distributed.  By default, this interval is [0,1).
2065c6c1daeSBarry Smith 
20720f4b53cSBarry Smith   Not Collective
2085c6c1daeSBarry Smith 
2095c6c1daeSBarry Smith   Input Parameters:
2105c6c1daeSBarry Smith + r    - the random number generator context
2115c6c1daeSBarry Smith . low  - The lower bound of the interval
2125c6c1daeSBarry Smith - high - The upper bound of the interval
2135c6c1daeSBarry Smith 
2145c6c1daeSBarry Smith   Level: intermediate
2155c6c1daeSBarry Smith 
21695452b02SPatrick Sanan   Notes:
21795452b02SPatrick 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.
218811af0c4SBarry Smith 
2195c6c1daeSBarry 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.
2205c6c1daeSBarry Smith 
221db781477SPatrick Sanan .seealso: `PetscRandomCreate()`, `PetscRandomGetInterval()`
2225c6c1daeSBarry Smith @*/
PetscRandomSetInterval(PetscRandom r,PetscScalar low,PetscScalar high)223d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscRandomSetInterval(PetscRandom r, PetscScalar low, PetscScalar high)
224d71ae5a4SJacob Faibussowitsch {
2255c6c1daeSBarry Smith   PetscFunctionBegin;
2265c6c1daeSBarry Smith   PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1);
2275c6c1daeSBarry Smith #if defined(PETSC_USE_COMPLEX)
22808401ef6SPierre Jolivet   PetscCheck(PetscRealPart(low) <= PetscRealPart(high), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "only low <= high");
22908401ef6SPierre Jolivet   PetscCheck(PetscImaginaryPart(low) <= PetscImaginaryPart(high), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "only low <= high");
2305c6c1daeSBarry Smith #else
23108401ef6SPierre Jolivet   PetscCheck(low < high, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "only low <= high: Instead %g %g", (double)low, (double)high);
2325c6c1daeSBarry Smith #endif
2335c6c1daeSBarry Smith   r->low   = low;
2345c6c1daeSBarry Smith   r->width = high - low;
2355c6c1daeSBarry Smith   r->iset  = PETSC_TRUE;
2363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2375c6c1daeSBarry Smith }
238