是的sparse本身不支持单精度
你可以转化为double再用sparse
如果还要用single类型进一步节省空间
还是有办法的
实际上sparse稀疏矩阵,能够节省存储空间的原因是
避免存储矩阵中大量的0元素
而sparse实际上是寻找矩阵的非零元素,记录它们的下标值和数值
如果是single的矩阵,使用不了sparse,我们可以用find得到类似的结果
假如原来的矩阵是a,a中有很多0元素,我们想压缩存储,首先利用
[r c v]=find(a)
就可以得到每个非零元素的行下标r,列下标c ,数值v
例如:
a=[ 0 1 0 ; 0 0 2];
如果我们用sparse存成稀疏矩阵,那么
>> sparse(a)
ans =
(1,2) 1
(2,3) 2
如果我们用find函数求得非零元素的下标和值
>> [r c v]=find(a);
>> [r c v]
ans =
1 2 1
2 3 2
可见sparse矩阵的显示结果中第n行的数据 实际上就是 (r(n),c(n)) v(n)
但是要存储行列两个坐标,还是数据太多,我们只需要
[r c v]=find(a(:))
这时候数据就会以先行后列的顺序排成一个一维的数组
我们只要一个坐标r就可以记录其元素所在的位置
以上面的例子为例
>> [r c v]=find(a(:));
>> [r v]
ans =
3 1
6 2
原来(1,2)位置的元素相当于第3个,(2,3) 位置的元素相当于第6个
这时候c全部是1,不需要记录,我们只需要记录r和v就可以了
这样又可以节省一半的存储下标的空间
这个时候v的数据类型是根据原来a的数据类型来定的
如果原来的a是single型的,v就是single型的
但是r是double型的占8位,也是比较占空间的,但是下标一定是正整数
我们可以使用uint8,uint16,uint32,uint64来转换为无符号整数
根据你矩阵的大小可以选择不同位数的整数类型储存下标
uint8只占1个字节但是最多只能到255,显然不能够满足要求
uint16占2个字节大表示整数65535,
uint32占4个字节最大表示整数4,294,967,295,
可以表示6万多行x6万多列的矩阵,应该能满足要求吧
最后如果你有一个很大的single矩阵a,只有少量非零元素,想压缩储存
那么
[m n]=size(a);
[r c v]=find(a(:));
r=unit32(r);
你只需要储存 m n r v 这四个量就可以储存矩阵a的全部信息
其中m n是double型,无论矩阵多大,就两个数占16字节
而r是uint32,v是single,元素个数由矩阵中非零元素的个数决定
假如原来a矩阵大小为mxn,其中有num个非零元素
全部存取矩阵需要 m*n*4个字节的空间
而用上述办法需要 num*8+16个字节的空间
可见当非零个数达到总元素个数的一半或以上时,
存储空间非但没有减少还会增加,所以非零元素所占的比例决定了储存效率
对于sparse生成的系数矩阵,我们可以用full得到完整的矩阵
而我们用上述办法得到的 m n r v,想恢复为完整的矩阵也不会太复杂
b=zeros(m,n,class(v));
b(r)=v;
这样就可以恢复矩阵b,矩阵b和矩阵a应该是一样的
它是一种使用命令集合的形式表示的过程式编程语言,这些命令集合需要像批处理文件一样顺序执行。