xref: /petsc/src/sys/classes/random/interface/random.c (revision 9f0394f42870b9e0a92685bbca597cb20a1d83c8)
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 
155c6c1daeSBarry Smith #include <../src/sys/classes/random/randomimpl.h>                              /*I "petscsys.h" I*/
165c6c1daeSBarry Smith 
175c6c1daeSBarry Smith #undef __FUNCT__
185c6c1daeSBarry Smith #define __FUNCT__ "PetscRandomGetValue"
195c6c1daeSBarry Smith /*@
205c6c1daeSBarry Smith    PetscRandomGetValue - Generates a random number.  Call this after first calling
215c6c1daeSBarry Smith    PetscRandomCreate().
225c6c1daeSBarry Smith 
235c6c1daeSBarry Smith    Not Collective
245c6c1daeSBarry Smith 
255c6c1daeSBarry Smith    Intput Parameter:
265c6c1daeSBarry Smith .  r  - the random number generator context
275c6c1daeSBarry Smith 
285c6c1daeSBarry Smith    Output Parameter:
295c6c1daeSBarry Smith .  val - the value
305c6c1daeSBarry Smith 
315c6c1daeSBarry Smith    Level: intermediate
325c6c1daeSBarry Smith 
335c6c1daeSBarry Smith    Notes:
345c6c1daeSBarry Smith    Use VecSetRandom() to set the elements of a vector to random numbers.
355c6c1daeSBarry Smith 
365c6c1daeSBarry Smith    When PETSc is compiled for complex numbers this returns a complex number with random real and complex parts.
375c6c1daeSBarry Smith    Use PetscGetValueReal() to get a random real number.
385c6c1daeSBarry Smith 
395c6c1daeSBarry Smith    To get a complex number with only a random real part, first call PetscRandomSetInterval() with a equal
405c6c1daeSBarry Smith    low and high imaginary part. Similarly to get a complex number with only a random imaginary part call
415c6c1daeSBarry Smith    PetscRandomSetInterval() with a equal low and high real part.
425c6c1daeSBarry Smith 
435c6c1daeSBarry Smith    Example of Usage:
445c6c1daeSBarry Smith .vb
455c6c1daeSBarry Smith       PetscRandomCreate(PETSC_COMM_WORLD,&r);
465c6c1daeSBarry Smith       PetscRandomGetValue(r,&value1);
475c6c1daeSBarry Smith       PetscRandomGetValue(r,&value2);
485c6c1daeSBarry Smith       PetscRandomGetValue(r,&value3);
495c6c1daeSBarry Smith       PetscRandomDestroy(&r);
505c6c1daeSBarry Smith .ve
515c6c1daeSBarry Smith 
525c6c1daeSBarry Smith    Concepts: random numbers^getting
535c6c1daeSBarry Smith 
545c6c1daeSBarry Smith .seealso: PetscRandomCreate(), PetscRandomDestroy(), VecSetRandom(), PetscRandomGetValueReal()
555c6c1daeSBarry Smith @*/
565c6c1daeSBarry Smith PetscErrorCode  PetscRandomGetValue(PetscRandom r,PetscScalar *val)
575c6c1daeSBarry Smith {
585c6c1daeSBarry Smith   PetscErrorCode ierr;
595c6c1daeSBarry Smith 
605c6c1daeSBarry Smith   PetscFunctionBegin;
615c6c1daeSBarry Smith   PetscValidHeaderSpecific(r,PETSC_RANDOM_CLASSID,1);
625c6c1daeSBarry Smith   PetscValidIntPointer(val,2);
635c6c1daeSBarry Smith   PetscValidType(r,1);
645c6c1daeSBarry Smith 
655c6c1daeSBarry Smith   ierr = (*r->ops->getvalue)(r,val);CHKERRQ(ierr);
665c6c1daeSBarry Smith   ierr = PetscObjectStateIncrease((PetscObject)r);CHKERRQ(ierr);
675c6c1daeSBarry Smith   PetscFunctionReturn(0);
685c6c1daeSBarry Smith }
695c6c1daeSBarry Smith 
705c6c1daeSBarry Smith #undef __FUNCT__
715c6c1daeSBarry Smith #define __FUNCT__ "PetscRandomGetValueReal"
725c6c1daeSBarry Smith /*@
735c6c1daeSBarry Smith    PetscRandomGetValueReal - Generates a purely real random number.  Call this after first calling
745c6c1daeSBarry Smith    PetscRandomCreate().
755c6c1daeSBarry Smith 
765c6c1daeSBarry Smith    Not Collective
775c6c1daeSBarry Smith 
785c6c1daeSBarry Smith    Intput Parameter:
795c6c1daeSBarry Smith .  r  - the random number generator context
805c6c1daeSBarry Smith 
815c6c1daeSBarry Smith    Output Parameter:
825c6c1daeSBarry Smith .  val - the value
835c6c1daeSBarry Smith 
845c6c1daeSBarry Smith    Level: intermediate
855c6c1daeSBarry Smith 
865c6c1daeSBarry Smith    Notes:
875c6c1daeSBarry Smith    Use VecSetRandom() to set the elements of a vector to random numbers.
885c6c1daeSBarry Smith 
895c6c1daeSBarry Smith    Example of Usage:
905c6c1daeSBarry Smith .vb
915c6c1daeSBarry Smith       PetscRandomCreate(PETSC_COMM_WORLD,&r);
925c6c1daeSBarry Smith       PetscRandomGetValueReal(r,&value1);
935c6c1daeSBarry Smith       PetscRandomGetValueReal(r,&value2);
945c6c1daeSBarry Smith       PetscRandomGetValueReal(r,&value3);
955c6c1daeSBarry Smith       PetscRandomDestroy(&r);
965c6c1daeSBarry Smith .ve
975c6c1daeSBarry Smith 
985c6c1daeSBarry Smith    Concepts: random numbers^getting
995c6c1daeSBarry Smith 
1005c6c1daeSBarry Smith .seealso: PetscRandomCreate(), PetscRandomDestroy(), VecSetRandom(), PetscRandomGetValue()
1015c6c1daeSBarry Smith @*/
1025c6c1daeSBarry Smith PetscErrorCode  PetscRandomGetValueReal(PetscRandom r,PetscReal *val)
1035c6c1daeSBarry Smith {
1045c6c1daeSBarry Smith   PetscErrorCode ierr;
1055c6c1daeSBarry Smith 
1065c6c1daeSBarry Smith   PetscFunctionBegin;
1075c6c1daeSBarry Smith   PetscValidHeaderSpecific(r,PETSC_RANDOM_CLASSID,1);
1085c6c1daeSBarry Smith   PetscValidIntPointer(val,2);
1095c6c1daeSBarry Smith   PetscValidType(r,1);
1105c6c1daeSBarry Smith 
1115c6c1daeSBarry Smith   ierr = (*r->ops->getvaluereal)(r,val);CHKERRQ(ierr);
1125c6c1daeSBarry Smith   ierr = PetscObjectStateIncrease((PetscObject)r);CHKERRQ(ierr);
1135c6c1daeSBarry Smith   PetscFunctionReturn(0);
1145c6c1daeSBarry Smith }
1155c6c1daeSBarry Smith 
1165c6c1daeSBarry Smith #undef __FUNCT__
1175c6c1daeSBarry Smith #define __FUNCT__ "PetscRandomGetInterval"
1185c6c1daeSBarry Smith /*@
1195c6c1daeSBarry Smith    PetscRandomGetInterval - Gets the interval over which the random numbers
1205c6c1daeSBarry Smith    will be randomly distributed.  By default, this interval is [0,1).
1215c6c1daeSBarry Smith 
1225c6c1daeSBarry Smith    Not collective
1235c6c1daeSBarry Smith 
1245c6c1daeSBarry Smith    Input Parameters:
1255c6c1daeSBarry Smith .  r  - the random number generator context
1265c6c1daeSBarry Smith 
1275c6c1daeSBarry Smith    Output Parameters:
1285c6c1daeSBarry Smith +  low - The lower bound of the interval
1295c6c1daeSBarry Smith -  high - The upper bound of the interval
1305c6c1daeSBarry Smith 
1315c6c1daeSBarry Smith    Level: intermediate
1325c6c1daeSBarry Smith 
1335c6c1daeSBarry Smith    Concepts: random numbers^range
1345c6c1daeSBarry Smith 
1355c6c1daeSBarry Smith .seealso: PetscRandomCreate(), PetscRandomSetInterval()
1365c6c1daeSBarry Smith @*/
1375c6c1daeSBarry Smith PetscErrorCode  PetscRandomGetInterval(PetscRandom r,PetscScalar *low,PetscScalar *high)
1385c6c1daeSBarry Smith {
1395c6c1daeSBarry Smith   PetscFunctionBegin;
1405c6c1daeSBarry Smith   PetscValidHeaderSpecific(r,PETSC_RANDOM_CLASSID,1);
1415c6c1daeSBarry Smith   if (low) {
1425c6c1daeSBarry Smith     PetscValidScalarPointer(low,2);
1435c6c1daeSBarry Smith     *low = r->low;
1445c6c1daeSBarry Smith   }
1455c6c1daeSBarry Smith   if (high) {
1465c6c1daeSBarry Smith     PetscValidScalarPointer(high,3);
1475c6c1daeSBarry Smith     *high = r->low+r->width;
1485c6c1daeSBarry Smith   }
1495c6c1daeSBarry Smith   PetscFunctionReturn(0);
1505c6c1daeSBarry Smith }
1515c6c1daeSBarry Smith 
1525c6c1daeSBarry Smith #undef __FUNCT__
1535c6c1daeSBarry Smith #define __FUNCT__ "PetscRandomSetInterval"
1545c6c1daeSBarry Smith /*@
1555c6c1daeSBarry Smith    PetscRandomSetInterval - Sets the interval over which the random numbers
1565c6c1daeSBarry Smith    will be randomly distributed.  By default, this interval is [0,1).
1575c6c1daeSBarry Smith 
1585c6c1daeSBarry Smith    Not collective
1595c6c1daeSBarry Smith 
1605c6c1daeSBarry Smith    Input Parameters:
1615c6c1daeSBarry Smith +  r  - the random number generator context
1625c6c1daeSBarry Smith .  low - The lower bound of the interval
1635c6c1daeSBarry Smith -  high - The upper bound of the interval
1645c6c1daeSBarry Smith 
1655c6c1daeSBarry Smith    Level: intermediate
1665c6c1daeSBarry Smith 
1675c6c1daeSBarry 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.
1685c6c1daeSBarry 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.
1695c6c1daeSBarry Smith 
1705c6c1daeSBarry Smith    Concepts: random numbers^range
1715c6c1daeSBarry Smith 
1725c6c1daeSBarry Smith .seealso: PetscRandomCreate(), PetscRandomGetInterval()
1735c6c1daeSBarry Smith @*/
1745c6c1daeSBarry Smith PetscErrorCode  PetscRandomSetInterval(PetscRandom r,PetscScalar low,PetscScalar high)
1755c6c1daeSBarry Smith {
1765c6c1daeSBarry Smith   PetscFunctionBegin;
1775c6c1daeSBarry Smith   PetscValidHeaderSpecific(r,PETSC_RANDOM_CLASSID,1);
1785c6c1daeSBarry Smith #if defined(PETSC_USE_COMPLEX)
179*9f0394f4SBarry Smith   if (PetscRealPart(low) > PetscRealPart(high))           SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"only low <= high");
180*9f0394f4SBarry Smith   if (PetscImaginaryPart(low) > PetscImaginaryPart(high)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"only low <= high");
1815c6c1daeSBarry Smith #else
182*9f0394f4SBarry Smith   if (low >= high) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"only low <= high: Instead %g %g",(double)low,(double)high);
1835c6c1daeSBarry Smith #endif
1845c6c1daeSBarry Smith   r->low   = low;
1855c6c1daeSBarry Smith   r->width = high-low;
1865c6c1daeSBarry Smith   r->iset  = PETSC_TRUE;
1875c6c1daeSBarry Smith   PetscFunctionReturn(0);
1885c6c1daeSBarry Smith }
189