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) { 58*28b400f6SJacob Faibussowitsch PetscCheck(r->ops->getvalues,PetscObjectComm((PetscObject)r),PETSC_ERR_SUP,"Random type %s cannot generate PetscScalar",((PetscObject)r)->type_name); 595f80ce2aSJacob Faibussowitsch CHKERRQ((*r->ops->getvalues)(r,1,val)); 60808ba619SStefano Zampini } else { 615f80ce2aSJacob Faibussowitsch CHKERRQ((*r->ops->getvalue)(r,val)); 62808ba619SStefano Zampini } 635f80ce2aSJacob Faibussowitsch CHKERRQ(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) { 101*28b400f6SJacob Faibussowitsch PetscCheck(r->ops->getvaluesreal,PetscObjectComm((PetscObject)r),PETSC_ERR_SUP,"Random type %s cannot generate PetscReal",((PetscObject)r)->type_name); 1025f80ce2aSJacob Faibussowitsch CHKERRQ((*r->ops->getvaluesreal)(r,1,val)); 103808ba619SStefano Zampini } else { 1045f80ce2aSJacob Faibussowitsch CHKERRQ((*r->ops->getvaluereal)(r,val)); 105808ba619SStefano Zampini } 1065f80ce2aSJacob Faibussowitsch CHKERRQ(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; 140*28b400f6SJacob 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++) { 1425f80ce2aSJacob Faibussowitsch CHKERRQ((*r->ops->getvalue)(r,val+i)); 143808ba619SStefano Zampini } 144808ba619SStefano Zampini } else { 1455f80ce2aSJacob Faibussowitsch CHKERRQ((*r->ops->getvalues)(r,n,val)); 146808ba619SStefano Zampini } 1475f80ce2aSJacob Faibussowitsch CHKERRQ(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; 178*28b400f6SJacob 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++) { 1805f80ce2aSJacob Faibussowitsch CHKERRQ((*r->ops->getvaluereal)(r,val+i)); 181808ba619SStefano Zampini } 182808ba619SStefano Zampini } else { 1835f80ce2aSJacob Faibussowitsch CHKERRQ((*r->ops->getvaluesreal)(r,n,val)); 184808ba619SStefano Zampini } 1855f80ce2aSJacob Faibussowitsch CHKERRQ(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) 2452c71b3e2SJacob Faibussowitsch PetscCheckFalse(PetscRealPart(low) > PetscRealPart(high),PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"only low <= high"); 2462c71b3e2SJacob Faibussowitsch PetscCheckFalse(PetscImaginaryPart(low) > PetscImaginaryPart(high),PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"only low <= high"); 2475c6c1daeSBarry Smith #else 2482c71b3e2SJacob Faibussowitsch PetscCheckFalse(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