Skip to content

Commit b7b6404

Browse files
authored
Example/bs (#755)
* EXAMPLE update example_bs.cpp
1 parent 3d7c734 commit b7b6404

File tree

2 files changed

+116
-102
lines changed

2 files changed

+116
-102
lines changed

dpnp/backend/examples/example_bs.cpp

Lines changed: 102 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -42,107 +42,161 @@
4242
void black_scholes(double* price,
4343
double* strike,
4444
double* t,
45-
double* mrs,
46-
double* vol_vol_twos,
47-
double* quarters,
48-
double* ones,
49-
double* halfs,
45+
const double rate,
46+
const double vol,
5047
double* call,
5148
double* put,
5249
const size_t size)
5350
{
51+
const size_t ndim = 1;
52+
const size_t scalar_size = 1;
53+
54+
double* mr = (double*)dpnp_memory_alloc_c(1 * sizeof(double));
55+
mr[0] = -rate;
56+
57+
double* vol_vol_two = (double*)dpnp_memory_alloc_c(1 * sizeof(double));
58+
vol_vol_two[0] = vol * vol * 2;
59+
60+
double* quarter = (double*)dpnp_memory_alloc_c(1 * sizeof(double));
61+
quarter[0] = 0.25;
62+
63+
double* one = (double*)dpnp_memory_alloc_c(1 * sizeof(double));
64+
one[0] = 1.;
65+
66+
double* half = (double*)dpnp_memory_alloc_c(1 * sizeof(double));
67+
half[0] = 0.5;
68+
5469
double* P = price;
5570
double* S = strike;
5671
double* T = t;
5772

58-
double* PdivS = (double*)dpnp_memory_alloc_c(size * sizeof(double));
59-
dpnp_divide_c<double, double, double>(P, S, PdivS, size); // P / S
73+
double* p_div_s = (double*)dpnp_memory_alloc_c(size * sizeof(double));
74+
// p_div_s = P / S
75+
dpnp_divide_c<double, double, double>(p_div_s, P, size, &size, ndim, S, size, &size, ndim, NULL);
6076
double* a = (double*)dpnp_memory_alloc_c(size * sizeof(double));
61-
dpnp_log_c<double, double>(PdivS, a, size); // np.log(P / S)
62-
dpnp_memory_free_c(PdivS);
77+
dpnp_log_c<double, double>(p_div_s, a, size); // a = np.log(p_div_s)
78+
dpnp_memory_free_c(p_div_s);
6379

6480
double* b = (double*)dpnp_memory_alloc_c(size * sizeof(double));
65-
dpnp_multiply_c<double, double, double>(T, mrs, b, size); // T * mrs
66-
81+
// b = T * mr
82+
dpnp_multiply_c<double, double, double>(b, T, size, &size, ndim, mr, scalar_size, &scalar_size, ndim, NULL);
83+
dpnp_memory_free_c(mr);
6784
double* z = (double*)dpnp_memory_alloc_c(size * sizeof(double));
68-
dpnp_multiply_c<double, double, double>(T, vol_vol_twos, z, size); // T * vol_vol_twos
85+
// z = T * vol_vol_twos
86+
dpnp_multiply_c<double, double, double>(z,
87+
T, size, &size, ndim,
88+
vol_vol_two, scalar_size, &scalar_size, ndim,
89+
NULL);
90+
dpnp_memory_free_c(vol_vol_two);
6991

7092
double* c = (double*)dpnp_memory_alloc_c(size * sizeof(double));
71-
dpnp_multiply_c<double, double, double>(quarters, z, c, size); // quarters * z
93+
// c = quarters * z
94+
dpnp_multiply_c<double, double, double>(c, quarter, scalar_size, &scalar_size, ndim, z, size, &size, ndim, NULL);
95+
dpnp_memory_free_c(quarter);
7296

7397
double* sqrt_z = (double*)dpnp_memory_alloc_c(size * sizeof(double));
74-
dpnp_sqrt_c<double, double>(z, sqrt_z, size); // np.sqrt(z)
98+
dpnp_sqrt_c<double, double>(z, sqrt_z, size); // sqrt_z = np.sqrt(z)
7599
dpnp_memory_free_c(z);
76100
double* y = (double*)dpnp_memory_alloc_c(size * sizeof(double));
77-
dpnp_divide_c<double, double, double>(ones, sqrt_z, y, size); // ones/np.sqrt(z)
101+
// y = ones / np.sqrt(z)
102+
dpnp_divide_c<double, double, double>(y, one, scalar_size, &scalar_size, ndim, sqrt_z, size, &size, ndim, NULL);
78103
dpnp_memory_free_c(sqrt_z);
104+
dpnp_memory_free_c(one);
79105

80106
double* a_sub_b = (double*)dpnp_memory_alloc_c(size * sizeof(double));
81-
dpnp_subtract_c<double, double, double>(a, b, a_sub_b, size); // a - b
107+
// a_sub_b = a - b
108+
dpnp_subtract_c<double, double, double>(a_sub_b, a, size, &size, ndim, b, size, &size, ndim, NULL);
82109
dpnp_memory_free_c(a);
83110
double* a_sub_b_add_c = (double*)dpnp_memory_alloc_c(size * sizeof(double));
84-
dpnp_add_c<double, double, double>(a_sub_b, c, a_sub_b_add_c, size); // a - b + c
111+
// a_sub_b_add_c = a_sub_b + c
112+
dpnp_add_c<double, double, double>(a_sub_b_add_c, a_sub_b, size, &size, ndim, c, size, &size, ndim, NULL);
85113
double* w1 = (double*)dpnp_memory_alloc_c(size * sizeof(double));
86-
dpnp_multiply_c<double, double, double>(a_sub_b_add_c, y, w1, size); // (a - b + c) * y
114+
// w1 = a_sub_b_add_c * y
115+
dpnp_multiply_c<double, double, double>(w1, a_sub_b_add_c, size, &size, ndim, y, size, &size, ndim, NULL);
87116
dpnp_memory_free_c(a_sub_b_add_c);
88117

89118
double* a_sub_b_sub_c = (double*)dpnp_memory_alloc_c(size * sizeof(double));
90-
dpnp_subtract_c<double, double, double>(a_sub_b, c, a_sub_b_sub_c, size); // a - b - c
119+
// a_sub_b_sub_c = a_sub_b - c
120+
dpnp_subtract_c<double, double, double>(a_sub_b_sub_c, a_sub_b, size, &size, ndim, c, size, &size, ndim, NULL);
91121
dpnp_memory_free_c(a_sub_b);
92122
dpnp_memory_free_c(c);
93123
double* w2 = (double*)dpnp_memory_alloc_c(size * sizeof(double));
94-
dpnp_multiply_c<double, double, double>(a_sub_b_sub_c, y, w2, size); // (a - b - c) * y
124+
// w2 = a_sub_b_sub_c * y
125+
dpnp_multiply_c<double, double, double>(w2, a_sub_b_sub_c, size, &size, ndim, y, size, &size, ndim, NULL);
95126
dpnp_memory_free_c(a_sub_b_sub_c);
96127
dpnp_memory_free_c(y);
97128

98129
double* erf_w1 = (double*)dpnp_memory_alloc_c(size * sizeof(double));
99-
dpnp_erf_c<double>(w1, erf_w1, size); // np.erf(w1)
130+
dpnp_erf_c<double>(w1, erf_w1, size); // erf_w1 = np.erf(w1)
100131
dpnp_memory_free_c(w1);
101132
double* halfs_mul_erf_w1 = (double*)dpnp_memory_alloc_c(size * sizeof(double));
102-
dpnp_multiply_c<double, double, double>(halfs, erf_w1, halfs_mul_erf_w1, size); // halfs * np.erf(w1)
133+
// halfs_mul_erf_w1 = halfs * erf_w1
134+
dpnp_multiply_c<double, double, double>(halfs_mul_erf_w1,
135+
half, scalar_size, &scalar_size, ndim,
136+
erf_w1, size, &size, ndim,
137+
NULL);
103138
dpnp_memory_free_c(erf_w1);
104139
double* d1 = (double*)dpnp_memory_alloc_c(size * sizeof(double));
105-
dpnp_add_c<double, double, double>(halfs, halfs_mul_erf_w1, d1, size); // halfs + halfs * np.erf(w1)
140+
// d1 = halfs + halfs_mul_erf_w1
141+
dpnp_add_c<double, double, double>(d1,
142+
half, scalar_size, &scalar_size, ndim,
143+
halfs_mul_erf_w1, size, &size, ndim,
144+
NULL);
106145
dpnp_memory_free_c(halfs_mul_erf_w1);
107146

108147
double* erf_w2 = (double*)dpnp_memory_alloc_c(size * sizeof(double));
109-
dpnp_erf_c<double>(w2, erf_w2, size); // np.erf(w2)
148+
dpnp_erf_c<double>(w2, erf_w2, size); // erf_w2 = np.erf(w2)
110149
dpnp_memory_free_c(w2);
111150
double* halfs_mul_erf_w2 = (double*)dpnp_memory_alloc_c(size * sizeof(double));
112-
dpnp_multiply_c<double, double, double>(halfs, erf_w2, halfs_mul_erf_w2, size); // halfs * np.erf(w2)
151+
// halfs_mul_erf_w2 = halfs * erf_w2
152+
dpnp_multiply_c<double, double, double>(halfs_mul_erf_w2,
153+
half, scalar_size, &scalar_size, ndim,
154+
erf_w2, size, &size, ndim,
155+
NULL);
113156
dpnp_memory_free_c(erf_w2);
114157
double* d2 = (double*)dpnp_memory_alloc_c(size * sizeof(double));
115-
dpnp_add_c<double, double, double>(halfs, halfs_mul_erf_w2, d2, size); // halfs + halfs * np.erf(w2)
158+
// d2 = halfs + halfs_mul_erf_w2
159+
dpnp_add_c<double, double, double>(d2,
160+
half, scalar_size, &scalar_size, ndim,
161+
halfs_mul_erf_w2, size, &size, ndim,
162+
NULL);
116163
dpnp_memory_free_c(halfs_mul_erf_w2);
164+
dpnp_memory_free_c(half);
117165

118166
double* exp_b = (double*)dpnp_memory_alloc_c(size * sizeof(double));
119-
dpnp_exp_c<double, double>(b, exp_b, size); // np.exp(b)
167+
dpnp_exp_c<double, double>(b, exp_b, size); // exp_b = np.exp(b)
120168
double* Se = (double*)dpnp_memory_alloc_c(size * sizeof(double));
121-
dpnp_multiply_c<double, double, double>(exp_b, S, Se, size); // np.exp(b) * S
169+
// Se = exp_b * S
170+
dpnp_multiply_c<double, double, double>(Se, exp_b, size, &size, ndim, S, size, &size, ndim, NULL);
122171
dpnp_memory_free_c(exp_b);
123172
dpnp_memory_free_c(b);
124173

125-
double* Pmul_d1 = (double*)dpnp_memory_alloc_c(size * sizeof(double));
126-
dpnp_multiply_c<double, double, double>(P, d1, Pmul_d1, size); // P * d1
174+
double* P_mul_d1 = (double*)dpnp_memory_alloc_c(size * sizeof(double));
175+
// P_mul_d1 = P * d1
176+
dpnp_multiply_c<double, double, double>(P_mul_d1, P, size, &size, ndim, d1, size, &size, ndim, NULL);
127177
dpnp_memory_free_c(d1);
128178
double* Se_mul_d2 = (double*)dpnp_memory_alloc_c(size * sizeof(double));
129-
dpnp_multiply_c<double, double, double>(Se, d2, Se_mul_d2, size); // Se * d2
179+
// Se_mul_d2 = Se * d2
180+
dpnp_multiply_c<double, double, double>(Se_mul_d2, Se, size, &size, ndim, d2, size, &size, ndim, NULL);
130181
dpnp_memory_free_c(d2);
131182
double* r = (double*)dpnp_memory_alloc_c(size * sizeof(double));
132-
dpnp_subtract_c<double, double, double>(Pmul_d1, Se_mul_d2, r, size); // P * d1 - Se * d2
183+
// r = P_mul_d1 - Se_mul_d2
184+
dpnp_subtract_c<double, double, double>(r, P_mul_d1, size, &size, ndim, Se_mul_d2, size, &size, ndim, NULL);
133185
dpnp_memory_free_c(Se_mul_d2);
134-
dpnp_memory_free_c(Pmul_d1);
186+
dpnp_memory_free_c(P_mul_d1);
135187

136188
dpnp_copyto_c<double, double>(call, r, size); // call[:] = r
137-
double* r_subP = (double*)dpnp_memory_alloc_c(size * sizeof(double));
138-
dpnp_subtract_c<double, double, double>(r, P, r_subP, size); // r - P
189+
double* r_sub_P = (double*)dpnp_memory_alloc_c(size * sizeof(double));
190+
// r_sub_P = r - P
191+
dpnp_subtract_c<double, double, double>(r_sub_P, r, size, &size, ndim, P, size, &size, ndim, NULL);
139192
dpnp_memory_free_c(r);
140-
double* r_subPaddSe = (double*)dpnp_memory_alloc_c(size * sizeof(double));
141-
dpnp_add_c<double, double, double>(r_subP, Se, r_subPaddSe, size); // r - P + Se
142-
dpnp_memory_free_c(r_subP);
193+
double* r_sub_P_add_Se = (double*)dpnp_memory_alloc_c(size * sizeof(double));
194+
// r_sub_P_add_Se = r_sub_P + Se
195+
dpnp_add_c<double, double, double>(r_sub_P_add_Se, r_sub_P, size, &size, ndim, Se, size, &size, ndim, NULL);
196+
dpnp_memory_free_c(r_sub_P);
143197
dpnp_memory_free_c(Se);
144-
dpnp_copyto_c<double, double>(put, r_subPaddSe, size); // put[:] = r - P + Se
145-
dpnp_memory_free_c(r_subPaddSe);
198+
dpnp_copyto_c<double, double>(put, r_sub_P_add_Se, size); // put[:] = r_sub_P_add_Se
199+
dpnp_memory_free_c(r_sub_P_add_Se);
146200
}
147201

148202
int main(int, char**)
@@ -174,64 +228,30 @@ int main(int, char**)
174228
double* mone = (double*)dpnp_memory_alloc_c(1 * sizeof(double));
175229
mone[0] = -1.;
176230

177-
double* mr = (double*)dpnp_memory_alloc_c(1 * sizeof(double));
178-
mr[0] = -RISK_FREE;
179-
180-
double* vol_vol_two = (double*)dpnp_memory_alloc_c(1 * sizeof(double));
181-
vol_vol_two[0] = VOLATILITY * VOLATILITY * 2.;
182-
183-
double* quarter = (double*)dpnp_memory_alloc_c(1 * sizeof(double));
184-
quarter[0] = 0.25;
185-
186-
double* one = (double*)dpnp_memory_alloc_c(1 * sizeof(double));
187-
one[0] = 1.;
188-
189-
double* half = (double*)dpnp_memory_alloc_c(1 * sizeof(double));
190-
half[0] = 0.5;
191-
192231
double* call = (double*)dpnp_memory_alloc_c(SIZE * sizeof(double));
193232
double* put = (double*)dpnp_memory_alloc_c(SIZE * sizeof(double));
194-
double* mrs = (double*)dpnp_memory_alloc_c(SIZE * sizeof(double));
195-
double* vol_vol_twos = (double*)dpnp_memory_alloc_c(SIZE * sizeof(double));
196-
double* quarters = (double*)dpnp_memory_alloc_c(SIZE * sizeof(double));
197-
double* ones = (double*)dpnp_memory_alloc_c(SIZE * sizeof(double));
198-
double* halfs = (double*)dpnp_memory_alloc_c(SIZE * sizeof(double));
199-
200-
dpnp_full_c<double>(zero, call, SIZE); // np.full(SIZE, 0., dtype=DTYPE)
201-
dpnp_full_c<double>(mone, put, SIZE); // np.full(SIZE, -1., dtype=DTYPE)
202-
dpnp_full_c<double>(mr, mrs, SIZE); // np.full(SIZE, -RISK_FREE, dtype=DTYPE)
203-
dpnp_full_c<double>(vol_vol_two, vol_vol_twos, SIZE); // np.full(SIZE, VOLATILITY * VOLATILITY * 2., dtype=DTYPE)
204-
dpnp_full_c<double>(quarter, quarters, SIZE); // np.full(SIZE, 0.25, dtype=DTYPE)
205-
dpnp_full_c<double>(one, ones, SIZE); // np.full(SIZE, 1., dtype=DTYPE)
206-
dpnp_full_c<double>(half, halfs, SIZE); // np.full(SIZE, 0.5, dtype=DTYPE)
207233

208-
dpnp_memory_free_c(half);
209-
dpnp_memory_free_c(one);
210-
dpnp_memory_free_c(quarter);
211-
dpnp_memory_free_c(vol_vol_two);
212-
dpnp_memory_free_c(mr);
234+
dpnp_full_c<double>(zero, call, SIZE); // np.full(SIZE, 0., dtype=DTYPE)
235+
dpnp_full_c<double>(mone, put, SIZE); // np.full(SIZE, -1., dtype=DTYPE)
236+
213237
dpnp_memory_free_c(mone);
214238
dpnp_memory_free_c(zero);
215239

216-
black_scholes(price, strike, t, mrs, vol_vol_twos, quarters, ones, halfs, call, put, SIZE);
240+
black_scholes(price, strike, t, RISK_FREE, VOLATILITY, call, put, SIZE);
217241

218-
std::cout << std::endl;
242+
std::cout << "call: ";
219243
for (size_t i = 0; i < 10; ++i)
220244
{
221245
std::cout << call[i] << ", ";
222246
}
223-
std::cout << std::endl;
247+
std::cout << "..." << std::endl;
248+
std::cout << "put: ";
224249
for (size_t i = 0; i < 10; ++i)
225250
{
226251
std::cout << put[i] << ", ";
227252
}
228-
std::cout << std::endl;
253+
std::cout << "..." << std::endl;
229254

230-
dpnp_memory_free_c(halfs);
231-
dpnp_memory_free_c(ones);
232-
dpnp_memory_free_c(quarters);
233-
dpnp_memory_free_c(vol_vol_twos);
234-
dpnp_memory_free_c(mrs);
235255
dpnp_memory_free_c(put);
236256
dpnp_memory_free_c(call);
237257

examples/example_bs.py

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -55,27 +55,30 @@
5555
VOLATILITY = 0.2
5656

5757

58-
def black_scholes(price, strike, t, mrs, vol_vol_twos, quarters, ones, halfs, call, put):
58+
def black_scholes(price, strike, t, rate, vol, call, put):
59+
mr = -rate
60+
sig_sig_two = vol * vol * 2
61+
5962
P = price
6063
S = strike
6164
T = t
6265

6366
a = np.log(P / S)
64-
b = T * mrs
67+
b = T * mr
6568

66-
z = T * vol_vol_twos
67-
c = quarters * z
68-
y = ones / np.sqrt(z)
69+
z = T * sig_sig_two
70+
c = 0.25 * z
71+
y = 1./np.sqrt(z)
6972

7073
w1 = (a - b + c) * y
7174
w2 = (a - b - c) * y
7275

73-
d1 = halfs + halfs * np.erf(w1)
74-
d2 = halfs + halfs * np.erf(w2)
76+
d1 = 0.5 + 0.5 * np.erf(w1)
77+
d2 = 0.5 + 0.5 * np.erf(w2)
7578

7679
Se = np.exp(b) * S
7780

78-
r = P * d1 - Se * d2
81+
r = P * d1 - Se * d2
7982
call[:] = r # temporary `r` is necessary for faster `put` computation
8083
put[:] = r - P + Se
8184

@@ -85,18 +88,9 @@ def black_scholes(price, strike, t, mrs, vol_vol_twos, quarters, ones, halfs, ca
8588
strike = np.random.uniform(SL, SH, SIZE)
8689
t = np.random.uniform(TL, TH, SIZE)
8790

88-
call = np.full(SIZE, 0, dtype=DTYPE)
89-
put = np.full(SIZE, -1, dtype=DTYPE)
90-
91-
mrs = np.full(SIZE, -RISK_FREE, dtype=DTYPE)
92-
93-
vol = VOLATILITY
94-
vol_vol_twos = np.full(SIZE, vol * vol * 2, dtype=DTYPE)
95-
96-
quarters = np.full(SIZE, 0.25, dtype=DTYPE)
97-
ones = np.full(SIZE, 1, dtype=DTYPE)
98-
halfs = np.full(SIZE, 0.5, dtype=DTYPE)
91+
call = np.zeros(SIZE, dtype=DTYPE)
92+
put = -np.ones(SIZE, dtype=DTYPE)
9993

100-
black_scholes(price, strike, t, mrs, vol_vol_twos, quarters, ones, halfs, call, put)
94+
black_scholes(price, strike, t, RISK_FREE, VOLATILITY, call, put)
10195
print(call[:10])
10296
print(put[:10])

0 commit comments

Comments
 (0)