backends/default API
Luna-Flow/linear-algebra/backends/default 是参考稠密后端。它用四个自有结构体包装具体的 @mutable 和 @immut 类型,并为它们实现 algebra trait,使受这些 trait 约束的泛型代码能够在真实的稠密数据上运行。它还提供三个受 trait 约束的辅助函数以及若干后端方法(scale、dot、axpy、matvec)。
源码:src/backends/default。包装类型存在的原因见 backends/default 设计。
导入
///|
import {
"Luna-Flow/linear-algebra/algebra",
"Luna-Flow/linear-algebra/backends/default",
}
概览
| 包装类型 | 被包装类型 | 语义 |
|---|---|---|
DenseVector[T] | @mutable.Vector[T] | 共享被包装的向量;运算符的结果是新向量 |
DenseMatrix[T] | @mutable.Matrix[T] | 共享被包装的矩阵;运算符的结果是新矩阵 |
ImmutableDenseVector[T] | @immut.Vector[T] | 值语义 |
ImmutableDenseMatrix[T] | @immut.Matrix[T] | 值语义 |
所有运算符都返回一个包裹新内部值的新包装对象;没有运算符会修改其操作数。与被包装类型一样,运算符中的形状不匹配会导致中止。
泛型辅助函数
shape_of
shape_of(m) 返回任意 MatrixShape 值的 (rows, cols)。
pub fn[M : @algebra.MatrixShape] shape_of(M) -> (Int, Int)
transpose
transpose(m) 返回任意 TransposeMatrix 值的转置,类型与原值相同。
pub fn[M : @algebra.TransposeMatrix] transpose(M) -> M
matmul
matmul(a, b) 对任意 MatMulMatrix 类型返回 a * b。
pub fn[M : @algebra.MatMulMatrix] matmul(M, M) -> M
前置条件 以及失败时的行为都由该类型的 * 决定;对于稠密包装类型,不匹配会导致中止。
///|
test "generic helpers on dense wrappers" {
let a = @default.DenseMatrix::from_2d_array([[1, 2, 3], [4, 5, 6]])
debug_inspect(@default.shape_of(a), content="(2, 3)")
let at = @default.transpose(a)
debug_inspect(@default.shape_of(at), content="(3, 2)")
inspect(@default.matmul(a, at).inner(), content="|14, 32|\n|32, 77|")
}
DenseVector
DenseVector
DenseVector[T] 是可变稠密向量的包装类型。
pub struct DenseVector[T] {
inner : @mutable.Vector[T]
}
该字段可从其他包读取。已实现的 trait:在下列方法的元素约束下的 Add、Neg、Sub 和 Mul(按元素),对所有 T 实现的 @algebra.VectorShape,当 T : Add + Neg 时的 @algebra.AdditiveVector,以及当 T : Add + Neg + Mul 时的 @algebra.VecMulVector。
DenseVector::from_array
DenseVector::from_array(xs) 包装一个由 xs 构建的新 @mutable.Vector。
pub fn[T] DenseVector::from_array(Array[T]) -> Self[T]
数组不会被复制:包装对象与 xs 共享存储,这与 @mutable.Vector::from_array 相同。
DenseVector::from_backend
DenseVector::from_backend(v) 包装一个已有的 @mutable.Vector,不进行复制。
pub fn[T] DenseVector::from_backend(@mutable.Vector[T]) -> Self[T]
DenseVector::make
DenseVector::make(n, x) 构建一个长度为 n、所有元素均为 x 的向量。
pub fn[T] DenseVector::make(Int, T) -> Self[T]
DenseVector::inner
DenseVector::inner(v) 返回被包装的 @mutable.Vector;对它的写入可以通过包装对象观察到。
pub fn[T] DenseVector::inner(Self[T]) -> @mutable.Vector[T]
DenseVector::length
DenseVector::length(v) 返回元素个数。
pub fn[T] DenseVector::length(Self[T]) -> Int
DenseVector::at
DenseVector::at(v, i) 返回第 i 个元素;它是 v[i] 的底层实现。
#alias("_[_]")
pub fn[T] DenseVector::at(Self[T], Int) -> T
超出 0..<length 的索引会导致中止。
DenseVector::add, DenseVector::sub, DenseVector::neg
这些是 u + v、u - v 和 -v 背后的提升运算符方法。
pub fn[T : Add] DenseVector::add(Self[T], Self[T]) -> Self[T]
pub fn[T : Add + Neg] DenseVector::sub(Self[T], Self[T]) -> Self[T]
pub fn[T : Neg] DenseVector::neg(Self[T]) -> Self[T]
长度不同的操作数会导致中止。减法按 计算。
DenseVector::mul
DenseVector::mul(u, v) 是 u * v 背后的按元素(Hadamard)乘积。
pub fn[T : Mul] DenseVector::mul(Self[T], Self[T]) -> Self[T]
DenseVector::scale
DenseVector::scale(v, a) 返回 ,即每个元素右乘该标量。
pub fn[T : Mul] DenseVector::scale(Self[T], T) -> Self[T]
DenseVector::dot
DenseVector::dot(u, v) 返回 ,从 Zero::zero() 开始自左向右求和。
pub fn[T : @luna-generic.AddMonoid + Mul] DenseVector::dot(Self[T], Self[T]) -> T
长度不同的向量会导致中止。
DenseVector::axpy
DenseVector::axpy(x, a, y) 返回 ,即以 self 作为 的 BLAS axpy 组合。
pub fn[T : Add + Mul] DenseVector::axpy(Self[T], T, Self[T]) -> Self[T]
结果是一个新向量;y 不会被原地更新。
///|
test "DenseVector backend methods" {
let x = @default.DenseVector::from_array([1.0, 2.0, 3.0])
let y = @default.DenseVector::make(3, 1.0)
inspect(x.dot(y), content="6")
inspect(x.axpy(2.0, y).inner(), content="|3, 5, 7|")
inspect((x * x - y).inner(), content="|0, 3, 8|")
inspect(x[2], content="3")
inspect(@algebra.VectorShape::length(x), content="3")
}
DenseMatrix
DenseMatrix
DenseMatrix[T] 是可变稠密矩阵的包装类型。
pub struct DenseMatrix[T] {
inner : @mutable.Matrix[T]
}
已实现的 trait:对所有 T 实现的 Add、Neg、Sub、Mul(矩阵乘积)、@algebra.MatrixShape 和 @algebra.TransposeMatrix,当 T : Add + Neg 时的 @algebra.AdditiveMatrix,以及当 T : Add + Neg + AddMonoid + Mul 时的 @algebra.MatMulMatrix。
DenseMatrix::from_2d_array
DenseMatrix::from_2d_array(rows) 从按行组织的嵌套数组构造矩阵。
pub fn[T] DenseMatrix::from_2d_array(Array[Array[T]]) -> Self[T]
参差不齐的输入会导致中止;[] 得到 矩阵。
DenseMatrix::from_backend
DenseMatrix::from_backend(m) 包装一个已有的 @mutable.Matrix,不进行复制。
pub fn[T] DenseMatrix::from_backend(@mutable.Matrix[T]) -> Self[T]
DenseMatrix::new
DenseMatrix::new(r, c, x) 构建一个所有元素均为 x 的 矩阵。
pub fn[T] DenseMatrix::new(Int, Int, T) -> Self[T]
负的维度会导致中止。
DenseMatrix::inner
DenseMatrix::inner(m) 返回被包装的 @mutable.Matrix,借此可以使用完整的 @mutable API(视图、分解、受检方法)。
pub fn[T] DenseMatrix::inner(Self[T]) -> @mutable.Matrix[T]
DenseMatrix::row, DenseMatrix::col
row 和 col 返回行数和列数。
pub fn[T] DenseMatrix::row(Self[T]) -> Int
pub fn[T] DenseMatrix::col(Self[T]) -> Int
DenseMatrix::shape
DenseMatrix::shape(m) 返回 (rows, cols);它是提升后的 @algebra.MatrixShape::shape。
pub fn[T] DenseMatrix::shape(Self[T]) -> (Int, Int)
DenseMatrix::transpose
DenseMatrix::transpose(m) 返回实化后的转置;它是提升后的 @algebra.TransposeMatrix::transpose。
pub fn[T] DenseMatrix::transpose(Self[T]) -> Self[T]
DenseMatrix::add, DenseMatrix::sub, DenseMatrix::neg
按元素的 +、- 和一元 -。
pub fn[T : Add] DenseMatrix::add(Self[T], Self[T]) -> Self[T]
pub fn[T : Add + Neg] DenseMatrix::sub(Self[T], Self[T]) -> Self[T]
pub fn[T : Neg] DenseMatrix::neg(Self[T]) -> Self[T]
形状不同的操作数会导致中止。
DenseMatrix::mul
DenseMatrix::mul(a, b) 是 a * b 背后的矩阵乘积。
pub fn[T : @luna-generic.AddMonoid + Mul] DenseMatrix::mul(Self[T], Self[T]) -> Self[T]
时会以 Matrix::mul: dimension mismatch 中止。开销: 次乘加。
DenseMatrix::matvec
DenseMatrix::matvec(a, x) 以新的 DenseVector 返回矩阵-向量乘积 。
pub fn[T : @luna-generic.AddMonoid + Mul] DenseMatrix::matvec(Self[T], DenseVector[T]) -> DenseVector[T]
长度不匹配会导致中止;如需受检版本,请使用 a.inner().mul_vec(x.inner())。
///|
test "DenseMatrix operations" {
let a = @default.DenseMatrix::from_2d_array([[2, 0], [1, 3]])
let x = @default.DenseVector::from_array([1, 1])
inspect(a.matvec(x).inner(), content="|2, 4|")
inspect((a * a).inner(), content="|4, 0|\n|5, 9|")
inspect(a.transpose().inner(), content="|2, 1|\n|0, 3|")
debug_inspect(a.shape(), content="(2, 2)")
inspect(a.inner().trace().unwrap(), content="5")
}
ImmutableDenseVector
ImmutableDenseVector
ImmutableDenseVector[T] 是不可变稠密向量的包装类型。
pub struct ImmutableDenseVector[T] {
inner : @immut.Vector[T]
}
它在相同约束下实现与 DenseVector 相同的 trait。
ImmutableDenseVector::from_array
ImmutableDenseVector::from_array(xs) 将 xs 复制到一个新的 @immut.Vector 中。
pub fn[T] ImmutableDenseVector::from_array(Array[T]) -> Self[T]
ImmutableDenseVector::from_backend
ImmutableDenseVector::from_backend(v) 包装一个已有的 @immut.Vector。
pub fn[T] ImmutableDenseVector::from_backend(@immut.Vector[T]) -> Self[T]
ImmutableDenseVector::make
ImmutableDenseVector::make(n, x) 构建一个长度为 n、所有元素均为 x 的向量。
pub fn[T] ImmutableDenseVector::make(Int, T) -> Self[T]
ImmutableDenseVector::inner
ImmutableDenseVector::inner(v) 返回被包装的 @immut.Vector。
pub fn[T] ImmutableDenseVector::inner(Self[T]) -> @immut.Vector[T]
ImmutableDenseVector::length
ImmutableDenseVector::length(v) 返回元素个数。
pub fn[T] ImmutableDenseVector::length(Self[T]) -> Int
ImmutableDenseVector::at
ImmutableDenseVector::at(v, i) 返回第 i 个元素;它是 v[i] 的底层实现。
#alias("_[_]")
pub fn[T] ImmutableDenseVector::at(Self[T], Int) -> T
ImmutableDenseVector::add, ImmutableDenseVector::sub, ImmutableDenseVector::neg, ImmutableDenseVector::mul
按元素的 +、-、一元 - 和 Hadamard *。
pub fn[T : Add] ImmutableDenseVector::add(Self[T], Self[T]) -> Self[T]
pub fn[T : Add + Neg] ImmutableDenseVector::sub(Self[T], Self[T]) -> Self[T]
pub fn[T : Neg] ImmutableDenseVector::neg(Self[T]) -> Self[T]
pub fn[T : Mul] ImmutableDenseVector::mul(Self[T], Self[T]) -> Self[T]
ImmutableDenseVector::scale
ImmutableDenseVector::scale(v, a) 返回 。
pub fn[T : Mul] ImmutableDenseVector::scale(Self[T], T) -> Self[T]
ImmutableDenseVector::dot
ImmutableDenseVector::dot(u, v) 返回 。
pub fn[T : @luna-generic.Zero + Add + Mul] ImmutableDenseVector::dot(Self[T], Self[T]) -> T
长度不同的向量会导致中止。
ImmutableDenseVector::axpy
ImmutableDenseVector::axpy(x, a, y) 返回 。
pub fn[T : Add + Mul] ImmutableDenseVector::axpy(Self[T], T, Self[T]) -> Self[T]
ImmutableDenseMatrix
ImmutableDenseMatrix
ImmutableDenseMatrix[T] 是不可变稠密矩阵的包装类型。
pub struct ImmutableDenseMatrix[T] {
inner : @immut.Matrix[T]
}
它实现与 DenseMatrix 相同的 trait;@algebra.MatMulMatrix 需要 T : Add + Neg + Zero + Mul。
ImmutableDenseMatrix::from_2d_array
ImmutableDenseMatrix::from_2d_array(rows) 从嵌套的行数组构造矩阵;参差不齐的输入会导致中止。
pub fn[T] ImmutableDenseMatrix::from_2d_array(Array[Array[T]]) -> Self[T]
ImmutableDenseMatrix::from_backend
ImmutableDenseMatrix::from_backend(m) 包装一个已有的 @immut.Matrix。
pub fn[T] ImmutableDenseMatrix::from_backend(@immut.Matrix[T]) -> Self[T]
ImmutableDenseMatrix::new
ImmutableDenseMatrix::new(r, c, x) 构建一个所有元素均为 x 的 矩阵。
pub fn[T] ImmutableDenseMatrix::new(Int, Int, T) -> Self[T]
ImmutableDenseMatrix::inner
ImmutableDenseMatrix::inner(m) 返回被包装的 @immut.Matrix。
pub fn[T] ImmutableDenseMatrix::inner(Self[T]) -> @immut.Matrix[T]
ImmutableDenseMatrix::row, ImmutableDenseMatrix::col, ImmutableDenseMatrix::shape
行数、列数和 (rows, cols);shape 是提升后的 @algebra.MatrixShape::shape。
pub fn[T] ImmutableDenseMatrix::row(Self[T]) -> Int
pub fn[T] ImmutableDenseMatrix::col(Self[T]) -> Int
pub fn[T] ImmutableDenseMatrix::shape(Self[T]) -> (Int, Int)
ImmutableDenseMatrix::transpose
ImmutableDenseMatrix::transpose(m) 返回转置;它是提升后的 @algebra.TransposeMatrix::transpose。
pub fn[T] ImmutableDenseMatrix::transpose(Self[T]) -> Self[T]
ImmutableDenseMatrix::add, ImmutableDenseMatrix::sub, ImmutableDenseMatrix::neg, ImmutableDenseMatrix::mul
按元素的 +、-、一元 - 以及矩阵乘积。
pub fn[T : Add] ImmutableDenseMatrix::add(Self[T], Self[T]) -> Self[T]
pub fn[T : Add + Neg] ImmutableDenseMatrix::sub(Self[T], Self[T]) -> Self[T]
pub fn[T : Neg] ImmutableDenseMatrix::neg(Self[T]) -> Self[T]
pub fn[T : Add + @luna-generic.Zero + Mul] ImmutableDenseMatrix::mul(Self[T], Self[T]) -> Self[T]
形状不匹配会导致中止。
ImmutableDenseMatrix::matvec
ImmutableDenseMatrix::matvec(a, x) 以新的 ImmutableDenseVector 返回 ;长度不匹配会导致中止。
pub fn[T : Add + @luna-generic.Zero + Mul] ImmutableDenseMatrix::matvec(Self[T], ImmutableDenseVector[T]) -> ImmutableDenseVector[T]
///|
test "immutable wrappers" {
let a = @default.ImmutableDenseMatrix::from_2d_array([[1, 2], [3, 4]])
let x = @default.ImmutableDenseVector::from_array([1, -1])
inspect(a.matvec(x).inner(), content="|-1, -1|")
inspect((a - a.transpose()).inner(), content="|0, -1|\n|1, 0|")
inspect(x.dot(x), content="2")
inspect(x.scale(3).inner(), content="|3, -3|")
}