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
main(int argc,char * argv[])32d71ae5a4SJacob Faibussowitsch int main(int argc, char *argv[])
33d71ae5a4SJacob Faibussowitsch {
34c4762a1bSJed Brown PetscReal r, dt;
35c4762a1bSJed Brown PetscInt n;
366497c311SBarry Smith PetscInt 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;
44c8025a54SPierre Jolivet PetscCall(PetscInitialize(&argc, &argv, NULL, 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
stdNormalArray(PetscReal * eps,PetscInt numdim,PetscRandom ran)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
basketPayoff(PetscReal vol[],PetscReal St0[],PetscInt n,PetscReal r,PetscReal dt,PetscReal eps[])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
readData(MPI_Comm comm,himaInfo * hinfo)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 }
1626497c311SBarry Smith PetscCallMPI(MPI_Bcast(v, (PetscMPIInt)(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
exchangeVal(PetscReal * a,PetscReal * b)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
mcVal(PetscReal St,PetscReal r,PetscReal vol,PetscReal dt,PetscReal eps)176d71ae5a4SJacob Faibussowitsch PetscReal mcVal(PetscReal St, PetscReal r, PetscReal vol, PetscReal dt, PetscReal eps)
177d71ae5a4SJacob Faibussowitsch {
1784ad8454bSPierre Jolivet return St * PetscExpReal((r - 0.5 * vol * vol) * dt + vol * PetscSqrtReal(dt) * eps);
179c4762a1bSJed Brown }
180c4762a1bSJed Brown
divWork(PetscMPIInt id,PetscInt num,PetscMPIInt size)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
194*3886731fSPierre Jolivet output_file: output/empty.out
195c4762a1bSJed Brown localrunfiles: ex2_stock.txt
196c4762a1bSJed Brown
197c4762a1bSJed Brown TEST*/
198