Compare commits

..
48 Commits
Author SHA1 Message Date
josh 9785f013c7 new post 2025-07-02 10:12:16 +08:00
josh e722750086 Merge branch 'master' of https://github.com/joshgao22/josh-blog-source 2025-06-26 14:38:29 +08:00
josh 3e39baaee4 update dependencies, config and post 2025-06-26 14:38:07 +08:00
Josh Gao 4009348802 Merge pull request #44 from joshgao22/dependabot/npm_and_yarn/hexo-word-counter-0.2.1
Bump hexo-word-counter from 0.2.0 to 0.2.1
2025-06-17 19:13:59 +08:00
dependabot[bot] 929cb50354 Bump hexo-word-counter from 0.2.0 to 0.2.1
Bumps [hexo-word-counter](https://github.com/next-theme/hexo-word-counter) from 0.2.0 to 0.2.1.
- [Release notes](https://github.com/next-theme/hexo-word-counter/releases)
- [Commits](https://github.com/next-theme/hexo-word-counter/compare/v0.2.0...v0.2.1)

---
updated-dependencies:
- dependency-name: hexo-word-counter
  dependency-version: 0.2.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2025-06-05 03:41:13 +00:00
Josh Gao a190552c0c Merge pull request #43 from joshgao22/dependabot/npm_and_yarn/next-theme/plugins-8.23.1
Bump @next-theme/plugins from 8.23.0 to 8.23.1
2025-06-05 11:40:06 +08:00
Josh Gao 3a0103be03 Merge pull request #42 from joshgao22/dependabot/npm_and_yarn/hexo-theme-next-8.23.1
Bump hexo-theme-next from 8.23.0 to 8.23.1
2025-06-05 11:39:56 +08:00
dependabot[bot] a406b98bac Bump @next-theme/plugins from 8.23.0 to 8.23.1
Bumps [@next-theme/plugins](https://github.com/next-theme/plugins) from 8.23.0 to 8.23.1.
- [Release notes](https://github.com/next-theme/plugins/releases)
- [Commits](https://github.com/next-theme/plugins/compare/v8.23.0...v8.23.1)

---
updated-dependencies:
- dependency-name: "@next-theme/plugins"
  dependency-version: 8.23.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2025-06-04 23:27:41 +00:00
dependabot[bot] be8b9ba539 Bump hexo-theme-next from 8.23.0 to 8.23.1
Bumps [hexo-theme-next](https://github.com/next-theme/hexo-theme-next) from 8.23.0 to 8.23.1.
- [Release notes](https://github.com/next-theme/hexo-theme-next/releases)
- [Commits](https://github.com/next-theme/hexo-theme-next/compare/v8.23.0...v8.23.1)

---
updated-dependencies:
- dependency-name: hexo-theme-next
  dependency-version: 8.23.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2025-06-04 23:27:32 +00:00
Josh Gao 2c43000367 Merge pull request #40 from joshgao22/dependabot/npm_and_yarn/hexo-markmap-2.0.8
Bump hexo-markmap from 1.2.5 to 2.0.8
2025-04-15 08:58:28 +08:00
dependabot[bot] 6b4afd1e42 Bump hexo-markmap from 1.2.5 to 2.0.8
Bumps [hexo-markmap](https://github.com/MaxChang3/hexo-markmap) from 1.2.5 to 2.0.8.
- [Release notes](https://github.com/MaxChang3/hexo-markmap/releases)
- [Commits](https://github.com/MaxChang3/hexo-markmap/compare/v1.2.5...v2.0.8)

---
updated-dependencies:
- dependency-name: hexo-markmap
  dependency-version: 2.0.8
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
2025-04-14 23:40:20 +00:00
josh 08b722f278 feat: add new server 2025-04-12 10:56:13 +08:00
josh 5cd88bb922 Revert "Merge pull request #37 from joshgao22/dependabot/npm_and_yarn/hexo-renderer-pandoc-0.5.0"
This reverts commit 7717b21612, reversing
changes made to 43aebe64fe.

hexo-renderer-pandoc 0.5.0 renders file header latex definition wrongly,
and should be checked later
2025-04-11 12:59:46 +08:00
Josh Gao 4c4201dd8c Merge pull request #39 from joshgao22/dependabot/npm_and_yarn/hexo-markmap-2.0.8
Bump hexo-markmap from 1.2.5 to 2.0.8
2025-04-11 10:58:54 +08:00
Josh Gao 7717b21612 Merge pull request #37 from joshgao22/dependabot/npm_and_yarn/hexo-renderer-pandoc-0.5.0
Bump hexo-renderer-pandoc from 0.4.0 to 0.5.0
2025-04-11 10:58:35 +08:00
Josh Gao 43aebe64fe Merge pull request #36 from joshgao22/dependabot/npm_and_yarn/hexo-generator-searchdb-1.5.0
Bump hexo-generator-searchdb from 1.4.1 to 1.5.0
2025-04-11 10:58:17 +08:00
Josh Gao 43b3a85289 Merge pull request #35 from joshgao22/dependabot/npm_and_yarn/hexo-theme-next-8.23.0
Bump hexo-theme-next from 8.22.0 to 8.23.0
2025-04-11 10:58:05 +08:00
dependabot[bot] 91cdcfa52f Bump hexo-theme-next from 8.22.0 to 8.23.0
Bumps [hexo-theme-next](https://github.com/next-theme/hexo-theme-next) from 8.22.0 to 8.23.0.
- [Release notes](https://github.com/next-theme/hexo-theme-next/releases)
- [Commits](https://github.com/next-theme/hexo-theme-next/compare/v8.22.0...v8.23.0)

---
updated-dependencies:
- dependency-name: hexo-theme-next
  dependency-version: 8.23.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2025-04-11 02:57:34 +00:00
Josh Gao 337f429ea7 Merge pull request #34 from joshgao22/dependabot/npm_and_yarn/next-theme/plugins-8.23.0
Bump @next-theme/plugins from 8.22.0 to 8.23.0
2025-04-11 10:57:04 +08:00
Josh Gao f1c3d5f6bd Merge pull request #30 from joshgao22/dependabot/npm_and_yarn/hexo-theme-landscape-1.1.0
Bump hexo-theme-landscape from 1.0.0 to 1.1.0
2025-04-11 10:56:21 +08:00
dependabot[bot] b688a474a8 Bump hexo-markmap from 1.2.5 to 2.0.8
Bumps [hexo-markmap](https://github.com/MaxChang3/hexo-markmap) from 1.2.5 to 2.0.8.
- [Release notes](https://github.com/MaxChang3/hexo-markmap/releases)
- [Commits](https://github.com/MaxChang3/hexo-markmap/compare/v1.2.5...v2.0.8)

---
updated-dependencies:
- dependency-name: hexo-markmap
  dependency-version: 2.0.8
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
2025-04-08 00:41:18 +00:00
dependabot[bot] 91b8d6c318 Bump hexo-renderer-pandoc from 0.4.0 to 0.5.0
Bumps [hexo-renderer-pandoc](https://github.com/hexojs/hexo-renderer-pandoc) from 0.4.0 to 0.5.0.
- [Commits](https://github.com/hexojs/hexo-renderer-pandoc/commits)

---
updated-dependencies:
- dependency-name: hexo-renderer-pandoc
  dependency-version: 0.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2025-04-03 23:12:13 +00:00
dependabot[bot] 285389294d Bump hexo-generator-searchdb from 1.4.1 to 1.5.0
Bumps [hexo-generator-searchdb](https://github.com/next-theme/hexo-generator-searchdb) from 1.4.1 to 1.5.0.
- [Release notes](https://github.com/next-theme/hexo-generator-searchdb/releases)
- [Commits](https://github.com/next-theme/hexo-generator-searchdb/compare/v1.4.1...v1.5.0)

---
updated-dependencies:
- dependency-name: hexo-generator-searchdb
  dependency-version: 1.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2025-04-01 00:02:29 +00:00
dependabot[bot] fa6b3f6ae2 Bump @next-theme/plugins from 8.22.0 to 8.23.0
Bumps [@next-theme/plugins](https://github.com/next-theme/plugins) from 8.22.0 to 8.23.0.
- [Release notes](https://github.com/next-theme/plugins/releases)
- [Commits](https://github.com/next-theme/plugins/compare/v8.22.0...v8.23.0)

---
updated-dependencies:
- dependency-name: "@next-theme/plugins"
  dependency-version: 8.23.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2025-03-31 23:55:14 +00:00
dependabot[bot] c967373488 Bump hexo-theme-landscape from 1.0.0 to 1.1.0
Bumps [hexo-theme-landscape](https://github.com/hexojs/hexo-theme-landscape) from 1.0.0 to 1.1.0.
- [Release notes](https://github.com/hexojs/hexo-theme-landscape/releases)
- [Commits](https://github.com/hexojs/hexo-theme-landscape/compare/v1.0.0...v1.1.0)

---
updated-dependencies:
- dependency-name: hexo-theme-landscape
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2025-02-14 23:29:39 +00:00
josh 5e51314dfe update packages and deploy server 2025-02-06 08:56:10 +08:00
Josh Gao fb06efb960 Merge pull request #26 from joshgao22/dependabot/npm_and_yarn/hexo-theme-next-8.22.0
Bump hexo-theme-next from 8.21.0 to 8.22.0
2025-02-05 22:20:32 +08:00
Josh Gao 99538a0e9e Merge pull request #28 from joshgao22/dependabot/npm_and_yarn/hexo-related-posts-1.6.2
Bump hexo-related-posts from 1.5.2 to 1.6.2
2025-02-05 22:20:21 +08:00
dependabot[bot] c4b5eecc85 Bump hexo-related-posts from 1.5.2 to 1.6.2
Bumps [hexo-related-posts](https://github.com/sergeyzwezdin/hexo-related-posts) from 1.5.2 to 1.6.2.
- [Release notes](https://github.com/sergeyzwezdin/hexo-related-posts/releases)
- [Commits](https://github.com/sergeyzwezdin/hexo-related-posts/commits/v1.6.2)

---
updated-dependencies:
- dependency-name: hexo-related-posts
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2025-01-15 23:56:18 +00:00
dependabot[bot] 9d9303e03f Bump hexo-theme-next from 8.21.0 to 8.22.0
Bumps [hexo-theme-next](https://github.com/next-theme/hexo-theme-next) from 8.21.0 to 8.22.0.
- [Release notes](https://github.com/next-theme/hexo-theme-next/releases)
- [Commits](https://github.com/next-theme/hexo-theme-next/compare/v8.21.0...v8.22.0)

---
updated-dependencies:
- dependency-name: hexo-theme-next
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2025-01-01 23:04:34 +00:00
josh 25e0a81a87 update posts 2024-10-11 20:58:04 +08:00
Josh Gao 4bcbbf54b0 Merge pull request #23 from joshgao22/dependabot/npm_and_yarn/hexo-theme-next-8.21.0
Bump hexo-theme-next from 8.20.0 to 8.21.0
2024-10-11 20:56:29 +08:00
Josh Gao c191a5af65 Merge pull request #22 from joshgao22/dependabot/npm_and_yarn/next-theme/plugins-8.21.0
Bump @next-theme/plugins from 8.20.0 to 8.21.0
2024-10-11 20:56:21 +08:00
dependabot[bot] 88ce267098 Bump hexo-theme-next from 8.20.0 to 8.21.0
Bumps [hexo-theme-next](https://github.com/next-theme/hexo-theme-next) from 8.20.0 to 8.21.0.
- [Release notes](https://github.com/next-theme/hexo-theme-next/releases)
- [Commits](https://github.com/next-theme/hexo-theme-next/compare/v8.20.0...v8.21.0)

---
updated-dependencies:
- dependency-name: hexo-theme-next
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2024-09-20 23:20:38 +00:00
dependabot[bot] 15aa117543 Bump @next-theme/plugins from 8.20.0 to 8.21.0
Bumps [@next-theme/plugins](https://github.com/next-theme/plugins) from 8.20.0 to 8.21.0.
- [Release notes](https://github.com/next-theme/plugins/releases)
- [Commits](https://github.com/next-theme/plugins/compare/v8.20.0...v8.21.0)

---
updated-dependencies:
- dependency-name: "@next-theme/plugins"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2024-09-20 23:20:26 +00:00
Josh Gao f0adb4a625 Merge pull request #21 from joshgao22/dependabot/npm_and_yarn/hexo-generator-index-4.0.0
Bump hexo-generator-index from 3.0.0 to 4.0.0
2024-08-19 10:19:17 +08:00
dependabot[bot] ae1862be8a Bump hexo-generator-index from 3.0.0 to 4.0.0
Bumps [hexo-generator-index](https://github.com/hexojs/hexo-generator-index) from 3.0.0 to 4.0.0.
- [Release notes](https://github.com/hexojs/hexo-generator-index/releases)
- [Commits](https://github.com/hexojs/hexo-generator-index/compare/v3.0.0...v4.0.0)

---
updated-dependencies:
- dependency-name: hexo-generator-index
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
2024-07-09 23:31:02 +00:00
josh c666cf18aa update posts 2024-07-07 17:12:20 +08:00
josh c8252851cb Merge branch 'master' of https://github.com/joshgao22/josh-blog-source 2024-07-07 17:04:27 +08:00
Josh Gao 56398591e7 Merge pull request #20 from joshgao22/dependabot/npm_and_yarn/hexo-7.3.0
Bump hexo from 7.2.0 to 7.3.0
2024-07-07 17:04:18 +08:00
josh a9ceb54cc6 new post josh-cvx-2.2, update josh-cvx-2.1, new draft zynq-debug-fsbl 2024-07-04 00:29:38 +08:00
dependabot[bot] 4dd6f0ffd3 Bump hexo from 7.2.0 to 7.3.0
Bumps [hexo](https://github.com/hexojs/hexo) from 7.2.0 to 7.3.0.
- [Release notes](https://github.com/hexojs/hexo/releases)
- [Commits](https://github.com/hexojs/hexo/compare/v7.2.0...v7.3.0)

---
updated-dependencies:
- dependency-name: hexo
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2024-07-01 23:52:29 +00:00
josh 5d0a940aea finish post, zynq dynamic ddr configuration 2024-06-28 10:39:55 +08:00
josh 83586f61d9 new post, zynq dynamic ddr configuration 2024-06-28 00:30:08 +08:00
josh ea44545b90 update post sv-1 2024-06-26 00:27:08 +08:00
josh 6218adecc8 update toc of post cvx-2.1 2024-06-24 10:37:04 +08:00
josh 3e4f48e36f finish post cvx-2.1 2024-06-16 13:32:18 +08:00
josh f1d95ce8b4 new post cvx-2.1, new hexo plugin to support mindmap 2024-06-15 16:36:21 +08:00
47 changed files with 5572 additions and 1825 deletions
+2 -2
View File
@@ -367,8 +367,8 @@ codeblock:
# Code Highlight theme # Code Highlight theme
# All available themes: https://theme-next.js.org/highlight/ # All available themes: https://theme-next.js.org/highlight/
theme: theme:
light: default light: vs
dark: github-dark dark: github-dark-dimmed
prism: prism:
light: prism light: prism
dark: prism-dark dark: prism-dark
+12 -18
View File
@@ -110,24 +110,12 @@ theme: next
## Docs: https://hexo.io/docs/one-command-deployment ## Docs: https://hexo.io/docs/one-command-deployment
deploy: deploy:
- type: git - type: git
repo: josh@101.43.227.73:/home/josh/documents/josh-blog-deploy.git repo: josh@129.153.124.210:/home/josh/documents/josh-blog-deploy.git
branch: master
- type: git
repo: [email protected]:/home/josh/documents/josh-blog-deploy.git
branch: master
- type: git
repo: [email protected]:josh-gao/josh-blog/josh-blog.git
branch: master branch: master
- type: git - type: git
repo: https://github.com/joshgao22/joshgao22.github.io.git repo: https://github.com/joshgao22/joshgao22.github.io.git
branch: master branch: master
# MathJax [Redundant]
# math:
# engine: 'mathjax'
# mathjax:
# src: https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.2/es5/tex-mml-chtml.min.js
# Local Search # Local Search
search: search:
path: search.xml path: search.xml
@@ -201,12 +189,18 @@ neat_js:
related_posts: related_posts:
enabled: true enabled: true
enable_env_name: prod
filter_threshold: 0.13 filter_threshold: 0.13
related_count: 5 related_count: 5
weight: weight:
title: 0.1 title: 0.1
description: 0 description: 0.01
keywords: 0 keywords: 0.01
tags: 0.01 tags: 0.005
categories: 0.05 categories: 0.005
text: 0 text: 0.2
# config of hexo-renderer-pandoc
pandoc:
args:
- --mathjax
+2894 -1332
View File
File diff suppressed because it is too large Load Diff
+11 -10
View File
@@ -9,30 +9,31 @@
"server": "hexo server" "server": "hexo server"
}, },
"hexo": { "hexo": {
"version": "7.2.0" "version": "7.3.0"
}, },
"dependencies": { "dependencies": {
"@next-theme/plugins": "^8.20.0", "@next-theme/plugins": "^8.23.1",
"hexo": "^7.2.0", "hexo": "^7.3.0",
"hexo-abbrlink": "^2.2.1", "hexo-abbrlink": "^2.2.1",
"hexo-deployer-git": "^4.0.0", "hexo-deployer-git": "^4.0.0",
"hexo-filter-github-emojis": "^3.0.5", "hexo-filter-github-emojis": "^3.0.5",
"hexo-generator-archive": "^2.0.0", "hexo-generator-archive": "^2.0.0",
"hexo-generator-category": "^2.0.0", "hexo-generator-category": "^2.0.0",
"hexo-generator-index": "^3.0.0", "hexo-generator-index": "^4.0.0",
"hexo-generator-searchdb": "^1.4.1", "hexo-generator-searchdb": "^1.5.0",
"hexo-generator-sitemap": "^3.0.1", "hexo-generator-sitemap": "^3.0.1",
"hexo-generator-tag": "^2.0.0", "hexo-generator-tag": "^2.0.0",
"hexo-helper-live2d": "^3.1.1", "hexo-helper-live2d": "^3.1.1",
"hexo-markmap": "^2.0.8",
"hexo-neat": "^1.0.9", "hexo-neat": "^1.0.9",
"hexo-related-posts": "^1.5.2", "hexo-related-posts": "^1.6.2",
"hexo-renderer-ejs": "^2.0.0", "hexo-renderer-ejs": "^2.0.0",
"hexo-renderer-pandoc": "^0.4.0", "hexo-renderer-pandoc": "^0.5.0",
"hexo-renderer-stylus": "^3.0.1", "hexo-renderer-stylus": "^3.0.1",
"hexo-server": "^3.0.0", "hexo-server": "^3.0.0",
"hexo-tag-cloud": "2.1.*", "hexo-tag-cloud": "2.1.*",
"hexo-theme-landscape": "^1.0.0", "hexo-theme-landscape": "^1.1.0",
"hexo-theme-next": "^8.20.0", "hexo-theme-next": "^8.23.1",
"hexo-word-counter": "^0.2.0" "hexo-word-counter": "^0.2.1"
} }
} }
@@ -0,0 +1,36 @@
---
title: Zynq 系列 SoC / MPSoC 创建可调试的 FSBL
mathjax: true
comments: true
copyright: true
toc:
enable: true
number: true
wrap: true
expand_all: true
max_depth: 4
tags:
- 调试记录
- MPSoC
- RFSoC
- Zynq
- FSBL
categories:
- 调试记录
date: 2024-06-29 16:46:38
---
FSBL 可以初始化 SoC 设备,将所需的应用程序或数据加载到内存,并在目标 CPU 核心上启动应用程序。
在 Vitis 中创建 Platform 时,可以选择同时创建 FSBL,这样 FSBL 就会位于 Platform 下。也可以创建单独的 FSBL 程序,作为普通程序使用,以便进一步修改或调试。
本文以 Zynq UltraScale+ RFSoC 为例,对 FSBL 进行调试。
# 名词释义
- [FSBL](https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842019/Zynq+UltraScale+FSBL#ZynqUltraScale+FSBL-WhatisFSBL?):First Stage Bootloader,第一阶段引导加载程序
- [SoC](https://en.wikipedia.org/wiki/System_on_a_chip):System-on-Chip,片上系统
# 参考文档
[Creating a Debuggable First Stage Boot Loader](https://xilinx.github.io/Embedded-Design-Tutorials/docs/2021.1/build/html/docs/Feature_Tutorials/debuggable-fsbl/debuggable-fsbl.html)
@@ -0,0 +1,35 @@
---
title: Josh's Summary — 工科数学分析<br>Part 1.2 常微分方程
mathjax: true
comments: true
copyright: true
toc:
enable: true
number: true
wrap: true
expand_all: true
max_depth: 4
tags:
- 高等数学
- 数学分析
- 微积分
categories:
- - Josh 的学习笔记
- 高等数学
- - 数学
- 数学分析
abbrlink: 5a263f58
date: 2025-06-26 10:21:02
---
# 常见等价无穷小
1. $\sin x \sim x$
2. $\tan x \sim x$
3. $\arcsin x \sim x$
4. $\arctan x \sim x$
5. $1 - \cos x \sim \frac{x^2}{2}$
6. $\ln(1+x) \sim x$
7. $e^x - 1 \sim x$
8. $a^x - 1 \sim x \ln a$
9. $(1+x)^\alpha - 1 \sim \alpha x$
+199 -163
View File
@@ -15,235 +15,264 @@ date: 2022-05-30 11:40:49
tags: tags:
- SystemVerilog - SystemVerilog
- Testbench - Testbench
- 测试平台
- 验证 - 验证
categories: categories:
- [Josh 的学习笔记, SystemVerilog] - [Josh 的学习笔记, SystemVerilog]
--- ---
在开始学习有关 System Verilog 语言的细节之前,需要理解如何制订计划来验证手中的设计,以及整个验证计划对 testbench 结构的影响。就像所有房子都有厨房、卧室和浴室一样,所有 testbench 也都需要共享一些用于产生激励、检验响应的结构。本文对 testbench 的构建和设计给出一些引导性的建议和编码风格方面的参考,以满足不同的需要。 &emsp;&emsp;在开始学习有关 SystemVerilog 语言的细节之前,我们需要了解如何制订计划来验证手中的设计,以及这个验证计划对测试平台(testbench)结构的影响。所有测试平台都有用于产生激励、检验响应的结构。本文对测试平台的构建和设计给出一些引导性的建议和编码风格方面的参考,以满足不同的需要。
验证工程师能学到的最重要的原则是“Bugs are good”,不要因为害怕 bug 而不敢 debug,每次找到 bug 都应该及时告警并记录下来。任何一个项目中都不可能没有 bug,所以在流片之前每发现一个 bug 都意味着用户手中的产品少一个 bug。我们应该尽可能细致深入地去检验设计,找出所有可能存在的 bug,尽管有时候这些 bug 可能很容易修复。 &emsp;&emsp;对于验证工程师而言,最重要的原则是“有漏洞是好事(Bugs are good)”,要勇于寻找程序中的漏洞,每次找到漏洞都应该及时告警并记录下来。任何一个项目中都不可能没有漏洞,所以在流片之前每发现一个漏洞都意味着用户手中的产品少一个漏洞。我们应该尽可能细致深入地去检验设计,找出所有可能存在的漏洞,尽管有时候这些漏洞可能很容易修复。
本文需要 Verilog 语言基础,面向对 SystemVerilog HVL (Hard­ware Verification Language, 硬件验证语言) 感兴趣的读者。与 HDL (Hardware Description Language, 硬件描述语言) 相比,HVL 具有一些特别的性质: &emsp;&emsp;本文需要 Verilog 语言基础,面向对 SystemVerilog HVL(Hard­ware Verification Language,硬件验证语言)感兴趣的读者。与 HDL(Hardware Description Language,硬件描述语言)相比,HVL 具有一些特别的性质:
1. **约束下的随机激励生成** (*Constrained-random stimulus generation*)。 1. **受约束的随机激励生成**(*Constrained-random stimulus generation*)。
2. **功能覆盖率** (*Functional coverage*)。
3. **更高层次的结构**,尤其是面向对象的编程 (*Higher-level structures*, especially object-oriented programming)。
4. **多线程**及线程间的通信 (*Multithreading* and interprocess communication)。
5. **支持 HDL 数据类型** (*Support for HDL types* such as Verilog’s 4-state values)。
6. **集成了事件仿真器**,便于对设计施加控制 (*Tight integration with event-simulator* for control of the design)。
上述特性使得 HVL 可以创建高度抽象的 testbench,其抽象层次比使用 HDL 或计算机编程语言如 C 所能达到的还要高。 2. **功能覆盖率**(*Functional coverage*)。
3. **更高层次的结构**,尤其是面向对象的编程(*Higher-level structures*, especially object-oriented programming)。
4. **多线程**及线程间的通信(*Multithreading* and interprocess communication)。
5. **支持 HDL 数据类型**(*Support for HDL types*)。
6. **集成了事件仿真器**,便于对设计施加控制(*Tight integration with event-simulator* for control of the design)。
&emsp;&emsp;此外还有其他很多有用的特性,但上述特性使得 HVL 可以创建高度抽象的测试平台,其抽象层次比使用 HDL 或计算机编程语言(如 C 语言)所能达到的还要高。
<!-- more --> <!-- more -->
# 1. 验证流程 # 1. 验证流程
验证的目的是什么?如果说是为了“寻找 bug”,那也只答对了一部分。硬件设计的目的是设计一个**基于设计规范并能完成特定任务的设计**,例如 DVD 播放器、路由器或者雷达信号处理器。验证工程师需要**确保这些设计能够成功地完成预定的任务**——也就是说,确保**设计能够准别表达这些规范**;而设计在超出预定目标之外的行为可以不用关心。 &emsp;&emsp;验证的目的是什么?如果说是为了“寻找漏洞”,那只答对了一部分。硬件设计的目的是设计一个**基于设计规范并能完成特定任务的设备**,例如 DVD 播放器、路由器或者雷达信号处理器。验证工程师需要**确保这些设备能够成功地完成预定的任务**——也就是说,该设计是**对规范的一种准确表达**;而设计在超出预定目标之外的行为可以不用关心。
验证和设计是并行的流程。对于每个设计模块,设计者需要首先了解硬件设计规范/设计输入,理解其中设计需求,然后使用 RTL 代码之类的机器语言创建相应的逻辑。为了完成这个过程,设计者需要知道输入格式、传输函数以及输出格式。在理解设计需求的过程中总是会有模糊的地方,可能因为是设计输入文档本身的表述不清楚,遗漏了细节或者前后不一致。验证工程师必须阅读硬件规范并拟定验证计划,然后按照计划,创建测试来检查 RTL 代码是否准确地实现了满足了所有的规范。 &emsp;&emsp;验证和设计是**并行**的流程。对于每个设计模块,设计工程师需要首先了解硬件设计规范/设计输入,理解其中的设计需求,然后使用 RTL 等的机器语言创建相应的逻辑。为了完成这个过程,设计工程师需要知道输入格式、传输函数以及输出格式。在理解设计需求的过程中总会有一定模糊(ambiguity),可能因为是设计输入文档本身的表述不清楚,遗漏了细节或者前后不一致。验证工程师必须阅读硬件规范并拟定验证计划,然后按照计划,创建测试来检查 RTL 代码是否准确地实现了所有的特性。
如果有多人按照同一规范进行解读,那么设计流程可能会出现冗余。验证工程师的工作是阅读同样的硬件设计规范并对其含义做出独立的判断,然后利用测试来检查对应的 RTL 代码是否与理解相一致。 &emsp;&emsp;如果有多人按照同一规范进行解读,那么设计流程可能会出现冗余。验证工程师的工作是阅读同样的硬件设计规范并对其含义做出独立的判断,然后利用测试来检查对应的 RTL 代码是否与理解相一致。
## 1.1. 不同层次上的测试 ## 1.1. 不同层次的测试
设计中会潜藏着哪些类型的 bug 呢?最容易检测的是在**代码块 (*block*) 层次**上,代码块由每个设计者在模块 (module) 内创建。ALU (Arithmetic-Logic Unit, 运算逻辑单元) 是否正确地执行了两个数的加法?是否每个总线传输都能够成功完成?是否所有的数据包都经过了网络交换机?为了找出这些 bug 而去编写定向测试是一件十分繁琐的事情,原因是这些 bug 都被包含在设计的代码块里。 &emsp;&emsp;设计中会潜藏着哪些类型的漏洞呢?最容易检测的是在**代码块(*block*)层次**上,代码块由每个设计工程师在模块(module)内创建。ALU(Arithmetic-Logic Unit,运算逻辑单元)是否正确地执行了两个数的加法?是否每次总线传输都能够成功完成?是否所有的数据包都经过了网络交换机?为了找出这些漏洞而去编写定向测试是一件十分繁琐的事情,因为这些漏洞都被包含在设计的代码块里。
除了代码块以外,代码块的**输入输出接口**也是 bug 丛生的地方,通常是因为多个设计者对同一规范产生了不同理解。对于一个给定的协议,什么信号发生了变化?在什么时候变化?第一个设计者按照自己对规范的理解建立了一个总线驱动器,第二个设计者也按照自己的理解建立了一个总线接收器,但两者对规范的理解略有不同。我们的工作就是找到两者在硬件逻辑上有冲突的地方,然后将两者进行统一。 &emsp;&emsp;除了代码块以外,代码块的**输入输出接口**也是容易出现漏洞的地方,通常是因为多个设计工程师对同一规范产生了不同理解。对于一个给定的协议,什么信号发生了变化?在什么时候变化?第一个设计工程师按照自己对规范的理解建立了一个总线驱动器,第二个设计工程师也按照自己的理解建立了一个总线接收器,但两者对规范的理解略有不同。**验证工程师的工作就是找到两者在硬件逻辑上有冲突的地方,然后将两者进行统一。**
为了对一个代码块进行仿真,我们需要创建测试集来模拟周围代码块产生激励,这是一件困难而繁琐的事情。好消息是低层次的仿真运行起来会很快。但是,随着代码块数量的增加,可能会在设计和 testbench 中同时找到 bug,因为 testbench 为了提供足够的激励,代码也会很长。当开始对所有的代码块进行合并测试时,它们也会相互激励,测试负担就会相对减少。多个代码块同时仿真可能会发现更多的 bug,但是运行起来也会慢一些。 &emsp;&emsp;为了对一个代码块进行仿真,我们需要创建测试集来模拟周围代码块产生激励,这是一件困难而繁琐的事情。虽然低层次的仿真运行起来会很快,但是随着代码块数量的增加,可能会在设计和测试平台中同时找到漏洞,因为测试平台为了提供足够的激励,代码量也会很长。当开始对所有的代码块进行合并测试时,它们也会相互激励,测试负担就会相对减少。多个代码块同时仿真可能会发现更多的漏洞,但是运行起来也会慢一些。
在 DUT (Design under Test, DUT) 的最高层次中,整个系统都会被测试,但是仿真过程会简单很多。我们的测试应该尽可能让所有的代码块并发活动。所有的输入输出端口都被激活,处理器正在处理数据,而高速缓存也正在载入数据。有了这些行为以后,数据分配和时序上的 bug 肯定会出现。 &emsp;&emsp;在 DUT(Design under Test,待测设计)的最高层次中,整个系统都会被测试,但是仿真过程会简单很多。我们的测试应该尽可能让所有的代码块并发活动。所有的输入输出端口都被激活,处理器正在处理数据,而高速缓存也正在载入数据。有了这些行为以后,数据分配和时序上的漏洞肯定会出现。
在这个层次上,能够运行更加精细的测试,可以**让 DUT 并发执行多种操作以激活尽可能多的代码块**。如果一个 MP3 播放器正在播放音乐时,用户希望从计算机上下载新的音乐会发生什么?在下载的过程中,用户在播放器上按键又会发生什么?显然,一个实际的设备在被使用时,有些用户会去做这些事情,那为什么不在设备制造之初去做同样的测试呢?这种测试可以把易于使用的产品和经常发生故障的产品区分开来。 &emsp;&emsp;在这个层次能够运行更加精细的测试,可以**让 DUT 并发执行多种操作以激活尽可能多的代码块**。如果一个 MP3 播放器正在播放音乐时,用户希望从计算机上下载新的音乐会发生什么?在下载的过程中,用户在播放器上按键又会发生什么?显然,一个实际的设备在被使用时,有些用户会去做这些事情,那为什么不在设备制造之初去做同样的测试呢?这种测试可以把易于使用的产品和经常发生故障的产品区分开来。
一旦验证了 DUT 能够执行所有预期的功能以后,还需要看一下当出现错误时 DUT 会怎样操作。设计是否能应对只进行了一半的事件,已经受损的数据或控制字段?想要列举出所有可能的问题就很困难,更不用说去判断设计会如何从这些错误中恢复了。所以**错误注入和处理 (Error Injection and Handling) 是验证中最具挑战性的部分**。 &emsp;&emsp;一旦验证了 DUT 能够执行所有预期的功能以后,还需要看一下当出现错误时 DUT 会怎样操作。设计是否能应对只进行了一半的事件,已经受损的数据或控制字段?想要列举出所有可能的问题就很困难,更不用说去判断设计会如何从这些错误中恢复了。所以**错误注入和处理(Error Injection and Handling)是验证中最具挑战性的部分**。
随着设计抽象层次的提高,验证的挑战性也会加大。我们可以确定单个信元是否正确通过 ATM (Asynchronous Transfer Mode, 异步传输模式) 路由器,但如果是一系列有着不同优先权的数据流呢?在最高的抽象层次中,下一个操作应该选择哪个信元并不是显而易见的,可能不得不统计成千上万的信元,以便确定这种集总的操作是否正确。 &emsp;&emsp;随着设计抽象层次的提高,验证的挑战性也会加大。我们可以确定单个信元是否正确通过 ATM(Asynchronous Transfer Mode,异步传输模式)路由器,但如果是一系列有着不同优先权的数据流呢?在最高的抽象层次中,下一个操作应该选择哪个信元并不是显而易见的,可能不得不统计成千上万的信元,以便确定这种集总的操作是否正确。
最后,**我们永远也无法证明没有任何遗留的 bug**,所以需要不停地尝试新的验证策略。 &emsp;&emsp;最后,**我们永远也无法证明没有任何遗留的漏洞**,所以需要不停地尝试新的验证策略。
## 1.2. 验证计划 ## 1.2. 验证计划
验证计划和硬件规范是紧密联系在一起的,它描述了需要验证什么样的特性,以及采用哪些技术。这些步骤可能包含有定向测试 (directed test) 或随机测试 (random test) 、断言 (assertion)、软硬件协同验证 (HW/SW co-verification)、硬件仿真 (emulation)、形式验证 (formal proof),以及对验证 IP 的使用等等。有关验证更全面的讨论,可参见 Bergeron 的 *Verification Methodology Manual for &emsp;&emsp;验证计划和硬件规范是紧密联系在一起的,它描述了需要验证什么样的特性,以及采用哪些技术。这些步骤可能包含有定向测试(directed testing)或随机测试(random testing)、断言(assertion)、软硬件协同验证(HW/SW co-verification)、硬件仿真(emulation)、形式验证(formal proof),以及对验证 IP 的使用等等。有关验证更全面的讨论,可参见 Bergeron 的 *Verification Methodology Manual for
SystemVerilog* (2006)。 SystemVerilog*(2006)。
# 2. Testbench 的基本功能 # 2. 测试平台的基本功能
Testbench 的用途在于**确定 DUT 的正确性**。包含下列步骤: &emsp;&emsp;测试平台的用途在于**确定 DUT 的正确性**。包含下列步骤:
1. 产生激励。 1. 产生激励。
2. 把激励施加到 DUT 上。
3. 捕捉响应。
4. 检验正确性。
5. 对照整个验证目标测算进展情况。
有些步骤是 testbench 自动完成的,有些则需要手动操作,所选择的验证方法学决定了上述步骤如何展开。 2. 把激励施加到 DUT 上。
3. 捕捉响应。
4. 检验正确性。
5. 对照整个验证目标测算进展情况。
&emsp;&emsp;有些步骤是测试平台自动完成的,有些则需要手动操作,所选择的验证方法学(methodology)决定了上述步骤如何展开。
# 3. 定向测试 # 3. 定向测试
当需要验证一个设计的正确性时,传统的做法可能是使用定向测试。使用这种方式,首先需要阅读硬件规范,然后写下验证计划,计划上列有各种测试,每个测试针对一系列相关的特性。按照这个计划,接着**编写针对 DUT 具体特性的激励向量,然后使用这些向量对 DUT 进行仿真**。仿真结束后,手动查看一下结果文件和波形,确保设计的行为与预期的一致。一旦测试结果正确,就可以开始下一个测试。 &emsp;&emsp;当需要验证一个设计的正确性时,传统的做法可能是使用**定向测试**(*directed testing*)。使用这种方式,首先需要阅读硬件规范,然后写下验证计划,计划上列有各种测试,每个测试针对一系列相关的特性。按照这个计划,接着**编写针对 DUT 具体特性的激励向量,然后使用这些向量对 DUT 进行仿真**。仿真结束后,手动查看一下结果文件和波形,确保设计的行为与预期的一致。一旦测试结果正确,就可以开始下一个测试。
这种渐进的方法比较容易取得稳步的进展,因而很受那些喜欢看到项目持续向前推进管理者的欢迎。由于创建每个激励向量时并不需要什么基础,所以定向测试的结果也会很快得到。只要给予足够的时间和人力,定向测试对于大部分设计验证来讲都是可以胜任的。 &emsp;&emsp;这种渐进的方法比较容易取得稳步的进展,因而很受那些喜欢看到项目持续向前推进的管理者的欢迎。由于创建每个激励向量时并不需要什么基础,所以定向测试的结果也会很快得到。只要给予足够的时间和人力,定向测试对于大部分设计验证来讲都是可以胜任的。
[图 1](#图1) 显示了定向测试如何逐步覆盖验证计划中的每个特性。每个测试都针对一个特别的设计元素集合。**如果有足够的时间**,可以写出 100% 覆盖整个验证计划所需要的全部测试。 &emsp;&emsp;[图 1](#图1) 显示了定向测试如何逐步覆盖验证计划中的每个特性。每个测试都针对一个特别的设计元素集合。**如果有足够的时间**,可以写出 100% 覆盖整个验证计划所需要的全部测试。
<a id="图1"></a> <a id="图1"></a>
![图 1 定向测试随时间的进展](../images/post/2022-05-30-josh-systemverilog-1/2022-05-30-josh-systemverilog-1-010-DirectedTestProgressOverTime.png){width=500px} ![图 1. 定向测试随时间的进展](../images/post/2022-05-30-josh-systemverilog-1/2022-05-30-josh-systemverilog-1-010-DirectedTestProgressOverTime.png){width=500px}
如果没有足够的时间和资源来完成定向测试该怎么办?如[图 1](#图1),当在时间往前推进时,覆盖率 (coverage) 可能维持不变。如果设计复杂度翻倍,那么测试就需要增加一倍的时间或者人力,而这种情况是我们所不愿意看到的。因此为了达到 100% 覆盖率的目标,需要一种可以更快找出 bug 的方法。 &emsp;&emsp;如果没有足够的时间和资源来完成定向测试该怎么办?如[图 1](#图1),当在时间往前推进时,覆盖率(coverage)可能维持不变。如果设计复杂度翻倍,那么测试就需要增加一倍的时间或者人力,而这种情况是我们所不愿意看到的。因此为了达到 100% 覆盖率的目标,需要一种可以更快找出漏洞的方法。
[图 2](#图2) 所示为整个设计空间和各种特性被定向测试案例覆盖的情形。在设计空间里有很多特性 (feature),其中有些存在 bug,需要编写各种测试 (test) 去覆盖所有的特性并找出 bug。 &emsp;&emsp;[图 2](#图2) 所示为整个设计空间和各种特性被定向测试案例覆盖的情形。在设计空间里有很多特性(feature),其中有些存在漏洞,需要编写各种测试(test)去覆盖所有的特性并找出漏洞。
<a id="图2"></a> <a id="图2"></a>
![图 2 定向测试的覆盖率](../images/post/2022-05-30-josh-systemverilog-1/2022-05-30-josh-systemverilog-1-020-DirectedTestCoverage.png){width=800px} ![图 2. 定向测试的覆盖率](../images/post/2022-05-30-josh-systemverilog-1/2022-05-30-josh-systemverilog-1-020-DirectedTestCoverage.png){width=800px}
# 4. 方法学基础 # 4. 方法学基础
本文使用如下原则: &emsp;&emsp;本文使用如下原则:
1. 约束下的随机激励。 1. 受约束的随机激励。
2. 功能覆盖率。
3. 使用事件处理器的分层 testbench。
4. 对所有测试通用的 testbench。
5. 独立于 testbench 之外的个性化测试代码。
这些原则是相关联的。随机激励对于测试复杂设计十分关键。**定向测试可以找出设计中预期的 bug,而随机测试则能够找出预料不到的 bug**。当使用随机激励时,需要用功能覆盖率来评估验证的进展情况。一旦开始使用自动生成的激励,就需要一种能够**自动预测结果**的方式——通常是记分板或者参考模型。建立包括自预测在内的 testbench 基础设施,是一件工作量很大的事情。分层 testbench (layered testbench) 能够把问题分解为容易处理的小块,这样有助于控制复杂度。事件处理器 (transactors) 能够为构建这些小块提供有用的模式。在适当的规划下,可以建立一个 testbench 所需的基础设施,它们能在所有测试中通用并且不需要经常修改,只需要在某些地方放置“hook”,以便测试能够在这些地方执行调整激励或注入错误等特定操作。相反,针对单一测试的个性化代码必须与 testbench 分开,这样可以避免增加基础设施的复杂度。 2. 功能覆盖率。
建立这种风格的 testbench 所需的时间要比传统的定向 testbench 多得多——尤其是自检的部分。其结果是,可能需要很长的准备时间才能进行第一次可运行的测试。这会给项目管理带来阵痛,所以需要在测试时间表上把这部分考虑进去。从[图 3](#图3) 中可以看到,第一个随机测试运行前有比较长的初始延迟。 3. 使用事件处理器的分层测试平台。
4. 对所有测试通用的测试平台。
5. 独立于测试平台之外的个性化测试代码。
&emsp;&emsp;些原则是相关联的。随机激励对于测试复杂设计十分关键。**定向测试可以找出设计中预期的漏洞,而随机测试则能够找出预料不到的漏洞**。当使用随机激励时,需要用功能覆盖率来评估验证的进展情况。一旦开始使用自动生成的激励,就需要一种能够**自动预测结果**的方式——通常是记分板(scoreboard)或者参考模型(reference model)。建立包括自预测在内的测试平台是一件工作量很大的事情。**分层测试平台**(*layered testbench*)能够把问题分解为容易处理的小块,这样有助于控制复杂度。**事件处理器**(*transactors*)能够为构建这些小块提供有用的模式(pattern)。在适当的规划下,可以建立一个测试平台所需的基础设施,它们能在所有测试中通用并且不需要经常修改,只需要在某些地方放置“钩子(hook)”,以便测试能够在这些地方执行调整激励或注入错误等特定操作。相反,针对单一测试的个性化代码必须与测试平台分开,这样可以避免增加基础设施的复杂度。
&emsp;&emsp;建立这种风格的测试平台所需的时间要比传统的定向测试平台多得多,尤其是自检的部分,因此可能需要很长的准备时间才能进行第一次可运行的测试。这会给项目管理带来阵痛,所以需要在测试时间表上把这部分考虑进去。从[图 3](#图3) 中可以看到,第一个随机测试运行前有比较长的初始延迟。
<a id="图3"></a> <a id="图3"></a>
![图 3 约束下的随机测试与定向测试随时间的进度比较](../images/post/2022-05-30-josh-systemverilog-1/2022-05-30-josh-systemverilog-1-030-ConstraineRandomTestProgressOverTimeVSDirectedTesting.png){width=500px} ![图 3. 受约束的随机测试与定向测试随时间的进度比较](../images/post/2022-05-30-josh-systemverilog-1/2022-05-30-josh-systemverilog-1-030-ConstraineRandomTestProgressOverTimeVSDirectedTesting.png){width=500px}
随机测试的前期准备工作看起来似乎令人不满意,但是其回报却很高。每个随机测试都可以共享这个通用的 testbench,不像每个定向测试都要从零开始编写。每个随机测试都会包含一部分代码,将激励约束到特定的方向上并触发期望的异常,比如创建一个协议违例。其结果是,约束下的随机 testbench 找起 bug 来会比很多定向测试快很多。随着 bug 出现率的下降,应该创建新的随机约束去探索新的区域。最后的几个 bug 可能只能通过定向测试来发现,但是绝大部分的 bug 都应该会在随机测试中出现。 &emsp;&emsp;随机测试的前期准备工作看起来似乎令人不满意,但是其回报却很高。每个随机测试都可以共享这个通用的测试平台,不像每个定向测试都要从零开始编写。每个随机测试都会包含一部分代码,将激励约束到特定的方向上并触发期望的异常,比如创建一个协议违例(protocol violation),受约束的随机测试平台找起漏洞来会比很多定向测试快很多。
# 5. 约束下的随机激励<a name="05"></a> &emsp;&emsp;随着漏洞出现率的下降,应该创建新的随机约束去探索新的区域。最后的几个漏洞可能只能通过定向测试来发现,但是绝大部分的漏洞都应该会在随机测试中出现。
虽然我们希望仿真器能产生随机激励,但同时又**不希望这些激励数值完全随机**。使用 SystemVerilog 语言可以描述激励的格式 (例如,地址是 32 位;操作码是 ADD 、 SUB 或 STORE;长度 < 32 字节),然后让仿真器产生满足约束的数值。这些数值会被发送到设计中去,同时也会被发送到一个负责预测仿真结果的高层模块中去。设计的实际输出最终需要和预测输出做对比。 # 5. 受约束的随机激励<a name="05"></a>
[图 4](#图4) 所示为约束下的随机测试在整个设计空间中的覆盖率。 &emsp;&emsp;虽然我们希望仿真器能产生随机激励,但同时又**不希望这些激励数值完全随机**。使用 SystemVerilog 语言可以描述激励的格式(例如,地址是 32 位;操作码是 ADD、 SUB 或 STORE;长度 < 32 字节),然后让仿真器产生满足约束的数值。这些数值会被发送到设计中去,同时也会被发送到一个负责预测仿真结果的高层模块中去。设计的实际输出最终需要和预测输出做对比。
- 值得注意的是,**一个随机测试的覆盖范围往往比一个定向测试大**。多出来的覆盖部分可能会与其他测试发生交叠,或者探测到事先没有预料到的新区域 (new area)。 &emsp;&emsp;[图 4](#图4) 所示为受约束的随机测试在整个设计空间中的覆盖率。
- 在这些新区域中发现 bug 是一件幸运的事情。如果这些对新区域的测试不合法,则需要编写更多的约束去阻止随机测试产生非法的功能。
- 对于那些约束下的随机测试覆盖不到的地方,可能还需要编写一些定向测试。 - 值得注意的是,**一个随机测试的覆盖范围往往比一个定向测试大**。多出来的覆盖部分可能会与其他测试发生交叠,或者探测到事先没有预料到的新区域(new area)。
- 在这些新区域中发现漏洞是一件幸运的事情。如果这些对新区域的测试不合法,则需要编写更多的约束去阻止随机测试产生非法的功能。
- 对于那些受约束的随机测试覆盖不到的地方,可能还需要编写一些定向测试。
<a id="图4"></a> <a id="图4"></a>
![图 4 约束下的随机测试覆盖率](../images/post/2022-05-30-josh-systemverilog-1/2022-05-30-josh-systemverilog-1-040-ConstrainedRandomTestCoverage.png){width=800px} ![图 4. 受约束的随机测试覆盖率](../images/post/2022-05-30-josh-systemverilog-1/2022-05-30-josh-systemverilog-1-040-ConstrainedRandomTestCoverage.png){width=800px}
[图 5](#图5) 所示为达到完全覆盖的技术路线: &emsp;&emsp;[图 5](#图5) 所示为达到完全覆盖的技术路线:
1. 从左上角的基本的约束下的随机测试 (constrained random test) 开始,使用不同的种子 (seed) 运行。 1. 从左上角的基本的受约束的随机测试(constrained random test)开始,使用不同的种子(seed)运行。
2. 当我们查看功能覆盖率 (functional coverage) 报告时,注意找出覆盖率中的间隙 (hole),即覆盖盲区。
3. 针对这些盲区进行最小程度代码修改 (minimal code modification),可能是使用新的约束 (constraint),也可能是把错误或延迟加入到 DUT 中。这个外部循环会花掉我们大部分的时间,只有对少数使用随机测试达不到的特性才编写定向测试。 2. 当我们查看功能覆盖率(functional coverage)报告时,注意找出覆盖率中的间隙(hole),即覆盖盲区。
3. 针对这些盲区进行最小程度代码修改(minimal code modification),可能是使用新的约束(constraint),也可能是把错误或延迟加入到 DUT 中。这个外部循环会花掉我们大部分的时间,只有对少数使用随机测试达不到的特性才编写定向测试。
<a id="图5"></a> <a id="图5"></a>
![图 5 覆盖率收敛](../images/post/2022-05-30-josh-systemverilog-1/2022-05-30-josh-systemverilog-1-050-CoverageConvergence.png){width=500px} ![图 5. 覆盖率收敛](../images/post/2022-05-30-josh-systemverilog-1/2022-05-30-josh-systemverilog-1-050-CoverageConvergence.png){width=500px}
# 6. 我们的随机化对象是什么<a name="06"></a> # 6. 我们的随机化对象是什么<a name="06"></a>
当考虑对一个设计的激励进行随机化时,首先想到的可能是数据字段。这种激励最容易创建——只需调用 `$random()` 即可。问题是这种随机数据在找 bug 方面的回报很小。能够使用随机数据找到的 bug 类型基本上都是在数据路径上的,很可能还都是比特级的错误,还需要找出**控制逻辑上的 bug**。 &emsp;&emsp;当考虑对一个设计的激励进行随机化时,首先想到的可能是数据字段。这种激励最容易创建——只需调用 `$random()` 即可。问题是这种随机数据在找漏洞方面的回报很小。能够使用随机数据找到的漏洞类型基本上都是在数据路径上的,很可能还都是比特级的错误,还需要找出**控制逻辑上的漏洞**。
此外,需要广泛地考虑所有的设计输入,如下所列: &emsp;&emsp;此外,需要广泛地考虑所有的设计输入,如下所列:
1. 设备配置。 1. 设备配置。
2. 环境配置。
3. 输入数据。 2. 环境配置。
4. 协议异常。
5. 错误和违例。 3. 输入数据。
6. 时延。
4. 协议异常。
5. 错误和违例。
6. 时延。
## 6.1. 设备和环境配置 ## 6.1. 设备和环境配置
在对 RTL 设计进行测试的过程中,察觉不到 bug 的最常见的原因是什么?是因为**没有尝试足够多的不同配置**。很多测试只使用了仅仅经过复位的设计,或者施加固定的初始化向量集把设计引向一个已知的状态。这就好比是在个人电脑上刚刚安装完操作系统,还没有安装任何应用程序的时候,就对操作系统进行测试。测试结果当然会很好,但是并没有挖掘出实际的问题。 &emsp;&emsp;在对 RTL 设计进行测试的过程中,察觉不到漏洞的最常见的原因是什么?是因为**没有尝试足够多的不同配置(*configuration*)**。很多测试只使用了仅仅经过复位的设计,或者施加固定的初始化向量集把设计引向一个已知的状态。这就好比是在个人电脑上刚刚安装完操作系统,还没有安装任何应用程序的时候,就对操作系统进行测试。测试结果当然会很好,但是并没有挖掘出实际的问题。
在一个实际的应用环境中,随着 DUT 使用时间的增加,其配置会变得越来越随机。例如,验证一个分时复用的多路开关,它有 2000 个输入通道和 12 个输出通道。这些通道在另外一边可以映射成各种不同的配置。每个输入可能作为单个通道使用,也可能会被进一步分割成多个通道。棘手的是,虽然大部分时间里使用的是几种标准的通道分割方式,但由于其他分割方式的组合也是合法的,所以存在着大量可能的用户配置。 > &emsp;&emsp;在一个实际的应用环境中,随着 DUT 使用时间的增加,其配置会变得越来越随机。例如,验证一个分时复用的多路开关,它有 2000 个输入通道和 12 个输出通道。这些通道在另外一边可以映射成各种不同的配置。每个输入可能作为单个通道使用,也可能会被进一步分割成多个通道。棘手的是,虽然大部分时间里使用的是几种标准的通道分割方式,但由于其他分割方式的组合也是合法的,所以存在着大量可能的用户配置。
>
> &emsp;&emsp;为了测试这个设备,对于每个通道的配置,工程师都必须写出好几十行的定向测试代码。显然,验证工程师无力应对如此多的通道配置。后来编写了一个测试平台,对每个通道的参数都采用随机化策略,然后把这部分代码放到一个循环里去完成所有开关通道的配置。现在,找出与配置相关的漏洞变得更加容易,而这些漏洞在以前常常不被察觉。
为了测试这个设备,对于每个通道的配置,工程师都必须写出好几十行的定向测试代码。显然,验证工程师无力应对如此多的通道配置。后来编写了一个 testbench,对每个通道的参数都采用随机化策略,然后把这部分代码放到一个循环里去完成所有开关通道的配置。现在,找出与配置相关的 bug 变得更加容易,而这些 bug 在以前常常不被察觉。 &emsp;&emsp;在实际的应用中,我们的设计所在的环境里会包含其他的部件。当对 DUT 进行验证时,实际上就是把测试平台连接起来模仿这个环境,应该对整个环境的配置进行随机化,包括仿真的时长、设备的数量,以及它们的配置方式。当然,需要创建约束以确保配置的合法性。
在实际的应用中,我们的设计所在的环境里会包含其他的部件。当对 DUT 进行验证时,实际上就是把 testbench 连接起来模仿这个环境,应该对整个环境的配置进行随机化,包括仿真的时长、设备的数量,以及它们的配置方式。当然,需要创建约束以确保配置的合法性。 > &emsp;&emsp;在另外一个 Synopsys 公司的客户案例中,一家公司设计了一个 I/O 交换芯片,用于把多套 PCI 总线连接到一套内部总线上。在仿真一开始,他们就随机地选择了 PCI 总线的数目(1\~4)以及总线上设备的数目(1\~8),而且对每个设备上的参数也进行了随机化(如主从模式、 CSR 地址等等)。他们使用功能覆盖率对测试过的组合进行跟踪,以确保所有可能的组合都被覆盖。
在另外一个 Synopsys 公司的客户案例中,一家公司设计了一个 I/O 交换芯片,用于把多套 PCI 总线连接到一套内部总线上。在仿真一开始,他们就随机地选择了 PCI 总线的数目 (1~4) 以及总线上设备的数目 (1~8),而且对每个设备上的参数也进行了随机化(如主从模式、 CSR 地址等等)。他们使用功能覆盖率对测试过的组合进行跟踪,以确保所有可能的组合都被覆盖。 &emsp;&emsp;其他环境参数还包括测试长度、错误注入比率,以及时延模式等。Bergeron(2006)在这方面有更多的例子。
其他环境参数还包括测试长度、错误注入比率,以及时延模式等。Bergeron (2006) 在这方面有更多的例子。
## 6.2. 输入数据 ## 6.2. 输入数据
当看到随机激励时,我们可能会想到**选取一个总线写入的事件或 ATM 信元,然后把随机数值填充到其中的数据字段里**。实际上,这种方式相当直接,需要事先估计好所有的分层协议和错误注入,以及记分板的内容和功能覆盖率。 &emsp;&emsp;当看到随机激励时,我们可能会想到**选取一个总线写入的事件或 ATM 信元,然后把随机数值填充到其中的数据字段里**。实际上,这种方式相当直接,需要事先估计好所有的分层协议和错误注入,以及记分板的内容和功能覆盖率。
## 6.3. 协议异常、错误和违例 ## 6.3. 协议异常、错误和违例
最令人沮丧的事情莫过于个人电脑或移动电话之类的设备死机。大多数情况下,唯一的办法就是关机然后重新启动。死机最有可能的原因是,产品内部的一部分逻辑遇到了错误以后无法恢复过来,因此使得设备不能正常工作。 &emsp;&emsp;最令人沮丧的事情莫过于个人电脑或移动电话之类的设备死机。大多数情况下,唯一的办法就是关机然后重新启动。死机最有可能的原因是,产品内部的一部分逻辑遇到了错误以后无法恢复过来,因此使得设备不能正常工作。
如何才能阻止这些问题出现在我们创建的硬件上呢?应该尽量尝试去仿真在实际的硬件中可能出现的错误,而且应该针对所有可能出现的错误。如果一个总线事件没有完成会怎么样?如果遇到一个非法的操作呢?设计规范中有没有指出哪两个信号互斥?要对这些情况一一尝试,然后确保设备还能继续正常运作。 &emsp;&emsp;如何才能阻止这些问题出现在我们创建的硬件上呢?应该尽量尝试去仿真在实际的硬件中可能出现的错误,而且应该针对所有可能出现的错误。如果一个总线事件没有完成会怎么样?如果遇到一个非法的操作呢?设计规范中有没有指出哪两个信号互斥?要对这些情况一一尝试,然后确保设备还能继续正常运作。
**在尝试使用不当的命令去激励硬件的同时,也应该注意捕捉出现的问题**。例如,重新调用那些互斥的信号。可以增加用于检验的代码来帮忙找出问题所在。这些代码应该至少能够在出错的地方打印一个警告信息,如果能够报告出错误并且使测试停下来则更好。花费大最时间在代码中追溯故障的根源,是一件令人非常不愉快的事情,尤其是在本来如果使用一个简单的断言就可以定位这个错误的情况下。(关于如何在 testbench 和设计代码中编写断言,可以参考 Vijayaraghavan 和 Ramanathan 在 2005 出版的著作。) 只要确保能够使代码在出错的地方停止仿真,那么就很容易应对测试中的错误。 &emsp;&emsp;**在尝试使用不当的命令去激励硬件的同时,也应该注意捕捉出现的问题**。例如,重新调用那些互斥的信号。可以增加用于检验的代码来帮忙找出问题所在。这些代码应该至少能够在出错的地方打印一个警告信息,如果能够报告出错误并且使测试停下来则更好。花费大最时间在代码中追溯故障的根源,是一件令人非常不愉快的事情,尤其是在本来如果使用一个简单的断言就可以定位这个错误的情况下。(关于如何在测试平台和设计代码中编写断言,可以参考 Vijayaraghavan 和 Ramanathan 在 2005 出版的著作。)只要确保能够使代码在出错的地方停止仿真,那么就很容易应对测试中的错误。
## 6.4. 时延和同步 ## 6.4. 时延和同步
Testbench 应该以多快的速度发送激励呢?使用**约束下的随机时延**有助于捕捉协议上的 bug。时延最短的测试运行速度最快,但它产生不了所有可能的激励。可以创建一个 testbench 以最快的速度与另一个代码块通信,但那些隐蔽的 bug 往往是在引入间歇性时延之后才被发现的。 &emsp;&emsp;测试平台应该以多快的速度发送激励呢?使用**受约束的随机时延**有助于捕捉协议上的漏洞。时延最短的测试运行速度最快,但它产生不了所有可能的激励。可以创建一个测试平台以最快的速度与另一个代码块通信,但那些隐蔽的漏洞往往是在引入间歇性时延之后才被发现的。
一个代码块对于来自同一接口的所有可能激励也许都能正常工作,但如果同时面对多个输入,隐蔽的 bug 可能就会出现。尝试协调各个驱动器使它们能够在不同的速率下进行通信。如果输入以可能的最快速率到达,而输出却被卡在一个较低的速率上,该怎么办?如何处理来自多个输人的激励同时到达的情况?如果这此激励带有不同的时延又该怎么办?使用功能覆盖率,可以测量随机生成的各种组合。 &emsp;&emsp;一个代码块对于来自同一接口的所有可能激励也许都能正常工作,但如果同时面对多个输入,隐蔽的漏洞可能就会出现。尝试协调各个驱动器使它们能够在不同的速率下进行通信。如果输入以可能的最快速率到达,而输出却被卡在一个较低的速率上,该怎么办?如何处理来自多个输人的激励同时到达的情况?如果这此激励带有不同的时延又该怎么办?使用功能覆盖率,可以测量随机生成的各种组合。
## 6.5. 并行的随机测试 ## 6.5. 并行的随机测试
如何运行测试?每个定向测试都带有一个 testbench,能够产生一组特定的激励和响应向量。如果想改变激励,就需要改变测试。随机测试则包含了 testbench 代码和随机种子。如果对同一个测试运行 50 次,每次都采用不同的种子,那么将会得到 50 个不同的激励集合。使用多个种子运行同一个测试可以加大覆盖率,同时也能减少工作量。 &emsp;&emsp;如何运行测试?每个定向测试都带有一个测试平台,能够产生一组特定的激励和响应向量。如果想改变激励,就需要改变测试。随机测试则包含了测试平台代码和随机种子。如果对同一个测试运行 50 次,每次都采用不同的种子,那么将会得到 50 个不同的激励集合。使用多个种子运行同一个测试可以加大覆盖率,同时也能减少工作量。
我们需要**为每次仿真选定一个独特的种子**。有些人使用自然时间作为种子,但这依然会引起重复。如果半夜里在一个计算机集群系统上开始 10 项任务会怎么样?多项任务可能会于同一时间在不同的计算机上启动,这样还是会得到相同的随机种子并运行相同的激励。因此,应该把处理器的名称加入到种子里去。如果集群系统里面有多核计算机,那还是可能会出现两个相同的种子,所以在这种情况下应该把处理器核的编号也加到种子里去,这样就能得到独一无二的种子了。 &emsp;&emsp;我们需要**为每次仿真选定一个独特的种子**。有些人使用自然时间作为种子,但这依然会引起重复。如果半夜里在一个计算机集群系统上开始 10 项任务会怎么样?多项任务可能会于同一时间在不同的计算机上启动,这样还是会得到相同的随机种子并运行相同的激励。因此,应该把处理器的名称加入到种子里去。如果集群系统里面有多核计算机,那还是可能会出现两个相同的种子,所以在这种情况下应该把处理器核的编号也加到种子里去,这样就能得到独一无二的种子了。
> 我们还需要对并行仿真的文件组织进行规划。每次仿真都会有一系列的输出文件,例如日志文件和功能覆盖率文件,可以让每个仿真在不同的目录里运行,或者也可以尝试给每个文件取不同的名字。最简单的办法是在目录名后面加上随机种子的值。 {% note info %}
&emsp;&emsp;我们还需要对并行仿真的文件组织进行规划。每次仿真都会有一系列的输出文件,例如日志文件和功能覆盖率文件,可以让每个仿真在不同的目录里运行,或者也可以尝试给每个文件取不同的名字。最简单的办法是在目录名后面加上随机种子的值。
{% endnote %}
# 7. 功能覆盖率 # 7. 功能覆盖率
本文[第 5 节](#05)和[第 6 节](#06)讲述了如何创建激励并使这些激励遍历整个可能的输入空间。使用这种方法,Testbench 会频繁访问部分区域,但需要花费很长的时间来达到所有可能的状态。即使对仿真时间不加限制,无法达到的状态还是永远也不会被访问到,因此需要知道哪些部分已经被验证过,这样才能对验证计划中的项目进行核对。 &emsp;&emsp;本文[第 5 节](#05)和[第 6 节](#06)讲述了如何创建激励并使这些激励遍历整个可能的输入空间。使用这种方法,测试平台会频繁访问部分区域,但需要花费很长的时间来达到所有可能的状态。即使对仿真时间不加限制,无法达到的状态还是永远也不会被访问到,因此需要知道哪些部分已经被验证过,这样才能对验证计划中的项目进行核对。
对功能覆盖率的测量和使用包含了几个步骤。首先,需要在 testbench 中加入代码,用于监控进入设备中的激励,以及设备对激励的反应,并据此确定哪些功能已经被验证过。运行几次仿真,每次使用不同的种子。接下来,把这些仿真的结果合并到一个报告中。然后需要对结果进行分析,最后决定如何采用新的激励来达到那些尚未被测试到的条件和逻辑。 &emsp;&emsp;对功能覆盖率的测量和使用包含了几个步骤。首先,需要在测试平台中加入代码,用于监控进入设备中的激励,以及设备对激励的反应,并据此确定哪些功能已经被验证过。运行几次仿真,每次使用不同的种子。接下来,把这些仿真的结果合并到一个报告中。然后需要对结果进行分析,最后决定如何采用新的激励来达到那些尚未被测试到的条件和逻辑。
## 7.1. 从功能覆盖率到激励的反馈 ## 7.1. 从功能覆盖率到激励的反馈
随机测试需要使用反馈 (feedback)。最初的测试会被运行很多次,使用不同的种子,创建很多互异的输入序列。但是到了最后,即使使用新的种子,所产生的激励也很可能无法在设计空间中探测到新区域。**随着功能覆盖率逐渐接近极限,需要改变测试,以期能找出新的方法去达到那些尚未被覆盖的区域**。这被称为“覆盖率驱动的验证”,如[图 6](#图6) 所示。 &emsp;&emsp;随机测试需要使用反馈(feedback)。最初的测试会被运行很多次,使用不同的种子,创建很多互异的输入序列。但是到了最后,即使使用新的种子,所产生的激励也很可能无法在设计空间中探测到新区域。**随着功能覆盖率逐渐接近极限,需要改变测试,以期能找出新的方法去达到那些尚未被覆盖的区域**。这被称为“覆盖率驱动的验证”,如[图 6](#图6) 所示。
<a id="图6"></a> <a id="图6"></a>
![图 6 带反馈和不带反馈的测试进展](../images/post/2022-05-30-josh-systemverilog-1/2022-05-30-josh-systemverilog-1-060-TestProgressWithAndWithoutFeedback.png){width=500px} ![图 6. 带反馈和不带反馈的测试进展](../images/post/2022-05-30-josh-systemverilog-1/2022-05-30-josh-systemverilog-1-060-TestProgressWithAndWithoutFeedback.png){width=500px}
Testbench 有没有可能为我们做到这一点呢?假设现在需要使用 testbench 在每个周期为处理器产生一个总线事件,并为总线事件做出终止判断(成功、校验错误、重试)。在没有使用 HVL 的时候,通常会编写一个很长的定向测试集,然后花费了很多天的工夫编排终止判断代码,并让它们在合适的周期里给出判断。经过了大量的手动分析以后才得出成功的结论达到 100 %的覆盖率。但之后可能由于处理器的时序有了一点微小的改变,不得不重新分析测试并改变激励。 &emsp;&emsp;测试平台有没有可能为我们做到这一点呢?假设现在需要使用测试平台在每个周期为处理器产生一个总线事件,并为总线事件做出终止判断(成功、校验错误、重试)。在没有使用 HVL 的时候,通常会编写一个很长的定向测试集,然后花费了很多天的工夫编排终止判断代码,并让它们在合适的周期里给出判断。经过了大量的手动分析以后才得出成功的结论达到 100 %的覆盖率。但之后可能由于处理器的时序有了一点微小的改变,不得不重新分析测试并改变激励。
更加有效的测试策略是**使用随机总线事件和终止判断**。运行的时间越长,覆盖率就会越高。另外的一个好处是,这种测试在创建激励时灵活性很高,足以应对设计时序有改变的情形。为了做到这一点,可以在测试代码中加入一个反馈循环,用于监测己生成的激励 (是否已经产生所有写周期?) 并根据情况调整约束的权重 (把写的权重降到零)。这种改进能大大缩减达到完全覆盖的时间,而且只需要很少量的人工干预。 &emsp;&emsp;更加有效的测试策略是**使用随机总线事件和终止判断**。运行的时间越长,覆盖率就会越高。另外的一个好处是,这种测试在创建激励时灵活性很高,足以应对设计时序有改变的情形。为了做到这一点,可以在测试代码中加入一个反馈循环,用于监测己生成的激励(是否已经产生所有写周期?)并根据情况调整约束的权重(把写的权重降到零)。这种改进能大大缩减达到完全覆盖的时间,而且只需要很少量的人工干预。
其实,这并不是一种典型的情况,因为从功能覆盖率到激励的反馈往往是微不足道的。在实际的设计中,应该如何改变激励以使它达到一个期望的设计状态呢?这不仅要求对设计有深入的了解,而且还需要高超的形式验证技术。总之答案并不简单,所以**在约束下的随机激励中很少采用动态反馈**。相反地,**需要手动分析覆盖率报告,然后调整随机约束**。 &emsp;&emsp;其实,这并不是一种典型的情况,因为从功能覆盖率到激励的反馈往往是微不足道的。在实际的设计中,应该如何改变激励以使它达到一个期望的设计状态呢?这不仅要求对设计有深入的了解,而且还需要高超的形式验证技术。总之答案并不简单,所以**在受约束的随机激励中很少采用动态反馈**。相反地,**需要手动分析覆盖率报告,然后调整随机约束**。
有些形式分析工具如 Magellan (Synopsys, 2003) 用到了反馈。它首先对设计进行分析并找出所有可以达到的互异状态。然后运行一小段仿真看有多少状态被访问到。最后,在状态机和设计输入之间进行搜索并计算出达到所有遗留状态所需要的激励,然后 Ma­gellan 再把这些激励施加到 DUT 上。 &emsp;&emsp;有些形式分析工具如 Magellan(Synopsys, 2003)用到了反馈。它首先对设计进行分析并找出所有可以达到的互异状态。然后运行一小段仿真看有多少状态被访问到。最后,在状态机和设计输入之间进行搜索并计算出达到所有遗留状态所需要的激励,然后 Ma­gellan 再把这些激励施加到 DUT 上。
# 8. Testbench 的构建 # 8. 测试平台的构建
在仿真时,**testbench 会把整个 DUT 包围起来**,就像一个硬件测试器连接到一个物理芯片上一样,如[图 7](#图7) 所示。testbench 和测试仪器都会产生激励并捕捉响应。不同的是,testbench 需要工作在一个很宽的抽象层次范围内,同时创建事件和激励序列并最终转换成比特向量。而测试仪器则只工作在比特级上。 &emsp;&emsp;在仿真时,**测试平台会把整个 DUT 包围起来**,就像一个硬件测试器连接到一个物理芯片上一样,如[图 7](#图7) 所示。测试平台和测试仪器都会产生激励并捕捉响应。不同的是,测试平台需要工作在一个很宽的抽象层次范围内,同时创建事件和激励序列并最终转换成比特向量。而测试仪器则只工作在比特级上。
<a id="图7"></a> <a id="图7"></a>
![图 7 Testbench 与设计环境](../images/post/2022-05-30-josh-systemverilog-1/2022-05-30-josh-systemverilog-1-070-TheTestbenchDesignEnvironment.png){width=450px} ![图 7. 测试平台与设计环境](../images/post/2022-05-30-josh-systemverilog-1/2022-05-30-josh-systemverilog-1-070-TheTestbenchDesignEnvironment.png){width=450px}
Testbench 模块里都包含了什么呢?有很多的 BFM (Bus Functional Models, 总线功能模型),可以把它们看成是 testbench 构件 (components) ——从 DUT 的角度看,它们和真实的构件没什么两样,但它们其实只是 testbench 的组成部分,并非 RTL 设计。如果实际应用中设备被连接到 AMBA、USB、PCI 和 SPI 总线上,那么就必须**在 testbench 中建立能够产生激励并校验响应的等效构件**,如[图 8](#图8) 所示。这些构件并不是带有细节的可综合模型,而是遵循协议并且执行速度更快的高层次事件处理器。如果把设计原型在 FPGA 上实现或者是进行硬件仿真,那么这些 BFM 就需要是可综合的。 &emsp;&emsp;测试平台模块里都包含了什么呢?有很多的 BFM(Bus Functional Models, 总线功能模型),可以把它们看成是测试平台构件(components)——从 DUT 的角度看,它们和真实的构件没什么两样,但它们其实只是测试平台的组成部分,并非 RTL 设计。如果实际应用中设备被连接到 AMBA、USB、PCI 和 SPI 总线上,那么就必须**在测试平台中建立能够产生激励并校验响应的等效构件**,如[图 8](#图8) 所示。这些构件并不是带有细节的可综合模型,而是遵循协议并且执行速度更快的高层次事件处理器。如果把设计原型在 FPGA 上实现或者是进行硬件仿真,那么这些 BFM 就需要是可综合的。
<a id="图8"></a> <a id="图8"></a>
![图 8 Testbench 构件](../images/post/2022-05-30-josh-systemverilog-1/2022-05-30-josh-systemverilog-1-080-TestbenchComponents.png){width=450px} ![图 8. 测试平台构件](../images/post/2022-05-30-josh-systemverilog-1/2022-05-30-josh-systemverilog-1-080-TestbenchComponents.png){width=450px}
# 9. 分层 testbench # 9. 分层测试平台
对于任何一种新型的验证方法学来讲,分层的 testbench 是一个关键的概念。虽然分层似乎会使 testbench 变得更复杂,但它能够把代码分而治之,**有助于减轻工作负担**。不要试图去编写一个包含所有功能 (随机产生所有合法和非法的激励,并使用多层协议进行错误注入) 的子程序,因为这样的子程序很快就会变得很复杂,并且难以维护。 &emsp;&emsp;对于任何一种新型的验证方法学来讲,分层的测试平台是一个关键的概念。虽然分层似乎会使测试平台变得更复杂,但它能够把代码分而治之,**有助于减轻工作负担**。不要试图去编写一个包含所有功能(随机产生所有合法和非法的激励,并使用多层协议进行错误注入)的子程序,因为这样的子程序很快就会变得很复杂,并且难以维护。
## 9.1. 不分层的 testbench ## 9.1. 不分层的测试平台
在刚开始学习 Verilog 并尝试写测试程序的时候,这些程序看起来可能会和[例 1.1](#例1.1) 所示的用于执行一个简单 APB (AMBA Peripheral Bus, AMBA 外设总线)写入的低层次代码很相似。 &emsp;&emsp;在刚开始学习 Verilog 并尝试写测试程序的时候,这些程序看起来可能会和[例 1.1](#例1.1) 所示的用于执行一个简单 APB(AMBA Peripheral Bus, AMBA 外围总线)写入的低层次代码很相似。
<a id="例1.1"></a> <a id="例1.1"></a>
``` verilog 例 1.1 驱动 APB 引脚 ``` verilog 例 1.1. 驱动 APB 引脚
module test(PAddr,PWrite,PSel,PWData,PEnable,Rst,clk); module test(PAddr,PWrite,PSel,PWData,PEnable,Rst,clk);
// 此处省略端口声明 // 此处省略端口声明
@@ -275,11 +304,11 @@ module test(PAddr,PWrite,PSel,PWData,PEnable,Rst,clk);
endmodule endmodule
``` ```
经过几天连续编写这种代码以后,我们可能会意识到这是一种重复性的劳动,所以会尝试创建可用于总线写入这种普通操作的任务,如[例 1.2](#例1.2) 所示。 &emsp;&emsp;经过几天连续编写这种代码以后,我们可能会意识到这是一种重复性的劳动,所以会尝试创建可用于总线写入这种普通操作的任务,如[例 1.2](#例1.2) 所示。
<a id="例1.2"></a> <a id="例1.2"></a>
``` verilog 例 1.2 一个用于驱动 APB 引脚的任务 ``` verilog 例 1.2. 一个用于驱动 APB 引脚的任务
task write(reg [15:0] addr, reg [31:0] data); task write(reg [15:0] addr, reg [31:0] data);
// 驱动控制总线 // 驱动控制总线
@(posedge clk) @(posedge clk)
@@ -296,11 +325,11 @@ task write(reg [15:0] addr, reg [31:0] data);
endtask endtask
``` ```
这样,testbench 就会变得简单一些,如[例 1.3](#例1.3)。 &emsp;&emsp;这样,测试平台就会变得简单一些,如[例 1.3](#例1.3)。
<a id="例1.3"></a> <a id="例1.3"></a>
``` verilog 例 1.3 低层次的 Verilog 测试 ``` verilog 例 1.3. 低层次的 Verilog 测试
module test(PAddr,PWrite,PSel,PWData,PEnable,Rst,clk); module test(PAddr,PWrite,PSel,PWData,PEnable,Rst,clk);
// 此处省略端口声明 // 此处省略端口声明
// 此处省略如例 1.2 给出的任务函数 // 此处省略如例 1.2 给出的任务函数
@@ -310,7 +339,7 @@ module test(PAddr,PWrite,PSel,PWData,PEnable,Rst,clk);
write(16'h50, 32'h50); // 把数据写入到存储器中 write(16'h50, 32'h50); // 把数据写入到存储器中
// 校验结果 // 校验结果
if (top.mem.memory[16'h50] == 32'h50) if(top.mem.memory[16'h50] == 32'h50)
$display("Success"); $display("Success");
else else
$display("Error, wrong value in memory"); $display("Error, wrong value in memory");
@@ -319,135 +348,142 @@ module test(PAddr,PWrite,PSel,PWData,PEnable,Rst,clk);
endmodule endmodule
``` ```
通过把一些通用的操作 (如复位、总线读出和总线写入) 放到一个子程序中,可以提高工作效率并减少错误。这里,物理和命令层的建立只是通往分层 testbench 的第一步。 &emsp;&emsp;通过把一些通用的操作(如复位、总线读出和总线写入)放到一个子程序中,可以提高工作效率并减少错误。这里,物理和命令层的建立只是通往分层测试平台的第一步。
## 9.2. 信号和命令层 ## 9.2. 信号和命令层
[图 9](#图9) 所示为一个 testbench 中最低的几个层次。 &emsp;&emsp;[图 9](#图9) 所示为一个测试平台中最低的几个层次。
<a id="图9"></a> <a id="图9"></a>
![图 9 信号和命令层](../images/post/2022-05-30-josh-systemverilog-1/2022-05-30-josh-systemverilog-1-090-SignalAndCommandLlayers.png){width=500px} ![图 9. 信号和命令层](../images/post/2022-05-30-josh-systemverilog-1/2022-05-30-josh-systemverilog-1-090-SignalAndCommandLlayers.png){width=500px}
在底部的**信号层** (*signal*),包含 DUT 和把 DUT 连接到 testbench 的信号。 &emsp;&emsp;在底部的**信号层**(*signal*),包含 DUT 和把 DUT 连接到测试平台的信号。
再往上一层是**命令层** (*command*)。执行总线读写命令的驱动器驱动 DUT 的输入。DUT 的输出与监视器 (monitor) 相连,监视器负责检测信号的变化,并把这些变化按照命令分组。断言 (assertion) 也穿过命令层和信号层,它们负责监视独立的信号以寻找穿越整个命令的信号变化。 &emsp;&emsp;再往上一层是**命令层**(*command*)。执行总线读写命令的驱动器驱动 DUT 的输入。DUT 的输出与监视器(monitor)相连,监视器负责检测信号的变化,并把这些变化按照命令分组。断言(assertion)也穿过命令层和信号层,它们负责监视独立的信号以寻找穿越整个命令的信号变化。
## 9.3. 功能层 ## 9.3. 功能层
[图 10](#图10) 给出了为加上**功能层** (*functional*) 的 testbench,功能层向下面对的是命令层。代理 (agent, 在 VMM 中称为事件处理器) 接收到来自上层的事件,例如,DMA 读或写,把它们分解成独立的命令。这些命令也被送往用于预测事件结果的记分板 (scoreboard)。检验器 (checker) 则负责比较来自监视器和记分板的命令。 &emsp;&emsp;[图 10](#图10) 给出了为加上**功能层**(*functional*)的测试平台,功能层向下面对的是命令层。代理(agent, 在 VMM 中称为事件处理器)接收到来自上层的事件,例如,DMA 读或写,把它们分解成独立的命令。这些命令也被送往用于预测事件结果的记分板(scoreboard)。检验器(checker)则负责比较来自监视器和记分板的命令。
<a id="图10"></a> <a id="图10"></a>
![图 10 加上功能层的 testbench](../images/post/2022-05-30-josh-systemverilog-1/2022-05-30-josh-systemverilog-1-100-TestbenchWithFunctionalLlayerAdded.png){width=500px} ![图 10. 加上功能层的测试平台](../images/post/2022-05-30-josh-systemverilog-1/2022-05-30-josh-systemverilog-1-100-TestbenchWithFunctionalLlayerAdded.png){width=500px}
## 9.4. 场景层 ## 9.4. 场景层
[图 11](#图11) 所示,功能层被位于**场景层** (*scenario*) 中的发生器 (generator) 所驱动。什么是场景呢?记住一点,验证工程师的工作是确保 DUT 能够完成预期的任务。比如 MP3 播放器,它能一边播放事先存储好的音乐,一边从一台主机上下载新的音乐,并且同时对用户输入如音量调整或音轨控制等操作保持响应。这中间的每一个操作都能称为一个场景。下载一个音乐文件需要若于步骤,例如前期准备时的控制寄存器的读写操作,歌曲传送过程中多次 DMA 写操作,以及之后的很多读写操作。场景层就是负责组织协调这些步骤的,操作的参数如音轨大小和寄存器位置等都采用约束下的随机值。 &emsp;&emsp;[图 11](#图11) 所示,功能层被位于**场景层**(*scenario*)中的发生器(generator)所驱动。什么是场景呢?记住一点,验证工程师的工作是确保 DUT 能够完成预期的任务。比如 MP3 播放器,它能一边播放事先存储好的音乐,一边从一台主机上下载新的音乐,并且同时对用户输入如音量调整或音轨控制等操作保持响应。这中间的每一个操作都能称为一个场景。下载一个音乐文件需要若于步骤,例如前期准备时的控制寄存器的读写操作,歌曲传送过程中多次 DMA 写操作,以及之后的很多读写操作。场景层就是负责组织协调这些步骤的,操作的参数如音轨大小和寄存器位置等都采用受约束的随机值。
<a id="图11"></a> <a id="图11"></a>
![图 11 加上场景层的 testbench](../images/post/2022-05-30-josh-systemverilog-1/2022-05-30-josh-systemverilog-1-110-TestbenchWithScenarioLayerAdded.png){width=500px} ![图 11. 加上场景层的测试平台](../images/post/2022-05-30-josh-systemverilog-1/2022-05-30-josh-systemverilog-1-110-TestbenchWithScenarioLayerAdded.png){width=500px}
在 testbench **环境** (*environment*) 中的这些块 ([图 11](#图11) 虚线框内) 是在刚开始开发的时候画出来的。随着项目的进展,它们可能会有一些变化,也可能会加入一些功能,但是这些块对于每个独立的测试都是不应改变的。可以通过在代码中留下“hook”来做到这一点,这样即使这些块的行为需要在测试时改变,也不必重新编写代码。“hook”可以使用工厂模式 (factory patterns) 和回调函数 (callbacks) 来创建。 &emsp;&emsp;在测试平台**环境**(*environment*)中的这些块([图 11](#图11)虚线框内)是在刚开始开发的时候画出来的。随着项目的进展,它们可能会有一些变化,也可能会加入一些功能,但是这些块对于每个独立的测试都是不应改变的。可以通过在代码中留下“钩子”来做到这一点,这样即使这些块的行为需要在测试时改变,也不必重新编写代码。“钩子”可以使用工厂模式(factory patterns)和回调函数(callbacks)来创建。
## 9.5. 测试的层次和功能覆盖率 ## 9.5. 测试的层次和功能覆盖率
现在到了 testbench 的最顶层——测试层,如[图 12](#图12)。DUT 模块间的 bug 是比较难以发现的,因为这些模块可能是不同的人按照不同的规范设计出来的。 &emsp;&emsp;现在到了测试平台的最顶层——测试层,如[图 12](#图12)。DUT 模块间的漏洞是比较难以发现的,因为这些模块可能是不同的人按照不同的规范设计出来的。
<a id="图12"></a> <a id="图12"></a>
![图 12 带着所有层次的完整 testbench](../images/post/2022-05-30-josh-systemverilog-1/2022-05-30-josh-systemverilog-1-120-FullTestbenchWithAllLayers.png){width=500px} ![图 12. 带着所有层次的完整测试平台](../images/post/2022-05-30-josh-systemverilog-1/2022-05-30-josh-systemverilog-1-120-FullTestbenchWithAllLayers.png){width=500px}
这个顶层的测试 (test) 就像一个指挥官:他不演奏任何乐器,但引领着其他人的表演。测试包含了用于创建激励的约束。 &emsp;&emsp;这个顶层的测试(test)就像一个指挥官:他不演奏任何乐器,但引领着其他人的表演。测试包含了用于创建激励的约束。
功能覆盖率 (functional coverage) 可以衡量所有测试在满足验证计划要求方面的进展。随着各项测量标准的完成,功能覆盖率代码在整个项目过程中会经常变化。由于代码经常被修改,所以它不作为测试环境的组成部分。 &emsp;&emsp;功能覆盖率(functional coverage)可以衡量所有测试在满足验证计划要求方面的进展。随着各项测量标准的完成,功能覆盖率代码在整个项目过程中会经常变化。由于代码经常被修改,所以它不作为测试环境的组成部分。
我们可以在约束下的随机环境中创建“定向测试”。只需在随机序列中间插入定向测试的代码,或者把两部分代码并列。定向代码执行期望的任务,而随机的“背景噪声”可能会使 bug 暴露出来,而且 bug 还有可能来自从未被关注过的模块。 &emsp;&emsp;我们可以在受约束的随机环境中创建“定向测试”。只需在随机序列中间插入定向测试的代码,或者把两部分代码并列。定向代码执行期望的任务,而随机的“背景噪声”可能会使漏洞暴露出来,而且漏洞还有可能来自从未被关注过的模块。
Testbench 中是否需要所有的层次呢?答案要视 DUT 而定。设计越复杂,所需的 testbench 就要越完备。测试层则是必须的。对于一个简单的设计来说,场景层可能过于简单以至于可以把它合并到代理中。 &emsp;&emsp;测试平台中是否需要所有的层次呢?答案要视 DUT 而定。设计越复杂,所需的测试平台就要越完备。测试层则是必须的。对于一个简单的设计来说,场景层可能过于简单以至于可以把它合并到代理中。
当然,可能还需要更多的层次。如果 DUT 有多个协议层,那么每个层都应该在 testbench 环境中有对应的层。例如使用 IP 封装了 TCP 流量,然后通过以太网数据包的形式发送,对这种情况的测试应该考虑使用三个独立的层来产生和校验数据,如 &emsp;&emsp;当然,可能还需要更多的层次。如果 DUT 有多个协议层,那么每个层都应该在测试平台环境中有对应的层。例如使用 IP 封装了 TCP 流量,然后通过以太网数据包的形式发送,对这种情况的测试应该考虑使用三个独立的层来产生和校验数据,如
果能够使用已有的验证构件则更好。 果能够使用已有的验证构件则更好。
[图 12](#图12) 中需要注意的最后一点是,它只给出了各块之间一些可能的连接方式,testbench 模块间的连接可能会与之不同。比如测试层可能需要连接到驱动器层以迫使物理 bug 出现。这里给出的只是一些引导——实际当中应该是,需要什么就创建什么。 &emsp;&emsp;[图 12](#图12) 中需要注意的最后一点是,它只给出了各块之间一些可能的连接方式,测试平台模块间的连接可能会与之不同。比如测试层可能需要连接到驱动器层以迫使物理漏洞出现。这里给出的只是一些引导——实际当中应该是,需要什么就创建什么。
# 10. 建立一个分层的 testbench # 10. 建立一个分层的测试平台
现在是学习如何把前面图示的那些构件映射成 SystemVerilog 结构时候了。 &emsp;&emsp;现在是学习如何把前面图示的那些构件映射成 SystemVerilog 结构时候了。
## 10.1. 创建一个简单的驱动器 ## 10.1. 创建一个简单的驱动器
首先,来仔细看看其中的一个模块——驱动器。[图 13](#图13) 所示的驱动器接收来自代理的命令。驱动器可能会注入错误或者增加时延,然后再把命令分解成一些信号的变化,例如总线请求或握手。这样一个 testbench 模块通常被称为“事件处理器 (transactor)”,它的核心部分是一个循环:有关事件处理器的示范代码如[例 1.4](#例1.4) 所示。 &emsp;&emsp;首先,来仔细看看其中的一个模块——驱动器。[图 13](#图13) 所示的驱动器接收来自代理的命令。驱动器可能会注入错误或者增加时延,然后再把命令分解成一些信号的变化,例如总线请求或握手。这样一个测试平台模块通常被称为“事件处理器(transactor)”,它的核心部分是一个循环:有关事件处理器的示范代码如[例 1.4](#例1.4)所示。
<a id="图13"></a> <a id="图13"></a>
![图 13 带着所有层次的完整 testbench](../images/post/2022-05-30-josh-systemverilog-1/2022-05-30-josh-systemverilog-1-130-ConnectionsForTheDriver.png){width=120px} ![图 13. 带着所有层次的完整测试平台](../images/post/2022-05-30-josh-systemverilog-1/2022-05-30-josh-systemverilog-1-130-ConnectionsForTheDriver.png){width=120px}
<a id="例1.4"></a> <a id="例1.4"></a>
``` verilog 例 1.4 基本的事件处理器代码 ``` verilog 例 1.4. 基本的事件处理器代码
task run(); task run();
done = 0; done = 0;
while (!done) begin while (!done) begin
// 获取下一个事件 // 获取下一个事件
// 进行变换 // 进行变换
// 发送事件 // 发送事件
end end
endtask endtask
``` ```
后序的文章给出了: &emsp;&emsp;后序的文章给出了:
- 基本的 OOP 以及如何创建一个对象并使对象里面包含事件处理器所需要的子程序和数据,事件处理器的另一个例子是代理,它可能会把一个复杂的事件如 DMA 读分解成多个总线命令; - 基本的 OOP 以及如何创建一个对象并使对象里面包含事件处理器所需要的子程序和数据,事件处理器的另一个例子是代理,它可能会把一个复杂的事件如 DMA 读分解成多个总线命令;
- 如何创建一个对象并使对象里面包含构成一个命令所需要的数据和子程序。使用 SystemVerilog 信箱可以实现这些对象在不同的事件处理器之间传递; - 如何创建一个对象并使对象里面包含构成一个命令所需要的数据和子程序。使用 SystemVerilog 信箱可以实现这些对象在不同的事件处理器之间传递;
- 还将介绍很多方法,用于在不同层之间交换数据并使事件处理器实现同步。 - 还将介绍很多方法,用于在不同层之间交换数据并使事件处理器实现同步。
# 11. 仿真环境的阶段 # 11. 仿真环境的阶段
到目前为止,已经学习了环境的构成部分。这些部分在什么时候执行呢?我们希望把各个阶段清楚地定义好,以便协调 testbench,使项目中的所有代码能在一起工作。三个基本的阶段是建立 (build)、运行 (run) 和收尾 (wrap-up)。每个阶段都可以再细分为更小的步骤。 &emsp;&emsp;到目前为止,已经学习了环境的构成部分。这些部分在什么时候执行呢?我们希望把各个阶段清楚地定义好,以便协调测试平台,使项目中的所有代码能在一起工作。三个基本的阶段是建立(build)、运行(run)和收尾(wrap-up)。每个阶段都可以再细分为更小的步骤。
**建立阶段**可以分为如下步骤。 &emsp;&emsp;**建立阶段**可以分为如下步骤。
1. **生成配置** (*Generate configuration*):把 DUT 的配置和周围的环境随机化。 1. **生成配置**(*Generate configuration*):把 DUT 的配置和周围的环境随机化。
2. **建立环境** (*Build environment*):基于配置来分配和连接 testbench 构件。Testbench 构件指的是存在于 testbench 中的部分,注意与设计中的物理构件区分开,后者是采用 RTL 代码描述的。例如,如果配置选择了三个总线驱动器,那么 testbench 应该在这个阶段对它们进行分配和初始化。
3. **对 DUT 进行复位** (*Reset the DUT.*)。
4. **配置 DUT** (*Configure the DUT*):基于第一步中生成的配置,载入 DUT 的命令寄存器。
**运行阶段**是指测试实际运行的阶段,可分为以下步骤。 2. **建立环境**(*Build environment*):基于配置来分配和连接测试平台构件。测试平台构件指的是存在于测试平台中的部分,注意与设计中的物理构件区分开,后者是采用 RTL 代码描述的。例如,如果配置选择了三个总线驱动器,那么测试平台应该在这个阶段对它们进行分配和初始化。
1. **启动环境** (*Start environment*):运行 testbench 构件,例如各种 BFM 和激励发生器。 3. **对 DUT 进行复位**(*Reset the DUT.*)。
2. **运行测试** (*Run the test*):启动测试然后等待测试完成。定向测试的完成很容易判断,但随机测试却比较困难。可以使用 testbench 的层作为引导。从顶层启动,等待一个层接收完来自上一层 (如果有的话) 的所有输入,接着等待当前层空闲下来,然后再等待下一层。应该同时使用超时检测以确保 DUT 或 testbench 不出现死锁 (lock up)。
收尾阶段包含如下两个步骤。 4. **配置 DUT**(*Configure the DUT*):基于第一步中生成的配置,载入 DUT 的命令寄存器。
1. **清空** (*Sweep*):在最下层完成以后,需要等待 DUT 清空最后的事务。 &emsp;&emsp;**运行阶段**是指测试实际运行的阶段,可分为以下步骤。
2. **报告** (*Report*):一旦 DUT 空闲下来,就可以清空遗留在 testbench 中的数据了。有时候保存在记分板里面的数据从来就没有送出来过,这些数据可能是被 DUT 丢弃掉的。可以根据这些信息创建最终报告,说明测试通过或者失败。如果测试失败,务必把相应的功能覆盖率结果删除,因为它们可能是不正确的。
如[图 12](#图12) 所示,测试启动环境以后,环境就会按上述步骤运行。 1. **启动环境**(*Start environment*):运行测试平台构件,例如各种 BFM 和激励发生器。
2. **运行测试**(*Run the test*):启动测试然后等待测试完成。定向测试的完成很容易判断,但随机测试却比较困难。可以使用测试平台的层作为引导。从顶层启动,等待一个层接收完来自上一层(如果有的话)的所有输入,接着等待当前层空闲下来,然后再等待下一层。应该同时使用超时检测以确保 DUT 或测试平台不出现死锁(lock up)。
&emsp;&emsp;收尾阶段包含如下两个步骤。
1. **清空**(*Sweep*):在最下层完成以后,需要等待 DUT 清空最后的事务。
2. **报告**(*Report*):一旦 DUT 空闲下来,就可以清空遗留在测试平台中的数据了。有时候保存在记分板里面的数据从来就没有送出来过,这些数据可能是被 DUT 丢弃掉的。可以根据这些信息创建最终报告,说明测试通过或者失败。如果测试失败,务必把相应的功能覆盖率结果删除,因为它们可能是不正确的。
&emsp;&emsp;如[图 12](#图12) 所示,测试启动环境以后,环境就会按上述步骤运行。
# 12. 最大限度的代码重用 # 12. 最大限度的代码重用
为了验证一个带有数百个特性的复杂设备,必须编写数百个定向测试。如果使用约束下的随机激励,需要编写的测试就会少很多。与定向测试相比,随机测试的主要工作是构建 testbench,使它包含所有较低的层:场景、功能、命令以及信号。这个 testbench 代码要能够被所有的测试使用,所以它需要有很好的**通用性**。 &emsp;&emsp;为了验证一个带有数百个特性的复杂设备,必须编写数百个定向测试。如果使用受约束的随机激励,需要编写的测试就会少很多。与定向测试相比,随机测试的主要工作是构建测试平台,使它包含所有较低的层:场景、功能、命令以及信号。这个测试平台代码要能够被所有的测试使用,所以它需要有很好的**通用性**。
这些建议似乎是在推荐一个极度复杂的 testbench,但需要记住的是,在 testbench 中每输入一行,就等于给每个单独的测试都减少了一行,相当于在同时创建很多个测试,而这也正是建立一个复杂 testbench 所能获得的巨额回报。 &emsp;&emsp;这些建议似乎是在推荐一个极度复杂的测试平台,但需要记住的是,在测试平台中每输入一行,就等于给每个单独的测试都减少了一行,相当于在同时创建很多个测试,而这也正是建立一个复杂测试平台所能获得的巨额回报。
# 13. Testbench 的性能 # 13. 测试平台的性能
如果你是第一次接触这种方法学的话,可能还是会怀疑它工作起来是否会优于定向测试?一个普遍的质疑便是 testbench 的性能。一个定向测试通常可以在一秒之内运行完,但**约束下的随机测试却要花费数分钟甚至数小时去搜索整个状态空间**。这种论点的问题在于,它忽略了一个在验证上真实存在的瓶颈:创建一个测试所需要的时间。你可以在一天之内手动编写完一个定向测试,然后再花一两天的时间调试并手动验证结果。测试的实际运行时间比起你在其他方面花费的时间其实要少得多。 &emsp;&emsp;如果你是第一次接触这种方法学的话,可能还是会怀疑它工作起来是否会优于定向测试?一个普遍的质疑便是测试平台 的性能。一个定向测试通常可以在一秒之内运行完,但**受约束的随机测试却要花费数分钟甚至数小时去搜索整个状态空间**。这种论点的问题在于,它忽略了一个在验证上真实存在的瓶颈:创建一个测试所需要的时间。你可以在一天之内手动编写完一个定向测试,然后再花一两天的时间调试并手动验证结果。测试的实际运行时间比起你在其他方面花费的时间其实要少得多。
创建约束下的随机测试需要几个步骤。 &emsp;&emsp;创建受约束的随机测试需要几个步骤。
1. 最重要的一步是建立分层的 testbench,包括自检的部分。这项工作能给所有的测试带来好处,所以是非常值得的。 1. 最重要的一步是建立分层的测试平台,包括自检的部分。这项工作能给所有的测试带来好处,所以是非常值得的。
2. 按照验证计划中列举的目标创建激励。可以使用随机约束,也可以采用注入错误或协议违例等迂回的方式。以这其中的任何一种方式创建激励所花费的时间可能可以用于创建好儿个定向测试,但是它的回报也要高很多。一个约束下的随机测试能够尝试成千上万种不同的协议违例,而在同样的时间里创建的几个定向测试却只能尝试几种情形,显然前者要比后者好得多。
3. 功能覆盖率 (约束下的随机测试)。这项任务的开始是创建一个强有力的验证计划,这个计划必须带有清晰而且便于测植的目标。接下来你需要创建 System­Verilog 代码,在环境中添加工具用于收集数据。最后很重要的一点,你需要 2. 按照验证计划中列举的目标创建激励。可以使用随机约束,也可以采用注入错误或协议违例等迂回的方式。以这其中的任何一种方式创建激励所花费的时间可能可以用于创建好儿个定向测试,但是它的回报也要高很多。一个受约束的随机测试能够尝试成千上万种不同的协议违例,而在同样的时间里创建的几个定向测试却只能尝试几种情形,显然前者要比后者好得多。
4. 对结果进行分析,并据此判断是否满足目标要求,如果不满足,应如何修改测试。
3. 功能覆盖率(受约束的随机测试)。这项任务的开始是创建一个强有力的验证计划,这个计划必须带有清晰而且便于测植的目标。接下来你需要创建 System­Verilog 代码,在环境中添加工具用于收集数据。最后很重要的一点,你需要对结果进行分析,并据此判断是否满足目标要求,如果不满足,应如何修改测试。
# 14. 结束语 # 14. 结束语
电子设计复杂度的持续增长要求以一种新颖的、系统的且自动化的方法来创建 testbench。从硬件规范到 RTL 编码、门级综合、芯片制造,以及最后到用户手里,项目每向前推进一步,修复单个 bug 所需要的代价就会增加数倍甚至数十倍。定向测试每次只能测试一个特性,而无法模拟设备在实际应用环境中所面对的复杂的激励和配置。为了得到稳健的设计,**必须使用约束下的随机激励加上功能覆盖率**,才能在可能的限度内创建出最广泛的激励。 &emsp;&emsp;电子设计复杂度的持续增长要求以一种新颖的、系统的且自动化的方法来创建测试平台。从硬件规范到 RTL 编码、门级综合、芯片制造,以及最后到用户手里,项目每向前推进一步,修复单个漏洞所需要的代价就会增加数倍甚至数十倍。定向测试每次只能测试一个特性,而无法模拟设备在实际应用环境中所面对的复杂的激励和配置。为了得到稳健的设计,**必须使用受约束的随机激励加上功能覆盖率**,才能在可能的限度内创建出最广泛的激励。
# 参考文献 # 参考文献
1. 克里斯·斯皮尔, 斯皮尔, 张春,等. SystemVerilog验证:测试平台编写指南[M]. 科学出版社, 2009. 1. C. Spear. *SystemVerilog 验证: 测试平台编写指南 原书第二版*. 北京: 科学出版社, 2009.
2. Spear C. SystemVerilog for verification: a guide to learning the testbench language features[M]. Springer Science & Business Media, 2008. 2. C. Spear. *SystemVerilog for verification: a guide to learning the testbench language features*, 2nd ed. New York: Springer, 2008.
@@ -1,194 +0,0 @@
---
title: 高等数学常用公式
mathjax: true
comments: true
copyright: true
toc:
enable: true
number: false
wrap: true
expand_all: true
max_depth: 4
abbrlink: 1823c9d1
date: 2023-04-14 16:25:59
tags:
- 等价无穷小
- 导数公式
- Maclaurin 公式
- 曲率
- 积分公式
- 三角函数
categories:
- [数学, 微积分]
---
# 1. 常见等价无穷小
||||
| :--: | :--: | :--: |
| $\sin x \sim x$ | $\tan x \sim x$ | $\arcsin x \sim x$ |
| $\arctan x \sim x$ | $\displaystyle\left( 1 - \cos x \right) \sim \frac{x^2}{2}$ | $\ln (1+x) \sim x$ |
| $\left( e^x -1 \right) \sim x$ | $\left( a^x - 1 \right) \sim x \ln a$ | $\left( \left( 1+x \right) ^\alpha -1 \right) \sim \alpha x$ |
<!-- more -->
# 2. 导数基本公式
| 一般函数 | 三角函数 | 反三角函数 | 双曲函数<br>(圆函数) |
| :--: | :--: | :--: | :----: |
| $\left( C \right)' = 0$ | $\left( \sin x \right)' = \cos x$ | $\displaystyle\left( \arcsin x \right)' = \frac{1}{\sqrt{1-x^2}}$ | $\displaystyle\left( \sinh x \right)' = \left(\frac{e^x-e^{-x}}{2}\right)' = \cosh x$ |
| $\left( x^\alpha \right)'=\alpha x^{\alpha-1} \left( \alpha \in \mathbf{Z} \right)$ | $\left( \cos x \right)' = -\sin x$ | $\displaystyle\left( \arccos x \right)' = -\frac{1}{\sqrt{1-x^2}}$ | $\displaystyle\left( \cosh x \right)' = \left( \frac{e^x+e^{-x}}{2} \right)'=\sinh x$ |
| $\displaystyle\left( \log_ax\right)'=\frac{1}{x\ln a}$ | $\displaystyle\left( \tan x \right)' = \frac{1}{\cos^2 x}=\sec^2 x$ | $\displaystyle\left( \arctan x \right)' = \frac{1}{1+x^2}$ | $\displaystyle\left( \mathrm{arsinh} \, x \right)' = \left(\ln \left( x+\sqrt{x^2 + 1} \right) \right)' = \frac{1}{x^2+1}$ |
| $( \ln$\| $x$ \|$)'=\displaystyle\frac{1}{x}$ | $\displaystyle\left( \cot x \right)' = -\frac{1}{\sin^2 x} = -\csc^2 x$ | $\displaystyle\left( \mathrm{arccot} \, x \right)' = -\frac{1}{1+x^2}$ | $\displaystyle\left( \mathrm{arcosh} \, x \right)' = \left( \ln \left( x + \sqrt{x^2 - 1} \right) \right)' = \frac{1}{\sqrt{x^2-1}}$
| | $\left( \sec x \right)' = \sec x \cdot \tan x$ |
| | $\left( \csc x \right)' = \csc x \cdot \cot x$ |
- Newton-Leibniz 公式:
$$
\begin{aligned}
\left( u \cdot v \right)^{\left( n \right)} &= u^{\left( n \right)}v + nu^{\left( n-1 \right)}v' + \frac{n \left( n-1 \right)}{2!}u^{\left( n-2 \right)}v'' + \cdots + \frac{n\left( n-1 \right)\cdots\left(n-k+1\right)}{k!}u^{\left( n-k \right)}v^{(k)} + \cdots + uv^{\left( n \right)} \\
&= \sum_{k=0}^{n}C_n^k u^{\left( u-k \right)}v^k
\end{aligned}
$$
可以注意到 Newton-Leibniz 公式具有类似二项式定理展开的形式。
# 3. 几个初等函数的 Maclaurin 公式
## 3.1 Taylor 公式的一般形式
$$
f(x)=f(x_0) + f'(x_0)(x-x_0) + \frac{f''(x_0)}{2!}(x-x_0)^2 + \cdots + \frac{f^{(n)}(x_0)}{n!}(x-x_0)^n + R_n
$$
其中
$$
R_n = \frac{f^{(n+1)}(\xi)}{(n+1)!}(x-x_0)^{n+1} \, (\xi\,在\,x\,和\,x_0\,之间) = o\left( \left( x - x_0 \right)^n \right)(x\to x_0)
$$
## 3.2 Maclaurin 公式的一般形式
$$
f(x)=f(0)+f'(0)\,x + \frac{f''(0)}{2!}x^2 + \cdots + \frac{f^{(n)}(0)}{n!}x^n + R_n
$$
其中
$$
R_n = \frac{f^{(n+1)}(\xi)}{(n+1)!}x^{n+1} \, (\xi\,在\,0\,和\,x\,之间) = \frac{f^{(n+1)}(\theta x)}{(n+1)!} x^{n+1}(0<\theta<1) = o\left( \left( x - x_0 \right)^n \right)(x\to x_0)
$$
## 3.3 指数函数的 Maclaurin 展开式
$$
e^x=1+x+\frac{x^2}{2} + \frac{x^3}{3} + \cdots +\frac{x^n}{n!} + \frac{e^{\theta x}}{(n+1)!}(0<\theta<1)
$$
## 3.4 正弦函数的 Maclaurin 展开式
$$
\sin x = x - \frac{x^3}{3!} + \frac{x^5}{5!} + \cdots + (-1)^{m-1}\frac{x^{2m-1}}{(2m-1)!} + R_{2m}
$$
其中
$$
R_{2m}=\frac{\sin\left( \theta x + \frac{(2m-1)\pi}{2}\right)}{(2m+1)!}x^{2m+1} = o(x^{2m})(0<\theta <1)
$$
## 3.5 余弦函数的 Maclaurin 展开式
$$
\cos x = 1 - \frac{x^2}{2!} + \frac{x^4}{4!} + \cdots + (-1)^m\frac{x^{2m}}{2m!} + R_{2m+1}
$$
其中
$$
R_{2m+1}=\frac{\cos(\theta x + (m+1)\pi)}{(2m+2)!} x^{2m+2}=o(x^{2m+2}) (0<\theta <1)
$$
## 3.6 $\ln (1+x)$ 的 Maclaurin 展开式
$$
\ln(1+x) = x - \frac{x^2}{2} + \frac{x^3}{3} -\frac{x^4}{4} + \cdots + \frac{(-1)^{n-1}x^n}{n} + R_n(x)
$$
其中
$$
R_n(x) = \frac{(-1)^n}{(n+1)(1+\theta x)^{n+1}}x^{n+1} = o(x^n)(0<\theta <1)
$$
## 3.7 $(1+x)^\alpha$ 的 Maclaurin 展开式
$$
(1+x)^\alpha = 1 + \alpha x + \frac{\alpha(\alpha-1)}{2!}x^2 + \cdots + \frac{\alpha(\alpha - 1)\cdots (\alpha-n+1)}{n!}x^n + R_n(x)
$$
其中
$$
R_n(x) = \frac{\alpha(\alpha -1)\cdots(\alpha-n)}{(n+1)!}(1+\theta x)^{\alpha-n-1}x^{n+1} = o(x)(0<\theta <1)
$$
## 3.8 $\frac{1}{1-x}$ 的 Maclaurin 展开式
$$
\frac{1}{1-x} = 1+x+x^2+\cdots+x^n +o(x^n)
$$
# 4. 曲率及曲率半径
| 曲率 | 曲率半径 |
| :--: | :--: |
| $K=\left\| \dfrac{\mathrm{d}\alpha}{\mathrm{d}s}\right\| \xlongequal{\tan \alpha = y' \Rightarrow \alpha = \arctan y'} \dfrac{\left\| \frac{y''}{1+y'^2}\mathrm{d}x \right\|}{\sqrt{1+y'^2}}\mathrm{d}x = \dfrac{\left\| y'' \right\|}{\left( 1 + y' \right)^\frac{3}{2}}$ | $R = \frac{1}{K}$ |
# 5. 积分常用公式
| 序 | 描述 | 公式 |
| :--: | :----: | :----------------------------------------------:|
| 1 | 定积分的定义 | $\displaystyle\int^1_0f(x)\mathrm{d}x=I=\lim_{\lambda \to 0}\sum_{i=1}^{n}f(\xi_i)\Delta x_i$,其中 $\lambda = \max \left\{ \Delta x_1,\Delta x_2, \cdots, \Delta x_n \right\}$ |
| 2 | 变上限积分 | $考察定积分\displaystyle\int^x_af(x)\mathrm{d}x=\int^x_af(t)\mathrm{d}t$,对 $\displaystyle\Phi(x)=\int_a^xf(t)\mathrm{d}t$,有 $\displaystyle\Phi'(x)=\frac{\mathrm{d}}{\mathrm{d}x}\int_a^xf(t)\mathrm{d}t = f(x)$ |
| 3. | — | $\displaystyle\frac{\mathrm{d}}{\mathrm{d}x}\int^{\beta(x)}_{\alpha(x)}f'(t)\mathrm{d}t = f\left[ \beta\left(x\right)\right]\beta'(x)-f[\alpha(x)]\alpha'(x)$ |
| 4 | 上下限对称的积分 | 若 $f(x)$ 为偶函数,则 $\displaystyle\int_{-a}^af(x)\mathrm{d}x=2\int_0^af(x)\mathrm{d}x$;若 $f(x)$ 为奇函数,则 $\displaystyle\int_{-a}^af(x)\mathrm{d}x=0$ |
| 5 | 周期函数的积分 | $\displaystyle f(x+T)=f(x)\Rightarrow\int_0^{nT}f(x)\mathrm{d}x=n\int^T_0f(x)\mathrm{d}x$ |
| 6 | 分部积分法 | $\displaystyle\int uv'\mathrm{d}x=uv - \int u'v\mathrm{d}x \Leftrightarrow \int u\mathrm{d}v = uv - \int v\mathrm{d}u$ |
# 6. 基本积分表
| 序 | 积分式 |
| :--: | :-------------------------: |
| 1 | $\displaystyle\int k\mathrm{d}x=kx+C$,特别地 $\displaystyle\int\mathrm{d}x=x+C$ |
| 2 | $\displaystyle\int x^\mu\mathrm{d}x=\frac{x^{\mu+1}}{\mu+1}+C(\mu\ne-1)$,特别地 $\displaystyle\int \frac{\mathrm{d}x}{x^2}=-\frac{1}{x}+C,\int\frac{\mathrm{d}x}{\sqrt{x}}=2\sqrt{x}+C$ |
| 3 | $\displaystyle\int\frac{\mathrm{d}x}{x}=\ln \|x\|+C$ |
| 4 | $\displaystyle\int\frac{\mathrm{d}x}{1+x^2} = \arctan x +C$ |
| 5 | $\displaystyle\int\frac{\mathrm{d}x}{\sqrt{1-x^2}}=\arcsin x+C$ |
| 6 | $\displaystyle\int\sin x\mathrm{d}x = -\cos x+C, \int\cos x\mathrm{d}x = \sin x +C$ |
| 7 | $\displaystyle\int\frac{\mathrm{d}x}{\cos^2x} = \int\sec^2x\mathrm{d}x = \tan x +C, \int\frac{\mathrm{d}x}{\sin^2x}=\int\csc^2x\mathrm{d}x = -\cot x +C$ |
| 8 | $\displaystyle\int a^x\mathrm{d}x = \frac{a^x}{\ln a} + C$,特别地 $\displaystyle\int e^x\mathrm{d}x = e^x +C$
| 9 | $\displaystyle\int \sinh x\mathrm{d}x = \cosh x + C,\int \cosh x \mathrm{d}x=\sinh x +C$ |
# 7. 三角函数相关公式
| 序 | 公式 |
| :--: | :-------------------------: |
| 1 | $\sin^2x+\cos^2x=1, \tan^2x+1=\sec^2x,\cot^2x+1=\csc^2x$ |
| 2 | $\begin{aligned}&\cosh^2x-\sinh^2x=1,\\ &\sinh(x\pm y)=\sinh x\cdot\cosh y \pm \sinh y\cdot\cosh x, \cosh(x\pm y) = \cosh x\cdot\cosh y,\\ &\sinh2x = 2\sinh x\cdot \cosh x, \cosh 2x = \cosh^2x+\sinh^2x = 2\cosh^2x - 1\end{aligned}$ |
| 3<br>积化和差公式 | $\sin\alpha\cos\beta=\frac12[\sin(\alpha+\beta)+\sin(\alpha-\beta)],\cos\alpha\sin\beta = \frac12[\sin(\alpha+\beta) - \sin(\alpha-\beta)]$ <br> $\cos\alpha\cos\beta = \frac12[cos(\alpha+\beta) + cos(\alpha - \beta)], \sin\alpha\sin\beta=-\frac12[\cos(\alpha+\beta) - \cos(\alpha-\beta)]$ |
| 4<br>和差化积公式 | $\displaystyle\sin\alpha + \sin\beta = 2\sin\left(\frac{\alpha+\beta}{2}\right) \cos\left(\frac{\alpha-\beta}{2}\right), \sin\alpha - \sin\beta = 2\sin\left(\frac{\alpha-\beta}{2}\right) \cos\left(\frac{\alpha+\beta}{2}\right)$ <br> $\displaystyle\cos\alpha + \cos\beta = 2\cos\left(\frac{\alpha+\beta}{2}\right) \cos\left(\frac{\alpha-\beta}{2}\right), \cos\alpha - \cos\beta = -2\sin\left(\frac{\alpha+\beta}{2}\right) \sin\left(\frac{\alpha-\beta}{2}\right)$ |
| 5<br>三角代换 | $\displaystyle\sqrt{a^2-x^2}\xrightarrow{x=a\sin t}a\cos t, \sqrt{a^2+x^2} \xrightarrow{x=a\tan t}a\sec t, \sqrt{x^2-a^2}\xrightarrow{x=a\sec t}a\tan t \left( a>0,t\in\left( -\frac{\pi}{2} , \frac{\pi}{2} \right) \right)$ |
| 6 | $\displaystyle\int\sqrt{a^2-x^2}\mathrm{d}x = \frac{a^2}{2}\arcsin\frac xa + \frac12x\sqrt{a^2-x^2} + C(a>0)$ |
| 7 | $\displaystyle\int\sqrt{x^2+a^2}\mathrm{d}x = \frac x2\sqrt{x^2+a^2} + \frac{a^2}2\ln \left\| x+\sqrt{x^2+a^2} \right\|+C(a>0)$ |
| 8 | $\displaystyle\int\frac{1}{\sqrt{x^2+a^2}}\mathrm{d}x = \ln\left\| x+ \sqrt{x^2+a^2} \right\| +C$, $\displaystyle\int\frac{1}{\sqrt{x^2-a^2}}\mathrm{d}x = \ln\left\| x + \sqrt{x^2+a^2}\right\|(a>0)$,特别地,$\displaystyle\int\frac{1}{\sqrt{x^2+1}}\mathrm{d}x=\left(x+\sqrt{x^2+1}\right) = \mathrm{arsinh}\, x$, $\displaystyle\int\frac{1}{\sqrt{x^2-1}}\mathrm{d}x = \ln\left( x+\sqrt{x^2-1}\right) = \mathrm{arcosh}\, x$ |
| 9 | $\displaystyle\int\sec x\mathrm{d}x = \int\frac{1}{\cos x}\mathrm{d}x = \int\frac{\sec^2x+\sec x \tan x}{\sec x + \tan x}\mathrm{d}x = \int\frac{1}{\sec x + \tan x}\mathrm{d}(\sec x + \tan x) = \ln \left\| \sec x + \tan x \right\| + C$ |
| 10 | $\displaystyle\int\csc x\mathrm{d}x = \int\frac{1}{\sin x}\mathrm{d}x = \ln\left\| \tan\frac x2 \right\| + C = \frac 12 \ln \left\| \frac{1-\cos x}{1 + \cos x}\right\| + C$ |
| 11 | $\displaystyle\int\tan x\mathrm{d}x = \int\frac{\sin x}{\cos x}\mathrm{d}x = -\int\frac{1}{\cos x}\mathrm{d}(\cos x) = -\ln \left\| \cos x\right\| +C$ |
| 12 | $\displaystyle\int\frac{1}{\tan x}\mathrm{d}x = \int\frac{\cos x}{\sin x}\mathrm{d}x = \int\frac{1}{\sin x}\mathrm{d}(\sin x) = \ln\left\| \sin x \right\| + C$ |
| 13 | $\displaystyle\int\arctan x\mathrm{d}x = x\arctan x - \ln \left\| 1+x^2 \right\| +C$ |
| 14<br>Wallis 公式 | $\displaystyle\int^{\frac{\pi}{2}}_{0}\sin^nx\mathrm{d}x = \int^{\frac{\pi}{2}}_{0}\cos^nx\mathrm{d}x = \begin{cases} \displaystyle\frac{n-1}{n}\cdot\frac{n-3}{n-2}\cdot\cdots\cdot\frac12\cdot\frac\pi2,&n为偶数 \\ \displaystyle\frac{n-1}{n}\cdot\frac{n-3}{n-2}\cdot\cdots\cdot\frac23\cdot1,&n为奇数 \end{cases} \\ = \begin{cases} \displaystyle\frac{(n-1)!!}{n!!}\cdot\frac\pi2,&n为偶数 \\ \displaystyle\frac{(n-1)!!}{n!!},&n为奇数 \end{cases}$ |
| 15 | $\displaystyle\int_0^\pi\sin^nx\mathrm{d}x = 2\int^\frac\pi2_0\sin^nx\mathrm{d}x,\int_0^\pi\cos^nx\mathrm{d}x = \begin{cases} 2\displaystyle\int^\frac\pi2_0\cos^nx\mathrm{d}x,&n为偶数 \\ 0,&n为奇数 \end{cases}$ <br> $\displaystyle\int_0^{2\pi}\sin^nx = \int_0^{2\pi}\cos^nx\mathrm{d}x = \begin{cases} 4\displaystyle\int^\frac\pi2_0\sin^nx\mathrm{d}x,&n为偶数 \\ 0,&n为奇数 \end{cases}$ <br> $\displaystyle\int_0^\frac\pi2f(\sin x)\mathrm{d}x = \int_0^\frac\pi2f(\cos x)\mathrm{d}x$, $\displaystyle\int_0^\pi f(\sin x)\mathrm{d}x \ne \int_0^\pi f(\cos x)\mathrm{d}x$ <br> $\displaystyle\int_0^\pi\pi f(\sin x)\mathrm{d}x = \frac\pi2\int_0^\pi f(\sin x)\mathrm{d}x = \pi\int_0^\frac\pi2 f(\sin x)\mathrm{d}x$ |
| 16<br>万能公式 | 令 $u=\displaystyle\tan\frac x2,x=2\arctan u$,则 $\displaystyle\sin x = \frac{2u}{1+u^2},\cos x=\frac{1-u^2}{1+u^2}, \mathrm{d}x = \frac{2}{1+u^2}\mathrm{d}u$ |
| 17 | $\displaystyle\int \frac{a\cos x+ b\sin x}{c\cos x + d \sin x} = A\int\mathrm{d}x+B\int\frac{\mathrm{d}(c\cos x+d \sin x)}{c \cos x + d \sin x}$ <br> (设 $a\cos x + b\sin x = A(c \cos x + d \sin x) + B(c \cos x + d \sin x)'$,由待定系数法求出A、B)$ |
@@ -0,0 +1,285 @@
---
title: Josh's Summary — 工科数学分析<br>Part 1.1 基本微分与积分
mathjax: true
comments: true
copyright: true
toc:
enable: true
number: false
wrap: true
expand_all: true
max_depth: 4
abbrlink: 1823c9d1
date: 2023-04-14 16:25:59
tags:
- 等价无穷小
- 导数公式
- Maclaurin 公式
- 曲率
- 积分公式
- 三角函数
categories:
- - Josh 的学习笔记
- 微积分
- - 数学
- 微积分
---
$\newcommand\diff{\mathop{}\!\mathrm{d}}$
# 1. 常见等价无穷小
||||
| :--: | :--: | :--: |
| $\sin x \sim x$ | $\tan x \sim x$ | $\arcsin x \sim x$ |
| $\arctan x \sim x$ | $\displaystyle\left( 1 - \cos x \right) \sim \dfrac{x^2}{2}$ | $\ln (1+x) \sim x$ |
| $\left( e^x -1 \right) \sim x$ | $\left( a^x - 1 \right) \sim x \ln a$ | $\left( \left( 1+x \right) ^\alpha -1 \right) \sim \alpha x$ |
<!-- more -->
# 2. 导数基本公式
| 一般函数 | 三角函数 | 反三角函数 | 双曲函数<br>(圆函数) |
| :--: | :--: | :--: | :----: |
| $\left( C \right)' = 0$ | $\left( \sin x \right)' = \cos x$ | $\displaystyle\left( \arcsin x \right)' = \dfrac{1}{\sqrt{1-x^2}}$ | $\displaystyle\left( \sinh x \right)' = \left(\dfrac{e^x-e^{-x}}{2}\right)' = \cosh x$ |
| $\left( x^\alpha \right)'=\alpha x^{\alpha-1} \left( \alpha \in \mathbb{Z} \right)$ | $\left( \cos x \right)' = -\sin x$ | $\displaystyle\left( \arccos x \right)' = -\dfrac{1}{\sqrt{1-x^2}}$ | $\displaystyle\left( \cosh x \right)' = \left( \dfrac{e^x+e^{-x}}{2} \right)'=\sinh x$ |
| $\displaystyle\left( \log_ax\right)'=\dfrac{1}{x\ln a}$ | $\displaystyle\left( \tan x \right)' = \dfrac{1}{\cos^2 x}=\sec^2 x$ | $\displaystyle\left( \arctan x \right)' = \dfrac{1}{1+x^2}$ | $\displaystyle\left( \mathrm{arsinh} \, x \right)' = \left(\ln \left( x+\sqrt{x^2 + 1} \right) \right)' = \dfrac{1}{x^2+1}$ |
| $( \ln$\| $x$ \|$)'=\displaystyle\dfrac{1}{x}$ | $\displaystyle\left( \cot x \right)' = -\dfrac{1}{\sin^2 x} = -\csc^2 x$ | $\displaystyle\left( \mathrm{arccot} \, x \right)' = -\dfrac{1}{1+x^2}$ | $\displaystyle\left( \mathrm{arcosh} \, x \right)' = \left( \ln \left( x + \sqrt{x^2 - 1} \right) \right)' = \dfrac{1}{\sqrt{x^2-1}}$
| | $\left( \sec x \right)' = \sec x \cdot \tan x$ |
| | $\left( \csc x \right)' = \csc x \cdot \cot x$ |
- Newton-Leibniz 公式:
$$
\begin{aligned}
\left( u \cdot v \right)^{\left( n \right)} &= u^{\left( n \right)}v + nu^{\left( n-1 \right)}v' + \dfrac{n \left( n-1 \right)}{2!}u^{\left( n-2 \right)}v'' + \cdots + \dfrac{n\left( n-1 \right)\cdots\left(n-k+1\right)}{k!}u^{\left( n-k \right)}v^{(k)} + \cdots + uv^{\left( n \right)} \\
&= \sum_{k=0}^{n}C_n^k u^{\left( u-k \right)}v^k
\end{aligned}
$$
可以注意到 Newton-Leibniz 公式具有类似二项式定理展开的形式。
# 3. 几个初等函数的 Maclaurin 公式
## 3.1 Taylor 公式的一般形式
$$\begin{aligned}
f(x)&=f(x_0) + f'(x_0)(x-x_0) + \dfrac{f''(x_0)}{2!}(x-x_0)^2 + \cdots + \dfrac{f^{(n)}(x_0)}{n!}(x-x_0)^n + R_n
\\
&= \sum_{k=0}^n \dfrac{f^{(n)}(x_0)}{n!}(x - x_0)^n + R_n
\end{aligned}$$
其中
$$
R_n = \dfrac{f^{(n+1)}(\xi)}{(n+1)!}(x-x_0)^{n+1} \xlongequal{x\to x_0} o\left( \left( x - x_0 \right)^n \right), \quad \xi\,在\,x\,和\,x_0\,之间
$$
## 3.2 Maclaurin 公式的一般形式
$$\begin{aligned}
f(x) &= f(0)+f'(0)\,x + \dfrac{f''(0)}{2!}x^2 + \cdots + \dfrac{f^{(n)}(0)}{n!}x^n + R_n
\\
&= \sum_{k=0}^n \dfrac{f^{(n)}(0)}{n!}x^n + R_n
\end{aligned}$$
其中
$$
R_n = \dfrac{f^{(n+1)}(\xi)}{(n+1)!}x^{n+1} = \dfrac{f^{(n+1)}(\theta x)}{(n+1)!} x^{n+1} \xlongequal{x\to x_0} o\left( \left( x - x_0 \right)^n \right), \quad \xi\,在\,0\,和\,x\,之间, 0<\theta<1
$$
## 3.3 指数函数的 Maclaurin 展开式
$$
e^x=1+x+\dfrac{x^2}{2} + \dfrac{x^3}{3} + \cdots +\dfrac{x^n}{n!} + \dfrac{e^{\theta x}}{(n+1)!}, \quad 0<\theta<1
$$
## 3.4 正弦函数的 Maclaurin 展开式
$$
\sin x = x - \dfrac{x^3}{3!} + \dfrac{x^5}{5!} + \cdots + (-1)^{m-1}\dfrac{x^{2m-1}}{(2m-1)!} + R_{2m}
$$
其中
$$
R_{2m}=\dfrac{\sin\left( \theta x + \dfrac{(2m-1)\pi}{2}\right)}{(2m+1)!}x^{2m+1} = o(x^{2m}), \quad 0<\theta<1
$$
## 3.5 余弦函数的 Maclaurin 展开式
$$
\cos x = 1 - \dfrac{x^2}{2!} + \dfrac{x^4}{4!} + \cdots + (-1)^m\dfrac{x^{2m}}{2m!} + R_{2m+1}
$$
其中
$$
R_{2m+1}=\dfrac{\cos(\theta x + (m+1)\pi)}{(2m+2)!} x^{2m+2}=o(x^{2m+2}), \quad 0<\theta<1
$$
## 3.6 $\ln (1+x)$ 的 Maclaurin 展开式
$$
\ln(1+x) = x - \dfrac{x^2}{2} + \dfrac{x^3}{3} -\dfrac{x^4}{4} + \cdots + \dfrac{(-1)^{n-1}x^n}{n} + R_n(x)
$$
其中
$$
R_n(x) = \dfrac{(-1)^n}{(n+1)(1+\theta x)^{n+1}}x^{n+1} = o(x^n), \quad 0<\theta<1
$$
## 3.7 $(1+x)^\alpha$ 的 Maclaurin 展开式
$$
(1+x)^\alpha = 1 + \alpha x + \dfrac{\alpha(\alpha-1)}{2!}x^2 + \cdots + \dfrac{\alpha(\alpha - 1)\cdots (\alpha-n+1)}{n!}x^n + R_n(x)
$$
其中
$$
R_n(x) = \dfrac{\alpha(\alpha -1)\cdots(\alpha-n)}{(n+1)!}(1+\theta x)^{\alpha-n-1}x^{n+1} = o(x), \quad 0<\theta<1
$$
## 3.8 $\dfrac{1}{1-x}$ 的 Maclaurin 展开式
$$
\dfrac{1}{1-x} = 1+x+x^2+\cdots+x^n +o(x^n)
$$
# 4. 曲率及曲率半径
| 曲率 | 曲率半径 |
| :--: | :--: |
| $K=\left\| \dfrac{\diff \alpha}{\diff s}\right\| \xlongequal{令\ \tan \alpha = y', 则\ \alpha = \arctan y'} \dfrac{\left\| \dfrac{y''}{1+y'^2}\diff x \right\|}{\sqrt{1+y'^2}}\diff x = \dfrac{\left\| y'' \right\|}{\left( 1 + y' \right)^{3/2}}$ | $R = \dfrac{1}{K}$ |
# 5. 积分常用公式
| 序 | 描述 | 公式 |
| :--: | :----: | :----------------------------------------------:|
| 1 | 定积分的定义 | $\displaystyle\int^1_0f(x)\diff x=I=\lim_{\lambda \to 0}\sum_{i=1}^{n}f(\xi_i)\Delta x_i$,其中 $\lambda = \max \left\{ \Delta x_1,\Delta x_2, \cdots, \Delta x_n \right\}$ |
| 2 | 变上限积分 | $考察定积分\displaystyle\int^x_af(x)\diff x=\int^x_af(t)\diff t$,对 $\displaystyle\Phi(x)=\int_a^xf(t)\diff t$,有 $\displaystyle\Phi'(x)=\dfrac{\diff }{\diff x}\int_a^xf(t)\diff t = f(x)$ |
| 3 | 变上限积分的扩展 | $\displaystyle\dfrac{\diff }{\diff x}\int^{\beta(x)}_{\alpha(x)}f'(t)\diff t = f\left[ \beta\left(x\right)\right]\beta'(x)-f[\alpha(x)]\alpha'(x)$ |
| 4 | 上下限对称的积分 | 若 $f(x)$ 为偶函数,则 $\displaystyle\int_{-a}^af(x)\diff x=2\int_0^af(x)\diff x$;若 $f(x)$ 为奇函数,则 $\displaystyle\int_{-a}^af(x)\diff x=0$ |
| 5 | 周期函数的积分 | $\displaystyle f(x+T)=f(x)\Rightarrow\int_0^{nT}f(x)\diff x=n\int^T_0f(x)\diff x$ |
| 6 | 分部积分法 | $\displaystyle\int uv'\diff x=uv - \int u'v\diff x \Leftrightarrow \int u\diff v = uv - \int v\diff u$ |
# 6. 基本积分表
| 序 | 积分式 |
| :--: | :-------------------------: |
| 1 | $\displaystyle\int k\diff x=kx+C$,特别地 $\displaystyle\int\diff x=x+C$ |
| 2 | $\displaystyle\int x^\mu\diff x=\dfrac{x^{\mu+1}}{\mu+1}+C(\mu\ne-1)$,特别地 $\displaystyle\int \dfrac{1}{x^2}\diff x=-\dfrac{1}{x}+C,\int\dfrac{1}{\sqrt{x}}\diff x=2\sqrt{x}+C$ |
| 3 | $\displaystyle\int\dfrac{1}{x}\diff x=\ln \|x\|+C$ |
| 4 | $\displaystyle\int\dfrac{1}{1+x^2}\diff x = \arctan x +C$ |
| 5 | $\displaystyle\int\dfrac{1}{\sqrt{1-x^2}}\diff x=\arcsin x+C$ |
| 6 | $\displaystyle\int\sin x\diff x = -\cos x+C, \int\cos x\diff x = \sin x +C$ |
| 7 | $\displaystyle\int\dfrac{\diff x}{\cos^2x} = \int\sec^2x\diff x = \tan x +C, \int\dfrac{\diff x}{\sin^2x}=\int\csc^2x\diff x = -\cot x +C$ |
| 8 | $\displaystyle\int a^x\diff x = \dfrac{a^x}{\ln a} + C$,特别地 $\displaystyle\int e^x\diff x = e^x +C$
| 9 | $\displaystyle\int \sinh x\diff x = \cosh x + C,\int \cosh x \diff x=\sinh x +C$ |
# 7. 三角函数相关公式
| 序 | 公式 |
| :--: | :-------------------------: |
| 1 | $\sin^2x+\cos^2x=1, \tan^2x+1=\sec^2x,\cot^2x+1=\csc^2x$ |
| 2 | $\begin{aligned}&\cosh^2x-\sinh^2x=1,\\ &\sinh(x\pm y)=\sinh x\cdot\cosh y \pm \sinh y\cdot\cosh x, \cosh(x\pm y) = \cosh x\cdot\cosh y,\\ &\sinh2x = 2\sinh x\cdot \cosh x, \cosh 2x = \cosh^2x+\sinh^2x = 2\cosh^2x - 1\end{aligned}$ |
| 3<br>积化和差公式 | $\sin\alpha\cos\beta=\dfrac12[\sin(\alpha+\beta)+\sin(\alpha-\beta)],\cos\alpha\sin\beta = \dfrac12[\sin(\alpha+\beta) - \sin(\alpha-\beta)]$ <br> $\cos\alpha\cos\beta = \dfrac12[cos(\alpha+\beta) + cos(\alpha - \beta)], \sin\alpha\sin\beta=-\dfrac12[\cos(\alpha+\beta) - \cos(\alpha-\beta)]$ |
| 4<br>和差化积公式 | $\displaystyle\sin\alpha + \sin\beta = 2\sin\left(\dfrac{\alpha+\beta}{2}\right) \cos\left(\dfrac{\alpha-\beta}{2}\right), \sin\alpha - \sin\beta = 2\sin\left(\dfrac{\alpha-\beta}{2}\right) \cos\left(\dfrac{\alpha+\beta}{2}\right)$ <br> $\displaystyle\cos\alpha + \cos\beta = 2\cos\left(\dfrac{\alpha+\beta}{2}\right) \cos\left(\dfrac{\alpha-\beta}{2}\right), \cos\alpha - \cos\beta = -2\sin\left(\dfrac{\alpha+\beta}{2}\right) \sin\left(\dfrac{\alpha-\beta}{2}\right)$ |
| 5<br>三角代换 | $\displaystyle\sqrt{a^2-x^2}\xrightarrow{x=a\sin t}a\cos t, \sqrt{a^2+x^2} \xrightarrow{x=a\tan t}a\sec t, \sqrt{x^2-a^2}\xrightarrow{x=a\sec t}a\tan t \left( a>0,t\in\left( -\dfrac{\pi}{2} , \dfrac{\pi}{2} \right) \right)$ |
| 6 | $\displaystyle\int\sqrt{a^2-x^2}\diff x = \dfrac{a^2}{2}\arcsin\dfrac xa + \dfrac12x\sqrt{a^2-x^2} + C(a>0)$ |
| 7 | $\displaystyle\int\sqrt{x^2+a^2}\diff x = \dfrac x2\sqrt{x^2+a^2} + \dfrac{a^2}2\ln \left\| x+\sqrt{x^2+a^2} \right\|+C(a>0)$ |
| 8 | $\displaystyle\int\dfrac{1}{\sqrt{x^2+a^2}}\diff x = \ln\left\| x+ \sqrt{x^2+a^2} \right\| +C$, $\displaystyle\int\dfrac{1}{\sqrt{x^2-a^2}}\diff x = \ln\left\| x + \sqrt{x^2-a^2}\right\|(a>0)$<br>特别地,$\displaystyle\int\dfrac{1}{\sqrt{x^2+1}}\diff x=\ln\left(x+\sqrt{x^2+1}\right) = \mathrm{arsinh}\, x$, $\displaystyle\int\dfrac{1}{\sqrt{x^2-1}}\diff x = \ln\left( x+\sqrt{x^2-1}\right) = \mathrm{arcosh}\, x$ |
| 9 | $\displaystyle\int\sec x\diff x = \int\dfrac{1}{\cos x}\diff x = \int\dfrac{\sec^2x+\sec x \tan x}{\sec x + \tan x}\diff x = \int\dfrac{1}{\sec x + \tan x}\diff (\sec x + \tan x) = \ln \left\| \sec x + \tan x \right\| + C$ |
| 10 | $\displaystyle\int\csc x\diff x = \int\dfrac{1}{\sin x}\diff x = \ln\left\| \tan\dfrac x2 \right\| + C = \dfrac 12 \ln \left\| \dfrac{1-\cos x}{1 + \cos x}\right\| + C$ |
| 11 | $\displaystyle\int\tan x\diff x = \int\dfrac{\sin x}{\cos x}\diff x = -\int\dfrac{1}{\cos x}\diff (\cos x) = -\ln \left\| \cos x\right\| +C$ |
| 12 | $\displaystyle\int\dfrac{1}{\tan x}\diff x = \int\dfrac{\cos x}{\sin x}\diff x = \int\dfrac{1}{\sin x}\diff (\sin x) = \ln\left\| \sin x \right\| + C$ |
| 13 | $\displaystyle\int\arctan x\diff x = x\arctan x - \ln \left\| 1+x^2 \right\| +C$ |
| 14<br>Wallis 公式 | $\displaystyle\int^{\pi/2}_{0}\sin^nx\diff x = \int^{\pi/2}_{0}\cos^nx\diff x = \begin{cases} \displaystyle\dfrac{n-1}{n}\cdot\dfrac{n-3}{n-2}\cdot\cdots\cdot\dfrac12\cdot\dfrac\pi2,&n为偶数 \\ \displaystyle\dfrac{n-1}{n}\cdot\dfrac{n-3}{n-2}\cdot\cdots\cdot\dfrac23\cdot1,&n为奇数 \end{cases} \\ = \begin{cases} \displaystyle\dfrac{(n-1)!!}{n!!}\cdot\dfrac\pi2,&n为偶数 \\ \displaystyle\dfrac{(n-1)!!}{n!!},&n为奇数 \end{cases}$ |
| 15 | $\displaystyle\int_0^\pi\sin^nx\diff x = 2\int^{\pi/2}_0\sin^nx\diff x,\int_0^\pi\cos^nx\diff x = \begin{cases} 2\displaystyle\int^{\pi/2}_0\cos^nx\diff x,&n为偶数 \\ 0,&n为奇数 \end{cases}$ <br> $\displaystyle\int_0^{2\pi}\sin^nx = \int_0^{2\pi}\cos^nx\diff x = \begin{cases} 4\displaystyle\int^{\pi/2}_0\sin^nx\diff x,&n为偶数 \\ 0,&n为奇数 \end{cases}$ <br> $\displaystyle\int_0^{\pi/2}f(\sin x)\diff x = \int_0^{\pi/2}f(\cos x)\diff x$, $\displaystyle\int_0^\pi f(\sin x)\diff x \ne \int_0^\pi f(\cos x)\diff x$ <br> $\displaystyle\int_0^\pi\pi f(\sin x)\diff x = \dfrac\pi2\int_0^\pi f(\sin x)\diff x = \pi\int_0^{\pi/2} f(\sin x)\diff x$ |
| 16<br>万能公式 | 令\ $u=\displaystyle\tan\dfrac x2,x=2\arctan u$,则\ $\displaystyle\sin x = \dfrac{2u}{1+u^2},\cos x=\dfrac{1-u^2}{1+u^2}, \diff x = \dfrac{2}{1+u^2}\diff u$ |
| 17 | $\displaystyle\int \dfrac{a\cos x+ b\sin x}{c\cos x + d \sin x} = A\int\diff x+B\int\dfrac{\diff (c\cos x+d \sin x)}{c \cos x + d \sin x}$ <br> (设 $a\cos x + b\sin x = A(c \cos x + d \sin x) + B(c \cos x + d \sin x)'$,由待定系数法求出 $A, B$) |
# 8. 定积分的几何应用
## 8.1 平面
### 8.1.1 直角坐标
1. 直角梯形的面积
$$\begin{equation*}
A = \int_a^b [f(x_1) - f(x_2)] \diff x
\end{equation*}$$
2. 曲边梯形的面积:对于参数方程 $\begin{cases}
x = \varphi(x) \\ y = {\psi(x)}
\end{cases}$,曲边梯形的面积(变换上下限)
$$\begin{equation*}
A = \int_a^b y\diff x = \int_{t_1}^{t_2} \psi(t) \diff \varphi(t) = \int_{t_1}^{t_2} \psi(t)\varphi'(t) \diff t
\end{equation*}$$
3. 椭圆的面积:椭圆 $\begin{cases}
x = a \cos t \\ y = b \sin t
\end{cases}$,即 $\dfrac{x^2}{a^2} + \dfrac{y^2}{b^2} = 1$ 的面积
$$\begin{equation*}
A = 4 \int_0^a y \diff x = 4ab \int_0^{\pi/2} (1-\cos t)^2 \diff t = 3\pi a^2
\end{equation*}$$
4. 摆线的面积:摆线 $\begin{cases}
x = a (t - \sin t) \\ y = a (1 - \cos t)
\end{cases}$ 的一拱与 $x$ 轴所围图形的面积
$$\begin{equation*}
A = \int_0^2\pi a y \diff x = a^2 \int_0^{2\pi} (1 - \cos t)^2 \diff t = 3\pi a^2
\end{equation*}$$
### 8.1.2 极坐标
1. 扇形的面积:由 $\rho = \rho(\theta)$ 及射线 $\theta = \alpha$ 和 $\theta = \beta$ 所围曲边扇形的面积
$$\begin{equation*}
A = \int_\alpha^\beta \frac{1}{2} \rho^2(\theta) \diff \theta = \frac{1}{2} \int_\alpha^\beta \rho^2 \diff \theta
\end{equation*}$$
2. 阿基米德螺线:阿基米德螺线 $\rho = a \theta (a > 0)$ 对应 $\theta$ 从 $0$ 变换到 $2\pi$ 所围图形的面积
$$\begin{equation*}
A = \int_0^{2\pi} \frac{1}{2} (a\theta)^2\diff \theta = \frac{4}{3} \pi^3 a^2
\end{equation*}$$
3. 双纽线:双纽线 $\rho^2 = a^2 \cos 2\theta$ 所围平面图形的面积
$$\begin{equation*}
A = 4 \int_0^{\pi/4} a^2 \cos 2\theta \diff \theta = a^2
\end{equation*}$$
4. 心形线:心形线 $\rho = a(a+\cos\theta), a>0$ 所围平面图形的面积
$$\begin{equation*}
A = 2 \cdot \frac{1}{2} \int_0^\pi a^2 (1+ \cos \theta)^2 \diff \theta = \frac{3}{2}\pi a^2
\end{equation*}$$
5. 曲线的弧长
| 弧微分 | 直角坐标 | 参数方程 | 极坐标 |
| :--: | :--: | :--: | :--: |
| $\diff s = \sqrt{(\diff x)^2 + (\diff y)^2}$ | $s = \displaystyle\int_a^b \sqrt{1 + y'^2}\diff x$ | $s = \displaystyle\int_a^b \sqrt{\varphi'^2(t) + \psi'^2(t)}\diff t$ | $s = \displaystyle\int_\alpha^\beta \sqrt{\rho^2{\theta} + \rho'^2(\theta)} \diff\theta$
## 8.2 空间
1. 已知平行截面面积求立体体积:令 $A(x)$ 为截面面积,则立体体积
$$\begin{equation*}
V = \int_a^b A(x) \diff x
\end{equation*}$$
2. 旋转体体积
| 薄片法 | 柱壳法 |
| :--: | :--: |
| $V = \displaystyle\int_a^b \pi f^2(x) \diff x$ | $V = \displaystyle\int_a^b 2\pi x \left| f(x) \right|\diff x$ |
+33 -23
View File
@@ -145,6 +145,8 @@ $$
> $$ > $$
> \{x\mid Ax\preceq b, Cx = d\} = \{ x\mid f(x) \in \bfR^m_+ \times \{0\}\} > \{x\mid Ax\preceq b, Cx = d\} = \{ x\mid f(x) \in \bfR^m_+ \times \{0\}\}
> $$ > $$
>
> {% note info %}这里可以这样理解:函数 $f(x) = (b -Ax, d - Cx)$ 在条件 $Ax \preceq b, Cx = d$ 下的值域为 $\mathbf{R}^m_+ \times \{0\}$。{% endnote %}
> **举例**&emsp;**线性矩阵不等式的解**。条件 > **举例**&emsp;**线性矩阵不等式的解**。条件
> >
@@ -168,7 +170,7 @@ $$
> \{ x\mid x^\TT Px \leqslant (c^\TT x) ^2, c^\TT x \geqslant 0 \} > \{ x\mid x^\TT Px \leqslant (c^\TT x) ^2, c^\TT x \geqslant 0 \}
> $$ > $$
> >
> 是凸集,其中 $P\in\bfS^n_+$,$c\in\bfR$ 这是因为它是二阶锥 > 是凸集,其中 $P\in\bfS^n_+$,$c\in\bfR$。这是因为它是二阶锥
> >
> $$ > $$
> \{ (z,t)\mid z^\TT z \leqslant t ^2 , t \geqslant 0 \} > \{ (z,t)\mid z^\TT z \leqslant t ^2 , t \geqslant 0 \}
@@ -190,9 +192,9 @@ $$
## 3.1 透视函数 ## 3.1 透视函数
&emsp;&emsp;定义 $P:\bfR^{n+1}\to\bfR^n$ 为**透视函数**(*perspective function*),其定义域为 $\dom P = \bfR^n \times \bfR_{++}$。(此处的 $\bfR_{++}$ 表示正实数集合,即 $\bfR_{++} = \{ x\in\bfR\mid x > 0 \}$。)透视函数对向量进行伸缩(scale),或称为规范化(normalize),使得最后一维分量为1 并舍弃之。 &emsp;&emsp;定义 $P:\bfR^{n+1}\to\bfR^n$,$P(z,t) = z/t$ 为**透视函数**(*perspective function*),其定义域为 $\dom P = \bfR^n \times \bfR_{++}$。(此处的 $\bfR_{++}$ 表示正实数集合,即 $\bfR_{++} = \{ x\in\bfR\mid x > 0 \}$。)透视函数对向量进行伸缩(scale),或称为规范化(normalize),使得最后一维分量为1 并舍弃之。
> **注释**&emsp;我们用小孔成象来解释透视函数。($\bfR^3$ 中的)小孔照相机由一个不透明的水平面 $x_3 = 0$ 和一个在原点的小孔组成,光线通过这个小孔在 $x_3 = -1$ 呈现出一个水平图像。在相机上方 $x(x_3 > 0)$ 处的一个物体,在相平面的点 $=(x_1/x_3,x_2/x_3,1)$ 处形成一个图像。忽略象点的最后一维分量(因为它恒等于 $-1$),$x$ 处的点的象在象平面上呈现于 $y=-(x_1/x_3,x_2/x_3)$ 处。[图 15](#图15)显示了这个过程。 > **注释**&emsp;我们用小孔成象来解释透视函数。($\bfR^3$ 中的)小孔照相机由一个不透明的水平面 $x_3 = 0$ 和一个在原点的小孔组成,光线通过这个小孔在 $x_3 = -1$ 呈现出一个水平图像。在相机上方 $x$($x_3 > 0$)处的一个物体,在相平面的点 $-(x_1/x_3,x_2/x_3,1)$ 处形成一个图像。忽略象点的最后一维分量(因为它恒等于 $-1$),$x$ 处的点的象在象平面上呈现于 $y=-(x_1/x_3,x_2/x_3)$ 处。[图 15](#图15)显示了这个过程。
> >
> <a id="图15"></a> > <a id="图15"></a>
> >
@@ -204,21 +206,23 @@ $$
P(C) = \{ P(x)\mid x\in C \} P(C) = \{ P(x)\mid x\in C \}
$$ $$
也是凸集。这个结论很直观:通过小孔观察一个凸的物体,可以得到凸的象。为解释这个事实,我们将说明在透视函数作用下,线段将被映射成线段。(也可以这样理解,通过小孔,一条线段的象是一条线段。)假设 $x = (\tilde{x},x_{n+1}), y = (\tilde{y}, y_{n+1}) \in \bfR^{n+1}$,并且 $x_{n+1}>0, y_{n+1}>0$ 。那么,对于 $0 \leqslant \theta \leqslant 1$ 也是凸集。这个结论很直观:通过小孔观察一个凸的物体,可以得到凸的象。为解释这个事实,我们将说明在透视函数作用下,线段将被映射成线段。(也可以这样理解,通过小孔,一条线段的象是一条线段。)
> **解释**&emsp;假设 $x = (\tilde{x},x_{n+1})$,$y = (\tilde{y}, y_{n+1}) \in \bfR^{n+1}$,并且 $x_{n+1}>0$,$y_{n+1}>0$ 。那么,对于 $0 \leqslant \theta \leqslant 1$
>
> $$
> P(\theta x + (1-\theta)y) = \frac{\theta\tilde{x}+ (1-\theta)\tilde{y}}{\theta x_{n+1} + (1-\theta)y_{n+1}} = \mu P(x) + (1-\mu) P(y)
$$ $$
P(\theta x + (1-\theta)y) = \frac{\theta\tilde{x}+ (1-\theta)\tilde{y}}{\theta x_{n+1} + (1-\theta)y_{n+1}} = \mu P(x) + (1-\mu) P(x) >
$$ > 其中
>
> $$
> \mu = \frac{\theta x_{n+1}}{\theta x_{n+1} + (1-\theta) y_{n+1}}\in[0,1]
> $$
>
> $\theta$ 和 $\mu$ 之间的关系是单调的:当 $\theta$ 在 $0$、$1$ 间变化时(形成线段 $[x,y]$),$\mu$ 也在 $0$、$1$ 间变化(形成线段 $[P(x),P(y)]$。这说明 $P([x,y]) = [P(x),P(y)]$。
其中 &emsp;&emsp;现在假设 $C$ 是凸的,并且有 $C \subseteq \dom P$(即对于所有 $x\in C$,$x_{n+1} > 0$)及 $x,y\in C$。为显示 $P(C)$ 的凸性,需要说明线段 $[P(x), P(y)]$ 在 $P(C)$ 中。这条线段是线段 $[x,y]$ 在 $P$ 的象,因而属于 $P(C)$。
$$
\mu = \frac{\theta x_{n+1}}{\theta x_{n+1} + (1-\theta) y_{n+1}}\in[0,1]
$$
$\theta$ 和 $\mu$ 之间的关系是单调的:当 $\theta$ 在 $0$、$1$ 间变化时(形成线段 $[x,y]$),$\mu$ 也在 $0$、$1$ 间变化(形成线段 $[P(x),P(y)]$。这说明 $P([x,y]) = [P(x),P(y)]$。
&emsp;&emsp;现在假设 $C$ 是凸的,并且有 $C \subseteq \dom P$(即对于所有 $x\in C$,$x_{n+1} > 0$) 及 $x,y\in C$。为显示 $P(C)$ 的凸性,需要说明线段 $[P(x), P(y)]$ 在 $P(C)$ 中。这条线段是线段 $[x,y]$ 在 $P$ 的象,因而属于 $P(C)$。
&emsp;&emsp;一个凸集在透视函数下的原象也是凸的:如果 $C\subseteq \bfR^n$ 为凸集,那么 &emsp;&emsp;一个凸集在透视函数下的原象也是凸的:如果 $C\subseteq \bfR^n$ 为凸集,那么
@@ -226,7 +230,7 @@ $$
P^{-1}(C) = \{ (x,t)\in\bfR^{n+1}\mid x/t\in C, t > 0 \} P^{-1}(C) = \{ (x,t)\in\bfR^{n+1}\mid x/t\in C, t > 0 \}
$$ $$
是凸集。为证明这点,假设 $(x,t)\in P^{-1}(C), (y,s)\in P^{-1}(C), 0 \leqslant \theta \leqslant 1$。我们需要说明 是凸集。为证明这点,假设 $(x,t)\in P^{-1}(C)$,$(y,s)\in P^{-1}(C)$,$0 \leqslant \theta \leqslant 1$。我们需要说明
$$ $$
\theta(x,t) + (1-\theta)(y,s) \in P^{-1} (C) \theta(x,t) + (1-\theta)(y,s) \in P^{-1} (C)
@@ -235,13 +239,19 @@ $$
即 即
$$ $$
\frac{\theta x + (1-\theta)y}{\theta t + (1-\theta)s} = \mu (x/t) + (1-\mu)(y/s) \frac{\theta x + (1-\theta)y}{\theta t + (1-\theta)s} \in C
$$
(显然,$\theta t+(1-\theta)s>0$)。这可从下式看出,
$$
\frac{\theta x+(1-\theta)y}{\theta t+(1-\theta)s}=\mu(x/t)+(1-\mu)(y/s)
$$ $$
其中 其中
$$ $$
\mu = \frac{\theta t}{\theta t + (1-\theta)s} \in [0,1] \mu=\frac{\theta t}{\theta t+(1-\theta)s}\in[0,1]
$$ $$
## 3.2 线性分式函数 ## 3.2 线性分式函数
@@ -256,13 +266,13 @@ $$\begin{equation}\label{AffineFunction}
\end{array}\right] \end{array}\right]
\end{equation}$$ \end{equation}$$
其中 $A \in \bfR ^{m\times n}, b \in \bfR^m, c \in \bfR^n$ 并且 $d\in\bfR^n$。则由 $f =P\circ g$ 给出的函数 $f:\bfR^n \to \bfR^m$ 其中 $A \in \bfR ^{m\times n}$,$b \in \bfR^m$,$c \in \bfR^n$ 并且 $d\in\bfR^n$。则由 $f =P\circ g$ 给出的函数 $f:\bfR^n \to \bfR^m$
$$\begin{equation}\label{LinearFractionalFunction} $$\begin{equation}\label{LinearFractionalFunction}
f(x) = (Ax+b)/(c^\TT x + d),\qquad \dom f = \{x\mid c^\TT x + d > 0\} f(x) = (Ax+b)/(c^\TT x + d),\qquad \dom f = \{x\mid c^\TT x + d > 0\}
\end{equation}$$ \end{equation}$$
称为**线性分式**(*linear-fractional*)(或**投射**(*projective*))函数。如果 $c = 0, d > 0$,则 $f$ 的定义域为 $\bfR^n$ 并且 $f$ 是仿射函数。因此,我们可以将仿射和线性函数视为特殊的线性分式函数。 称为**线性分式**(*linear-fractional*)(或**投射**(*projective*))函数。如果 $c = 0$,$d > 0$,则 $f$ 的定义域为 $\bfR^n$ 并且 $f$ 是仿射函数。因此,我们可以将仿射和线性函数视为特殊的线性分式函数。
> **注释**&emsp;**投射解释**。可以很方便地将一个线性分式函数表示为:将矩阵 > **注释**&emsp;**投射解释**。可以很方便地将一个线性分式函数表示为:将矩阵
> >
@@ -274,7 +284,7 @@ $$\begin{equation}\label{LinearFractionalFunction}
> >
> 作用于(即左乘)点 $(x,1)$,得到 $(Ax + b,c^\TT x + d)$;然后将所得结果做伸缩变换或归一化,以使得其最后一个分量为一,得到 $(f(x), 1)$。 > 作用于(即左乘)点 $(x,1)$,得到 $(Ax + b,c^\TT x + d)$;然后将所得结果做伸缩变换或归一化,以使得其最后一个分量为一,得到 $(f(x), 1)$。
> >
> 也可以从儿何上进行解释,即这个表达式将 $\bfR^n$ 与 $\bfR^{n+1}$ 空间上的一组射线联系了起来。也就是说,对于 $\bfR^n$ 空间的一个点 $z$,我们可以构造一个 $\bfR^{n+1}$ 空间的(开)射线 $P(z) = \{t(z,1)\mid t > 0\}$。这条射线上每个点的最后一个分量均是正值。反之, $\bfR^{n+1}$ 空间中每条以原点为顶点并且最后一个分量为正值的射线均可以由一些 $v\in\bfR^n$ 表示为 $\P(v) = \{t(v, 1)\mid t \geqslant 0\}$。$\P$ 表示了 $\bfR^n$ 与最后一个分量为正的射线之间的(投射)关系,这种关系是一一对应和满的。 > 也可以从儿何上进行解释,即这个表达式将 $\bfR^n$ 与 $\bfR^{n+1}$ 空间上的一组射线联系了起来。也就是说,对于 $\bfR^n$ 空间的一个点 $z$,我们可以构造一个 $\bfR^{n+1}$ 空间的(开)射线 $\P(z) = \{t(z,1)\mid t > 0\}$。这条射线上每个点的最后一个分量均是正值。反之, $\bfR^{n+1}$ 空间中每条以原点为顶点并且最后一个分量为正值的射线均可以由一些 $v\in\bfR^n$ 表示为 $\P(v) = \{t(v, 1)\mid t \geqslant 0\}$。$\P$ 表示了 $\bfR^n$ 与最后一个分量为正的射线之间的(投射)关系,这种关系是一一对应和满的。
> >
> 线性分式函数 $\eqref{LinearFractionalFunction}$ 可以表示为 > 线性分式函数 $\eqref{LinearFractionalFunction}$ 可以表示为
> >
@@ -282,11 +292,11 @@ $$\begin{equation}\label{LinearFractionalFunction}
> f(x) = \P^{-1}(Q\P(x)) > f(x) = \P^{-1}(Q\P(x))
> $$ > $$
> >
> 因此,从 $x\in\dom f$ 出发,即由一个满足 $c^\TT x +d > 0$ 的点,可以得到 $\bfR^{n+1}$ 空间的一条射线 $\P(x)$。将线性变换矩阵 $Q$ 作用于这条射线,就可以得到另一条射线 $Q\P(x)$。因为 $x \in \dom f$, 这条射线的最后一个分量为正。最后,我们也可以通过逆投射变换恢复出 $f(x)$。 > 因此,从 $x\in\dom f$ 出发,即由一个满足 $c^\TT x +d > 0$ 的点,可以得到 $\bfR^{n+1}$ 空间的一条射线 $\P(x)$。将线性变换矩阵 $Q$ 作用于这条射线,就可以得到另一条射线 $Q\P(x)$。因为 $x \in \dom f$,这条射线的最后一个分量为正。最后,我们也可以通过逆投射变换恢复出 $f(x)$。
&emsp;&emsp;类似于透视函数,线性分式函数也是保凸的。如果 $C$ 是凸集并且在 $f$ 的定义域中(即任意 $x\in C$ 满足 $c^\TT x+d > 0$),那么 $C$ 的象 $f(C)$ 也是凸集。根据前述的结果可以直接得到这个结论: $C$ 在仿射映射 $\eqref{AffineFunction}$ 下的象是凸的,并且在透视函数 $P$ 下的映射(即 $f(C)$)是凸的。类似地,如果 $C \subseteq \bfR^m$ 是凸集,那么其原象 $f^{-1}(C)$ 也是凸的。 &emsp;&emsp;类似于透视函数,线性分式函数也是保凸的。如果 $C$ 是凸集并且在 $f$ 的定义域中(即任意 $x\in C$ 满足 $c^\TT x+d > 0$),那么 $C$ 的象 $f(C)$ 也是凸集。根据前述的结果可以直接得到这个结论: $C$ 在仿射映射 $\eqref{AffineFunction}$ 下的象是凸的,并且在透视函数 $P$ 下的映射(即 $f(C)$)是凸的。类似地,如果 $C \subseteq \bfR^m$ 是凸集,那么其原象 $f^{-1}(C)$ 也是凸的。
> **举例**&emsp;**条件概率**。设 $u$ 和 $v$ 是分别在 $\{1, \cdots, n\}$ 和 $\{1, \cdots, m\}$ 中取值的随机变量,并且 $p_ij$ 表示概率 $\prob(u = i,v = j)$。那么条件概率 $f_{ij} = \prob(u = i\mid v = j)$ 由下式给出 > **举例**&emsp;**条件概率**。设 $u$ 和 $v$ 是分别在 $\{1, \cdots, n\}$ 和 $\{1, \cdots, m\}$ 中取值的随机变量,并且 $p_{ij}$ 表示概率 $\prob(u = i,v = j)$。那么条件概率 $f_{ij} = \prob(u = i\mid v = j)$ 由下式给出
> >
> $$ > $$
> f_{ij} = \frac{p_{ij}}{\displaystyle\sum_{k=1}^n p_{kj}} > f_{ij} = \frac{p_{ij}}{\displaystyle\sum_{k=1}^n p_{kj}}
+7 -9
View File
@@ -49,7 +49,7 @@ $$
x \preceq_K y \Longleftrightarrow y - x \in K x \preceq_K y \Longleftrightarrow y - x \in K
$$ $$
$y \prec_K x$ 也可以写为 $x \succeq_K y$。类似地,定义相应的严格偏序关系为 $y \preceq_K x$ 也可以写为 $x \succeq_K y$。类似地,定义相应的严格偏序关系为
$$ $$
x \prec_K y \Longleftrightarrow y - x \in \iint K x \prec_K y \Longleftrightarrow y - x \in \iint K
@@ -59,16 +59,15 @@ $$
<!-- more --> <!-- more -->
&emsp;&emsp;当 $K = \bfR_+$ 时,偏序关系 $\preceq_K$ 就是通常意义上 $\bfR$ 中的序 $\leqslant$ 相应地,严格偏序关系 $\prec_K$ 与 $\bfR$ 上的严格序 $<$ 相同。因此,广义不等式包含了 $\bfR$ 上的(不严格和严格)不等式,它是广义不等式的一种特殊情况。 &emsp;&emsp;当 $K = \bfR_+$ 时,偏序关系 $\preceq_K$ 就是通常意义上 $\bfR$ 中的序 $\leqslant$;相应地,严格偏序关系 $\prec_K$ 与 $\bfR$ 上的严格序 $<$ 相同。因此,广义不等式包含了 $\bfR$ 上的(不严格和严格)不等式,它是广义不等式的一种特殊情况。
> **举例**&emsp;**非负象限及分量不等式**。非负象限 $K = \bfR^n_+$ 是一个正常锥。相应的广义不等式 $\preceq_K$ 对应于向量间的分量不等式,即 $x \preceq_K y$ 等价于 $x_i \leqslant y_i, i = 1,\cdots,n$。相应地,其严格不等式对应于严格的分量不等式,即 $x \prec_K y$ 等价于 $x_i < y_i, i = 1,\cdots,n$。 > **举例**&emsp;**非负象限及分量不等式**。非负象限 $K = \bfR^n_+$ 是一个正常锥。相应的广义不等式 $\preceq_K$ 对应于向量间的分量不等式,即 $x \preceq_K y$ 等价于 $x_i \leqslant y_i, i = 1,\cdots,n$。相应地,其严格不等式对应于严格的分量不等式,即 $x \prec_K y$ 等价于 $x_i < y_i, i = 1,\cdots,n$。
> >
> 我们将常常使用对应于非负象限的不严格和严格的偏序关系,因此省略下标 $\bfR^n_+$。当 $\preceq$ 或 $\prec$ 出现在向量间的时候,该符号应被理解为分量不等式。 > 我们会经常使用对应于非负象限的不严格和严格的偏序关系,因此省略下标 $K$。当 $\preceq$ 或 $\prec$ 出现在向量间的时候,该符号应被理解为分量不等式。
> **举例**&emsp;**半正定锥和矩阵不等式**。半正定锥是 $S^n$ 空间中的正常锥,相应的广义不等式 $\preceq_K$ 就是通常的矩阵不等式,即 $X \preceq_K Y$ 等价于 $Y - X$ 为半正定矩阵。(在 $S^n$ 中)$S^n_+$ 的内部由正定矩阵组成,因此严格广义不等式也等同于通常的对称矩阵的严格不等式,即 $X \prec_K Y$ 等价于 $Y - X$ 为正定矩阵。 > **举例**&emsp;**半正定锥和矩阵不等式**。半正定锥是 $\bfS^n$ 空间中的正常锥,相应的广义不等式 $\preceq_K$ 就是通常的矩阵不等式,即 $X \preceq_K Y$ 等价于 $Y - X$ 为半正定矩阵。(在 $\bfS^n$ 中)$\bfS^n_+$ 的内部由正定矩阵组成,因此严格广义不等式也等同于通常的对称矩阵的严格不等式,即 $X \prec_K Y$ 等价于 $Y - X$ 为正定矩阵。
> >
> 这里,也是由于经常使用这种偏序关系,因此省略其下标,即对于对称矩阵,我们将广义不 > 这里,也是由于经常使用这种偏序关系,因此省略其下标,即对于对称矩阵,我们将广义不等式简写为 $X \preceq Y$ 或 $X \prec Y$, 它们表示关于半正定锥的广义不等式。
等式简写为 $X \preceq Y$ 或 $X \prec Y$, 它们表示关于半正定锥的广义不等式。
> **举例**&emsp;**$[0, 1]$ 上非负的多项式锥**。$K$ 定义如下 > **举例**&emsp;**$[0, 1]$ 上非负的多项式锥**。$K$ 定义如下
> >
@@ -107,14 +106,13 @@ $$
# 2. 最小与极小元 # 2. 最小与极小元
&emsp;&emsp;广义不等式的符号($\preceq_K$,$\prec_K$)似乎表明它们与 $\bfR$ 上的普通不等式($\leqslant$,$<$)有着相同的性质。虽然普通不等式的许多性质对于广义不等式确实成立,但很多重要的性质并不如此。最明显的区别在于,$\bfR$ 上的 $\leqslant$ 是一个**线性序**(*linear ordering*),即任意两点都是**可比的**(*comparable*),也就是说 $x\leqslant y$ 和 $y \leqslant x$ 二者必居其一。这个性质对于其他广义不等式并不成立。这导致了最小、最大这些概念在广义不等式环境下变得更加复杂。本节将对此进行简要的 &emsp;&emsp;广义不等式的符号($\preceq_K$,$\prec_K$)似乎表明它们与 $\bfR$ 上的普通不等式($\leqslant$,$<$)有着相同的性质。虽然普通不等式的许多性质对于广义不等式确实成立,但很多重要的性质并不如此。最明显的区别在于,$\bfR$ 上的 $\leqslant$ 是一个**线性序**(*linear ordering*),即任意两点都是**可比的**(*comparable*),也就是说 $x\leqslant y$ 和 $y \leqslant x$ 二者必居其一。这个性质对于其他广义不等式并不成立。这导致了最小、最大这些概念在广义不等式环境下变得更加复杂。本节将对此进行简要的讨论。
讨论。
&emsp;&emsp;如果对于每个 $y \in S$,均有 $x \preceq_K y$,称 $x\in S$ 是 $S$(关于广义不等式 $\preceq_K$)的**最小元**(*minimum element*)。类似地,我们可以定义关于广义不等式的**最大元**(**maximum element**)。如果一个集合有最小(或最大)元,那么它们是唯一的。 &emsp;&emsp;如果对于每个 $y \in S$,均有 $x \preceq_K y$,称 $x\in S$ 是 $S$(关于广义不等式 $\preceq_K$)的**最小元**(*minimum element*)。类似地,我们可以定义关于广义不等式的**最大元**(**maximum element**)。如果一个集合有最小(或最大)元,那么它们是唯一的。
&emsp;&emsp;相对应的概念是**极小元**(*minimal element*)。如果 $y \in S$,$y \preceq_K x$ 可以推得 $y=x$,那么称 $x\in S$ 是 $S$ 上(关于广义不等式 $\preceq_K$)的**极小元**(*minimal element*)。同样地,可以定义**极大元**(*maximal element*)。一个集合可以有多个极小(或极大)元。 &emsp;&emsp;相对应的概念是**极小元**(*minimal element*)。如果 $y \in S$,$y \preceq_K x$ 可以推得 $y=x$,那么称 $x\in S$ 是 $S$ 上(关于广义不等式 $\preceq_K$)的**极小元**(*minimal element*)。同样地,可以定义**极大元**(*maximal element*)。一个集合可以有多个极小(或极大)元。
&emsp;&emsp;用简单的集合符号,我们可以对最小元和极小元进行描述。元素 $x\in S$ 是 $S$ 中的一个最小元,当且仅当 &emsp;&emsp;可以用简单的集合符号对最小元和极小元进行描述。元素 $x\in S$ 是 $S$ 中的一个最小元,当且仅当
$$ $$
S \subseteq x + K S \subseteq x + K
+36 -32
View File
@@ -32,7 +32,7 @@ $
\def\iint{\mathop{\bf int}} \def\iint{\mathop{\bf int}}
\def\bd{\mathop{\bf bd}} \def\bd{\mathop{\bf bd}}
\def\cl{\mathop{\bf cl}} \def\cl{\mathop{\bf cl}}
$&emsp;&emsp;本节将阐述一个在之后非常重要的想法:用超平面或仿射函数将两个不相交的凸集分离开来。其基本结果就是**超平面分离定理**(*separating hyperplane theorem*):假设 $C$ 和 $D$ 是两个不相交的凸集,即 $C \cap D = \emptyset$,那么存在 $a \ne 0$ 和 $b$ 使得对于所有 $x\in C$ 有 $a^\TT x \leqslant b$,对于所有 $x\in D$ 有 $a^\TT x \geqslant b$。换言之,仿射函数 $a^\TT x-b$ 在 $C$ 中非正,而在 $D$ 中非负。超平面 $\{ x\mid a^\TT x = b \}$ 称为集合 $C$ 和 $D$ 的分离超平面,或称超平面分离了集合 $C$ 和 $D$,如[图 19](#图19)。 $&emsp;&emsp;本节将阐述一个在之后非常重要的想法:用超平面或仿射函数将两个不相交的凸集分离开来。其基本结果就是**超平面分离定理**(*separating hyperplane theorem*):假设 $C$ 和 $D$ 是两个不相交的凸集,即 $C \cap D = \emptyset$,那么存在 $a \ne 0$ 和 $b$ 使得对于所有 $x\in C$ 有 $a^\TT x \leqslant b$,对于所有 $x\in D$ 有 $a^\TT x \geqslant b$。换言之,仿射函数 $a^\TT x-b$ 在 $C$ 中非正,而在 $D$ 中非负。超平面 $\{ x\mid a^\TT x = b \}$ 称为集合 $C$ 和 $D$ 的**分离超平面**(*separating hyperplane*),或称超平面**分离**(*separate*)了集合 $C$ 和 $D$,如[图 19](#图19)。
<a id="图19"></a> <a id="图19"></a>
@@ -48,7 +48,7 @@ $$
\dist(C,D) = \inf\{ \|u,v\|_2\mid u \in C,\ v \in D\} \dist(C,D) = \inf\{ \|u,v\|_2\mid u \in C,\ v \in D\}
$$ $$
并且存在 $c\in C$ 和 $d\in D$ 达到这个最小距离,即 $ \| c- d \|_2= \dist(C, D)$ 。(这些条件是可以被满足的,例如当 $C$ 和 $D$ 是闭的并且其中之一是有界的。) 并且存在 $c\in C$ 和 $d\in D$ 达到这个最小距离,即 $\|c-d\|_2=\dist(C,D)$。(这些条件是可以被满足的,例如当 $C$ 和 $D$ 是闭的并且其中之一是有界的。)
&emsp;&emsp;定义 &emsp;&emsp;定义
@@ -68,37 +68,39 @@ $$
![图 20. 两个凸集间分离超平面的构造。$c \in C$ 和 $d\in D$ 是两个集合中最靠近彼此的一个点对。分离超平面垂直并且等分 $c$ 和 $d$ 之间的线段。](../images/post/2024-06-12-josh-cvx-1-5/2024-06-12-josh-cvx-1-5-200-SeparateHyperplane.png){width=400px} ![图 20. 两个凸集间分离超平面的构造。$c \in C$ 和 $d\in D$ 是两个集合中最靠近彼此的一个点对。分离超平面垂直并且等分 $c$ 和 $d$ 之间的线段。](../images/post/2024-06-12-josh-cvx-1-5/2024-06-12-josh-cvx-1-5-200-SeparateHyperplane.png){width=400px}
&emsp;&emsp;首先证明 $f$ 在 $D$ 中非负。关于 $f$ 在 $C$ 中非正的证明是相似的(只需将 $C$ 和 $D$ 交换并考虑 $-f$ 即可)。假设存在一个点 $u\in D$,并且 &emsp;&emsp;首先证明 $f$ 在 $D$ 中非负。关于 $f$ 在 $C$ 中非正的证明是相似的(只需将 $C$ 和 $D$ 交换并考虑 $-f$ 即可)。
$$\begin{equation}\label{ufunction} > **证明**&emsp;假设存在一个点 $u\in D$,并且
f(u) = (d-c)^\TT (u - (1/2)(d+c)) < 0 >
\end{equation}$$ > $$\begin{equation}\label{ufunction}
> f(u) = (d-c)^\TT (u - (1/2)(d+c)) < 0
> \end{equation}$$
>
> 可以将 $f(u)$ 表示为
>
> $$
> f(u) = (d-c)^\TT (u - d + (1/2)(d-c)) = (d-c)^\TT(u-d) + (1/2) \| d-c \|_2^2
> $$
>
> 可以看出式 $\eqref{ufunction}$ 意味着 $(d-c)^\TT(u-d) < 0$。于是,观察到
>
> $$
> \left. \frac{\d}{\d t} \|d + t(u-d) - c\|_2^2 \right|_{t=0} = 2(d-c)^\TT(u-d) < 0
> $$
>
> 因此,对于足够小的 $t>0$ 及 $t\leqslant 1$,有
>
> $$
> \| d + t(u-d) - c \|_2 < \| d -c \|_2
> $$
>
> 即点 $d+t(u-d)$ 比 $d$ 更靠近 $c$。因为 $D$ 是包含 $d$ 和 $u$ 的凸集,我们有 $d+t(u-d) \in D$。但这是不可能的,因为根据假设,$d$ 应当是 $D$ 中离 $C$ 最近的点。
可以将 $f(u)$ 表示为 > **举例**&emsp;**仿射集与凸集的分离**。设 $C$ 是凸集,而 $D$ 是仿射的,即 $D = \{ Fu + g\mid u \in \bfR^m\}$,其中 $F \in \bfR^{n\times m}$。设 $C$ 和 $D$ 不相交,那么根据超平面分离定理,存在 $a \ne 0$ 和 $b$ 使得对于所有 $x \in C$ 有 $a^\TT x \leqslant b$,对于所有 $x \in D$ 有 $a^\TT x \geqslant b$。
$$
f(u) = (d-c)^\TT (u - d + (1/2)(d-c)) = (d-c)^\TT(u-d) + (1/2) \| d-c \|_2^2
$$
可以看出式 $\eqref{ufunction}$ 意味着 $(d-c)^\TT(u-d) < 0$。于是,观察到
$$
\left. \frac{\d}{\d t} \|d + t(u-d) - c\|_2^2 \right|_{t=0} = 2(d-c)^\TT(u-d) < 0
$$
因此,对于足够小的 $t>O$ 及 $t\leqslant 1$,有
$$
\| d + t(u-d) - c \|_2 < \| d -c \|_2
$$
即点 $d+t(u-d)$ 比 $d$ 更靠近 $c$。因为 $D$ 是包含 $d$ 和 $u$ 的凸集,我们有 $d+t(u-d) \in D$。但这是不可能的,因为根据假设,$d$ 应当是 $D$ 中离 $C$ 最近的点。
> **举例**&emsp;**仿射集与凸集的分离**。设 $C$ 是凸集,而 $D$ 是仿射的,即 $D = \{ Fu + g\mid u \in \bfR^m\}$,其中 $F \in \bfR^{n\times m}$。设 $C$ 和 $D$ 不相交,那么根据超平面分离定理,存在 $a \ne 0$ 和 $b$ 使得对于所有 $x \in C$ 有 $a^\TT x = b$,对于所有 $x \in D$ 有 $a^\TT x \geqslant b$。
> >
> 这里 $a^\TT x \geqslant b$ 对于所有 $x \in D$ 均成立,表明对于任意 $u \in \bfR^m$ 均有 $a^\TT Fu \geqslant b - a^\TT g$。但是在 $\bfR^m$ 上,只有当一个线性函数为零时,它才是有界的。因此,可以推知 $a^\TT F=0$ (并且因此有 $b \leqslant a^\TT g$)。 > 这里 $a^\TT x \geqslant b$ 对于所有 $x \in D$ 均成立,表明对于任意 $u \in \bfR^m$ 均有 $a^\TT Fu \geqslant b - a^\TT g$。但是在 $\bfR^m$ 上,只有当一个线性函数为零时,它才是有界的。因此,可以推知 $a^\TT F=0$ (并且因此有 $b \leqslant a^\TT g$)。
> >
> 所以,我们可知存在 $a \ne 0$ 使得 $F^\TT a =0$ 和 $a^\TT x \leqslant a^\TT g$ 对于所有 $x\in C$ 均成立。 > 所以可知,存在 $a \ne 0$ 使得 $F^\TT a =0$ 和 $a^\TT x \leqslant a^\TT g$ 对于所有 $x\in C$ 均成立。
## 1.2 严格分离 ## 1.2 严格分离
@@ -106,7 +108,7 @@ $$
> **举例**&emsp;**点和闭凸集的严格分离**。令 $C$ 为闭凸集,而 $x_0 \notin C$,那么存在将 $x_0$ 与 $C$ 严格分离的超平面。 > **举例**&emsp;**点和闭凸集的严格分离**。令 $C$ 为闭凸集,而 $x_0 \notin C$,那么存在将 $x_0$ 与 $C$ 严格分离的超平面。
> >
> 为说明这一点,需要注意,对于足够小的 $c > 0$,存在两个不相交的集合 $C$ 和 $B(x_0, \epsilon)$。根据超平面分离定理,存在 $a \ne 0$ 和 $b$,使得对于任意 $x\in C$ 有 $a^\TT x \leqslant b$;对于任意 $x \in B(x_0, \epsilon)$ 有 $a^\TT x \geqslant b$。 > 为说明这一点,需要注意,对于足够小的 $\epsilon > 0$,存在两个不相交的集合 $C$ 和 $B(x_0, \epsilon)$。根据超平面分离定理,存在 $a \ne 0$ 和 $b$,使得对于任意 $x\in C$ 有 $a^\TT x \leqslant b$;对于任意 $x \in B(x_0, \epsilon)$ 有 $a^\TT x \geqslant b$。
> >
> 利用 $B(x_0, \epsilon) = \{ x_0 + u\mid \|u\|_2 \leqslant \epsilon \}$,可以将前述第二个条件表示为 > 利用 $B(x_0, \epsilon) = \{ x_0 + u\mid \|u\|_2 \leqslant \epsilon \}$,可以将前述第二个条件表示为
> >
@@ -128,7 +130,7 @@ $$
> >
> 在 $C$ 上是负的,而在 $x_0$ 点是正的。 > 在 $C$ 上是负的,而在 $x_0$ 点是正的。
> >
> 作为一个直接的结果,我们可以得到前面已提及的事实:一个闭凸集是包含它的所有半空间的交集。事实上,令 $C$ 为闭和凸的,$S$ 为所有包含 $C$ 的半空间。显然,$x\in C \Rightarrow x \in S$。为证明反方向,假设存在 $x\in S$ 并且 $x \notin C$。根据严格分离的结果,存在一个将 $x$ 与 $C$ 严格分离的超平面,即存在一个包含 $C$ 但不包含 $x$ 的半空间。也就是说,$x \notin S$。 > 由此可以得到前面已提及的事实:一个闭凸集是包含它的所有半空间的交集。事实上,令 $C$ 为闭和凸的,$S$ 为所有包含 $C$ 的半空间。显然,$x\in C \Rightarrow x \in S$。为证明反方向,假设存在 $x\in S$ 并且 $x \notin C$。根据严格分离的结果,存在一个将 $x$ 与 $C$ 严格分离的超平面,即存在一个包含 $C$ 但不包含 $x$ 的半空间。也就是说,$x \notin S$。
## 1.3 超平面分离定理的逆定理 ## 1.3 超平面分离定理的逆定理
@@ -136,7 +138,9 @@ $$
> **反例**&emsp;考虑 $C = D = \{0\} \subseteq \bfR$,超平面 $x=0$ 可以分离 $C$ 和 $D$。 > **反例**&emsp;考虑 $C = D = \{0\} \subseteq \bfR$,超平面 $x=0$ 可以分离 $C$ 和 $D$。
&emsp;&emsp;通过给 $C$ 和 $D$ 增加一些条件,可以得到超平面分离定理的多种逆定理。作为一个简单的例子,设 $C$ 和 $D$ 是凸集,$C$ 是开集,如果存在一个仿射函数 $f$,它在 $C$ 中非正而在 $D$ 中非负,那么 $C$ 和 $D$ 不相交。(为说明此结论,首先可知 $f$ 在 $C$ 上是负的。否则,如果 $f$ 在 $C$ 中的某一点为零,那么 $f$ 在这个点附近会取得正值,这与前述矛盾。因此 $C$ 和 $D$ 一定是不相交的,因为 $f$ 在 $C$ 中为负,而在 $D$ 中非负。)将逆定理与超平面分离定理相结合,我们可以得到下面的结论:任何两个凸集 $C$ 和 $D$,如果其中至少有一个是开集,那么当且仅当存在分离超平面时,它们不相交。 &emsp;&emsp;通过给 $C$ 和 $D$ 增加一些条件,可以得到超平面分离定理的多种逆定理。
> **举例**&emsp;设 $C$ 和 $D$ 是凸集,$C$ 是开集,如果存在一个仿射函数 $f$,它在 $C$ 中非正而在 $D$ 中非负,那么 $C$ 和 $D$ 不相交。(为说明此结论,首先可知 $f$ 在 $C$ 上是负的。否则,如果 $f$ 在 $C$ 中的某一点为零,那么 $f$ 在这个点附近会取得正值,这与前述矛盾。因此 $C$ 和 $D$ 一定是不相交的,因为 $f$ 在 $C$ 中为负,而在 $D$ 中非负。)将逆定理与超平面分离定理相结合,我们可以得到下面的结论:任何两个凸集 $C$ 和 $D$,如果其中至少有一个是开集,那么当且仅当存在分离超平面时,它们不相交。
> **举例**&emsp;**严格线性不等式的择一定理**。我们导出严格线性不等式 > **举例**&emsp;**严格线性不等式的择一定理**。我们导出严格线性不等式
> >
@@ -170,7 +174,7 @@ $$
x_0 \in \bd C = \cl C\ \backslash\ \iint C x_0 \in \bd C = \cl C\ \backslash\ \iint C
$$ $$
如果 $a \ne 0$,并且对任意 $x \ in C$ 满足 $a^\TT x \leqslant a^\TT x_0$,那么称超平面 $\{ x\mid a^\TT x = a^\TT x_0 \}$ 为集合 $C$ 在点 $x_0$ 处的**支撑超平面**(*supporting hyperplane*)。这等于说点 $x_0$ 与集合 $C$ 被超平面 $\{ x\mid a^\TT x = a^\TT x_0 \}$ 所分离。其几何解释是超平面 $\{ x\mid a^\TT x = a^\TT x_0 \}$ 与 $C$ 相切于点 $x_0$,而且半空间 $\{ x\mid a^\TT x \leqslant a^\TT x_0 \} 包含 $C$,如[图 21](#图21)。 如果 $a \ne 0$,并且对任意 $x \in C$ 满足 $a^\TT x \leqslant a^\TT x_0$,那么称超平面 $\{ x\mid a^\TT x = a^\TT x_0 \}$ 为集合 $C$ 在点 $x_0$ 处的**支撑超平面**(*supporting hyperplane*)。这等于说点 $x_0$ 与集合 $C$ 被超平面 $\{ x\mid a^\TT x = a^\TT x_0 \}$ 所分离。其几何解释是超平面 $\{ x\mid a^\TT x = a^\TT x_0 \}$ 与 $C$ 相切于点 $x_0$,而且半空间 $\{ x\mid a^\TT x \leqslant a^\TT x_0 \}$ 包含 $C$,如[图 21](#图21)。
<a id="图21"></a> <a id="图21"></a>
+42 -42
View File
@@ -48,37 +48,37 @@ $$\begin{equation}
<!-- more --> <!-- more -->
> **举例**&emsp;**非负象限**锥 $\bfR^n_+$ 的对偶是它本身: > **举例**&emsp;**非负象限**。锥 $\bfR^n_+$ 的对偶是它本身:
> >
> $$ > $$
> y^\TT x \geqslant 0,\ \forall x \succeq 0 \Longleftrightarrow y \succeq 0 > y^\TT x \geqslant 0,\ \forall x \succeq 0 \Longleftrightarrow y \succeq 0
> $$ > $$
> >
> 我们称这种锥**自对偶**(*self-dual*)。 > 称这种锥**自对偶**(*self-dual*)。
> **举例**&emsp;**半正定锥**。在 $n \times n$ 对称矩阵的集合 $\bfS^n$ 上,我们使用其标准内积 $\tr(XY) = \displaystyle\sum_{i,j=1}^{n} X_{ij}Y_{ij}$。半正定锥 $\bfS^n_+$ 是自对偶的,即对于任意的 $X,Y\in\bfS^n$ > **举例**&emsp;**半正定锥**。在 $n \times n$ 对称矩阵的集合 $\bfS^n$ 上,其标准内积 $\tr(XY) = \displaystyle\sum_{i,j=1}^{n} X_{ij}Y_{ij}$。半正定锥 $\bfS^n_+$ 是自对偶的,即对于任意的 $X,Y\in\bfS^n$
> >
> $$ > $$
> \tr (XY) \geqslant 0,\ \forall X \succeq 0 \Longleftrightarrow Y \succeq 0 > \tr (XY) \geqslant 0,\ \forall X \succeq 0 \Longleftrightarrow Y \succeq 0
> $$ > $$
> >
> 下面,我们将说明这一结论。 > 下面说明这一结论。
> >
> 假设 $Y \notin \bfS^n_+$,那么存在 $q \in \bfR^n$ 并且 > > **证明**&emsp;假设 $Y \notin \bfS^n_+$,那么存在 $q \in \bfR^n$ 并且
> > >
> $$ > > $$
> q^\TT Yq = \tr (qq^\TT Y) < 0 > > q^\TT Yq = \tr (qq^\TT Y) < 0
> $$ > > $$
> > >
> 于是半正定矩阵 $X = qq^\TT$ 满足 $\tr(XY) < 0$,由此可知 $Y \notin (\bfS^n_+)^\ast$。 > > 于是半正定矩阵 $X = qq^\TT$ 满足 $\tr(XY) < 0$,由此可知 $Y \notin (\bfS^n_+)^\ast$。
> > >
> 假设 $X,T\in\bfS^n_+$,我们可以利用特征值分解将 $X$ 表述为 $X = \displaystyle\sum_{i=1}^n \lambda_i q_i q_i^\TT$,其中(特征 $\lambda_i \geqslant 0,\ i = 1,\cdots,n$。于是,我们有 > > 假设 $X,Y\in\bfS^n_+$,可以利用特征值分解将 $X$ 表述为 $X = \displaystyle\sum_{i=1}^n \lambda_i q_i q_i^\TT$,其中(特征值)$\lambda_i \geqslant 0,\ i = 1,\cdots,n$。于是有
> > >
> $$ > > $$
> \tr (XY) = \tr \left( Y \sum_{i=1}^n \lambda_i q_i q_i^\TT \right) = \sum_{i=1}^n \lambda_i q^\TT Y q_i \geqslant 0 > > \tr (XY) = \tr \left( Y \sum_{i=1}^n \lambda_i q_i q_i^\TT \right) = \sum_{i=1}^n \lambda_i q^\TT Y q_i \geqslant 0
> $$ > > $$
> > >
> 以上表明 $Y \in (\bfS^n_+)^\ast$。 > > 以上表明 $Y \in (\bfS^n_+)^\ast$。
> **举例**&emsp;**范数锥的对偶**。令 $\|\cdot\|$ 为定义在 $\bfR^n$ 上的范数。与之相关的锥 $K = \{ (x,t) \in \bfR^{n+1}\mid \|x\|\leqslant t \}$ 的对偶锥由其对偶范数定义, > **举例**&emsp;**范数锥的对偶**。令 $\|\cdot\|$ 为定义在 $\bfR^n$ 上的范数。与之相关的锥 $K = \{ (x,t) \in \bfR^{n+1}\mid \|x\|\leqslant t \}$ 的对偶锥由其对偶范数定义,
> >
@@ -94,21 +94,21 @@ $$\begin{equation}
> x^\TT u + tv \geqslant 0\ 只要\ \|x\|\leqslant t \Longleftrightarrow \|u\|_\ast \leqslant v > x^\TT u + tv \geqslant 0\ 只要\ \|x\|\leqslant t \Longleftrightarrow \|u\|_\ast \leqslant v
> \end{equation}$$ > \end{equation}$$
> >
> 首先,证明由右端关于 $(u,v)$ 的条件可以得出左端的条件。设 $\|u\|_\ast \leqslant v$,并且对于一些 $t>0$ 有 $\|x\| \leqslant t$。(如果 $t = 0$,$x$ 必须是零,因此显然有 $u^\TT x + vt \geqslant 0$。)根据对偶锥的定义以及 $\|-x/t\|\leqslant 1$,我们有 > > **证明**&emsp;首先,证明由右端关于 $(u,v)$ 的条件可以得出左端的条件。设 $\|u\|_\ast \leqslant v$,并且对于一些 $t>0$ 有 $\|x\| \leqslant t$。(如果 $t = 0$,$x$ 必须是零,因此显然有 $u^\TT x + vt \geqslant 0$。)根据对偶锥的定义以及 $\|-x/t\|\leqslant 1$,我们有
> > >
> $$ > > $$
> u^\TT (-x/t) \leqslant \|u\|_\ast \leqslant v > > u^\TT (-x/t) \leqslant \|u\|_\ast \leqslant v
> $$ > > $$
> > >
> 因此,$u^\TT x + vt \geqslant 0$。 > > 因此,$u^\TT x + vt \geqslant 0$。
> > >
> 其次,我们证明 $\eqref{DualOfNormCone}$ 左端的条件可以导出 $\eqref{DualOfNormCone}$ 右端的条件。假设 $\|u\|_\ast> v$,即右端不成立。那么,根据对偶锥的定义,存在 $x$ 满足 $\|x\|\leqslant 1$ 及 $x^\TT u > v$。取 $t=1$,我们有 > > 其次,我们证明 $\eqref{DualOfNormCone}$ 左端的条件可以导出 $\eqref{DualOfNormCone}$ 右端的条件。假设 $\|u\|_\ast> v$,即右端不成立。那么,根据对偶锥的定义,存在 $x$ 满足 $\|x\|\leqslant 1$ 及 $x^\TT u > v$。取 $t=1$,我们有
> > >
> $$ > > $$
> u^\TT (-x) + v < 0 > > u^\TT (-x) + v < 0
> $$ > > $$
> > >
> 这与 $\eqref{DualOfNormCone}$ 的左端相矛盾。 > > 这与 $\eqref{DualOfNormCone}$ 的左端相矛盾。
&emsp;&emsp;对偶锥满足一些性质,例如 &emsp;&emsp;对偶锥满足一些性质,例如
@@ -127,7 +127,7 @@ $$\begin{equation}
- $x \preceq_K y$ 当且仅当对于任意 $\lambda \succeq_{K^\ast}$,有 $\lambda^\TT x \leqslant \lambda^\TT y$。 - $x \preceq_K y$ 当且仅当对于任意 $\lambda \succeq_{K^\ast}$,有 $\lambda^\TT x \leqslant \lambda^\TT y$。
- $x \prec_K y$ 当且仅当对于任意 $\lambda \succeq_{K^\ast}$ 和 $\lambda\ne 0$,有 $\lambda^\TT T x < \lambda^\TT y$。 - $x \prec_K y$ 当且仅当对于任意 $\lambda \succeq_{K^\ast}$ 和 $\lambda\ne 0$,有 $\lambda^\TT T x < \lambda^\TT y$。
因为 $K = K^{\ast\ast}$,与 $\preceq_{K^\ast}$ 相关的对偶广义不等式为 $\preceq_{K}$,因此交换广义不等式及其对偶后,这些性质依然成立。作为一个具体的例子,我们可知 $\lambda\preceq_{K^\ast} \mu$ 的充要条件是对于所有 $x \succeq_K 0$ 有 $\lambda^\TT x \leqslant \mu^\TT x$。 &emsp;&emsp;因为 $K = K^{\ast\ast}$,与 $\preceq_{K^\ast}$ 相关的对偶广义不等式为 $\preceq_{K}$,因此交换广义不等式及其对偶后,这些性质依然成立。作为一个具体的例子,我们可知 $\lambda\preceq_{K^\ast} \mu$ 的充要条件是对于所有 $x \succeq_K 0$ 有 $\lambda^\TT x \leqslant \mu^\TT x$。
> **举例**&emsp;**线性严格广义不等式的择一定理**。设 $K \subseteq \bfR^m$ 为正常锥。考虑严格广义不等式 > **举例**&emsp;**线性严格广义不等式的择一定理**。设 $K \subseteq \bfR^m$ 为正常锥。考虑严格广义不等式
> >
@@ -137,7 +137,7 @@ $$\begin{equation}
> >
> 其中 $x \in \bfR^n$ > 其中 $x \in \bfR^n$
> >
> 我们将导出对于这个不等式的择一定理。假设它是不可行的,即仿射集合 $\{b-Ax\mid x\in\bfR^n\}$ 与开凸集 $\iint K$ 不相交。那么存在一个分离超平面,即非零的 $\lambda\in\bfR^m$ 和 $\mu\in \bfR$ 使得对于任意 $x$ 有灯 $\lambda^\TT(b-Ax) \leqslant \mu$,对于任意 $y \in \iint K$ 有 $\lambda^\TT y \geqslant \mu$。第一个条件表明 $A^\TT \lambda = 0$ 及 $\lambda^\TT b \leqslant \mu$。第二个条件表明对于任意 $y\in K$ 有 $\lambda^\TT y \geqslant \mu$,这种情况仅当 $\lambda \in K^\ast$ 和 $\mu \leqslant 0$ 时才可能发生。 > 下面推导对于这个不等式的择一定理。假设它是不可行的,即仿射集合 $\{b-Ax\mid x\in\bfR^n\}$ 与开凸集 $\iint K$ 不相交。那么存在一个分离超平面,即非零的 $\lambda\in\bfR^m$ 和 $\mu\in \bfR$ 使得对于任意 $x$ 有灯 $\lambda^\TT(b-Ax) \leqslant \mu$,对于任意 $y \in \iint K$ 有 $\lambda^\TT y \geqslant \mu$。第一个条件表明 $A^\TT \lambda = 0$ 及 $\lambda^\TT b \leqslant \mu$。第二个条件表明对于任意 $y\in K$ 有 $\lambda^\TT y \geqslant \mu$,这种情况仅当 $\lambda \in K^\ast$ 和 $\mu \leqslant 0$ 时才可能发生。
> >
> 综上,我们可知当 $\eqref{StrictGeneralInequality}$ 不可行时,存在 $\lambda$ 使得 > 综上,我们可知当 $\eqref{StrictGeneralInequality}$ 不可行时,存在 $\lambda$ 使得
> >
@@ -155,29 +155,29 @@ $$\begin{equation}
## 3.1 最小元的对偶性质 ## 3.1 最小元的对偶性质
&emsp;&emsp;我们首先考虑**最小**(*minimum*)元的性质。$x$ 是 $S$ 上关于广义不等式 $\preceq _K$ 的最小元的充要条件是,对于所有 $\lambda\succ_{K^*}0$,$x$ 是在 $z\in S$ 上极小化 $\lambda^\TT z$ 的唯一最优解。几何上看,这意味着对于任意 $\lambda\succ_{K^*}0$,超平面 &emsp;&emsp;首先考虑**最小**(*minimum*)元的性质。$x$ 是 $S$ 上关于广义不等式 $\preceq _K$ 的最小元的充要条件是,对于所有 $\lambda\succ_{K^*}0$,$x$ 是在 $z\in S$ 上极小化 $\lambda^\TT z$ 的唯一最优解。几何上看,这意味着对于任意 $\lambda\succ_{K^*}0$,超平面
$$ $$
\{z\mid \lambda^\TT (z-x)=0\} \{z\mid \lambda^\TT (z-x)=0\}
$$ $$
是在 $x$ 处对 $S$ 的一个严格支撑超平面。(我们用严格支撑超平面表明这个超平面与 $S$ 只相交于 $x$。)注意此处并不要求 $S$ 是凸集。这可由[图 23](#图23)来表示。 是在 $x$ 处对 $S$ 的一个严格支撑超平面。(用严格支撑超平面表明这个超平面与 $S$ 只相交于 $x$。)注意此处并不要求 $S$ 是凸集。这可由[图 23](#图23)来表示。
<a id="图23"></a> <a id="图23"></a>
![图 23. 最小元的对偶性质。点 $x$ 是集合 $S$ 中关于 $\mathbf{R}_+^2$ 的极小元。这等价于:对于任意 $\lambda\succ0$,超平面 $\{z\mid\lambda^\TT (z-x)=0\}$ 在 $x$ 处对 $S$ 严格支撑,即在超平面的一边包含了 $S$,并只在 $x$ 处与 $S$ 接触。](../images/post/2024-06-13-josh-cvx-1-6/2024-06-13-josh-cvx-1-6-230-DualCharacterizationOfMinimumElement.png){width=400px} ![图 23. 最小元的对偶性质。点 $x$ 是集合 $S$ 中关于 $\mathbf{R}_+^2$ 的极小元。这等价于:对于任意 $\lambda\succ0$,超平面 $\{z\mid\lambda^\TT (z-x)=0\}$ 在 $x$ 处对 $S$ 严格支撑,即在超平面的一边包含了 $S$,并只在 $x$ 处与 $S$ 接触。](../images/post/2024-06-13-josh-cvx-1-6/2024-06-13-josh-cvx-1-6-230-DualCharacterizationOfMinimumElement.png){width=400px}
&emsp;&emsp;为说明这个结论,设 $x$ 是 $S$ 的最小元,即对于任意 $z\in S$ 有 $x\preceq_Kz$,同时,令 $\lambda\succ_{K^*} 0$,而$z\in S, z\neq x$。因为 $x$ 是 $S$ 上的最小元,我们有 $z-x\succeq_K0 $。根据 $\lambda\succ_{K^*}0$ 及 $z-x\succeq_K0,z-x\neq0$,可以得到 $\lambda^\TT (z-x)>0$。因为 $z$ 是 $S$ 上任意一个不等于 $x$ 的元素,所以 $x$ 是在 $z\in S$ 上极小化 $\lambda^\TT z$ 的唯一解。反之,假设对于所有 $\lambda\succ_{K^*}0$,$x$ 是 $z\in S$ 上极小化 $\lambda^\TT z$ 的唯一解,但 $x$ 不是 $S$ 的最小元。那么存在 $z\in S$ 满足 $z\nsucceq_Kx$。因为 $z-x\nsucceq_K0$,存在 $\tilde{\lambda}\succeq_{K^*} 0$ 并且 $\tilde{\lambda}^\TT(z-x)<0$。因此,对于 $\lambda\succ_{K^*} 0$,在 $\tilde{\lambda}$ 的邻域内有 $\lambda^\TT (z-x)<0$。这与 $x$ 是 $S$ 上极小化 $\lambda^\TT z$ 的唯一解相矛盾。 &emsp;&emsp;为说明这个结论,设 $x$ 是 $S$ 的最小元,即对于任意 $z\in S$ 有 $x\preceq_Kz$,同时,令 $\lambda\succ_{K^*} 0$,而$z\in S$,$z\neq x$。因为 $x$ 是 $S$ 上的最小元,所以有 $z-x\succeq_K0$。根据 $\lambda\succ_{K^*}0$ 及 $z-x\succeq_K0$,$z-x\neq0$,可以得到 $\lambda^\TT (z-x)>0$。因为 $z$ 是 $S$ 上任意一个不等于 $x$ 的元素,所以 $x$ 是在 $z\in S$ 上极小化 $\lambda^\TT z$ 的唯一解。反之,假设对于所有 $\lambda\succ_{K^*}0$,$x$ 是 $z\in S$ 上极小化 $\lambda^\TT z$ 的唯一解,但 $x$ 不是 $S$ 的最小元。那么存在 $z\in S$ 满足 $z\nsucceq_Kx$。因为 $z-x\nsucceq_K0$,存在 $\tilde{\lambda}\succeq_{K^*} 0$ 并且 $\tilde{\lambda}^\TT(z-x)<0$。因此,对于 $\lambda\succ_{K^*} 0$,在 $\tilde{\lambda}$ 的邻域内有 $\lambda^\TT (z-x)<0$。这与 $x$ 是 $S$ 上极小化 $\lambda^\TT z$ 的唯一解相矛盾。
## 3.2 极小元的对偶性质 ## 3.2 极小元的对偶性质
&emsp;&emsp;现在我们转而讨论**极小**(*minimal*)元的类似性质。此时,在必要和充分条件间存在一定的间隙。如果 $\lambda\succ_{K^*} 0$ 并且 $x$ 在 $z\in S$ 上极小化 $\lambda^\TT z$,那么 $x$ 是极小的,如[图 24](#图24)所示。 &emsp;&emsp;现在讨论**极小**(*minimal*)元的类似性质。此时,在必要和充分条件间存在一定的间隙。如果 $\lambda\succ_{K^*} 0$ 并且 $x$ 在 $z\in S$ 上极小化 $\lambda^\TT z$,那么 $x$ 是极小的,如[图 24](#图24)所示。
<a id="图24"></a> <a id="图24"></a>
![图 24. 集合 $S\subseteq\mathbf{R}^2$。其关于 $\mathbf{R}_+^2$ 的极小点集合由其边界的(左下)深色部分所示。$S$ 上极小化 $\lambda_1^\TT z$ 的解为 $x_1$,因为 $\lambda_1\succ0$,所以 $x_1$ 是极小的。$S$ 上极小化 $\lambda_2^\TT z$ 的解为 $x_2$,因为 $\lambda_2\succ0$,所以它是 $S$ 的另一个极小点。](../images/post/2024-06-13-josh-cvx-1-6/2024-06-13-josh-cvx-1-6-240-ASetAndItsSetOfMinimalPoints.png){width=400px} ![图 24. 集合 $S\subseteq\mathbf{R}^2$。其关于 $\mathbf{R}_+^2$ 的极小点集合由其边界的(左下)深色部分所示。$S$ 上极小化 $\lambda_1^\TT z$ 的解为 $x_1$,因为 $\lambda_1\succ0$,所以 $x_1$ 是极小的。$S$ 上极小化 $\lambda_2^\TT z$ 的解为 $x_2$,因为 $\lambda_2\succ0$,所以它是 $S$ 的另一个极小点。](../images/post/2024-06-13-josh-cvx-1-6/2024-06-13-josh-cvx-1-6-240-ASetAndItsSetOfMinimalPoints.png){width=400px}
&emsp;&emsp;为说明这点,假设 $\lambda\succ_{K^*} 0$ 并且 $x$ 在 $S$ 上极小化 $\lambda^\TT z$,但 $x$ 不是极小元,即存在 $z\in S$ 满足 $z\neq x,z\preceq_Kx$。那么 $\lambda^\TT (x-z)>0$,这与我们的假设,即 $x$ 在 $S$ 上极小化了 $\lambda^\TT z$,相矛盾。 > **证明**&emsp;假设 $\lambda\succ_{K^*} 0$ 并且 $x$ 在 $S$ 上极小化 $\lambda^\TT z$,但 $x$ 不是极小元,即存在 $z\in S$ 满足 $z\neq x$,$z\preceq_Kx$。那么 $\lambda^\TT (x-z)>0$,这与我们的假设,即 $x$ 在 $S$ 上极小化了 $\lambda^\TT z$,相矛盾。
&emsp;&emsp;其逆命题在一般情况下不成立:$S$ 上的极小元 $x$ 可以对于任何 $\lambda$ 都不是 $z\in S$ 上极小化 $\lambda^\TT z$ 的解,如[图 25](#图25)所示。此图表明了凸性在这个逆定理中的重要作用,当凸性成立时,逆定理是成立的。假设集合 $S$ 是凸集,可以说对于任意极小元 $x$,存在非零的 $\lambda\succeq_{K^*} 0$ 使得 $x$ 在 $z\in S$ 上极小化 $\lambda^\TT z$。 &emsp;&emsp;其逆命题在一般情况下不成立:$S$ 上的极小元 $x$ 可以对于任何 $\lambda$ 都不是 $z\in S$ 上极小化 $\lambda^\TT z$ 的解,如[图 25](#图25)所示。此图表明了凸性在这个逆定理中的重要作用,当凸性成立时,逆定理是成立的。假设集合 $S$ 是凸集,可以说对于任意极小元 $x$,存在非零的 $\lambda\succeq_{K^*} 0$ 使得 $x$ 在 $z\in S$ 上极小化 $\lambda^\TT z$。
@@ -185,7 +185,7 @@ $$
![图 25. 点 $x$ 是 $S\subseteq\mathbf{R}^2$ 关于 $\mathbf{R}_+^2$ 的极小元。但是,不存在 $\lambda$,使得 $x$ 在 $z\in S$ 上极小化 $\lambda^\TT z$](../images/post/2024-06-13-josh-cvx-1-6/2024-06-13-josh-cvx-1-6-250-MinimalElement.png){width=350px} ![图 25. 点 $x$ 是 $S\subseteq\mathbf{R}^2$ 关于 $\mathbf{R}_+^2$ 的极小元。但是,不存在 $\lambda$,使得 $x$ 在 $z\in S$ 上极小化 $\lambda^\TT z$](../images/post/2024-06-13-josh-cvx-1-6/2024-06-13-josh-cvx-1-6-250-MinimalElement.png){width=350px}
&emsp;&emsp;为证明这一点,假设 $x$ 是极小的,也就是说 $((x-K)\setminus\{x\})\cap S=\emptyset$。对凸集 $(x-K)\setminus\{x\}$ 和 $S$ 应用超平面分离定理,我们可以得出:存在 $\lambda\neq0$和$\mu$,使得对于所有 $y\in K$ 有 $\lambda^\TT (x-y)\leqslant\mu$,对于所有 $z\in S$ 有 $\lambda^\TT z\geqslant\mu$。根据第一个不等式,我们可知 $\lambda\succeq_{K^*} 0$。由于 $x\in S$ 和 $x\in x-K$,我们有 $\lambda^\TT x=\mu$,所以第二个不等式表明 $\mu$ 是 $S$ 上 $\lambda^\TT z$ 的最小值。因此,$x$ 是 $S$ 上极小化 $\lambda^\TT z$ 的一个解,这里 $\lambda\neq0,\lambda\succeq_{K^*}0$。 > **证明**&emsp;假设 $x$ 是极小的,也就是说 $((x-K)\setminus\{x\})\cap S=\emptyset$。对凸集 $(x-K)\setminus\{x\}$ 和 $S$ 应用超平面分离定理,可以得出:存在 $\lambda\neq0$ 和 $\mu$,使得对于所有 $y\in K$ 有 $\lambda^\TT (x-y)\leqslant\mu$,对于所有 $z\in S$ 有 $\lambda^\TT z\geqslant\mu$。根据第一个不等式,可知 $\lambda\succeq_{K^*} 0$。由于 $x\in S$ 和 $x\in x-K$,所以有 $\lambda^\TT x=\mu$,所以第二个不等式表明 $\mu$ 是 $S$ 上 $\lambda^\TT z$ 的最小值。因此,$x$ 是 $S$ 上极小化 $\lambda^\TT z$ 的一个解,这里 $\lambda\neq0$,$\lambda\succeq_{K^*}0$。
&emsp;&emsp;这个逆定理无法加强为 $\lambda\succ_{K^*} 0$。反例表明,凸集 $S$ 上的极小元 $x$,可以对于任意 $\lambda\succ_{K^*}0$,都不是 $z\in S$ 中极小化 $\lambda ^\TT z$ 的解(参见[图 26,左图](#图26))。同时,并不是对于任意 $\lambda\succeq_{K^*} 0$,在 $z\in S$ 上极小化 $\lambda^\TT z$ 的解都一定是极小的(参见[图 26,左图](#右26))。 &emsp;&emsp;这个逆定理无法加强为 $\lambda\succ_{K^*} 0$。反例表明,凸集 $S$ 上的极小元 $x$,可以对于任意 $\lambda\succ_{K^*}0$,都不是 $z\in S$ 中极小化 $\lambda ^\TT z$ 的解(参见[图 26,左图](#图26))。同时,并不是对于任意 $\lambda\succeq_{K^*} 0$,在 $z\in S$ 上极小化 $\lambda^\TT z$ 的解都一定是极小的(参见[图 26,左图](#右26))。
+569
View File
@@ -0,0 +1,569 @@
---
title: Josh's Note — 凸优化<br>Part 2.1 凸函数—基本性质和例子
mathjax: true
comments: true
copyright: true
toc:
enable: true
number: false
wrap: true
expand_all: true
max_depth: 4
categories:
- - Josh 的学习笔记
- 凸优化
- 凸函数
- - 数学
- 凸优化
tags:
- 凸优化
- 凸函数
abbrlink: 320f661c
date: 2024-06-14 20:29:26
---
# 1. 定义
$
\newcommand{\TT}{\mathrm{T}}
\newcommand{\dd}{\mathrm{d}}
\def\dom{\mathop{\bf dom}}
\def\diag{\mathop{\bf diag}}
\def\epi{\mathop{\bf epi}}
\def\hypo{\mathop{\bf hypo}}
\def\prob{\mathop{\bf prob}}
$&emsp;&emsp;函数 $f:\mathbf{R}^n\to\mathbf{R}$ 是**凸**(*Convex*)的,若 $\dom f$ 是凸集,且对于任意 $x,y\in\dom f$ 和任意 $0\leqslant\theta\leqslant1$,有
$$\begin{equation}\label{DefinitionOfConvexFunction}
f(\theta x+(1-\theta)y)\leqslant\theta f(x)+(1-\theta)f(y)
\end{equation}$$
&emsp;&emsp;从几何意义上看,上述不等式意味着点 $(x,f(x))$ 和 $(y,f(y))$ 之间的线段,即从 $x$ 到 $y$ 的**弦**(*chord*),在函数 $f$ 的图像上方(如[图 1](#图1)所示)。称函数 $f$ 是**严格凸**(*strictly convex*)的,若式 $\eqref{DefinitionOfConvexFunction}$ 中的不等式当 $x\neq y$ 以及 $0<\theta<1$ 时严格成立。称函数 $f$ 是**凹**(*concave*)的,若函数 $-f$ 是凸的;称函数 $f$ 是**严格凹**(*strictly concave*)的,若 $-f$ 严格凸。
<a id="图1"></a>
![图 1. 凸函数示意图。图上任意两点之间的弦(即线段)都在函数图像之上。](../images/post/2024-06-14-josh-cvx-2-1/2024-06-14-josh-cvx-2-1-010-ConvexFunction.png){width=400px}
<!-- more -->
&emsp;&emsp;对于仿射函数,式 $\eqref{DefinitionOfConvexFunction}$ 始终可以取等号,因此所有的[仿射函数][](包括线性函数)是既凸且凹的。反之,若某个函数是既凸又凹的,则其是仿射函数。
&emsp;&emsp;函数是凸的,当且仅当其在与其定义域相交的任何直线上都是凸的。换言之,函数 $f$ 是凸的,当且仅当对于任意 $x\in\dom f$ 和任意向量 $v$,函数 $g(t)=f(x+tv)$ 是凸的(其定义域为 $\{t\mid x+tv\in\dom f\}$)。这个性质非常有用,因为它让我们可以通过将函数限制在直线上来判断其是否是凸函数。
{% note info 注解 %}
这里可能是由于翻译问题导致不是很好理解,我们先看原文:
> A function is convex if and only if it is convex when restricted to any line that
intersects its domain. In other words $f$ is convex if and only if for all $x\in\mathbf{dom}\, f$ and all $v$, the function $g(t) = f(x + tv)$ is convex (on its domain, $\{t\mid x+tv\in\mathbf{dom}\, f\}$). This property is very useful, since it allows us to check whether a function is convex by restricting it to a line.
仍然不是很好理解。因此询问 ChatGPT 得到如下解释:
- 限制在直线上:考虑一个函数 $f$ 和其定义域内的任意一点 $x$。再选择一个任意方向向量 $v$。我们沿着这个方向 $v$ 从点 $x$ 出发,得到一条直线。任何点 $x+tv$(其中 $t$ 是一个实数)都在这条直线上。这就叫做将函数限制在直线上。
- 直线上的函数:我们定义一个新的函数 $g(t)=f(x+tv)$。这个新的函数 $g(t)$ 表示原函数 $f$ 在直线 $x+tv$ 上的值。
- 检查凸性:若对于任意 $x$ 和 $v$,新的函数 $g(t)$ 是凸的,则我们就说原函数 $f$ 是凸的。也就是说,若 $f$ 在所有限制的直线上都是凸的,则 $f$ 本身就是凸的。
通过限制在直线上,我们将原来的多变量问题简化为单变量问题。对于单变量函数,判断凸性要比多变量情况简单得多。这使得我们可以用更简单的方法来判断一个函数是否是凸的。
> **举例**&emsp;假设我们有一个二次函数 $f(x)=x_1^2+x_2^2$。我们选一个点 $x=(a,b)$ 和一个方向 $v=(c,d)$,沿着这个方向得到直线 $(a,b)+t(c,d)$,然后我们可以定义一个新函数:
>
> $$
> g(t)=f((a,b)+t(c,d))=f(a+tc,b+td)=(a+tc)^2+(b+td)^2
> $$
>
> 我们需要检查这个新函数 $g(t)$ 是否是凸的。若对所有 $x$ 和 $v$ 新函数 $g(t)$ 都是凸的,则原函数 $f$ 就是凸的。在这个例子中,显然 $g(t)=(a+tc)^2+(b+td)^2$ 是一个关于 $t$ 的二次函数,它是凸的。因此,原函数 $f(x)=x_1^2+x_2^2$ 是凸的。
总的来说,"将函数限制在直线上"意味着通过沿着任意方向取直线来简化判断多变量函数的凸性,从而可以更方便地确定函数的整体凸性。
{% endnote %}
&emsp;&emsp;对凸函数的**分析**(*analysis*)已经相当地透彻,这里不再继续深入。例如有这样一个简单的结论,凸函数在其定义域相对内部是连续的;它只可能在相对边界上不连续。
# 2. 扩展值延伸
&emsp;&emsp;通常可以定义凸函数在定义域外的值为 $\infty$,从而将这个凸函数延伸至全空间 $\mathbf{R}^n$。若 $f$ 是凸函数,我们定义它的**扩展值延伸**(*extended-value extension*)$\tilde{f}:\mathbf{R}^n\to\mathbf{R}\cup\{\infty\}$ 如下
$$
\tilde{f}(x)=\begin{cases}
f(x)&x\in\textbf{dom}f\\\infty&x\not\in\textbf{dom}f
\end{cases}
$$
延伸函数 $\tilde{f}$ 是定义在全空间 $\mathbf{R}^n$ 上的,取值集合为 $\mathbf{R}\cup\{\infty\}$。我们也可以从延伸函数 $\tilde{f}$ 的定义中确定原函数 $f$ 的定义域,即 $\dom f=\{x\mid\tilde{f}(x)<\infty\}$。
&emsp;&emsp;这种延伸可以简化符号描述,此时我们就不需要明确描述定义域或者每次提到 $f(x)$ 时都限定“对于所有的 $x\in\dom f$”。以基本不等式 $\eqref{DefinitionOfConvexFunction}$ 为例,对于延伸函数 $\tilde{f}$,可以描述为:对于**任意**(*any*)$x$ 和 $y$,以及 $0<\theta<1$,有
$$
\tilde{f}(\theta x+(1-\theta)y)\leqslant\theta\tilde{f}(x)+(1-\theta)\tilde{f}(y)
$$
(当 $\theta=0$ 或 $\theta=1$ 时不等式总成立。)当然此时应当利用扩展运算和扩展序来理解这个不等式。
- 若 $x$ 和 $y$ 在 $\dom f$ 内,上述不等式即为不等式 $\eqref{DefinitionOfConvexFunction}$;
- 若 $x$ 或 $y$ 在 $\dom f$ 外,上述不等式的右端为 $\infty$,不等式仍然成立。
> **举例**&emsp;设 $f_1$ 和 $f_2$ 是 $\mathbf{R}^n$ 上的两个凸函数。逐点和函数 $f=f_1+f_2$ 的定义域为 $\dom f=\dom f_1\cap\dom f_2$,对于任意 $x\in\dom f$,有 $f(x)=f_1(x)+f_2(x)$。利用扩展值延伸我们可以简单地描述为,对于任意 $x$,$\tilde{f}(x)=\tilde{f}_1(x)+\tilde{f}_2(x)$。在这个方程里,函数 $f$ 的定义域被自动定义为 $\dom f=\dom f_1\cap\dom f_2$,因为当 $x\not\in\dom f_1$ 或者 $x\not\in\dom f_2$ 时,$\tilde{f}(x)=\infty$。在此例中,我们就可以利用扩展运算来自动定义定义域。
&emsp;&emsp;在不会造成歧义的情况下,可以用同样的符号来表示一个凸函数及其延伸函数。即假设所有的凸函数都隐含地被延伸了,也就是在定义域外都被定义为 $\infty$。
> **举例**&emsp;**凸集的示性函数**。设 $C\subseteq\mathbf{R}^n$ 是一个凸集,考虑(凸)函数 $I_C$,其定义域为 $C$,对于所有的 $x\in C$,有 $I_C(x)=0$。换言之,此函数在集合 $C$ 上一直为零。其扩展值延伸可以描述如下
>
> $$
> \tilde{I}_C(x)=\begin{cases}0&x\in C\\\infty&x\not\in C.\end{cases}
> $$
>
> 凸函数 $\tilde{I}_C$ 被称作集合 $C$ 的**示性函数**(*indicator function*)。
>
> 利用示性函数 $\tilde{I}_C$,可以更加灵活地定义符号描述。例如,对于在集合 $C$ 上极小化函数 $f$ 的问题(假设 $f$ 定义在整个 $\mathbf{R}^n$ 空间),可以给出等价的问题,即在 $\mathbf{R}^n$ 上极小化函数 $f+\tilde{I}_C$。事实上,按照不会造成歧义的约定,函数 $f+\tilde{I}_C$ 等价于定义在集合 $C$ 上的函数 $f$。
&emsp;&emsp;类似地,可以通过定义凹函数在定义域外都为 $-\infty$ 对其进行延伸。
# 3. 一阶条件
&emsp;&emsp;假设 $f$ 可微(即其梯度 $\nabla f$ 在开集 $\dom f$ 内处处存在),则函数 $f$ 是凸函数的充要条件是 $\dom f$ 是凸集且对于任意 $x,y\in\dom f$,下式成立
$$\begin{equation}\label{FirstOrderCondition}
f(y)\geqslant f(x)+\nabla f(x)^\TT (y-x)
\end{equation}$$
[图 2](#图2) 描述了上述不等式,也即沿函数上任意一点作切线,函数始终位于切线上方。
<a id="图2"></a>
![图 2. 若函数 $f$ 是凸的且可微,则对于任意 $x,y\in\dom f$,有 $f(x)+\nabla f(x)^\TT(y-x)\leqslant f( y)$。](../images/post/2024-06-14-josh-cvx-2-1/2024-06-14-josh-cvx-2-1-020-FirstOrderCondition.png){width=500px}
&emsp;&emsp;由 $f(x)+\nabla f(x)^\TT (y-x)$ 得出的仿射函数 $y$ 即为函数 $f$ 在点 $x$ 附近的 Taylor 近似。不等式 $\eqref{FirstOrderCondition}$ 表明,对于一个凸函数,其一阶 Taylor 近似实质上是原函数的一个**全局下估计**(*global underestimator*)。反之,若某个函数的一阶 Taylor 近似总是其全局下估计,则这个函数是凸的。
&emsp;&emsp;不等式 $\eqref{FirstOrderCondition}$ 说明从一个凸函数的**局部信息**(*local information*)(即它在某点的函数值及导数),可以得到一些**全局信息**(*global information*)(如它的全局下估计)。这也许是凸函数的最重要的信息,由此可以解释凸函数以及凸优化问题的一些非常重要的性质。
> **举例**&emsp;由不等式 $\eqref{FirstOrderCondition}$ 可以知道,若 $\nabla f(x)=0$,则对于所有的 $y\in\dom f$,存在 $f(y)\geqslant f(x)$,即 $x$ 是函数 $f$ 的全局极小点。
&emsp;&emsp;严格凸性同样可以由一阶条件刻画:函数 $f$ 严格凸的充要条件是 $\dom f$ 是凸集且对于任意 $x,y\in\dom f$,$x\neq y$,有
$$\begin{equation}\label{StrictFirstOrderCondition}
f(y)>f(x)+\nabla f(x)^\TT (y-x)
\end{equation}$$
&emsp;&emsp;对于凹函数,亦存在与之对应的一阶条件:函数 $f$ 是凹函数的充要条件是 $\dom f$ 是凸集且对于任意 $x,y\in\dom f$,下式成立
$$
f(y)\leqslant f(x)+\nabla f(x)^\TT (y-x)
$$
## 3.1 一阶凸性条件的证明
&emsp;&emsp;为了证明式 $\eqref{FirstOrderCondition}$,先考虑 $n=1$ 的情况:我们证明可微函数 $f:\mathbf{R}\to\mathbf{R}$ 是凸函数的充要条件是对于 $\dom f$ 内的任意 $x$ 和 $y$,有
$$\begin{equation}\label{FirstOrderConditionWhenNEquals1}
f(y)\geqslant f(x)+f'(x)(y-x)
\end{equation}$$
&emsp;&emsp;首先证明必要性。假设 $f$ 是凸函数,且 $x,y\in\dom f$。因为 $\dom f$ 是凸集(某个区间),对于任意 $0<t\leqslant1$,我们有 $x+t(y-x)\in\dom f$,由函数 $f$ 的凸性可得
$$
f(x+t(y-x))\leqslant(1-t)f(x)+tf(y)
$$
将上式两端同除 $t$ 可得
$$
f(y)\geqslant f(x)+\frac{f(x+t(y-x))-f(x)}{t}
$$
令 $t\to 0$,可以得到不等式 $\eqref{FirstOrderConditionWhenNEquals1}$。
&emsp;&emsp;为了证明充分性,假设对 $\dom f$(某个区间)内的任意 $x$ 和 $y$,函数满足不等式 $\eqref{FirstOrderConditionWhenNEquals1}$。选择任意 $x\neq y$,$0\leqslant\theta\leqslant1$,令 $z=\theta x+(1-\theta)y$。两次应用不等式 $\eqref{FirstOrderConditionWhenNEquals1}$ 可得
$$
f(x)\geqslant f(z)+f'(z)(x-z),\quad f(y)\geqslant f(z)+f'(z)(y-z)
$$
将第一个不等式乘以 $\theta$,第二个不等式乘以 $1-\theta$,并将二者相加可得
$$
\theta f(x)+(1-\theta)f(y)\geqslant f(z)
$$
从而说明了函数 $f$ 是凸的。
&emsp;&emsp;现在来证明一般情况,即 $f:\mathbf{R}^n\to\mathbf{R}$。设 $x,y\in\mathbf{R}^n$,考虑过这两点的直线上的函数 $f$,即函数 $g(t)=f(ty+(1-t)x)$,此函数对 $t$ 求导可得 $g'(t)=\nabla f(ty+(1-t)x)^\TT(y-x)$。
&emsp;&emsp;首先假设函数 $f$ 是凸的,则函数 $g$ 是凸的,由前面的讨论可得 $g(1)\geqslant g(0)+g'(0)$,即
$$
f(y)\geqslant f(x)+\nabla f(x)^\TT (y-x)
$$
再假设此不等式对于任意 $x$ 和 $y$ 均成立,因此若 $ty+(1-t)x\in\dom f$ 以及 $\tilde{t}y+(1-\tilde{t})x\in\dom f$,有
$$
f(ty+(1-t)x)\geqslant f(\tilde{t}y+(1-\tilde{t})x)+\nabla f(\tilde{t}y+(1-\tilde{t})x)^\TT (y-x)(t-\tilde{t})
$$
即 $g(t)\geqslant g(\tilde{t})+g'(\tilde{t})(t-\tilde{t})$,说明了函数 $g$ 是凸的。
# 4 二阶条件
&emsp;&emsp;现在假设函数 $f$ 二阶可微,即对于开集 $\dom f$ 内的任意一点,它的 **Hessian 矩阵**或者二阶导数 $\nabla^2f$ 存在,则函数 $f$ 是凸函数的充要条件是,其 Hessian 矩阵是半正定阵:即对于所有的 $x\in\dom f$,有
$$
\nabla^2f(x)\succeq0
$$
对于 $\mathbf{R}$ 上的函数,上式可以简化为一个简单的条件 $f''(x)\geqslant0$($\dom f$ 是凸的,即一个区间),此条件说明函数 $f$ 的导数是非减的。条件 $\nabla^2f(x)\succeq0$ 从几何上可以理解为函数图像在点 $x$ 处具有正(向上)的曲率。
&emsp;&emsp;类似地,函数 $f$ 是凹函数的充要条件是,$\dom f$ 是凸集且对于任意 $x\in$ $\dom f$,$\nabla ^{2}f( x)$ $\preceq$ 0。严格凸的条件可以部分由二阶条件刻画。若对于任意的 $x\in\dom f$ 有 $\nabla^2f(x)\succ0$,则函数 $f$ 严格凸。反过来则不一定成立:例如,函数 $f:\mathbf{R}\to\mathbf{R}$,其表达式为 $f(x)=x^4$,它是严格凸的,但是在 $x=0$ 处,二阶导数为零。
> **举例**&emsp;**二次函数**。考虑二次函数 $f:\mathbf{R}^n\to\mathbf{R}$,其定义域为 $\dom f=\mathbf{R}^n$,其表达式为
>
> $$
> f(x)=(1/2)x^\TT Px+q^\TT x+r
> $$
>
> 其中 $P\in\mathbf{S}^{n}$,$q\in\mathbf{R}^{n}$,$r\in\mathbf{R}$。因为对于任意 $x$,$\nabla^2f(x)=P$,所以函数 $f$ 是凸的,当且仅当 $P\succeq0$($f$ 是凹的当且仅当 $P\preceq0$)。
>
> 对于二次函数,严格凸比较容易表达:函数 $f$ 是严格凸的,当且仅当 $P\succ0$(函数是严格凹的当且仅当 $P\prec0$)。
> **注释**&emsp;在判断函数的凸性和凹性时,不管是一阶条件还是二阶条件,$\dom f$ 必须是凸集这个前提条件必须满足。例如,考虑函数 $f(x)=1/x^2$,其定义域为 $\dom f=\{x\in$ $\mathbf{R}\mid x\neq0\}$,对于所有 $x\in\dom f$ 均满足 $f''(x)>0$,但是函数 $f(x)$ 并不是凸函数。
# 5. 例子
&emsp;&emsp;前文已经提到所有的线性函数和仿射函数均为凸函数(同时也是凹函数),并描述了凸和凹的二次函数。本节绘出更多的凸函数和凹函数的例子。
## $\mathbf{R}$ 上的例子
&emsp;&emsp;首先考虑 $\mathbf{R}$ 上的一些函数,其自变量为 $x$。
- **指数函数**(*Exponential*)。对任意 $a\in\mathbf{R}$,函数 $e^{ax}$ 在 $\mathbf{R}$ 上是凸的。
- **幂函数**(*Power*)。当 $a\geqslant1$ 或 $a\leqslant0$ 时,$x^a$ 在 $\mathbf{R}_{++}$ 上是凸函数;当 $0\leqslant a\leqslant1$ 时,$x^a$ 在 $\mathbf{R}_{++}$ 上是凹函数。
- **绝对值幂函数**(*Power of absolute value*)。当 $p\geqslant1$ 时,函数 $|x|^p$ 在 $\mathbf{R}$ 上是凸函数。
- **对数函数**(*Logarithm*)。函数 $\log x$ 在 $\mathbf{R}_{++}$ 上是凹函数。
- **负熵**(*Negative entropy*)。函数 $x\log x$ 在其定义域上是凸函数。(定义域为 $\mathbf{R}_{++}$ 或者 $\mathbf{R}_+$,当 $x=0$ 时定义函数值为 0。)
&emsp;&emsp;我们可以通过基本不等式 $\eqref{DefinitionOfConvexFunction}$ 或者二阶导数半正定或半负定来判断上述函数是凸的或是凹的。以函数 $f(x)=x\log x$ 为例,其导数和二阶导数为
$$
f'(x)=\log x+1,\quad f''(x)=1/x
$$
即对于 $x>0$,有 $f''(x)>0$。所以负熵函数是(严格)凸的。
## $\mathbf{R}^n$ 上的例子
&emsp;&emsp;下面给出 $\mathbf{R}^n$ 上的一些例子。
**范数**(*Norm*)。 $\mathbf{R}^n$ 上的任意范数均为凸函数。
**最大值函数**(*Max function*)。函数 $f(x)=\max\{x_1,\cdots,x_n\}$ 在 $\mathbf{R}^n$ 上是凸的。
**二次-线性分式函数**(*Quadratic-over-linear function*)。函数 $f(x,y)=x^2/y$,其定义域为
$$
\dom f= \mathbf{R} \times \mathbf{R} _{+ + }= \{ ( x, y) \in \mathbf{R} ^{2}\mid y> 0\}
$$
是凸函数(如[图 3](#图3)所示)。
<a id="图3"></a>
![图 3. 函数 $f(x, y) = x^2/y$ 的图像。](../images/post/2024-06-14-josh-cvx-2-1/2024-06-14-josh-cvx-2-1-030-QuadraticOverLinearFunction.png){width=400px}
**指数和的对数**(*Log-sum-exp*)。函数 $f(x)=\log\left(e^{x_1}+\cdots+e^{x_n}\right)$ 在 $\mathbf{R}^n$上是凸函数。这个函数可以看成最大值函数的可微(实际上是解析)近似,因为对任意 $x$,下面的不等式成立
$$
\max\{x_{1},\cdots,x_{n}\}\leqslant f(x)\leqslant\max\{x_{1},\cdots,x_{n}\}+\log n
$$
(第二个不等式当 $x$ 的所有分量都相等时是紧的。)[图 4](#图4) 描述了当 $n=2$ 时 $f$ 的图像。
<a id="图4"></a>
![图 4. 函数 $f(x, y) = log(e^x + e^y)$ 的图像。](../images/post/2024-06-14-josh-cvx-2-1/2024-06-14-josh-cvx-2-1-040-LogSumExo.png){width=400px}
**几何平均**(*Geometric mean*)。几何平均函数$f(x)=\left(\displaystyle\prod_{i=1}^n x_i\right)^{1/n}$在定义域 $\dom f=\mathbf{R}_{++}^n$ 上是凹函数。
**对数-行列式**(*Log-determinant*)。函数 $f(X)=\log\det X$ 在定义域 $\dom f=\mathbf{S}_{++}^n$ 上是凹函数。
&emsp;&emsp;判断上述函数的凸性(或者凹性)可以有多种途径,可以直接验证不等式 $\eqref{DefinitionOfConvexFunction}$ 是否成立,亦可以验证其 Hessian 矩阵是否半正定,或者可以将函数转换到与其定义域相交的任意直线上,通过得到的单变量函数判断原函数的凸性。
**范数**。若函数 $f:\mathbf{R}^n\to\mathbf{R}$ 是范数,任取 $0\leqslant\theta\leqslant1$,有
$$
f(\theta x+(1-\theta)y)\leqslant f(\theta x)+f((1-\theta)y)=\theta f(x)+(1-\theta)f(y)
$$
上述不等式可以由三角不等式得到,当范数满足齐次性时,上述不等式取等号。
**最大值函数**。对任意 $0\leqslant\theta\leqslant1$,函数 $f(x)=\displaystyle\max_i x_i$ 满足
$$\begin{aligned}
f(\theta x+(1-\theta)y)&=\max_{i}(\theta x_{i}+(1-\theta)y_{i})
\\
&\leqslant\theta\max_{i}x_{i}+(1-\theta)\max_{i}y_{i}
\\
&=\theta f(x)+(1-\theta)f(y)
\end{aligned}$$
**二次线性分式函数**。为了说明二次-线性分式函数 $f( x, y) = x^2/ y$ 是凸的,我们注意到,对于 $y>0$,有
$$
\nabla^2f(x,y)=\dfrac{2}{y^3}\left[\begin{array}{cc}
y^2&-xy\\-xy&x^2
\end{array}\right]=\dfrac{2}{y^3}\left[\begin{array}{c}
y\\-x
\end{array}\right]\left[\begin{array}{c}
y\\-x
\end{array}\right]^\TT \succeq0
$$
**指数和的对数**。指数和的对数函数的 Hessian 矩阵为
$$
\nabla^{2}f(x)=\frac{1}{(\mathbf{1}^\TT z)^{2}}\left((\mathbf{1}^\TT z)\diag(z)-zz^\TT\right)
$$
其中 $z=(e^{x_1},\cdots,e^{x_n})$。为了说明 $\nabla^2f(x)\succeq0$,我们证明对任意 $v$,有 $v^\TT \nabla^2f(x)v\geqslant0$,即
$$
v^\TT \nabla^{2}f(x)v=\frac{1}{(\mathbf{1}^\TT z)^{2}}\left(\left(\sum_{i=1}^{n}z_{i}\right)\left(\sum_{i=1}^{n}v_{i}^{2}z_{i}\right)-\left(\sum_{i=1}^{n}v_{i}z_{i}\right)^{2}\right)\geqslant0
$$
上述不等式可以应用 Cauchy-Schwarz 不等式 $(a^\TT a)(b^\TT b)\geqslant(a^\TT b)^2$ 得到,此时向量 $a$ 和 $b$ 的分量为 $a_i= v_i\sqrt {z_i}$,$b_i= \sqrt {z_i}$。
**几何平均**。类似地,我们说明,几何平均函数 $f(x)=\left(\displaystyle\prod_{i=1}^nx_i\right)^{1/n}$ 在定义域 $\dom f=\mathbf{R}_{++}^{n}$上是凹的。其 Hessian 矩阵 $\nabla^2f(x)$ 可以通过下面两个式子给出
$$
\frac{\partial^{2}f(x)}{\partial x_{k}^{2}}=-(n-1)\frac{\left(\displaystyle\prod_{i=1}^{n}x_{i}\right)^{1/n}}{n^{2}x_{k}^{2}},\quad\frac{\partial^{2}f(x)}{\partial x_{k}\partial x_{l}}=\frac{\left(\displaystyle\prod_{i=1}^{n}x_{i}\right)^{1/n}}{n^{2}x_{k}x_{l}}\quad\forall\:k\neq l
$$
因此 $\nabla^2f(x)$ 具有如下表达式
$$\nabla^{2}f(x)=-\frac{\displaystyle\prod_{i=1}^{n}x_{i}^{1/n}}{n^{2}}\left(n \diag(1/x_{1}^{2},\cdots,1/x_{n}^{2})-qq^\TT\right)
$$
其中,$q_i=1/x_i$。我们需要证明 $\nabla^2f(x)\preceq0$,即对于任意向量 $v$,有
$$
v^\TT \nabla^2f(x)v=-\frac{\displaystyle\prod_{i=1}^nx_i^{1/n}}{n^2}\left(n\sum_{i=1}^nv_i^2/x_i^2-\left(\sum_{i=1}^nv_i/x_i\right)^2\right)\leqslant0
$$
这同样可以应用 Cauchy-Schwarz 不等式 $(a^\TT a)(b^\TT b)\geqslant(a^\TT b)^2$ 得到,只需令向量 $a=\mathbf{1}$,向量 $b$ 的分量 $b_i=v_i/x_i$。
**对数-行列式**。对于函数 $f(X)=\log\det X$,我们可以将其转化为任意直线上的单变量函数来验证它是凹的。令 $X=Z+tV$,其中 $Z,V\in\mathbf{S}^n$,定义 $g(t)=f(Z+tV)$,自变量 $t$ 满足 $Z+tV\succ0$。不失一般性,假设 $t=0$ 满足条件,即 $Z\succ0$。我们有
$$\begin{aligned}
g(t)&=\log\det(Z+tV)
\\
&=\log\det(Z^{1/2}(I+tZ^{-1/2}VZ^{-1/2})Z^{1/2})
\\
&=\sum_{i=1}^{n}\log(1+t\lambda_{i})+\log\det Z
\end{aligned}$$
其中 $\lambda_1,\cdots,\lambda_n$ 是矩阵 $Z^{-1/2}VZ^{-1/2}$ 的特征值。因此下式成立
$$
g'(t)=\sum_{i=1}^{n}\frac{\lambda_{i}}{1+t\lambda_{i}},\qquad g''(t)=-\sum_{i=1}^{n}\frac{\lambda_{i}^{2}}{(1+t\lambda_{i})^{2}}
$$
因为 $g''(t)\leqslant0$,函数 $f$ 是凹的。
# 6. 下水平集
&emsp;&emsp;函数 $f: \mathbf{R} ^{n}\to \mathbf{R}$ 的 **$\alpha$-下水平集**(*$\alpha$-sublevel set*)定义为
$$
C_{\alpha}=\{x\in\dom f\mid f(x)\leqslant\alpha\}
$$
对于任意 $\alpha$ 值,凸函数的下水平集仍然是凸集。证明可以由凸集的定义直接得到:若 $x,y\in C_{\alpha }$,则有 $f( x) \leqslant \alpha$,$f( y) \leqslant \alpha$,因此对于任意$0\leqslant\theta\leqslant1$,$f(\theta x+(1-\theta)y)\leqslant\alpha$,即 $\theta x+(1-\theta)y\in C_{\alpha}$。
&emsp;&emsp;反过来不一定正确:某个函数的所有下水平集都是凸集,但这个函数可能不是凸函数。例如,函数 $f(x)=-e^x$ 在 $\mathbf{R}$ 上不是凸函数(实质上,它是严格凹函数),但是其所有下水平集均为凸集。
&emsp;&emsp;若 $f$ 是凹函数,则由 $\{x\in\dom f\mid f(x)\geqslant\alpha\}$ 定义的 **$\alpha$-上水平集**(*$\alpha$-superlevel set*)也是凸集。下水平集的性质可以用来判断集合的凸性,若某个集合可以描述为一个凸函数的下水平集,或者一个凹函数的上水平集,则其是凸集。
> **举例**&emsp;对于 $x\in\mathbf{R}_+^n$,其几何平均和算术平均分别为
>
> $$
> G(x)=\left(\prod_{i=1}^{n}x_{i}\right)^{1/n},\qquad A(x)=\frac{1}{n}\sum_{i=1}^{n}x_{i}
> $$
>
> (在 $G$ 中,定义 $0^{1/n}=0$)。算术几何平均不等式为 $G(x)\leqslant A(x)$。
>
> 设 $0\leqslant\alpha\leqslant1$,考虑集合
>
> $$
> \{x\in\mathbf{R}_{+}^{n}\mid G(x)\geqslant\alpha A(x)\}
> $$
>
> 即使得几何平均至少大于等于算术平均的 $\alpha$ 倍的集合。此集合是凸集,因为它是凹函数 $G(x)=\alpha A(x)$ 的 $0$-上水平集。事实上,这个每合是正齐次的,因此它是凸锥
# 7. 上境图
&emsp;&emsp;函数 $f:\mathbf{R}^{n}\to\mathbf{R}$ 的图像定义为
$$
\{(x,f(x))\mid x\in\dom f\}
$$
它是 $\mathbf{R}^{n+1}$ 空间的子集。函数 $f:\mathbf{R}^n\to\mathbf{R}$ 的**上境图**(*epigraph*)定义为
$$
\epi f=\{(x,t)\mid x\in\dom f,f(x)\leqslant t\}
$$
它也是 $\mathbf{R}^{n+1}$ 空间的子集。(“Epi”是之上的意思,所以上境图的英文 epigraph 是“在函数图像之上”的意思。)[图 5](#图5)说明了上境图的定义。
<a id="图5"></a>
![图 5. 函数 $f$ 的上境图,见阴影部分。深颜色的下边界是函数 $f$ 的图像。](../images/post/2024-06-14-josh-cvx-2-1/2024-06-14-josh-cvx-2-1-050-EpigraphOfF.png){width=400px}
&emsp;&emsp;凸集和凸函数的联系可以通过上境图来建立:一个函数是凸函数,当且仅当其上境图是凸集。一个函数是凹函数,当且仅当其**亚图**(*hypograph*)
$$
\hypo f=\{(x,t)\mid t\leqslant f(x)\},
$$
是凸集。
> **举例**&emsp;**矩阵分式函数**。矩阵分式函数 $f:\mathbf{R}^n\times\mathbf{S}^n\to\mathbf{R}$
>
> $$
> f(x,Y)=x^\TT Y^{-1}x
> $$
>
> 在定义域 $\dom f=\mathbf{R}^n\times\mathbf{S}_{++}^n$ 上是凸的。(这实质上是定义域为 $\dom f=\mathbf{R}\times\mathbf{R}_{++}$ 的二次-线性分式函数 $f(x,y)=x^2/y$ 的一个扩展。)
>
> 一个简单的方式来验证矩阵分式函数 $f$ 的凸性是通过其上境图
>
> $$\begin{aligned}
> \epi f &= \left\{(x,Y,t)\mid Y\succ0,\ x^\TT Y^{-1}x\leqslant t\right\}
> \\
> &=\left\{(x,Y,t)\:\middle|\left[\begin{array}{cc}
> Y&x
> \\
> x^\TT&t
> \end{array}\right]\succeq0,\:Y\succ0\right\}
> \end{aligned}$$
>
> 并应用 Schur 补条件判断分块矩阵的半正定性。最后一个条件是关于 $(x,Y,t)$ 的线性矩阵不等式,因此 $\epi f$ 是凸集。
>
> 对于 $n=1$ 的特殊情况,矩阵分式函数简化为二次-线性分式函数 $x^2/y$,相应的线性矩阵不等式表示为
> $$
> \left[\begin{array}{cc}y&x\\x&t\end{array}\right]\succeq0,\quad y>0
> $$
>
> (函数图像如[图 3](#图3) 所示)。
&emsp;&emsp;关于凸函数的很多结果可以从几何的角度利用上境图并结合凸集的一些结论来证明(或理解),例如,考虑凸函数的一阶条件
$$
f(y)\geqslant f(x)+\nabla f(x)^\TT (y-x)
$$
其中函数 $f$ 是凸的,$x,y\in\dom f$。我们可以利用 $\epi f$ 从几何角度理解上述基本不等式。若 $(y,t)\in\epi f$,有
$$
t\geqslant f(y)\geqslant f(x)+\nabla f(x)^\TT (y-x)
$$
上式可以描述为
$$
(y,t)\in\epi f\implies\left[\begin{array}{c}\nabla f(x)\\-1\end{array}\right]^\TT \left(\left[\begin{array}{c}y\\t\end{array}\right]-\left[\begin{array}{c}x\\f(x)\end{array}\right]\right)\leqslant0
$$
这意味着法向量为 $(\nabla f(x),-1)$ 的超平面在边界点 $(x,f(x))$ 支撑着 $\epi f$,如[图 6](#图6) 所示。
<a id="图6"></a>
![图 6. 对于可微凸函数 $f$,向量 $(\nabla f(x),-1)$ 定义了函数 $f$ 在点 $x$ 处的上境图的一个支撑超平面。](../images/post/2024-06-14-josh-cvx-2-1/2024-06-14-josh-cvx-2-1-060-EpigraphAndSupportingHyperplane.png){width=400px}
# 8. Jensen 不等式及其扩展
&emsp;&emsp;基本不等式
$$
f(\theta x+(1-\theta)y)\leqslant\theta f(x)+(1-\theta)f(y)
$$
有时也称作 **Jensen 不等式**(*Jensen’s inequality*)。此不等式可以很方便地扩展至更多点的凸组合:若函数 $f$ 是凸函数,$x_1,\cdots,x_k\in\dom f$,$\theta_1,\cdots,\theta_k\geqslant0$ 且 $\theta_1+\cdots+\theta_k=1$,则下式成立
$$
f(\theta_1x_1+\cdots+\theta_kx_k)\leqslant\theta_1f(x_1)+\cdots+\theta_kf(x_k)
$$
考虑凸集时,此不等式可以扩展至无穷项和、积分以及期望。例如,若在 $S\subseteq\dom f$ 上 $p(x)\geqslant0$ 且 $\displaystyle\int_Sp(x) \dd x = 1$,则当相应的积分存在时,下式成立
$$
f\left(\int_Sp(x)x\dd x\right)\leqslant\int_Sf(x)p(x)\dd x
$$
扩展到更一般的情况,我们可以采用其支撑属于 $\dom f$ 的任意概率测度。若 $x$ 是随机变量,事件 $x\in\dom f$ 发生的概率为 1,函数 $f$ 是凸函数,当相应的期望存在时,我们有
$$\begin{equation}\label{GeneralJensenInequality}
f(\mathbb{E}x)\leqslant\mathbb{E}f(x)
\end{equation}$$
设随机变量 $x$ 的可能取值为 $\{ x_1, x_2\}$ 相应地取值概率为 $\prob ( x= x_1) = \theta$,$\prob( x=x_2)=1-\theta$,则由一般形式 $\eqref{GeneralJensenInequality}$ 可以得到基本不等式 $\eqref{DefinitionOfConvexFunction}$。所以不等式 $\eqref{GeneralJensenInequality}$ 可以刻画凸性:若函数 $f$ 不是凸函数,则存在随机变量 $x$,$x\in\dom f$ 以概率 $1$ 发生,使得 $f(\mathbb{E}x)>\mathbb{E}f(x)$。
&emsp;&emsp;上述所有不等式均被称为 **Jensen 不等式**(*Jensen’s inequality*),而实际上最初由 Jensen 提出的不等式相当简单
$$
f\left(\frac{x+y}2\right)\leqslant\frac{f(x)+f(y)}2
$$
> **注释**&emsp;我们可以这样理解式 $\eqref{GeneralJensenInequality}$。假设 $x\in\dom f\subseteq\mathbf{R}^n$,$z$ 是 $\mathbf{R}^n$ 中的随机变量,其均值为零,则有
>
> $$
> \mathbb{E}f(x+z)\geqslant f(x)
> $$
>
> 因此,随机化或者扰动(即在自变量上增加一个零均值的随机变量)从平均效果上不会减小凸函数的值。
# 9. 不等式
&emsp;&emsp;很多著名的不等式都可以通过将 Jensen 不等式应用于合适的凸函数得到。(事实上,凸性和 Jensen 不等式可以构成不等式理论的基础。)
> **举例**&emsp;考虑算术-几何平均不等式
>
> $$\begin{equation}\label{ArithmeticGeometricMeanInequality}
> \sqrt{a b} \leqslant( a+b ) / 2
> \end{equation}$$
>
> 其中 $a, b \geqslant0$。我们可以利用凸性和 Jensen 不等式得到此不等式。函数 $-\log x$ 是凸函数:利用 Jensen 不等式,令 $\theta=1 / 2$ ,可得
>
> $$
> -\log \left( \frac{a+b} {2} \right) \leqslant\frac{-\log a-\log b} {2}
> $$
>
> 等式两边取指数即可得到式 $\eqref{ArithmeticGeometricMeanInequality}$。
> **举例**&emsp;证明 Hölder 不等式:对 $p > 1$,$1 / p+1 / q=1$,以及 $x,y \in\mathbf{R}^{n}$ 有
>
> $$
> \sum_{i=1}^{n} x_{i} y_{i} \leqslant\left( \sum_{i=1}^{n} | x_{i} |^{p} \right)^{1 / p} \left( \sum_{i=1}^{n} | y_{i} |^{q} \right)^{1 / q}
> $$
>
> 由 $-\log x$ 的凸性以及 Jensen 不等式,可以得到更为一般的算术-几何平均不等式
>
> $$
> a^{\theta} b^{1-\theta} \leqslant\theta a+( 1-\theta) b,
> $$
>
> 其中 $a,b \geqslant0$,$0 \leqslant\theta\leqslant1$。令
>
> $$
> a=\frac{| x_{i} |^{p}} {\displaystyle\sum_{j=1}^{n} | x_{j} |^{p}}, \qquad b=\frac{| y_{i} |^{q}} {\displaystyle\sum_{j=1}^{n} | y_{j} |^{q}}, \qquad\theta=1 / p,
> $$
>
> 可以得到如下不等式
>
> $$
> \left( \frac{| x_{i} |^{p}} {\displaystyle\sum_{j=1}^{n} | x_{j} |^{p}} \right)^{1 / p} \left( \frac{| y_{i} |^{q}} {\displaystyle\sum_{j=1}^{n} | y_{j} |^{q}} \right)^{1 / q} \leqslant\frac{| x_{i} |^{p}} {p \displaystyle\sum_{j=1}^{n} | x_{j} |^{p}}+\frac{| y_{i} |^{q}} {q \displaystyle\sum_{j=1}^{n} | y_{j} |^{q}}.
> $$
>
> 对 $i$ 进行求和可以得到 Hölder 不等式。
# 参考文献
1. Stephen P. Boyd and Lieven Vandenberghe, *Convex optimization*. Cambridge, UK: Cambridge University Press, 2004.
2. Stephen P. Boyd and Lieven Vandenberghe, *凸优化*. 北京: 清华大学出版社, 2013.
[仿射函数]: https://josh-gao.top/posts/a4a69a4f.html?#%E4%BB%BF%E5%B0%84%E5%87%BD%E6%95%B0
@@ -0,0 +1,479 @@
---
title: Zynq MPSoC / RFSoC 动态配置 DIMM DDR
mathjax: true
comments: true
copyright: true
toc:
enable: true
number: true
wrap: true
expand_all: true
max_depth: 4
tags:
- 调试记录
- DDR
- MPSoC
- RFSoC
- SPD
- Zynq
categories:
- 调试记录
abbrlink: 11cd1dc
date: 2024-06-27 20:06:13
---
对于 DIMM 拓扑的 DDR,通常可以使用 I2C 对搭载在 DIMM 上的 SPD EEPROM 进行读取后获得配置参数,然后对 DDR 控制器进行配置。
AMD Xilinx UG1085 的 [Dynamic DDR Configuration](https://docs.amd.com/r/en-US/ug1085-zynq-ultrascale-trm/Dynamic-DDR-Configuration) 一节指出,当 DDR 控制器处于复位状态时,可以在运行时通过 FSBL 获取 DDR 参数并对 DDR 控制器进行初始化。
本文基于 Zynq RFSoC,对 PS 端的 SO-DIMM DDR 进行动态配置。
<!-- more -->
# 名词释义
- [BSP](https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842276/Standalone+Board+Support+Package+BSP):Board Support Package,板级支持包
- [EEPROM](https://en.wikipedia.org/wiki/EEPROM):Electrically-Erasable Programmable Read-Only Memory,电子擦除式可复写只读存储器
- [FSBL](https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842019/Zynq+UltraScale+FSBL#ZynqUltraScale+FSBL-WhatisFSBL?):First Stage Bootloader,第一阶段引导加载程序
- [DDR DRAM](https://en.wikipedia.org/wiki/DDR_SDRAM):Double Data Rate Synchronous Dynamic Random-Access Memory,双倍数据率同步动态随机存取存储器
- [DIMM](https://en.wikipedia.org/wiki/DIMM):Dual In-line Memory Modules,双列直插式存储模块
- PCW:Processing System Configuration Wizard,处理系统配置向导
- [SO-DIMM](https://en.wikipedia.org/wiki/DIMM#SO-DIMM):Small Outline Dual In-line Memory Modules,小外形双列直插式内存模块
- [SPD](https://en.wikipedia.org/wiki/Serial_presence_detect):Serial Presence Detect,串行存在检测
# 硬软件版本
| 硬软件 | 型号/版本 |
| :--: | :-------: |
| FPGA | Zynq RFSoC XCZU48DR-2-FSVG1517-I |
| DDR4 | Micron MTA4ATF51264HZ-2G6E1 |
| I2C Mux | TI TCA9548APWR |
| Vivado | 2024.1 |
| Vitis Classic | 2024.1 |
# Zynq MPSoC / RFSoC 动态 DDR 配置简介
Zynq MPSoC / RFSoC 动态 DDR 配置具有如下特性:
- 无需在 Vivado 中进行改动即可更换 DIMM,并使用动态 DDR 配置初始化 DDR;
- 支持 DDR3 和 DDR4 DIMM;
- 单一的 PetaLinux BSP 即可支持任何可安装的 DIMM 器件。
{% note warning %}
动态 DDR 配置功能仅可用于 PS DIMM DDR,不支持颗粒 DDR。
{% endnote %}
# 具体操作方法
## PCW GUI 配置
在使用动态 DDR 配置之前,需要在如[图 1](#图1) 的 Vivado 的 PCW GUI 中启用 DDR 控制器,且将“DDR Controller Options”部分设置为:
- Memory Type:DDR4 或 DDR3
- Components:UDIMM 或 RDIMM
- ECC:Enabled 或 Disabled
- Effective DRAM Bus Width:64 Bit
<a id="图1"></a>
![图 1. Zynq UltraScale+ MPSoC 配置 GUI](../images/post/2024-06-27-zynq-mpsoc-ddr-spd/2024-06-27-zynq-mpsoc-ddr-spd-010-ZynqGui.png)
动态 DDR 配置将自动读取 SPD 表,并设置“DDR Memory Option”部分的所有参数,如下表。
| Option | Value Example | Option | Value Example |
| -------------- | --------- | -------------- | --------- |
| Speed Bin (Use Tooltip) | DDR42133P | DRAM IC Bus Width (per die) | 8 Bits |
| Cas Latency | 15 | DRAM Device Capacity(per die) | 4096 MBits |
| RAS to CAS Delay (Cycles) | 15 | Bank Group Address Count (Bits) | 2 |
| Pre-charge Time (Cycles) | 15 | Bank Address Count (Bits) | 2 |
| Cas Write Latency (Cycles) | 14 | Row Address Count (Bits) | 15 |
| tRC (ns) | 46.5 | Column Address Count | 10 |
| tRASmin (ns) | 33 | Dual Rank | |
| tFAW (ns) | 21 | DDR Size (in hexa) | 0XFFFFFFFF (4GB) |
| Additive Latency (Cycles) | 0 | | |
而“Other Options”部分的所有值都需要用户根据需要设置,无法从 SPD 表中获得,如下表。
| Option | Value Example | Option | Value Example |
| -------------- | --------- | -------------- | --------- |
| Memory Address Map | ROW BANK COL | Power Mode Settings | Power Down Enable |
| Data Mask and DBI | DM NO DBI | Clock Stop |
| Address Mirroring | | **Refresh Mode Settings** |
| 2nd Clock | | Lower-Power Auto Self-Refresh | Manual Normal |
| Parity | | Temp Controlled Refresh | |
| 2Tck Command Timing (2T) | | Max. Operating Temperature | Normal (0-85) |
| | | Fine Granularity Refresh Mode | 1x |
| | | Self-Refresh Abort | |
## 启用动态 DDR 配置功能
要启用动态 DDR 配置功能,需要在 Vivado 中使用 TCL 命令将参数 `CONFIG.PSU_DYNAMIC_DDR_CONFIG_EN` 置为 1:
``` tcl
set_property CONFIG.PSU_DYNAMIC_DDR_CONFIG_EN 1 [get_bd_cells /zynq_ultra_ps_e]
```
这里的 `zynq_ultra_ps_e` 需要替换为实际 Block Design 中 Zynq UltraScale+ MPSoC IP 核的名称,如[图 2](#图2)。
<a id="图2"></a>
![图 2. Block Design 整体](../images/post/2024-06-27-zynq-mpsoc-ddr-spd/2024-06-27-zynq-mpsoc-ddr-spd-020-BlockDesign.png)
然后重新生成 Output Products 即可(若除 PS 处理器外还有其他逻辑,则需要重新生成比特流)。FSBL 将会在启动过程中使用该参数,并执行动态 DDR 配置。
{% note info %}
如果设置了上述参数却出现了如下警告,是因为 GUI 中 DDR 类型必须为 UDIMM 或 RDIMM,不能为 Component。
``` plain
WARNING: [BD 41-721] Attempt to set value '1' on disabled parameter 'PSU_DYNAMIC_DDR_CONFIG_EN' of cell '/zynq_ultra_ps_e_0' is ignored
```
{% endnote %}
## I2C 硬件要求
由于动态 DDR 配置需要在 FSBL 中使用 I2C 读取 DDR SPD EEPROM 中的数据,而在 Xilinx 自动生成 FSBL 中,I2C 读取 DDR SPD EEPROM 的方式是固定的,因此**若不想对生成的 FSBL 进行修改,则需要在硬件上适配 FSBL**。
Xilinx FSBL 使用 I2C1(1 号 I2C 控制器),借助一个 I2C Mux 与 SPD EEPROM 进行通信,使用的地址为:
- I2C Mux 地址: 0x75
- I2C Slave 地址: 0b1010001 (0x51)
- SODIMM SA[2:0]: 0b001
{% note info %}
从 Vivado 2019.1 开始,动态 DDR 配置对于所有使用 DIMM DDR 的 Zynq MPSoC / RFSoC 评估板均启用,在使用预置硬件配置时无需额外用户操作。
{% endnote %}
## 根据硬件修改 FSBL
若 I2C 硬件连接不满足上述要求,还可以按照实际连接关系修改 FSBL。FSBL 中使用 I2C 读取 DDR SPD EEPROM 的函数为 `u32 XFsbl_IicReadSpdEeprom(u8 *SpdData)`。
``` c xfsbl_ddr_init.c
u32 XFsbl_DdrInit(void)
{
// ...
/* Get the Model Part Number from the SPD stored in EEPROM */
Status = XFsbl_IicReadSpdEeprom(SpdData);
if (Status != XFSBL_SUCCESS) {
Status = XFSBL_FAILURE;
goto END;
}
// ...
}
```
下面对函数进行拆解,结合注释可以更好理解操作的过程。
### 初始化 I2C 控制器
首先对 I2C 控制器 I2C1 进行初始化。值得一提的是,从 Vivado / Vitis 2023.2 版本开始,对设备进行寻址时,不再依赖于设备的 Device ID,而是直接使用基地址 Base Address,少了从 Device ID 到 Base Address 这一步操作,从开发的角度来看更为合理了。
{% note info %}
若设计使用了 I2C 控制器 I2C0,则可以改为使用基地址 `XPAR_I2C0_BASEADDR` 或 Device ID `XPAR_PSU_I2C_0_DEVICE_ID` 来寻找设备。
{% endnote %}
``` c xfsbl_ddr_init.c
static u32 XFsbl_IicReadSpdEeprom(u8 *SpdData)
{
// ...
/* Lookup for I2C-1U device */
#ifdef SDT
ConfigIic = XIicPs_LookupConfig(XPAR_I2C1_BASEADDR);
#else
ConfigIic = XIicPs_LookupConfig(XPAR_PSU_I2C_1_DEVICE_ID);
#endif
if (!ConfigIic) {
UStatus = XFSBL_FAILURE;
goto END;
}
/* Initialize the I2C device */
Status = XIicPs_CfgInitialize(&IicInstance, ConfigIic,
ConfigIic->BaseAddress);
if (Status != XST_SUCCESS) {
UStatus = XFSBL_FAILURE;
goto END;
}
/* Set the Serial Clock for I2C */
Status = XIicPs_SetSClk(&IicInstance, XFSBL_IIC_SCLK_RATE);
if (Status != XST_SUCCESS) {
UStatus = XFSBL_FAILURE;
goto END;
}
// ...
}
```
### 选择 I2C Mux 的 Slave
由于开发板搭载了较多 I2C 外设,而 Zynq MPSoC / RFSoC 的 I2C 控制器数量有限,因此需要通过 I2C Mux 来扩展所连 I2C Slave 的数量。
本板卡 I2C1 原理图如[图 3](#图3),所用 I2C Mux 的型号为 TCA9548A,其地址配置方式如[图 4](#图4),Slave 选择方式如[图 5](#图5),这里均和评估板保持一致,因此可以与自动生成的 FSBL 兼容。
结合[图 3](#图3) 和[图 4](#图4) 可知 I2C Mux 的地址为 `0x75`,从[图 3](#图3) 中可知 PS DDR4 SODIMM 的 I2C 连接在了第 3 号 Slave 的位置,因此按照[图 5](#图5) 需要将 B3 置 1,也即需要向地址为 `0x75` 的 I2C Mux TCA9548A 的控制寄存器中写入 `0x08`。
<a id="图3"></a>
![图 3. I2C Mux 原理图](../images/post/2024-06-27-zynq-mpsoc-ddr-spd/2024-06-27-zynq-mpsoc-ddr-spd-030-I2C1Schematic.png)
<a id="图4"></a>
![图 4. TCA9548A 地址配置](../images/post/2024-06-27-zynq-mpsoc-ddr-spd/2024-06-27-zynq-mpsoc-ddr-spd-040-tca9548aAddress.png){width=600px}
<a id="图5"></a>
![图 5. TCA9548A Slave选择](../images/post/2024-06-27-zynq-mpsoc-ddr-spd/2024-06-27-zynq-mpsoc-ddr-spd-050-tca9548aConfig.png){width=1000px}
按照上述分析,下面的代码就不难理解了,首先向地址为 `XFSBL_MUX_ADDR`(默认为 `0x75`)的 I2C Mux 写入选通配置 `0x08`,然后从同样的地址回读,验证配置是否正确。
{% note info %}
- 若设计中没有使用到 I2C Mux,而是直接将 I2C 控制器连接到了 DIMM,则可以删去这部分代码;
- 若设计中 I2C Mux 地址不同,则可以修改 `XFSBL_MUX_ADDR` 的宏定义;
- 若设计中 I2C Mux 连接的 Slave 不同,可以修改 I2C 发送的 `TxArray`。
{% endnote %}
``` c xfsbl_ddr_init.c
static u32 XFsbl_IicReadSpdEeprom(u8 *SpdData)
{
// ...
/*
* Configure I2C Mux to select DDR4 SODIMM Slave
* 0x08U - Enable DDR4 SODIMM module
*/
TxArray = 0x08U;
XIicPs_MasterSendPolled(&IicInstance, &TxArray, 1U, XFSBL_MUX_ADDR);
/*
* Wait until bus is idle to start another transfer.
*/
Status = Xil_WaitForEvent(IicInstance.Config.BaseAddress +
XIICPS_SR_OFFSET, XIICPS_SR_BA_MASK, 0U, XFSBL_IIC_BUS_TIMEOUT);
if (Status != XST_SUCCESS) {
UStatus = XFSBL_FAILURE;
goto END;
}
/*
* Get Configuration to confirm the selection of the slave
* device.
*/
Status = XIicPs_MasterRecvPolled(&IicInstance, SpdData, 1U,
XFSBL_MUX_ADDR);
if (Status != XST_SUCCESS) {
UStatus = XFSBL_FAILURE;
goto END;
}
/*
* Wait until bus is idle to start another transfer.
*/
Status = Xil_WaitForEvent(IicInstance.Config.BaseAddress +
XIICPS_SR_OFFSET, XIICPS_SR_BA_MASK, 0U, XFSBL_IIC_BUS_TIMEOUT);
if (Status != XST_SUCCESS) {
UStatus = XFSBL_FAILURE;
goto END;
}
// ...
}
```
### 读取 EEPROM 的第一页
配置完 I2C Mux 后,即可开始读取 SPD EEPROM 中的内容了。[图 6](#图6) 给出了 EEPROM 支持的指令表,由于 EEPROM 一次读的最大长度为一页,也即一个 Page,因此需要分两次对其中的两个 Page 进行读取。
<a id="图6"></a>
![图 6. DDR4 SPD EEPROM 指令表](../images/post/2024-06-27-zynq-mpsoc-ddr-spd/2024-06-27-zynq-mpsoc-ddr-spd-060-DDR4SPDAddress.png){width=800px}
首先设置 Page Address 为 0,也即向地址 `0x36` 中写入 `0x00`,表示从 Page 0 中进行读取,一次读取 256 Byte。
{% note info %}
通常 SPD EEPROM 的 Page 选择地址是固定的,如果 Page Address 0 的地址有变更,修改 `XFSBL_SODIMM_CONTROL_ADDR_LOW` 的宏定义即可。
{% endnote %}
``` c xfsbl_ddr_init.c
static u32 XFsbl_IicReadSpdEeprom(u8 *SpdData)
{
// ...
/*
* Set SODIMM control address to enable access to lower
* EEPROM page (0U to 255U Bytes).
* 0x00U - Enable Read of Lower Page from EEPROM
*/
TxArray = 0x00U;
XIicPs_MasterSendPolled(&IicInstance, &TxArray, 1U,
XFSBL_SODIMM_CONTROL_ADDR_LOW);
/*
* Wait until bus is idle to start another transfer.
*/
Status = Xil_WaitForEvent(IicInstance.Config.BaseAddress +
XIICPS_SR_OFFSET, XIICPS_SR_BA_MASK, 0U, XFSBL_IIC_BUS_TIMEOUT);
if (Status != XST_SUCCESS) {
UStatus = XFSBL_FAILURE;
goto END;
}
/*
* Configure SODIMM Slave address to select starting address of the
* read bytes.
* 0x00U - Set starting byte address of read Lowe Page from EEPROM
* This will result in to starting address of 0x149U (0x100U + 0x49U) in
* the EEPROM.
*/
TxArray = 0x00U;
XIicPs_MasterSendPolled(&IicInstance, &TxArray, 1U,
XFSBL_SODIMM_SLAVE_ADDR);
/*
* Wait until bus is idle to start another transfer.
*/
Status = Xil_WaitForEvent(IicInstance.Config.BaseAddress +
XIICPS_SR_OFFSET, XIICPS_SR_BA_MASK, 0U, XFSBL_IIC_BUS_TIMEOUT);
if (Status != XST_SUCCESS) {
UStatus = XFSBL_FAILURE;
goto END;
}
/*
* Receive the Data of 256U Bytes from SPD EEPROM via I2C.
*/
Status = XIicPs_MasterRecvPolled(&IicInstance, SpdData, 256U,
XFSBL_SODIMM_SLAVE_ADDR);
if (Status != XST_SUCCESS) {
UStatus = XFSBL_FAILURE;
goto END;
}
/*
* Wait until bus is idle.
*/
Status = Xil_WaitForEvent(IicInstance.Config.BaseAddress +
XIICPS_SR_OFFSET, XIICPS_SR_BA_MASK, 0U, XFSBL_IIC_BUS_TIMEOUT);
if (Status != XST_SUCCESS) {
UStatus = XFSBL_FAILURE;
goto END;
}
// ...
}
```
### 读取 EEPROM 的第二页
然后设置 Page Address 为 1,也即向地址 `0x37` 中写入 `0x00`,表示从 Page 0 中进行读取,一次读取 256 Byte。
{% note info %}
通常 SPD EEPROM 的 Page 选择地址是固定的,如果 Page Address 1 的地址有变更,修改 `XFSBL_SODIMM_CONTROL_ADDR_HIGH` 的宏定义即可。
{% endnote %}
``` c xfsbl_ddr_init.c
static u32 XFsbl_IicReadSpdEeprom(u8 *SpdData)
{
// ...
/*
* Set SODIMM control address to enable access to upper
* EEPROM page (256U to 511U Bytes).
* 0x01U - Enable Read of Upper Page from EEPROM
*/
TxArray = 0x01U;
XIicPs_MasterSendPolled(&IicInstance, &TxArray, 1U,
XFSBL_SODIMM_CONTROL_ADDR_HIGH);
/*
* Wait until bus is idle to start another transfer.
*/
Status = Xil_WaitForEvent(IicInstance.Config.BaseAddress +
XIICPS_SR_OFFSET, XIICPS_SR_BA_MASK, 0U, XFSBL_IIC_BUS_TIMEOUT);
if (Status != XST_SUCCESS) {
UStatus = XFSBL_FAILURE;
goto END;
}
/*
* Configure SODIMM Slave address to select starting address of the
* read bytes.
* 0x00U - Set starting byte address of read Upper Page from EEPROM
* This will result in to starting address of 0x149U (0x100U + 0x49U) in
* the EEPROM.
*/
TxArray = 0x00U;
XIicPs_MasterSendPolled(&IicInstance, &TxArray, 1U,
XFSBL_SODIMM_SLAVE_ADDR);
/*
* Wait until bus is idle to start another transfer.
*/
Status = Xil_WaitForEvent(IicInstance.Config.BaseAddress +
XIICPS_SR_OFFSET, XIICPS_SR_BA_MASK, 0U, XFSBL_IIC_BUS_TIMEOUT);
if (Status != XST_SUCCESS) {
UStatus = XFSBL_FAILURE;
goto END;
}
/*
* Receive the Data of 256U Bytes from SPD EEPROM via I2C.
*/
Status = XIicPs_MasterRecvPolled(&IicInstance, &SpdData[256U], 256U,
XFSBL_SODIMM_SLAVE_ADDR);
if (Status != XST_SUCCESS) {
UStatus = XFSBL_FAILURE;
goto END;
}
/*
* Wait until bus is idle.
*/
Status = Xil_WaitForEvent(IicInstance.Config.BaseAddress +
XIICPS_SR_OFFSET, XIICPS_SR_BA_MASK, 0U, XFSBL_IIC_BUS_TIMEOUT);
if (Status != XST_SUCCESS) {
UStatus = XFSBL_FAILURE;
goto END;
}
// ...
}
```
# 调试
配置完成后可以实测了,这里对 FSBL 进行 Debug,观察整个读写的过程。在单独调试 FSBL 的时候,可以不勾选“Program FPGA”和“Initialize using FSBL”,如[图 7](#图7)。
<a id="图7"></a>
![图 7. Debug 配置](../images/post/2024-06-27-zynq-mpsoc-ddr-spd/2024-06-27-zynq-mpsoc-ddr-spd-070-DebugConfig.png)
将断点设置在函数 `XFsbl_IicReadSpdEeprom()` 被调用的地方。
<a id="图8"></a>
![图 8. `XFsbl_IicReadSpdEeprom()` 函数断点](../images/post/2024-06-27-zynq-mpsoc-ddr-spd/2024-06-27-zynq-mpsoc-ddr-spd-080-Breakpoint.png)
观察 I2C Mux 回读的数据。回读的数据存储在 `SpdData` 数组中,可以观察到数组的第 0 个字节为 `0x08`,与写入的数据一致。
<a id="图9"></a>
![图 9. I2C Mux 回读](../images/post/2024-06-27-zynq-mpsoc-ddr-spd/2024-06-27-zynq-mpsoc-ddr-spd-090-IICMuxRead.png)
然后观察 I2C EEPROM 回读的数据,并与 Micron 给出的 [MTA4ATF51264HZ-2G6E1 的 SPD 数据][]进行对比,可以观察到数据是一致的。
<a id="图10"></a>
![图 10. I2C EEPROM 回读](../images/post/2024-06-27-zynq-mpsoc-ddr-spd/2024-06-27-zynq-mpsoc-ddr-spd-100-IICEEPROMRead.png)
最后,`XFsbl_DdrInit()` 函数的剩余部分会完成 DDR 参数的解析与 DDR 控制器的初始化。
# 参考文档
[75768 - Zynq MPSoC Dynamic DDR Configuration Support for DIMM Devices](https://support.xilinx.com/s/article/75768)
[SPD I2c Address for DDR4 SODIMM](https://electronics.stackexchange.com/questions/554703/spd-i2c-address-for-ddr4-sodimm)
[MTA4ATF51264HZ-2G6E1 的 SPD 数据]: https://www.micron.com/products/memory/dram-modules/sodimm/part-catalog/part-detail/spd-data/mta4atf51264hz-2g6e1
+653
View File
@@ -0,0 +1,653 @@
---
title: Josh's Note — 凸优化<br>Part 2.2 凸函数—保凸运算
mathjax: true
comments: true
copyright: true
toc:
enable: true
number: false
wrap: true
expand_all: true
max_depth: 4
categories:
- - Josh 的学习笔记
- 凸优化
- 凸函数
- - 数学
- 凸优化
tags:
- 凸优化
- 凸函数
- 保凸运算
abbrlink: c3476904
date: 2024-07-03 23:04:33
---
$
\newcommand{\dd}{\mathrm{d}}
\newcommand{\TT}{\mathrm{T}}
\def\diag{\mathop{\bf diag}}
\def\dist{\mathop{\bf dist}}
\def\dom{\mathop{\bf dom}}
\def\epi{\mathop{\bf epi}}
$&emsp;&emsp;本文讨论几种保持函数凸性或者凹性的运算,这样可以构造新的凸函数或者凹函数。首先从一些简单的运算开始,如求和、伸缩以及逐点上确界,之后再介绍一些更为复杂的运算(其中一些运算的特例即为简单运算)。
# 1. 非负加权求和
&emsp;&emsp;显然,若函数 $f$ 是凸函数且 $\alpha\geqslant0$,则函数 $\alpha f$ 也是凸函数。若函数 $f_1$ 和 $f_2$ 都是凸函数,则它们的和 $f_1+f_2$ 也是凸函数。将非负伸缩以及求和运算结合起来,可以看出,凸函数的集合本身是一个凸锥:凸函数的非负加权求和仍然是凸函数,即函数
$$
f=w_1f_1+\cdots+w_mf_m
$$
是凸函数。类似地,凹函数的非负加权求和仍然是凹函数。严格凸(凹)函数的非负,非零加权求和是严格凸(凹)函数。
&emsp;&emsp;这个性质可以扩展至无限项的求和以及积分的情形。例如,若对于每一个 $y\in\mathcal{A}$,函数 $f(x,y)$ 关于 $x$ 都是凸函数,且 $w(y)\geqslant 0$,则函数
$$
g(x)=\int_{\mathcal{A}}w(y)f(x,y)\dd y
$$
关于 $x$是凸函数(若此积分存在)。
<!-- more -->
&emsp;&emsp;容易验证非负伸缩以及求和运算是保凸运算,或者可以根据相关的上境图得到此结论。例如,若 $w\geqslant 0$ 且 $f$ 是凸函数,则有
$$
\epi (wf)=\left[\begin{array}{cc}
I&0\\
0&w
\end{array}\right]\epi f
$$
因为凸集通过线性变换得到的像仍然是凸集,所以 $\epi(wf)$ 是凸集。
{% note info 注解 %}
这里对上镜图的相关结论进行解释。函数 $f:\mathbf{R}^{n}\to\mathbf{R}$ 的上镜图定义为
$$
\epi f=\{(x,t)\mid f(x)\leqslant t\}
$$
则有
$$\begin{aligned}
\left[\begin{array}{cc}
I&0\\
0&w
\end{array}\right]\epi f&=\left\{\left[\begin{array}{cc}
I&0\\
0&w
\end{array}\right](x,t)\:\middle|\: f(x)\leqslant t\right\}
\\
&= \{(x,wt)\mid f(x)\leqslant t\}
\\
&= \{(x,t)\mid wf(x)\leqslant t\}
\\
&= \epi (wf)
\end{aligned}
$$
{% endnote %}
# 2. 复合仿射映射
&emsp;&emsp;假设函数 $f:\mathbf{R}^n\to\mathbf{R}$,$A\in\mathbf{R}^{n\times m}$,$b\in\mathbf{R}^n$,定义**复合仿射映射**(*composition with an affine mapping*)$ g:\mathbf{R}^m\to\mathbf{R}$ 为
$$
g(x)=f(Ax+b)
$$
其中 $\dom g=\{x\mid Ax+b\in\dom f\}$。若函数 $f$ 是凸函数,则函数 $g$ 是凸函数;若函数 $f$ 是凹函数,则函数 $g$ 是凹函数。
# 3. 逐点最大和逐点上确界
## 3.1 逐点最大
&emsp;&emsp;若函数 $f_{1}$ 和 $f_{2}$ 均为凸函数,则二者的**逐点最大**(*pointwise maximum*)函数
$$
f(x)=\max\{f_1(x),f_2(x)\}
$$
其定义域为 $\dom f=\dom f_1\cap\dom f_2$,仍然是凸函数。这个性质很容易验证:任取 $0\leqslant \theta \leqslant 1$ 以及 $x,y\in\dom f$,有
$$\begin{aligned}
f(\theta x+(1-\theta)y)&=\max\{f_1(\theta x+(1-\theta)y),f_2(\theta x+(1-\theta)y)\}
\\
&\leqslant\max\{\theta f_1(x)+(1-\theta)f_1(y),\theta f_2(x)+(1-\theta)f_2(y)\}
\\
&\leqslant\theta\max\{f_1(x),f_2(x)\}+(1-\theta)\max\{f_1(y),f_2(y)\}
\\
&=\theta f(x)+(1-\theta)f(y)
\end{aligned}$$
从而得到了函数 $f$ 的凸性。同样很容易证明,若函数 $f_1,\cdots,f_m$ 为凸函数,则它们的逐点最大函数
$$
f(x)=\max\{f_1(x),\cdots,f_m(x)\}
$$
仍然是凸函数。
> **举例**&emsp;**分段线性函数**(*Piecewise-linear functions*)。函数
>
> $$
> f(x)=\max\left\{a_1^\TT x+b_1,\cdots,a_L^\TT x+b_L\right\}
> $$
>
> 定义了一个(具有不大于 $L$ 个子区域的)分段线性函数(实际上是仿射函数)。因为它是一系列仿射函数的逐点最大函数,所以它是凸函数。反之亦成立:任意具有不大于 $L$ 个子区域的分段线性凸函数都可以表述成上述形式。
>
> {% note info 注解 %}
> 参考 Wikipedia,[分段线性函数词条](https://en.wikipedia.org/wiki/Piecewise_linear_function)即为我们通常理解的分段函数,但是这里的分段线性函数有所不同,定义为多个分段函数的逐点最大,因此数凸的。
>
> 关于子区域数量,可以这样理解:若 $L$ 个仿射函数相邻两段各不相同,则每一段仿射函数均对应着一个子区域,因此最多共有 $L$ 个子区域。
> {% endnote %}
> **举例**&emsp;**最大 $r$ 个分量之和**。对于任意 $x\in\mathbf{R}^n$,用 $x_{[i]}$ 表示 $x$ 中第 $i$ 大的分量,将 $x$ 的分量按照非升序进行排列
>
> $$
> x_{[1]}\geqslant x_{[2]}\geqslant\cdots\geqslant x_{[n]}
> $$
>
> 则对 $x$ 的最大 $r$ 个分量进行求和所得到的函数
>
> $$
> f(x)=\sum_{i=1}^rx_{[i]}
> $$
>
> 是凸函数。事实上,此函数可以表述为
>
> $$
> f(x)=\sum_{i=1}^rx_{[i]}=\max\{x_{i_1}+\cdots+x_{i_r}\mid1\leqslant i_1<i_2<\cdots<i_r\leqslant n\}
> $$
>
> 即从 $x$ 的分量中选取 $r$ 个不同分量进行求和的所有可能组合的最大值。因为函数 $f$ 是 $\displaystyle\frac{n!}{r!(n-r)!}$ 个线性函数的逐点最大,所以是凸函数。
>
> 进一步可以证明,当 $w_1\geqslant w_2\geqslant\cdots\geqslant w_r\geqslant 0$ 时,函数 $\displaystyle\sum_{i=1}^rw_ix_{[i]}$ 是凸函数。
## 3.2 逐点上确界
&emsp;&emsp;逐点最大的性质可以扩展至无限个凸函数的**逐点上确界**(*pointwise supremum*)。
{% note info 上确界和下确界 %}
&emsp;&emsp;假定 $C\subseteq\mathbf{R}$。若对每个 $x\in C$ 均有 $x\leqslant a$,则称 $a$ 是 $C$ 的**上界**(*upper bound*)。$C$ 的上界组成的集合或是空集(此时称 $C$ 无上界),或等于 $\mathbf{R}$(仅当 $C=\emptyset$ 时),或是闭的无限区间 $[b,\infty)$。称 $b$ 为 $C$ 的**最小上界**(*least upper bound*)或**上确界**(*supremum*),用 $\sup C$ 表示。规定 $\sup\emptyset=-\infty$,当 $C$ 无上界时取 $\sup C=\infty$。当 $\sup C\in C$ 时,称 $C$ 的上确界是可达的。
&emsp;&emsp;当 $C$ 是有限集时,$\sup C$ 是它所有元素的最大值。一些作者用符号 $\max C$ 表示可达的上确界,但我们采用标准的数学习惯,只在 $C$ 是有限集时用 $\max C$。
&emsp;&emsp;类似地,可以定义下界和下确界。若对每个 $x\in C$ 均有 $a\leqslant x$,则称 $a$ 是 $C\subseteq\mathbf{R}$ 的下界。$C\subseteq\mathbf{R}$ 的**下确界**(*infimum*)或**最大下界**(*greatest lower bound*)定义为 $\inf C=-\sup(-C)$。当 $C$ 是有限集时,下确界是它所有元素的最小值。规定 $\inf\emptyset=\infty$,并在 $C$ 无下界时,取 $\inf C=-\infty$。
{% endnote %}
&emsp;&emsp;若对于任意 $y\in\mathcal{A}$,函数 $f(x,y)$ 关于 $x$ 都是凸的,则函数
$$\begin{equation}\label{PointwiseMaximum}
g(x)=\sup_{y\in\mathcal{A}}f(x,y)
\end{equation}$$
关于 $x$ 亦是凸的。此时,函数 $g$ 的定义域为
$$
\dom g=\{x\mid(x,y)\in\dom f\:\forall y\in\mathcal{A},\sup_{y\in\mathcal{A}}f(x,y)<\infty\}
$$
类似地,一系列凹函数的逐点下确界仍然是凹函数。
&emsp;&emsp;从上境图的角度理解,一系列函数的逐点上确界函数对应着这些函数上境图的交集:对于函数 $f$,$g$ 以及式 $\eqref{PointwiseMaximum}$ 定义的 $\mathcal{A}$,有
$$
\epi g=\bigcap_{y\in\mathcal{A}}\epi f(\:\cdot\:,y)
$$
因此,函数 $g$ 的凸性可由一系列凸集的交集仍然是凸集得到。
> **举例**&emsp;**集合的支撑函数**。令集合 $C\subseteq\mathbf{R}^n$,且 $C\neq\emptyset$,定义集合 $C$ 的**支撑函数**(*support function*)$S_C$ 为
>
> $$
> S_C(x)=\sup\{x^\TT y\mid y\in C\}
> $$
>
> (自然地,函数 $S_C$ 的定义域为 $\dom S_{C}=\left\{x\mid\sup_{y\in C}x^\TT y<\infty\right\}$)。
>
> 对于任意 $y\in C$,$x^\TT y$ 是 $x$ 的线性函数,所以 $S_{C}$ 是一系列线性函数的逐点上确界函数,因此是凸函数。
> **举例**&emsp;**到集合中最远点的距离**。令集合 $C\subseteq\mathbf{R}^n$,定义点 $x$ 与集合中最远点的距离(范数)为
>
> $$
> f(x)=\sup_{y\in C}\|x-y\|
> $$
>
> 此函数是凸函数。为了说明这一点,我们注意到,对于任意 $y$,函数 $\|x-y\|$ 关于 $x$ 是凸函数。因为函数 $f$ 是一族凸函数(对应不同的 $y\in C$)的逐点上确界,所以是凸函数。
> **举例**&emsp;**以权为变量的最小二乘代价函数**。令 $a_1,\cdots,a_n\in\mathbf{R}^m$,在加权最小二乘问题中我们对所有的 $x\in\mathbf{R}^m$ 极小化目标函数 $\displaystyle\sum_{i=1}^nw_i(a_i^\TT x-b_i)^2$。我们称 $w_i$ 为**权**(*weight*),并允许 $w_i$ 为负(则目标函数有可能无下界)。
>
> 定义(最优)**加权最小二乘代价**(*weighted least-squares cost*)函数为
>
> $$
> g(w)=\inf_{x}\sum_{i=1}^{n}w_{i}(a_{i}^{\TT}x-b_{i})^{2}
> $$
>
> 其定义域为
>
> $$\dom g=\left\{w\,\middle|\,\inf_{x}\sum_{i=1}^{n}w_{i}(a_{i}^{\TT}x-b_{i})^{2}>-\infty\right\}$$
>
> 因为函数 $g$ 是一族关于 $w$ 的线性函数的下确界(对应于不同的 $x\in\mathbf{R}^m$),它是 $w$ 的凹函数。
>
> 至少在部分定义域上,我们可以得到函数 $g$ 的一个显式表达式。令 $W=\diag(w)$ 是一对角阵,其对角线元素为 $w_1,\cdots,w_n$,令 $A\in\mathbf{R}^{n\times m}$,其行向量为 $a_i^\TT$,有
>
> $$
> g(w)=\inf_{x}(Ax-b)^{\TT}W(Ax-b)=\inf_{x}(x^{\TT}A^{\TT}WAx-2b^{\TT}WAx+b^{\TT}Wb)
> $$
>
> 从上式可以看出,若 $A^{\TT}WA\not\succeq0$,括号里的二次函数关于 $x$ 无下界,故 $g(w)=-\infty$,即 $w\not\in\dom g$。当 $A^\TT WA\succ0$ 时(即定义了一个严格的线性矩阵不等式),通过解析求解二次函数的极小值,可以得到函数 $g$ 的一个简单的表达式
>
> $$\begin{aligned}
> g(w)&=b^{\TT}Wb-b^{\TT}WA(A^{\TT}WA)^{-1}A^{\TT}Wb
> \\
> &=\sum_{i=1}^{n}w_{i}b_{i}^{2}-\sum_{i=1}^{n}w_{i}^{2}b_{i}^{2}a_{i}^{\TT}\left(\sum_{j=1}^{n}w_{j}a_{j}a_{j}^{\TT}\right)^{-1}a_{i}
> \end{aligned}$$
>
> 从上述表达式并不能立即得到函数 $g$ 的凹性(不过可以从矩阵分式函数的凸性来推导函数 $g$ 的凹性)。
> **举例**&emsp;**对称矩阵的最大特征值**。 定义函数 $f(X)=\lambda_{\max}(X)$,其定义域为 $\dom f=\mathbf{S}^m$,它是凸函数。为了说明这一点,我们将 $f$ 表述为
>
> $$
> f(X)=\sup\{y^\TT Xy\mid\|y\|_2=1\}
> $$
>
> 即针对不同的 $y\in\mathbf{R}^m$ 关于 $X$ 的一族线性函数(即$y^\TT Xy$)的逐点上确界。
> **举例**&emsp;**矩阵范数**。考虑函数 $f(X)=\|X\|_2$,其定义域为 $\dom f=\mathbf{R}^{p\times q}$,其中 $\|\cdot\|_2$ 表示谱范数或者最大奇异值。函数 $f$ 可以表述为
>
> $$
> f(X)=\sup\{u^{\TT}Xv\mid\|u\|_{2}=1,\|v\|_{2}=1\}
> $$
>
> 由于它是 $X$ 的一族线性函数的逐点上确界,所以是凸函数。
>
> 作为一个推广,假设 $\|\cdot\|_a$和$\|\cdot\|_b$ 分别是 $\mathbf{R}^p$ 和 $\mathbf{R}^q$ 上的范数,定义矩阵 $X\in\mathbf{R}^{p\times q}$ 的诱导范数为
>
> $$
> \|X\|_{a,b}=\sup_{v\neq0}\frac{\|Xv\|_{a}}{\|v\|_{b}}
> $$
## 3.3 表示成一族仿射函数的逐点上确界
&emsp;&emsp;上述例子描述了一个建立函数凸性的好方法:将函数表示为一族仿射函数的逐点上确界。除了一个技术条件,反过来也是成立的:几乎所有的凸函数都可以表示成一族仿射函数的逐点上确界。例如,若函数 $f:\mathbf{R}^n\to\mathbf{R}$ 是凸函数,其定义域为 $\dom f=\mathbf{R}^n$,我们有
$$
f(x)=\sup\{g(x)\mid g\:\text{仿射},\:g(z)\leqslant f(z)\:\forall z\}
$$
换言之,函数 $f$ 是它所有的仿射全局下估计的逐点上确界。下面我们将证明这个结论。
&emsp;&emsp;设函数 $f$ 是凸函数,定义域为 $\dom f=\mathbf{R}^{n}$ ,显然下面的不等式成立
$$
f ( x ) \geqslant \sup \{g ( x ) \mid g\:\text{仿射}, \ g ( z ) \leqslant f ( z ) \ \forall z \},
$$
因为函数 $g$ 是函数 $f$ 的任意仿射下估计,我们有 $g ( x ) \leqslant f ( x )$。为了建立等式,我们说明,对于任意 $x \in\mathbf{R}^{n}$,存在仿射函数 $g$ 是函数 $f$ 的全局下估计,并且满足 $g ( x )=f ( x )$。
&emsp;&emsp;毫无疑问,函数 $f$ 的上境图是凸集,因此我们在点 $( x, f ( x ) )$ 处可以找到此凸集的支撑超平面,即存在 $a \in\mathbf{R}^{n}$,$\; b \in\mathbf{R}$ 且 $( a, b ) \neq0$,使得对任意 $( z, t ) \in\epi f$,有
$$
\left[ \begin{array} {c} a \\ b \\ \end{array} \right]^{\TT} \left[ \begin{array} {c} {x-z} \\ {f ( x )-t} \\ \end{array} \right] \leqslant0.
$$
即对任意 $z\in\dom f=\mathbf{R}^n$ 以及所有 $s\geqslant0$($(z,t)\in\epi f$ 等价于存在 $s\geqslant0$ 使得 $t=f(z)+s$),下式成立
$$\begin{equation}\label{ProofOfAffineFunctionRepresentation}
a^\TT(x-z)+b(f(x)-f(z)-s)\leqslant0
\end{equation}
$$
为了保证不等式 $\eqref{ProofOfAffineFunctionRepresentation}$ 对所有的 $s\geqslant0$ 均成立,必须有 $b\geqslant0$。若 $b=0$,对所有的$z\in\mathbf{R}^n$,不等式 $\eqref{ProofOfAffineFunctionRepresentation}$ 可以简化为 $a^\TT(x-z)\leqslant0$,这意味着 $a=0$,于是和假设 $(a,b)\neq0$ 矛盾。因此 $b>0$,即支撑超平面不是竖直的。
&emsp;&emsp;我们知道 $b>0$,因此,对任意 $z$,令 $s=0$,式 $\eqref{ProofOfAffineFunctionRepresentation}$ 可以重新表述为
$$
g(z)=f(x)+(a/b)^{\TT}(x-z)\leqslant f(z)
$$
由此说明函数 $g$ 是函数 $f$ 的一个仿射下估计,并且满足 $g(x)=f(x)$。
# 4. 复合
&emsp;&emsp;本节给定函数 $h:\mathbf{R}^k\to\mathbf{R}$ 以及 $g:\mathbf{R}^n\to\mathbf{R}^k$,定义复合函数 $f=h\circ g:\mathbf{R}^n\to\mathbf{R}$ 为
$$
f(x)=h(g(x)),\quad\dom f=\{x\in\dom g\mid g(x)\in\dom h\}
$$
我们考虑当函数 $f$ 保凸或者保凹时,函数 $h$ 和 $g$ 必须满足的条件。
## 4.1 标量复合
&emsp;&emsp;首先考虑 $k=1$ 的情况,即 $h:\mathbf{R}\to\mathbf{R}$,$g:\mathbf{R}^n\to\mathbf{R}$。仅考虑 $n=1$ 的情况(事实上,将函数限定在与其定义域相交的任意直线上得到的函数决定了原函数的凸性)。
&emsp;&emsp;为了找出复合规律,首先假设函数 $h$ 和 $g$ 是二次可微的,且 $\dom g= \dom h= \mathbf{R}$。在上述假设下,函数 $f$ 是凸的等价于 $f^{\prime\prime}\geqslant 0$(即对所有的 $x\in\mathbf{R}$,$f^{\prime\prime}(x)\geqslant 0$)。
&emsp;&emsp;复合函数 $f=h\circ g$ 的二阶导数为
$$\begin{equation}\label{SecondDerivativeOfScalarCompositionFunction}
f''(x)=h''(g(x))g'(x)^2+h'(g(x))g''(x)
\end{equation}$$
假设函数 $g$ 是凸函数($g^{\prime\prime}\geqslant 0$),函数 $h$ 是凸函数且非减(即$h^{\prime\prime}\geqslant0$ 且 $h^{\prime}\geqslant0$),从式 $\eqref{SecondDerivativeOfScalarCompositionFunction}$ 可以得出 $f^{\prime\prime}\geqslant 0$,即函数 $f$ 是凸函数。类似地,由式 $\eqref{SecondDerivativeOfScalarCompositionFunction}$ 可以得出如下结论
$$\begin{equation}\label{Conclusion1}\begin{aligned}
若\,h\,是凸函数且非减,g\,是凸函数,则\,f\,是凸函数,\\
若\,h\,是凸函数且非增,g\,是凹函数,则\,f\,是凸函数,\\
若\,h\,是凹函数且非减,g\,是凹函数,则\,f\,是凹函数,\\
若\,h\,是凹函数且非增,g\,是凸函数,则\,f\,是凹函数。
\end{aligned}\end{equation}$$
上述结论在函数 $g$ 和 $h$ 二次可微且定义域均为 $\mathbf{R}$ 时成立。事实上,对于更一般的情况,如 $n>1$,不再假设函数 $h$ 和 $g$ 可微或者 $\dom g=\mathbf{R}^n$,$\dom h=\mathbf{R}$,一些相似的复合规则仍然成立
$$\begin{equation}\label{Conclusion2}\begin{aligned}
若\,h\,是凸函数且\,\tilde{h}\,非减,\,g\,是凸函数,则\,f\,是凸函数,\\
若\,h\,是凸函数且\,\tilde{h}\,非增,\,g\,是凹函数,则\,f\,是凸函数,\\
若\,h\,是凹函数且\,\tilde{h}\,非减,\,g\,是凹函数,则\,f\,是凹函数,\\
若\,h\,是凹函数且\,\tilde{h}\,非增,\,g\,是凸函数,则\,f\,是凹函数。
\end{aligned}\end{equation}$$
其中,$\tilde{h}$ 表示函数 $h$ 的扩展值延伸,若点不在 $\dom h$ 内,对其赋值 $\infty$(若 $h$ 是凸函数)或者$-\infty$(若 $h$ 是凹函数)。这些结论和式 $\eqref{Conclusion1}$ 中的结论的唯一不同是我们要求**扩展值延伸**(*extended-value extension*)$\tilde{h}$ 在整个 $\mathbf{R}$ 上非增或者非减。
&emsp;&emsp;为了更好地理解式 $\eqref{Conclusion2}$ 中的结论,假设 $h$ 是凸函数,所以 $\tilde{h}$ 在定义域 $\dom h$ 外取值为 $\infty$。$\tilde{h}$ 非减意味着对于任意 $x,y\in\mathbf{R}$,$x<y$,有 $\tilde{h}(x)\leqslant\tilde{h}(y)$。特别地,若 $y\in\dom h$,则 $x\in\dom h$。换言之,我们可以认为 $h$ 的定义域在负方向上无限延伸。它或者是 $\mathbf{R}$ 或者是形如 $(-\infty,a)$ 或 $\left(-\infty,a\right]$ 的区间。类似地,若 $h$ 是凸函数且 $\tilde{h}$ 非增,我们可以理解为 $h$ 是非增的且 $\dom h$ 在正方向上趋于无穷。[图 7](#图7) 描述了不同的扩展值延伸的情况。
<a id="图7"></a>
![图 7. **左**:函数 $x^2$,其定义域为 $\mathbf{R}_+$,在其定义域内是凸且非减的,但是其扩展值延伸不是非减的。**右**:函数 $\max\{x,0\}^2$,其定义域为 $\mathbf{R}$,函数是凸函数,且其扩展值延伸是非减的。](../images/post/2024-07-03-josh-cvx-2-2/2024-07-03-josh-cvx-2-2-070-ExtendedValueExtension.png){width=700px}
> **举例**&emsp;通过一些简单例子,我们可以更好地理解复合定理中函数 $h$ 需要满足的条件。
>
> - 函数 $h(x)=\log x$:定义域为 $\dom h=\mathbf{R}_{++}$,为凹函数且 $\tilde{h}$ 非减。
> - 函数 $h(x)=x^1/2$:定义域为 $\dom h=\mathbf{R}_+$,为凹函数且 $\tilde{h}$ 非减。
> - 函数 $h(x)=x^{3/2}$:定义域为 $\dom h=\mathbf{R}_+$,为凸函数,但是**不**满足 $\tilde{h}$ 非减的条件。例如,$\tilde{h}(-1)=\infty$ 但 $\tilde{h}(1)=1$。
> - 当 $x\geqslant 0$ 时,$h(x)=x^3/2$,当 $x<0$ 时,$h(x)=0$:定义域为 $\dom h=\mathbf{R}$,$h$ 是凸函数且满足 $\tilde{h}$ 非减的条件。
&emsp;&emsp;即使不假设可微并运用表达式 $\eqref{SecondDerivativeOfScalarCompositionFunction}$,也可以直接证明复合函数结论式 $\eqref{Conclusion2}$。举例来说,我们证明如下结论:若 $g$ 是凸函数,$h$ 是凸函数且 $\tilde{h}$ 非减,则 $f=h\circ g$ 是凸函数。
> **证明**&emsp;假设 $x,y\in\dom f$,$0\leqslant\theta\leqslant1$。由 $x,y\in\dom f$,有 $x,y\in\dom g$ 且 $g( x)$, $g( y) \in \dom h$。因为 $\dom g$ 是凸集,有 $\theta x+(1-\theta)y\in\dom g$,由函数 $g$ 的凸性可得
>
> $$\begin{equation}\label{ConvexityOfFunctionG}
> g(\theta x+(1-\theta)y)\leqslant\theta g(x)+(1-\theta)g(y)
> \end{equation}
> $$
>
> 由 $g(x),g(y)\in\dom h$ 可得 $\theta g(x)+(1-\theta)g(y)\in\dom h$,即式 $\eqref{ConvexityOfFunctionG}$ 的右端在 $\dom h$ 内。根据假设 $\tilde{h}$ 是非减的,可以理解为其定义域在负方向上无限延伸。由式 $\eqref{ConvexityOfFunctionG}$ 的右端在 $\dom h$ 内,我们知道其左侧仍在定义域内,即 $g(\theta x+(1-\theta)y)\in\dom h$,因此 $\dom f$ 是凸集。
>
> 根据前提条件,$\tilde{h}$ 非减,利用不等式 $\eqref{ConvexityOfFunctionG}$,有
>
> $$\begin{equation}\label{NondecreasingOfFunctionH}
> h(g(\theta x+(1-\theta)y))\leqslant h(\theta g(x)+(1-\theta)g(y))
> \end{equation}
> $$
>
> 由函数 $h$ 的凸性可得
>
> $$\begin{equation}\label{ConvexityOfFunctionH}
> h(\theta g(x)+(1-\theta)g(y))\leqslant\theta h(g(x))+(1-\theta)h(g(y))
> \end{equation}
> $$
>
> 综合式 $\eqref{NondecreasingOfFunctionH}$ 和式 $\eqref{ConvexityOfFunctionH}$ 可得
>
> $$
> h(g(\theta x+(1-\theta)y))\leqslant\theta h(g(x))+(1-\theta)h(g(y))
> $$
>
> 复合定理得证。
> **举例**&emsp;**简单的复合结论**。
>
> - 若 $g$ 是凸函数,则 $\exp g(x)$ 是凸函数。
> - 若 $g$ 是凹函数且大于零,则 $\log g(x)$ 是凹函数。
> - 若 $g$ 是凹函数且大于零,则 $1/g(x)$是凸函数。
> - 若 $g$ 是凸函数且不小于零,$p\geqslant1$,则 $g(x)^p$ 是凸函数。
> - 若 $g$ 是凸函数,则 $-\log(-g(x))$ 在 $\{x\mid g(x)<0\}$ 上是凸函数。
> **注释**&emsp;扩展值延伸 $\tilde{h}$ 的单调性要求必须满足,注意到是 $\tilde{h}$,而不仅仅是 $h$。例如,考虑 $g( x) = x^2$,$\dom g = \mathbf{R}$,$h( x) = 0$,$\dom h= [ 1, 2]$ 复合的情形。此时 $g$ 是凸函数,$h$ 是凸函数且非减,但是函数 $f=h\circ g$
>
> $$
> f(x)=0,\quad\dom f=[-\sqrt{2},-1]\:\cup\:[1,\sqrt{2}]
> $$
>
> 不是凸函数,因为其定义域非凸。当然,此时函数 $\tilde{h}$ 不是非减的。
## 4.2 矢量复合
&emsp;&emsp;下面考虑 $k\geqslant1$ 的情况,此时更复杂一些。设
$$
f(x)=h(g(x))=h(g_1(x),\cdots,g_k(x))
$$
其中 $h: \mathbf{R} ^k\to \mathbf{R}$,$g_i: \mathbf{R} ^n\to \mathbf{R}$。和上一节一样,不失一般性,假设 $n=1$。和 $k=1$ 的情形类似,为了得到复合规则,假设函数二次可微,且 $\dom g=$ $\mathbf{R}$,$\dom h= \mathbf{R} ^{k}$。此时,对函数 $f$ 进行二次微分可得
$$\begin{equation}\label{SecondDerivativeOfVectorCompositionFunction}
f''(x)=g'(x)^{\TT}\nabla^2h(g(x))g'(x)+\nabla h(g(x))^{\TT}g''(x)
\end{equation}
$$
上式可以看成式 $\eqref{SecondDerivativeOfScalarCompositionFunction}$ 对应的向量形式。同样我们需要判断在什么条件下对所有 $x$ 有 $f(x)^{\prime\prime}\geqslant0$(或者对所有 $x$ 有 $f(x)^\prime\prime\leqslant 0$,此时 $f$ 是凹函数)。利用式 $\eqref{SecondDerivativeOfVectorCompositionFunction}$,我们可以得到很多规则,例如:
$$\begin{aligned}
若\:h\:是凸函数且在每维分量上\:h\:非减,g_i\:是凸函数,则\:f\:是凸函数;\\
若\:h\:是凸函数且在每维分量上\:h\:非增,g_i\:是凹函数,则\:f\:是凸函数;\\
若\:h\:是凹函数且在每维分量上\:h\:非减,g_i\:是凹函数,则\:f\:是凹函数。
\end{aligned}$$
和标量的情形类似,对于更一般的情况:$n>1$,不假设 $h$ 或 $g$ 可微以及一般的定义域类似的复合结论仍然成立。对于一般的结论,不仅 $h$ 需要满足单调性条件,其扩展值延伸 $\tilde{h}$ 同样必须满足。
&emsp;&emsp;为了更好地理解扩展值延伸 $\tilde{h}$ 必须满足单调性条件的含义,我们考虑凸函数 $h:\mathbf{R}^{k}\to\mathbf{R}$,且 $\tilde{h}$ 非减,即对任意 $u\preceq v$,有 $\tilde{h}(u)\leqslant\tilde{h}(v)$。这说明了若 $v\in\dom h$ 则 $u\in\dom h$,也即 $h$ 的定义域在方向 $-\mathbf{R}_+^k$ 上必须无限延伸。这个条件可以紧凑地描述为 $\dom h-\mathbf{R}_{+}^{k}=\dom h$。
> **举例**&emsp;矢量复合的例子。
>
> - 令 $h(z)=z_[1]+\cdots+z_{[r]}$,即对 $z\in\mathbf{R}^k$ 的前 $r$ 大分量进行求和。则 $h$ 是凸函数且在每一维分量上非减。假设 $g_1,\cdots,g_k$ 是 $\mathbf{R}^n$ 上的凸函数,则复合函数 $f=h\circ g$,即最大 $r\uparrow g_i$ 函数的逐点和,是凸函数。
>
> - 函数 $h(z)=\log\left(\displaystyle\sum_{i=1}^k\mathrm{e}^{z_i}\right)$ 是凸函数且在每一维分量上非减,因此只要 $g_i$ 是凸函数,$\log\left(\displaystyle\sum_{i=1}^{k}\mathrm{e}^{g_{i}}\right)$ 就是凸函数。
>
> - 对 $0<p\leqslant 1$,定义在 $\mathbf{R}_+^k$ 上的函数 $h(z)=\left(\displaystyle\sum_{i=1}^kz_i^p\right)^{1/p}$ 是凹的,且其扩展值延伸(当 $z\not\succeq0$ 时为 $-\infty$)在每维分量上非减,则若 $g_i$ 是凹函数且非负,$f(x)=\left(\displaystyle\sum_{i=1}^kg_i(x)^p\right)^{1/p}$ 是凸函数。
>
> - 设 $p\geqslant 1$, $g_{1}, \cdots , g_{k}$ 是凸函数且非负。则函数 $\left(\displaystyle\sum_{i=1}^ng_i(x)^p\right)^{1/p}$
>
> 为了说明这一点,考虑函数 $h:\mathbf{R}^k\to\mathbf{R}$
>
> $$
> h(z)=\left(\sum_{i=1}^{k}\max\{z_{i},0\}^{p}\right)^{1/p}
> $$
>
> 其中 $\dom h=\mathbf{R}^{k}$,因此 $h=\tilde{h}$。由函数 $h$ 是凸函数且非减可知 $h(g(x))$ 关于 $x$ 是凸函数。对 $z\succeq0$,我们有 $h(z)=\left(\displaystyle\sum_{i=1}^kz_i^p\right)^{1/p}$,所以 $\left(\displaystyle\sum_{i=1}^kg_i(x)^p\right)^{1/p}$ 是凸函数。
>
> - 几何平均函数 $h(z)=\left(\displaystyle\prod_{i=1}^kz_i\right)^{1/k}$,定义域为 $\mathbf{R}_+^k$,它是凹函数,且其扩展值延伸在每维分量上非减。因此若 $g_1,\cdots,g_k$ 是非负凹函数,它们的几何平均 $\left(\displaystyle\prod_{i=1}^kg_i\right)^{1/k}$ 也是非负凸函数。
# 5. 最小化
&emsp;&emsp;我们已经得到,任意个凸函数的逐点最大或者上确界仍然是凸函数。事实上,一些特殊形式的最小化同样可以得到凸函数。若函数 $f$ 关于 $(x,y)$ 是凸函数,集合 $C$ 是非空凸集,定义函数
$$\begin{equation}\label{DefinitionOfMinimization}
g(x)=\inf_{y\in C}f(x,y)
\end{equation}
$$
若存在某个 $x$ 使得 $g(x)>-\infty$(该条件隐含着对所有 $x,g(x)>-\infty$),则函数 $g$ 关于 $x$ 是凸函数。函数 $g$ 的定义域是 $\dom f$ 在 $x$ 方向上的投影,即
$$
\dom g=\{x\mid 对某些\:y\in C\:有\: (x,y)\in\dom f\}
$$
&emsp;&emsp;任取 $x_1$, $x_2\in \dom g$,利用 Jensen 不等式来证明上述结论。
> **证明**&emsp;令 $\epsilon>0$,则存在 $y_{1}$, $y_{2}\in C$,使 $f( x_{i}, y_{i}) \leqslant g( x_{i}) + \epsilon ( i= 1$, 2)。设 $\theta\in[0,1]$,有
>
> $$\begin{aligned}
> g(\theta x_{1}+(1-\theta)x_{2})&=\inf_{y\in C}f(\theta x_{1}+(1-\theta)x_{2},y)
> \\
> &\leqslant f(\theta x_1+(1-\theta)x_2,\theta y_1+(1-\theta)y_2)
> \\
> &\leqslant\theta f(x_1,y_1)+(1-\theta)f(x_2,y_2)
> \\
> &\leqslant\theta g(x_1)+(1-\theta)g(x_2)+\epsilon
> \end{aligned}$$
>
> 因为上式对任意$\epsilon>0$均成立,所以下式成立
> $$
> g(\theta x_1+(1-\theta)x_2)\leqslant\theta g(x_1)+(1-\theta)g(x_2)
> $$
&emsp;&emsp;此结论亦可通过上境图来说明。对式 $\eqref{DefinitionOfMinimization}$ 中定义的 $f$,$g$ 和 $C$,设对每个 $x$,在集合 $y\in C$ 上求下确界均可达到,则有
$$
\epi g=\{(x,t)\mid$对某个$y\in C$成立$(x,y,t)\in\epi f\}
$$
由于 $\epi g$是凸集在其中一些分量上的投影,所以它仍然是凸集。
> **举例**&emsp;**Schur 补**。设二次函数
>
> $$
> f(x,y)=x^{\TT}Ax+2x^{\TT}By+y^{\TT}Cy
> $$
>
> (其中$A$和$C$是对称矩阵)关于 $(x,y)$ 是凸函数,即
>
> $$
> \left[\begin{array}{cc}A&B\\B^{\TT}&C\end{array}\right]\succeq0
> $$
>
> 我们可以将$g(x)=\inf_yf(x,y)$表述为
>
> $$
> g(x)=x^{\TT}(A-BC^\dagger B^{\TT})x
> $$
>
> 其中 $C^\dagger$ 是矩阵 $C$ 的伪逆。根据极小化的性质,$g$ 是凸函数,因此 $A-BC^\dagger B^{\TT}\succeq 0$。
>
> 如果矩阵$C$可逆,即$C\succ0$,则矩阵$A-BC^{-1}B^{\TT}$称为$C$在矩阵
>
> $$
> \left[\begin{array}{cc}A&B\\B^{\TT}&C\end{array}\right]
> $$
>
> 中的 Schur 补。
> **举例**&emsp;**到某一集合的距离**。采用范数 $\|\cdot\|$,某点$x$到集合 $S\subseteq\mathbb{R}^n$ 的距离定义为
>
> $$
> \dist (x,S)=\inf_{y\in S}\|x-y\|
> $$
>
> 函数 $\|x-y\|$关于$(x,y)$ 是凸的,所以若集合 $S$ 是凸集,距离函数 $\dist (x,S)$ 是 $x$ 的凸函数。
> **举例**&emsp;设 $h$ 是凸函数。则函数 $g$
>
> $$
> g(x)=\inf\{h(y)\mid Ay=x\}
> $$
>
> 是凸函数。为了说明这一点,定义函数 $f$
>
> $$
> f(x,y)=\left\{\begin{array}{ll}h(y)&\text{如果}Ay=x\\\infty&\text{其他情况,}\end{array}\right.
> $$
>
> 此函数关于$(x,y)$是凸的。以$y$为自变量,极小化函数$f$即可得到函数$g$,因此函数$g$是凸函数。(直接证明$g$是凸函数亦不复杂。)
# 6. 透视函数
&emsp;&emsp;给定函数 $f:\mathbf{R}^n\to\mathbf{R}$,则 $f$ 的透视函数 $g:\mathbf{R}^n+1\to\mathbf{R}$ 定义为
$$
g(x,t)=tf(x/t)
$$
其定义域为
$$
\mathbf{dom}g=\{(x,t)\mid x/t\in\mathbf{dom}f,t>0\}
$$
透视运算是保凸运算:如果函数 $f$ 是凸函数,则其透视函数 $g$ 也是凸函数。类似地,若
$f$ 是凹函数,则 $g$ 亦是凹函数。
&emsp;&emsp;可以从多个角度来证明此结论,例如,我们可以直接验证定义凸性的不等式。这里应用上境图和[透视函数][]一节所描述的 $\mathbf{R}^{n+1}$ 上的透视映射给出一个简短的证明(同时也可以说明“透视”一词的由来)。当 $t>0$ 时,我们有
$$\begin{array}{lll}
(x,t,s)\in\epi g&\iff&tf(x/t)\leqslant s
\\
&\iff&f(x/t)\leqslant s/t
\\
&\iff&(x/t,s/t)\in\epi f
\end{array}$$
因此,$\epi g$是透视映射下 $\epi f$ 的原像,此透视映射将 $(u,v,w)$ 映射为 $(u,w)/v$。根据[透视函数][]一节中的结论,$\epi g$ 是凸集,所以函数 $g$ 是凸函数。
> **举例**&emsp;**Euclid 范数的平方**。$\mathbb{R}^n$ 上的凸函数 $f(x)=x^{\TT}x$ 的透视函数由下式给出
>
> $$
> g(x,t)=t(x/t)^{\TT}(x/t)=\frac{x^{\TT}x}{t}
> $$
>
> 当 $t>0$ 时它关于 $(x,t)$ 是凸函数。
>
> 我们可以利用其他方法导出$g$的凸性。首先,将 $g$ 表示为一系列二次-线性分式函数 $x_i^2/t$ 的和。在[凸函数举例][]部分,我们已经知道,每一项 $x_i^2/t$ 是凸函数,因此和亦为凸函数。另一方面。我们可以将 $g$ 表述为一种特殊的矩阵分式函数 $x^{\TT}(tI)^{-1}x$,由此导出凸性。
> **举例**&emsp;**负对数**。考虑 $\mathbf{R}_{++}$ 上的凸函数 $f(x)=-\log x$,其透视函数为
>
> $$
> g(x,t)=-t\log(x/t)=t\log(t/x)=t\log t-t\log x
> $$
>
> 在 $\mathbf{R}_{++}^{2}$ 上它是凸函数。函数 $g$ 称为关于 $t$ 和 $x$ 的**相对熵**(*relative entropy*)。当 $x=1$ 时,$g$ 即为负熵函数。
>
> 基于函数 $g$ 的凸性,我们可以得出一些有趣的相关函数的凸性或凹性。首先,定义两个向量 $u, v\in \mathbf{R} _{+ + }^{n}$ 的相对熵
>
> $$
> \sum_{i=1}^nu_i\log(u_i/v_i)
> $$
>
> 由于它是一系列 $u_i,v_i$ 的相对熵的和,因此关于 $(u,v)$ 是凸函数。
>
> 另一个密切相关的函数是向量 $u,v\in\mathbf{R}_{++}^{n}$ 之间的 **Kullback-Leibler 散度**(Kullback-Leibler divergence),其形式为
>
> $$\begin{equation}\label{KLDivergence}
> D_{\mathrm{kl}}(u,v)=\sum_{i=1}^{n}\left(u_{i}\log(u_{i}/v_{i})-u_{i}+v_{i}\right)
> \end{equation}
> $$
>
> 因为它是 $(u,v)$ 的相对熵和线性函数的和,所以它也是凸函数。Kullback-Leibler 散度总是满足 $D_{\mathrm{kl}}(u,v)\geqslant0$,当且仅当 $u=v$ 时,$D_\mathrm{kl}(u,v)=0$,因此 Kullback-Leibler 散度可以用来衡量两个正向量之间的偏差。(注意到当 $u$ 和 $v$ 都是概率向量,即 $\mathbf{1}^{\TT}u=\mathbf{1}^{\TT}v=1$ 时,相对熵和 Kullback-Leibler 散度是等价的。)
>
> 如果在相对熵函数中选择 $v_i=\mathbf{1}^{\TT}u$,我们可以得到定义在 $u\in\mathbb{R}_+^n$ 上的凹函数(也是齐次函数)
>
> $$
> \sum_{i=1}^{n}u_{i}\log(\mathbf{1}^{\TT}u/u_{i})=(\mathbf{1}^{\TT}u)\sum_{i=1}^{n}z_{i}\log(1/z_{i})
> $$
>
> 其中 $z=u/(\mathbf{1}^{\TT}u)$。此函数称为**归一化熵**(*normalized entropy*)函数。向量 $z=u/\mathbf{1}^{\TT}u$ 的分量和为 1,称为归一化向量或者概率分布;$u$ 的归一化熵是 $\mathbf{1}^{\TT}u$和归一化概率分布 $z$ 的熵的乘积。
> **举例**&emsp;设 $f:\mathbf{R}^m\to\mathbf{R}$ 是凸函数,$A\in\mathbf{R}^m\times n,b\in\mathbf{R}^m,c\in\mathbf{R}^n,d\in\mathbf{R}$。定义
>
> $$
> g(x)=(c^Tx+d)f\left((Ax+b)/(c^Tx+d)\right)
> $$
>
> 其定义域为
>
> $$
> \mathbf{dom}g=\{x\mid c^Tx+d>0,(Ax+b)/(c^Tx+d)\in\mathbf{dom}f\}
> $$
>
> 则$g$是凸函数。
# 参考文献
1. Stephen P. Boyd and Lieven Vandenberghe, *Convex optimization*. Cambridge, UK: Cambridge University Press, 2004.
2. Stephen P. Boyd and Lieven Vandenberghe, *凸优化*. 北京: 清华大学出版社, 2013.
[透视函数]: https://josh-gao.top/posts/a4a69a4f.html#%E9%80%8F%E8%A7%86%E5%87%BD%E6%95%B0
[凸函数举例]: https://josh-gao.top/posts/320f661c.html#%E4%BE%8B%E5%AD%90
@@ -0,0 +1,279 @@
---
title: 信息论角度推导高斯分布的概率密度函数
mathjax: true
comments: true
copyright: true
toc:
enable: true
number: true
wrap: true
expand_all: true
max_depth: 4
abbrlink: '741621e3'
date: 2025-07-02 09:20:07
tags:
- 高斯分布
- 信息论
categories:
- [数学, 概率论]
---
$\newcommand\diff{\mathop{}\!\mathrm{d}}$
# 背景与目标
在统计建模中,我们常常面临这样一个问题:**已知某个连续随机变量的期望和方差,如何合理地确定它的概率分布?** 最大熵原理(Maximum Entropy Principle)提供了一个具有信息论意义的答案:
> 在已知约束(如期望与方差)下,熵最大的概率密度函数是最“中立”或最“无偏”的选择。
熵在此表示不确定性或信息量。连续型随机变量的微分熵定义为:
$$
\begin{equation*}
H[p] = -\int_{-\infty}^{\infty} p(x) \ln p(x) \, \diff x
\end{equation*}
$$
我们的目标是:**在已知期望和方差的约束下,最大化熵 $H[p]$,求出最优概率密度函数 $p(x)$**。
<!-- more -->
# 约束条件
我们假设随机变量 $X$ 满足:
- 归一化约束:
$$
\begin{equation*}
\int_{-\infty}^{\infty} p(x) \, \diff x = 1
\end{equation*}
$$
- 期望约束:
$$
\begin{equation*}
\int_{-\infty}^{\infty} x \, p(x) \, \diff x = \mu
\end{equation*}
$$
- 方差约束:
$$
\begin{equation*}
\int_{-\infty}^{\infty} (x - \mu)^2 \, p(x) \, \diff x = \sigma^2
\end{equation*}
$$
# 构造拉格朗日泛函
引入拉格朗日乘子 $\lambda_0, \lambda_1, \lambda_2$,构造带约束的目标泛函:
$$
\begin{equation*}
\mathcal{L}[p] = -\int p(x) \ln p(x) \diff x
+ \lambda_0 \left( \int p(x) \diff x - 1 \right)
+ \lambda_1 \left( \int x p(x) \diff x - \mu \right)
+ \lambda_2 \left( \int (x - \mu)^2 p(x) \diff x - \sigma^2 \right)
\end{equation*}
$$
将所有积分项合并为:
$$
\begin{equation*}
\mathcal{L}[p] = \int \left[
- p(x) \ln p(x)
+ \lambda_0 p(x)
+ \lambda_1 x p(x)
+ \lambda_2 (x - \mu)^2 p(x)
\right] \diff x
\end{equation*}
$$
# 变分法求极值
我们考虑一个扰动:
$$
\begin{equation*}
p(x) \rightarrow p(x) + \epsilon \eta(x)
\end{equation*}
$$
其中 $\epsilon$ 是足够小的实数,$\eta(x)$ 是任意光滑、在积分区间内有界且满足边界条件的函数(可理解为“任意小的扰动”)。为了求出 $\dfrac{\delta \mathcal{L}}{\delta p(x)}$,我们代入扰动项进行展开:
$$
\begin{equation*}
\mathcal{L}[p + \epsilon \eta]
= -\int (p(x) + \epsilon \eta(x)) \ln (p(x) + \epsilon \eta(x)) \, \diff x + \text{其余约束项}
\end{equation*}
$$
> 注意:这里只展开了主熵项 $-\displaystyle\int p \ln p$,约束项形式类似,将在后面统一处理。
---
对主项使用泰勒展开(忽略高阶小量):
> **泰勒展开回顾:**
>
> 设 $f(p) = p \ln p$,我们对 $p(x) + \epsilon \eta(x)$ 展开,有:
> $$
> f(p + \epsilon \eta) = p \ln p + \epsilon \eta (1 + \ln p) + o(\epsilon)
> $$
> 其中:
> $$
> \frac{\diff }{\diff p}(p \ln p) = \ln p + 1
> $$
将其代入:
$$
\begin{align*}
\mathcal{L}[p + \epsilon \eta]
&= -\int \left[ p(x) \ln p(x) + \epsilon \eta(x)(1 + \ln p(x)) \right] \diff x + o(\epsilon) + \text{约束项} \\
&= \mathcal{L}[p] - \epsilon \int \eta(x) (1 + \ln p(x)) \diff x + o(\epsilon) + \text{约束项}
\end{align*}
$$
对约束项也类似展开:
- 对归一化项:
$$
\begin{equation*}
\lambda_0 \left( \int (p + \epsilon \eta) \diff x - 1 \right)
= \lambda_0 \left( \int p \, \diff x - 1 + \epsilon \int \eta \, \diff x \right)
\end{equation*}
$$
- 对期望项:
$$
\begin{equation*}
\lambda_1 \left( \int x (p + \epsilon \eta) \diff x - \mu \right)
= \lambda_1 \left( \int x p \, \diff x - \mu + \epsilon \int x \eta \, \diff x \right)
\end{equation*}
$$
- 对方差项:
$$
\begin{equation*}
\lambda_2 \left( \int (x - \mu)^2 (p + \epsilon \eta) \diff x - \sigma^2 \right)
= \lambda_2 \left( \int (x - \mu)^2 p \, \diff x - \sigma^2 + \epsilon \int (x - \mu)^2 \eta(x) \diff x \right)
\end{equation*}
$$
---
将所有一阶 $\epsilon$ 项收集起来:
$$
\begin{equation*}
\mathcal{L}[p + \epsilon \eta] = \mathcal{L}[p]
+ \epsilon \int \eta(x) \left[ - (1 + \ln p(x)) + \lambda_0 + \lambda_1 x + \lambda_2 (x - \mu)^2 \right] \diff x + o(\epsilon)
\end{equation*}
$$
对 $\epsilon$ 求导并令其在 $\epsilon = 0$ 处为零:
$$
\begin{equation*}
\left. \frac{\diff}{\diff \epsilon} \mathcal{L}[p + \epsilon \eta] \right|_{\epsilon=0}
= \int \eta(x) \left[ -\ln p(x) - 1 + \lambda_0 + \lambda_1 x + \lambda_2 (x - \mu)^2 \right] \diff x = 0
\end{equation*}
$$
根据变分法基本引理,这个积分当且仅当括号内为 $0$ 时对所有扰动函数 $\eta(x)$ 为零:
> 变分法基本引理:
>
> 若函数 $F(x)$ 满足
> $$
> \int_{a}^{b} F(x) \cdot \eta(x) dx = 0
> $$
> 对所有合适扰动 $\eta(x)$ 成立,则必有
> $$
> F(x) = 0 \quad \forall x \in (a, b)
> $$
>
> 这是因为若 $F(x_0) \ne 0$,则可构造在 $x_0$ 附近支持的 $\eta(x)$ 使得积分不为零,导致矛盾。
$$
\begin{equation*}
\frac{\delta \mathcal{L}}{\delta p(x)} = -\ln p(x) - 1 + \lambda_0 + \lambda_1 x + \lambda_2 (x - \mu)^2 = 0
\end{equation*}
$$
也即求得了变分导数。移项得:
$$
\begin{equation*}
\ln p(x) = \lambda_0' + \lambda_1 x + \lambda_2 (x - \mu)^2
\end{equation*}
$$
两边取指数:
$$
\begin{equation*}
p(x) = \exp\left( \lambda_0' + \lambda_1 x + \lambda_2 (x - \mu)^2 \right)
\end{equation*}
$$
要满足可积性,需 $\lambda_2 < 0$。设
$$
\begin{equation*}
p(x) = A \cdot \exp\left( -\alpha (x - \mu)^2 \right)
\end{equation*}
$$
# 归一化与确定参数
根据归一化条件:
$$
\begin{equation*}
A \cdot \int_{-\infty}^{\infty} \exp\left( -\alpha (x - \mu)^2 \right) \diff x = 1
\end{equation*}
$$
已知高斯积分结果:
$$
\begin{equation*}
\int_{-\infty}^{\infty} \exp\left( -\alpha (x - \mu)^2 \right) \diff x = \sqrt{\frac{\pi}{\alpha}}
\end{equation*}
$$
得到:
$$
\begin{equation*}
A = \sqrt{\frac{\alpha}{\pi}}
\end{equation*}
$$
若令 $\alpha = \dfrac{1}{2\sigma^2}$,则最终得:
$$
\begin{equation*}
p(x) = \frac{1}{\sqrt{2\pi\sigma^2}} \exp\left( -\frac{(x - \mu)^2}{2\sigma^2} \right)
\end{equation*}
$$
# 总结
从最大熵原理出发,在已知均值与方差的约束下,最“无偏”或熵最大的概率密度函数是:
$$
\begin{equation*}
p(x) = \frac{1}{\sqrt{2\pi\sigma^2}} \exp\left( -\frac{(x - \mu)^2}{2\sigma^2} \right)
\end{equation*}
$$
这正是**高斯分布**的标准形式,说明它不仅数学上方便,**信息论上也是最合理的选择**。
Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 810 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 469 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 490 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 496 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB