1

I am developing a program to read a time series of NIfTY format images to a 4D matrix in MATLAB. There are about 60 images in the stack and the program runs without problems until the 28th image. (All the images are approximately same size, same details) But after that the reading get slower and slower.

In fact, the delay is accumulating. I checked the program again and there are no open files. Everything looks fine.

Can someone give me an advice?

user3566905
  • 113
  • 1
  • 6
  • how exactly are you constructing the 4D matrix? is it possible you did not pre-allocated memory? can you show us your code (the relevant parts of it)? – Shai Jul 29 '14 at 11:50

1 Answers1

2

Size of current array (double)

Unless you are running on a machine with more than ~20GB RAM memory your matrix simply becomes too large to handle.

To check the size of the first three dimensions of your matrix:

A = rand(512,512,160);
whos('A')

Output:

Name        Size                     Bytes      Class     Attributes

A           512x512x160              335544320  double       

Now multiply by 60 to obtain the size of your 4D matrix and divide by 1024^3 to obtain GB's:

335544320*60/1024^3 = 18.7500 GB

So yes, your matrix is most likely too large to handle efficiently/effectively.

A matrix exceeding your RAM memory forces MatLab to use the swap file (HDD/SSD) which is orders of magnitude slower than your random access memory (even if you have a SSD).

Switch to different data types

I you do not require double precision, i.e. 16 digits of accuracy, you can always switch to less digits, i.e. single precision floating point numbers. By doing this you can reduce size. You can even reduce size further is the numbers are for example unsigned integers in the range of 0-255. See code below:

% Create doubles
A_double = rand(512,512,160);
S1=whos('A_double');


% Create floats
A_float = single(A_double);
S2=whos('A_float');


% Create unsigned int range 0-255
A_uint=uint8(randi(256,[512,512,160])-1);
S3=whos('A_uint');

fprintf('Size A_double is %4.2f GB\n',(S1.bytes*60)/1024^3)
fprintf('Size A_float is %4.2f GB\n',(S2.bytes*60)/1024^3)
fprintf('Size A_uint is %4.2f GB\n',(S3.bytes*60)/1024^3)

Output:

Size A_double is 18.75 GB
Size A_float is 9.38 GB
Size A_uint is 2.34 GB

Which may just fit inside your RAM. Make sure you indeed pre-allocate memory first, i.e. create an empty matrix using the zeros() function.

EJG89
  • 1,189
  • 7
  • 17