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

前置条件 cols⁡(a)=rows⁡(b)\operatorname{cols}(a) = \operatorname{rows}(b) 以及失败时的行为都由该类型的 * 决定;对于稠密包装类型,不匹配会导致中止。

///|
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]

长度不同的操作数会导致中止。减法按 u+(−v)u + (-v) 计算。

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) 返回 (vi⋅a)i(v_i \cdot a)_i,即每个元素右乘该标量。

pub fn[T : Mul] DenseVector::scale(Self[T], T) -> Self[T]

DenseVector::dot

DenseVector::dot(u, v) 返回 ∑iuivi\sum_i u_i v_i,从 Zero::zero() 开始自左向右求和。

pub fn[T : @luna-generic.AddMonoid + Mul] DenseVector::dot(Self[T], Self[T]) -> T

长度不同的向量会导致中止。

DenseVector::axpy

DenseVector::axpy(x, a, y) 返回 xa+yx a + y,即以 self 作为 xx 的 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]

参差不齐的输入会导致中止;[] 得到 0×00 \times 0 矩阵。

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 的 r×cr \times c 矩阵。

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]

cols⁡(a)≠rows⁡(b)\operatorname{cols}(a) \ne \operatorname{rows}(b) 时会以 Matrix::mul: dimension mismatch 中止。开销:rcnrcn 次乘加。

DenseMatrix::matvec

DenseMatrix::matvec(a, x) 以新的 DenseVector 返回矩阵-向量乘积 AxA x。

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) 返回 (vi⋅a)i(v_i \cdot a)_i。

pub fn[T : Mul] ImmutableDenseVector::scale(Self[T], T) -> Self[T]

ImmutableDenseVector::dot

ImmutableDenseVector::dot(u, v) 返回 ∑iuivi\sum_i u_i v_i。

pub fn[T : @luna-generic.Zero + Add + Mul] ImmutableDenseVector::dot(Self[T], Self[T]) -> T

长度不同的向量会导致中止。

ImmutableDenseVector::axpy

ImmutableDenseVector::axpy(x, a, y) 返回 xa+yx 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 的 r×cr \times c 矩阵。

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 返回 AxA x;长度不匹配会导致中止。

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|")
}