xref: /petsc/src/sys/classes/random/interface/random.c (revision 3ba1676111f5c958fe6c2729b46ca4d523958bb3)
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
19811af0c4SBarry 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:
32811af0c4SBarry 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.
35811af0c4SBarry Smith    Use `PetscRandomGetValueReal()` to get a random real number.
365c6c1daeSBarry Smith 
37811af0c4SBarry 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
39811af0c4SBarry 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 
50811af0c4SBarry Smith .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomDestroy()`, `VecSetRandom()`, `PetscRandomGetValueReal()`, `PetscRandomSetInterval()`
515c6c1daeSBarry Smith @*/
52d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscRandomGetValue(PetscRandom r, PetscScalar *val)
53d71ae5a4SJacob Faibussowitsch {
545c6c1daeSBarry Smith   PetscFunctionBegin;
555c6c1daeSBarry Smith   PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1);
565c6c1daeSBarry Smith   PetscValidType(r, 1);
57dbbe0bcdSBarry Smith   if (!r->ops->getvalue) PetscUseTypeMethod(r, getvalues, 1, val);
58dbbe0bcdSBarry Smith   else PetscUseTypeMethod(r, getvalue, val);
599566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)r));
60*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
615c6c1daeSBarry Smith }
625c6c1daeSBarry Smith 
635c6c1daeSBarry Smith /*@
64808ba619SStefano Zampini    PetscRandomGetValueReal - Generates a real random number.  Call this after first calling
65811af0c4SBarry Smith    `PetscRandomCreate()`.
665c6c1daeSBarry Smith 
675c6c1daeSBarry Smith    Not Collective
685c6c1daeSBarry Smith 
6901d2d390SJose E. Roman    Input Parameter:
705c6c1daeSBarry Smith .  r  - the random number generator context
715c6c1daeSBarry Smith 
725c6c1daeSBarry Smith    Output Parameter:
735c6c1daeSBarry Smith .  val - the value
745c6c1daeSBarry Smith 
755c6c1daeSBarry Smith    Level: intermediate
765c6c1daeSBarry Smith 
77811af0c4SBarry Smith    Note:
78811af0c4SBarry Smith    Use `VecSetRandom()` to set the elements of a vector to random numbers.
795c6c1daeSBarry Smith 
805c6c1daeSBarry Smith    Example of Usage:
815c6c1daeSBarry Smith .vb
825c6c1daeSBarry Smith       PetscRandomCreate(PETSC_COMM_WORLD,&r);
835c6c1daeSBarry Smith       PetscRandomGetValueReal(r,&value1);
845c6c1daeSBarry Smith       PetscRandomGetValueReal(r,&value2);
855c6c1daeSBarry Smith       PetscRandomGetValueReal(r,&value3);
865c6c1daeSBarry Smith       PetscRandomDestroy(&r);
875c6c1daeSBarry Smith .ve
885c6c1daeSBarry Smith 
89811af0c4SBarry Smith .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomDestroy()`, `VecSetRandom()`, `PetscRandomGetValue()`
905c6c1daeSBarry Smith @*/
91d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscRandomGetValueReal(PetscRandom r, PetscReal *val)
92d71ae5a4SJacob Faibussowitsch {
935c6c1daeSBarry Smith   PetscFunctionBegin;
945c6c1daeSBarry Smith   PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1);
955c6c1daeSBarry Smith   PetscValidType(r, 1);
96dbbe0bcdSBarry Smith   if (!r->ops->getvaluereal) PetscUseTypeMethod(r, getvaluesreal, 1, val);
97dbbe0bcdSBarry Smith   else PetscUseTypeMethod(r, getvaluereal, val);
989566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)r));
99*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
100808ba619SStefano Zampini }
101808ba619SStefano Zampini 
102808ba619SStefano Zampini /*@
103808ba619SStefano Zampini    PetscRandomGetValues - Generates a sequence of random numbers.  Call this after first calling
104811af0c4SBarry Smith    `PetscRandomCreate()`.
105808ba619SStefano Zampini 
106808ba619SStefano Zampini    Not Collective
107808ba619SStefano Zampini 
10801d2d390SJose E. Roman    Input Parameters:
109808ba619SStefano Zampini +  r  - the random number generator context
110808ba619SStefano Zampini -  n  - number of random numbers to generate
111808ba619SStefano Zampini 
112808ba619SStefano Zampini    Output Parameter:
113808ba619SStefano Zampini .  val - the array to hold the values
114808ba619SStefano Zampini 
115808ba619SStefano Zampini    Level: intermediate
116808ba619SStefano Zampini 
117808ba619SStefano Zampini    Notes:
118811af0c4SBarry Smith    Use `VecSetRandom()` to set the elements of a vector to random numbers.
119808ba619SStefano Zampini 
120808ba619SStefano Zampini    When PETSc is compiled for complex numbers this returns an array of complex numbers with random real and complex parts.
121811af0c4SBarry Smith    Use `PetscRandomGetValuesReal()` to get an array of random real numbers.
122808ba619SStefano Zampini 
123811af0c4SBarry Smith .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomDestroy()`, `VecSetRandom()`, `PetscRandomGetValue()`
124808ba619SStefano Zampini @*/
125d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscRandomGetValues(PetscRandom r, PetscInt n, PetscScalar *val)
126d71ae5a4SJacob Faibussowitsch {
127808ba619SStefano Zampini   PetscFunctionBegin;
128808ba619SStefano Zampini   PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1);
129808ba619SStefano Zampini   PetscValidType(r, 1);
130808ba619SStefano Zampini   if (!r->ops->getvalues) {
13188ba4fe4SJacob Faibussowitsch     PetscErrorCode (*const getvalue)(PetscRandom, PetscScalar *) = r->ops->getvalue;
13288ba4fe4SJacob Faibussowitsch 
13388ba4fe4SJacob Faibussowitsch     for (PetscInt i = 0; i < n; ++i) PetscCall(getvalue(r, val + i));
134dbbe0bcdSBarry Smith   } else PetscUseTypeMethod(r, getvalues, n, val);
1359566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)r));
136*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
137808ba619SStefano Zampini }
138808ba619SStefano Zampini 
139808ba619SStefano Zampini /*@
140808ba619SStefano Zampini    PetscRandomGetValuesReal - Generates a sequence of real random numbers.  Call this after first calling
141811af0c4SBarry Smith    `PetscRandomCreate()`.
142808ba619SStefano Zampini 
143808ba619SStefano Zampini    Not Collective
144808ba619SStefano Zampini 
14501d2d390SJose E. Roman    Input Parameters:
146808ba619SStefano Zampini +  r  - the random number generator context
147808ba619SStefano Zampini -  n  - number of random numbers to generate
148808ba619SStefano Zampini 
149808ba619SStefano Zampini    Output Parameter:
150808ba619SStefano Zampini .  val - the array to hold the values
151808ba619SStefano Zampini 
152808ba619SStefano Zampini    Level: intermediate
153808ba619SStefano Zampini 
154811af0c4SBarry Smith    Note:
155811af0c4SBarry Smith    Use `VecSetRandom()` to set the elements of a vector to random numbers.
156808ba619SStefano Zampini 
157811af0c4SBarry Smith .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomDestroy()`, `VecSetRandom()`, `PetscRandomGetValues()`
158808ba619SStefano Zampini @*/
159d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscRandomGetValuesReal(PetscRandom r, PetscInt n, PetscReal *val)
160d71ae5a4SJacob Faibussowitsch {
161808ba619SStefano Zampini   PetscFunctionBegin;
162808ba619SStefano Zampini   PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1);
163808ba619SStefano Zampini   PetscValidType(r, 1);
164808ba619SStefano Zampini   if (!r->ops->getvaluesreal) {
165808ba619SStefano Zampini     PetscInt i;
16648a46eb9SPierre Jolivet     for (i = 0; i < n; i++) PetscCall((*r->ops->getvaluereal)(r, val + i));
167dbbe0bcdSBarry Smith   } else PetscUseTypeMethod(r, getvaluesreal, n, val);
1689566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)r));
169*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1705c6c1daeSBarry Smith }
1715c6c1daeSBarry Smith 
1725c6c1daeSBarry Smith /*@
1735c6c1daeSBarry Smith    PetscRandomGetInterval - Gets the interval over which the random numbers
174811af0c4SBarry Smith    will be distributed.  By default, this interval is [0,1).
1755c6c1daeSBarry Smith 
1765c6c1daeSBarry Smith    Not collective
1775c6c1daeSBarry Smith 
178f899ff85SJose E. Roman    Input Parameter:
1795c6c1daeSBarry Smith .  r  - the random number generator context
1805c6c1daeSBarry Smith 
1815c6c1daeSBarry Smith    Output Parameters:
1825c6c1daeSBarry Smith +  low - The lower bound of the interval
1835c6c1daeSBarry Smith -  high - The upper bound of the interval
1845c6c1daeSBarry Smith 
1855c6c1daeSBarry Smith    Level: intermediate
1865c6c1daeSBarry Smith 
187811af0c4SBarry Smith .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomSetInterval()`
1885c6c1daeSBarry Smith @*/
189d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscRandomGetInterval(PetscRandom r, PetscScalar *low, PetscScalar *high)
190d71ae5a4SJacob Faibussowitsch {
1915c6c1daeSBarry Smith   PetscFunctionBegin;
1925c6c1daeSBarry Smith   PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1);
1935c6c1daeSBarry Smith   if (low) {
1945c6c1daeSBarry Smith     PetscValidScalarPointer(low, 2);
1955c6c1daeSBarry Smith     *low = r->low;
1965c6c1daeSBarry Smith   }
1975c6c1daeSBarry Smith   if (high) {
1985c6c1daeSBarry Smith     PetscValidScalarPointer(high, 3);
1995c6c1daeSBarry Smith     *high = r->low + r->width;
2005c6c1daeSBarry Smith   }
201*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2025c6c1daeSBarry Smith }
2035c6c1daeSBarry Smith 
2045c6c1daeSBarry Smith /*@
2055c6c1daeSBarry Smith    PetscRandomSetInterval - Sets the interval over which the random numbers
206811af0c4SBarry Smith    will be distributed.  By default, this interval is [0,1).
2075c6c1daeSBarry Smith 
2085c6c1daeSBarry Smith    Not collective
2095c6c1daeSBarry Smith 
2105c6c1daeSBarry Smith    Input Parameters:
2115c6c1daeSBarry Smith +  r  - the random number generator context
2125c6c1daeSBarry Smith .  low - The lower bound of the interval
2135c6c1daeSBarry Smith -  high - The upper bound of the interval
2145c6c1daeSBarry Smith 
2155c6c1daeSBarry Smith    Level: intermediate
2165c6c1daeSBarry Smith 
21795452b02SPatrick Sanan    Notes:
21895452b02SPatrick 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.
219811af0c4SBarry Smith 
2205c6c1daeSBarry 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.
2215c6c1daeSBarry Smith 
222db781477SPatrick Sanan .seealso: `PetscRandomCreate()`, `PetscRandomGetInterval()`
2235c6c1daeSBarry Smith @*/
224d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscRandomSetInterval(PetscRandom r, PetscScalar low, PetscScalar high)
225d71ae5a4SJacob Faibussowitsch {
2265c6c1daeSBarry Smith   PetscFunctionBegin;
2275c6c1daeSBarry Smith   PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1);
2285c6c1daeSBarry Smith #if defined(PETSC_USE_COMPLEX)
22908401ef6SPierre Jolivet   PetscCheck(PetscRealPart(low) <= PetscRealPart(high), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "only low <= high");
23008401ef6SPierre Jolivet   PetscCheck(PetscImaginaryPart(low) <= PetscImaginaryPart(high), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "only low <= high");
2315c6c1daeSBarry Smith #else
23208401ef6SPierre Jolivet   PetscCheck(low < high, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "only low <= high: Instead %g %g", (double)low, (double)high);
2335c6c1daeSBarry Smith #endif
2345c6c1daeSBarry Smith   r->low   = low;
2355c6c1daeSBarry Smith   r->width = high - low;
2365c6c1daeSBarry Smith   r->iset  = PETSC_TRUE;
237*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2385c6c1daeSBarry Smith }
239