1c4762a1bSJed Brown static char help[] = "Tests PetscRandom functions.\n\n"; 2c4762a1bSJed Brown 3c4762a1bSJed Brown #include <petscsys.h> 4c4762a1bSJed Brown 5c4762a1bSJed Brown #define PETSC_MAXBSIZE 40 6c4762a1bSJed Brown #define DATAFILENAME "ex2_stock.txt" 7c4762a1bSJed Brown 8c4762a1bSJed Brown struct himaInfoTag { 9c4762a1bSJed Brown PetscInt n; 10c4762a1bSJed Brown PetscReal r; 11c4762a1bSJed Brown PetscReal dt; 12c4762a1bSJed Brown PetscInt totalNumSim; 13c4762a1bSJed Brown PetscReal *St0; 14c4762a1bSJed Brown PetscReal *vol; 15c4762a1bSJed Brown }; 16c4762a1bSJed Brown typedef struct himaInfoTag himaInfo; 17c4762a1bSJed Brown 18c4762a1bSJed Brown PetscErrorCode readData(MPI_Comm, himaInfo *); 19c4762a1bSJed Brown PetscReal mcVal(PetscReal, PetscReal, PetscReal, PetscReal, PetscReal); 20c4762a1bSJed Brown void exchangeVal(PetscReal *, PetscReal *); 21c4762a1bSJed Brown PetscReal basketPayoff(PetscReal[], PetscReal[], PetscInt, PetscReal, PetscReal, PetscReal[]); 22c4762a1bSJed Brown PetscErrorCode stdNormalArray(PetscReal *, PetscInt, PetscRandom); 23c4762a1bSJed Brown PetscInt divWork(PetscMPIInt, PetscInt, PetscMPIInt); 24c4762a1bSJed Brown 25c4762a1bSJed Brown /* 26c4762a1bSJed Brown Contributed by Xiaoyan Zeng <zengxia@iit.edu> and Liu, Kwong Ip" <kiliu@math.hkbu.edu.hk> 27c4762a1bSJed Brown 28c4762a1bSJed Brown Example of usage: 29c4762a1bSJed Brown mpiexec -n 4 ./ex2 -num_of_stocks 30 -interest_rate 0.4 -time_interval 0.01 -num_of_simulations 10000 30c4762a1bSJed Brown */ 31c4762a1bSJed Brown 32d71ae5a4SJacob Faibussowitsch int main(int argc, char *argv[]) 33d71ae5a4SJacob Faibussowitsch { 34c4762a1bSJed Brown PetscReal r, dt; 35c4762a1bSJed Brown PetscInt n; 36c4762a1bSJed Brown unsigned long i, myNumSim, totalNumSim, numdim; 37c4762a1bSJed Brown PetscReal *vol, *St0, x, totalx; 38c4762a1bSJed Brown PetscMPIInt size, rank; 39c4762a1bSJed Brown PetscReal *eps; 40c4762a1bSJed Brown himaInfo hinfo; 41c4762a1bSJed Brown PetscRandom ran; 42c4762a1bSJed Brown 43327415f7SBarry Smith PetscFunctionBeginUser; 449566063dSJacob Faibussowitsch PetscCall(PetscInitialize(&argc, &argv, (char *)0, help)); 459566063dSJacob Faibussowitsch PetscCall(PetscRandomCreate(PETSC_COMM_WORLD, &ran)); 469566063dSJacob Faibussowitsch PetscCall(PetscRandomSetFromOptions(ran)); 47c4762a1bSJed Brown 489566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size)); 499566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); 50c4762a1bSJed Brown 51c4762a1bSJed Brown hinfo.n = 31; 52c4762a1bSJed Brown hinfo.r = 0.04; 53c4762a1bSJed Brown hinfo.dt = 1.0 / 12; /* a month as a period */ 54c4762a1bSJed Brown hinfo.totalNumSim = 1000; 55c4762a1bSJed Brown 56f4f49eeaSPierre Jolivet PetscCall(PetscOptionsGetInt(NULL, NULL, "-num_of_stocks", &hinfo.n, NULL)); 57cc73adaaSBarry Smith PetscCheck(hinfo.n >= 1 && hinfo.n <= 31, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only 31 stocks listed in stock.txt. num_of_stocks %" PetscInt_FMT " must between 1 and 31", hinfo.n); 58f4f49eeaSPierre Jolivet PetscCall(PetscOptionsGetReal(NULL, NULL, "-interest_rate", &hinfo.r, NULL)); 59f4f49eeaSPierre Jolivet PetscCall(PetscOptionsGetReal(NULL, NULL, "-time_interval", &hinfo.dt, NULL)); 60f4f49eeaSPierre Jolivet PetscCall(PetscOptionsGetInt(NULL, NULL, "-num_of_simulations", &hinfo.totalNumSim, NULL)); 61c4762a1bSJed Brown 62c4762a1bSJed Brown n = hinfo.n; 63c4762a1bSJed Brown r = hinfo.r; 64c4762a1bSJed Brown dt = hinfo.dt; 65c4762a1bSJed Brown totalNumSim = hinfo.totalNumSim; 669566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(2 * n + 1, &hinfo.vol)); 67c4762a1bSJed Brown vol = hinfo.vol; 68c4762a1bSJed Brown St0 = hinfo.St0 = hinfo.vol + n; 699566063dSJacob Faibussowitsch PetscCall(readData(PETSC_COMM_WORLD, &hinfo)); 70c4762a1bSJed Brown 71c4762a1bSJed Brown numdim = n * (n + 1) / 2; 72c4762a1bSJed Brown if (numdim % 2 == 1) numdim++; 739566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numdim, &eps)); 74c4762a1bSJed Brown 75c4762a1bSJed Brown myNumSim = divWork(rank, totalNumSim, size); 76c4762a1bSJed Brown 77c4762a1bSJed Brown x = 0; 78c4762a1bSJed Brown for (i = 0; i < myNumSim; i++) { 799566063dSJacob Faibussowitsch PetscCall(stdNormalArray(eps, numdim, ran)); 80c4762a1bSJed Brown x += basketPayoff(vol, St0, n, r, dt, eps); 81c4762a1bSJed Brown } 82c4762a1bSJed Brown 839566063dSJacob Faibussowitsch PetscCallMPI(MPI_Reduce(&x, &totalx, 1, MPIU_REAL, MPIU_SUM, 0, PETSC_COMM_WORLD)); 84c4762a1bSJed Brown /* payoff = exp(-r*dt*n)*(totalx/totalNumSim); 85c4762a1bSJed Brown ierr = PetscPrintf(PETSC_COMM_WORLD,"Option price = $%.3f using %ds of %s computation with %d %s for %d stocks, %d trading period per year, %.2f%% interest rate\n", 86d0609cedSBarry Smith payoff,(int)(stop - start),"parallel",size,"processors",n,(int)(1/dt),r); */ 87c4762a1bSJed Brown 889566063dSJacob Faibussowitsch PetscCall(PetscFree(vol)); 899566063dSJacob Faibussowitsch PetscCall(PetscFree(eps)); 909566063dSJacob Faibussowitsch PetscCall(PetscRandomDestroy(&ran)); 919566063dSJacob Faibussowitsch PetscCall(PetscFinalize()); 92b122ec5aSJacob Faibussowitsch return 0; 93c4762a1bSJed Brown } 94c4762a1bSJed Brown 95d71ae5a4SJacob Faibussowitsch PetscErrorCode stdNormalArray(PetscReal *eps, PetscInt numdim, PetscRandom ran) 96d71ae5a4SJacob Faibussowitsch { 97c4762a1bSJed Brown PetscInt i; 98c4762a1bSJed Brown PetscScalar u1, u2; 99c4762a1bSJed Brown PetscReal t; 100c4762a1bSJed Brown 101c4762a1bSJed Brown PetscFunctionBegin; 102c4762a1bSJed Brown for (i = 0; i < numdim; i += 2) { 1039566063dSJacob Faibussowitsch PetscCall(PetscRandomGetValue(ran, &u1)); 1049566063dSJacob Faibussowitsch PetscCall(PetscRandomGetValue(ran, &u2)); 105c4762a1bSJed Brown 106c4762a1bSJed Brown t = PetscSqrtReal(-2 * PetscLogReal(PetscRealPart(u1))); 107c4762a1bSJed Brown eps[i] = t * PetscCosReal(2 * PETSC_PI * PetscRealPart(u2)); 108c4762a1bSJed Brown eps[i + 1] = t * PetscSinReal(2 * PETSC_PI * PetscRealPart(u2)); 109c4762a1bSJed Brown } 1103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 111c4762a1bSJed Brown } 112c4762a1bSJed Brown 113d71ae5a4SJacob Faibussowitsch PetscReal basketPayoff(PetscReal vol[], PetscReal St0[], PetscInt n, PetscReal r, PetscReal dt, PetscReal eps[]) 114d71ae5a4SJacob Faibussowitsch { 115c4762a1bSJed Brown PetscReal Stk[PETSC_MAXBSIZE], temp; 116c4762a1bSJed Brown PetscReal payoff; 117c4762a1bSJed Brown PetscInt maxk, i, j; 118c4762a1bSJed Brown PetscInt pointcount = 0; 119c4762a1bSJed Brown 120c4762a1bSJed Brown for (i = 0; i < n; i++) Stk[i] = St0[i]; 121c4762a1bSJed Brown 122c4762a1bSJed Brown for (i = 0; i < n; i++) { 123c4762a1bSJed Brown maxk = 0; 124c4762a1bSJed Brown for (j = 0; j < (n - i); j++) { 125c4762a1bSJed Brown Stk[j] = mcVal(Stk[j], r, vol[j], dt, eps[pointcount++]); 126c4762a1bSJed Brown if ((Stk[j] / St0[j]) > (Stk[maxk] / St0[maxk])) maxk = j; 127c4762a1bSJed Brown } 128c4762a1bSJed Brown exchangeVal(Stk + j - 1, Stk + maxk); 129c4762a1bSJed Brown exchangeVal(St0 + j - 1, St0 + maxk); 130c4762a1bSJed Brown exchangeVal(vol + j - 1, vol + maxk); 131c4762a1bSJed Brown } 132c4762a1bSJed Brown 133c4762a1bSJed Brown payoff = 0; 134c4762a1bSJed Brown for (i = 0; i < n; i++) { 135c4762a1bSJed Brown temp = (Stk[i] / St0[i]) - 1; 136c4762a1bSJed Brown if (temp > 0) payoff += temp; 137c4762a1bSJed Brown } 138c4762a1bSJed Brown return payoff; 139c4762a1bSJed Brown } 140c4762a1bSJed Brown 141d71ae5a4SJacob Faibussowitsch PetscErrorCode readData(MPI_Comm comm, himaInfo *hinfo) 142d71ae5a4SJacob Faibussowitsch { 143c4762a1bSJed Brown PetscInt i; 144c4762a1bSJed Brown FILE *fd; 145c4762a1bSJed Brown char temp[50]; 146c4762a1bSJed Brown PetscMPIInt rank; 147c4762a1bSJed Brown PetscReal *v = hinfo->vol, *t = hinfo->St0; 148c4762a1bSJed Brown PetscInt num = hinfo->n; 149c4762a1bSJed Brown 150c4762a1bSJed Brown PetscFunctionBeginUser; 1519566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 152dd400576SPatrick Sanan if (rank == 0) { 1539566063dSJacob Faibussowitsch PetscCall(PetscFOpen(PETSC_COMM_SELF, DATAFILENAME, "r", &fd)); 154c4762a1bSJed Brown for (i = 0; i < num; i++) { 155c4762a1bSJed Brown double vv, tt; 15608401ef6SPierre Jolivet PetscCheck(fscanf(fd, "%s%lf%lf", temp, &vv, &tt) == 3, PETSC_COMM_SELF, PETSC_ERR_FILE_UNEXPECTED, "Badly formatted input file"); 157c4762a1bSJed Brown v[i] = vv; 158c4762a1bSJed Brown t[i] = tt; 159c4762a1bSJed Brown } 160c4762a1bSJed Brown fclose(fd); 161c4762a1bSJed Brown } 1629566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(v, 2 * num, MPIU_REAL, 0, PETSC_COMM_WORLD)); 163c4762a1bSJed Brown /* ierr = PetscPrintf(PETSC_COMM_SELF,"[%d] vol %g, ... %g; St0 %g, ... %g\n",rank,hinfo->vol[0],hinfo->vol[num-1],hinfo->St0 [0],hinfo->St0[num-1]); */ 1643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 165c4762a1bSJed Brown } 166c4762a1bSJed Brown 167d71ae5a4SJacob Faibussowitsch void exchangeVal(PetscReal *a, PetscReal *b) 168d71ae5a4SJacob Faibussowitsch { 169c4762a1bSJed Brown PetscReal t; 170c4762a1bSJed Brown 171c4762a1bSJed Brown t = *a; 172c4762a1bSJed Brown *a = *b; 173c4762a1bSJed Brown *b = t; 174c4762a1bSJed Brown } 175c4762a1bSJed Brown 176d71ae5a4SJacob Faibussowitsch PetscReal mcVal(PetscReal St, PetscReal r, PetscReal vol, PetscReal dt, PetscReal eps) 177d71ae5a4SJacob Faibussowitsch { 178*4ad8454bSPierre Jolivet return St * PetscExpReal((r - 0.5 * vol * vol) * dt + vol * PetscSqrtReal(dt) * eps); 179c4762a1bSJed Brown } 180c4762a1bSJed Brown 181d71ae5a4SJacob Faibussowitsch PetscInt divWork(PetscMPIInt id, PetscInt num, PetscMPIInt size) 182d71ae5a4SJacob Faibussowitsch { 183c4762a1bSJed Brown PetscInt numit; 184c4762a1bSJed Brown 185c4762a1bSJed Brown numit = (PetscInt)(((PetscReal)num) / size); 186c4762a1bSJed Brown numit++; 187c4762a1bSJed Brown return numit; 188c4762a1bSJed Brown } 189c4762a1bSJed Brown 190c4762a1bSJed Brown /*TEST 191c4762a1bSJed Brown 192c4762a1bSJed Brown test: 193c4762a1bSJed Brown nsize: 2 194c4762a1bSJed Brown output_file: output/ex1_1.out 195c4762a1bSJed Brown localrunfiles: ex2_stock.txt 196c4762a1bSJed Brown 197c4762a1bSJed Brown TEST*/ 198