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)); 603ba16761SJacob 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)); 993ba16761SJacob 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)); 1363ba16761SJacob 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)); 1693ba16761SJacob 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 176*20f4b53cSBarry 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 } 2013ba16761SJacob 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 208*20f4b53cSBarry 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; 2373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2385c6c1daeSBarry Smith } 239