BNU-FZH

fengzhenhua@outlook.com

本来我的Outlook邮箱是相当纯净的,但是最近总是收到Start Daily的邮件,有点不能接受。研究后发现解决方法:

  • 登录网页版的Outlook邮箱:Outlook登录
  • 点击右上角您的头象,然后选择我的Microsoft帐户
  • 在左侧点击第二项您的信息
  • 在右侧向下滚动,找到帐户信息, 再点击通信首选项
  • 将所有的订阅取消,然后点击应用,Outlook得归清静。

插件vim-vsnip自带了相当数量的补全插件,但是一般都是通用的片段,对于编写自己常用的文件还需要自定义片段。本文记录自定义片段的具体过程。

安装插件

~/.config/nvim/lua/lazy-init.lua
1
2
3
4
5
6
7
require("lazy").setup({
...
'hrsh7th/cmp-vsnip' ,
'hrsh7th/vim-vsnip' ,
'rafamadriz/friendly-snippets' ,
...
})

编辑片段

这里可以使用命令VsnipOpen, 或者直接编辑~/.vsnip/markdown.json就可以直接添加markdown相应的片段。在编写过程中,为了适应Next博客主题输入数学公式的需要,需要输入$$, 但是这个片段是错误的,因为默认$是变量的符号,于是转义,片段的转义符号为\\, 于是得相应片段为:

