第一讲里没有具体需要好好理解的部分,不过自测题目题目值得过一遍。

1.线性方程Ax=b的求解

有线性方程$Ax=b$,若已知$A,b$,需要求解$x$,该如何求解?这对$A$和$b$有哪些要求?

(提示:从$A$的维度和秩的角度来分析)

这个问题很简单,但是值得全面地分析和理解:

首先假设$A$是一个$m \times n$矩阵,$x$是一个$n \times 1$的列向量,$b$是一个$m \times 1$的列向量。这里的$m$表示方程的数量,$n$表示未知数的数量。

先从矩阵的秩出发来理解,以列的角度看,矩阵的秩表示了所有列向量线性组合所能达到的空间范围,对于方程$Ax=b$,如果向量$b$在矩阵$A$的列空间中($b$可以被$A$的列向量线性表示),那么存在至少一个解$x$使得$Ax=b$,因此就有了下面的判断性质(比较矩阵$A$和增广矩阵$A|b$秩的关系):

  • $rank(A) = rank(A|b)$:表明向量$b$在矩阵$A$的列空间中,因此至少存在一个解$x$使得$Ax=b$。
  • $rank(A) < rank(A|b)$:表明$b$不在$A$的列空间中,因此没有解。

然后再分析$rank(A)$来确定解的情况,是有唯一解还是存在多个解:

  • 如果$rank(A)=n$(未知数的数量,也就是列的数量),则$A$的所有列向量都是线性独立的,意味着对于给定的$b$,存在唯一的$x$满足$Ax=b$。
  • 如果$rank(A)<n$,则$A$中的某些列向量是其他列向量的线性组合,意味着给定的$b$时,这些可以被其他列向量表示的向量不参与线性组合出$b$,也就可以有任意值作为系数,导致存在无限多个解。

线性方程$Ax=b$的求解方法

‼️以下的回答来自GPT,自己还不是很理解,需要重新系统学习线性代数的知识后再进行自己的消化吸收!

  • 超定系统:$m > n$,方程数量多于未知数。
  • 欠定系统:$m < n$,方程数量少于未知数。
  • 适定系统:$m = n$,方程数量等于未知数。

LU分解

  • 原理:将矩阵$A$分解为两个特殊的矩阵乘积,一个下三角矩阵$L$和一个上三角矩阵$U$,即$A=LU$。这样,原始问题$Ax=b$变为求解两个更简单的线性方程组$L(Ux)=b$。
  • 求解过程:首先解$L\mathbf{y}=b$找到$\mathbf{y}$,然后解$Ux=\mathbf{y}$找到$x$。
  • 适用性:特别适用于适定系统,也可用于某些类型的超定和欠定系统,假设$A$可以进行有效的LU分解。

QR分解

  • 原理:将矩阵$A$分解为一个正交矩阵$Q$和一个上三角矩阵$R$,即$A=QR$。正交矩阵具有性质$Q^TQ=I$($I$是单位矩阵)。
  • 求解过程:利用$Q$的正交性质,原方程$Ax=b$变为$QRx=b$,进一步化简为$Rx=Q^Tb$,然后可以通过回代求解上三角方程组$Rx=Q^Tb$来找到$x$。
  • 适用性:适用于所有类型的系统,尤其是超定系统,因为QR分解提供了一种求解最小二乘问题的自然方法。

奇异值分解(SVD)

  • 原理:SVD将矩阵$A$分解为三个矩阵的乘积,即$A=U\Sigma V^T$,其中$U$和$V$是正交矩阵,$\Sigma$是对角矩阵,对角线上的元素是所谓的奇异值。
  • 求解过程:对于方程$Ax=b$,可以转换为$\Sigma y=U^Tb$(这里$y=V^Tx$),然后通过求解$\Sigma y=U^Tb$来找到$y$,进一步求得$x=Vy$。
  • 适用性:SVD是一种非常强大的方法,特别是对于奇异矩阵或矩阵秩不满的情况,因为它允许计算伪逆矩阵$A^+$,即使在$A$不可逆的情况下也能找到最小二乘解或最小范数解。

迭代方法求解

  • 原理:迭代方法是从一个初始估计开始,通过重复应用迭代公式来逐步逼近方程的解。常见的迭代方法包括雅可比方法、高斯-赛德尔方法和共轭梯度法等。
  • 求解过程:根据具体的迭代公式,每一步都基于前一步的结果来更新解的估计值,直至满足某个终止条件(如解的变化小于某个阈值)。
  • 适用性:迭代方法特别适用于大规模稀疏矩阵的系统,因为它们通常不需要矩阵分解,而矩阵分解在大规模问题上可能非常昂贵。

