Skip to content

Commit d594d79

Browse files
Pass rng as explicit argument in monte_carlo.md functions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 80128a3 commit d594d79

1 file changed

Lines changed: 34 additions & 17 deletions

File tree

lectures/monte_carlo.md

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,9 @@ S / n
181181
We can also construct a function that contains these operations:
182182

183183
```{code-cell} ipython3
184-
def compute_mean(n=1_000_000):
184+
def compute_mean(n=1_000_000, rng=None):
185+
if rng is None:
186+
rng = np.random.default_rng()
185187
S = 0.0
186188
for i in range(n):
187189
X_1 = np.exp(μ_1 + σ_1 * rng.standard_normal())
@@ -196,7 +198,7 @@ def compute_mean(n=1_000_000):
196198
Now let's call it.
197199

198200
```{code-cell} ipython3
199-
compute_mean()
201+
compute_mean(rng=rng)
200202
```
201203

202204

@@ -210,7 +212,9 @@ But the code above runs quite slowly.
210212
To make it faster, let's implement a vectorized routine using NumPy.
211213

212214
```{code-cell} ipython3
213-
def compute_mean_vectorized(n=1_000_000):
215+
def compute_mean_vectorized(n=1_000_000, rng=None):
216+
if rng is None:
217+
rng = np.random.default_rng()
214218
X_1 = np.exp(μ_1 + σ_1 * rng.standard_normal(n))
215219
X_2 = np.exp(μ_2 + σ_2 * rng.standard_normal(n))
216220
X_3 = np.exp(μ_3 + σ_3 * rng.standard_normal(n))
@@ -221,7 +225,7 @@ def compute_mean_vectorized(n=1_000_000):
221225
```{code-cell} ipython3
222226
%%time
223227
224-
compute_mean_vectorized()
228+
compute_mean_vectorized(rng=rng)
225229
```
226230

227231

@@ -233,7 +237,7 @@ We can increase $n$ to get more accuracy and still have reasonable speed:
233237
```{code-cell} ipython3
234238
%%time
235239
236-
compute_mean_vectorized(n=10_000_000)
240+
compute_mean_vectorized(n=10_000_000, rng=rng)
237241
```
238242

239243

@@ -515,7 +519,9 @@ $$ s_{t+1} = s_t + \mu + \exp(h_t) \xi_{t+1} $$
515519
Here is a function to simulate a path using this equation:
516520

517521
```{code-cell} ipython3
518-
def simulate_asset_price_path(μ=default_μ, S0=default_S0, h0=default_h0, n=default_n, ρ=default_ρ, ν=default_ν):
522+
def simulate_asset_price_path(μ=default_μ, S0=default_S0, h0=default_h0, n=default_n, ρ=default_ρ, ν=default_ν, rng=None):
523+
if rng is None:
524+
rng = np.random.default_rng()
519525
s = np.empty(n+1)
520526
s[0] = np.log(S0)
521527
@@ -538,7 +544,7 @@ titles = 'log paths', 'paths'
538544
transforms = np.log, lambda x: x
539545
for ax, transform, title in zip(axes, transforms, titles):
540546
for i in range(50):
541-
path = simulate_asset_price_path()
547+
path = simulate_asset_price_path(rng=rng)
542548
ax.plot(transform(path))
543549
ax.set_title(title)
544550
@@ -576,7 +582,10 @@ def compute_call_price(β=default_β,
576582
n=default_n,
577583
ρ=default_ρ,
578584
ν=default_ν,
579-
M=10_000):
585+
M=10_000,
586+
rng=None):
587+
if rng is None:
588+
rng = np.random.default_rng()
580589
current_sum = 0.0
581590
# For each sample path
582591
for m in range(M):
@@ -594,7 +603,7 @@ def compute_call_price(β=default_β,
594603

595604
```{code-cell} ipython3
596605
%%time
597-
compute_call_price()
606+
compute_call_price(rng=rng)
598607
```
599608

600609

@@ -625,8 +634,10 @@ def compute_call_price_vector(β=default_β,
625634
n=default_n,
626635
ρ=default_ρ,
627636
ν=default_ν,
628-
M=10_000):
629-
637+
M=10_000,
638+
rng=None):
639+
if rng is None:
640+
rng = np.random.default_rng()
630641
s = np.full(M, np.log(S0))
631642
h = np.full(M, h0)
632643
for t in range(n):
@@ -640,7 +651,7 @@ def compute_call_price_vector(β=default_β,
640651

641652
```{code-cell} ipython3
642653
%%time
643-
compute_call_price_vector()
654+
compute_call_price_vector(rng=rng)
644655
```
645656

646657

@@ -651,7 +662,7 @@ Now let's try with larger $M$ to get a more accurate calculation.
651662

652663
```{code-cell} ipython3
653664
%%time
654-
compute_call_price(M=10_000_000)
665+
compute_call_price(M=10_000_000, rng=rng)
655666
```
656667

657668

@@ -697,7 +708,10 @@ def compute_call_price_with_barrier(β=default_β,
697708
ρ=default_ρ,
698709
ν=default_ν,
699710
bp=default_bp,
700-
M=50_000):
711+
M=50_000,
712+
rng=None):
713+
if rng is None:
714+
rng = np.random.default_rng()
701715
current_sum = 0.0
702716
# For each sample path
703717
for m in range(M):
@@ -723,7 +737,7 @@ def compute_call_price_with_barrier(β=default_β,
723737
```
724738

725739
```{code-cell} ipython3
726-
%time compute_call_price_with_barrier()
740+
%time compute_call_price_with_barrier(rng=rng)
727741
```
728742

729743

@@ -740,7 +754,10 @@ def compute_call_price_with_barrier_vector(β=default_β,
740754
ρ=default_ρ,
741755
ν=default_ν,
742756
bp=default_bp,
743-
M=50_000):
757+
M=50_000,
758+
rng=None):
759+
if rng is None:
760+
rng = np.random.default_rng()
744761
s = np.full(M, np.log(S0))
745762
h = np.full(M, h0)
746763
option_is_null = np.full(M, False)
@@ -758,7 +775,7 @@ def compute_call_price_with_barrier_vector(β=default_β,
758775
```
759776

760777
```{code-cell} ipython3
761-
%time compute_call_price_with_barrier_vector()
778+
%time compute_call_price_with_barrier_vector(rng=rng)
762779
```
763780

764781
```{solution-end}

0 commit comments

Comments
 (0)