xref: /petsc/src/sys/classes/random/interface/random.c (revision 95452b02e12c0ee11232c7ff2b24b568a8e07e43)
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 /*@
185c6c1daeSBarry Smith    PetscRandomGetValue - Generates a random number.  Call this after first calling
195c6c1daeSBarry Smith    PetscRandomCreate().
205c6c1daeSBarry Smith 
215c6c1daeSBarry Smith    Not Collective
225c6c1daeSBarry Smith 
235c6c1daeSBarry Smith    Intput 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.
355c6c1daeSBarry Smith    Use PetscGetValueReal() 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    Concepts: random numbers^getting
515c6c1daeSBarry Smith 
525c6c1daeSBarry Smith .seealso: PetscRandomCreate(), PetscRandomDestroy(), VecSetRandom(), PetscRandomGetValueReal()
535c6c1daeSBarry Smith @*/
545c6c1daeSBarry Smith PetscErrorCode  PetscRandomGetValue(PetscRandom r,PetscScalar *val)
555c6c1daeSBarry Smith {
565c6c1daeSBarry Smith   PetscErrorCode ierr;
575c6c1daeSBarry Smith 
585c6c1daeSBarry Smith   PetscFunctionBegin;
595c6c1daeSBarry Smith   PetscValidHeaderSpecific(r,PETSC_RANDOM_CLASSID,1);
605c6c1daeSBarry Smith   PetscValidIntPointer(val,2);
615c6c1daeSBarry Smith   PetscValidType(r,1);
625c6c1daeSBarry Smith 
635c6c1daeSBarry Smith   ierr = (*r->ops->getvalue)(r,val);CHKERRQ(ierr);
645c6c1daeSBarry Smith   ierr = PetscObjectStateIncrease((PetscObject)r);CHKERRQ(ierr);
655c6c1daeSBarry Smith   PetscFunctionReturn(0);
665c6c1daeSBarry Smith }
675c6c1daeSBarry Smith 
685c6c1daeSBarry Smith /*@
695c6c1daeSBarry Smith    PetscRandomGetValueReal - Generates a purely real random number.  Call this after first calling
705c6c1daeSBarry Smith    PetscRandomCreate().
715c6c1daeSBarry Smith 
725c6c1daeSBarry Smith    Not Collective
735c6c1daeSBarry Smith 
745c6c1daeSBarry Smith    Intput Parameter:
755c6c1daeSBarry Smith .  r  - the random number generator context
765c6c1daeSBarry Smith 
775c6c1daeSBarry Smith    Output Parameter:
785c6c1daeSBarry Smith .  val - the value
795c6c1daeSBarry Smith 
805c6c1daeSBarry Smith    Level: intermediate
815c6c1daeSBarry Smith 
825c6c1daeSBarry Smith    Notes:
835c6c1daeSBarry Smith    Use VecSetRandom() to set the elements of a vector to random numbers.
845c6c1daeSBarry Smith 
855c6c1daeSBarry Smith    Example of Usage:
865c6c1daeSBarry Smith .vb
875c6c1daeSBarry Smith       PetscRandomCreate(PETSC_COMM_WORLD,&r);
885c6c1daeSBarry Smith       PetscRandomGetValueReal(r,&value1);
895c6c1daeSBarry Smith       PetscRandomGetValueReal(r,&value2);
905c6c1daeSBarry Smith       PetscRandomGetValueReal(r,&value3);
915c6c1daeSBarry Smith       PetscRandomDestroy(&r);
925c6c1daeSBarry Smith .ve
935c6c1daeSBarry Smith 
945c6c1daeSBarry Smith    Concepts: random numbers^getting
955c6c1daeSBarry Smith 
965c6c1daeSBarry Smith .seealso: PetscRandomCreate(), PetscRandomDestroy(), VecSetRandom(), PetscRandomGetValue()
975c6c1daeSBarry Smith @*/
985c6c1daeSBarry Smith PetscErrorCode  PetscRandomGetValueReal(PetscRandom r,PetscReal *val)
995c6c1daeSBarry Smith {
1005c6c1daeSBarry Smith   PetscErrorCode ierr;
1015c6c1daeSBarry Smith 
1025c6c1daeSBarry Smith   PetscFunctionBegin;
1035c6c1daeSBarry Smith   PetscValidHeaderSpecific(r,PETSC_RANDOM_CLASSID,1);
1045c6c1daeSBarry Smith   PetscValidIntPointer(val,2);
1055c6c1daeSBarry Smith   PetscValidType(r,1);
1065c6c1daeSBarry Smith 
1075c6c1daeSBarry Smith   ierr = (*r->ops->getvaluereal)(r,val);CHKERRQ(ierr);
1085c6c1daeSBarry Smith   ierr = PetscObjectStateIncrease((PetscObject)r);CHKERRQ(ierr);
1095c6c1daeSBarry Smith   PetscFunctionReturn(0);
1105c6c1daeSBarry Smith }
1115c6c1daeSBarry Smith 
1125c6c1daeSBarry Smith /*@
1135c6c1daeSBarry Smith    PetscRandomGetInterval - Gets the interval over which the random numbers
1145c6c1daeSBarry Smith    will be randomly distributed.  By default, this interval is [0,1).
1155c6c1daeSBarry Smith 
1165c6c1daeSBarry Smith    Not collective
1175c6c1daeSBarry Smith 
1185c6c1daeSBarry Smith    Input Parameters:
1195c6c1daeSBarry Smith .  r  - the random number generator context
1205c6c1daeSBarry Smith 
1215c6c1daeSBarry Smith    Output Parameters:
1225c6c1daeSBarry Smith +  low - The lower bound of the interval
1235c6c1daeSBarry Smith -  high - The upper bound of the interval
1245c6c1daeSBarry Smith 
1255c6c1daeSBarry Smith    Level: intermediate
1265c6c1daeSBarry Smith 
1275c6c1daeSBarry Smith    Concepts: random numbers^range
1285c6c1daeSBarry Smith 
1295c6c1daeSBarry Smith .seealso: PetscRandomCreate(), PetscRandomSetInterval()
1305c6c1daeSBarry Smith @*/
1315c6c1daeSBarry Smith PetscErrorCode  PetscRandomGetInterval(PetscRandom r,PetscScalar *low,PetscScalar *high)
1325c6c1daeSBarry Smith {
1335c6c1daeSBarry Smith   PetscFunctionBegin;
1345c6c1daeSBarry Smith   PetscValidHeaderSpecific(r,PETSC_RANDOM_CLASSID,1);
1355c6c1daeSBarry Smith   if (low) {
1365c6c1daeSBarry Smith     PetscValidScalarPointer(low,2);
1375c6c1daeSBarry Smith     *low = r->low;
1385c6c1daeSBarry Smith   }
1395c6c1daeSBarry Smith   if (high) {
1405c6c1daeSBarry Smith     PetscValidScalarPointer(high,3);
1415c6c1daeSBarry Smith     *high = r->low+r->width;
1425c6c1daeSBarry Smith   }
1435c6c1daeSBarry Smith   PetscFunctionReturn(0);
1445c6c1daeSBarry Smith }
1455c6c1daeSBarry Smith 
1465c6c1daeSBarry Smith /*@
1475c6c1daeSBarry Smith    PetscRandomSetInterval - Sets the interval over which the random numbers
1485c6c1daeSBarry Smith    will be randomly distributed.  By default, this interval is [0,1).
1495c6c1daeSBarry Smith 
1505c6c1daeSBarry Smith    Not collective
1515c6c1daeSBarry Smith 
1525c6c1daeSBarry Smith    Input Parameters:
1535c6c1daeSBarry Smith +  r  - the random number generator context
1545c6c1daeSBarry Smith .  low - The lower bound of the interval
1555c6c1daeSBarry Smith -  high - The upper bound of the interval
1565c6c1daeSBarry Smith 
1575c6c1daeSBarry Smith    Level: intermediate
1585c6c1daeSBarry Smith 
159*95452b02SPatrick Sanan    Notes:
160*95452b02SPatrick 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.
1615c6c1daeSBarry 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.
1625c6c1daeSBarry Smith 
1635c6c1daeSBarry Smith    Concepts: random numbers^range
1645c6c1daeSBarry Smith 
1655c6c1daeSBarry Smith .seealso: PetscRandomCreate(), PetscRandomGetInterval()
1665c6c1daeSBarry Smith @*/
1675c6c1daeSBarry Smith PetscErrorCode  PetscRandomSetInterval(PetscRandom r,PetscScalar low,PetscScalar high)
1685c6c1daeSBarry Smith {
1695c6c1daeSBarry Smith   PetscFunctionBegin;
1705c6c1daeSBarry Smith   PetscValidHeaderSpecific(r,PETSC_RANDOM_CLASSID,1);
1715c6c1daeSBarry Smith #if defined(PETSC_USE_COMPLEX)
1729f0394f4SBarry Smith   if (PetscRealPart(low) > PetscRealPart(high))           SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"only low <= high");
1739f0394f4SBarry Smith   if (PetscImaginaryPart(low) > PetscImaginaryPart(high)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"only low <= high");
1745c6c1daeSBarry Smith #else
1759f0394f4SBarry Smith   if (low >= high) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"only low <= high: Instead %g %g",(double)low,(double)high);
1765c6c1daeSBarry Smith #endif
1775c6c1daeSBarry Smith   r->low   = low;
1785c6c1daeSBarry Smith   r->width = high-low;
1795c6c1daeSBarry Smith   r->iset  = PETSC_TRUE;
1805c6c1daeSBarry Smith   PetscFunctionReturn(0);
1815c6c1daeSBarry Smith }
182