Octave: how can these vector vectors be vectorized?

I am writing an Octave script to calculate the price of a European version.

In the first part, Monte Carlo is used to model the price of the underlying asset for n number of time periods. This is repeated several times.

Octave makes it easy to set up source matrices. But I did not find a way to complete the task in vector form, avoiding FOR loops:

%% Octave simplifies creation of 'e', 'dlns', and 'Prices' e = norminv(rand(nIter,n)); dlns = cat(2, ones(nIter,1), exp((adj_r+0.5*sigma^2)*dt+sigma*e.*sqrt(dt))); Prices = zeros(nIter, n+1); for i = 1:nIter % IS THERE A WAY TO VECTORIZE THESE FOR LOOPS? for j = 1:n+1 if j == 1 Prices(i,j)=S0; else Prices(i,j)=Prices(i,j-1)*dlns(i,j); end endfor endfor 

Please note that the price of n is equal to the price of n-1 times the factor, so the following does not work ...

 Prices(i,:) = S0 * dlns(i,:) 

... since he takes S0 and multiplies it by all factors, which gives different results than the expected random walk.

+5
source share
1 answer

Due to the relationship between iterations, to get the results for each new column relative to the previous column, it seems you will need at least one loop, but all the operations inside the column will be vectorized and that can speed it up for you. A vector replacement for two nested loops will look something like this:

 Prices(:,1)=S0; for j = 2:n+1 Prices(:,j) = Prices(:,j-1).*dlns(:,j); endfor 

It just occurred to me that the dependency can be solved with cumprod , which gets us a cumulative product , which essentially runs here and, therefore, will lead to creation without a loop! Here's the implementation -

 Prices = [repmat(S0,nIter,1) cumprod(dlns(:,2:end),2)*S0] 

Benchmarking on MATLAB

Benchmarking Code -

 %// Parameters as told by OP and then create the inputs nIter= 100000; n = 100; adj_r = 0.03; sigma = 0.2; dt = 1/n; S0 = 60; e = norminv(rand(nIter,n)); dlns = cat(2, ones(nIter,1), exp((adj_r+0.5*sigma^2)*dt+sigma*e.*sqrt(dt))); disp('-------------------------------------- With Original Approach') tic Prices = zeros(nIter, n+1); for i = 1:nIter for j = 1:n+1 if j == 1 Prices(i,j)=S0; else Prices(i,j)=Prices(i,j-1)*dlns(i,j); end end end toc, clear Prices disp('-------------------------------------- With Proposed Approach - I') tic Prices2(nIter, n+1)=0; %// faster pre-allocation scheme Prices2(:,1)=S0; for j = 2:n+1 Prices2(:,j)=Prices2(:,j-1).*dlns(:,j); end toc, clear Prices2 disp('-------------------------------------- With Proposed Approach - II') tic Prices3 = [repmat(S0,nIter,1) cumprod(dlns(:,2:end),2)*S0]; toc, clear Prices3 

Runtimes Results -

 -------------------------------------- With Original Approach Elapsed time is 0.259054 seconds. -------------------------------------- With Proposed Approach - I Elapsed time is 0.020566 seconds. -------------------------------------- With Proposed Approach - II Elapsed time is 0.067292 seconds. 

Now the runtime suggests that the first approach proposed may be better suited here!

+6
source

Source: https://habr.com/ru/post/1214446/


All Articles