Vectorisation of for loops

Being fairly new to Matlab and the concept of vectorisation rather than iteration I need some help getting my head around avoiding for loops.
I'd like to use arrayfun but don't know how to implement it with changing parameter dimensions.
Nested for loop
for k = 1:Sims
for i = 1:Days
Hist = sum(Weights(1:i,1) .* FF(1:i,k));
Deltas(i,k) = Delta(FF(i,k), Hist, v(i:end), 60.64633, Weights(i:Days), 2500, Days-i);
end
end
Notice that v and Weights dimensions decreases as i increases, and the last parameter passed to Delta (Days) is decreased in size by i.
Any thoughts, can it even be done?

3 comentarios

Matt Fig
Matt Fig el 11 de Sept. de 2012
Editada: Matt Fig el 11 de Sept. de 2012
w and Weights do not change sizes in the loop. What is Sims and Days? And what is Delta?
Whether it is worthwhile to vectorize this will depend on these two values and what Delta is.
Alex Gregory
Alex Gregory el 11 de Sept. de 2012
Delta approximates the value of Delta for an Asian option. It does this for i=1 to Days=(3*365) over k=1 to Sims=1000.
As i increases 1 day less of volatility and daily weightings are needed for the calculation as there are Days-i days remaining until the option expires.
Jan
Jan el 11 de Sept. de 2012
@Alex: A cute answer. The meaning of the values is not important, only the type and size or if it is an array or a function. :-)

Iniciar sesión para comentar.

Respuestas (2)

Sean de Wolski
Sean de Wolski el 11 de Sept. de 2012

1 voto

arrayfun is slow and difficult to use/read. It has really no advantages. I do not know why you would want to use it over the for-loops. If you preallocate Deltas that will help with speed. Using arrayfun will hurt and make your code harder to understand.
Before the loop:
Deltas = zeros(Sims,Days)
Jan
Jan el 11 de Sept. de 2012
Editada: Jan el 11 de Sept. de 2012

1 voto

At least calculating the sum repeatedly can be avoided:
Deltas = zeros(Days, Sims);
for k = 1:Sims
Hist = cumsum(Weights(:, 1) .* FF(:, k));
for ii = 1:Days
Deltas(ii,k) = Delta(FF(i,k), Hist(ii), v(ii:end), 60.64633, Weights(ii:Days), 2500, Days-ii);
end
end
If you post the code of "Delta" further improvements are possible.

3 comentarios

Alex Gregory
Alex Gregory el 12 de Sept. de 2012
Editada: Alex Gregory el 12 de Sept. de 2012
function [ Delta ] = Delta( UnderlyingPrice, Hist, Vols, k, weights, sims, days)
l = size(Vols,1);
er = exp(-0.01*days/365);
b = 0.001;
t = 1/365;
FFa = repmat(-0.5.*Vols.^2.*t,1,sims);
Rands = randn(l,sims);
FFb = repmat(Vols.*sqrt(t),1,sims) .* Rands;
FF = exp(FFa+FFb);
UL = repmat(UnderlyingPrice,l,sims);
ULB = repmat(UnderlyingPrice+b,l,sims);
W = repmat(weights,1,sims);
FFCP = cumprod(FF);
FCNB = FFCP .* UL .* W;
FCNB = sum(FCNB) + Hist;
FCNBPo = max(0,FCNB-k)*er;
FCB = FFCP .* ULB .* W;
FCB = sum(FCB) + Hist;
FCBPo = max(0,FCB-k)*er;
FF = exp(FFa-FFb);
FFCP = cumprod(FF);
FCatNB = FFCP .* UL .* W;
FCatNB = sum(FCatNB) + Hist;
FCatNBPo = max(0,FCatNB-k)*er;
FCatB = FFCP .* ULB .* W;
FCatB = sum(FCatB) + Hist;
FCatBPo = max(0,FCatB-k)*er;
Delta = mean(((FCBPo-FCNBPo) ./ b + (FCatBPo-FCatNBPo) ./ b) ./ 2);
end
Jan
Jan el 12 de Sept. de 2012
Obviously the main part of the program happens inside the function Delta(). Then the outer loop is most likely negligible.
If you provide some sample data, e.g. created by RAND(), such that we can tun your program, it would be easier to test modifications. I assume the REPMAT waste a lot of time here and some BSXFUN would be remarkably faster.
Sean de Wolski
Sean de Wolski el 12 de Sept. de 2012
That would be my first recommendation: replace every repmat with the corresponding bsxfun.

Iniciar sesión para comentar.

Categorías

Más información sobre Creating and Concatenating Matrices en Centro de ayuda y File Exchange.

Preguntada:

el 11 de Sept. de 2012

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by