playbook/docs/tsl/syntax/26_matrix_deep_dive.md

176 lines
5.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Matrix Deep Dive
文档类型:语法主线
是否可直接用于生成代码:是
是否含已验证可执行示例:是
是否含已验证反例:是
遇到不确定时跳转到:[13_matrix_and_collections.md](13_matrix_and_collections.md)、[27_fmarray.md](27_fmarray.md)、[25_set_operations.md](25_set_operations.md)
手册位置:第 26 篇,共 32 篇。上一篇:[25_set_operations.md](25_set_operations.md)。下一篇:[27_fmarray.md](27_fmarray.md)。
这一篇开始讲真正的矩阵语法主干:矩阵初始化、数列构造,以及怎样读取矩阵的行列大小和索引。它和 [13_matrix_and_collections.md](13_matrix_and_collections.md) 的分工是:`13` 只讲数组与矩阵样数据,这一篇开始讲矩阵专用构造与大小接口。
## 这一篇解决什么问题
回答“怎样直接构造全零矩阵、全一矩阵、随机矩阵、单位矩阵、空矩阵和数列数组,以及怎样拿到矩阵的行数、列数、行索引和列索引”。
## 必须记住的规则
- `Zeros(...)`、`Ones(...)`、`Rand(...)`、`Nils(...)`、`Eye(...)` 都可以直接用于矩阵初始化。
- `Zeros(3)`、`Ones(3)`、`Nils(2)` 这类单参数写法可以直接生成一维结果。
- `Zeros(2, 3)`、`Rand(2, 3)` 这类双参数写法可以直接生成二维矩阵。
- `Zeros(2, array("A", "B"))` 这种写法可以直接生成带列名的二维结果。
- `Eye(3)` 生成的是 `3 x 3` 单位矩阵,不是一维数组。
- `->` 用来生成数列;默认步长是 `1`,也可以显式传入步长和索引数组。
- `MSize(A)` 返回 `array(行数, 列数)`
- `MSize(A, 1)` 返回行索引数组和列索引数组。
- `MRows(A)` / `MCols(A)` 默认返回数量;第二个参数写成 `1` 时返回索引数组。
## 已验证语法
### 矩阵初始化
代码块身份:已验证可执行示例
```tsl
program test;
begin
Z1 := Zeros(3);
Z2 := Zeros(2, 3);
O1 := Ones(3);
N1 := Nils(2);
E1 := Eye(3);
R1 := Rand(2, 3);
T1 := Zeros(2, array("A", "B"));
end.
```
已验证运行结果:
- `Zeros(3)` 的长度是 `3`,前三个元素依次是 `0`、`0`、`0`
- `Zeros(2, 3)` 的行数是 `2`、列数是 `3`,第一行前三个元素是 `0`、`0`、`0`
- `Ones(3)` 的前三个元素依次是 `1`、`1`、`1`
- `Nils(2)` 已验证可直接生成长度为 `2` 的结果
- `Eye(3)` 的行数是 `3`、列数是 `3`,并且 `(0,0)`、`(1,1)`、`(2,2)` 为 `1``(0,1)`、`(1,0)` 为 `0`
- `Rand(2, 3)` 的行数是 `2`、列数是 `3`
- `Zeros(2, array("A", "B"))` 的行数是 `2`、列数是 `2`,并且 `T1[0]["A"]`、`T1[0]["B"]`、`T1[1]["A"]`、`T1[1]["B"]` 都是 `0`
### `->` 数列数组初始化
默认步长为 `1`
代码块身份:已验证可执行示例
```tsl
program test;
begin
S1 := 1 -> 5;
end.
```
已验证运行结果:
- `S1``array(1, 2, 3, 4, 5)`
显式指定步长:
代码块身份:已验证可执行示例
```tsl
program test;
begin
S2 := array(2.5, 0.5) -> 5;
end.
```
已验证运行结果:
- `S2` 的长度是 `6`
- 六个元素依次是 `2.5`、`3`、`3.5`、`4`、`4.5`、`5`
显式指定索引数组:
代码块身份:已验证可执行示例
```tsl
program test;
begin
S3 := array(0, 1, array("A", "B", "C", "D", "E", "F")) -> 5;
end.
```
已验证运行结果:
- `S3` 的长度是 `6`
- `S3["A"]``S3["F"]` 依次是 `0`、`1`、`2`、`3`、`4`、`5`
### `MSize`、`MRows`、`MCols`
代码块身份:已验证可执行示例
```tsl
program test;
begin
A := array(
("A": 1, "B": 2),
("A": 11, "B": 22),
("A": 21, "B": 32)
);
SizeInfo := MSize(A);
SizeIndex := MSize(A, 1);
RowCount := MRows(A);
RowIndex := MRows(A, 1);
ColCount := MCols(A);
ColIndex := MCols(A, 1);
end.
```
已验证运行结果:
- `MSize(A)` 返回 `array(3, 2)`
- `MSize(A, 1)` 的第一项是 `array(0, 1, 2)`,第二项是 `array("A", "B")`
- `MRows(A)` 返回 `3`
- `MRows(A, 1)` 返回 `array(0, 1, 2)`
- `MCols(A)` 返回 `2`
- `MCols(A, 1)` 返回 `array("A", "B")`
## 最小可编译示例
如果你只想先记住最短矩阵构造,从这个开始:
代码块身份:已验证可执行示例
```tsl
M := Zeros(2, 3);
```
## 常见误写
-`Eye(3)` 当成一维数组。
- 以为 `MRows(A, 1)``MCols(A, 1)` 返回的还是数量。
- 写带步长的 `->` 时,漏掉外层 `array(...)`
- 还在普通数组页里硬塞矩阵专用大小接口。
代码块身份:反例 / 不可照写
```text
S := 2.5, 0.5 -> 5;
```
上面这种写法不对。显式步长模式需要写成 `array(2.5, 0.5) -> 5`
代码块身份:反例 / 不可照写
```text
Cols := MCols(A, 1);
```
不要把上面这一句的返回值当成数字 `2`。当前解释器下,`MCols(A, 1)` 返回的是列索引数组,例如 `array("A", "B")`
## 跳转指引
- 回看数组与嵌套数组:见 [13_matrix_and_collections.md](13_matrix_and_collections.md)
- 看结果集过滤:见 [14_resultset_and_filters.md](14_resultset_and_filters.md)
- 看集合运算:见 [25_set_operations.md](25_set_operations.md)
- 进入 `FMArray`:见 [27_fmarray.md](27_fmarray.md)