自学内容网 自学内容网

三对角矩阵@带状矩阵的压缩存储与换源

三对角矩阵

对角矩阵也称带状矩阵。对 n n n 阶矩阵 A A A 中的任意一个元素 a i , j a_{i,j} ai,j,当 ∣ i − j ∣ > 1 |i-j| > 1 ij>1 时,若有 a i , j = 0 a_{i,j} = 0 ai,j=0 ( 1 ≤ i , j ≤ n 1 \leq i, j \leq n 1i,jn),则称为三对角矩阵

在三对角矩阵中,所有非零元素都集中在以主对角线为中心的 3 条对角线的区域,其他区域的元素都为零。
A n = [ a 1 , 1 a 1 , 2 0 ⋯ 0 a 2 , 1 a 2 , 2 a 2 , 3 ⋯ 0 0 a 3 , 2 a 3 , 3 ⋯ 0 ⋮ ⋮ ⋮ ⋱ ⋮ 0 0 0 ⋯ a n , n ] A_{n}=\begin{bmatrix} a_{1,1} & a_{1,2} & 0 & \cdots & 0 \\ a_{2,1} & a_{2,2} & a_{2,3} & \cdots & 0 \\ 0 & a_{3,2} & a_{3,3} & \cdots & 0 \\ \vdots & \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & 0 & \cdots & a_{n,n} \end{bmatrix} An= a1,1a2,100a1,2a2,2a3,200a2,3a3,30000an,n

[ a 1 , 1 a 1 , 2 a 2 , 1 a 2 , 2 a 2 , 3 0 a 3 , 2 a 3 , 3 a 3 , 4 ⋱ ⋱ ⋱ 0 a n − 1 , n − 2 a n − 1 , n − 1 a n − 1 , n a n , n − 1 a n , n ] \begin{bmatrix}a_{1,1}&a_{1,2}&&&&\\ a_{2,1}&a_{2,2}&a_{2,3}&&\Huge\it0\\ &a_{3,2}&a_{3,3}&a_{3,4}\\ &&\ddots&\ddots&\ddots\\ &\Huge\it0&&a_{n-1,n-2}&a_{n-1,n-1}&a_{n-1,n}\\ &&&&a_{n,n-1}&a_{n,n} \end{bmatrix} a1,1a2,1a1,2a2,2a3,20a2,3a3,3a3,4an1,n20an1,n1an,n1an1,nan,n

三对角矩阵 A A A 也可以采用压缩存储,将 3 条对角线上的元素按行优先方式存放在一维数组 B B B 中,且 a 1 , 1 a_{1,1} a1,1 存放于 B [ 0 ] B[0] B[0] 中,其存储形式如图下
a 1 , 1 a 1 , 2 a 2 , 1 a 2 , 2 a 2 , 3 ⋯ a n − 1 , n a n , n − 1 a n , n \begin{array}{|c|c|c|c|c|c|c|c|c|} \hline a_{1,1} & a_{1,2} & a_{2,1} & a_{2,2} & a_{2,3} & \cdots & a_{n-1,n} & a_{n,n-1} & a_{n,n} \\ \hline \end{array} a1,1a1,2a2,1a2,2a2,3an1,nan,n1an,n

i=1( Q − 1 Q_{-1} Q1)(虚拟) Q 0 Q_0 Q0 Q 1 Q_1 Q1
2 Q 2 Q_2 Q2 Q 3 Q_{3} Q3 Q 4 Q_4 Q4
3 Q 5 Q_5 Q5 Q 6 Q_{6} Q6 Q 7 Q_7 Q7
4 ⋮ \vdots ⋮ \vdots
QQQ
QQ

计算带状区域元素数量

带状区域指的是三对角线上的元素构成的区域