~/.vsnip/markdown.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
{
"math-sup": {
"Vsnips.EnableAutoTrigger": true,
"prefix": ["^{"],
"body": [
"^{$1}<++>"
],
"description": "math formular"
},
"math-sub": {
"Vsnips.EnableAutoTrigger": true,
"prefix": ["_{"],
"body": [
"_{$1}<++>"
],
"description": "math formular"
},
"math-dkuohao": {
"Vsnips.EnableAutoTrigger": true,
"prefix": ["{"],
"body": [
"{$1}<++>"
],
"description": "math formular"
},
"math-fkuohao": {
"Vsnips.EnableAutoTrigger": true,
"prefix": ["["],
"body": [
"[$1]<++>"
],
"description": "math formular"
},
"math-ykuohao": {
"Vsnips.EnableAutoTrigger": true,
"prefix": ["("],
"body": [
"($1)<++>"
],
"description": "math formular"
},
"math-sqrt": {
"Vsnips.EnableAutoTrigger": true,
"prefix": ["sqrt"],
"body": [
"\\sqrt{$1}<++>"
],
"description": "math formular"
},
"math-frac": {
"Vsnips.EnableAutoTrigger": true,
"prefix": ["frac"],
"body": [
"\\frac{$1}{<++>}<++>"
],
"description": "math formular"
},
"math-tag": {
"prefix": ["tag"],
"body": [
"\\$\\tag{$1}\\label{tag<++>}\\$<++>"
],
"description": "math referance"
},
"math-eqref": {
"prefix": ["eqref"],
"body": [
"\\$\\eqref{eq:$1}\\$<++>"
],
"description": "math referance"
},
"math-label": {
"prefix": ["eqlabel"],
"body": [
"\\label{eq:$1}<++>"
],
"description": "math labels"
},
"math-multi2": {
"prefix": ["align"],
"body": [
"\\$\\$\\begin{align}",
"$1",
"\\end{align}\\$\\$<++>"
],
"description": "Multi-line Equations"
},
"math-multi1": {
"prefix": ["mequation"],
"body": [
"\\$\\$\\begin{equation}\\label{eq:$1}",
"\\begin{aligned}",
"<++>",
"\\end{aligned}",
"\\end{equation}\\$\\$<++>"
],
"description": "Multi-line Equations"
},
"math-simple": {
"prefix": ["equation"],
"body": [
"\\$\\$\\begin{equation}\\label{eq:$1}",
"<++>",
"\\end{equation}\\$\\$<++>"
],
"description": "Simple Equation"
},
"LinkGrid": {
"prefix": ["linkgrid"],
"body": [
"{% linkgrid %}",
" $1 | https://<+url+> | <+description+> | /Picture/<++>",
"{% endlinkgrid %}"
],
"description": "For diary.sh write"
},
"button": {
"prefix": ["button"],
"body": [
"{% button https://<+url+>, $1 %}"
],
"description": "For diary.sh write"
},
"fold": {
"prefix": ["fold"],
"body": [
"<details><summary>$1</summary>",
"<+contents+>",
"</details>"
],
"description": "For diary.sh write"
},
"more": {
"prefix": ["more"],
"body": [
"<!-- more -->"
],
"description": "For diary.sh write"
},
"arrow": {
"prefix": ["arrow"],
"body": [
"${1|&rarr;,&uarr;,&darr;,&larr;,&harr;|}"
]
},
"picture": {
"prefix": ["picture"],
"body": [
"![$1](/Picture/<+pic+> \"<+title+>\")<++>"
]
},
"centertext": {
"prefix": ["center"],
"body": [
"{% cq %}",
"$1",
"{% endcq %}",
"<++>"
]
},
"textcolor": {
"prefix": ["color"],
"body": [
"<label style=\"color:${1|red,yellow,blue,cyan,gold,green,gray,orange|}\"><++></label><++>"
]
},
"underline": {
"prefix": ["underline"],
"body": [
"<u>$1</u><++>"
]
},
"sub": {
"prefix": ["__"],
"body": [
"<sub>$1</sub><++>"
]
},
"sup": {
"prefix": ["^^"],
"body": [
"<sup>$1</sup><++>"
]
},
"href": {
"prefix": ["ref"],
"body": [
"[$1](/<+year+>/<+month+>/<+day+>/<+article+>)"
],
"description": "Ref the article of my blog"
},
"hurl": {
"prefix": ["url"],
"body": [
"[$1](<+url+>)<++>"
]
},
"delete": {
"prefix": ["delete"],
"body": [
"~~$1~~"
]
},
"code": {
"prefix": ["code"],
"body": [
"{% code <+title+> lang:${1|sh,python,lua,perl,yaml,ruby|} %}",
"<+code+>",
"{% endcode %}",
"<++>"
],
"description": "Next theme environment for Hexo"
},
"codeblock": {
"prefix": ["codeblock"],
"body": [
"{% codeblock <+title+> lang:${1|sh,python,lua,perl,yaml,ruby|} %}",
"<+code+>",
"{% endcodeblock %}",
"<++>"
],
"description": "Next theme environment for Hexo"
},
"```": {
"prefix": ["```"],
"body": [
"```${1|sh,python,lua,perl,yaml,ruby|} <+title+> ",
"<+code+>",
"```",
"<++>"
],
"description": "Next theme environment for Hexo"
},
"note": {
"prefix": ["note"],
"body": [
"{% note ${1|default,primary,success,info,warning,danger|} %}",
"<++>",
"{% endnote %}",
"<++>"
],
"description": "Next theme environment for Hexo"
},
"tabs": {
"prefix": ["tabs"],
"body": [
"{% tabs ${1:<+UniqueName+>} %}",
"<!-- tab ${2:<+tabcaption+>} -->",
"<++>",
"<!-- endtab -->",
"<++>",
"{% endtabs %}",
"<++>"
],
"description": "Next theme environment for Hexo"
},
"tab": {
"prefix": ["tab"],
"body": [
"<!-- tab ${2:<+tabcaption+>} -->",
"<++>",
"<!-- endtab -->",
"<++>"
],
"description": "Next theme environment for Hexo"
},
"label": {
"prefix": ["label"],
"body": [
"{% label ${1|default,primary,success,info,warning,danger|}@${2:<+content+>} %}<++>"
],
"description": "Next theme environment for Hexo"
},
"centerquote": {
"prefix": ["centerquote"],
"body": [
"{% centerquote %}",
"${1:<+content+>}",
"{% endcenterquote %}",
"<++>"
],
"description": "Next theme environment for Hexo"
},
"video": {
"prefix": ["video"],
"body": [
"{% video ${1|/Video/<++>,https://<+website+>|}%}<++>"
],
"description": "Next theme environment for Hexo"
},

"pdf": {
"prefix": ["pdf"],
"body": [
"{% pdf ${1|/PDF/<++>.pdf,https://<+website+>|}%}<++>"
],
"description": "Next theme environment for Hexo"
},
"grouppicture": {
"prefix": ["grouppicture"],
"body": [
"{% grouppicture ${1:<+number+>}-${2:<+layout+>} }%}",
"![${3:<+picturetitle+>}](${4:<+picture+>})",
"{% endgroudpicture %}",
"<++>"
],
"description": "Next theme environment for Hexo"
}
}

参考资料

inix 是一个用于获取 Linux 系统信息的终端命令。能够获取软件和硬件的详细信息,比如计算机型号、内核版本、发行版号以及桌面环境等信息,甚至可以读取主存模块占用主板的哪块 RAM 卡槽等详细信息。

inxi 还可以用于监控系统中正在消耗 CPU 或者内存资源的进程。

在本文中,我将展示使用 inxi 命令获取系统信息的常用操作。

首先,我将展示下如何安装 inxi 命令。

在 Linux 上安装 inxi

inxi 是一个非常流行的工具,所以在大多数 Linux 发行版仓库中都可以轻松获取到该工具。不过还没有流行到各大 Linux 发行版默认就安装了该软件,所以需要我们自己安装一下。

在 Ubuntu/Debian 发行版系统中,安装命令:

1
sudo apt install inxi

在 Fedora/RHEL8-based 等发行版中,安装命令:

