当前位置:网站首页>2.C语言矩阵乘法
2.C语言矩阵乘法
2022-07-06 09:19:00 【是王久久阿】
目录
1.原理
左乘和右乘
在线性代数中,矩阵左乘和矩阵右乘是不一样的。
例如:现有矩阵A: ,矩阵B:
。
AB为矩阵B左乘矩阵A:
BA为矩阵B右乘矩阵A:
通过计算发现:左乘和右乘的结果是完全不同的,所以在进行矩阵乘法时,需分清左乘和右乘。
乘法原理
矩阵乘法需要满足的条件:左侧矩阵的列数=右侧矩阵的行数。
结果矩阵的行和列:行数=左侧矩阵的行数,列数=右侧矩阵的列数。
矩阵的相乘过程:
以AB为例:
- A矩阵的第一行中的元素和B矩阵第一列中的元素对应相乘再相加,结果放在第一行第一列中;
- A矩阵的第一行中的元素和B矩阵第二列中的元素对应相乘再相加,结果放在第一行第二列中;
- A矩阵的第一行中的元素和B矩阵第三列中的元素对应相乘再相加,结果放在第一行第三列中;
- ......
- A矩阵的第三行中的元素和B矩阵第三列中的元素对应相乘再相加,结果放在第三行第三列中;
最后的结果为:
2.C语言编写矩阵乘法函数
编写函数(数组形式和指针形式)
矩阵虽然有左乘和右乘之分,但是只要更改传入参数的位置,即可实现左乘和右乘。
核心思想:
- 利用二维数组将矩阵中的数存放起来,用define定义行和列的数值,方便代码的更改。
- 定义一个矩阵左乘函数Matrix_left_mul,将矩阵以及矩阵的行列长度传给函数。
- 利用3个for循环遍历完成计算。
传参的时候可以用数组的形式传,也可以用指针的形式传,二者本质都一样。两种方法都会进行介绍。
1、我们创建两个数组arr1和arr2来存放两个矩阵
(在平时创建二维数组时,不能省略列,可以省略行;但是在矩阵乘法中,行和列的信息都要有)
//左矩阵的行和列
#define COL1 4
#define ROW1 3
//右矩阵的行和列
#define ROW2 4
#define COL2 3
double arr1[ROW1][COL1] = { 1,2,3,4,5,6,7,8,9,10,11,12};
double arr2[ROW2][COL2] = { 12,11,10,9,8,7,6,5,4,3,2,1};
2、传参以及判断矩阵相称的条件是否成立
利用assert断言条件是否成立,如果不成立系统会提示报错,assert需要包含头文件<assert.h>。
因为数组传参传的是地址,所以函数的类型设置为void即可。
如果不进行判断,传入错误的参数后,二维数组的访问会溢出,返回一个随机数。
数组形式:
void Matrix_left_mul(double arr1[][COL1], double arr2[][COL2], double arr3[][COL2],int row1,int row2,int col1,int col2)
{
assert(col1 == row2);//判定左列是否等于右行,需包含头文件
}
指针形式:
void Matrix_left_mul(double(*arr1)[COL1], double (*arr2)[COL2], double(*arr3)[COL2], int row1, int row2, int col1, int col2)
{
assert(col1 == row2);//判定左列是否等于右行,assert需包含头文件
}
3、for循环遍历计算
创建三个for循环:
- 第一个for循环(i):循环左矩阵的i行
- 第二个for循环(j):循环右矩阵的j列
- 第三个for循环(k):逐个循环左行k元素×右列k元素,将其结果累加
数组形式:
int i = 0;//行
int j = 0;//列
int k = 0;//行列中,第k个元素相乘
for (i = 0; i < row1; i++)//从第i行开始
{
for (j = 0; j < col2; j++)//从第j列开始
{
for (k = 0; k < col1; k++)//i行元素和j列元素相乘,结果累加
{
arr3[i][j] += arr1[i][k] * arr2[k][j];
}
}
}
指针形式:
void Matrix_left_mul(double(*arr1)[COL1], double (*arr2)[COL2], double(*arr3)[COL2], int row1, int row2, int col1, int col2)
{
assert(col1 == row2);//判定左列是否等于右行,assert需包含头文件
int i = 0;//行
int j = 0;//列
int k = 0;//行列中,第k个元素相乘
for (i = 0; i < row1; i++)//从第i行开始
{
for (j = 0; j < col2; j++)//从第j列开始
{
for (k = 0; k < col1; k++)//i行元素和j列元素相乘,结果累加
{
*(* (arr3 + i)+j) += *(*(arr1 + i) + k) * *(*(arr2 +k) + j);
}
}
}
}
用define定义常量的优点就是灵活,方便使用,后续只需要更改输入矩阵的相关参数即可进行运算。
测试
在VS中,F10进入调试模式,监视arr1,arr2,arr3数组。这里为了监视方便,我们暂时将数组改成整型,数组中的参数都是整数。
结果完全正确,如果不放心还可以多试验几组数据。
3.完整代码
数组形式:
#include<stdio.h>
#include<assert.h>
//左矩阵的行和列
#define COL1 4
#define ROW1 3
//右矩阵的行和列
#define ROW2 4
#define COL2 3
void Matrix_left_mul(double arr1[][COL1], double arr2[][COL2], double arr3[][COL2],int row1,int row2,int col1,int col2)
{
assert(col1 == row2);//判定左列是否等于右行,assert需包含头文件
int i = 0;//行
int j = 0;//列
int k = 0;//行列中,第k个元素相乘
for (i = 0; i < row1; i++)//从第i行开始
{
for (j = 0; j < col2; j++)//从第j列开始
{
for (k = 0; k < col1; k++)//i行元素和j列元素相乘,结果累加
{
arr3[i][j] += arr1[i][k] * arr2[k][j];
}
}
}
}
int main()
{
double arr1[ROW1][COL1] = { 1,2,3,4,5,6,7,8,9,10,11,12};
double arr2[ROW2][COL2] = { 12,11,10,9,8,7,6,5,4,3,2,1 };
double arr3[ROW1][COL2]={0};//结果矩阵的行等于左矩阵的行,列等于右矩阵的列
Matrix_left_mul(arr1, arr2, arr3,ROW1,ROW2,COL1,COL2);
return 0;
}
指针形式
#include<stdio.h>
#include<assert.h>
//左矩阵的行和列
#define COL1 4
#define ROW1 3
//右矩阵的行和列
#define ROW2 4
#define COL2 3
void Matrix_left_mul(double(*arr1)[COL1], double (*arr2)[COL2], double(*arr3)[COL2], int row1, int row2, int col1, int col2)
{
assert(col1 == row2);//判定左列是否等于右行,assert需包含头文件
int i = 0;//行
int j = 0;//列
int k = 0;//行列中,第k个元素相乘
for (i = 0; i < row1; i++)//从第i行开始
{
for (j = 0; j < col2; j++)//从第j列开始
{
for (k = 0; k < col1; k++)//i行元素和j列元素相乘,结果累加
{
*(* (arr3 + i)+j) += *(*(arr1 + i) + k) * *(*(arr2 +k) + j);
}
}
}
}
int main()
{
double arr1[ROW1][COL1] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
double arr2[ROW2][COL2] = { 12,11,10,9,8,7,6,5,4,3,2,1 };
double arr3[ROW1][COL2] = { 0 };//结果矩阵的行等于左矩阵的行,列等于右矩阵的列
Matrix_left_mul(arr1, arr2, arr3, ROW1, ROW2, COL1, COL2);
return 0;
}
边栏推荐
- 167. Sum of two numbers II - input ordered array - Double pointers
- 4.30 dynamic memory allocation notes
- Network layer 7 protocol
- String类
- 如何保障 MySQL 和 Redis 的数据一致性?
- Alibaba cloud microservices (I) service registry Nacos, rest template and feign client
- Employment of cashier [differential constraint]
- 继承和多态(上)
- Several high-frequency JVM interview questions
- Record: newinstance() obsolete replacement method
猜你喜欢
TYUT太原理工大学2022“mao gai”必背
E-R graph to relational model of the 2022 database of tyut Taiyuan University of Technology
西安电子科技大学22学年上学期《信号与系统》试题及答案
最新坦克大战2022-全程开发笔记-2
MPLS experiment
Alibaba cloud microservices (I) service registry Nacos, rest template and feign client
几道高频的JVM面试题
2022 National Games RE1 baby_ tree
系统设计学习(三)Design Amazon‘s sales rank by category feature
Inheritance and polymorphism (I)
随机推荐
阿里云微服务(三)Sentinel开源流控熔断降级组件
Questions and answers of "basic experiment" in the first semester of the 22nd academic year of Xi'an University of Electronic Science and technology
阿里云微服务(一)服务注册中心Nacos以及REST Template和Feign Client
MYSQL索引钟B-TREE ,B+TREE ,HASH索引之间的区别和应用场景
Interview Essentials: talk about the various implementations of distributed locks!
Arduino+ds18b20 temperature sensor (buzzer alarm) +lcd1602 display (IIC drive)
Error: symbol not found
Share a website to improve your Aesthetics
TYUT太原理工大学2022数据库大题之E-R图转关系模式
Application architecture of large live broadcast platform
Solution: warning:tensorflow:gradients do not exist for variables ['deny_1/kernel:0', 'deny_1/bias:0',
10 minutes pour maîtriser complètement la rupture du cache, la pénétration du cache, l'avalanche du cache
What are the advantages of using SQL in Excel VBA
Record: Navicat premium can't connect to MySQL for the first time
TYUT太原理工大学2022数据库题库选择题总结
Common method signatures and meanings of Iterable, collection and list
2022 National Games RE1 baby_ tree
Rt-ppp test using rtknavi
MPLS experiment
Record: I accidentally wrote a recursion next time