Why is Matlab crashing during this program?
11 views (last 30 days)
Show older comments
For the attached .m files below, when I run sandpiles.m, Matlab is asked to do an intensive computation. It very reliably fails to complete the requested computation by crashing: the entire UI and program act as if I quit the program. No error message appears. What specifically is crashing my code? I am using MATLAB 2017b
1 Comment
Arvind Sathyanarayanan
on 15 Mar 2019
Edited: Arvind Sathyanarayanan
on 15 Mar 2019
Try using the debug mode to see where exactly MATLAB gets stuck.
Also, its good practice to avoid clear all as it clears all the functions are removed from the RAM and ends up decreasing your code's performance.
EDIT: I ran your code in debug mode and it looks like you're caught in an infinite loop when you call topple at line 47, the cluprit seems to be this piece of code in topple.m:
if any(sum(A1>crit))
A1 = topple(A1,crit);
else
return
end
You might need to rethink your program's logic.
Accepted Answer
Guillaume
on 15 Mar 2019
Matlab actually crashing (i.e. the application terminates) should not happen. Perhaps you run out of memory?
Matlab actually stopping running your with an error message is more likely. In this case, give us the full text of the error message, everything that is in red.
As far as I can tell, your neighbors.m is simply a convolution. A few notes on your code:
num_r = length(A(:, 1));
num_c = length(A(, 1:));
is simply
num_r = size(A, 1); %no need to extract a column to get the height of A
num_c = size(A, 2); %no need to extract a row to get the width of A
In any case,
N = zeros(num_r,num_c);
is simply:
N = zeros(size(A));
Now, if you have a bunch of
if somecondition
...
elseif someothercondition
...
elseif yetanothercondition
...
elseif
...
end
you should always finish on an else, not an elsif. Particularly, as your last condition is guaranteed to be true if all previous elsif have failed.
Also, if makes sense to test for the most common condition first (i.e. the centre of the matrix) rather than last. The first condition you're testing is one that will be true for just one element.
In any case, as far as I can tell, your function is just:
function N = neighbors(A, crit)
N = zeros(size(A));
N(A > crit) = A(A > crit);
N = conv2(floor(N / 4), [0 1 0; 1 0 1; 0 1 0], 'same');
end
Similarly, in your topple.m function, it looks like your
A1 = A;
[row,col] = find(A>crit);
for i = 1:length(row)
n = floor(A(row(i),col(i))/4); % # toppled grains to neighbors
A1(row(i),col(i)) = A(row(i),col(i)) - 4*n;
end
is simply:
A1 = A;
A1(A > crit) = mod(A1(A > crit), 4);
You need to learn to work on whole matrices rather than using overcomplicated loops.
Also,
if any(sum(A1 > crit))
would be clearer as
if any(any(A1 > crit))
or even better
if nnz(A1 > crit)
Your function recurse n itself until you've toppled all your grains. There is no need for a recursion here, you could simply use a while loop. recursion is expensive since calling a function is expensive. Matlab imposes a limit on the number of recursions but you can increase that. However if you do that, it can make your system unstable. Perhaps, that's why you crash.
function A = topple(A, crit);
while nnz(A > crit) %much more fficient than a recursion
N = neighbors(A, crit);
A(A > crit) = mod(A(A > crit), 4);
A = A + N;
end
end
0 Comments
More Answers (0)
See Also
Categories
Find more on Logical in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!