xref: /petsc/src/sys/classes/random/interface/random.c (revision 08401ef684002a709c6d3db98a0c9f54a8bcf1ec)
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
195c6c1daeSBarry 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:
325c6c1daeSBarry 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.
3550d92d24SPierre Jolivet    Use PetscRandomGetValueReal() to get a random real number.
365c6c1daeSBarry Smith 
375c6c1daeSBarry 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
395c6c1daeSBarry 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 
505c6c1daeSBarry Smith .seealso: PetscRandomCreate(), PetscRandomDestroy(), VecSetRandom(), PetscRandomGetValueReal()
515c6c1daeSBarry Smith @*/
525c6c1daeSBarry Smith PetscErrorCode  PetscRandomGetValue(PetscRandom r,PetscScalar *val)
535c6c1daeSBarry Smith {
545c6c1daeSBarry Smith   PetscFunctionBegin;
555c6c1daeSBarry Smith   PetscValidHeaderSpecific(r,PETSC_RANDOM_CLASSID,1);
565c6c1daeSBarry Smith   PetscValidType(r,1);
57808ba619SStefano Zampini   if (!r->ops->getvalue) {
5828b400f6SJacob Faibussowitsch     PetscCheck(r->ops->getvalues,PetscObjectComm((PetscObject)r),PETSC_ERR_SUP,"Random type %s cannot generate PetscScalar",((PetscObject)r)->type_name);
599566063dSJacob Faibussowitsch     PetscCall((*r->ops->getvalues)(r,1,val));
60808ba619SStefano Zampini   } else {
619566063dSJacob Faibussowitsch     PetscCall((*r->ops->getvalue)(r,val));
62808ba619SStefano Zampini   }
639566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)r));
645c6c1daeSBarry Smith   PetscFunctionReturn(0);
655c6c1daeSBarry Smith }
665c6c1daeSBarry Smith 
675c6c1daeSBarry Smith /*@
68808ba619SStefano Zampini    PetscRandomGetValueReal - Generates a real random number.  Call this after first calling
695c6c1daeSBarry Smith    PetscRandomCreate().
705c6c1daeSBarry Smith 
715c6c1daeSBarry Smith    Not Collective
725c6c1daeSBarry Smith 
7301d2d390SJose E. Roman    Input Parameter:
745c6c1daeSBarry Smith .  r  - the random number generator context
755c6c1daeSBarry Smith 
765c6c1daeSBarry Smith    Output Parameter:
775c6c1daeSBarry Smith .  val - the value
785c6c1daeSBarry Smith 
795c6c1daeSBarry Smith    Level: intermediate
805c6c1daeSBarry Smith 
815c6c1daeSBarry Smith    Notes:
825c6c1daeSBarry Smith    Use VecSetRandom() to set the elements of a vector to random numbers.
835c6c1daeSBarry Smith 
845c6c1daeSBarry Smith    Example of Usage:
855c6c1daeSBarry Smith .vb
865c6c1daeSBarry Smith       PetscRandomCreate(PETSC_COMM_WORLD,&r);
875c6c1daeSBarry Smith       PetscRandomGetValueReal(r,&value1);
885c6c1daeSBarry Smith       PetscRandomGetValueReal(r,&value2);
895c6c1daeSBarry Smith       PetscRandomGetValueReal(r,&value3);
905c6c1daeSBarry Smith       PetscRandomDestroy(&r);
915c6c1daeSBarry Smith .ve
925c6c1daeSBarry Smith 
935c6c1daeSBarry Smith .seealso: PetscRandomCreate(), PetscRandomDestroy(), VecSetRandom(), PetscRandomGetValue()
945c6c1daeSBarry Smith @*/
955c6c1daeSBarry Smith PetscErrorCode  PetscRandomGetValueReal(PetscRandom r,PetscReal *val)
965c6c1daeSBarry Smith {
975c6c1daeSBarry Smith   PetscFunctionBegin;
985c6c1daeSBarry Smith   PetscValidHeaderSpecific(r,PETSC_RANDOM_CLASSID,1);
995c6c1daeSBarry Smith   PetscValidType(r,1);
100808ba619SStefano Zampini   if (!r->ops->getvaluereal) {
10128b400f6SJacob Faibussowitsch     PetscCheck(r->ops->getvaluesreal,PetscObjectComm((PetscObject)r),PETSC_ERR_SUP,"Random type %s cannot generate PetscReal",((PetscObject)r)->type_name);
1029566063dSJacob Faibussowitsch     PetscCall((*r->ops->getvaluesreal)(r,1,val));
103808ba619SStefano Zampini   } else {
1049566063dSJacob Faibussowitsch     PetscCall((*r->ops->getvaluereal)(r,val));
105808ba619SStefano Zampini   }
1069566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)r));
107808ba619SStefano Zampini   PetscFunctionReturn(0);
108808ba619SStefano Zampini }
109808ba619SStefano Zampini 
110808ba619SStefano Zampini /*@
111808ba619SStefano Zampini    PetscRandomGetValues - Generates a sequence of random numbers.  Call this after first calling
112808ba619SStefano Zampini    PetscRandomCreate().
113808ba619SStefano Zampini 
114808ba619SStefano Zampini    Not Collective
115808ba619SStefano Zampini 
11601d2d390SJose E. Roman    Input Parameters:
117808ba619SStefano Zampini +  r  - the random number generator context
118808ba619SStefano Zampini -  n  - number of random numbers to generate
119808ba619SStefano Zampini 
120808ba619SStefano Zampini    Output Parameter:
121808ba619SStefano Zampini .  val - the array to hold the values
122808ba619SStefano Zampini 
123808ba619SStefano Zampini    Level: intermediate
124808ba619SStefano Zampini 
125808ba619SStefano Zampini    Notes:
126808ba619SStefano Zampini    Use VecSetRandom() to set the elements of a vector to random numbers.
127808ba619SStefano Zampini 
128808ba619SStefano Zampini    When PETSc is compiled for complex numbers this returns an array of complex numbers with random real and complex parts.
12950d92d24SPierre Jolivet    Use PetscRandomGetValuesReal() to get an array of random real numbers.
130808ba619SStefano Zampini 
131808ba619SStefano Zampini .seealso: PetscRandomCreate(), PetscRandomDestroy(), VecSetRandom(), PetscRandomGetValue()
132808ba619SStefano Zampini @*/
133808ba619SStefano Zampini PetscErrorCode  PetscRandomGetValues(PetscRandom r, PetscInt n, PetscScalar *val)
134808ba619SStefano Zampini {
135808ba619SStefano Zampini   PetscFunctionBegin;
136808ba619SStefano Zampini   PetscValidHeaderSpecific(r,PETSC_RANDOM_CLASSID,1);
137808ba619SStefano Zampini   PetscValidType(r,1);
138808ba619SStefano Zampini   if (!r->ops->getvalues) {
139808ba619SStefano Zampini     PetscInt i;
14028b400f6SJacob Faibussowitsch     PetscCheck(r->ops->getvalue,PetscObjectComm((PetscObject)r),PETSC_ERR_SUP,"Random type %s cannot generate PetscScalar",((PetscObject)r)->type_name);
141808ba619SStefano Zampini     for (i = 0; i < n; i++) {
1429566063dSJacob Faibussowitsch       PetscCall((*r->ops->getvalue)(r,val+i));
143808ba619SStefano Zampini     }
144808ba619SStefano Zampini   } else {
1459566063dSJacob Faibussowitsch     PetscCall((*r->ops->getvalues)(r,n,val));
146808ba619SStefano Zampini   }
1479566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)r));
148808ba619SStefano Zampini   PetscFunctionReturn(0);
149808ba619SStefano Zampini }
150808ba619SStefano Zampini 
151808ba619SStefano Zampini /*@
152808ba619SStefano Zampini    PetscRandomGetValuesReal - Generates a sequence of real random numbers.  Call this after first calling
153808ba619SStefano Zampini    PetscRandomCreate().
154808ba619SStefano Zampini 
155808ba619SStefano Zampini    Not Collective
156808ba619SStefano Zampini 
15701d2d390SJose E. Roman    Input Parameters:
158808ba619SStefano Zampini +  r  - the random number generator context
159808ba619SStefano Zampini -  n  - number of random numbers to generate
160808ba619SStefano Zampini 
161808ba619SStefano Zampini    Output Parameter:
162808ba619SStefano Zampini .  val - the array to hold the values
163808ba619SStefano Zampini 
164808ba619SStefano Zampini    Level: intermediate
165808ba619SStefano Zampini 
166808ba619SStefano Zampini    Notes:
167808ba619SStefano Zampini    Use VecSetRandom() to set the elements of a vector to random numbers.
168808ba619SStefano Zampini 
169808ba619SStefano Zampini .seealso: PetscRandomCreate(), PetscRandomDestroy(), VecSetRandom(), PetscRandomGetValues()
170808ba619SStefano Zampini @*/
171808ba619SStefano Zampini PetscErrorCode  PetscRandomGetValuesReal(PetscRandom r, PetscInt n, PetscReal *val)
172808ba619SStefano Zampini {
173808ba619SStefano Zampini   PetscFunctionBegin;
174808ba619SStefano Zampini   PetscValidHeaderSpecific(r,PETSC_RANDOM_CLASSID,1);
175808ba619SStefano Zampini   PetscValidType(r,1);
176808ba619SStefano Zampini   if (!r->ops->getvaluesreal) {
177808ba619SStefano Zampini     PetscInt i;
17828b400f6SJacob Faibussowitsch     PetscCheck(r->ops->getvaluereal,PetscObjectComm((PetscObject)r),PETSC_ERR_SUP,"Random type %s cannot generate PetscReal",((PetscObject)r)->type_name);
179808ba619SStefano Zampini     for (i = 0; i < n; i++) {
1809566063dSJacob Faibussowitsch       PetscCall((*r->ops->getvaluereal)(r,val+i));
181808ba619SStefano Zampini     }
182808ba619SStefano Zampini   } else {
1839566063dSJacob Faibussowitsch     PetscCall((*r->ops->getvaluesreal)(r,n,val));
184808ba619SStefano Zampini   }
1859566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)r));
1865c6c1daeSBarry Smith   PetscFunctionReturn(0);
1875c6c1daeSBarry Smith }
1885c6c1daeSBarry Smith 
1895c6c1daeSBarry Smith /*@
1905c6c1daeSBarry Smith    PetscRandomGetInterval - Gets the interval over which the random numbers
1915c6c1daeSBarry Smith    will be randomly distributed.  By default, this interval is [0,1).
1925c6c1daeSBarry Smith 
1935c6c1daeSBarry Smith    Not collective
1945c6c1daeSBarry Smith 
195f899ff85SJose E. Roman    Input Parameter:
1965c6c1daeSBarry Smith .  r  - the random number generator context
1975c6c1daeSBarry Smith 
1985c6c1daeSBarry Smith    Output Parameters:
1995c6c1daeSBarry Smith +  low - The lower bound of the interval
2005c6c1daeSBarry Smith -  high - The upper bound of the interval
2015c6c1daeSBarry Smith 
2025c6c1daeSBarry Smith    Level: intermediate
2035c6c1daeSBarry Smith 
2045c6c1daeSBarry Smith .seealso: PetscRandomCreate(), PetscRandomSetInterval()
2055c6c1daeSBarry Smith @*/
2065c6c1daeSBarry Smith PetscErrorCode  PetscRandomGetInterval(PetscRandom r,PetscScalar *low,PetscScalar *high)
2075c6c1daeSBarry Smith {
2085c6c1daeSBarry Smith   PetscFunctionBegin;
2095c6c1daeSBarry Smith   PetscValidHeaderSpecific(r,PETSC_RANDOM_CLASSID,1);
2105c6c1daeSBarry Smith   if (low) {
2115c6c1daeSBarry Smith     PetscValidScalarPointer(low,2);
2125c6c1daeSBarry Smith     *low = r->low;
2135c6c1daeSBarry Smith   }
2145c6c1daeSBarry Smith   if (high) {
2155c6c1daeSBarry Smith     PetscValidScalarPointer(high,3);
2165c6c1daeSBarry Smith     *high = r->low+r->width;
2175c6c1daeSBarry Smith   }
2185c6c1daeSBarry Smith   PetscFunctionReturn(0);
2195c6c1daeSBarry Smith }
2205c6c1daeSBarry Smith 
2215c6c1daeSBarry Smith /*@
2225c6c1daeSBarry Smith    PetscRandomSetInterval - Sets the interval over which the random numbers
2235c6c1daeSBarry Smith    will be randomly distributed.  By default, this interval is [0,1).
2245c6c1daeSBarry Smith 
2255c6c1daeSBarry Smith    Not collective
2265c6c1daeSBarry Smith 
2275c6c1daeSBarry Smith    Input Parameters:
2285c6c1daeSBarry Smith +  r  - the random number generator context
2295c6c1daeSBarry Smith .  low - The lower bound of the interval
2305c6c1daeSBarry Smith -  high - The upper bound of the interval
2315c6c1daeSBarry Smith 
2325c6c1daeSBarry Smith    Level: intermediate
2335c6c1daeSBarry Smith 
23495452b02SPatrick Sanan    Notes:
23595452b02SPatrick 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.
2365c6c1daeSBarry 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.
2375c6c1daeSBarry Smith 
2385c6c1daeSBarry Smith .seealso: PetscRandomCreate(), PetscRandomGetInterval()
2395c6c1daeSBarry Smith @*/
2405c6c1daeSBarry Smith PetscErrorCode  PetscRandomSetInterval(PetscRandom r,PetscScalar low,PetscScalar high)
2415c6c1daeSBarry Smith {
2425c6c1daeSBarry Smith   PetscFunctionBegin;
2435c6c1daeSBarry Smith   PetscValidHeaderSpecific(r,PETSC_RANDOM_CLASSID,1);
2445c6c1daeSBarry Smith #if defined(PETSC_USE_COMPLEX)
245*08401ef6SPierre Jolivet   PetscCheck(PetscRealPart(low) <= PetscRealPart(high),PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"only low <= high");
246*08401ef6SPierre Jolivet   PetscCheck(PetscImaginaryPart(low) <= PetscImaginaryPart(high),PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"only low <= high");
2475c6c1daeSBarry Smith #else
248*08401ef6SPierre Jolivet   PetscCheck(low < high,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"only low <= high: Instead %g %g",(double)low,(double)high);
2495c6c1daeSBarry Smith #endif
2505c6c1daeSBarry Smith   r->low   = low;
2515c6c1daeSBarry Smith   r->width = high-low;
2525c6c1daeSBarry Smith   r->iset  = PETSC_TRUE;
2535c6c1daeSBarry Smith   PetscFunctionReturn(0);
2545c6c1daeSBarry Smith }
255