container/adapters 教程
本教程演示如何为仓库中的每种类型挑选合适的现成字典,并将其与 container 算法配合使用,包括 @mutable.Matrix 的实时视图。如果你想为自己的类型编写字典,请改读 container 教程。
快速上手
moon add Luna-Flow/linear-algebra@0.5.0
///|
import {
"Luna-Flow/linear-algebra/container",
"Luna-Flow/linear-algebra/container/adapters" @container_adapters,
"Luna-Flow/linear-algebra/immut",
"Luna-Flow/linear-algebra/mutable",
}
工厂函数的名称表明了类型和能力:
///|
test "read one entry through an adapter" {
let v = @immut.Vector::from_array([10, 20, 30])
let ops = @container_adapters.immutable_vector_read_ops()
inspect((ops.length)(v), content="3")
inspect((ops.get)(v, 2).unwrap(), content="30")
}
日常任务
从矩阵中复制出一行
行视图是向量源,因此任何向量目标都可以接收它:
///|
test "copy a row view into an immutable vector" {
let m = @mutable.Matrix::from_2d_array([[1, 2, 3], [4, 5, 6]])
let row : @immut.Vector[Int] = @container.vector_convert(
m.row_view(1),
@container_adapters.mutable_row_view_read_ops(),
@container_adapters.immutable_vector_build_ops(),
).unwrap()
m.set(1, 0, 40)
inspect(row, content="|4, 5, 6|")
}
物化转置视图
@mutable.Matrix 的转置视图是矩阵源,因此 matrix_convert 可以将其物化为任意表示:
///|
test "materialize a transpose view" {
let m = @mutable.Matrix::from_2d_array([[1, 2, 3], [4, 5, 6]])
let t : @immut.Matrix[Int] = @container.matrix_convert(
m.to_transpose(),
@container_adapters.mutable_transpose_read_ops(),
@container_adapters.immutable_matrix_build_ops(),
).unwrap()
inspect(t, content="|1, 4|\n|2, 5|\n|3, 6|")
}
通过列视图写入
///|
test "clear a column through its view" {
let m = @mutable.Matrix::from_2d_array([[1, 2], [3, 4], [5, 6]])
let col = m.col_view(0)
let edit = @container_adapters.mutable_col_view_mutable_edit_ops()
for i in 0..<col.length() {
(edit.set)(col, i, 0).unwrap()
}
inspect(m, content="|0, 2|\n|0, 4|\n|0, 6|")
}
在默认后端的包装类型之间搬运
///|
test "mutable dense wrapper to immutable dense wrapper" {
let source = @default.DenseVector::from_array([1.5, 2.5])
let target : @default.ImmutableDenseVector[Double] = @container.vector_convert(
source,
@container_adapters.dense_vector_read_ops(),
@container_adapters.immutable_dense_vector_build_ops(),
).unwrap()
inspect(target[1], content="2.5")
}
进一步了解
选择编辑形式。 具有值语义的类型(@immut、Immutable* 包装类型)只有 *_persistent_edit_ops;具有原地语义的类型(@mutable、视图、DenseVector、DenseMatrix)只有 *_mutable_edit_ops。进行编辑的泛型代码应接收与其所预期所有权模型相匹配的记录。
把视图作为目标。 视图没有构造字典。若要用另一个向量填充已有矩阵的一行,请读取源,并在循环中通过 mutable_row_view_mutable_edit_ops 写入。
常见陷阱
- 以为转换结果会保持关联。 转换视图会复制;之后对矩阵的写入不会影响副本,正如复制行的示例所示。
- 对默认包装类型使用
immutable_*。immutable_matrix_*适配的是@immut.Matrix;包装类型@default.ImmutableDenseMatrix有自己的immutable_dense_matrix_*工厂函数。
后续步骤
- adapters API:完整列表。
- container 教程:编写自己的字典。
- adapters 设计:依赖结构。