稀疏矩阵乘法的运算
scipy稀疏矩阵按行乘

scipy稀疏矩阵按行乘
稀疏矩阵按行乘是指使用Scipy库中的稀疏矩阵功能进行矩阵乘法运算时按行
进行操作。
在实际应用中,稀疏矩阵往往是非常大的矩阵,因此对于大规模稀疏矩阵的操作效率是非常重要的。
Scipy库提供了一系列的函数和方法来处理稀疏矩阵,其中包括按行乘法操作。
在Scipy库中,稀疏矩阵主要有三种类型:COO格式、CSR格式和CSC格式。
这些格式都有各自的优势和适用场景。
在进行稀疏矩阵按行乘的操作时,通常会选择CSR格式的稀疏矩阵,因为CSR格式在按行进行乘法操作时效率更高。
稀疏矩阵按行乘的操作可以通过矩阵乘法运算来实现。
对于两个稀疏矩阵A和B,可以使用稀疏矩阵乘法的方式来实现按行乘的操作。
具体步骤如下:
1. 将稀疏矩阵A和B转换为CSR格式。
2. 遍历稀疏矩阵A的每一行,将该行乘以稀疏矩阵B的对应列,得到乘积矩
阵的对应行。
3. 将乘积矩阵的对应行存储起来,最终得到稀疏矩阵按行乘的结果。
在实际应用中,稀疏矩阵按行乘的操作可以用于矩阵乘法运算、矩阵向量乘法
等问题的求解。
通过Scipy库提供的稀疏矩阵功能,可以高效地处理大规模稀疏矩
阵的按行乘操作,提高计算效率和节约存储空间。
总的来说,稀疏矩阵按行乘是一种重要的矩阵操作,通过Scipy库提供的稀疏
矩阵功能,可以方便高效地实现这种操作,应用于各种科学计算和工程问题的求解中。
Scipy的稀疏矩阵功能在处理稀疏矩阵的矩阵乘法等操作中具有很大的优势,
是矩阵运算的重要工具之一。
稀疏矩阵乘法 并行

稀疏矩阵乘法并行全文共四篇示例,供读者参考第一篇示例:稀疏矩阵乘法是一种重要的数值计算问题,它在很多领域都有着广泛的应用,比如图像处理、机器学习等。
由于稀疏矩阵的特性是大部分元素都是0,只有少量非零元素,所以传统的矩阵乘法算法在处理稀疏矩阵时会浪费大量的计算资源。
为了解决这个问题,人们提出了一种并行计算的方法,即利用多个处理器同时计算矩阵乘法,从而提高计算效率。
在并行计算中,稀疏矩阵乘法也有着自己的特点和挑战。
稀疏矩阵的非零元素分布在整个矩阵中,处理起来比较困难。
矩阵乘法的计算量随着非零元素的增加而增加,所以需要合理地分配计算资源和任务。
稀疏矩阵乘法的并行计算需要考虑通信开销和负载均衡,以充分利用多个处理器的计算能力。
为了解决上述问题,人们提出了一些并行的稀疏矩阵乘法算法。
其中比较有代表性的是基于CSR(Compressed Sparse Row)格式的算法。
CSR格式是一种压缩存储稀疏矩阵的方法,它将矩阵分成三部分:非零元素数组、列索引数组和行偏移数组。
基于CSR格式的算法在并行计算中能够有效地减少通信开销,提高计算效率。
还有一些其他的并行稀疏矩阵乘法算法,比如基于COO (Coordinate)格式、基于Ecoo(Ellpack-Chebyshev)格式等。
这些算法都有着自己的特点和适用场景,可以根据具体的问题选择合适的算法。
在并行计算中,负载均衡是一个非常重要的问题。
负载不均衡会导致一些处理器的计算资源被浪费,影响整体的计算效率。
为了解决负载均衡问题,人们提出了一些方法,比如动态任务分配、静态任务划分、自适应任务调度等。
这些方法能够根据任务的计算量和数据分布特点,合理地分配任务,从而提高计算效率。
除了负载均衡,通信开销也是一个需要考虑的重要问题。
在并行计算中,处理器之间需要进行通信,传递计算结果和数据,这会导致一定的开销。
为了减小通信开销,人们提出了一些方法,比如数据压缩、异步通信、消息合并等。
基于mpi实现稀疏矩阵的乘法

