immut API

Luna-Flow/linear-algebra/immut は値指向の稠密線形代数を提供します。Matrix[T] と Vector[T] は永続ベクトルに支えられた不変の値で、MatrixFn[T] は座標の関数で与えられる遅延行列です。すべての演算は新しい値を返し、引数を変更しません。

ソース: src/immut。値の意味論、行列式のアルゴリズム、コストモデルは immut の設計 で説明しています。mutable は同じ中核の名前を持つインプレース版です。

インポート

///|
import {
  "Luna-Flow/linear-algebra/immut",
}

規約

  • 形状。 行列は row() 行 col() 列を持ち、どちらも非負です。0×n0 \times n と n×0n \times 0 は有効で互いに異なり、== は形状と成分を比較します。
  • 格納。 成分は行優先の順で永続ベクトル(moonbitlang/core/immut/vector、32 分岐のトライ)に格納されます。一つの成分の読み取りや置き換えのコストは O(log⁡32(rc))O(\log_{32}(rc)) で、行列全体の演算は O(rc)O(rc) です。
  • インデックス。 m[r][c] は成分を読みます。m[r](Matrix::at)が行アクセサ Indexed[T] を返し、[c](Indexed::at)がそこから読みます。どちらのインデックスも境界検査され、範囲外なら中断します。m[r][c] = x はありません。新しい行列を返す set を使ってください。
  • 検査付きと検査なし。 matmul、trace、determinant、pow は Result[_, LinearAlgebraError] を返します。対応する unchecked_* と演算子 +、-、* は、事前条件が満たされないと中断します。両者を結ぶ法則は error の設計 を参照してください。
  • スカラー。 制約は luna-generic の Zero、One、Semiring、Num(abs と signum を持つ環)、Conjugate から来ます。

型

Matrix

Matrix[T] は不変の稠密な r×cr \times c 行列です。

type Matrix[T] derive(Eq)

この型は抽象型なので、下記のコンストラクタで作ります。対応するメソッドの要素制約のもとで Eq、Show(各行を |a, b| として改行区切りで表示)、Add、Sub、Neg、Mul(行列積)を実装します。

Indexed

Indexed[T] は m[r] が返す行アクセサです。

type Indexed[T]

列インデックスから成分への関数であり、行のコピーは持ちません。

Indexed::at

Indexed::at(row, c) は列 c の成分を返し、m[r][c] の実体です。

#alias("_[_]")
pub fn[T] Indexed::at(Self[T], Int) -> T

0..<col() の外の列インデックスは中断します。

MatrixFn

MatrixFn[T] は遅延行列です。形状と関数 (i,j)↦aij(i, j) \mapsto a_{ij} の組です。

type MatrixFn[T]

成分は読み取りのたびに計算され、格納されることはありません。メソッドは MatrixFn の操作 に一覧があります。

Vector

Vector[T] は不変の稠密ベクトルです。

#alias(VecLib)
type Vector[T] derive(Eq)

Eq、Show(|a, b, c| と表示)、Add、Mul(要素ごと)、Neg、Debug、quickcheck の Arbitrary を実装します。

VecLib

VecLib[T] は Vector[T] のエイリアスです。

#alias(VecLib)
type Vector[T]

VecCore

VecCore[T] は Vector を支えるコアの永続ベクトル @moonbitlang/core/immut/vector.Vector[T] のエイリアスです。

pub using @vector {type Vector as VecCore}

行列の構築

Matrix::make

Matrix::make(r, c, f) は成分が aij=f(i,j)a_{ij} = f(i, j) の r×cr \times c 行列を作ります。

pub fn[T] Matrix::make(Int, Int, (Int, Int) -> T) -> Self[T]

f は各成分について行優先の順で一回ずつ呼ばれ、r=0r = 0 または c=0c = 0 のときは一度も呼ばれません。負の次元は中断します。

Matrix::new

Matrix::new(r, c, x) はすべての成分が x の r×cr \times c 行列を作ります。

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]

[] は 0×00 \times 0 に、[[], []] は 2×02 \times 0 になります。長さの異なる行は中断します。入力はコピーされます。

Matrix::from_array