1
2
sudo dnf install -y epel-release
sudo dnf install -y inxi

在 Arch Linux 以及它的派生分支版本中,安装命令:

1
sudo pacman -S inxi

使用 inxi 获取系统信息

你可以在终端运行 inxi 命令来总体浏览下系统信息。

1
inxi

如下图所示,运行 inxi 命令可以简要浏览 CPU、时钟频率(speed/min/max)、内核(Kernel)、内存(Mem)、磁盘存储空间(Storage)、运行进程数量(Procs)以及 Shell 等信息。

The default output of inxi command

使用 -b 参数可以获取更为详细的系统信息。-b 参数会读取更多有关 CPU、驱动器、当前运行进程、主板 UEFI 版本、GPU、显示分辨率以及网络设备等详细信息。

1
inxi -b
Detailed hardware and software information about machine as reported by inxi

类似 -b 参数使用方法,inxi 还有许多其他的参数可供使用。你可以综合使用这些参数来获取你关心的信息。

让我们看几个实例。

获取音频设备信息

使用 -A 参数可以获取有关音频(输出)设备信息,包括物理音频(输出)设备、声音服务器以及音频驱动等详细信息。

1
inxi -A
Output of inxi command when “-A” flag is used

获取电池信息

使用 -B 参数,可以获取有关电池的信息(如果安装了电池)。你将读取到例如以 Wh(瓦特小时)为单位的当前电池电量和状况。

因为我使用的是台式机,所以这里仅仅作为一个示例,让我们看看使用 inxi -B 会输出什么。

1
Battery:   ID-1: BAT0 charge: 50.0 Wh (100.0%) condition: 50.0/50.0

获取 CPU 信息

-C 参数用于获取有关 CPU 的详细信息。比如包括 CPU 缓存大小、频率(单位 MHz,如果有多核,会显示每个核心的频率)、核心数、CPU 型号以及 CPU 是 32 位还是 64 位。

1
inxi -C
Detailed CPU information displayed by inxi

注意,如果是在虚拟机中使用 inix -Cinxi 读取到的 CPU 的最大和最小频率可能异常。下面是一个在四核 Debian 11 虚拟机中使用 -C 参数的示例输出。

An example output of using the “-C” flag in a Virtual Machine

获取更多的系统信息

使用 -F 参数可以获取更详细的系统信息(类似 -b 参数,但会更为详细)。几乎囊括了所有层次的系统信息。

1
inxi -F

获取图形显示相关信息

-G 参数可以获取和图形相关的信息。

它会显示所有的图形设备(GPU)、正在使用的 GPU 驱动(有助于检查是否使用 Nvidia 驱动还是 nouveau 驱动)、显示输出分辨率和驱动程序版本。

1
inxi -G

获取运行进程信息

-I 参数(大写字母 i)显示正在运行的进程、当前 shell 、内存(内存使用情况)以及 inxi 版本号等信息。

inxi get running process info

获取内存信息

可能你已经猜到了,-m 参数可以获取与内存相关的信息。

它读取了如总可用内存、最大内存容量(硬件或 CPU 支持的)、主板物理内存插槽数、是否存在 ECC、插入的内存插槽,以及枚举每个插槽中运行的内存模块的大小和运行速度等信息。

1
inxi -m

要使用 -m 参数获取更详细的信息,例如最大容量、每个插槽的内存模块信息等,需要超级用户权限。

1
sudo inxi -m

如果只是希望简短的输出内存信息,可以使用 -memory-short 参数。

使用 -memroy-short 参数将会只显示总内存以及当前已使用的内存量。

查看正在使用的包存储库

当使用 -r 参数时,会列举当前正在使用的包管理仓库或者更新本地仓库缓存中的所有存储库列表。

List of repositories in use

获取 RAID 设备信息

-R 参数用于获取所有 RAID 设备相关信息。

令人惊喜的是,它甚至显示了有关 ZFS RAID(默认情况下,多数 Linux 系统不包含该文件系统)的信息。它显示了 RAID 设备上文件系统的详细信息、状态(包含离线状态、总大小和可用大小等)。

1
inxi -R

在 Linux 终端中查询天气(对,这是可以的)

利用 -W 参数,你可以查询地球上任何地方的天气情况。

-W 参数后面,需要携带以下中的任一一个体现位置的信息

  • 邮政编码
  • 纬度
  • 城市(及州)、国家(不能含有空格,使用 “+” 替换空格)
1
inxi -W Baroda,India
Use of the “-W” flag with inxi followed by the city,country location descriptor

监控系统资源使用情况

inxi 除了提供有关已安装的硬件和驱动的信息外,还可以用于资源监控。

使用 -t 参数可以显示进程信息。你还可以可选项 -c (用于 CPU)和 -m(用于内存)。这些选项结合使用可以按指定数量列出进程信息。

