编程,计算两个矩阵相乘计算器

用C语言编写 计算两个5*5矩阵的乘积_百度知道
用C语言编写 计算两个5*5矩阵的乘积
题目:计算两个5*5矩阵的乘积。 要求:两个5*5矩阵的数据由数据文件输入,计算乘积存入珐碃粹度诔道达权惮护另一个文件后再显示出。
我有更好的答案
#include&stdio.h&
void main()
int a[5][5],b[5][5],c[5][5];
int i,j,k,n;
printf(&请输入数字:&);
scanf(&%d&,&n);
/*初始化 答案c数组*/
for(i=0;i&n;i++)
for(j=0;j&n;j++)
c[i][j]=0;
/*初始化 a数组 scanf赋值*/
for(i=0;i&n;i++)
for(j=0;j&n;j++){
printf(&a[%d][%d]=&,i,j);
scanf(&%d&,&a[i][j]);
printf(&(a)=\n&);
/*打印 答案b数组*/
for(i=0;i&n;i++){
其他类似问题
为您推荐:
c语言的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁C语言矩阵相乘帮忙写一个程序要求:利用动态分配数组方式输入并存储A、B两矩阵,并求出两矩阵相乘结果.
冬子EP93ZU80
/* Matrix_main.cpp *///#include #include #include #include /* #include
*/void main(void){ int col, row, row_s;
/* the column & row of the matrix */ int **pM_f = NULL, **pM_s = NULL;
/* point to two matrix,they will be multiplied */ int **pM_r = NULL;
/* the matrix will store the result */ int i, j, printf("Input column & row of the first matrix:\n(depart with blank): "); scanf("%d %d", &col, &row); printf("Input row of the second one:\n(column needn't): "); scanf("%d", &row_s); /* ---------------Request storage for process--------------- */ pM_f = (int**)malloc(col * sizeof(int*)); pM_s = (int**)malloc(row * sizeof(int*)); pM_r = (int**)malloc(col * sizeof(int*)); for (i=0; i
为您推荐:
其他类似问题
扫描下载二维码C语言科学计算入门之矩阵乘法的相关计算
作者:Denlee
字体:[ ] 类型:转载 时间:
这篇文章主要介绍了C语言科学计算入门之矩阵乘法的相关计算,文章中还介绍了矩阵相关的斯特拉森算法的实现,需要的朋友可以参考下
1.矩阵相乘
矩阵相乘应满足的条件:
(1) 矩阵A的列数必须等于矩阵B的行数,矩阵A与矩阵B才能相乘;
(2) 矩阵C的行数等于矩阵A的行数,矩阵C的列数等于矩阵B的列数;
(3) 矩阵C中第i行第j列的元素等于矩阵A的第i行元素与矩阵B的第j列元素对应乘积之和,即
2. 常用矩阵相乘算法
&&& 用A的第i行分别和B的第j列的各个元素相乘求和,求得C的第i行j列的元素,这种算法中,B的访问是按列进行访问的,代码如下:
void arymul(int a[4][5], int b[5][3], int c[4][3])
for(i = 0; i & 4; i++){
for(j = 0; j & 3; j++){
for(k = 0; k & 5; k++){
temp += a[i][k] * b[k][j];
printf("%d/t", c[i][j]);
printf("%d/n");
3. 改进的算法
&&& 矩阵A、B、C都按行(数据的存储顺序)访问,以提高存储器访问效率,对于A的第i行中,第j列的元素分别和B的第j行的元素相乘,对于B中相同的列k在上述计算过程中求和,从而得到C第i行k列的数据,代码如下:
void arymul1(int a[4][5], int b[5][3], int c[4][3])
int temp[3] = {0};
for(i = 0; i & 4; i++){
for(k = 0; k & 3; k ++)
temp[k] = 0;
for(j = 0; j & 5; j++){//当前行的每个元素
for(k = 0; k & 3; k++){
temp[k] += a[i][j] * b[j][k];
for(k = 0; k & 3; k++){
c[i][k] = temp[k];
printf("%d/t", c[i][k]);
printf("%d/n");
这种算法很容易转到稀疏矩阵的相乘算法。
PS:斯特拉森算法的实现
斯特拉森方法,是由v.斯特拉森在1969年提出的一个方法。
我们先讨论二阶矩阵的计算方法。
对于二阶矩阵
a11 a12 b11 b12
A = a21 a22 B = b21 b22
先计算下面7个量(1)
x1 = (a11 + a22) * (b11 + b22);
x2 = (a21 + a22) * b11;
x3 = a11 * (b12 - b22);
x4 = a22 * (b21 - b11);
x5 = (a11 + a12) * b22;
x6 = (a21 - a11) * (b11 + b12);
x7 = (a12 - a22) * (b21 + b22);
再设C = AB。根据矩阵相乘的规则,C的各元素为(2)
c11 = a11 * b11 + a12 * b21
c12 = a11 * b12 + a12 * b22
c21 = a21 * b11 + a22 * b21
c22 = a21 * b12 + a22 * b22
比较(1)(2),C的各元素可以表示为(3)
c11 = x1 + x4 - x5 + x7
c12 = x3 + x5
c21 = x2 + x4
c22 = x1 + x3 - x2 + x6
根据以上的方法,我们就可以计算4阶矩阵了,先将4阶矩阵A和B划分成四块2阶矩阵,分别利用公式计算它们的乘积,再使用(1)(3)来计算出最后结果。
ma11 ma12 mb11 mb12
A4 = ma21 ma22 B4 = mb21 mb22
a11 a12 a13 a14 b11 b12 b13 b14
ma11 = a21 a22 ma12 = a23 a24 mb11 = b21 b22 mb12 = b23 b24
a31 a32 a33 a34 b31 b32 b33 b34
ma21 = a41 a42 ma22 = a43 a44 mb21 = b41 b42 mb22 = b43 b44
// 计算2X2矩阵
void Multiply2X2(float& fOut_11, float& fOut_12, float& fOut_21, float& fOut_22,
float f1_11, float f1_12, float f1_21, float f1_22,
float f2_11, float f2_12, float f2_21, float f2_22)
const float x1((f1_11 + f1_22) * (f2_11 + f2_22));
const float x2((f1_21 + f1_22) * f2_11);
const float x3(f1_11 * (f2_12 - f2_22));
const float x4(f1_22 * (f2_21 - f2_11));
const float x5((f1_11 + f1_12) * f2_22);
const float x6((f1_21 - f1_11) * (f2_11 + f2_12));
const float x7((f1_12 - f1_22) * (f2_21 + f2_22));
fOut_11 = x1 + x4 - x5 + x7;
fOut_12 = x3 + x5;
fOut_21 = x2 + x4;
fOut_22 = x1 - x2 + x3 + x6;
// 计算4X4矩阵
void Multiply(CLAYMATRIX& mOut, const CLAYMATRIX& m1, const CLAYMATRIX& m2)
float fTmp[7][4];
// (ma11 + ma22) * (mb11 + mb22)
Multiply2X2(fTmp[0][0], fTmp[0][1], fTmp[0][2], fTmp[0][3],
m1._11 + m1._33, m1._12 + m1._34, m1._21 + m1._43, m1._22 + m1._44,
m2._11 + m2._33, m2._12 + m2._34, m2._21 + m2._43, m2._22 + m2._44);
// (ma21 + ma22) * mb11
Multiply2X2(fTmp[1][0], fTmp[1][1], fTmp[1][2], fTmp[1][3],
m1._31 + m1._33, m1._32 + m1._34, m1._41 + m1._43, m1._42 + m1._44,
m2._11, m2._12, m2._21, m2._22);
// ma11 * (mb12 - mb22)
Multiply2X2(fTmp[2][0], fTmp[2][1], fTmp[2][2], fTmp[2][3],
m1._11, m1._12, m1._21, m1._22,
m2._13 - m2._33, m2._14 - m2._34, m2._23 - m2._43, m2._24 - m2._44);
// ma22 * (mb21 - mb11)
Multiply2X2(fTmp[3][0], fTmp[3][1], fTmp[3][2], fTmp[3][3],
m1._33, m1._34, m1._43, m1._44,
m2._31 - m2._11, m2._32 - m2._12, m2._41 - m2._21, m2._42 - m2._22);
// (ma11 + ma12) * mb22
Multiply2X2(fTmp[4][0], fTmp[4][1], fTmp[4][2], fTmp[4][3],
m1._11 + m1._13, m1._12 + m1._14, m1._21 + m1._23, m1._22 + m1._24,
m2._33, m2._34, m2._43, m2._44);
// (ma21 - ma11) * (mb11 + mb12)
Multiply2X2(fTmp[5][0], fTmp[5][1], fTmp[5][2], fTmp[5][3],
m1._31 - m1._11, m1._32 - m1._12, m1._41 - m1._21, m1._42 - m1._22,
m2._11 + m2._13, m2._12 + m2._14, m2._21 + m2._23, m2._22 + m2._24);
// (ma12 - ma22) * (mb21 + mb22)
Multiply2X2(fTmp[6][0], fTmp[6][1], fTmp[6][2], fTmp[6][3],
m1._13 - m1._33, m1._14 - m1._34, m1._23 - m1._43, m1._24 - m1._44,
m2._31 + m2._33, m2._32 + m2._34, m2._41 + m2._43, m2._42 + m2._44);
mOut._11 = fTmp[0][0] + fTmp[3][0] - fTmp[4][0] + fTmp[6][0];
mOut._12 = fTmp[0][1] + fTmp[3][1] - fTmp[4][1] + fTmp[6][1];
mOut._21 = fTmp[0][2] + fTmp[3][2] - fTmp[4][2] + fTmp[6][2];
mOut._22 = fTmp[0][3] + fTmp[3][3] - fTmp[4][3] + fTmp[6][3];
mOut._13 = fTmp[2][0] + fTmp[4][0];
mOut._14 = fTmp[2][1] + fTmp[4][1];
mOut._23 = fTmp[2][2] + fTmp[4][2];
mOut._24 = fTmp[2][3] + fTmp[4][3];
mOut._31 = fTmp[1][0] + fTmp[3][0];
mOut._32 = fTmp[1][1] + fTmp[3][1];
mOut._41 = fTmp[1][2] + fTmp[3][2];
mOut._42 = fTmp[1][3] + fTmp[3][3];
mOut._33 = fTmp[0][0] - fTmp[1][0] + fTmp[2][0] + fTmp[5][0];
mOut._34 = fTmp[0][1] - fTmp[1][1] + fTmp[2][1] + fTmp[5][1];
mOut._43 = fTmp[0][2] - fTmp[1][2] + fTmp[2][2] + fTmp[5][2];
mOut._44 = fTmp[0][3] - fTmp[1][3] + fTmp[2][3] + fTmp[5][3];
在标准的定义算法中我们需要进行n * n * n次乘法运算,新算法中我们需要进行7log2n次乘法,对于最常用的4阶矩阵:   原算法 新算法
加法次数 48 72(48次加法,24次减法)
乘法次数 64 49
需要额外空间 16 * sizeof(float) 28 * sizeof(float)
新算法要比原算法多了24次减法运算,少了15次乘法。但因为浮点乘法的运算速度要远远慢于加/减法运算,所以新算法的整体速度有所提高。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具后使用快捷导航没有帐号?
查看: 2537|回复: 7
使用mapreduce计算大矩阵相乘
高级会员, 积分 720, 距离下一级还需 280 积分
论坛徽章:2
本帖最后由 fenss 于
22:34 编辑
前几周的作业都是关于hadoop的部署、调优等,总感觉有那么一点点枯燥,本人还是对mapreduce编程模型比较感兴趣。mapreduce这种模型可以做很多事,但是具体哪一类问题适合使用呢、又应该怎么样去用,似乎在本论坛找不到很多资料。也对,这种事情本来就不是那么好下定论,还是自己实践一下、体会一下比较好。由于本人又对数据挖掘算法比较感兴趣,于是从比较简单的矩阵乘法入手,做了一个完整的例子,希望能抛砖引玉,使大家多讨论关于编程模型方面的问题、有更多好的想法共享。矩阵相乘的定义是,如果有矩阵、,则相乘的结果为矩阵,并且内的元素满足:其中表示矩阵第i行k列的元素。的值就是的第i行与的第k列内积的结果。以、为例,相乘的基本定义如下:其中的计算所需的元素以红色做了标记,可以看到只要把的第1行、的第1列抽取出来,按顺序分别相乘然后求和即可。(红色的latex被狗吃了,下面还有两个公式是用红色标记的,合并到一张图作为附件了,在最后。。)计算矩阵乘法最简单的实现是使用三重循环,显然这是效率相当低的做法,本文考虑使用mapreduce模型解决。考察上述公式,可以把每个的计算独立出来(其实方法应该有很多,这里只是对mapreduce这个模型本身能做什么、以及怎样把问题转化为mapreduce问题进行探讨,因此只是选择了其中一种方法),在计算的时候,需要“收集”与,这个过程可以放在map中进行,然后求内积的运算可以放在reduce中进行。关于数据格式,由于mapreduce处理数据都是以行为单位的,因此可以每一行表示一个矩阵元素,同时带有行列信息,比如“s#1#1#0.5462”表示矩阵s的第2行第2列元素值为0.5462。计算的基本思想是,在map过程把结果矩阵的每个元素所需要的数据收集起来,因此在处理每一行数据的时候,可以知道结果矩阵中哪些元素使用了该行数据,然后以结果矩阵的行列为key,以该行数据的值为value写进context,当然,不能直接把所有value简单写进去就了事,还需要知道这个值的索引。这个过程还是以、为例进行说明:现在假设在map过程遇到了,由定义可以知道,在计算的时候,第1行的元素均需要使用,因此可以知道,需要把的值放到key为“0#0”及“0#1”容器中(map的输出,reduce的输入)。当遇到的时候,过程也是相同的,我们需要把的值放到key为“0#0”及“1#0”容器中。处理完、的时候,reduce的输入应该是这样的:0#0:、0#1:1#0:继续map过程,当处理完、的时候,key为“0#0”的容器内已经有4个元素,分别是、、、,就可以开始计算的值了,但还是有一点需要细化一下,就是相乘及求和的顺序问题,得到了这4个值是需要有顺序信息的,因此在map阶段需要把这个信息也带入到value当中,比如,实际存放的值可以是0#,对于,实际存放的值可以是1#,总之就是需要记录一下内积的顺序。完整的mapper代码如下:package org.tat.mr.
import java.io.IOE
import org.apache.hadoop.io.T
import org.apache.hadoop.mapreduce.M
public class MultiplyMapper extends Mapper&Object,Text,Text,Text& {
& && &&&private Text _map_key = new Text();
& && &&&private Text _map_value = new Text();
& && &&&protected void map(Object key,Text value,Context context)
& && && && && && && && &throws IOException,InterruptedException {
& && && && && & String[] args = value.toString().split(&#&);
& && && && && & String type = args[0];
& && && && && & int i = Integer.parseInt(args[1]);
& && && && && & int j = Integer.parseInt(args[2]);
& && && && && & double val = Double.parseDouble(args[3]);
& && && && && & if (Const.FIRST_PREFIX.equals(type)) {
& && && && && && && && &for (int k = 0;k & Const.COLUMN;k ++) {
& && && && && && && && && && &&&_map_key.set(i + &#& + k);
& && && && && && && && && && &&&_map_value.set(Const.FIRST_PREFIX + &#& + j + &#& + val);
& && && && && && && && && && &&&context.write(_map_key,_map_value);
& && && && && && && && &}
& && && && && & } else if (Const.SECOND_PREFIX.equals(type)) {
& && && && && && && && &for (int k = 0;k & Const.ROW;k ++) {
& && && && && && && && && && &&&_map_key.set(k + &#& + j);
& && && && && && && && && && &&&_map_value.set(Const.SECOND_PREFIX + &#& + i + &#& + val);
& && && && && && && && && && &&&context.write(_map_key,_map_value);
& && && && && && && && &}
& && && && && & }
& && &&&}
}
复制代码完整的reducer代码如下:package org.tat.mr.
import java.io.IOE
import org.apache.hadoop.io.T
import org.apache.hadoop.mapreduce.R
public class MultiplyReducer extends Reducer&Text,Text,Text,Text& {
& && &&&private Text _result = new Text();
& && &&&@Override
& && &&&protected void reduce(Text key,Iterable&Text& values,Context context)
& && && && && && && && &throws IOException,InterruptedException {
& && && && && & double[] _f_row = new double[Const.HIDDEN];
& && && && && & double[] _s_column = new double[Const.HIDDEN];
& && && && && & for (Text value : values) {
& && && && && && && && &String[] args = value.toString().split(&#&);
& && && && && && && && &String type = args[0];
& && && && && && && && &int idx = Integer.parseInt(args[1]);
& && && && && && && && &double val = Double.parseDouble(args[2]);
& && && && && && && && &if (Const.FIRST_PREFIX.equals(type)) {
& && && && && && && && && && &&&_f_row[idx] =
& && && && && && && && &} else if (Const.SECOND_PREFIX.equals(type)) {
& && && && && && && && && && &&&_s_column[idx] =
& && && && && && && && &}
& && && && && & }
& && && && && & Double sum = 0.0;
& && && && && & for (int i = 0;i & Const.HIDDEN;i ++) {
& && && && && && && && &sum += _f_row[i] * _s_column[i];
& && && && && & }
& && && && && & _result.set(sum.toString());
& && && && && & context.write(key,_result);
& && &&&}
}
复制代码可以使用shell命令生成测试数据,本文使用的是java生成随机数矩阵进行测试,4*2矩阵乘以2*4矩阵,数据如下:f#0#0#0.84469
f#0#1#0.2338
f#1#0#0.8748
f#1#1#0.3334
f#2#0#0.6504
f#2#1#0.4095
f#3#0#0.5438
f#3#1#0.78588
s#0#0#0.3128
s#0#1#0.3083
s#0#2#0.718617
s#0#3#0.5906
s#1#0#0.5657
s#1#1#0.5462
s#1#2#0.4354
s#1#3#0.36184
复制代码查看作业输出,结果如下:0#0& && &&&0.9817
0#1& && &&&0.4082
0#2& && &&&0.40806
0#3& && &&&0.56142
1#0& && &&&0.9708
1#1& && &&&1.5686
1#2& && &&&0.4145
1#3& && &&&0.155
2#0& && &&&0.169
2#1& && &&&1.
2#2& && &&&0.9604
2#3& && &&&0.5167
3#0& && &&&0.01813
3#1& && &&&0.891
3#2& && &&&0.34808
3#3& && &&&0.6493
复制代码使用wolframalpha或者别的什么可以对结果进行验证,提交到wolframalpha的测试数据及结果如下:{{0.3},{0.7},{0.2},{0.7}} *
{{0.7,0.2},{0.5,0.8}}
----------------------------------------------------------------
{{0....155485},
{0..763,0.503714},
{0..091,0.564989},
{0....243774}}
复制代码可以看到mapreduce的计算结果与wolframalpha的计算结果是一致的。这只是一个简单的例子,如果要在数据挖掘分析领域应用mapreduce模型,还有很长的路,比如关联规则、聚类、分类等问题,更细的还有当中的神经网络、最优化问题等,相信都不是简简单单就能解决的,还是有待各位爱好者发挥想象力。
pic.jpg (41.16 KB)
22:32 上传
金牌会员, 积分 1341, 距离下一级还需 1659 积分
论坛徽章:6
注册会员, 积分 63, 距离下一级还需 137 积分
论坛徽章:0
论坛徽章:15
参考一下,你的思路,试试用r来实现 。
金牌会员, 积分 1655, 距离下一级还需 1345 积分
论坛徽章:13
原创贴,有意思,顶一下。
高级会员, 积分 720, 距离下一级还需 280 积分
论坛徽章:2
bsspirit 发表于
参考一下,你的思路,试试用r来实现 。
其实我也是直接参考别人的代码,不过原文没说明过程,我自己整理出思路而已
新手上路, 积分 23, 距离下一级还需 27 积分
论坛徽章:0
麻烦问一下 Const.FIRST_PREFIX 这个是什么东西?
高级会员, 积分 515, 距离下一级还需 485 积分
论坛徽章:1
没有数据基础咋办啊<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
您的访问请求被拒绝 403 Forbidden - ITeye技术社区
您的访问请求被拒绝
亲爱的会员,您的IP地址所在网段被ITeye拒绝服务,这可能是以下两种情况导致:
一、您所在的网段内有网络爬虫大量抓取ITeye网页,为保证其他人流畅的访问ITeye,该网段被ITeye拒绝
二、您通过某个代理服务器访问ITeye网站,该代理服务器被网络爬虫利用,大量抓取ITeye网页
请您点击按钮解除封锁&

我要回帖

更多关于 matlab 矩阵相乘 的文章

 

随机推荐