Matrix::from_array(r, c, v) はベクトル v を r×cr \times c 行列の行優先の成分として使います。

pub fn[T] Matrix::from_array(Int, Int, Vector[T]) -> Self[T]

負の次元や v.length() != r * c は中断します。コピーはしません。v は不変だからです。

Matrix::identity

Matrix::identity(n) は n×nn \times n の単位行列 InI_n を作ります。

pub fn[T : @luna-generic.One + @luna-generic.Zero] Matrix::identity(Int) -> Self[T]

負の n は中断します。

///|
test "immut matrix construction" {
  let a = @immut.Matrix::make(2, 3, (i, j) => 10 * i + j)
  inspect(a, content="|0, 1, 2|\n|10, 11, 12|")
  let b = @immut.Matrix::from_array(
    2,
    2,
    @immut.Vector::from_array([1, 2, 3, 4]),
  )
  inspect(b, content="|1, 2|\n|3, 4|")
  let i3 : @immut.Matrix[Int] = @immut.Matrix::identity(3)
  inspect(i3, content="|1, 0, 0|\n|0, 1, 0|\n|0, 0, 1|")
  let empty : @immut.Matrix[Int] = @immut.Matrix::from_2d_array([[], []])
  debug_inspect(empty.shape(), content="(2, 0)")
}

形状とアクセス

Matrix::row, Matrix::col

row と col は行数と列数を返します。

pub fn[T] Matrix::row(Self[T]) -> Int
pub fn[T] Matrix::col(Self[T]) -> Int

Matrix::shape

Matrix::shape(m) は (row, col) を返します。

pub fn[T] Matrix::shape(Self[T]) -> (Int, Int)

Matrix::is_square

Matrix::is_square(m) は row() == col() を返します。0×00 \times 0 行列は正方行列です。

pub fn[T] Matrix::is_square(Self[T]) -> Bool

Matrix::null

Matrix::null(m) はすべての成分が Zero::zero() に等しいとき true を返します。空の行列は零行列とみなされます。

pub fn[T : Compare + @luna-generic.Zero] Matrix::null(Self[T]) -> Bool

Matrix::at

Matrix::at(m, r) は行 r のアクセサを返し、m[r] の実体です。

#alias("_[_]")
pub fn[T] Matrix::at(Self[T], Int) -> Indexed[T]

0..<row() の外の行インデックスはただちに中断します。

Matrix::set

Matrix::set(m, r, c, x) は成分 (r,c)(r, c) が x である以外は m と等しい行列を返します。

pub fn[T] Matrix::set(Self[T], Int, Int, T) -> Self[T]

m は変化しません。範囲外のインデックスは中断します。コストは O(log⁡32(rc))O(\log_{32}(rc)) で、新しい行列はそれ以外の格納領域をすべて m と共有します。

Matrix::equal

Matrix::equal(a, b) は形状と成分を比較し、== の実体です。

pub fn[T : Eq] Matrix::equal(Self[T], Self[T]) -> Bool

Matrix::to_string

Matrix::to_string(m) は各行を |a, b| の行として \n でつないで表示します。

pub fn[T : Show] Matrix::to_string(Self[T]) -> String

空の行列は空文字列になります。

///|
test "immut access and update" {
  let m = @immut.Matrix::from_2d_array([[1, 2], [3, 4]])
  let m2 = m.set(0, 1, 20)
  inspect(m[0][1], content="2")
  inspect(m2[0][1], content="20")
  inspect(m == m2, content="false")
  inspect(m.is_square(), content="true")
  inspect(@immut.Matrix::new(2, 2, 0).null(), content="true")
}

要素ごとの変換

Matrix::map

Matrix::map(m, f) はすべての成分に f を適用します。要素型は変わってもかまいません。

pub fn[T, U] Matrix::map(Self[T], (T) -> U) -> Self[U]

Matrix::mapi

Matrix::mapi(m, f) はすべての成分に f(i, j, a_ij) を適用します。

pub fn[T, U] Matrix::mapi(Self[T], (Int, Int, T) -> U) -> Self[U]

Matrix::scale

Matrix::scale(m, a) はすべての成分に右から a を掛けます: (aija)(a_{ij} a)。

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