下面是一些使用 -t 参数监控资源信息的示例。

1
inxi -t

命令 inxi -t 默认效果等同于 inxi -t cm5 的效果。

No difference in output of “inti -t” and “inxi -t cm5”
1
inxi -t cm10

偶尔需要监控资源使用情况时,该工具挺管用。如果需要更多的资源监控功能,则推荐使用 专用系统资源监控工具

总结

对于需要诊断计算机问题以及获取那些并不熟悉的软硬件信息的人来说,inxi 工具是十分便利且有用的。它能识别那些消耗 CPU、内存的进程;可以检查是否安装了合适的图形驱动程序、主板 UEFI/BIOS 是否需要更新等等。

事实上,在 inxi 开源社区论坛上,我们要求那些寻求帮助的成员提供 inxi 命令输出内容以便判断他们当前正在使用什么样的系统环境。

我知道也有其他的工具可以读取 Linux 上的硬件信息,不过 inxi 同时能读取硬件和软件信息,这也是我喜欢它的地方所在。

在日常Shell脚本的编写过程中,经常遇到判断文件或文件夹是否存在的问题,有时候也需要判断文件的新旧,所以本文罗列出Shell对文件的相关判断方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
-e 判断对象是否存在
-d 判断对象是否存在,并且为目录
-f 判断对象是否存在,并且为常规文件
-L 判断对象是否存在,并且为符号链接
-h 判断对象是否存在,并且为软链接
-s 判断对象是否存在,并且长度不为0
-r 判断对象是否存在,并且可读
-w 判断对象是否存在,并且可写
-x 判断对象是否存在,并且可执行
-O 判断对象是否存在,并且属于当前用户
-G 判断对象是否存在,并且属于当前用户组
-nt 判断file1是否比file2新 [ "/data/file1" -nt "/data/file2" ]
-ot 判断file1是否比file2旧 [ "/data/file1" -ot "/data/file2" ]

应用举例

文件夹不存在则创建

1
2
3
4
5
if [ ! -d "/data/" ];then
mkdir /data
else
echo "文件夹已经存在"
fi

文件存在则删除

1
2
3
4
5
if [ ! -f "/data/filename" ];then
echo "文件不存在"
else
rm -f /data/filename
fi

判断文件夹是否存在

1
2
3
4
5
if [ -d "/data/" ];then
echo "文件夹存在"
else
echo "文件夹不存在"
fi

判断文件是否存在

1
2
3
4
5
if [ -f "/data/filename" ];then
echo "文件存在"
else
echo "文件不存在"
fi

先创建一个测试文件testfile, 如下

testfile
1
2
3
4
5
6
7
8
9
10
$ cat testfile #查看testfile 中的内容  
HELLO LINUX!
Linux is a free unix-type opterating system.
This is a linux testfile!
Linux test
Google
Taobao
Runoob
Tesetfile
Wiki

数据的搜寻并显示

搜索 testfile 有 oo 关键字的行:
1
2
3
$ nl testfile | sed -n '/oo/p'
5 Google
7 Runoob

数据的搜寻并删除

删除 testfile 所有包含 oo 的行,其他行输出
1
2
3
4
5
6
7
8
$ nl testfile | sed  '/oo/d'
1 HELLO LINUX!
2 Linux is a free unix-type opterating system.
3 This is a linux testfile!
4 Linux test
6 Taobao
8 Tesetfile
9 Wiki

数据的搜寻并执行命令

搜索 testfile,找到 oo 对应的行,执行后面花括号中的一组命令,每个命令之间用分号分隔,这里把 oo 替换为 kk,再输出这行:

1
2
$ nl testfile | sed -n '/oo/{s/oo/kk/;p;q}'  
5 Gkkgle

参考资料

前几天配置好的新电脑后,逐步完成ArchLinux的使用细节配置,但是在使用paru安装软件时会出现一个提示:

1
错误:选项节 [options] 中有未知的选项 'FileManager'

这源自于paru的配置文件/etc/paru.conf中出现了错误,即将[bin]前的注释去掉,即修改为:

/etc/paru.conf
1
2
3
4
# Binary OPTIONS
#
[bin]
FileManager = vifm

注意:在之前的配置中我的[bin]是被注释掉的,但是能正常工作,或许是升级后作者修复了这个bug,因些需要严格的启动这个选项。

工作和学习中编写PPT是一件很平常的事情,但是做的多了就需要提高效率。目前网络上的AI生成PPT的工具有很多,但是大多需要注册或者有使用次数限制,这非常不方便。本文隆重介绍一个永久免费的,免注册的工具。点击官网直接进入:

https://aippt.antdanceai.com

官方的介绍:

