如何用矩阵乘法替代依赖前序列的递推for循环?
Hey there! I get why you're stuck—this recursive step feels like it has to be a loop at first glance, but we can absolutely refactor it using matrix operations by leaning into cumulative products. Let's walk through this.
First, let's recap what your original code does
Your loop generates paths for a geometric Brownian motion (GBM) process, where each step depends on the previous value:
S= zeros(Sim,n+1); S(:,1)=S_0; for i=1:round(n) S(:,i+1) = S(:,i) .* cte_exp .* exp(sigma.*sqrt(dt).*normrnd(0,1,Sim,1)); end
Every iteration multiplies the current value by cte_exp and a random exponential term. This is equivalent to multiplying the initial value by the product of all those step-wise factors.
The Matrix-Based Solution
Here's how to replace the loop with vectorized operations:
Generate all random perturbations at once
Instead of generating one column of random numbers per loop iteration, create an entireSim×nmatrix of normal random values upfront:Z = normrnd(0, 1, Sim, n);Compute the multiplicative factor for each step
Calculate the full matrix of step-wise growth factors (combining the deterministiccte_expterm and the random exponential):step_factors = cte_exp * exp(sigma * sqrt(dt) * Z);Compute cumulative products across steps
To replicate the recursive multiplication, we need the product of factors up to each step. Add a column of1s (for the initial state, where no multiplication has happened yet) and usecumprodto compute row-wise cumulative products:cumulative_factors = cumprod([ones(Sim, 1), step_factors], 2);The
2incumprodtells Matlab to compute the product along columns (i.e., step-by-step for each simulation path).Calculate the full S matrix
Multiply the initial valueS_0by the cumulative factors to get all paths in one go:S = S_0 .* cumulative_factors;
Why This Works
Each row of cumulative_factors represents the product of all step factors up to that point. For example:
cumulative_factors(:,1)is1→ matchesS(:,1) = S_0cumulative_factors(:,2)isstep_factors(:,1)→ matchesS(:,2) = S_0 * step_factors(:,1)cumulative_factors(:,3)isstep_factors(:,1)*step_factors(:,2)→ matchesS(:,3) = S(:,2)*step_factors(:,2) = S_0*step_factors(:,1)*step_factors(:,2)
This exactly replicates your original loop's behavior, but with vectorized operations that are often faster in Matlab, especially for large Sim or n.
内容的提问来源于stack exchange,提问作者user9609639