Matrix::add_constant

Matrix::add_constant(m, a) はすべての成分に a を加えます。

pub fn[T : Add] Matrix::add_constant(Self[T], T) -> Self[T]

Matrix::adjoint

Matrix::adjoint(m) は共役転置 A∗A^{*}((A∗)ij=aji‾(A^{*})_{ij} = \overline{a_{ji}})を返します。

pub fn[T : @luna-generic.Conjugate] Matrix::adjoint(Self[T]) -> Self[T]

複素数型のように Conjugate を実装したスカラー型が必要です。組み込みの実数型は実装していません。

///|
test "immut element-wise transforms" {
  let m = @immut.Matrix::from_2d_array([[1, 2], [3, 4]])
  inspect(m.map(x => x * x), content="|1, 4|\n|9, 16|")
  inspect(
    m.mapi((i, j, x) => if i == j { x } else { 0 }),
    content="|1, 0|\n|0, 4|",
  )
  inspect(m.scale(10).add_constant(1), content="|11, 21|\n|31, 41|")
}

算術

Matrix::add, Matrix::sub, Matrix::neg

要素ごとの A+BA + B、A−BA - B、−A-A で、演算子の実体です。

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::mul

Matrix::mul(a, b) は a * b の背後にある行列積で、unchecked_matmul と同じです。

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

Matrix::matmul

Matrix::matmul(a, b) は cols⁡(A)=rows⁡(B)\operatorname{cols}(A) = \operatorname{rows}(B) なら Ok(AB) を、そうでなければ種類 DimensionMismatch の Err を返します。

pub fn[T : Mul + Add + @luna-generic.Zero] Matrix::matmul(Self[T], Self[T]) -> Result[Self[T], @error.LinearAlgebraError]

(AB)ik=∑jaijbjk(AB)_{ik} = \sum_{j} a_{ij} b_{jk} を jj の昇順に足し合わせます。内側の次元が 00 のとき、結果は空和である形状 rows⁡(A)×cols⁡(B)\operatorname{rows}(A) \times \operatorname{cols}(B) の零行列です。コスト: rcnrcn 回の積和と、BB の転置コピー O(cn)O(cn)。

Matrix::unchecked_matmul

Matrix::unchecked_matmul(a, b) は ABAB を返し、形状が両立しないと中断します。

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

Matrix::pow

Matrix::pow(a, k) は正方行列と k≥0k \ge 0 に対して Ok(A^k) を返します。A0=IA^0 = I です。

pub fn[T : @luna-generic.Semiring] Matrix::pow(Self[T], Int) -> Result[Self[T], @error.LinearAlgebraError]

正方でない行列は NonSquareMatrix(最初に検査)、負の指数は NegativeExponent になります。べき乗は二進累乗法で、行列積は高々 2⌊log⁡2k⌋+12\lfloor\log_2 k\rfloor + 1 回です。

Matrix::unchecked_pow

Matrix::unchecked_pow(a, k) は AkA^k を返し、正方でない行列や負の指数では中断します。

pub fn[T : @luna-generic.Semiring] Matrix::unchecked_pow(Self[T], Int) -> Self[T]

Matrix::trace

Matrix::trace(a) は正方行列に対して Ok(tr A)(∑iaii\sum_i a_{ii})を、それ以外では NonSquareMatrix を返します。

pub fn[T : Add + @luna-generic.Zero] Matrix::trace(Self[T]) -> Result[T, @error.LinearAlgebraError]

0×00 \times 0 行列のトレースは Zero::zero() です。

Matrix::unchecked_trace

Matrix::unchecked_trace(a) は tr⁡A\operatorname{tr} A を返し、正方でない行列では中断します。

pub fn[T : Add + @luna-generic.Zero] Matrix::unchecked_trace(Self[T]) -> T

Matrix::determinant

Matrix::determinant(a) は正方行列に対して Ok(det A) を、それ以外では NonSquareMatrix を返します。

pub fn[T : Compare + @luna-generic.Num + Div] Matrix::determinant(Self[T]) -> Result[T, @error.LinearAlgebraError]

