[矩阵的特征向量是什么]特征向量-定义数学上,线性变换的特征向量(本征向量)是一个非退化的向量,其方向在该变换【2】下不变。该向量在此变换下缩放的比例称为其特征值(本征值)。图1给出了一幅图像的例子...+阅读
/*Multiplicate part*///C = A * B/*算法分析:首先,由于楼主没有给出输入函数,也没有对三元组的稀疏矩阵的数据结构做完整的说明,所以我只能猜测这个稀疏矩阵是以行为主序存储的。(后面的乘法函数佐证了我的猜测,但是如果我不幸猜错了,还请楼主告知) 另一个猜测是楼主的程序中设定矩阵和数组的下标都是从1开始,而非从0开始。接下来,我们说一下普通矩阵的乘法,这个在线性代数里面有定义,无需赘言。我要说的是稀疏矩阵的乘法也是用这个公式来计算,但却有一个问题——效率。我们举一个例子来说明:假设我们已知A:m*n和B:n*l,要计算C:m*l,那么C(i,j)的计算公式就是:C(i,j) = A(i,1)*B(1,j) + A(i,2)*B(2,j) + …… + A(i,n)*B(n,j) 公式1 如果A、B都是普通矩阵(并且以二维数组存储),那么直接用循环语句就可以完成。如果A、B都是稀疏矩阵(并且乱序存储,即是说没有以行序或列序存储),那么计算就会很麻烦。我们需要首先遍历整个A矩阵去查找是否存在A(i,1)(若有则取其值,若无则其值为0),然后再去 遍历B矩阵查找B(1,j),并将两者相乘;接着又是A(i,2)和B(2,j),以此类推。这样做当然是可行的,但是显然效率太低了,一种改进的方法(就是楼主的程序中所用的方法)如下:首先我们要优化稀疏矩阵的存储,不能乱序存储,而是以行序或列序为主序来存储,比如这里我们以行序为主序,以列序为次序。具体来说,就是将稀疏矩阵的第一行中的非零元素排列在前面,然后才是第二行、第三行…… 在各行的非零元素中又以列序来排列,这样存储的稀疏矩阵就是有序的。接下来,在真正用公式来计算之前,我们要做一个预处理。这个预处理是对矩阵B所做的,其实就是要计算得到矩阵B所对应的pos数组。那么这个pos数组代表什么意思呢?我们从代码中不难看出pos数组的长度是矩阵B的行数(也就是B->m)加1。pos[i](1m + 1)是为了方便后面的计算而增加一个标记,类似于监视哨。有了这个pos数组之后,我们再来计算公式1就可以提高效率了。效率的提高表现在两个方面:
1、我们看到代码中(如下)虽然有两层while循环,但是其实总共只执行了A->t次。 p=1; while(pt) { …… while (pt&A->data[p].row==crow) { …… p=p+1; } …… }
2、在第二层while循环中的for循环,由于pos数组的作用使得循环次数减少很多。 for(q=pos[brow];qdata[q].col; ctemp[ccol]=ctemp[ccol] + A->data[p].v * B->data[q].v; } 好了,以上就是这个稀疏矩阵乘法的大致过程,如有错误请指正。*/ void MultS(TriTable *A,TriTable *B,TriTable *C) { int k,p,q,brow,crow,ccol; int num[MAXSIZE],pos[MAXSIZE],ctemp[MAXSIZE]; if (A->n==B->m) { for(k=1;km;k++) num[k]=0; for(k=1;kt;k++) num[B->data[k].row]++; pos[1]=1; for(k=2;km;k++) //这里将kt改为km pos[k]=pos[k-1]+num[k-1]; pos[1+B->m]=pos[B->m]+1; //这里将kt改为km C->m=A->m; C->n=B->n; C->t=0; p=1; while(pt) { crow=A->data[p].row; for(k=1;kn;k++) ctemp[k]=0; while (pt&A->data[p].row==crow) { brow=A->data[p].col; for(q=pos[brow];qdata[q].col; ctemp[ccol]=ctemp[ccol] + A->data[p].v * B->data[q].v; } p=p+1; } for(ccol=1;ccoln;ccol++) if(ctemp[ccol]!=0) { C->t=C->t+1; C->data[C->t].row=crow; C->data[C->t].col=ccol; C->data[C->t].v=ctemp[ccol]; } } }else printf("these two arrat can't Multiplicate"); return; }