adAI 艾达艾ai一键生成ppt工具,是adAI 艾达艾旗下一个通过ai能力,一键全自动生成图文信息的ppt工具。adAI 艾达艾ai ppt工具,可以在2分钟内,根据用户输入的对ppt制作的要求,一键生成精美页面的ppt文字内容和针对性配图。

adAI 艾达艾ai一键生成ppt工具,通过针对数十万种ppt生成格式的训练,用户只需要通过简洁清晰描述需求,即可转化为高质量的ppt文字结构的内容。并且通过针对每页的ppt标题,智能理解标题语义并根据语义,智能匹配对应的配图。实现了一键自动化生成图文并茂的ppt。并且支持一键免费下载生成的ppt。如果对生成的ppt需要进行编辑和调整,只需要通过wps 或PowerPoint打开后即可编辑。

adAI 艾达艾ai ppt还创新的采用了新的商业模式。对于用户而言,这是一个真正免费的 ,并且免注册登录的,也无需科学上网即可使用的ai ppt生成工具。只是在生成的ppt最后一页带有 广告。用户可以随时删除。这个广告是通过adAI 艾达艾的千人千面ai算法实现基于用户输入的ppt提示词智能匹配的。比如用户输入如果策划一场车展,那么匹配的广告会跟:车、展会、策划相关。做到精准广告匹配。

adAI 艾达艾人工智能科技有限公司,致力于通过ai重构传统营销模式,除了ai ppt工具以外,还提供基于 ai的全自动内容营销服务。

根据Next主题官方文档Math Equation配置好Hexo对数学公式的支持,对于一些小问题可以写成LaTeX记录在博客中。但是这里面遇到的问题是,MarkDown毕竟不是针对LaTeX设计的,所以一些特殊的宏包在博客中是不能使用的,对于一些特殊复杂的公式需要撰写tex文件编译,而不是发表在博客上。对于一些简单的公式,如果在Hexo博客上编写,应当注意使用原始的LaTeX命令,以增强其兼容性,对于一些数学符号的输入,请参考:关于LaTeX公式编辑 Introduce, 而对于Hexo支持的数学公式格式,为了方便使用,直接引用其官方的例子。

支持的数学公式

Hexo中开启数学支持,有两种插件支持,其中MathJax依赖JavaScript,但其支持的数学公式更多,而KaTeX不依赖JavaScript, 同时速度更快,但是其持的数学公式少一些,因些根据Next主题官方,推荐使用MathJax.它们支持的TeX/LaTeX命令参考:

Simple Equations

For simple equations, use the following form to give a tag,

1
2
3
$$\begin{equation} \label{eq1}
e=mc^2
\end{equation}$$

\[\begin{equation} \label{eq1} e=mc^2 \end{equation}\]

Then, you can refer to this equation in your text easily by using something like:

1
The famous matter-energy equation $\eqref{eq1}$ proposed by Einstein...

The famous matter-energy equation \(\eqref{eq1}\) proposed by Einstein...

Multi-line Equations

For multi-line equations, inside the equation environment, you can use the aligned environment to split it into multiple lines:

1
2
3
4
5
6
7
$$\begin{equation} \label{eq2}
\begin{aligned}
a &= b + c \\
&= d + e + f + g \\
&= h + i
\end{aligned}
\end{equation}$$

\[\begin{equation} \label{eq2} \begin{aligned} a &= b + c \\ &= d + e + f + g \\ &= h + i \end{aligned} \end{equation}\]

1
Equation $\eqref{eq2}$ is a multi-line equation.

Equation \(\eqref{eq2}\) is a multi-line equation.

Multiple Aligned Equations

We can use align environment to align multiple equations. Each of these equations will get its own numbers.

1
2
3
4
5
$$\begin{align}
a &= b + c \label{eq3} \\
x &= yz \label{eq4} \\
l &= m - n \label{eq5}
\end{align}$$

\[\begin{align} a &= b + c \label{eq3} \\ x &= yz \label{eq4} \\ l &= m - n \label{eq5} \end{align}\]

1
There are three aligned equations: equation $\eqref{eq3}$, equation $\eqref{eq4}$ and equation $\eqref{eq5}$.

There are three aligned equations: equation \(\eqref{eq3}\), equation \(\eqref{eq4}\) and equation \(\eqref{eq5}\).

Since align in and of itself is a complete equation environment (read here about the difference between aligned and align in LaTeX). You do not need to wrap it with equation environment.

Exclude Equations from Numbering

In the align environment, if you do not want to number one or some equations, just use \nonumber right behind these equations. Like the following:

1
2
3
4
5
$$\begin{align}
-4 + 5x &= 2 + y \nonumber \\
w + 2 &= -1 + w \\
ab &= cb
\end{align}$$

\[\begin{align} -4 + 5x &= 2 + y \nonumber \\ w + 2 &= -1 + w \\ ab &= cb \end{align}\]

Use \tag to Tag Equations