n≤4n \le 4 では閉じた余因子公式を評価し、n≥5n \ge 5 では行ピボット付きの分数なし(Bareiss)消去を行います。その除算は整域において割り切れます。したがって結果は BigInt では 厳密 であり、Int と Int64 でも途中の小行列式がオーバーフローしない限り厳密です。0×00 \times 0 行列の det⁡\det は One::one() です。コストは O(n3)O(n^3) です。導出は immut の設計 を参照してください。

Matrix::unchecked_determinant

Matrix::unchecked_determinant(a) は det⁡A\det A を返し、正方でない行列では中断します。

pub fn[T : Compare + @luna-generic.Num + Div] Matrix::unchecked_determinant(Self[T]) -> T
///|
test "immut checked algebra" {
  let a = @immut.Matrix::from_2d_array([[1, 1], [1, 0]])
  inspect(a.pow(10).unwrap(), content="|89, 55|\n|55, 34|")
  inspect(a.trace().unwrap(), content="1")
  inspect(a.determinant().unwrap(), content="-1")
  let r = @immut.Matrix::from_2d_array([[1, 2, 3]])
  inspect(r.matmul(r) is Err(_), content="true")
  inspect(r.matmul(r.transpose()).unwrap(), content="|14|")
}

///|
test "exact determinant with BigInt" {
  let h = @immut.Matrix::make(6, 6, (i, j) => BigInt::from_int(i * i + j + 1))
  let v = @immut.Matrix::make(6, 6, (i, j) => {
    let mut p = 1N
    for _ in 0..<j {
      p = p * BigInt::from_int(i + 2)
    }
    p
  })
  inspect(h.determinant().unwrap(), content="0")
  inspect(v.determinant().unwrap(), content="34560")
}

二つ目の行列は節点 2,…,72, \dots, 7 の Vandermonde 行列で、その行列式は ∏i<j(xj−xi)=1! 2! 3! 4! 5!=34560\prod_{i<j}(x_j - x_i) = 1!\,2!\,3!\,4!\,5! = 34560 です。

構造的な操作

Matrix::transpose

Matrix::transpose(m) は実体化された転置 ATA^{\mathsf T} を返します。

pub fn[T] Matrix::transpose(Self[T]) -> Self[T]

Matrix::horizontal_combine

Matrix::horizontal_combine(a, b) は b を a の右に並べたブロック行列 [A  B][A \; B] を作ります。

pub fn[T] Matrix::horizontal_combine(Self[T], Self[T]) -> Self[T]

行数が異なると中断します。

Matrix::vertical_combine

Matrix::vertical_combine(a, b) は b を a の下に並べます。

pub fn[T] Matrix::vertical_combine(Self[T], Self[T]) -> Self[T]

列数が異なると中断します。

Matrix::swap_rows, Matrix::swap_cols

swap_rows(i, j) と swap_cols(i, j) は二つの行または列を入れ替えた行列を返します。

pub fn[T] Matrix::swap_rows(Self[T], Int, Int) -> Self[T]
pub fn[T] Matrix::swap_cols(Self[T], Int, Int) -> Self[T]

範囲外のインデックスは中断します。同じインデックス同士の入れ替えは m 自身を返します。それ以外では行列全体を作り直し、O(rc)O(rc) かかります。

///|
test "immut structural operations" {
  let a = @immut.Matrix::from_2d_array([[1, 2], [3, 4]])
  let b = @immut.Matrix::from_2d_array([[5], [6]])
  inspect(a.horizontal_combine(b), content="|1, 2, 5|\n|3, 4, 6|")
  inspect(
    a.vertical_combine(a.swap_rows(0, 1)),
    content="|1, 2|\n|3, 4|\n|3, 4|\n|1, 2|",
  )
  inspect(a.transpose().swap_cols(0, 1), content="|3, 1|\n|4, 2|")
}

反復と変換

Matrix::iter

Matrix::iter(m) はすべての成分を行優先の順にたどります。

pub fn[T] Matrix::iter(Self[T]) -> Iter[T]

Matrix::iter_row, Matrix::iter_col

iter_row(r) は行 r を左から右へ、iter_col(c) は列 c を上から下へたどります。