i − 1 i-1 i1行的元素数量

  • 第1行到 i − 1 i-1 i1行每行都有有三个元素(补上的虚拟元素 Q − 1 Q_{-1} Q1后面再 − 1 -1 1,则 s i − 1 = 3 ( i − 1 ) − 1 s_{i-1}=3(i-1)-1 si1=3(i1)1

i i i行有 j − ( i − 1 ) j-(i-1) j(i1)个元素

  • 三对角矩阵的斜对角区域的第 i i i行的三个元素可以表示为: a i , i − 1 , a i , i , a i , i + 1 a_{i,i-1},a_{i,i},a_{i,i+1} ai,i1,ai,i,ai,i+1

  • 对于带状区域内的第 i i i行元素 a i j a_{ij} aij,有 j ∈ {   i − 1 , i , i + 1   } j\in\set{i-1,i,i+1} j{i1,i,i+1}

  • 所以第 i i i行前 a i j a_{ij} aij前有 j − ( i − 1 ) = j − i + 1 j-(i-1)=j-i+1 j(i1)=ji+1个元素,如果算上 a i j a_{ij} aij自身,则有 j − ( i − 1 ) + 1 j-(i-1)+1 j(i1)+1= j − i + 2 j-i+2 ji+2个元素

所以带状区域内,第 a i j a_{ij} aij前有 3 ( i − 1 ) − 1 + j − i + 1 3(i-1)-1+j-i+1 3(i1)1+ji+1= 2 i + j − 3 2i+j-3 2i+j3个元素

如果从0计数,那么 a i j a_{ij} aij将恰好计数为 2 i + j − 3 2i+j-3 2i+j3

压缩公式

将三对角矩阵的带状区域依次存入数组 B B B,则 a i j a_{ij} aij存在数组 B B B的索引为

  • k ( i , j ) k(i,j) k(i,j)= 2 i + j − 3 2i+j-3 2i+j3, ∣ j − i ∣ ⩽ 1 |j-i|\leqslant{1} ji1
  • k ( i , j ) k(i,j) k(i,j)= 0 0 0, ∣ j − i ∣ > 1 |j-i|>1 ji>1

k k k确定 i , j i,j i,j

若已知三对角矩阵中的某个元素 a i j a_{ij} aij存放在一维数组 B B B的第 k k k个位置(索引 k k k),则 i , j i,j i,j的取值分别为多少?

a a a的下标 i , j i,j i,j都是 1 ⋯ n 1\cdots{n} 1n,而不是从0开始计数,但是数组 B B B中的元素索引从0开始计数

例如 a 1 , 1 a_{1,1} a1,1在数组 B B B中的索引为 k = 0 k=0 k=0,也就是 B [ 0 ] = a 1 , 1 B[0]=a_{1,1} B[0]=a1,1,现在要求更一般的情况 B [ k ] = a i ( k ) , j ( k ) B[k]=a_{i(k),j(k)} B[k]=ai(k),j(k)

也就是确定两个函数 i ( k ) , j ( k ) i(k),j(k) i(k),j(k)的表达式

根据压缩公式 k = 2 i + j − 3 k=2i+j-3 k=2i+j3难以确定 i , j i,j i,j关于 k k k的表达式

先绘制对应的矩阵示意图
[ a 1 , 1 a 1 , 2 0 ⋯ 0 a 2 , 1 a 2 , 2 a 2 , 3 ⋯ 0 0 a 3 , 2 a 3 , 3 ⋯ 0 ⋮ ⋮ ⋮ ⋱ ⋮ 0 0 0 ⋯ a n , n ] \begin{bmatrix} a_{1,1} & a_{1,2} & 0 & \cdots & 0 \\ a_{2,1} & a_{2,2} & a_{2,3} & \cdots & 0 \\ 0 & a_{3,2} & a_{3,3} & \cdots & 0 \\ \vdots & \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & 0 & \cdots & a_{n,n} \end{bmatrix} a1,1a2,100a1,2a2,2a3,200a2,3a3,30000an,n
第一行三对角线上元素为 0, 1,第二行为 2, 3, 4,依此类推。使用省略号来表示中间的元素,以适应任意大小的矩阵。

A = [ 0 1 0 0 ⋯ 0 2 3 4 0 ⋯ 0 0 5 6 7 ⋯ 0 0 0 8 9 ⋱ ⋮ ⋮ ⋮ ⋮ ⋱ ⋱ n − 1 0 0 0 ⋯ n n + 1 ] A = [ 0 1 2 3 4 5 6 7 8 9 10 ⋱ ⋱ ⋱ ] A = \begin{bmatrix} 0 & 1 & 0 & 0 & \cdots & 0 \\ 2 & 3 & 4 & 0 & \cdots & 0 \\ 0 & 5 & 6 & 7 & \cdots & 0 \\ 0 & 0 & 8 & 9 & \ddots & \vdots \\ \vdots & \vdots & \vdots & \ddots & \ddots & n-1 \\ 0 & 0 & 0 & \cdots & n & n+1 \end{bmatrix} A = \begin{bmatrix} 0 & 1 & & & & \\ 2 & 3 & 4 & & & \\ & 5 & 6 & 7 & & \\ & & 8 & 9 & 10 & \\ & & & \ddots & \ddots&\ddots\\ \end{bmatrix} A= 0200013500046800079n000n1n+1 A= 021354687910

确定 i ( k ) i(k) i(k)

i ( k ) i(k) i(k)的表达式形式不是唯一的,只要正确映射 B [ k ] B[k] B[k]对应的元素在三对角矩阵中的位置即可

容易观察到,矩阵A除了第一行以外,每一行都有3个元素,如此排列下去,问题和 B [ k ] B[k] B[k]排列在几行相关;

设矩阵B第一层存放1,2,3,第二层存放4,5,6,依次类推,第 i i i层存放的就是 i − 2 , i − 1 , i i-2,i-1,i i2,i1,i;或者 3 ( i − 1 ) + 1 , 3 ( i − 1 ) + 2 , 3 i 3(i-1)+1,3(i-1)+2,3i 3(i1)+1,3(i1)+2,3i

显然第 x x x个元素所在的层数为 i = ⌈ x / 3 ⌉ i=\lceil{x/3}\rceil i=x/3;

现在回到矩阵 A A A,可以发现,相对于矩阵B存放 x x x的位置变成存放 x − 2 x-2 x2,这相当于第一层的前两个存储空间损坏,存放的位置要往后移动2个位置,现在第 x x x个元素需要存放到原来存放 x + 2 x+2 x+2的位置;因此为了计算此时的元素存放层号 i i i,可以计算 ⌈ ( x + 2 ) / 3 ⌉ \lceil{(x+2)/3}\rceil (x+2)/3

由此得到 k = 1 , 2 , ⋯ k=1,2,\cdots k=1,2,在矩阵 A A A中的行号, i ( k ) = ⌈ ( k + 2 ) / 3 ⌉ i(k)=\lceil{(k+2)/3}\rceil i(k)=(k+2)/3(1)

可以验证 k = 0 k=0 k=0也满足此公式

另一种表达式

仔细观察矩阵 A A A,其第 i i i ( i = 1 , 2 , ⋯   ) (i=1,2,\cdots) (i=1,2,)的第2个元素为 3 ( i − 1 ) 3(i-1) 3(i1),也就是说第 i i i行三对角线上存储的元素分别是索引 3 ( i − 1 ) − 1 , 3 ( i − 1 ) , 3 ( i − 1 ) + 1 3(i-1)-1,3(i-1),3(i-1)+1 3(i1)1,3(i1),3(i1)+1;它们的行号都是 i i i;将这三个值记为序列 S S S

事实上,任意一个合法的 k , ( k = 0 , 1 , 2 , ⋯   ) k,(k=0,1,2,\cdots) k,(k=0,1,2,),都能找到一个整数 i i i使得 k ∈ S k\in{S} kS

如果能找到一种映射关系 f ( {   3 ( i − 1 ) − 1 , 3 ( i − 1 ) , 3 ( i − 1 ) + 1   } ) f(\set{3(i-1)-1,3(i-1),3(i-1)+1}) f({3(i1)1,3(i1),3(i1)+1})= {   i , i , i   } \set{i,i,i} {i,i,i}就相当于找到 i ( k ) i(k) i(k)函数表达式

S S S中的三个值分别都加1,得 3 ( i − 1 ) , 3 ( i − 1 ) + 1 , 3 ( i − 1 ) + 2 3(i-1),3(i-1)+1,3(i-1)+2 3(i1),3(i1)+1,3(i1)+2,这三个数除以3向下取整结果都是 i − 1 i-1 i1;

也就是 ⌊ ( k + 1 ) / 3 ⌋ \lfloor(k+1)/3\rfloor ⌊(k+1)/3= i − 1 i-1 i1;从而 i i i关于 k k k的函数 i ( k ) i(k) i(k)= ⌊ ( k + 1 ) / 3 ⌋ + 1 \lfloor(k+1)/3\rfloor+1 ⌊(k+1)/3+1= ⌊ ( k + 1 ) / 3 + 1 ⌋ \lfloor(k+1)/3+1\rfloor ⌊(k+1)/3+1(2)

考虑到取整号的性质(无论是向下取整还是向上取整, [ a + z ] = [ a ] + z [a+z]=[a]+z [a+z]=[a]+z,其中 z ∈ Z z\in\mathbb{Z} zZ,因为任何数和整数相加减不会改变小数部分,计算顺序自然不会影响取整结果)

确定 j ( k ) j(k) j(k)

j ( k ) j(k) j(k)的确定比 i ( k ) i(k) i(k)更容易些,需要用到 i ( k ) i(k) i(k)

首先计算 i ( k ) i(k) i(k),得知 B [ k ] B[k] B[k]会被排列到第几行( i = i ( k ) i=i(k) i=i(k))

然后计算 B [ k ] B[k] B[k]在第 i i i行的第几个位置(从1开始计数)

矩阵 A A A的前 i − 1 i-1 i1行元素个数为 s i − 1 = 3 ( i − 1 ) − 1 s_{i-1}=3(i-1)-1 si1=3(i1)1(末尾减1是因为第一行只有2个元素)

那么三对角线第 i i i行上剩下 k + 1 − s i − 1 k+1-s_{i-1} k+1si1,(其中加1是因为 k k k是从0计数的, B [ 0 ] B[0] B[0] B [ k ] B[k] B[k]共有 k + 1 k+1 k+1个元素)

而第 i i i行三对角线前的元素 i − 2 i-2 i2个(注意第 i i i行第一个三对角线上的元素列号为 i − 1 i-1 i1,再前一号是 i − 2 i-2 i2),所以 j = i − 2 + k + 1 − s i − 1 j=i-2+k+1-s_{i-1} j=i2+k+1si1= k − 2 i + 3 k-2i+3 k2i+3(3)

公式总结

注意公式中的 i , j i,j i,j都是从 1 1 1开始计算,如果要从0开始计算,需要各自减去1

三对角线上的元素解压:

  • i ( k ) i(k) i(k)= ⌈ ( k + 2 ) / 3 ⌉ \lceil{(k+2)/3}\rceil (k+2)/3= ⌊ ( k + 1 ) / 3 ⌋ + 1 \lfloor(k+1)/3\rfloor+1 ⌊(k+1)/3+1= ⌊ ( k + 1 ) / 3 + 1 ⌋ \lfloor(k+1)/3+1\rfloor ⌊(k+1)/3+1
  • j ( k ) j(k) j(k)= k − 2 i + 3 k-2i+3 k2i+3= k − 2 ( ⌊ k + 1 3 + 1 ⌋ ) + 3 k-2(\lfloor{\frac{k+1}{3}+1}\rfloor)+3 k2(⌊3k+1+1⌋)+3

其他位置元素全部填充0

应用举例

计算 k = 4 k=4 k=4时, a i j a_{ij} aij i , j i,j i,j

i ( k ) i(k) i(k)= [ ( 4 + 1 ) / 3 + 1 ] [(4+1)/3+1] [(4+1)/3+1]= 2 2 2

j ( k ) j(k) j(k)= 4 − 2 × 2 + 3 4-2\times{2}+3 42×2+3= 3 3 3

所以 B [ 4 ] = a 2 , 3 B[4]=a_{2,3} B[4]=a2,3


原文地址:https://blog.csdn.net/xuchaoxin1375/article/details/144335763

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!