Using boolean matrix to govern While loop
2 次查看(过去 30 天)
显示 更早的评论
Hi there,
I'm working on a radiation transport MC in which I adjust two variables in incremental steps to produce a table of outputs. The following code does what I want it to:
for a = 1:5 % variable 1
for b = 1:5 % variable 2
for n = 1:10^5 % monte carlo
while x(a,b) < 10 % the tricky part!
x(a,b) = x(a,b) + rand * (a*2) * (b*.1);
end
end
end
end
handwave everything's initialized and the physics actually make sense.
So as I said, the above nested For loops work...but now I want to do all 25 combinations of variables at the same time using matrices. I hope to cut down on the number of random variables I generate, and also I just think it's a cooler way to do business. The problem is the "while" loop; each neutron "n" may scatter a different number of times before reaching arbitrary distance "10".
So, now I have something like:
a = meshgrid(1:5)*2;
b = meshgrid(6:10)*.1;
for n = 1:10^5
s = ones(5); % keep track of "live" combinations of variables
x = zeros(5); % distance traveled in each simulation
while sum(s(:)) ~= 0
x = x + s.* rand .* a .* b; % only if associated "s" is still 1
s = s .* (x<10); % if any simulations exceeded 10, kill them
end
end
Again, pretend that the physics make sense and that I'm storing useful data from the result of each "n". This code also works, but it's much slower than the nested for loops. I think that's because each time there are a bunch of "multiply by zero" calculations that are slowing me down.
So finally, my question! Does anyone know a way to not calculate the zeros? I sort of want to do like a "forEach s(:,:), while s(:,:)==true, calculate all x(:,:)'s together". Can anyone help me translate that into Matlab-speak?
Thanks very much,
Bryan
0 个评论
采纳的回答
Walter Roberson
2013-4-30
编辑:Walter Roberson
2013-4-30
numA = 5;
numB = 5;
[a, b] = ndgrid(1:numA, 1:numB);
a = a(:) .* 2;
b = b(:) .* 0.1;
ab = a .* b;
numAB = length(ab);
for n = 1 : 10^5
s = true(numAB, 1);
x = zeros(numAB, 1);
while any(s)
x(s) = x(s) + rand(nnz(s),1) .* ab(s);
s(s) = x(s) < 10;
end
end
x = reshape(x, numA, numB);
2 个评论
Walter Roberson
2013-4-30
Opps, fixed the any(s) typo.
Your original code used a different rand for each iteration, so that's what I used.
x(s) is using logical indexing; having them be the same size is typical.
更多回答(0 个)
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!