Sometimes, you want to use more «exotic» style to refer your equation. You can use \tag{} to achieve this. For example:

1
$$x+1\over\sqrt{1-x^2} \tag{i}\label{eq_tag}$$

\[x+1\over\sqrt{1-x^2} \tag{i}\label{eq_tag}\]

1
Equation $\eqref{eq_tag}$ use `\tag{}` instead of automatic numbering.

Equation \(\eqref{eq_tag}\) use \tag{} instead of automatic numbering.

二项分布和泊松分布的表达式

  • 二项分布: \[ P(x=k)=C_n^kp^k(1-p)^{n-k}\]

  • 泊松分布: \[P(x=k)=\frac{\lambda^k}{k!}e^{-\lambda}\]

一个现实生活中的例子

一条汽车单向行驶的公路边有个便利店,店家经过一周的统计,得到数据:上个周一共有100辆次的车从这个便利店通过,其中有5辆次的车来买了东西。那么,店家现在想用这个数据来推测,下周,有6辆次的车会在这个便利店买东西的概率是多少?

现在,假设我们只知道二项分布而对泊松分布一无所知,我们如何通过构建二项分布的数学模型来解决这个问题呢?

这是二项分布的经典场景。对于通过的每一辆车,它只有两种可能的观测结果,那就是买东西和不买东西。这是一个 0-1 分布。现在我们做一个假设,假设每辆车通过时停下来买东西的概率是一样的(这样做假设不会影响整体的推测,因为做统计时,我们只统计了通过的车的总辆次和停下来买东西的车的总次数,也就是说做统计时每辆车是没有区别的)。通过买东西的车的总辆次 / 通过的车的总辆次,我们能得到每一辆车的 0-1 分布,任意一辆车停下来买东西的概率 P 为: \(\frac{5}{100}=0.05\)

行为 买东西 不买东西
P 0.05 0.95

现在,我们已经通过对之前统计的数据的分析,知道了任意一辆车通过时停下来买东西的概率。如何通过这个0-1分布来做预测?那就做独立重复实验(也就是伯努利试验),假设有 n 辆车在下个周通过该路口,每辆车停下来买东西的概率都是 p,则有 k 辆车到商店买东西的概率为:

\[P(x=k)=C_n^kp^k(1-p)^{n-k}\]

为此,我们必须颇为无奈地对下个周通过这条路的车的总辆次做个假设,那就是也通过100辆。现在我们就能做预测啦!

\[P(x=6)=C_{100}^{6}\times-.005^6\times(1-0.05)^{100-6}\approx0.15\]

如果以时间为维度来考量,二项分布就会出问题

上一种通过二项分布来做预测的方法,依赖于我们需要做一个假设,即下一个周通过这条路的车的总辆次是100辆。现在我们想绕过需要对总辆次做假设这一障碍,用时间来作为观察的基准。但是因为二项分布所对应的伯努利实验的每一次实验是零散的,所以不得不将连续的时间进行分割。这就要涉及到单位时间,我们不妨把单位时间设置成小时,\(1周=7\times24=168小时\)。根据之前的观察,一共有 5 辆车次的车去到商店买东西,也就是说,每小时有车进商店买东西的概率为 \(P=\frac{5}{168}\approx 0.02976\)。好像,我们又可以像上面那样去建立一个关于单位时间的0-1分布了。但是其实这个模型缺陷就出来了,由于考察的对象是单位时间,它的结果不再只有两个,即该时间段进入商店买东西的车的数量除了01,还可能是2、3、4、…,所以其实用0-1分布来对单位时间进入商店的车的数量进行模拟是不太科学的。

那怎么办呢?自然而然,会想到将单位时间继续分割为更小的单位时间,如果把小时分割为分钟,那每小时就可以做60次独立重复实验,也就是说这下每小时最多可以有60辆车进入商店买东西了。但是这样仍然不满足时间这个连续的度量,要是出现极端情况,每小时有70辆车进入商店呢,这个模型又没法满足了。自然而然,我们想到将时间无限的分割下去。在非常非常小的一段时间里,我们就能做0-1分布的假设了,即在这段时间里只有 01 辆车进入商店买东西。但是无限的分割时间之后,我们还怎么计算这个无穷小的单位时间里车进入商店的概率呢?答案是,根本就不用去计算。因为我们的观测量是一个周汽车进入商店的辆次的总数,不妨把它记为 \(\lambda\),它满足下面的等式:

\[ \lambda = np \]

其中 n 为将一周的时间无限分割成的无穷小的单位时间的总份数,而 p 是分割成这么多份数之后,根据观测值 \(\lambda\) 所计算出来的该单位时间里有车辆进入商店的概率。

从二项式公式推导泊松公式

