Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.10)

project (main)

set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED True)


set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

aux_source_directory(src SRC_LIST)

include_directories(inc)

add_executable (main ${SRC_LIST})
161 changes: 95 additions & 66 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,66 +1,95 @@
# algebra
硬件技术团队编程基础作业
## 课件资料 | Reference
* [课程PPT](https://tannin-1316822731.cos.ap-nanjing.myqcloud.com/2025-04-19-2025%E7%A1%AC%E4%BB%B6%E7%AC%AC%E4%B8%80%E6%AC%A1%E5%86%85%E8%AE%AD.pdf)
* [VSCode的C/C++环境配置教程](https://www.bilibili.com/video/BV1UZ421e7ty/?share_source=copy_web&vd_source=d82c2ec75577b6834f9f580f066180c1)
* [Git使用教程](https://www.bilibili.com/video/BV1og4y1u7XU/?share_source=copy_web&vd_source=d82c2ec75577b6834f9f580f066180c1)
## 预修要求|Requirements
修读过《C程序设计基础》、《线性代数》以及X·Lab硬件技术团队编程基础课程或其对应的高阶课程。
## 说明|Explainations
本题目的难度对于初学者而言相对较高,主要考察了基础的数学能力、通过编程解决问题的能力以及工程管理、CMake、git等综合能力。该作业的最终得分仅作参考,同学们可根据自己的能力来决定实现哪些函数。
## 题目背景|Background
《线性代数》作为浙江大学工科多数专业必修的数学基础课程,对于其掌握是至关重要的,后续各大专业的专业课程也都离不开线性代数。然而,在后续的专业课程学习中,我们往往只需要计算一些矩阵的数值解,这个过程如果用手去计算的话是十分痛苦的。秉承着“我都学编程了就不要自己做一些无意义的事情”的原则,我们决定实现一个线性代数计算库,来辅助我们进行运算。
> 当然,如MATLAB、Python等高级编程语言已经可以做到这类事情,且做得更好,但这并不妨碍我们通过这样一种方式来锻炼自己的C语言编程能力。
## 题目介绍|Introduction
本仓库给出了我们在内训中提到的工程模板,同学们要做的任务如下:
1. 自学git,注册GitHub账号,将本仓库在自己的GitHub账户下Fork一份(注意是Fork,禁止直接clone本仓库到本地,否则你将无法完成后续提交),并按照`yourname_hw1`的格式更改仓库名称(在仓库中的Settings处可修改,记得不要用中文,仓库权限为public,如涉及到隐私保护,可设为private,但要将`tanninrachel@yinlin.wiki`这个账户设置为协作者)。
2. 将你的仓库clone到本地。
3. 按照内训所讲的工程模板补充所缺的文件夹。
4. 根据`inc/algebra.h`中的注释和预定义,在`src/algebra.c`中实现对应的函数。
5. 根据内训所讲,自行编写`CMakeLists.txt`文件,使你的工程能够在本地成功编译运行。
6. 自学Markdown,修改`README.md`文件,需要包含你的实现思路(大致描述即可)以及本地运行截图。
7. 将你的修改提交到远程仓库,并将仓库链接提交(提交方式见下文)。
## 思路参考|Thinking
见`doc`文件夹。
## 交互格式|Format
在本题目中,`main.c`文件已给出,不需要同学们自己实现,也请不要更改这个文件,否则可能出现判题错误。
### 输入格式
本题目采用帧判定的思路进行,每一帧的第一行指令代码,`+`、`-`、`*`、`.`、`t`、`d`、`i`、`r`、`j`分别测试`add_matrix`、`sub_matrix`、`mul_matrix`、`scale_matrix`、`transpose_matrix`、`det_matrix`、`inv_matrix`、`rank_matrix`、`trace_matrix`函数,`q`表示退出。

接下来的一行输入矩阵 $\mathbf{A}$ 的行数 $m$ 和列数 $n$ ,在接下来的 $m$ 行中输入 $n$ 个双精度浮点数,以空格分开。
对于二元运算函数的测试,需要再按照上述过程输入矩阵 $\textbf{B}$ 。

可能的一次运行输入如下:
```
+
2 2
1.1 1.3
2.4 3.7
2 2
3.1 4.3
5.1 7.1
+
2 2
1.1 1.2
2.4 3.5
2 3
1 2 2.1
3 2 3.3
q
```
### 输出格式
在每一帧中,依次根据输入的指令代码运行对应的函数,并给出函数的输出与标准值比对。上述输入的正确输出如下:
```
4.20 5.60
7.50 10.80
Error: Matrix a and b must have the same rows and cols.
```
## 评分标准|Standard
* 成功运行:+25分
* `add_matrix`、`sub_matrix`、`mul_matrix`、`scale_matrix`、`transpose_matrix`、`trace_matrix`功能正常每个+5分
* `det_matrix`、`inv_matrix`、`rank_matrix`功能正常共+10分(此处为附加题,有一定难度,可选做)
> 为了保证题目难度,每个函数具体的评分标准不予公布。
## 提交方式|Submit
将你的每个函数的测试运行结果以截图的形式放在你仓库的`README.md`文件中(请注意Markdown中图片的引用要包含源文件)。并将你的最终代码仓库链接(在浏览器上的那个,不要带有`.git`的)填写如下问卷发送:

![](https://tannin-1316822731.cos.ap-nanjing.myqcloud.com/2025-04-19-%E7%AC%AC%E4%B8%80%E6%AC%A1%E5%86%85%E8%AE%AD%E4%BD%9C%E4%B8%9A%E6%8F%90%E4%BA%A4.png)
# 实现思路及运行结果
## 创建矩阵
create_matrix 函数创建指定列数和行数的元素均为0的矩阵
## 矩阵的九项基本运算
### 加法运算
* 函数:add_matrix。
* 首先判断两个函数的行数和列数是否相等,若不相等,无法进行加法运算,输出“Error: Matrix a and b must have the same rows and cols.“并返回一个空矩阵。
* 若相同,则可以进行加法运算,新矩阵的元素等于对应行列的元素相加。
* 运行截图:![加法运行](https://img.picui.cn/free/2025/05/01/68134f2c207f9.png)
### 减法运算
* 函数:sub_matrix。
* 首先判断两个函数的行数和列数是否相等,若不相等,无法进行减法运算,输出“Error: Matrix a and b must have the same rows and cols.”并返回一个空矩阵
* 若相同,则可以进行减法运算,新矩阵的元素等于对应行列的元素相减。
* 运行截图:![减法运行](https://img.picui.cn/free/2025/05/01/681365664f96d.png)
### 乘法运算
* 函数 :mul_matrix。
* 若第一个矩阵的列和第二个矩阵的行不相等,无法进行乘法运算
* 若相同,则新矩阵的元素等于第一个矩阵该行元素与第二个矩阵该列元素一一相乘后之和。
* 运行截图:![乘法运行](https://img.picui.cn/free/2025/05/01/681369d4c2b50.png)
### 数乘运算
* 函数:scale_matrix.
* 新矩阵元素即原矩阵对应元素乘常数k
* 运行截图:![数乘运行](https://img.picui.cn/free/2025/05/01/68136cdc4b8d0.png)
### 转置运算
* 函数: transpose_matrix。
* 新矩阵元素即原矩阵元素行列互换。
* 运行截图:![转置运行](https://img.picui.cn/free/2025/05/01/68136d79c83c7.png)
### 行列式运算
* 函数:det_matrix。
* 若不是方阵,无法进行行列式计算。
* 行列式的计算通过将行列式按第一行展开来计算,运算通过递归实现。首先需要创建一个计算行列式的代数余子式的函数。
* 对于一个 $n \times n$ 的方阵 $\textbf{A}$ ,由Laplace定理可知:
$$|\textbf{A}|=\sum_{j=1}^n (-1)^{i+j}a_{ij}|\textbf{A}_{ij}|$$
其中 $\textbf{A}_{ij}$ 表示矩阵 $\textbf{A}$ 将第 $i$ 行和第 $j$ 列删除后得到的子矩阵。因此可以通过递归的方式进行求解,其中递归结束为 $n=2$ 的情形,即

$$
\begin{vmatrix}
a_{11} & a_{12} \\
a_{21} & a_{22}
\end{vmatrix}
=a_{11}a_{22}-a_{12}a_{21}
$$

对于 $n=1$ 的情形,直接返回该元素本身即可。
* 运行截图:![行列式运行](https://img.picui.cn/free/2025/05/01/681373d6046ff.png)
### 求逆运算
* 函数:inv_matrix。
* 方阵才能求逆
* 对于一个 $n\times n$ 的方阵 $\textbf{A}$ ,应首先判断其是否可逆,矩阵 $\textbf{A}$ 可逆的充要条件为

$$|\textbf{A}|\neq 0$$
* 如果方阵是可逆的,则可以根据伴随矩阵来求逆,即

$$ \textbf{A}^{-1}=\dfrac{1}{|\textbf{A}|}\textbf{A}^* $$

其中 $\textbf{A}^*$ 是 $\textbf{A}$ 的伴随矩阵,其计算方法为

$$ a^*\_{ij}=(-1)^{i+j}|\textbf{A}_{ji}| $$

与前一部分相同, $\textbf{A}_{ji}$ 表示矩阵 $\textbf{A}$ 将第 $j$ 行和第 $i$ 列删除后得到的子矩阵。
* 运行截图:![求逆运行](https://i.postimg.cc/RFk9y1rm/i-ni.png)
### 求秩运算
* 函数:rank_matrix。
* 求解矩阵的秩可以通过高斯消元法转化为上三角矩阵的过程来实现。对于 $m\times n$ 的矩阵 $\textbf{A}$ ,求 $\text{rank}(\textbf{A})$ 的具体步骤为:

1. 首先,函数初始化秩为矩阵行数和列数中较小的那个值:

$$
\text{rank} = \min(m,n)
$$

2. 接下来,函数将矩阵转化为上三角形式。这个过程通过高斯消元法实现,具体步骤如下:

a. 对于每一列 $i$,从第 $i$ 行开始,检查当前主对角线上的元素 $a_{ii}$ 是否为零。如果 $a_{ii} \neq 0$ ,则表示可以进行高斯消元操作,否则需要在下方寻找一个非零元素,并将其与当前行交换。

b. 对于当前主对角线上的元素 $a_{ii}$,将其下方的所有元素通过行运算消除为零,使得当前列下方的元素全部为零。

c. 如果主对角线上的元素 $a_{ii}$ 为零,则需要在下方寻找一个非零元素 $a_{ji}$ 并将其与当前行交换,以确保在进行下一轮高斯消元时可以继续消去元素。

d. 如果在下方找不到非零元素,说明当前列已经全为零,需要将秩减一,并将当前列的元素全部设为最后一列对应位置的元素。

3. 最后,函数返回计算得到的秩值。

其中,行运算的具体方式为

$$ R_j=R_j-\dfrac{a_{ji}}{a_{ii}}\times R_i $$
* 运行截图:![求秩运行](https://i.postimg.cc/SQY5bpqc/r-zhi.png)
### 求迹运算
* 函数:trace_matrix。
* 方阵才能求迹
* 方阵的迹即对角线元素之和
* 运行截图:![求迹运行](https://i.postimg.cc/qvJjqffb/j.png)
## 打印矩阵
* 按行打印,每个元素占8个字符的宽度,小数点后保留2位,左对齐

Binary file added bin/main.exe
Binary file not shown.
Loading