pub fn[T] Matrix::iter_row(Self[T], Int) -> Iter[T]
pub fn[T] Matrix::iter_col(Self[T], Int) -> Iter[T]

範囲外のインデックスはイテレータを作る時点で中断します。

Matrix::to_array

Matrix::to_array(m) は成分を平坦な行優先の配列にコピーします。

pub fn[T] Matrix::to_array(Self[T]) -> Array[T]

Matrix::to_2d_array

Matrix::to_2d_array(m) は成分を入れ子の行配列にコピーします。

pub fn[T] Matrix::to_2d_array(Self[T]) -> Array[Array[T]]

r×0r \times 0 行列では、結果は rr 個の空の行になります。

///|
test "immut iteration" {
  let m = @immut.Matrix::from_2d_array([[1, 2], [3, 4]])
  debug_inspect(m.iter_col(1).to_array(), content="[2, 4]")
  debug_inspect(m.iter().fold(init=0, (s, x) => s + x), content="10")
  debug_inspect(m.to_2d_array(), content="[[1, 2], [3, 4]]")
}

MatrixFn の操作

MatrixFn の操作はすべて遅延的です。関数を合成するだけで、成分が読まれるまで何も計算しません。形状の検査はすぐに行い、境界の検査は読み取り時に行います。

MatrixFn::make

MatrixFn::make(r, c, f) は成分が f(i,j)f(i, j) の遅延行列を作ります。

pub fn[T] MatrixFn::make(Int, Int, (Int, Int) -> T) -> Self[T]

負の次元は中断します。形状の外の成分を読むと中断します。

MatrixFn::new

MatrixFn::new(r, c) は成分が T::default() の r×cr \times c 遅延行列を作ります。

pub fn[T : Default] MatrixFn::new(Int, Int) -> Self[T]

MatrixFn::from_2d_array

MatrixFn::from_2d_array(rows) は入れ子の行に対する遅延ビューを作ります。

pub fn[T] MatrixFn::from_2d_array(Array[Array[T]]) -> Self[T]

行の長さがそろっていない入力は中断します。配列はコピーされず捕捉されるので、あとからの書き込みは MatrixFn を通して見えます。

MatrixFn::identity

MatrixFn::identity(n) は遅延的な n×nn \times n 単位行列です。

pub fn[T : @luna-generic.One + @luna-generic.Zero] MatrixFn::identity(Int) -> Self[T]

MatrixFn::shape

MatrixFn::shape(m) は (rows, cols) を返します。

pub fn[T] MatrixFn::shape(Self[T]) -> (Int, Int)

MatrixFn::at

MatrixFn::at(m, r) は m[r][c] の背後にある行アクセサを返します。

#alias("_[_]")
pub fn[T] MatrixFn::at(Self[T], Int) -> Indexed[T]

行インデックスはすぐに、列インデックスは読み取り時に検査されます。

MatrixFn::map

MatrixFn::map(m, f) は各成分のあとに f を合成します。

pub fn[T, U] MatrixFn::map(Self[T], (T) -> U) -> Self[U]

MatrixFn::map_row, MatrixFn::map_col

map_row(r, f) と map_col(c, f) は一つの行または列に f を適用します。

pub fn[T] MatrixFn::map_row(Self[T], Int, (T) -> T) -> Self[T]
pub fn[T] MatrixFn::map_col(Self[T], Int, (T) -> T) -> Self[T]

範囲外のインデックスはただちに中断します。

MatrixFn::zip_with

MatrixFn::zip_with(a, b, f) は二つの遅延行列を成分ごとに組み合わせます。

pub fn[T, U, W] MatrixFn::zip_with(Self[T], Self[U], (T, U) -> W) -> Self[W]

形状が異なると中断します。

MatrixFn::fold

MatrixFn::fold(m, init~, f) はすべての成分を行優先の順で畳み込みます。

pub fn[T, U] MatrixFn::fold(Self[T], init~ : U, (U, T) -> U) -> U

これによりすべての成分が一回ずつ評価されます。

MatrixFn::add, MatrixFn::sub, MatrixFn::neg, MatrixFn::scale

遅延的な要素ごとの A+BA + B、A−BA - B、−A-A、AaA a です。

