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]

配列はコピーされません。@mutable.Vector::from_array と同様に、ラッパーと xs は格納領域を共有します。

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) は x で埋めた長さ n のベクトルを作ります。

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: Add、Neg、Sub、Mul(行列積)、すべての T に対する @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) は行列とベクトルの積 AxA 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) は x で埋めた長さ n のベクトルを作ります。

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