假如说有一个矩阵A = 1, 3, 0, 0
0, 1, 0, 0
0, 0, 3, 0
0, 0, 5, 1
共6个有效点。
通常存储稀疏矩阵用三元组,比如c语言,
//为了方便跟后面matlab的对比,下标从1开始
int r[6] = [1, 1, 2, 3, 4, 4];//row index
int v[6] = [1, 2, 1, 3, 5, 1];//value of element
int c[6] = [1, 2, 2, 3, 3, 4];//column index
那么所需要的存储空间是,4 * 6 + 4 * 6 + 8 * 6 = 96 bytes
而在matlab中,存储的是三个矩阵(当然啦,实际上是一片连续的空间)
第1个矩阵r存各个元素的row index,
第2个矩阵v存各个元素的value,这两部分跟上面c语言的一样
第3个矩阵h存各列的头指针(指向第2个矩阵中的各列)+ 1个标志矩阵结束的 flag 指针
(实际上这个flag指针的位置跟在v数组之后,注意是这个指针本身,不是它的内容,它的内容应该是一个定值)
那么所需空间就是4 * (4 + 1) + 4 * 6 + 8 * 6 = 92 bytes
访问
不同就不同在这第3个矩阵上,接下来我们只讨论这第3个矩阵
c中存储下标用int,占4个字节,matlab存的是指针,也是占4个字节
假如一个稀疏矩阵的真实size为m*n,有效元素有k个
那么c中的方式的内存花费是4*k
matlab中为4 * (n+1)
当k = n + 1时花费相同。但是实际应用中k一般是大于n的,matlab的方式实践效果更好。
访问方式如下:
如A(4, 3),
由于是第3列,先通过访问column pointer数组的第3个元素h(3),得到了一个指向第3列元素的头指针
也就是定位到v数组v(4) = 3处
那么在此指针之后,还有多个值,哪个才是第4行的呢?
从此处开始遍历v数组,若r(i)等于要寻找的目标行号,就返回v(i);
若指针指向了结束标志位,就说明没有存这个元素,返回0
matlab里矩阵操作相关函数,SP表稀疏矩阵,A表完全矩阵
A = sparse(r, c, v, m, n),其中rcv均为列向量,涵义就是上方三元组的涵义,mn为系数矩阵的真实size
[r, c, v] = find(SP),抽取稀疏矩阵的数据为三元组
SP = sparse(B),直接用完全矩阵构造稀疏矩阵
A = full(SP),将稀疏矩阵补全为完全矩阵
whos,返回存储信息
nnz(SP),返回稀疏矩阵中非零元素的个数
nonzeros(A),返回稀疏矩阵中非零元素组成的列向量