pub fn[T : Add] MatrixFn::add(Self[T], Self[T]) -> Self[T]
pub fn[T : Add + Neg] MatrixFn::sub(Self[T], Self[T]) -> Self[T]
pub fn[T : Neg] MatrixFn::neg(Self[T]) -> Self[T]
pub fn[T : Mul] MatrixFn::scale(Self[T], T) -> Self[T]

MatrixFn には公開された * 演算子がありません。pow を使うか Matrix に変換してください。

MatrixFn::pow

MatrixFn::pow(a, k) は二進累乗法で遅延的なべき乗 AkA^k を返します。

pub fn[T : @luna-generic.Semiring] MatrixFn::pow(Self[T], Int) -> Self[T]

正方でない入力や負の指数は中断します。何もキャッシュしないため、AkA^{k} の成分を一つ読むたびに入れ子の積が再計算され、深さ d≈log⁡2kd \approx \log_2 k の積の木では O(nd)O(n^{d}) 回の成分読み取りがかかります。多くの成分が必要なら、すべてを Matrix に読み込んでください。

MatrixFn::determinant

MatrixFn::determinant(a) は行列を実体化し、Matrix::determinant のアルゴリズムで行列式を返します。

pub fn[T : Compare + @luna-generic.Num + Div] MatrixFn::determinant(Self[T]) -> T

正方でない行列は中断します。検査付きの形はありません。

MatrixFn::transpose, MatrixFn::adjoint

遅延的な転置と共役転置です。

pub fn[T] MatrixFn::transpose(Self[T]) -> Self[T]
pub fn[T : @luna-generic.Conjugate] MatrixFn::adjoint(Self[T]) -> Self[T]

MatrixFn::swap_rows, MatrixFn::swap_cols

遅延的な行と列の入れ替えです。範囲外のインデックスは中断します。

pub fn[T] MatrixFn::swap_rows(Self[T], Int, Int) -> Self[T]
pub fn[T] MatrixFn::swap_cols(Self[T], Int, Int) -> Self[T]

MatrixFn::horizontal_combine, MatrixFn::vertical_combine

遅延的なブロック連結です。行数または列数が合わないと中断します。

pub fn[T] MatrixFn::horizontal_combine(Self[T], Self[T]) -> Self[T]
pub fn[T] MatrixFn::vertical_combine(Self[T], Self[T]) -> Self[T]

MatrixFn::equal, MatrixFn::to_string

equal は形状とすべての成分を(評価して)比較し、to_string は Matrix と同じ形で表示します。

pub fn[T : Eq] MatrixFn::equal(Self[T], Self[T]) -> Bool
pub fn[T : Show] MatrixFn::to_string(Self[T]) -> String
///|
test "lazy matrices" {
  let hilbert_denominators = @immut.MatrixFn::make(3, 3, (i, j) => i + j + 1)
  inspect(hilbert_denominators, content="|1, 2, 3|\n|2, 3, 4|\n|3, 4, 5|")
  let fib = @immut.MatrixFn::from_2d_array([[1, 1], [1, 0]]).pow(20)
  inspect(fib[0][1], content="6765")
  let total = hilbert_denominators.fold(init=0, (s, x) => s + x)
  inspect(total, content="27")
  inspect(
    hilbert_denominators.transpose() == hilbert_denominators,
    content="true",
  )
}

ベクトル

Vector::from_array

Vector::from_array(xs) は配列を新しいベクトルにコピーします。

pub fn[T] Vector::from_array(Array[T]) -> Self[T]

Vector::make, Vector::makei

make(n, x) は x の nn 個のコピーを、makei(n, f) は (f(0),…,f(n−1))(f(0), \dots, f(n-1)) を作ります。

pub fn[T] Vector::make(Int, T) -> Self[T]
pub fn[T] Vector::makei(Int, (Int) -> T) -> Self[T]

Vector::length

Vector::length(v) は要素数を返します。

pub fn[T] Vector::length(Self[T]) -> Int

Vector::at

Vector::at(v, i) は要素 i を返し、v[i] の実体です。範囲外のインデックスは中断します。

#alias("_[_]")
pub fn[T] Vector::at(Self[T], Int) -> T