基于MPI实现稀疏矩阵的乘法1. 引言稀疏矩阵是指大部分元素为零的矩阵,与之相对应的是稠密矩阵,其中大部分元素非零。
由于稀疏矩阵中有大量的零元素,传统的矩阵乘法算法在计算稀疏矩阵乘法时效率较低。
为了提高计算效率,我们可以利用并行计算的思想,使用MPI (Message Passing Interface)来实现稀疏矩阵的乘法。
MPI是一种用于编写并行程序的标准通信库,它定义了一组函数和语义,用于在多个进程之间进行通信和同步操作。
通过将任务划分为多个进程,每个进程负责处理一部分数据,并通过消息传递进行通信和协调,可以实现并行计算。
本文将介绍如何使用MPI实现稀疏矩阵的乘法算法。
首先我们会介绍稀疏矩阵的表示方法和存储格式,然后详细说明基于MPI的稀疏矩阵乘法算法的实现过程。
2. 稀疏矩阵的表示和存储格式稀疏矩阵有多种表示方法,常用的有三元组表示法、行压缩存储(CSR)和列压缩存储(CSC)。
三元组表示法将稀疏矩阵中非零元素的行、列和值分别存储在三个数组中。
这种表示方法简单直观,但对于大型稀疏矩阵来说,空间效率较低。
行压缩存储(CSR)是一种常用的稀疏矩阵存储格式。
在CSR格式中,我们将稀疏矩阵拆分为三个数组:值数组(values)、列指针数组(col_indices)和行偏移量数组(row_offsets)。
其中,值数组存储非零元素的值,列指针数组存储非零元素所在的列索引,行偏移量数组记录每一行第一个非零元素在值数组和列指针数组中的索引。
通过这种方式,我们可以快速访问稀疏矩阵中的非零元素。
列压缩存储(CSC)与CSR类似,只是将列指针数组变为行指针数组,将行偏移量数组变为列偏移量数组。
CSC格式适合于按列访问稀疏矩阵。
在本文中,我们将使用CSR格式来表示稀疏矩阵,并基于该格式实现稀疏矩阵的乘法算法。
3. 基于MPI的稀疏矩阵乘法算法基于MPI的稀疏矩阵乘法算法可以分为以下几个步骤:1.初始化MPI环境:在开始进行并行计算之前,需要初始化MPI环境,获取进程数量和进程编号等信息。
?LeetCode刷题实战311:稀疏矩阵的乘法

LeetCode刷题实战311:稀疏矩阵的乘法算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试。
所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选!今天和大家聊的问题叫做稀疏矩阵的乘法,我们先来看题面:/problems/sparse-matrix-multiplication/Given two sparse matrices A and B, return the result of AB.You may assume that A's column number is equal to B's row number.给你两个稀疏矩阵 A 和 B,请你返回 AB 的结果。
你可以默认 A 的列数等于 B 的行数。
示例解题由于是稀疏数组可以只计算非零数字。
将A矩阵转存为hashmap,然后对每一个非零数遍历B的列数来更新它在ans矩阵里可以被用到的位置。
class Solution {public:vector<vector<int>> multiply(vector<vector<int>>& A, vector<vector<int>>& B) {int n = A.size(), m = A[0].size(), k = B[0].size();vector<vector<int>> res(n, vector<int>(k, 0));unordered_map<int, int> am;for (int i = 0; i < n; i ++)for (int j = 0; j < m; j ++){if (!A[i][j]) continue;int idx = i * m + j;am[idx] = A[i][j];}for (auto aij : am){int va = aij.second, aidx = aij.first, ai = aidx / m, aj = aidx % m;for (int j = 0; j < k; j ++){res[ai][j] += va * B[aj][j];}}return res;}};好了,今天的文章就到这里,如果觉得有所收获,请顺手点个在看或者转发吧,你们的支持是我最大的动力。
稀疏矩阵的运算

稀疏矩阵的运算稀疏矩阵的运算稀疏矩阵,顾名思义,就是矩阵中空值(0)的比例很大,而实际值(非0)的比例很小的矩阵。
它最大的特点就是,当矩阵的规模增大时,仍然可以保持较低的计算量。
在运算时,因为稀疏矩阵中的0值没有意义,所以对其做运算也没有意义。
所以,在运算中需要把稀疏矩阵转换成一维数组,即只保留其有意义的值。
下面介绍几种常用的稀疏矩阵运算技术。
1.索引表(Indextable)这是一种最简单的稀疏矩阵运算技术,在使用索引表时,需要用一个额外的一维数组来保存有意义的值的位置,而把矩阵本身变成一维数组,进行运算。
例如矩阵A:1 0 0 0 00 0 0 4 00 0 0 0 00 3 0 0 00 0 7 0 0这样的矩阵,可以使用一个一维数组来保存其有意义的值及其位置,例如:[1,(0,0); 4,(1,3); 3,(3,1); 7,(2,2)]这样,我们就可以用简单的一维数组代替复杂的二维矩阵,从而加快稀疏矩阵的运算。
2.矩阵向量乘法(Matrix-Vector Multiplication)这是一种最常用的稀疏矩阵运算技术,把一个大的稀疏矩阵A和一个向量(一维数组)V作乘法,得到一个新的向量C,即:C = A * V对于上面的实例,可以用以下方式求出C:C[0] = 1 * V[0] + 0 * V[1] + 0 * V[2] + 0 * V[3] + 0 * V[4] C[1] = 0 * V[0] + 0 * V[1] + 0 * V[2] + 4 * V[3] + 0 * V[4] C[2] = 0 * V[0] + 0 * V[1] + 0 * V[2] + 0 * V[3] + 7 * V[4] C[3] = 0 * V[0] + 3 * V[1] + 0 * V[2] + 0 * V[3] + 0 * V[4] 3.矩阵乘法(Matrix Multiplication)矩阵乘法也是一种常用的稀疏矩阵运算技术,把两个大的稀疏矩阵A和B相乘,得到一个新的稀疏矩阵C,即:C = A * B以上就是稀疏矩阵运算的一些常用技术,稀疏矩阵也可以用于解决很多复杂的运算问题,例如机器学习和深度学习等。
稀疏矩阵乘法

