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 19*811af0c4SBarry 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: 32*811af0c4SBarry 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. 35*811af0c4SBarry Smith Use `PetscRandomGetValueReal()` to get a random real number. 365c6c1daeSBarry Smith 37*811af0c4SBarry 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 39*811af0c4SBarry 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 50*811af0c4SBarry Smith .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomDestroy()`, `VecSetRandom()`, `PetscRandomGetValueReal()`, `PetscRandomSetInterval()` 515c6c1daeSBarry Smith @*/ 529371c9d4SSatish Balay PetscErrorCode PetscRandomGetValue(PetscRandom r, PetscScalar *val) { 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)); 595c6c1daeSBarry Smith PetscFunctionReturn(0); 605c6c1daeSBarry Smith } 615c6c1daeSBarry Smith 625c6c1daeSBarry Smith /*@ 63808ba619SStefano Zampini PetscRandomGetValueReal - Generates a real random number. Call this after first calling 64*811af0c4SBarry 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 76*811af0c4SBarry Smith Note: 77*811af0c4SBarry 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 88*811af0c4SBarry Smith .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomDestroy()`, `VecSetRandom()`, `PetscRandomGetValue()` 895c6c1daeSBarry Smith @*/ 909371c9d4SSatish Balay PetscErrorCode PetscRandomGetValueReal(PetscRandom r, PetscReal *val) { 915c6c1daeSBarry Smith PetscFunctionBegin; 925c6c1daeSBarry Smith PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1); 935c6c1daeSBarry Smith PetscValidType(r, 1); 94dbbe0bcdSBarry Smith if (!r->ops->getvaluereal) PetscUseTypeMethod(r, getvaluesreal, 1, val); 95dbbe0bcdSBarry Smith else PetscUseTypeMethod(r, getvaluereal, val); 969566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)r)); 97808ba619SStefano Zampini PetscFunctionReturn(0); 98808ba619SStefano Zampini } 99808ba619SStefano Zampini 100808ba619SStefano Zampini /*@ 101808ba619SStefano Zampini PetscRandomGetValues - Generates a sequence of random numbers. Call this after first calling 102*811af0c4SBarry Smith `PetscRandomCreate()`. 103808ba619SStefano Zampini 104808ba619SStefano Zampini Not Collective 105808ba619SStefano Zampini 10601d2d390SJose E. Roman Input Parameters: 107808ba619SStefano Zampini + r - the random number generator context 108808ba619SStefano Zampini - n - number of random numbers to generate 109808ba619SStefano Zampini 110808ba619SStefano Zampini Output Parameter: 111808ba619SStefano Zampini . val - the array to hold the values 112808ba619SStefano Zampini 113808ba619SStefano Zampini Level: intermediate 114808ba619SStefano Zampini 115808ba619SStefano Zampini Notes: 116*811af0c4SBarry Smith Use `VecSetRandom()` to set the elements of a vector to random numbers. 117808ba619SStefano Zampini 118808ba619SStefano Zampini When PETSc is compiled for complex numbers this returns an array of complex numbers with random real and complex parts. 119*811af0c4SBarry Smith Use `PetscRandomGetValuesReal()` to get an array of random real numbers. 120808ba619SStefano Zampini 121*811af0c4SBarry Smith .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomDestroy()`, `VecSetRandom()`, `PetscRandomGetValue()` 122808ba619SStefano Zampini @*/ 1239371c9d4SSatish Balay PetscErrorCode PetscRandomGetValues(PetscRandom r, PetscInt n, PetscScalar *val) { 124808ba619SStefano Zampini PetscFunctionBegin; 125808ba619SStefano Zampini PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1); 126808ba619SStefano Zampini PetscValidType(r, 1); 127808ba619SStefano Zampini if (!r->ops->getvalues) { 128808ba619SStefano Zampini PetscInt i; 12948a46eb9SPierre Jolivet for (i = 0; i < n; i++) PetscCall((*r->ops->getvalue)(r, val + i)); 130dbbe0bcdSBarry Smith } else PetscUseTypeMethod(r, getvalues, n, val); 1319566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)r)); 132808ba619SStefano Zampini PetscFunctionReturn(0); 133808ba619SStefano Zampini } 134808ba619SStefano Zampini 135808ba619SStefano Zampini /*@ 136808ba619SStefano Zampini PetscRandomGetValuesReal - Generates a sequence of real random numbers. Call this after first calling 137*811af0c4SBarry Smith `PetscRandomCreate()`. 138808ba619SStefano Zampini 139808ba619SStefano Zampini Not Collective 140808ba619SStefano Zampini 14101d2d390SJose E. Roman Input Parameters: 142808ba619SStefano Zampini + r - the random number generator context 143808ba619SStefano Zampini - n - number of random numbers to generate 144808ba619SStefano Zampini 145808ba619SStefano Zampini Output Parameter: 146808ba619SStefano Zampini . val - the array to hold the values 147808ba619SStefano Zampini 148808ba619SStefano Zampini Level: intermediate 149808ba619SStefano Zampini 150*811af0c4SBarry Smith Note: 151*811af0c4SBarry Smith Use `VecSetRandom()` to set the elements of a vector to random numbers. 152808ba619SStefano Zampini 153*811af0c4SBarry Smith .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomDestroy()`, `VecSetRandom()`, `PetscRandomGetValues()` 154808ba619SStefano Zampini @*/ 1559371c9d4SSatish Balay PetscErrorCode PetscRandomGetValuesReal(PetscRandom r, PetscInt n, PetscReal *val) { 156808ba619SStefano Zampini PetscFunctionBegin; 157808ba619SStefano Zampini PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1); 158808ba619SStefano Zampini PetscValidType(r, 1); 159808ba619SStefano Zampini if (!r->ops->getvaluesreal) { 160808ba619SStefano Zampini PetscInt i; 16148a46eb9SPierre Jolivet for (i = 0; i < n; i++) PetscCall((*r->ops->getvaluereal)(r, val + i)); 162dbbe0bcdSBarry Smith } else PetscUseTypeMethod(r, getvaluesreal, n, val); 1639566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)r)); 1645c6c1daeSBarry Smith PetscFunctionReturn(0); 1655c6c1daeSBarry Smith } 1665c6c1daeSBarry Smith 1675c6c1daeSBarry Smith /*@ 1685c6c1daeSBarry Smith PetscRandomGetInterval - Gets the interval over which the random numbers 169*811af0c4SBarry Smith will be distributed. By default, this interval is [0,1). 1705c6c1daeSBarry Smith 1715c6c1daeSBarry Smith Not collective 1725c6c1daeSBarry Smith 173f899ff85SJose E. Roman Input Parameter: 1745c6c1daeSBarry Smith . r - the random number generator context 1755c6c1daeSBarry Smith 1765c6c1daeSBarry Smith Output Parameters: 1775c6c1daeSBarry Smith + low - The lower bound of the interval 1785c6c1daeSBarry Smith - high - The upper bound of the interval 1795c6c1daeSBarry Smith 1805c6c1daeSBarry Smith Level: intermediate 1815c6c1daeSBarry Smith 182*811af0c4SBarry Smith .seealso: `PetscRandom`, `PetscRandomCreate()`, `PetscRandomSetInterval()` 1835c6c1daeSBarry Smith @*/ 1849371c9d4SSatish Balay PetscErrorCode PetscRandomGetInterval(PetscRandom r, PetscScalar *low, PetscScalar *high) { 1855c6c1daeSBarry Smith PetscFunctionBegin; 1865c6c1daeSBarry Smith PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1); 1875c6c1daeSBarry Smith if (low) { 1885c6c1daeSBarry Smith PetscValidScalarPointer(low, 2); 1895c6c1daeSBarry Smith *low = r->low; 1905c6c1daeSBarry Smith } 1915c6c1daeSBarry Smith if (high) { 1925c6c1daeSBarry Smith PetscValidScalarPointer(high, 3); 1935c6c1daeSBarry Smith *high = r->low + r->width; 1945c6c1daeSBarry Smith } 1955c6c1daeSBarry Smith PetscFunctionReturn(0); 1965c6c1daeSBarry Smith } 1975c6c1daeSBarry Smith 1985c6c1daeSBarry Smith /*@ 1995c6c1daeSBarry Smith PetscRandomSetInterval - Sets the interval over which the random numbers 200*811af0c4SBarry Smith will be distributed. By default, this interval is [0,1). 2015c6c1daeSBarry Smith 2025c6c1daeSBarry Smith Not collective 2035c6c1daeSBarry Smith 2045c6c1daeSBarry Smith Input Parameters: 2055c6c1daeSBarry Smith + r - the random number generator context 2065c6c1daeSBarry Smith . low - The lower bound of the interval 2075c6c1daeSBarry Smith - high - The upper bound of the interval 2085c6c1daeSBarry Smith 2095c6c1daeSBarry Smith Level: intermediate 2105c6c1daeSBarry Smith 21195452b02SPatrick Sanan Notes: 21295452b02SPatrick 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. 213*811af0c4SBarry Smith 2145c6c1daeSBarry 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. 2155c6c1daeSBarry Smith 216db781477SPatrick Sanan .seealso: `PetscRandomCreate()`, `PetscRandomGetInterval()` 2175c6c1daeSBarry Smith @*/ 2189371c9d4SSatish Balay PetscErrorCode PetscRandomSetInterval(PetscRandom r, PetscScalar low, PetscScalar high) { 2195c6c1daeSBarry Smith PetscFunctionBegin; 2205c6c1daeSBarry Smith PetscValidHeaderSpecific(r, PETSC_RANDOM_CLASSID, 1); 2215c6c1daeSBarry Smith #if defined(PETSC_USE_COMPLEX) 22208401ef6SPierre Jolivet PetscCheck(PetscRealPart(low) <= PetscRealPart(high), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "only low <= high"); 22308401ef6SPierre Jolivet PetscCheck(PetscImaginaryPart(low) <= PetscImaginaryPart(high), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "only low <= high"); 2245c6c1daeSBarry Smith #else 22508401ef6SPierre Jolivet PetscCheck(low < high, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "only low <= high: Instead %g %g", (double)low, (double)high); 2265c6c1daeSBarry Smith #endif 2275c6c1daeSBarry Smith r->low = low; 2285c6c1daeSBarry Smith r->width = high - low; 2295c6c1daeSBarry Smith r->iset = PETSC_TRUE; 2305c6c1daeSBarry Smith PetscFunctionReturn(0); 2315c6c1daeSBarry Smith } 232