\[\begin{equation}\label{eq:poisson} \begin{aligned} P(X=k)&=\lim_{n\to\infty} C_n^kp^k(1-p)^{n-k} \\ &= \lim_{n\to\infty} C_n^k(\frac{\lambda}{n})^k(1-\frac{\lambda}{n})^{n-k}\\ &=\lim_{n\to\infty} \frac{n\times(n-1)\times\cdots\times(n-k+1)}{k!}(\frac{\lambda}{n})^k(1-\frac{\lambda}{n})^n(1-\frac{\lambda}{n})^{-k}\\ &=\lim_{n\to\infty} \frac{n\times(n-1)\times\cdots\times(n-k+1)}{k!}\frac{\lambda^k}{n^k}(1-\frac{\lambda}{n})^{-k}(1-\frac{\lambda}{n})^{n}\\ &=1\times\frac{\lambda^k}{k!}\times 1\times e^{-\lambda}\\ &=\frac{\lambda^k}{k!}e^{-\lambda} \end{aligned} \end{equation}\]

推导之后我们发现,其实根本不需要用到 np 这两个数据,而只有观测值 \(\lambda\)。到这里是不是觉得泊松大大干了一件非常有价值的事情!

通过泊松分布来对这个问题进行预测

根据之前的统计, \(\lambda = 5\) \[P(X=6) = \frac{5^6}{6!}e^{-5} \approx 0.1462\]

总结

根据二项分布推导出了泊松分布,并不代表二项分布就没有泊松分布先进,只是对于解决连续时间的这种问题,显然泊松分布更好用。但是有些情况下,二项分布会更好用。

声明

本文引用自:如何深刻理解从二项式分布到泊松分布, 只是对数学公式部分重新编写以适应Next主题。

As you know, the transition to Wayland from the traditional Xorg server in the Linux ecosystem has been a hot topic that caused much controversy and, admittedly, a fair share of troubleshooting.

While Wayland promises a more streamlined and secure interface than its predecessor, Xorg, users have often encountered hurdles, particularly regarding compatibility with NVIDIA graphics cards.

In other words, the journey hasn’t always been without bumps, from rendering issues to compatibility quirks. However, it’s becoming increasingly clear that the NVIDIA and Wayland combo, while not yet a perfect match, is evolving into a viable, working solution for many.

Still, with the proper guidance and a bit of patience, using NVIDIA with Wayland on Arch is not just a possibility but a largely workable solution. You can approach this transition with confidence.

This guide is designed to do precisely this: usher you through the setup process and offer solutions to ensure you can take most of your NVIDIA and Wayland experience on Arch Linux. So, let’s get started.

1、Install NVIDIA Driver

1
sudo pacman -S nvidia nvidia-settings

2、Set Environment Variables

With NVIDIA’s introduction of GBM (Generic Buffer Management) support, a crucial component of the Linux graphics stack that provides an API for allocating buffers for graphics rendering and display, many compositors have adopted it as their default. So, to force GBM as a backend, we need to set some environment variables.

Open the “/etc/environment” file, paste the following two lines, then save the file and exit.

/etc/environment
1
2
GBM_BACKEND=nvidia-drm
__GLX_VENDOR_LIBRARY_NAME=nvidia

Set environment variables.

3、Loading the NVIDIA Modules at System Boot

To ensure that the NVIDIA modules are loaded at the earliest possible stage, i.e., on the system boot, we need to add the ‘nvidia,’ ‘nvidia_modeset,’ ‘nvidia_uvm,’ and ‘nvidia_drm‘ modules to the initramfs – a temporary root file system loaded into memory as part of the boot process before the real root file system is mounted.

This is possible by entering them in the “MODULES” section of the “/etc/mkinitcpio.conf” file. This is a configuration file for mkinitcpio, a tool Arch uses to generate initial ramdisk images.

So, open the “/etc/mkinitcpio.conf” file. Then, enter the modules mentioned above, as the final version should look like this:

/etc/mkinitcpio.conf
1
MODULES=(nvidia nvidia_modeset nvidia_uvm nvidia_drm)

Loading the NVIDIA modules at system boot.

Great, but we’re not done with this file yet. Scroll down and remove the “kms” from the “HOOKS” section. This ensures that the initramfs will avoid including the open-source “nouveau” driver to mess with the work of the proprietary NVIDIA one we have installed and rely on.

Removing KMS from the Hooks.

We’ve finished modifying “/etc/mkinitcpio.conf“. Save your changes and close the file. Next, we’ll proceed to regenerate the initramfs. To do this, execute the following command:

1
sudo mkinitcpio -P

In the command’s output, you might notice messages like “WARNING: Possibly missing firmware for module…” These shouldn’t cause concern and are unrelated to the modifications we are currently implementing.

4、Enable DRM

