对角矩阵的压缩存储

对角矩阵

●定义

• 若一个n阶方阵A满足,其所有非零元素都集中在以对角线为中心的带状区域中,则称其为n阶对角矩阵

●术语

        • b - 矩阵半带宽:主对角线上下方各有b条次对角线
        • (2b+1)--矩阵的带宽

● 特征

        • 对于半带宽为 b(0<=b<(n-1))的对角矩阵,其|i-j|<=b的元素 ai,j不为零,其余元素为零.

●存储策略:

        •为了压缩存储空间,为0的空间,我们就不存储,或者判断出不是带状区域就输出 0
        •找到对角矩阵坐标和一维数组的关系,进而对坐标进行换算,映射一维数组位序
        •设计算法,保证逻辑结构不变,存储空间减小
        • 利用一维数组,按顺序存储对角矩阵的元素

●观察对角矩阵的结构(我们此处以三对角矩阵举例):

        •在三对角矩阵中,除了第一行和最后一行各有两个元素,其余各行非零元素aij均有三个,所以共有(3n-2)个非零元素 ,(第一行和最后一行,节点个数为2两个)
        • 处于对角线下方的节点,(a10,a21,a32,...),观察得出,有:j = i-1;
        • 处于对角线上的节点,(a00,a11,a22,...),有 : j=i;
        • 处于对角线上方的节点,(a01,a12,a23,...),有: j=i+1;

●寻找二维坐标和一位数组的位序关系

•方法一: 输入坐标的时候,可以判断,然后确定是哪个位置上的节点,从而得出对应的一维数组的位序
        •方法二:① 观察
                ② 先确定节点,前i行的元素个数,为: 2+3*(i-1)=3i-1;
                 因为,第一行和最后一行有两个元素,所以先把第一行算上,然后再算剩余i-1行,即可.
                ③ 对角线下方的节点, aij是本行第一个非零元素,所以其前面的元素是k = 3i-1 = 2i+j
                ④ 对角线的节点,是本行的第二个非零元素, k = 3i = 2i+j
                ⑤ 对角线上方的节点,是本行的第三个非零元素, k = 3i+1 = 2i+j;
        •我们一维数组是从0开始计算的,所以元素前面的节点个数,就是对应的坐标位序


●下面我们开始构建三对角矩阵代码:

#include <stdio.h>
#include <malloc.h>
#define N 6
//构建一维数组数组
void Init(int *&b)
{
	b = (int*)malloc(sizeof(int)*(3*N-1));
}
//将e赋值给对应的二维数组A[i][j]里面的值,存储在一维数组里面
void Assign(int b[],int e,int i, int j)
{
	if(j == i-1)
	{
		b[3*i-1] = e;
	}
	else if(j == i)
	{
		b[3*i] = e;
	}
	else if(j==i+1)
	{
		b[3*i+1] = e;
	}
}
//返回特定坐标里面的数值
int Value(int b[],int i, int j)
{
	if(j == i-1)
	{
		return b[3*i-1];
	}
	else if(j == i)
	{
		return b[3*i];
	}
	else if(j==i+1)
	{
		return b[3*i+1];
	}
	else
	{
		return b[3*N-2];
	}
}
//逐个输出二维数组里面的数据
void Disp(int b[])
{
	int i,j;
	for(i=0; i<N; i++)
	{
		for(j = 0; j<N; j++)
		{
			printf("%4d",Value(b,i,j));
		}
		printf("\n");
	}
}
//销毁存储空间
void Destroy(int b[])
{
    free(b);
}


int main()
{
	//构建一维数组
	//一维数组在元素矩阵个数的基础上加一,存放两侧的数据
	int *b1;
	//坐标
	int i,j;
	//承载输入数据
	int v;
	//构建一位数组
	Init(b1);
	printf("请输入要压缩的带状数据两侧的数据是多少?\n");
	scanf("%d",&v);
	b1[3*N-2] = v;
	printf("请一次输入矩阵内的数据");
	for(i=0;i<N;i++)
	{
		printf("请输入第%d行的%d个元素\n",i+1,N);
		for(j = 0;j < N;j++)
		{
			scanf("%d",&v);
			Assign(b1,v,i,j);
		}
	}
	Disp(b1);
    Destroy(b1);
    return 0;
}

运行结果如图:

 

 

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
您好!很高兴回答您的问题。三对角矩阵压缩存储是指对于某些特殊的矩阵(如对称矩阵、三对角矩阵等),可以通过压缩存储来减少存储空间和运算量。具体的实现方法如下: 1. 压缩存储矩阵的非零元素,可以采用两个一维数组存储矩阵的上/下对角线和主对角线元素,这些数组的长度为矩阵的行数(或列数)减一。其中,上/下对角线元素的索引比主对角线元素的索引小一(因为它们位于主对角线上/下一行)。 2. 如果是三对角矩阵,可以只存储三个一维数组,分别存储主对角线、上对角线和下对角线元素即可。 以下是一份可能的代码实现,供您参考: ```python import numpy as np class TridiagonalMatrix: def __init__(self, data): self.size = len(data) self.main_diagonal = np.zeros(self.size) self.upper_diagonal = np.zeros(self.size - 1) self.lower_diagonal = np.zeros(self.size - 1) self.main_diagonal[:] = data self.upper_diagonal[:-1] = data[1:] self.lower_diagonal[1:] = data[:-1] def to_array(self): A = np.zeros((self.size, self.size)) np.fill_diagonal(A, self.main_diagonal) np.fill_diagonal(A[1:], self.upper_diagonal) np.fill_diagonal(A[:, 1:], self.lower_diagonal) return A # Test data = [4, 7, 2, 9, 1] M = TridiagonalMatrix(data) print("Main diagonal:", M.main_diagonal) print("Upper diagonal:", M.upper_diagonal) print("Lower diagonal:", M.lower_diagonal) A = M.to_array() print(A) ``` 当输入数据 `[4, 7, 2, 9, 1]` 时,输出结果如下: ``` Main diagonal: [4. 7. 2. 9. 1.] Upper diagonal: [7. 2. 9. 1.] Lower diagonal: [4. 7. 2. 9.] [[4. 7. 0. 0. 0.] [4. 2. 9. 0. 0.] [0. 7. 2. 1. 0.] [0. 0. 9. 1. 0.] [0. 0. 0. 1. 0.]] ``` 希望我能够帮到您,如果您还有其他问题欢迎继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值