2
votes

I want to convert a sparse matrix in matlab to single precision, however it appears that matlab doesn't have single sparse implemented.

Instead of that, I am just planning on checking it the values are outside of the single precision range and rounding them off to the highest and lowest values of the single precision range.

I'd like to do something like this:

for i = 1:rows
    for j = 1:cols
        if (abs(A(i,j) < 2^-126))
            A(i,j) == 0;
        end
    end
end

However, ths is extremely slow. Is there another command I can use that will work on sparse matrix class type in MATLAB? I notice most commands don't work for the sparse data type.

EDIT 1:

I also tried the following, but as you can see I run out of memory (the matrix is sparse and is 200K x 200K with ~3 million nonzeros):

A(A < 2^-126) = 0
Error using  < 
Out of memory. Type HELP MEMORY for your options.

EDIT 2:

Current solution I developed based on input from @rahnema1:

% Convert entries that aren't in single precision
idx = find(A); % find locations of nonzeros
idx2 = find(abs(A(idx)) < double(realmin('single')));
A(idx(idx2)) = sign(A(idx(idx2)))*double(realmin('single'));
idx3 = find(abs(Problem.A(idx)) > double(realmax('single')));
A(idx(idx3)) = sign(A(idx(idx3)))*double(realmax('single'));
1

1 Answers

1
votes

You can find indices of non zero elements and use that to change the matrix;

idx = find(A);
Anz = A(idx);
idx = idx(Anz < 2^-126);
A(idx) = 0;

Or more compact:

idx = find(A);
A(idx(A(idx) < 2^-126)) = 0;

However if you want to convert from double to single you can use single function:

idx = find(A); 
A(idx) = double(single(full(A(idx))));

or

A(find(A)) = double(single(nonzeros(A)));

To convert Inf to realmax you can write:

A(find(A)) = double(max(-realmax('single'),min(realmax('single'),single(nonzeros(A)))));

If you only want to convert Inf to realmax you can do:

Anz = nonzeros(A);
AInf = isinf(A);
Anz(AInf) = double(realmax('single')) * sign(Anz(AInf));
A(find(A)) = Anz;