2.高斯分布

高斯分布是什么?它的一维形式是什么样子?它的高维形式是什么样子?

高斯分布,也称为正态分布,高斯分布可以被视为描述自然和人为现象中随机误差的理想模型,其普遍性来源于中心极限定理(Central Limit Theorem, CLT),这个定理说明了许多小效应的累积可以产生高斯分布的现象,具体而言就是:“大量相互独立且分布相同的随机变量之和趋向于服从正态分布,无论原始随机变量的分布如何。”

高斯分布的一维形式

一维高斯分布(或简称为正态分布)的数学表达式为:

$$ f(x | \mu, \sigma^2) = \frac{1}{\sqrt{2\pi\sigma^2}} \exp\left(-\frac{(x-\mu)^2}{2\sigma^2}\right) $$

其中,$\mu$是分布的均值,$\sigma^2$是方差,$\sigma$是标准差。这个公式描述了在给定均值$\mu$和方差$\sigma^2$的情况下,随机变量$X$取特定值$x$的概率密度。图形上,一维高斯分布是一个对称的钟形曲线,其中心位于均值$\mu$,曲线的宽度由标准差$\sigma$决定。

高斯分布的高维形式

高维高斯分布,或多变量高斯分布,是一维高斯分布在多维空间中的推广。其数学表达式为:

$$ f(\mathbf{x} | \boldsymbol{\mu}, \Sigma) = \frac{1}{\sqrt{(2\pi)^k |\Sigma|}} \exp\left(-\frac{1}{2}(\mathbf{x}-\boldsymbol{\mu})^T \Sigma^{-1} (\mathbf{x}-\boldsymbol{\mu})\right) $$

其中,$\mathbf{x}$是一个$k$维随机向量,$\boldsymbol{\mu}$是均值向量,$\Sigma$是协方差矩阵,$|\Sigma|$是协方差矩阵的行列式。高维高斯分布的图形是在多维空间中的一个“山峰”,其中心位于均值向量$\boldsymbol{\mu}$,“山峰”的形状和方向由协方差矩阵$\Sigma$决定。

协方差是衡量两个随机变量联合变化趋势的度量。如果两个变量的增减趋势相同(即一个变量增加时,另一个也增加),则它们的协方差为正;如果一个变量增加时另一个减少,则协方差为负。

对于两个随机变量$X$和$Y$,协方差定义为$Cov(X, Y) = E[(X - \mu_X)(Y - \mu_Y)]$,其中$\mu_X$和$\mu_Y$分别是$X$和$Y$的均值,$E$表示期望值操作。

3.C++基本知识

C++中的类是什么?STL是什么?模版又是什么?

(将基本常用的举例出来进行说明)

C++11的新特性以及其他标准

对于C和C++,我觉得需要系统的课程来学习补充,边用边学是持续的,先打好基础,边学边成长才更好

以下只是对这个回答的简要回答(举例说明)

类(Class)

类是C++中用于数据封装和面向对象编程的基本构建块。它定义了一种数据类型的蓝图,包括数据成员(属性)和成员函数(方法),用于操作这些数据。

class Car {
public:
    Car(int y, const std::string& m) : year(y), model(m) {}
    void display() const {
        std::cout << "Year: " << year << ", Model: " << model << std::endl;
    }
private:
    int year;
    std::string model;
};

标准模板库(STL)

STL是一组模板化的通用类和函数的集合,提供了常见的数据结构(如向量、列表、队列等)和算法(如排序、搜索等)。STL的核心组成部分包括:

  • 容器:存储数据的数据结构。例如std::vectorstd::liststd::map等。
  • 算法:操作数据的函数,例如std::sortstd::find
  • 迭代器:提供对容器中元素的访问方式。
#include <vector>
#include <algorithm>
#include <iostream>

int main() {
    std::vector<int> vec = {4, 1, 3, 5, 2};
    std::sort(vec.begin(), vec.end());
    for(int i : vec) {
        std::cout << i << " ";
    }
}

模板(Template)

模板允许在不指定具体类型的情况下编写代码。它们使得可以创建泛型类和函数,使代码更加灵活和可重用。

template <typename T>
T add(T a, T b) {
    return a + b;
}

// 使用模板函数
int result = add<int>(1, 2);

C++11/14/17的新特性举例

