matlabsingle-precision

What is the application of single-precision format in the following MATLAB code?


I am imitating the following MATLAB code. actually, this code implement the eigenface method for face recognition.

%You are free to use, modify or distribute this code
loaded_Image=load_img();
random_Index=round(400*rand(1,1));          
random_Image=loaded_Image(:,random_Index);                         
rest_of_the_images=loaded_Image(:,[1:random_Index-1 random_Index+1:end]);         
image_Signature=20;                            
white_Image=uint8(ones(1,size(rest_of_the_images,2)));
mean_value=uint8(mean(rest_of_the_images,2));                
mean_Removed=rest_of_the_images-uint8(single(mean_value)*single(white_Image)); 
L=single(mean_Removed)'*single(mean_Removed);
[V,D]=eig(L);
V=single(mean_Removed)*V;
V=V(:,end:-1:end-(image_Signature-1));          
all_image_Signatire=zeros(size(rest_of_the_images,2),image_Signature);
for i=1:size(rest_of_the_images,2);
    all_image_Signatire(i,:)=single(mean_Removed(:,i))'*V;  
end
subplot(121);
imshow(reshape(random_Image,112,92));
title('Looking for this Face','FontWeight','bold','Fontsize',16,'color','red');
subplot(122);
p=random_Image-mean_value;
s=single(p)'*V;
z=[];
for i=1:size(rest_of_the_images,2)
    z=[z,norm(all_image_Signatire(i,:)-s,2)];
    if(rem(i,20)==0),imshow(reshape(rest_of_the_images(:,i),112,92)),end;
    drawnow;
end
[a,i]=min(z);
subplot(122);
imshow(reshape(rest_of_the_images(:,i),112,92));
title('Recognition Completed','FontWeight','bold','Fontsize',16,'color','red');

Do you know why it uses single-precision format? what is the applications of this format? as far as I know, the the difference between single-precision format and double-precision format is the number of bits used for exponential, mantissa and etc.


Solution

  • The loaded_Image, rest_of_the_images, random_Image, etc. are all stored as type uint8 for saving space because pixel values range from [0 0 0] (black) to [255 255 255] (white) and 8-bits are sufficient for that (0:255). But some mathematical operations are not supported for integer classes. For example, if I try to multiply two uint8 matrices I get this error:

    >> uint8(ones(5)) * uint8(ones(5))
    Error using  * 
    MTIMES (*) is not fully supported for integer classes. 
    At least one argument must be scalar.
    

    Same for eig:

    >> eig(uint8(ones(5)))
    Error using eig
    Invalid data type. Input matrix must be double or single.
    

    So, one has to convert to a supported datatype before the operation and re-convert back to uint8 when storing the image. The author chose single because it saves 50% of memory compared to double, but the speed difference will be negligible on modern architectures.

    The authors makes unnecessary conversions, though. For example, the following line could be written without any conversions:

    mean_Removed = rest_of_the_images - uint8(single(mean_value)*single(white_Image))
    % could be written
    mean_Removed = rest_of_the_images - mean_value
    

    Other places where single would be the right choice is when dealing with specific architectures like GPUs, because GPUs fully support single datatypes but not doubles yet.