mutable API
Luna-Flow/linear-algebra/mutable 提供面向执行的稠密线性代数:Matrix[T] 将元素存放在一个行主序的 Array[T] 中,并可原地更新;Vector[T] 包装一个 Array[T];RowView、ColView 和 Transpose 是矩阵的实时视图。在存储之上,该包实现了仓库中的数值例程:基于 LU 的行列式、逆矩阵与秩,Cholesky 分解,对称矩阵特征值,幂法,行化简以及简单统计。
源码:src/mutable。算法及其数值性质在 mutable 设计中推导;immut 是面向值的对应包,核心名称相同。
导入
///|
import {
"Luna-Flow/linear-algebra/mutable",
}
约定
- 形状与存储。 矩阵有
row()行、col()列,二者均非负; 与 都合法且互不相同。元素 存放在偏移 处。 - 修改。 返回
Unit的方法(set、swap_rows、*_inplace、视图写入)会原地修改矩阵,它的所有视图和别名都能看到这一修改。其余方法都返回新值,不改变参数;唯一的例外是reduce_row_elimination,它原地工作并返回其接收者。 - 别名构造函数。
Matrix::from_array与Vector::from_array直接接管给定数组而不复制。from_2d_array、copy以及所有到数组的转换都会复制。 - 边界。 所有公开访问器都分别检查行和列,索引越界时中止;迭代器、视图和转置视图也是如此。
- 受检与非受检。 存在运行时失败情形的操作返回
Result[_, LinearAlgebraError],并有一个会中止的unchecked_*对应版本(unchecked_inverse则返回Option)。参见错误设计。 - 数值例程要求
T : Compare + Field + Num + Tolerance(需要开平方时还要求Sqrt)。Tolerance只为Double和Float实现,因此这些例程面向浮点矩阵。 - 目标平台。 内核针对
native、js、wasm和wasm-gc分别调优。公开语义在所有目标上相同;若某个内核的求和顺序不同,浮点结果的最后几位可能有差异。
类型
Matrix
Matrix[T] 是可变稠密矩阵。
type Matrix[T] derive(Eq)
该类型是抽象的。它实现了 Eq(形状与元素)、Show、Add、Sub、Neg 和 Mul(矩阵乘积),元素约束与相应方法一致。
Lens
Lens[T] 是 m[r] 返回的行访问器;它支撑 m[r][c] 与 m[r][c] = x。
type Lens[T]
Lens::at, Lens::set
Lens::at(l, c) 读取、Lens::set(l, c, x) 写入该 lens 所指行的第 c 列。
#alias("_[_]")
pub fn[T] Lens::at(Self[T], Int) -> T
#alias("_[_]=_")
pub fn[T] Lens::set(Self[T], Int, T) -> Unit
从 Transpose 获得的 lens 寻址的是转置后的矩阵。列越界时中止。
RowView, ColView
RowView[T] 和 ColView[T] 是一行或一列的实时视图。
pub struct RowView[T] {
data : Matrix[T]
row : Int
}
pub struct ColView[T] {
data : Matrix[T]
col : Int
}
字段可读。通过视图写入会改变底层矩阵。
Transpose
Transpose[T] 是矩阵的实时转置视图。
pub struct Transpose[T](Matrix[T])
它与被包装的矩阵共享存储。它的方法寻址转置后的矩阵:视图的元素 就是矩阵的元素 。
Vector
Vector[A] 是可变稠密向量,是 Array[A] 的包装类型。
pub struct Vector[A](Array[A])
数组可通过 v.0 读取。它实现了 Eq、Show(|a, b, c|)、Add、Mul(逐元素)、Neg、Debug 以及 quickcheck 的 Arbitrary。
Tolerance
Tolerance 提供数值例程使用的绝对阈值。
pub trait Tolerance {
fn tolerance() -> Self
}
pub impl Tolerance for Float
pub impl Tolerance for Double
两个实例都返回 。该 trait 不是开放的:其他包不能添加实例。阈值如何以及在何处使用,见 mutable 设计。
Sqrt
Sqrt 是 Luna-Flow/arithmetic.Sqrt 的重新导出,cholesky_decomposition、eigen、is_positive_definite、frobenius_norm 和 std_dev 需要它。
pub using @arithmetic {trait Sqrt}
构造
Matrix::make
Matrix::make(r, c, f) 构造元素为 的 矩阵。
pub fn[A] Matrix::make(Int, Int, (Int, Int) -> A) -> Self[A]
负维度会中止。f 应当是纯函数;对同一元素调用它的次数未作规定。
Matrix::new
Matrix::new(r, c, x) 构造一个以 x 填充的 矩阵。
pub fn[T] Matrix::new(Int, Int, T) -> Self[T]
Matrix::from_2d_array
Matrix::from_2d_array(rows) 把嵌套的行复制到新矩阵中。
pub fn[T] Matrix::from_2d_array(Array[Array[T]]) -> Self[T]
[] 得到 ;行长不一致时中止。
Matrix::from_array
Matrix::from_array(r, c, data) 将 data 直接作为 矩阵的行主序存储。
pub fn[T] Matrix::from_array(Int, Int, Array[T]) -> Self[T]
负维度或 data.length() != r * c 会中止。数组不会被复制:之后对 data 的写入会改变矩阵,反之亦然。
identity
identity(n) 构造 单位矩阵。它是顶层函数 @mutable.identity(n)。
pub fn[T : @luna-generic.Zero + @luna-generic.One] identity(Int) -> Matrix[T]
Matrix::copy
Matrix::copy(m) 返回拥有独立存储的深拷贝。
pub fn[T] Matrix::copy(Self[T]) -> Self[T]
///|
test "mutable construction and aliasing" {
let data = [1, 2, 3, 4]
let shared = @mutable.Matrix::from_array(2, 2, data)
data[0] = 100
inspect(shared.get(0, 0), content="100")
let separate = shared.copy()
shared.set(0, 0, 1)
inspect(separate.get(0, 0), content="100")
let id : @mutable.Matrix[Double] = @mutable.identity(2)
inspect(id, content="|1, 0|\n|0, 1|")
inspect(
@mutable.Matrix::make(2, 3, (i, j) => i * 3 + j),
content="|0, 1, 2|\n|3, 4, 5|",
)
}
形状与元素访问
Matrix::row, Matrix::col, Matrix::shape
行数、列数以及 (row, col)。
pub fn[T] Matrix::row(Self[T]) -> Int
pub fn[T] Matrix::col(Self[T]) -> Int
pub fn[T] Matrix::shape(Self[T]) -> (Int, Int)
Matrix::is_square
Matrix::is_square(m) 返回 row() == col()。
pub fn[T] Matrix::is_square(Self[T]) -> Bool
Matrix::get, Matrix::set
get(r, c) 读取元素 ;set(r, c, x) 原地写入该元素。
pub fn[T] Matrix::get(Self[T], Int, Int) -> T
pub fn[T] Matrix::set(Self[T], Int, Int, T) -> Unit
二者均为 ,索引越界时中止。它们是访问单个元素最快的方式。
Matrix::at
Matrix::at(m, r) 返回第 r 行的 Lens;它支撑 m[r][c] 与 m[r][c] = x。
#alias("_[_]")
pub fn[T] Matrix::at(Self[T], Int) -> Lens[T]
Matrix::row_view, Matrix::col_view
row_view(r) 与 col_view(c) 返回一行或一列的实时视图。
pub fn[T] Matrix::row_view(Self[T], Int) -> RowView[T]
pub fn[T] Matrix::col_view(Self[T], Int) -> ColView[T]
索引在创建视图时检查。
Matrix::to_transpose
Matrix::to_transpose(m) 在 时间内返回与 m 共享存储的实时转置视图。
pub fn[T] Matrix::to_transpose(Self[T]) -> Transpose[T]
Matrix::equal, Matrix::to_string
equal 比较形状和元素(支撑 ==);to_string 把每行渲染为 |a, b| 形式的一行。
pub fn[T : Eq] Matrix::equal(Self[T], Self[T]) -> Bool
pub fn[T : Show] Matrix::to_string(Self[T]) -> String
///|
test "mutable access" {
let m = @mutable.Matrix::from_2d_array([[1, 2, 3], [4, 5, 6]])
m[0][2] = 30
m.set(1, 0, 40)
inspect(m.get(0, 2), content="30")
inspect(m[1][0], content="40")
let r = m.row_view(1)
r[2] = 60
inspect(m, content="|1, 2, 30|\n|40, 5, 60|")
debug_inspect(m.shape(), content="(2, 3)")
}
遍历与原地变换
Matrix::each, Matrix::eachi
each(f) 按行主序对每个元素调用 f;eachi(f) 还会传入扁平的行主序索引。
pub fn[T] Matrix::each(Self[T], (T) -> Unit) -> Unit
pub fn[T] Matrix::eachi(Self[T], (Int, T) -> Unit) -> Unit
Matrix::each_row_col
each_row_col(f) 按行主序对每个元素调用 f(i, j, a_ij)。
pub fn[T] Matrix::each_row_col(Self[T], (Int, Int, T) -> Unit) -> Unit
Matrix::each_row, Matrix::eachi_row, Matrix::each_col, Matrix::eachi_col
访问一行(从左到右)或一列(从上到下);eachi_* 形式会传入元素在该行或该列中的位置。
pub fn[T] Matrix::each_row(Self[T], Int, (T) -> Unit) -> Unit
pub fn[T] Matrix::eachi_row(Self[T], Int, (Int, T) -> Unit) -> Unit
pub fn[T] Matrix::each_col(Self[T], Int, (T) -> Unit) -> Unit
pub fn[T] Matrix::eachi_col(Self[T], Int, (Int, T) -> Unit) -> Unit
Matrix::iter, Matrix::iter_row, Matrix::iter_col
遍历全部元素(行主序)、一行或一列的迭代器。
pub fn[T] Matrix::iter(Self[T]) -> Iter[T]
pub fn[T] Matrix::iter_row(Self[T], Int) -> Iter[T]
pub fn[T] Matrix::iter_col(Self[T], Int) -> Iter[T]
Matrix::map, Matrix::mapi
map(f) 与 mapi(f) 返回对每个元素应用 f 后的新矩阵;mapi 还会收到 (i, j)。
pub fn[T, U] Matrix::map(Self[T], (T) -> U) -> Self[U]
pub fn[T, U] Matrix::mapi(Self[T], (Int, Int, T) -> U) -> Self[U]
Matrix::map_inplace, Matrix::map_row_inplace, Matrix::map_col_inplace
将每个元素、某一行的每个元素或某一列的每个元素原地替换为 f(entry)。
#alias(map_in_place, deprecated)
pub fn[T] Matrix::map_inplace(Self[T], (T) -> T) -> Unit
#alias(map_row_in_place, deprecated)
pub fn[T] Matrix::map_row_inplace(Self[T], Int, (T) -> T) -> Unit
#alias(map_col_in_place, deprecated)
pub fn[T] Matrix::map_col_inplace(Self[T], Int, (T) -> T) -> Unit
Matrix::swap_rows, Matrix::swap_cols
原地交换两行或两列。
pub fn[T] Matrix::swap_rows(Self[T], Int, Int) -> Unit
pub fn[T] Matrix::swap_cols(Self[T], Int, Int) -> Unit
索引越界时中止;两个索引相等时矩阵保持不变。
///|
test "mutable traversal" {
let m = @mutable.Matrix::from_2d_array([[1, 2], [3, 4]])
let mut sum = 0
m.each(x => sum = sum + x)
inspect(sum, content="10")
m.map_col_inplace(1, x => x * 10)
m.swap_rows(0, 1)
inspect(m, content="|3, 40|\n|1, 20|")
debug_inspect(m.iter_col(0).to_array(), content="[3, 1]")
}
转换
Matrix::to_array, Matrix::to_2d_array, Matrix::to_vector
将所有元素复制到扁平的行主序数组、嵌套行或扁平的 Vector 中。
pub fn[T] Matrix::to_array(Self[T]) -> Array[T]
pub fn[T] Matrix::to_2d_array(Self[T]) -> Array[Array[T]]
pub fn[T] Matrix::to_vector(Self[T]) -> Vector[T]
Matrix::row_to_array, Matrix::col_to_array, Matrix::row_to_vector, Matrix::col_to_vector
将一行或一列复制到数组或 Vector 中。
pub fn[T] Matrix::row_to_array(Self[T], Int) -> Array[T]
pub fn[T] Matrix::col_to_array(Self[T], Int) -> Array[T]
pub fn[T] Matrix::row_to_vector(Self[T], Int) -> Vector[T]
pub fn[T] Matrix::col_to_vector(Self[T], Int) -> Vector[T]
Matrix::transpose
Matrix::transpose(m) 返回一个新的、已物化的转置;对比 to_transpose,后者返回视图。
pub fn[T] Matrix::transpose(Self[T]) -> Self[T]
Matrix::horizontal_combine, Matrix::vertical_combine
分块拼接 与 ;行数(或列数)不同时中止。
pub fn[T] Matrix::horizontal_combine(Self[T], Self[T]) -> Self[T]
pub fn[T] Matrix::vertical_combine(Self[T], Self[T]) -> Self[T]
算术运算
Matrix::add, Matrix::sub, Matrix::neg
逐元素的 、、;它们支撑相应运算符,形状不同时中止。
pub fn[T : Add] Matrix::add(Self[T], Self[T]) -> Self[T]
pub fn[T : Add + Neg] Matrix::sub(Self[T], Self[T]) -> Self[T]
pub fn[T : Neg] Matrix::neg(Self[T]) -> Self[T]
Matrix::scale, Matrix::add_constant
将每个元素右乘一个标量,或给每个元素加上一个标量。
pub fn[T : Mul] Matrix::scale(Self[T], T) -> Self[T]
pub fn[T : Add] Matrix::add_constant(Self[T], T) -> Self[T]
Matrix::adjoint
Matrix::adjoint(m) 返回共轭转置 ;它要求标量类型实现 Conjugate。
pub fn[T : @luna-generic.Conjugate] Matrix::adjoint(Self[T]) -> Self[T]
Matrix::null
当每个元素都严格等于 Zero::zero() 时,Matrix::null(m) 返回 true。
pub fn[T : Compare + @luna-generic.Zero] Matrix::null(Self[T]) -> Bool
Matrix::mul
Matrix::mul(a, b) 是 a * b 背后的矩阵乘积。
pub fn[T : @luna-generic.AddMonoid + Mul] Matrix::mul(Self[T], Self[T]) -> Self[T]
它检查 ,不满足时以 Matrix::mul: dimension mismatch 中止,满足时调用 unchecked_matmul。本包没有返回 Result 的 matmul;请先检查形状,或使用 @immut.Matrix::matmul。
Matrix::unchecked_matmul
Matrix::unchecked_matmul(a, b) 返回 ,不验证形状。
pub fn[T : @luna-generic.AddMonoid + Mul] Matrix::unchecked_matmul(Self[T], Self[T]) -> Self[T]
开销: 次乘加。较大的乘积(至少 )会先把 的列连续打包,再做乘法。
Matrix::mul_vec
当 时,Matrix::mul_vec(a, x) 返回 Ok(Ax),否则返回 DimensionMismatch。
pub fn[T : @luna-generic.AddMonoid + Mul] Matrix::mul_vec(Self[T], Vector[T]) -> Result[Vector[T], @error.LinearAlgebraError]
Matrix::unchecked_mul_vec
Matrix::unchecked_mul_vec(a, x) 返回 ,长度不匹配时中止。
pub fn[T : @luna-generic.AddMonoid + Mul] Matrix::unchecked_mul_vec(Self[T], Vector[T]) -> Vector[T]
Matrix::pow, Matrix::matrix_power
对方阵 和 ,pow(k) 通过二进制快速幂返回 Ok(A^k)()。matrix_power 是同一函数的另一个名字。
pub fn[T : @luna-generic.Semiring] Matrix::pow(Self[T], Int) -> Result[Self[T], @error.LinearAlgebraError]
pub fn[T : @luna-generic.Semiring] Matrix::matrix_power(Self[T], Int) -> Result[Self[T], @error.LinearAlgebraError]
错误:NonSquareMatrix(先检查),然后是 NegativeExponent。
Matrix::unchecked_pow, Matrix::unchecked_matrix_power
pow 与 matrix_power 的中止形式。
pub fn[T : @luna-generic.Semiring] Matrix::unchecked_pow(Self[T], Int) -> Self[T]
pub fn[T : @luna-generic.Semiring] Matrix::unchecked_matrix_power(Self[T], Int) -> Self[T]
Matrix::trace, Matrix::unchecked_trace
对方阵,trace() 返回 Ok(Σ a_ii),否则返回 NonSquareMatrix;unchecked_trace 则改为中止。
pub fn[T : @luna-generic.AddMonoid] Matrix::trace(Self[T]) -> Result[T, @error.LinearAlgebraError]
pub fn[T : @luna-generic.AddMonoid] Matrix::unchecked_trace(Self[T]) -> T
///|
test "mutable arithmetic" {
let a = @mutable.Matrix::from_2d_array([[1.0, 2.0], [3.0, 4.0]])
let x = @mutable.Vector::from_array([1.0, 1.0])
inspect(a.mul_vec(x).unwrap(), content="|3, 7|")
inspect(a * a, content="|7, 10|\n|15, 22|")
inspect(a.pow(0).unwrap(), content="|1, 0|\n|0, 1|")
inspect(a.trace().unwrap(), content="5")
inspect(
a.mul_vec(@mutable.Vector::from_array([1.0])) is Err(_),
content="true",
)
}
线性方程组与分解
本节所有例程都面向 Float 与 Double 矩阵。诸如“该主元为零”之类的判断,是将绝对值与 Tolerance::tolerance()()比较;算法、开销与误差界见设计页面。
Matrix::determinant
对于方阵,Matrix::determinant(a) 返回 Ok(det A);否则返回 NonSquareMatrix。
pub fn[T : Compare + @luna-generic.Field + @luna-generic.Num + Tolerance] Matrix::determinant(Self[T]) -> Result[T, @error.LinearAlgebraError]
当 时:使用闭式余子式公式。当 时:若矩阵在容差内为三角矩阵,则取对角线乘积;否则做部分选主元的 LU 分解,对 次行交换有 。若某个主元低于容差,结果严格为零。 矩阵的 为 。
Matrix::unchecked_determinant
determinant 的中止形式。
pub fn[T : Compare + @luna-generic.Field + @luna-generic.Num + Tolerance] Matrix::unchecked_determinant(Self[T]) -> T
Matrix::inverse
Matrix::inverse(a) 返回 Ok(A^{-1});对非方阵返回 NonSquareMatrix;当某个主元低于容差时返回 SingularMatrix。
pub fn[T : Compare + @luna-generic.Field + @luna-generic.Num + Tolerance] Matrix::inverse(Self[T]) -> Result[Self[T], @error.LinearAlgebraError]
单位矩阵、对角矩阵和置换矩阵会被识别并直接求逆();其他矩阵则基于部分选主元的 LU 分解逐列求解。开销 flops。 矩阵的逆矩阵是 矩阵。
Matrix::unchecked_inverse
Matrix::unchecked_inverse(a) 返回 Some(A^{-1}),对奇异矩阵返回 None,对非方阵则中止。
pub fn[T : Compare + @luna-generic.Field + @luna-generic.Num + Tolerance] Matrix::unchecked_inverse(Self[T]) -> Self[T]?
Matrix::is_invertible, Matrix::unchecked_is_invertible
当 LU 分解没有发现低于容差的主元时,is_invertible() 返回 Ok(true),否则返回 Ok(false);对非方阵返回 NonSquareMatrix;unchecked_is_invertible 则改为中止。
pub fn[T : Compare + @luna-generic.Field + @luna-generic.Num + Tolerance] Matrix::is_invertible(Self[T]) -> Result[Bool, @error.LinearAlgebraError]
pub fn[T : Compare + @luna-generic.Field + @luna-generic.Num + Tolerance] Matrix::unchecked_is_invertible(Self[T]) -> Bool
Matrix::rank
Matrix::rank(a) 返回在 a 的副本上做部分选主元高斯消元所找到的主元个数。
pub fn[T : Compare + @luna-generic.Field + @luna-generic.Num + Tolerance] Matrix::rank(Self[T]) -> Int
若某列剩余元素中的最大值低于容差,该列不贡献主元。适用于任意形状;a 保持不变。开销 。
Matrix::reduce_row_elimination
Matrix::reduce_row_elimination(a) 通过部分选主元的 Gauss–Jordan 消元把 a 原地变换为简化行阶梯形,并返回 a 本身。
pub fn[T : Compare + @luna-generic.Field + @luna-generic.Num + Tolerance] Matrix::reduce_row_elimination(Self[T]) -> Self[T]
主元被精确置为一,主元列的其他元素被精确置为零,过程中绝对值不超过容差的元素会被置零。如需保留原矩阵,请先复制。
Matrix::cholesky_decomposition
Matrix::cholesky_decomposition(a) 返回 Some(L),其中 为下三角矩阵、对角线为正且 ;否则返回 None。
pub fn[T : Compare + @luna-generic.Field + @luna-generic.Num + @arithmetic.Sqrt + Tolerance] Matrix::cholesky_decomposition(Self[T]) -> Self[T]?
None 表示 a 不是方阵、在容差内不对称,或者某个对角主元 不超过容差(矩阵不是正定的,或接近奇异)。开销 flops。
Matrix::is_positive_definite
Matrix::is_positive_definite(a) 返回 cholesky_decomposition 是否成功。
pub fn[T : Compare + @luna-generic.Field + @luna-generic.Num + @arithmetic.Sqrt + Tolerance] Matrix::is_positive_definite(Self[T]) -> Bool
Matrix::is_symmetric
当 a 是方阵且对所有 有 时,Matrix::is_symmetric(a) 返回 true。
pub fn[T : Compare + @luna-generic.Num + Tolerance] Matrix::is_symmetric(Self[T]) -> Bool
///|
test "solving and factorizing" {
let a = @mutable.Matrix::from_2d_array([[4.0, 2.0], [2.0, 3.0]])
inspect(a.determinant().unwrap(), content="8")
inspect(a.inverse().unwrap(), content="|0.375, -0.25|\n|-0.25, 0.5|")
let l = a.cholesky_decomposition().unwrap()
inspect(l, content="|2, 0|\n|1, 1.4142135623730951|")
inspect(a.is_positive_definite(), content="true")
let r = @mutable.Matrix::from_2d_array([
[1.0, 2.0, 3.0],
[2.0, 4.0, 6.0],
[7.0, 8.0, 9.0],
])
inspect(r.rank(), content="2")
inspect(r.is_invertible().unwrap(), content="false")
}
特征值
Matrix::eigen
Matrix::eigen(a) 以 (values, vectors) 的形式返回实对称矩阵的特征值与特征向量,其中 vectors 的第 列是对应 values[k] 的特征向量。
pub fn[T : Compare + @luna-generic.Field + @luna-generic.Num + @arithmetic.Sqrt + Tolerance] Matrix::eigen(Self[T]) -> (Vector[T], Self[T])
- 若
a不是方阵、在容差内不对称,或某个特征值在 60 次迭代内未收敛,则中止。 - 对 输入,特征值由特征多项式给出:,其中 ,并按 排序;特征向量列未归一化。
- 对其他规模,矩阵先通过 Householder 反射约化为三对角形式,再用带 Wilkinson 位移的隐式 QL 算法对角化。特征向量列在舍入误差范围内是标准正交的。特征值不排序。
- 开销 。
Matrix::power_method
Matrix::power_method(a, max_iterations) 通过幂迭代逼近主特征对 ,一旦 即返回 Some((λ, x))。
pub fn[T : Compare + @luna-generic.Field + @luna-generic.Num + Tolerance] Matrix::power_method(Self[T], Int) -> (T, Vector[T])?
- 被缩放使得 ; 是 Rayleigh 商 。
- 若迭代在
max_iterations步内未通过残差检验,或迭代向量在数值上变为零(例如对幂零矩阵),则返回None。两个模相等、符号相反的主特征值(例如 )会阻碍收敛。 - 对非方阵或空矩阵中止。
- 每次迭代的开销为一次矩阵-向量乘积,即 。
///|
test "eigenvalues" {
let a = @mutable.Matrix::from_2d_array([[2.0, 1.0], [1.0, 2.0]])
let (values, vectors) = a.eigen()
inspect(values, content="|3, 1|")
inspect(vectors, content="|1, 1|\n|1, -1|")
let b = @mutable.Matrix::from_2d_array([[2.0, 1.0], [1.0, 3.0]])
let (lambda, x) = b.power_method(200).unwrap()
inspect((lambda - 3.618033988749895).abs() < 1.0e-9, content="true")
inspect(x[1], content="1")
let flip = @mutable.Matrix::from_2d_array([[1.0, 0.0], [0.0, -1.0]])
inspect(flip.power_method(100) is None, content="true")
}
统计量与范数
统计函数把矩阵视为其 个元素组成的扁平列表。
Matrix::mean, Matrix::unchecked_mean
mean() 返回 Ok(\bar a),其中 ;当 时返回 EmptyMatrix;unchecked_mean 则改为中止。
pub fn[T : @luna-generic.Field] Matrix::mean(Self[T]) -> Result[T, @error.LinearAlgebraError]
pub fn[T : @luna-generic.Field] Matrix::unchecked_mean(Self[T]) -> T
Matrix::variance, Matrix::unchecked_variance
variance() 返回总体方差 (两遍算法),或返回 EmptyMatrix。
pub fn[T : @luna-generic.Field] Matrix::variance(Self[T]) -> Result[T, @error.LinearAlgebraError]
pub fn[T : @luna-generic.Field] Matrix::unchecked_variance(Self[T]) -> T
Matrix::std_dev, Matrix::unchecked_std_dev
std_dev() 返回总体方差的平方根,或返回 EmptyMatrix。
pub fn[T : @luna-generic.Field + @arithmetic.Sqrt] Matrix::std_dev(Self[T]) -> Result[T, @error.LinearAlgebraError]
pub fn[T : @luna-generic.Field + @arithmetic.Sqrt] Matrix::unchecked_std_dev(Self[T]) -> T
Matrix::max_element, Matrix::min_element
按 Compare 取最大或最小元素,或返回 EmptyMatrix。
pub fn[T : Compare] Matrix::max_element(Self[T]) -> Result[T, @error.LinearAlgebraError]
pub fn[T : Compare] Matrix::min_element(Self[T]) -> Result[T, @error.LinearAlgebraError]
若含有 NaN 元素,结果取决于它们的位置;请先将其过滤。
Matrix::unchecked_max_element, Matrix::unchecked_min_element
max_element 与 min_element 的中止形式。
pub fn[T : Compare] Matrix::unchecked_max_element(Self[T]) -> T
pub fn[T : Compare] Matrix::unchecked_min_element(Self[T]) -> T
Matrix::frobenius_norm
Matrix::frobenius_norm(a) 返回 。
pub fn[T : @luna-generic.AddMonoid + Mul + @arithmetic.Sqrt] Matrix::frobenius_norm(Self[T]) -> T
平方和不做缩放,因此对 Double 而言,大于约 的元素会溢出。空矩阵的范数为 。
///|
test "statistics" {
let m = @mutable.Matrix::from_2d_array([[1.0, 2.0], [3.0, 4.0]])
inspect(m.mean().unwrap(), content="2.5")
inspect(m.variance().unwrap(), content="1.25")
inspect(m.max_element().unwrap(), content="4")
inspect(
@mutable.Matrix::from_2d_array([[3.0, 4.0]]).frobenius_norm(),
content="5",
)
}
视图
RowView::get, RowView::set, ColView::get, ColView::set
读取或写入所视行或列的第 i 个位置;它们支撑 view[i] 与 view[i] = x。
#alias("_[_]")
pub fn[T] RowView::get(Self[T], Int) -> T
#alias("_[_]=_")
pub fn[T] RowView::set(Self[T], Int, T) -> Unit
#alias("_[_]")
pub fn[T] ColView::get(Self[T], Int) -> T
#alias("_[_]=_")
pub fn[T] ColView::set(Self[T], Int, T) -> Unit
RowView::length, ColView::length
矩阵的列数(行视图)或行数(列视图)。
pub fn[T] RowView::length(Self[T]) -> Int
pub fn[T] ColView::length(Self[T]) -> Int
RowView::each, RowView::eachi, RowView::iter, ColView::each, ColView::eachi, ColView::iter
按顺序遍历视图中的元素。
pub fn[T] RowView::each(Self[T], (T) -> Unit) -> Unit
pub fn[T] RowView::eachi(Self[T], (Int, T) -> Unit) -> Unit
pub fn[T] RowView::iter(Self[T]) -> Iter[T]
pub fn[T] ColView::each(Self[T], (T) -> Unit) -> Unit
pub fn[T] ColView::eachi(Self[T], (Int, T) -> Unit) -> Unit
pub fn[T] ColView::iter(Self[T]) -> Iter[T]
RowView::map_inplace, ColView::map_inplace
在底层矩阵中把视图中的每个元素替换为 f(entry)。
pub fn[T] RowView::map_inplace(Self[T], (T) -> T) -> Unit
pub fn[T] ColView::map_inplace(Self[T], (T) -> T) -> Unit
RowView::to_array, RowView::to_vector, ColView::to_array, ColView::to_vector
把视图中的元素复制出来。
pub fn[T] RowView::to_array(Self[T]) -> Array[T]
pub fn[T] RowView::to_vector(Self[T]) -> Vector[T]
pub fn[T] ColView::to_array(Self[T]) -> Array[T]
pub fn[T] ColView::to_vector(Self[T]) -> Vector[T]
RowView::to_string, ColView::to_string
把视图中的元素渲染为 |a, b, c|。
pub fn[T : Show] RowView::to_string(Self[T]) -> String
pub fn[T : Show] ColView::to_string(Self[T]) -> String
转置视图
除非文档说明返回新值,Transpose 的每个方法都寻址转置后的矩阵,并作用于共享存储。
Transpose::row, Transpose::col
视图的形状:row() 是被包装矩阵的列数,col() 是其行数。
pub fn[T] Transpose::row(Self[T]) -> Int
pub fn[T] Transpose::col(Self[T]) -> Int
Transpose::get, Transpose::set, Transpose::at
get(i, j) 与 set(i, j, x) 访问视图的元素 ,即矩阵的元素 ;at 支撑 t[i][j] 与 t[i][j] = x。
pub fn[T] Transpose::get(Self[T], Int, Int) -> T
pub fn[T] Transpose::set(Self[T], Int, Int, T) -> Unit
#alias("_[_]")
pub fn[T] Transpose::at(Self[T], Int) -> Lens[T]
Transpose::transpose
Transpose::transpose(t) 返回被包装的矩阵本身,而不是副本。
pub fn[T] Transpose::transpose(Self[T]) -> Matrix[T]
Transpose::materialize
Transpose::materialize(t) 把视图复制到一个具有转置形状的新矩阵中。
pub fn[T] Transpose::materialize(Self[T]) -> Matrix[T]
Transpose::copy
Transpose::copy(t) 返回被包装矩阵深拷贝的视图。
pub fn[T] Transpose::copy(Self[T]) -> Self[T]
遍历:Transpose::each、Transpose::eachi、Transpose::each_row_col、Transpose::each_row、Transpose::eachi_row、Transpose::each_col、Transpose::eachi_col
遍历视图。
pub fn[T] Transpose::each(Self[T], (T) -> Unit) -> Unit
pub fn[T] Transpose::eachi(Self[T], (Int, T) -> Unit) -> Unit
pub fn[T] Transpose::each_row_col(Self[T], (Int, Int, T) -> Unit) -> Unit
pub fn[T] Transpose::each_row(Self[T], Int, (T) -> Unit) -> Unit
pub fn[T] Transpose::eachi_row(Self[T], Int, (Int, T) -> Unit) -> Unit
pub fn[T] Transpose::each_col(Self[T], Int, (T) -> Unit) -> Unit
pub fn[T] Transpose::eachi_col(Self[T], Int, (Int, T) -> Unit) -> Unit
each、eachi 和 each_row_col 按被包装矩阵的存储顺序访问元素,对视图而言这是列主序;eachi 传入的是视图的行主序索引,each_row_col 传入视图坐标。行和列形式按顺序访问视图的一行或一列。
Transpose::row_to_array, Transpose::col_to_array, Transpose::row_to_vector, Transpose::col_to_vector
复制视图的一行或一列。
pub fn[T] Transpose::row_to_array(Self[T], Int) -> Array[T]
pub fn[T] Transpose::col_to_array(Self[T], Int) -> Array[T]
pub fn[T] Transpose::row_to_vector(Self[T], Int) -> Vector[T]
pub fn[T] Transpose::col_to_vector(Self[T], Int) -> Vector[T]
Transpose::map, Transpose::map_inplace, Transpose::map_row_inplace, Transpose::map_col_inplace
map 返回一个新矩阵的新视图;*_inplace 形式修改共享存储。
pub fn[T] Transpose::map(Self[T], (T) -> T) -> Self[T]
#alias(map_in_place, deprecated)
pub fn[T] Transpose::map_inplace(Self[T], (T) -> T) -> Unit
#alias(map_row_in_place, deprecated)
pub fn[T] Transpose::map_row_inplace(Self[T], Int, (T) -> T) -> Unit
#alias(map_col_in_place, deprecated)
pub fn[T] Transpose::map_col_inplace(Self[T], Int, (T) -> T) -> Unit
Transpose::swap_rows, Transpose::swap_cols
原地交换视图的两行或两列(即被包装矩阵的两列或两行)。
pub fn[T] Transpose::swap_rows(Self[T], Int, Int) -> Unit
pub fn[T] Transpose::swap_cols(Self[T], Int, Int) -> Unit
Transpose::horizontal_combine, Transpose::vertical_combine
视图的分块拼接,返回一个新矩阵的视图。
pub fn[T] Transpose::horizontal_combine(Self[T], Self[T]) -> Self[T]
pub fn[T] Transpose::vertical_combine(Self[T], Self[T]) -> Self[T]
Transpose::add, Transpose::sub, Transpose::neg, Transpose::scale, Transpose::add_constant
逐元素算术,返回一个新矩阵的视图。
pub fn[T : Add] Transpose::add(Self[T], Self[T]) -> Self[T]
pub fn[T : Add + Neg] Transpose::sub(Self[T], Self[T]) -> Self[T]
pub fn[T : Neg] Transpose::neg(Self[T]) -> Self[T]
pub fn[T : Mul] Transpose::scale(Self[T], T) -> Self[T]
pub fn[T : Add] Transpose::add_constant(Self[T], T) -> Self[T]
Transpose::mul
Transpose::mul(s, t) 返回两个视图的乘积,按 计算,无需移动数据。
pub fn[T : @luna-generic.AddMonoid + Mul] Transpose::mul(Self[T], Self[T]) -> Self[T]
Transpose::equal, Transpose::to_string
equal 比较被包装的矩阵;to_string 逐行渲染视图。
pub fn[T : Eq] Transpose::equal(Self[T], Self[T]) -> Bool
pub fn[T : Show] Transpose::to_string(Self[T]) -> String
///|
test "transpose view" {
let m = @mutable.Matrix::from_2d_array([[1, 2, 3], [4, 5, 6]])
let t = m.to_transpose()
inspect(t, content="|1, 4|\n|2, 5|\n|3, 6|")
t[2][0] = 30
inspect(m.get(0, 2), content="30")
let s = @mutable.Matrix::from_2d_array([[1, 0], [0, 1], [1, 1]]).to_transpose()
let product = t * s
debug_inspect((product.row(), product.col()), content="(3, 3)")
inspect(t.materialize().row(), content="3")
let order = []
t.each(x => order.push(x))
debug_inspect(order, content="[1, 2, 30, 4, 5, 6]")
}
向量
Vector::from_array
Vector::from_array(xs) 直接将 xs 作为向量的存储,不做复制。
pub fn[A] Vector::from_array(Array[A]) -> Self[A]
Vector::make, Vector::makei
某个值的 份拷贝,或 。
pub fn[A] Vector::make(Int, A) -> Self[A]
pub fn[A] Vector::makei(Int, (Int) -> A) -> Self[A]
Vector::length, Vector::copy, Vector::iter
长度、深拷贝与迭代器。
pub fn[A] Vector::length(Self[A]) -> Int
pub fn[A] Vector::copy(Self[A]) -> Self[A]
pub fn[T] Vector::iter(Self[T]) -> Iter[T]
Vector::at, Vector::set
原地读取或写入第 i 个元素;它们支撑 v[i] 与 v[i] = x。索引越界时中止。
#alias("_[_]")
pub fn[A] Vector::at(Self[A], Int) -> A
#alias("_[_]=_")
pub fn[A] Vector::set(Self[A], Int, A) -> Unit
Vector::map, Vector::zip_with, Vector::map_inplace
map 与 zip_with 返回新向量(zip_with 在长度不同时中止);map_inplace 改写每个元素。
pub fn[A, B] Vector::map(Self[A], (A) -> B) -> Self[B]
pub fn[A, U, V] Vector::zip_with(Self[A], Self[U], (A, U) -> V) -> Self[V]
#alias(map_in_place, deprecated)
pub fn[A] Vector::map_inplace(Self[A], (A) -> A) -> Unit
Vector::add, Vector::mul, Vector::neg, Vector::add_constant
逐元素的 、Hadamard 积 、 以及 。长度不同时中止。没有 Sub;请写作 u + -v。
pub fn[T : Add] Vector::add(Self[T], Self[T]) -> Self[T]
pub fn[T : Mul] Vector::mul(Self[T], Self[T]) -> Self[T]
pub fn[T : Neg] Vector::neg(Self[T]) -> Self[T]
pub fn[T : Add] Vector::add_constant(Self[T], T) -> Self[T]
Vector::left_scale, Vector::right_scale, Vector::left_scale_inplace, Vector::right_scale_inplace
与 ,可得到新向量,也可原地进行。
pub fn[A : Mul] Vector::left_scale(Self[A], A) -> Self[A]
pub fn[A : Mul] Vector::right_scale(Self[A], A) -> Self[A]
#alias(left_scale_in_place, deprecated)
pub fn[A : Mul] Vector::left_scale_inplace(Self[A], A) -> Unit
#alias(right_scale_in_place, deprecated)
pub fn[A : Mul] Vector::right_scale_inplace(Self[A], A) -> Unit
Vector::dot
Vector::dot(u, v) 返回 ,从左到右求和;长度不同时中止。
pub fn[T : @luna-generic.AddMonoid + Mul] Vector::dot(Self[T], Self[T]) -> T
Vector::lerp
Vector::lerp(u, v, t) 返回 。
pub fn[T : @luna-generic.MulMonoid + Add + Neg] Vector::lerp(Self[T], Self[T], T) -> Self[T]
Vector::lin_comb
Vector::lin_comb(weights, vectors) 一遍计算出 。
pub fn[T : Mul + Add + @luna-generic.Zero] Vector::lin_comb(Array[T], Array[Self[T]]) -> Self[T]
输入为空、权重与向量个数不同,或向量长度不同时中止。
lin_comb
lin_comb(a, u, b, v) 返回 ;它是顶层函数。
pub fn[T : Add + Mul] lin_comb(T, Vector[T], T, Vector[T]) -> Vector[T]
Vector::to_row_matrix, Vector::to_col_matrix, Vector::scaled_matrix, Vector::tensor_product
把向量作为 或 矩阵(复制)、对角矩阵 ,以及外积 。
pub fn[T] Vector::to_row_matrix(Self[T]) -> Matrix[T]
pub fn[T] Vector::to_col_matrix(Self[T]) -> Matrix[T]
pub fn[T : @luna-generic.Zero] Vector::scaled_matrix(Self[T]) -> Matrix[T]
pub fn[T : Mul] Vector::tensor_product(Self[T], Self[T]) -> Matrix[T]
Vector::equal, Vector::to_string
equal 比较元素(支撑 ==);to_string 渲染为 |a, b, c|。
pub fn[T : Eq] Vector::equal(Self[T], Self[T]) -> Bool
pub fn[T : Show] Vector::to_string(Self[T]) -> String
///|
test "mutable vectors" {
let v = @mutable.Vector::from_array([1, 2, 3])
v[0] = 10
v.left_scale_inplace(2)
inspect(v, content="|20, 4, 6|")
inspect(v.dot(@mutable.Vector::make(3, 1)), content="30")
let w = @mutable.Vector::lin_comb([1, 2], [
v,
@mutable.Vector::makei(3, i => i),
])
inspect(w, content="|20, 6, 10|")
inspect(@mutable.lin_comb(1, v, -1, w), content="|0, -2, -4|")
}
已弃用
| 项 | 替代方案 |
|---|---|
Matrix::map_in_place、map_row_in_place、map_col_in_place(别名) | map_inplace, map_row_inplace, map_col_inplace |
Transpose::map_in_place、map_row_in_place、map_col_in_place(别名) | *_inplace 系列名称 |
Vector::map_in_place、left_scale_in_place、right_scale_in_place(别名) | map_inplace, left_scale_inplace, right_scale_inplace |
Matrix、Transpose、Vector 上的 not_equal 方法形式(隐藏) | != |
Matrix、Transpose、RowView、ColView、Vector 上的 output 方法形式(隐藏) | 字符串插值或 Show::output(x, logger) |
Vector::to_repr(隐藏) | Repr(v) 或 @debug.Debug::to_repr(v) |
Vector::arbitrary(隐藏) | @quickcheck.Arbitrary::arbitrary |