稀疏矩阵乘法给定两个 A 和 B,返回AB的结果。
您可以假设A的列数等于B的⾏数。
本参考程序来⾃九章算法,由 @Roger 提供。
题⽬解法:时间复杂度分析:假设矩阵A,B均为 n x n 的矩阵,矩阵A的稀疏系数为a,矩阵B的稀疏系数为b,a,b∈[0, 1],矩阵越稀疏,系数越⼩。
⽅法⼀:暴⼒,不考虑稀疏性Time (n^2 * (1 + n)) = O(n^2 + n^3)Space O(1)⽅法⼆:改进,仅考虑A的稀疏性Time O(n^2 * (1 + a * n) = O(n^2 + a * n^3)Space O(1)⽅法三(最优):进⼀步改进,考虑A与B的稀疏性Time O(n^2 * (1 + a * b * n)) = O(n^2 + a * b * n^3)Space O(b * n^2)⽅法四:另外⼀种思路,将矩阵A, B⾮0元素的坐标抽出,对⾮0元素进⾏运算和结果累加Time O(2 * n^2 + a * b * n^4) = O(n^2 + a * b * n^4)Space O(a * n^2 + b * n^2)解读:矩阵乘法的两种形式,假设 A(n, t) * B(t, m) = C(n, m)// 形式⼀:外层两个循环遍历C (常规解法)for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {for (int k = 0; k < t; k++) {C[i][j] += A[i][k] * B[k][j];}}}// 或者写成下⾯这样⼦for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {int sum = 0;for (int k = 0; k < t; k++) {sum += A[i][k] * B[k][j];}C[i][j] = sum;}}// 形式⼆:外层两个循环遍历Afor (int i = 0; i < n; i++) {for (int k = 0; k < t; k++) {for (int j = 0; j < m; j++) {C[i][j] += A[i][k] * B[k][j];}}}两种⽅法的区别代码上的区别(表象):调换了第⼆三层循环的顺序核⼼区别(内在):形式⼀以C为核⼼进⾏遍历,每个C[i][j]只会被计算⼀次,就是最终答案。
拓展阅读3——稀疏矩阵的相乘

稀疏矩阵的相乘*两个矩阵相乘的经典算法是大家所熟悉的,设Q=M×N其中,M 是m 1×n 1矩阵,N 是m 2×n 2矩阵。
当n 1=m 2时有:for (i=1;i<=m1;++i )for(j=1;j<=n2;++j){Q[i][j]=0;for(k=1;k<=n1;++k)Q[i][j]+=M[i][k]×N[k][j];}此算法的时间复杂度是O(m 1×n 1×n 2)。
当矩阵变成稀疏矩阵,并且用三元组表作存储结构时,上面这个算法就不能用了,下面我们讨论稀疏矩阵三元组表的相乘算法。
已知稀疏矩阵A(m 1× n 1)和B(m 2× n 2),求乘积C(m 1× n 2)。
稀疏矩阵A 、B 、C 及它们对应的三元组表A.data 、B.data 、C.data 如图1所示。
A=⎥⎥⎥⎦⎤⎢⎢⎢⎣⎡000203008005 B=⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎣⎡-01500720 C=⎥⎥⎥⎦⎤⎢⎢⎢⎣⎡-40150108 115148233312ij v 114523712221-v j i 42315221021811-v j i 图1 稀疏矩阵相乘图例由矩阵乘法规则知:C (i ,j )=A(i,1)×B(1,j)+A(i,2)×B(2,j)+…+A(i,n)×B(n,j)=)11(),(),(2,11n j m i j k B k i A n k ≤≤≤≤⨯∑=矩阵用二维数组表示时,在经典算法中,不论A(i,k)与B(k,j)的值是否为零,都要进行一次乘法运算,而在三元组表示的稀疏矩阵相乘时,只需从A.data 和B.data 中找到A.data 中列值与B.data 中行值相等的各对元素相乘并将结果累加即可。
为此需要在B.data 中找到矩阵B 第k 行中所有非零元素,跟矩阵转置改进算法相同的原理,我们引入num 和rpot 两个向量。
稀疏矩阵乘法的时间复杂度

稀疏矩阵乘法的时间复杂度稀疏矩阵乘法的时间复杂度,这话一说出来,可能有些朋友会皱眉头,觉得这又是个高深的数学问题。
但实际上,咱们今天就来聊聊这个看似复杂的事情,轻松点、幽默点,让大家都能明白。
咱们得搞清楚什么是稀疏矩阵。
简单来说,就是矩阵里有很多的零。
想象一下,你在看一张桌子,上面摆着很多碗,只有几个碗里有东西,其他的都是空的。
这样的矩阵就叫稀疏矩阵。
其实在很多实际应用中,稀疏矩阵的出现是非常常见的,特别是在图像处理、机器学习和数据科学中,真是频繁得让人惊叹。
咱们就要说说稀疏矩阵乘法。
说白了,就是把两个稀疏矩阵相乘。
这个过程其实可以看作是把两个“空碗”组合成一个新碗,看看能不能得到一些“有料”的东西。
由于很多位置上都是零,所以在计算的时候,咱们可以聪明点,干脆不去计算那些零的位置,省得浪费时间和精力,简直就是把“事半功倍”发挥到了极致。
这一招可不是什么秘笈,很多程序员和数学家都用得特别溜。
不过,时间复杂度是个什么鬼呢?简单来说,它就是描述算法运行时间的一个指标。
想象一下,咱们去市场买菜,时间复杂度就像是你去菜市场的路程,如果你走的路特别绕,那肯定花的时间就长;如果你选了一条最近的路,当然就能更快到达。
对于稀疏矩阵乘法来说,时间复杂度跟矩阵的稀疏程度和大小有很大关系。
一般来说,如果你有一个稀疏矩阵A和B,那么它们相乘的复杂度大致是O(NzA + NzB),Nz代表非零元素的数量。
别被这些符号吓到,通俗点说,就是看你非零元素有多少,越多计算的时间就越长。
再说个形象的例子。
想象你在一个派对上,跟一群朋友聊得火热,结果你发现只有几个人是你特别想交流的。
如果你一个一个去找他们,肯定费时费力。
但是如果你能知道他们在哪,直接冲过去,效率简直翻倍。
稀疏矩阵乘法就像这样,只找非零的元素,省去那些冗余的时间,简直太聪明了。
再来聊聊实际应用。
稀疏矩阵在机器学习中可是大显身手。
比如在推荐系统里,用户和物品的评分矩阵常常都是稀疏的,绝大多数用户根本没给某些物品打过分。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
课程设计任务书学生姓名:专业班级:指导教师:夏红霞工作单位:计算机科学与技术学院题目: 稀疏矩阵乘法的运算课程设计要求:1、熟练掌握基本的数据结构;2、熟练掌握各种算法;3、运用高级语言编写质量高、风格好的应用程序。
课程设计任务:1、系统应具备的功能:(1)设计稀疏矩阵的存储结构(2)建立稀疏矩阵(3)实现稀疏矩阵的乘法2、数据结构设计;3、主要算法设计;4、编程及上机实现;5、撰写课程设计报告,包括:(1)设计题目;(2)摘要和关键字;(3)正文,包括引言、需求分析、数据结构设计、算法设计、程序实现及测试、不足之处、设计体会等;(4)结束语;(5)参考文献。
时间安排:2010年7月5日-9日(第19周)7月5日查阅资料7月6日系统设计,数据结构设计,算法设计7月7日 -8日编程并上机调试7月9日撰写报告7月10日验收程序,提交设计报告书。
指导教师签名: 2010年7月4日系主任(或责任教师)签名: 2010年7月4日目录1.摘要 (1)2.关键字 (1)3.引言 (1)4. 问题描述 (1)5. 系统设计 (1)6. 数据结构 (3)7. 算法描述 (3)8. 测试结果与分析 (4)9. 源代码 (12)10. 总结 (29)11.参考文献 (29)稀疏矩阵乘法的运算1.摘要:在一些数值计算中,一些二维矩阵的乘法运算很常见,我们经常采用线性代数中的知识进行运算,然而对一些含有非零元很少的二维矩阵也采用相同的方法时,就会发现那样的方法不仅需要很多的空间来存储0,造成空间复杂度比较大,而且算法的时间复杂度也较大。
因此需要采取其他的方法来解决这个问题,由于0在乘法中其结果总是0,所以可以考虑采用三元组的方式去存储稀疏矩阵中的非零元,这样在计算过程中不仅需要的内存空间减少了,而且运算的速率也提高了。
2.关键字:稀疏矩阵乘法二维矩阵算法复杂度3.引言:随着科学技术的发展,人们对矩阵的运算的几率越来越大,特别是高新科技研究中对矩阵的运算更是常见。
但是如何高效的并占内存少的进行矩阵运算就是一个急需解决的问题。
本文主要对稀疏矩阵的存储以及稀疏矩阵的乘法运算进行了研究和探讨。
4.问题描述:在一些数值计算中,一些二维矩阵的乘法运算很常见,我们经常采用线性代数中的知识进行运算,然而对一些含有非零元很少的二维矩阵也采用相同的方法时,就会发现那样的方法不仅需要很多的空间来存储0,造成空间复杂度比较大,而且算法的时间复杂度也较大。
为了减少空间和时间复杂度,可以根据给定的二维数组的数据设计稀疏矩阵的存储结构,然后根据设计的稀疏矩阵存储结构建立一个稀疏矩阵,最后获得两个二维数组得到他们各自的稀疏矩阵,计算这两个稀疏矩阵的乘积。
5.系统设计:5.1 设计目标:通过一定的数据结构,存储含有少量数据的矩阵,把他们存入一个稀疏矩阵中,然后实现稀疏矩阵的乘法运算。
[基本要求]设计稀疏矩阵的存储结构;建立稀疏矩阵;实现稀疏矩阵的乘法5.2 系统实现的操作和功能:5.2.1初始化:初始化一些数据5.2.2获得数据:根据客户的要求可以采用人工输入和从文件中读取数据两种方式获得二维矩阵的中的数据。
然后根据相应的数据建立稀疏矩阵。
5.2.3检查数据的合法性:当这两个二维矩阵不满足矩阵相乘的条件时,系统将报错,并退出系统。
5.2.4稀疏矩阵的乘法:当两个二维矩阵合法时将对其进行乘法运算,然后将结果输出并按用户的要求保存到相应的文件中。
5.3设计思想:在操作的过程中采用三元组建立稀疏矩阵。
用户可以通过输入数据或者文件名以后,系统会自动建立一个三元组的稀疏矩阵,然后对其进行乘法运算。
在里面主要包含两个函数文件:获得数据并建立稀疏矩阵,对稀疏矩阵进行合法性的检查并进行乘法运算。
5.4系统模块划分:6.数据结构:采用结构体存储每行每列的元素:typedef struct DataNode {int row ;//存储所在二维矩阵的行数 int col ;//存储所在二维矩阵的列数稀疏矩阵乘法的运算获得数据并建立稀疏矩阵检查矩阵合法性并进行乘法运算输出结果并存到指定文件中数据初始化ElemType data;//存储row行col列的元素的值}DataNode;采用结构体存储稀疏二维数组:typedef struct SparseMatrix{DataType *matrix;//用数组存储非零元int row;//二维数组的行数int col;//二维数组的列数int *rpos;//每行第一个非零元在matrix中的位置int num;//非零元的个数int con;//指定常数};注:在第二个结构体中num和con这两个变量,在本此系统中con默认为0,num的功能是检验数据是否完整。
当二维数组中出现很多非零元素值一样的时候,也可以采用三元组的方法存储,只要让con等于那个非零元素值即可。
7.算法描述:本系统的主要算法为稀疏矩阵的乘法运算。
算法如下:Q初始化;if (Q是非零矩阵){//逐行求积for(arow=1;arow<=M.row;++arow){//处理M的每一行ctemp[]=0;//累加器清零计算Q中第arow行的积并存入ctemp[]中;将ctemp[]中的非零元压缩存储到Q.matrix中;}}8.测试结果与分析:测试1:两个文件数据完全正确Input the method of getting data(1 is from file,2 is from inputting):1 Input two names of the data file:data1.txt data2.txtRead the first file successfully!Read the second file successfully!The first matrix is:1 1 31 4 52 2 -13 1 2The second matrix is:1 2 22 1 13 1 -23 2 4The result is:3 0 3 21 2 62 1 -13 2 4Input one name of the data file:data5.txt测试2:一个文件数据完全正确,另一个文件数据不正确Input the method of getting data(1 is from file,2 is from inputting):1 Input two names of the data file:data1.txt data4.txtRead the first file successfully!The data is wrong!The first data is wrong!Please check it carefully,then input it again:1 2 2The data is wrong!The 4th data is wrong!Please check it carefully,then input it again:3 2 4Read the second file successfully!The first matrix is:1 1 31 4 52 2 -13 1 2The second matrix is:1 2 22 1 13 1 -23 2 4The result is:3 0 3 21 2 62 1 -13 2 4Input one name of the data file:data6.txt测试3:两个数据文件都错误Input the method of getting data(1 is from file,2 is from inputting):1 Input two names of the data file:data3.txt data4.txtThe data is wrong!The second data is wrong!Please check it carefully,then input it again:The data is wrong!The 4th data is wrong!Please check it carefully,then input it again: 3 1 2Read the first file successfully!The data is wrong!The first data is wrong!Please check it carefully,then input it again: 1 2 2The data is wrong!The 4th data is wrong!Please check it carefully,then input it again: 3 2 4Read the second file successfully!The first matrix is:1 1 31 4 52 2 -13 1 2The second matrix is:1 2 22 1 13 1 -23 2 4The result is:3 0 3 21 2 62 1 -1Input one name of the data file:data7.txt测试4:不符合矩阵乘法运算条件Input the method of getting data(1 is from file,2 is from inputting):1Input two names of the data file:data.txt data1.txtRead the first file successfully!Read the second file successfully!The first matrix is:1 2 121 3 93 1 -33 6 144 3 245 2 186 1 156 4 -7The second matrix is:1 1 31 4 52 2 -13 1 2The matrix multiply is illegal!测试5:输入数据完全正确Input the method of getting data(1 is from file,2 is from inputting):2Input the first matrix:With the order of a specified number of constant,specified constant and rows and columns number:4 0 3 4Enter each element of a two-dimensional arrays in the number of rows and columns and the location of the element value:1 1 31 4 52 2 -13 1 2Input the second matrix:With the order of a specified number of constant,specified constant and rows and columns number:4 0 4 2Enter each element of a two-dimensional arrays in the number of rows and columns and the location of the element value:1 2 22 1 13 1 -23 2 4The first matrix is:1 1 31 4 52 2 -13 1 2The second matrix is:1 2 22 1 13 1 -23 2 4The result is:3 0 3 22 1 -13 2 4Input one name of the data file:data8.txt测试6:输入数据时有错误Input the method of getting data(1 is from file,2 is from inputting):2Input the first matrix:With the order of a specified number of constant,specified constant and rows and columns number:4 0 3 4Enter each element of a two-dimensional arrays in the number of rows and columns and the location of the element value:1 1 31 4 52 2 -13 1 2Input the second matrix:With the order of a specified number of constant,specified constant and rows and columns number:4 0 4 2Enter each element of a two-dimensional arrays in the number of rows and columns and the location of the element value:1 2 22 1 13 1 -23 3 4The data is wrong!Input again:3 2 4The first matrix is:1 4 52 2 -13 1 2The second matrix is:1 2 22 1 13 1 -23 2 4The result is:3 0 3 21 2 62 1 -13 2 4Input one name of the data file:data9.txt测试7:输入数据不满足矩阵相乘的条件Input the method of getting data(1 is from file,2 is from inputting):2Input the first matrix:With the order of a specified number of constant,specified constant and rows and columns number:4 0 3 4Enter each element of a two-dimensional arrays in the number of rows and columns and the location of the element value:1 1 31 4 52 2 -13 1 2Input the second matrix:With the order of a specified number of constant,specified constant and rows and columns number:8 0 6 7Enter each element of a two-dimensional arrays in the number of rows and columns and the location of the element value:1 2 121 3 93 1 -33 6 144 3 245 2 186 1 156 4 -7The first matrix is:1 1 31 4 52 2 -13 1 2The second matrix is:1 2 121 3 93 1 -33 6 144 3 245 2 186 1 156 4 -7The matrix multiply is illegal!9.源代码:----------------------------Makefile------------------------------- CC=gccCLFAGS=-g -Wall -O2 -lmOBJECTS=main.o getdata.o init.o matrixmulti.o print.o main:$(OBJECTS)$(CC) $(CLFAGS) -o $@ $^.c.o:$(CC) -c $<.PHONY:cleanclean:rm -f $(OBJECTS) main-------------------------------main.c------------------------------- /*---------------------------基本信息------------------------------- 作者:方金卫日期:2010年7月8日系统名称:稀疏矩阵乘法系统功能:稀疏矩阵的乘法-------------------------------------------------------------------*/ #include<stdio.h>#include"data.h"int main(void){SparseMatrix sparsematrix1;SparseMatrix sparsematrix2;SparseMatrix sparsematrix3;char filename1[32];char filename2[32];char filename3[32];int tag;int sign;printf("Input the method of getting data(1 is from file,2 is from inputting):"); scanf("%d",&tag);InitSparseMatrix(&sparsematrix1);InitSparseMatrix(&sparsematrix2);/*初始化*//*获取数据*/if(tag==1){printf("Input two names of the data file:");scanf("%s %s",filename1,filename2);sign=GetData(&sparsematrix1,filename1);if(sign==1)printf("Read the first file successfully!\n");if(sign==-1)return 0;sign=GetData(&sparsematrix2,filename2);if(sign==1)printf("Read the second file successfully!\n");if(sign==-1)return 0;if(tag==2){printf("Input the first matrix:\n");InputData(&sparsematrix1);printf("Input the second matrix:\n");InputData(&sparsematrix2);}/*输出稀疏矩阵*/printf("The first matrix is:\n");PrintMatrix(sparsematrix1);printf("The second matrix is:\n");PrintMatrix(sparsematrix1);sparsematrix3=MatrixMulti(sparsematrix1,sparsematrix2);/*稀疏矩阵的乘法运算*//*输出结果*/printf("The result is:\n");printf("%d %d %d %d\n",sparsematrix3.num,sparsematrix3.con,sparsematrix3.row,sp arsematrix3.col);PrintMatrix(sparsematrix3);/*输出到指定的文件中*/printf("Input one name of the data file:");scanf("%s",filename3);PrintToFile(sparsematrix3,filename3);return 1;}--------------------------------data.h------------------------------#ifndef DATA_H_#define DATA_H_#include<stdio.h>#include<stdlib.h>#define INT#ifdef FLOATtypedef float DataType;#endif#ifdef INTtypedef int DataType;#endif#define MAXSIZE 30#define INITMAX 65535typedef int Status;/*-----------------定义数据结构-----------------*//*定义数据节点:每个节点存放所在的行数与列数,以及该处的值*/ typedef struct DataNode{int row,col;/*该元素所在的行数和列数*/DataType data;}DataNode;/*数组的行列数*/typedef struct SparseMatrix{int num;/*非指定元素的个数*/int con;/*指定常数*/int row,col;/*矩阵的行数和列数*/DataNode *matrix;int *rpos;/*各行第一个非指定元素的位置表,若不含某行时其值为-1*/}SparseMatrix;/*-----------------一些基本操作-----------------*//*In the getdata.c file*/Status InputData(SparseMatrix *sparsematrix);/*人工输入数据*/Status GetData(SparseMatrix *sparsematrix,char filename[]);/*从指定的文件中获得数据*//*In the init.c file*/Status InitSparseMatrix(SparseMatrix *sparsematrix);/*初始化稀疏矩阵的数据*//*In the matrixmulti.c file*/SparseMatrix MatrixMulti(SparseMatrix sparsematrix1,SparseMatrix sparsematrix2);/*稀疏矩阵相乘*//*In the print.c file*/void PrintMatrix(SparseMatrix sparsematrix);/*输出系数矩阵里的值*/void PrintToFile(SparseMatrix sparsematrix,char filename[]);/*将矩阵输入指定的文件中*/#endif--------------------------------init.c------------------------------#include"data.h"/*初始化数据*/Status InitSparseMatrix(SparseMatrix *sparsematrix){int i;(*sparsematrix).num=0;(*sparsematrix).con=0;(*sparsematrix).row=0;(*sparsematrix).col=0;(*sparsematrix).matrix=(DataNode*)malloc(sizeof(DataNode));if(!(*sparsematrix).matrix){printf("Memory allocation failed in init.c!\n");exit(1);}(*sparsematrix).matrix=NULL;(*sparsematrix).rpos=(int *)malloc(sizeof(int));if(!(*sparsematrix).rpos){printf("Memory allocation failed in init.c!\n");exit(1);}(*sparsematrix).rpos=NULL;return 1;}-----------------------------getdata.c-------------------------------#include"data.h"/*-----------------------检验数据的合法性--------------------------*/Status IsRight(SparseMatrix sparsematrix,int i){if(sparsematrix.matrix[i].row>sparsematrix.row||sparsematrix.matrix[i].col>sparsemat rix.col){printf("The data is wrong!\n");return 0;}return 1;}/*---------------------从文件中读取数据-------------------------*/Status GetData(SparseMatrix *sparsematrix,char filename[]){FILE *fp;int i;int *count;/*辅助确定每行第一个元素的位置*/InitSparseMatrix(sparsematrix);if((fp=fopen(filename,"r+"))==NULL){printf("Can't open this file!\n");exit(1);}/*分别获得二维矩阵非指定常数的个数,指定常数,以及它的行数和列数*/ fscanf(fp,"%d%d%d%d",&(*sparsematrix).num,&(*sparsematrix).con,&(*sparsematr ix).row,&(*sparsematrix).col);(*sparsematrix).matrix=(DataNode*)malloc(((*sparsematrix).num+1)*sizeof(DataNo de));if(!(*sparsematrix).matrix){printf("Memory allocation failed in getdata.c!\n");exit(1);}(*sparsematrix).rpos=(int *)malloc(((*sparsematrix).row+1)*sizeof(int));if(!(*sparsematrix).rpos){printf("Memory allocation failed in getdata.c!\n");exit(1);}count=(int *)malloc(((*sparsematrix).row+1)*sizeof(int));if(!count){printf("Memory allocation failed in getdata.c!\n");exit(1);}for(i=0;i<=(*sparsematrix).row;++i)/*初始化数组*/{(*sparsematrix).rpos[i]=0;count[i]=0;}/*0号单元都不用*/for(i=1;i<=(*sparsematrix).num&&!feof(fp);++i){fscanf(fp,"%d",&(*sparsematrix).matrix[i].row);fscanf(fp,"%d",&(*sparsematrix).matrix[i].col);++count[(*sparsematrix).matrix[i].row];/*统计每行非零元素个数*/ #ifdef FLOATfscanf(fp,"%f",&(*sparsematrix).matrix[i].data);#endif#ifdef INTfscanf(fp,"%d",&(*sparsematrix).matrix[i].data);#endifwhile(IsRight(*sparsematrix,i)==0)/*检验数据的合法性*/{if(i==1)printf("The first data is wrong!\n");else if(i==2)printf("The second data is wrong!\n");else if(i==3)printf("The third data is wrong!\n");elseprintf("The %dth data is wrong!\n",i);printf("Please check it carefully,then input it again:\n");--count[(*sparsematrix).matrix[i].row];/*第row的非指定常数的个数减一*/scanf("%d",&(*sparsematrix).matrix[i].row);scanf("%d",&(*sparsematrix).matrix[i].col);++count[(*sparsematrix).matrix[i].row];/*统计每行非零元素个数*/ #ifdef FLOATscanf("%f",&(*sparsematrix).matrix[i].data);#endif#ifdef INTscanf("%d",&(*sparsematrix).matrix[i].data);#endif}}if(i!=(*sparsematrix).num+1){printf("Get data wrong!\n");return -1;}/*确定每行第一个非指定常数在rpos数组的位置*/for(i=1;i<=(*sparsematrix).row;++i){(*sparsematrix).rpos[i]=count[i-1]+1;count[i]+=count[i-1];}fclose(fp);return 1;}/*----------------------通过终端人工输入数据---------------------*/Status InputData(SparseMatrix *sparsematrix){int i;int *count;InitSparseMatrix(sparsematrix);printf("With the order of a specified number of constant,specified constant and rows and columns number:\n");scanf("%d %d %d %d",&(*sparsematrix).num,&(*sparsematrix).con,&(*sparsematri x).row,&(*sparsematrix).col);(*sparsematrix).matrix=(DataNode*)malloc(((*sparsematrix).num+1)*sizeof(DataNo de));if(!(*sparsematrix).matrix){printf("Memory allocation failed in getdata.c!\n");exit(1);}(*sparsematrix).rpos=(int *)malloc(((*sparsematrix).row+1)*sizeof(int));if(!(*sparsematrix).rpos){printf("Memory allocation failed in getdata.c!\n");exit(1);}count=(int *)malloc(((*sparsematrix).row+1)*sizeof(int));if(!count){printf("Memory allocation failed in getdata.c!\n");exit(1);}for(i=0;i<=(*sparsematrix).row;++i){(*sparsematrix).rpos[i]=0;count[i]=0;}printf("Enter each element of a two-dimensional arrays in the number of rows and columns and the location of the element value:\n");for(i=1;i<=(*sparsematrix).num;++i){scanf("%d",&(*sparsematrix).matrix[i].row);scanf("%d",&(*sparsematrix).matrix[i].col);++count[(*sparsematrix).matrix[i].row];/*统计每行非零元素个数*/#ifdef FLOATscanf("%f",&(*sparsematrix).matrix[i].data);#endif#ifdef INTscanf("%d",&(*sparsematrix).matrix[i].data);#endifif(IsRight(*sparsematrix,i)==0)/*检验数据的合法性*/{printf("Input again:");--i;}}/*确定每行第一个非指定常数在rpos数组的位置*/for(i=1;i<=(*sparsematrix).row;++i){(*sparsematrix).rpos[i]=count[i-1]+1;count[i]+=count[i-1];}return 1;}---------------------------matrixmulti.c-----------------------------#include"data.h"/*两个稀疏矩阵相乘*/SparseMatrix MatrixMulti(SparseMatrix sparsematrix1,SparseMatrix sparsematrix2) {SparseMatrix sparsematrix3;int arow,ccol,brow,temp,tp,temp1,temp2;DataType ctemp[MAXSIZE+1]={};int i;if(sparsematrix1.col!=sparsematrix2.row){printf("The matrix multiply is illegal!\n");exit(1);}InitSparseMatrix(&sparsematrix3);/*结果矩阵的初始化*/sparsematrix3.row=sparsematrix1.row;sparsematrix3.col=sparsematrix2.col;sparsematrix3.num=0;/*为数组rpos分配空间*/sparsematrix3.rpos=(int *)malloc(sparsematrix3.row*sizeof(int));if(!sparsematrix3.rpos){printf("Memory allocation failed!\n");exit(1) ;}sparsematrix3.matrix=(DataNode*)malloc(sparsematrix3.row*sparsematrix3.col*sizeof(DataNode));if(!sparsematrix3.matrix){printf("Memory allocation failed!\n");exit(1);}if(!sparsematrix3.rpos){printf("Memory allocation failed!\n");exit(1);}if(sparsematrix3.col>MAXSIZE){printf("The MAXSIZE is defined smaller,please define it again!\n");exit(1);}if(sparsematrix1.num*sparsematrix2.num!=0)/*非零矩阵*/ {for(arow=1;arow<=sparsematrix1.row;++arow)/*处理第一个矩阵的每一行*/{for(i=0;i<=MAXSIZE;++i) /*当前行各元素累加器清零*/ctemp[i]=0;sparsematrix3.rpos[arow]=sparsematrix3.num+1;/*统计每行第一个非指定元素的位置*/if(arow<sparsematrix1.row) tp=sparsematrix1.rpos[arow+1];else tp=sparsematrix1.num+1;for(temp=sparsematrix1.rpos[arow];temp<tp;++temp){/*对当前行中每一个非零元*/brow=sparsematrix1.matrix[temp].col;/*找到对应元在第二个矩阵对应的行号*/if(brow<sparsematrix2.row)temp1=sparsematrix2.rpos[brow+1];else temp1=sparsematrix2.num+1;for(temp2=sparsematrix2.rpos[brow];temp2<temp1;++temp2){ccol=sparsematrix2.matrix[temp2].col;/*乘积元素结果矩阵中的列号*/ctemp[ccol]+=sparsematrix1.matrix[temp].data*sparsematrix2.matrix[temp2].data;}}for(ccol=1;ccol<=sparsematrix3.col;++ccol)/*压缩存储该行所有非指定常数*/if(ctemp[ccol]){if(++sparsematrix3.num>MAXSIZE) return ;sparsematrix3.matrix[sparsematrix3.num].row=arow;sparsematrix3.matrix[sparsematrix3.num].col=ccol;sparsematrix3.matrix[sparsematrix3.num].data=ctemp[ccol];}}}return sparsematrix3;}-----------------------------print.c-----------------------------#include"data.h"/*输出稀疏矩阵*/void PrintMatrix(SparseMatrix sparsematrix){int i;if(sparsematrix.num==0){printf("The sparse matrix is empty!\n");return ;}for(i=1;i<=sparsematrix.num;++i){#ifdef FLOATprintf("%d %d %f\n",sparsematrix.matrix[i].row,sparsematrix.matrix[i].col,sparsematr ix.matrix[i].data);#endif#ifdef INTprintf("%d %d %d\n",sparsematrix.matrix[i].row,sparsematrix.matrix[i].col,sparsemat rix.matrix[i].data);#endif}}/*输出稀疏矩阵到指定的文件里*/void PrintToFile(SparseMatrix sparsematrix,char filename[]){FILE *fp;int i;if((fp=fopen(filename,"w"))==NULL){printf("Open this file errror!\n");return ;}fprintf(fp,"%d %d %d %d\n",sparsematrix.num,sparsematrix.con,sparsematrix.row,sp arsematrix.col);for(i=1;i<=sparsematrix.num;++i){fprintf(fp,"%d ",sparsematrix.matrix[i].row);fprintf(fp,"%d ",sparsematrix.matrix[i].col);fprintf(fp,"%d",sparsematrix.matrix[i].data);fprintf(fp,"\n");}fclose(fp);}10.总结:这个系统的主要功能是计算两个稀疏矩阵的乘法运算,本系统可以采用人工输入和读取文件获得数据,在运算的过程中对数据的合法性进行了检查,以及两个矩阵是否满足进行乘法运算的条件,这保证了系统的健壮性。