将matlab稀疏矩阵转换为单精度
Converting matlab sparse matrix to single precision
我想将 matlab 中的稀疏矩阵转换为单精度矩阵,但是 matlab 似乎没有实现单精度矩阵。
相反,我只是计划检查它的值是否超出单精度范围,并将它们四舍五入为单精度范围的最高值和最低值。
我想做这样的事情:
for i = 1:rows
for j = 1:cols
if (abs(A(i,j) < 2^-126))
A(i,j) == 0;
end
end
end
但是,这非常慢。有没有我可以使用的另一个命令,它可以在 MATLAB 中的稀疏矩阵 class 类型上工作?我注意到大多数命令不适用于稀疏数据类型。
编辑 1:
我也尝试了以下方法,但如您所见,我 运行 内存不足(矩阵是稀疏的,大小为 200K x 200K,有约 300 万个非零值):
A(A < 2^-126) = 0
Error using <
Out of memory. Type HELP MEMORY for your options.
编辑 2:
我根据@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'));
您可以找到非零元素的索引并使用它来更改矩阵;
idx = find(A);
Anz = A(idx);
idx = idx(Anz < 2^-126);
A(idx) = 0;
或更紧凑:
idx = find(A);
A(idx(A(idx) < 2^-126)) = 0;
然而,如果你想从双精度转换为单精度,你可以使用 single
函数:
idx = find(A);
A(idx) = double(single(full(A(idx))));
或
A(find(A)) = double(single(nonzeros(A)));
要将 Inf
转换为 realmax
,您可以这样写:
A(find(A)) = double(max(-realmax('single'),min(realmax('single'),single(nonzeros(A)))));
如果您只想将 Inf 转换为 realmax,您可以这样做:
Anz = nonzeros(A);
AInf = isinf(A);
Anz(AInf) = double(realmax('single')) * sign(Anz(AInf));
A(find(A)) = Anz;
当有人对如何将稀疏转换为单一感兴趣时仍然会看到此线程:一个简单的答案是使用 full()
。但是,如果您依赖稀疏为您节省的内存,这可能会有问题,因为它基本上首先转换为双倍。
sparseMatrix = sparse(ones(2, 'double'));
single(full(sparseMatrix)) % works
% ans =
% 2×2 single matrix
% 1 1
% 1 1
single(sparseMatrix) % doesn't work
% Error using single
% Attempt to convert to unimplemented sparse type
我想将 matlab 中的稀疏矩阵转换为单精度矩阵,但是 matlab 似乎没有实现单精度矩阵。
相反,我只是计划检查它的值是否超出单精度范围,并将它们四舍五入为单精度范围的最高值和最低值。
我想做这样的事情:
for i = 1:rows
for j = 1:cols
if (abs(A(i,j) < 2^-126))
A(i,j) == 0;
end
end
end
但是,这非常慢。有没有我可以使用的另一个命令,它可以在 MATLAB 中的稀疏矩阵 class 类型上工作?我注意到大多数命令不适用于稀疏数据类型。
编辑 1:
我也尝试了以下方法,但如您所见,我 运行 内存不足(矩阵是稀疏的,大小为 200K x 200K,有约 300 万个非零值):
A(A < 2^-126) = 0
Error using <
Out of memory. Type HELP MEMORY for your options.
编辑 2:
我根据@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'));
您可以找到非零元素的索引并使用它来更改矩阵;
idx = find(A);
Anz = A(idx);
idx = idx(Anz < 2^-126);
A(idx) = 0;
或更紧凑:
idx = find(A);
A(idx(A(idx) < 2^-126)) = 0;
然而,如果你想从双精度转换为单精度,你可以使用 single
函数:
idx = find(A);
A(idx) = double(single(full(A(idx))));
或
A(find(A)) = double(single(nonzeros(A)));
要将 Inf
转换为 realmax
,您可以这样写:
A(find(A)) = double(max(-realmax('single'),min(realmax('single'),single(nonzeros(A)))));
如果您只想将 Inf 转换为 realmax,您可以这样做:
Anz = nonzeros(A);
AInf = isinf(A);
Anz(AInf) = double(realmax('single')) * sign(Anz(AInf));
A(find(A)) = Anz;
当有人对如何将稀疏转换为单一感兴趣时仍然会看到此线程:一个简单的答案是使用 full()
。但是,如果您依赖稀疏为您节省的内存,这可能会有问题,因为它基本上首先转换为双倍。
sparseMatrix = sparse(ones(2, 'double'));
single(full(sparseMatrix)) % works
% ans =
% 2×2 single matrix
% 1 1
% 1 1
single(sparseMatrix) % doesn't work
% Error using single
% Attempt to convert to unimplemented sparse type