3

I am running a script which creates a lot of big arrays. Everything runs fine until the following lines:

%dist is a sparse matrix
inds=dist~=0;
inserts=exp(-dist(inds).^2/2*sig_dist);
dist(inds)=inserts;

The last line causes the error: ??? Maximum variable size allowed by the program is exceeded.

I don't understand how could the last line increase the variable size - notice I am inserting into the matrix dist only in places which were non-zero to begin with. So what's happening here?

2
  • 1
    Is sig_dist a scalar? Otherwise inserts probably isn't sparse. Commented Sep 6, 2011 at 16:52
  • @Richie Cotton - yes, of course, it's a scalar - it's the "sigma" term of the gaussian :) Commented Sep 7, 2011 at 9:53

3 Answers 3

1

I'm not sure why you are seeing that error. However, I suggest you use the Matlab function spfun to apply a function to the nonzero elements in a sparse matrix. For example:

>>dist = sprand(10000,20000,0.001);
>>f = @(x) exp(-x.^2/2*sig_dist);
>>dist = spfun(f,dist)
Sign up to request clarification or add additional context in comments.

1 Comment

nice, I forgot about about SPFUN.. In fact, its implemented as an M-file (not built-in), and if you check its source code, it's doing exactly the same thing I did: FIND followed by SPARSE :)
1

MATLAB implements a "lazy copy-on-write" model. Let me explain with an example.

First, create a really large vector

x = ones(5*1e7,1);

Now, say we wanted to create another vector of the same size:

y = ones(5*1e7,1);

On my machine, this will fail with the following error

??? Out of memory. Type HELP MEMORY for your options.

We know that y will require 5*1e7*8 = 400000000 bytes ~ 381.47 MB (which is also confirmed by which x), but if we check the amount of free contiguous-memory left:

>> memory
Maximum possible array:             242 MB (2.540e+008 bytes) *
Memory available for all arrays:    965 MB (1.012e+009 bytes) **
Memory used by MATLAB:              820 MB (8.596e+008 bytes)
Physical Memory (RAM):             3070 MB (3.219e+009 bytes)

*  Limited by contiguous virtual address space available.
** Limited by virtual address space available.

we can see that it exceeds the 242 MB available.

On the other hand, if you assign:

y = x;

it will succeed almost instantly. This is because MATLAB is not actually allocating another memory chunk of the same size as x, instead it creates a variable y that shares the same underlying data as x (in fact, if you call memory again, you will see almost no difference).

MATLAB will only try to make another copy of the data once one of the variables changes, thus if you try this rather innocent assignment statement:

y(1) = 99;

it will throw an error, complaining that it ran out of memory, which I suspect is what is happening in your case...


EDIT:

I was able to reproduce the problem with the following example:

%# a large enough sparse matrix (you may need to adjust the size)
dist = sparse(1:3000000,1:3000000,1);

First, lets check the memory status:

» whos
  Name            Size                    Bytes  Class     Attributes

  dist      3000000x3000000            48000004  double    sparse    

» memory
Maximum possible array:             394 MB (4.132e+008 bytes) *
Memory available for all arrays:   1468 MB (1.539e+009 bytes) **
Memory used by MATLAB:              328 MB (3.440e+008 bytes)
Physical Memory (RAM):             3070 MB (3.219e+009 bytes)

*  Limited by contiguous virtual address space available.
** Limited by virtual address space available.

say we want to apply a function to all non-zeros elements:

f = @(X) exp(-X.^2 ./ 2);

strange enough, if you try to slice/assign then it will fail:

» dist(dist~=0) = f( dist(dist~=0) );
??? Maximum variable size allowed by the program is exceeded.

However the following assignment does not throw an error:

[r,c,val] = find(dist);
dist = sparse(r, c, f(val));

I still don't have an explanation why the error is thrown in the first case, but maybe using the FIND function this way will solve your problem...

3 Comments

I was really hoping you were right, but when I tried doing dist(5)=7 (which should've created a local copy of the matrix), it went fine with no errors. So I guess that's not the reason.
It must be that you have very little free contiguous-memory left. In theory, we expect that indexing and assigning sparse matrices should work in-place, and does not involve making copies or converting to full matrices. Still, I think that such assignment requires "some" memory, and I guess you are at the point where MATLAB is unable to allocate what little memory it needs to complete the operation. Of course, these are all speculations on my part... My advice is to be aware of your functions memory footprint, and try to clear variables that are no longer needed as soon as possible.
I really don't know what to say. memory gives me: Maximum possible array: 491 MB (5.147e+008 bytes) * while the size of dist (the array I am dealing with) is ~3MB. So I don't understand what's going on...
0

In general, reassigning non-sparse elements does not change the memory footprint of the matrix. Call whos before and after assignment to check.

dist = sparse(10, 10);
dist(1,1) = 99;
dist(6,7) = exp(1);
inds = dist ~= 0;
whos
dist(inds) = 1;
whos

Without a reproducible example it is hard to determine the cause of the problem. It may be that some intermediate assignment is taking place that isn't sparse. Or you have something specific to your problem that we can't see here.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.