三九宝宝网宝宝教育学龄段教育

C中矩阵与向量乘法运算用友元

02月28日 编辑 39baobao.com

[在拓展中培养元认知能力]在拓展中培养元认知能力 ----《长征》教学案例谈 丹阳市延陵中心校 汤国荣 元认知是美国心理学家弗拉维尔于七十年代提出来的,所谓元认知就是指个体对自身认知过程的认识和意...+阅读

你犯的错误是C++初学者很容易犯的一个错误。Vector中出现了个以int类型为参数构造函数,但没有一个“拷贝构造函数”。你的multiply方法的反回值是Vector类型,当这个函数在返回时,会调用Vector的“拷贝构造函数”,编译器发现你没有自己定制一个“拷贝构造函数”,于是它自己给你加了一个默认的“拷贝构造函数”,这个默认的“拷贝构造函数”的默认行为就是按位来拷贝Vector对象,于是乎返回的个这Vector对象中的int* v;成员就指向一个multiply栈中的数据,而这个数据在multiply返回后就变为无用的了。这就是“野指针”的一种形式,因为它指向了一个已经返回了的函数的栈中的数据,所以它会出错。知道了原因后,解决方法很简单,自己定义Vector的“拷贝构造函数”,然后将int* v;指向的数据再拷贝一份。

即可。

稀疏矩阵的乘法的算法思想

/*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; }

矩阵列向量乘法

列向量就是只有一列的矩阵,可以用来表示向量

矩阵的乘法规则简单来说是这样的:左右两个矩阵相乘,乘得矩阵行同左,列同右,要求左列右行要相同。行由左边定,列由右边定,对应相乘以后求和为相应的数值。举个例子就明白了:

1 2 3 1 1 2 3

2 3 4 2 X 4 5 6

3 4 5 3 7 8 9

1 2 3

随便编了几个数,根据上面说的规则,新的矩阵应该是3行3列的,左面的行是3行,所以是3行,右边的列是3列,所以是3列

之后看第一行第一列,从左边找第一行,右边找第一列,对应相乘(他们的项数是相等的,都是4),第一项乘第一项1*1,第二项相乘2*4,第三项3*7,第四项1*1

然后相加为31,这就是新矩阵最左上角的数字,同理可以求得其他项,最后的结果就是

31 38 45

44 55 66

57 72 87

上面这些都是我自己写的,没有任何复制粘贴,例子也是自己出自己算的,如果可以,就选为最佳答案吧

以下为关联文档:

浅议小学数学中几个运算定律的文字表述数学运算定律,是计算法则的理论基础,在学生学习过程中应用相当广泛,是学生必须掌握的基础知识,根据这些运算定律可以使一些运算简便。因此,在教学中让学生很好的掌握,灵活地应用这...

加减法简便运算中容易出现的错误及原因分析学生在加减法简便运算作业中出现错误的原因归纳起来,主要表现在这几方面:道理不明白;对运算定律不理解;对知识的运用不灵活;对问题理解片面;学习习惯差,粗心大意。现分析如下: 1.加上...

matlab中已知协方差矩阵怎样算相关系数计算方法如下: 假设协方差矩阵为c 第i行与第j行的相关系数为: r(i,j)=c(i,j)/sqrt(c(i,i)*c(j,j)) 若要求整个矩阵可用循环实现 [m,n]=size(c); for i=1:m for j=1:n r(i,j)=c...

矩阵的特征向量是什么特征向量-定义数学上,线性变换的特征向量(本征向量)是一个非退化的向量,其方向在该变换【2】下不变。该向量在此变换下缩放的比例称为其特征值(本征值)。图1给出了一幅图像的例子...

一个C程序的编程问题测试小学生的四则运算刚开始错了 重新修改 经过调试 可行 #include#includevoid main() { long a,b,d,s[5],sum; int num=0; char c; s[1]='+'; s[2]='-'; s[3]='*'; s[4]='/'; printf("Please in...

C语言编程小学生数学四则运算题要求可以输入所出题目数判断对错#include <stdio.h> #include <time.h> void main() { int num,mark=0,i; int num1,num2,sum,n; scanf("%d",&num); srand((unsigned) time(NULL)); for(i=0;i<num;i++) { num...

小学四则运算法则与有理数运算法则有什么相同和不同????在初等数学中,当一级运算(加减)和二级运算(乘除)同时出现在一个式子中时,它们的运算顺序是先乘除,后加减,如果有括号就先算括号内后算括号外,同一级运算顺序是从左到右.这样的运算叫...

C关于乘法口诀的问题#include<stdio.h> int main() { int n; printf("Input the number :"); scanf("%d",&n); printf("Result : %d times table\n",n); for(int i=1;i<=9;i++) printf("%d*%d=%d\n",n,i...

求分析C语言程序就是乘法口诀表的#include "stdio.h" int main() { int i,j; for(i=1;i<=9;i++)//一共是1到9行 { for(j=1;j<=i; j++)//j是从1开始,第i行都是从1*i到j*i(其中j<=i),空白不用输出,即什么都不显示。 p...

推荐阅读
图文推荐