DRM (Direct Rendering Manager) is a subsystem of the Linux kernel responsible for interfacing with GPUs. It provides a framework for graphics drivers to enable direct access to the graphics hardware, which is crucial for performance in rendering tasks, 3D graphics, video playback, and more.

NVIDIA provides proprietary graphics drivers for Linux that use the DRM subsystem to interact with their GPUs. These drivers are essential for getting the best performance and feature support on NVIDIA hardware under Linux.

Enabling the DRM kernel mode setting is required for Wayland compositors to function properly. So, we will pass it as a parameter to the Linux kernel during its initial boot through the GRUB bootloader.

Open its configuration file/etc/default/grub. Locate the line that begins with “GRUB_CMDLINE_LINUX_DEFAULT” and append “nvidia-drm.modeset=1” to its end. The completed line should resemble the example provided below.

Enabling DRM (Direct Rendering Manager) via GRUB.

Finally, regenerate the GRUB configuration by running:

1
sudo grub-mkconfig -o /boot/grub/grub.cfg

Regenerating the main GRUB configuration file.

5、Testing Wayland with NVIDIA on Arch Linux

You are all set up. Now, reboot your Arch system. At the login screen of the display manager you’re using, choose the Wayland Session option.

Switching to Wayland session on Arch.

Log in and enjoy a seamless Wayland experience with NVIDIA and your beloved Arch Linux.

Arch Linux is running on Wayland with NVIDIA GPU.

In addition, to verify that the NVIDIA DRM settings were correctly applied after a reboot, execute the following command; in response, you should get “Y.”

1
sudo cat /sys/module/nvidia_drm/parameters/modeset

Verifying the NVIDIA DRM settings.

6、设置 nvidia 电源管理

  1. Create a file /etc/modprobe.d/nvidia-power-management.conf with the following content:

    1
    options nvidia NVreg_PreserveVideoMemoryAllocations=1 NVreg_TemporaryFilePath=/var/tmp

  2. sudo update-initramfs -c -k all to re-generate the kernels. 此处我没有执行成功命令,但是并没有影响,系统正常配置成功。

  3. Reboot

  4. Go to suspend mode.

  5. Get an error when trying to load a saved state.

7、配置wayland

经过上述配置后,我发现重启系统将会默认进入到x11, 它是可以正常工作的,效果良好。但是,既然有强大的独立nvidia显卡,我们还是需要设置好nvidia. 下述根据 Wayland and the proprietary NVIDIA driver主操作,详细信息可以参考。

  • 启用nvidia相关服务

    1
    sudo systemctl enable nvidia-suspend.service nvidia-hibernate.service nvidia-resume.service
    此项参考:Preserve video memory after suspend

  • 强制启用Wayland, As of GDM 42 and NVIDIA driver 510, GDM defaults to Wayland. For older NVIDIA drivers (in between version 470 and 510), GDM has chipset-dependent udev rules to use Xorg rather than Wayland. To force-enable Wayland, override these rules by creating the following symlink:

    1
    sudo ln -s /dev/null /etc/udev/rules.d/61-gdm.rules

注意:如果没有第67步,在GNOME桌面环境启动后,GDM不能显示wayland启动选项,而只是默认启动Xorg, 设置好67后,系统正常进入到wayland

8、Bottom Line

In the end, it’s essential to clarify a key point. Our guide has confidently demonstrated that Wayland can operate smoothly with NVIDIA on an Arch system. This, however, does not extend to guaranteeing that every application, game, or desktop environment will also function flawlessly.

The compatibility of these components with Wayland varies and is dependent on the extent to which they have integrated support for it.

For example, desktop environments like KDE Plasma and GNOME offer very good support for Wayland, ensuring a seamless experience. On the other hand, environments like Cinnamon, with only basic Wayland support, may not deliver the same smoothness. So, it’s important to consider these differences.

Similarly, using the Hyprland dynamic tiling Wayland compositor would result in a smooth user experience, whereas others that are still dependent on Xorg may not offer the necessary support for Wayland. This variability in compatibility applies to individual applications too, so it’s important to be aware of potential issues when using specific software.

In conclusion, navigating the complexities of setting up Wayland on Arch can seem daunting, especially for those wielding the power of NVIDIA GPUs, who have historically faced hurdles ranging from rendering glitches to compatibility concerns.

Yet, with the proper knowledge, a dash of perseverance, and our guidance, the hurdles that once seemed impossible begin to shrink to the level that, with the correct setup, NVIDIA and Wayland can indeed create a synergy that brings out the best in your Arch setup.

Finally, we recommend referring to the specific Wayland and NVIDIA sections on the official Arch wiki for a more comprehensive understanding. They provide detailed information on setting up and troubleshooting Wayland and NVIDIA on Arch, making them valuable resources for further exploration.

And, of course, we’d love to hear your feedback or thoughts, so please don’t hesitate to share them in the comment box below.

9、References