Vector::set

Vector::set(v, i, x) は i 以外が v と等しいベクトルを O(log⁡32n)O(\log_{32} n) で返します。v は変化しません。

pub fn[T] Vector::set(Self[T], Int, T) -> Self[T]

Vector::iter

Vector::iter(v) は要素を順にたどります。

pub fn[T] Vector::iter(Self[T]) -> Iter[T]

Vector::map, Vector::zip_with

map(f) はすべての要素に f を適用し、zip_with(w, f) は二つのベクトルを要素ごとに組み合わせます(長さが異なると中断します)。

pub fn[T, U] Vector::map(Self[T], (T) -> U) -> Self[U]
pub fn[T, U, V] Vector::zip_with(Self[T], Self[U], (T, U) -> V) -> Self[V]

Vector::add, Vector::mul, Vector::neg

要素ごとの u+vu + v、Hadamard 積 u⊙vu \odot v、−u-u で、演算子の実体です。長さが異なると中断します。

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]

Vector は Sub を実装していません。u + -v と書いてください。

Vector::add_constant

Vector::add_constant(v, a) はすべての要素に a を加えます。

pub fn[T : Add] Vector::add_constant(Self[T], T) -> Self[T]

Vector::left_scale, Vector::right_scale

left_scale(a) は (avi)i(a v_i)_i を、right_scale(a) は (via)i(v_i a)_i を返します。両者が異なるのは非可換なスカラーの場合だけです。

pub fn[T : Mul] Vector::left_scale(Self[T], T) -> Self[T]
pub fn[T : Mul] Vector::right_scale(Self[T], T) -> Self[T]

Vector::lerp

Vector::lerp(u, v, t) は (1−t)u+tv(1 - t) u + t v を返します。スカラーは左から掛けます。

pub fn[T : @luna-generic.One + Mul + Add + Neg] Vector::lerp(Self[T], Self[T], T) -> Self[T]

長さが異なると中断します。

lin_comb

lin_comb(a, u, b, v) は au+bva 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

ベクトルを 1×n1 \times n または n×1n \times 1 の行列として表したものです。

pub fn[T] Vector::to_row_matrix(Self[T]) -> Matrix[T]
pub fn[T] Vector::to_col_matrix(Self[T]) -> Matrix[T]

Vector::scaled_matrix

Vector::scaled_matrix(v) は対角行列 diag⁡(v0,…,vn−1)\operatorname{diag}(v_0, \dots, v_{n-1}) を返します。

pub fn[T : @luna-generic.Zero] Vector::scaled_matrix(Self[T]) -> Matrix[T]

Vector::tensor_product

Vector::tensor_product(u, v) は外積 uvTu v^{\mathsf T}、つまり成分が uivju_i v_j の m×nm \times n 行列を返します。

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 "immut vectors" {
  let u = @immut.Vector::from_array([1, 2, 3])
  let v = @immut.Vector::makei(3, i => 10 * i)
  inspect(u + v, content="|1, 12, 23|")
  inspect(u * v, content="|0, 20, 60|")
  inspect(@immut.lin_comb(2, u, -1, v), content="|2, -6, -14|")
  inspect(u.set(0, 100), content="|100, 2, 3|")
  inspect(u, content="|1, 2, 3|")
  inspect(
    u.tensor_product(@immut.Vector::from_array([1, -1])),
    content="|1, -1|\n|2, -2|\n|3, -3|",
  )
  inspect(u.scaled_matrix(), content="|1, 0, 0|\n|0, 2, 0|\n|0, 0, 3|")
  inspect(u.lerp(@immut.Vector::make(3, 5), 2), content="|9, 8, 7|")
}

非推奨

これらのメソッド形式はソース互換性のためだけに存在します。インターフェースからは隠されており、使用すると警告が出ます。

項目代替
Matrix::not_equal, MatrixFn::not_equal, Vector::not_equal!=
Matrix::output, MatrixFn::output, Vector::output文字列補間または Show::output(x, logger)
Vector::to_reprRepr(v) または @debug.Debug::to_repr(v)
Vector::arbitrary@quickcheck.Arbitrary::arbitrary