C++11

  • 自动类型推断(auto:让编译器自动推断变量的类型。
  • 基于范围的for循环:简化了集合的遍历。
  • 智能指针:如std::shared_ptrstd::unique_ptr,管理动态分配的内存。
  • Lambda表达式:允许定义匿名函数。

C++14

  • 泛型Lambda:Lambda表达式中使用自动类型推断。
  • 返回类型推断:函数的返回类型可以被自动推断。

C++17

  • 结构化绑定:允许从数组或元组中一次性解包多个值。
  • 内联变量:对于头文件中的全局变量,允许多个源文件中包含同一个变量而不会引起重定义错误。
  • std::optional:表示一个可能不存在的值。

4.Linux必备的操作

Linux必备知识

  1. 基本命令行操作: 理解如何使用命令行界面(CLI)进行文件系统的导航(如cd, ls, pwd)、文件操作(如cp, mv, rm, mkdir)和文本文件查看与编辑(如cat, nano, vi/vim)。

  2. 软件安装与管理: 熟悉所用发行版的包管理器,如Ubuntu的apt, CentOS的yum或Fedora的dnf,用于安装、更新和管理软件包。

  3. 权限和用户管理: 了解文件权限(chmod, chown)和用户管理命令(useradd, usermod, groupadd),以及如何使用sudo来执行需要超级用户权限的命令。

  4. 进程管理: 学会如何使用ps, top, htop, kill, 和systemctl来查看和管理运行中的进程和服务。

  5. 网络配置和故障排除: 掌握使用ifconfig/ipconfig, ping, netstat, ss, traceroute等命令进行网络配置和故障排查。

  6. Shell脚本编写: 学习基本的Shell脚本编写,以自动化日常任务。

  7. 文件系统管理: 了解不同的文件系统类型,磁盘分区(fdisk, parted),以及如何挂载和卸载文件系统(mount, umount)。

  8. 安全和防火墙: 基本的系统安全知识,如使用iptablesufw管理防火墙规则,以及使用ssh进行安全远程登录。

Linux的一些“术”

  • 使用man命令: 几乎所有Linux命令都有手册页,通过man <命令名>可以查看详细的使用说明和选项。
  • 命令行自动完成: 通过按Tab键自动完成命令名称或参数,这不仅可以加快命令输入速度,还可以帮助记忆命令。
  • 使用apropos命令: 如果不确定使用哪个命令,可以通过apropos <关键词>来搜索相关的命令。
  • 建立个人命令备忘录: 当学习新命令时,将它们记录在笔记中,随时查阅。

Linux安装软件

在使用apt(或apt-get)在Ubuntu或基于Debian的系统中安装软件时,软件包通常会被安装到系统的标准目录下,这遵循了Linux的文件系统层次结构标准(FHS)。大部分可执行文件会放置在/usr/bin//usr/local/bin/目录下,库文件通常位于/usr/lib//usr/local/lib/,而配置文件大多数在/etc/下。文档和示例文件可能位于/usr/share/doc/

如何安装软件

如果你只是模糊知道某个软件包的名字,可以使用apt提供的搜索功能来查找正确的软件包名。以下是步骤和示例,以Eigen这个数学库为例:

  1. 更新软件包列表:首先,最好更新本地软件包列表,以确保搜索和安装的是最新版本的软件。在终端中运行:

    sudo apt update
    
  2. 搜索软件包:如果不确定软件包的确切名称,可以使用apt-cache search命令进行搜索。例如,如果要搜索Eigen,可以运行:

    apt-cache search eigen
    

    这将列出所有与“eigen”相关的软件包。在结果中,会看到很多与Eigen相关的包,其中可能包括实际的Eigen库包和其他相关包。

  3. 安装软件包:一旦你找到了想要安装的确切软件包名称,就可以使用apt-get install命令进行安装。如果结果显示Eigen的开发包是libeigen3-dev(这是一个常见的包名,用于包含Eigen库的开发文件),就可以运行:

    sudo apt-get install libeigen3-dev
    

    这条命令会安装Eigen库及其所有依赖项。

如何找到安装的软件

如果想知道apt安装的软件具体放在哪里,可以使用dpkg -L命令来列出软件包安装的所有文件的位置。例如,要找到libeigen3-dev安装的所有文件,可以运行:

dpkg -L libeigen3-dev

这将列出所有由该软件包安装的文件和目录的路径,包括库文件、头文件、文档等。

✨Linux的文件系统

Linux的文件系统层次结构标准(FHS, Filesystem Hierarchy Standard)定义了操作系统中目录和目录内容的标准布局。这种标准化设计使得开发者和用户能够预测在任何基于Linux的系统上找到特定类型文件的位置。以下是一些主要目录及其用途的简要说明:

根目录 /

在Linux中,所有的文件和目录都从根目录开始。这是整个文件系统的起点。

/bin

这个目录包含执行文件(二进制文件),这些文件是系统启动和运行所必需的,同时也存放了用户常用的命令(如ls, cp等)所依赖的执行文件。

用例:存放基本的命令,如grep, echo, sleep。这些命令在单用户模式下或紧急恢复时也必须可用。

/boot

包含启动Linux系统所需的文件,比如Linux内核(vmlinuz),引导加载程序(GRUB或LILO)的配置文件等。

/dev

这个目录下包含设备文件。Linux将设备视为文件,这些设备文件代表系统中的硬件组件。

/etc

包含系统配置文件。这些文件只能被根用户或具有适当权限的用户修改。这里包括系统启动脚本、网络配置文件等。

用例:包含如/etc/passwd(用户账户信息)和/etc/fstab(文件系统挂载的静态信息)等关键配置文件。

/home

用户的个人目录位于此处。每个用户都有一个与其用户名对应的目录,用于存储个人文件、配置等。

/lib

包含系统最基本的共享库和内核模块。这些库支持位于/bin/sbin目录中的二进制文件。

用例:存放动态链接库(如libc.so.6),它们是执行/bin/sbin下命令所必需的。

/media/mnt

/media通常用于挂载可移动媒体设备,如CD-ROMs、USB驱动器等,而/mnt则用作临时挂载文件系统的目的。

/opt

用于安装“可选”的软件应用。这些是非基本系统软件,通常作为整个应用程序安装在这里。

用例:第三方应用程序如Google Chrome或某些商业软件可能会安装在这里,每个应用通常有其自己的子目录。

/proc

这是一个虚拟文件系统,提供对内核和进程信息的接口。它并不占用磁盘空间,而是在内存中动态生成。

/root

这是系统管理员,也就是root用户的家目录。这与/home目录分开,为了安全性和管理方便。

/sbin

包含系统管理和维护的必需的执行文件,这些命令通常由root用户运行,如fdisk, ifconfig, swapon等。

/tmp

一个临时文件存储区域。系统和用户可以在这里创建临时文件。通常,此目录在系统重启时会被清空。

/usr

包含用户程序和数据。它是Unix System Resources的缩写。随着时间的推移,/usr目录已经成为存储共享系统资源的主要目录。

  • /usr/bin:包含用户安装的非系统必需的执行文件。
  • /usr/lib:类似/lib,但是为/usr/bin下的程序提供库支持。
  • /usr/local:用于系统管理员安装本地软件,保持与由包管理器安装的软件的分离。
  • 用例/usr/bin下可能会有如python, gcc等用户级程序。

/var

包含经常变化的文件,如日志文件、打印队列、邮件等。

  • /var/log:存放系统日志文件,如/var/log/syslog/var/log/apache2
  • /var/mail:存储用户的邮件。
  • /var/cache:用于存放应用程序缓存数据。
  • 用例:系统管理员可能需要定期检查/var/log来监控系统和应用程序的活动。

/srv

用于存放服务提供的数据,例如Web服务器和FTP服务器的数据文件。

用例:如果您运行一个Web服务,网站的数据可能位于/srv/www

/sys

/proc相似,/sys是一个虚拟文件系统,提供了内核、设备和驱动程序的接口。

用例/sys提供了一种更加结构化的方式来浏览设备和驱动程序的信息,如查询特定USB设备的信息。

/etc/cron.*

这些目录(cron.daily, cron.hourly, cron.monthly, cron.weekly)用于存放定时执行的脚本。

用例:自动备份脚本可能放在/etc/cron.daily中,以确保每天执行。

5.Vim必须会的几个操作

已经不在执着于美化Vim的各种插件了(因为完全可以用更好的CLion、VSCode之类)

‼️但是命令行中Vim最方便,但只要知道最基础的操作就足够了:怎么增删改查,怎么复制粘贴。

Vim是一个非常强大的文本编辑器,常被用于编程和脚本编辑。它的操作方式与其他文本编辑器有很大不同,主要基于键盘快捷键,分为多种模式,最主要的是普通模式(Normal Mode)、插入模式(Insert Mode)、命令模式(Command-Line Mode)和可视模式(Visual Mode)。以下是关于Vim的基本用法,包括增删改查、复制粘贴,以及批量执行命令的方法。

Vim的基本操作

进入插入模式

  • 在普通模式下,按i进入插入模式,在光标前插入文本。
  • a也可以进入插入模式,在光标后插入文本。
  • I在当前行首进入插入模式,按A在当前行尾进入插入模式。

删除文本

  • 在普通模式下,按x删除光标所在位置的字符。
  • dd删除光标所在行。
  • 要删除从当前光标位置到行尾的内容,可以使用D

修改文本

  • 在普通模式下,按r后跟一个字符可以替换光标所在位置的字符。
  • 使用cw可以更改光标开始的单词,这将删除单词并进入插入模式。

查找文本

  • 在普通模式下,按/后输入要查找的文字,然后按Enter进行搜索。按n查找下一个匹配项,按N查找上一个匹配项。

复制和粘贴

  • 在普通模式下,按yy复制当前行,按p粘贴到光标后。
  • 要复制多行,可以先按2yy来复制两行(2可以替换为任何数字,表示行数)。
  • 使用可视模式(按v进入)可以选择特定的文本区域,然后按y复制。

移动操作

  • 基本移动h(左移)、j(下移)、k(上移)、l(右移)。
  • 按单词移动
    • w:向前移动到下一个单词的开头。
    • b:向后移动到前一个单词的开头。
    • e:向前移动到当前或下一个单词的结尾。
  • 按行移动
    • 0(零):移动到当前行的开始。
    • ^:移动到当前行的第一个非空白字符。
    • $:移动到当前行的末尾。
  • 跳转到特定行
    • gg:跳转到文件的第一行。
    • G:跳转到文件的最后一行。
    • :<行号>+Enter:跳转到文件中的特定行号。
  • 屏幕移动
    • H:移动到屏幕顶部的行。
    • M:移动到屏幕中间的行。
    • L:移动到屏幕底部的行。
  • 翻页
    • Ctrl+f:向前翻一页。
    • Ctrl+b:向后翻一页。
    • Ctrl+d:向前翻半页。
    • Ctrl+u:向后翻半页。

可以结合前置数字来实现“批量移动”,这意味着可以在移动命令前加上一个数字来重复该命令多次,例如:

  • 5j 表示向下(j)移动5行。
  • 3w 表示向前跳过3个单词到下一个单词的开头。
  • 10k 表示向上(k)移动10行。
  • 4$ 表示移动到后面4行的末尾。

Vim与外部(macOS)的复制粘贴

在macOS上,从Vim复制文本到外部程序,首先需要确认你的Vim版本是否支持剪贴板(clipboard)功能。可以通过在终端中输入vim --version查看。如果看到+clipboard,则表示支持剪贴板功能;如果是-clipboard,则表示不支持,可能需要安装支持剪贴板的Vim版本,比如通过brew install vim

  1. 启用剪贴板支持:确保Vim版本支持系统剪贴板。

  2. 复制文本到剪贴板

    • 在普通模式下,要复制整行到系统剪贴板,使用"+yy。(一个一个字符来按
    • 要复制指定文本,先按v进入可视模式,选择需要的文本,然后使用"+y复制。
  3. 从外部粘贴到Vim:在插入模式下,使用Cmd+V(macOS通常的粘贴快捷键)或在普通模式下使用"+p来粘贴剪贴板的内容到Vim。

一些技巧

  • 在普通模式下,可以通过:norm命令批量执行操作。比如,:norm I//会在所有选中的行前添加//(注释掉这些行)。

  • 批量替换文本,可以使用:s命令。例如,要在整个文件中替换"old"为"new",可以使用:s/old/new/g

  • 在多个行前添加内容:假设想在文件的每一行前添加序号或特定标记,可以使用:norm命令。例如,:5,10norm I// 会在第5行到第10行的开头添加//

  • 转换大小写:要将选定行的文本转换为大写,可以使用:norm结合gU命令。例如,:5,10norm gU$会将第5到第10行的内容转换为大写。

  • 快速跳转至匹配的括号:在普通模式下,使用%可以跳转至匹配的括号,这在编辑代码时非常有用。

  • 撤销和重做:使用u来撤销最近的一次更改,使用Ctrl+r来重做被撤销的更改。

  • 打开/关闭行号显示:快速切换行号显示,可以使用:set nu!:set rnu!来分别切换绝对行号和相对行号的显示状态。