mutable API
Luna-Flow/linear-algebra/mutable は実行指向の密な線形代数を提供します。Matrix[T] は要素を行優先の 1 本の 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_inverseの場合はOptionを返す)unchecked_*版を対として持ちます。エラーの設計 を参照してください。 - 数値ルーチン は
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) はレンズが指す行の列 c を読み取り、Lens::set(l, c, x) は書き込みます。
#alias("_[_]")
pub fn[T] Lens::at(Self[T], Int) -> T
#alias("_[_]=_")
pub fn[T] Lens::set(Self[T], Int, T) -> Unit
Transpose から得たレンズは転置された行列を指します。範囲外の列では中断します。
RowView, ColView
RowView[T] と ColView[T] は、1 つの行または 1 つの列に対する動的なビューです。
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 は純粋であるべきです。1 つの要素に対して呼び出される回数は規定されていません。
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) は 1 つの行または列の動的なビューを返します。
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
1 つの行(左から右)または 1 つの列(上から下)を走査します。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
全要素(行優先)、1 つの行、または 1 つの列に対するイテレータです。
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
すべての要素、1 つの行のすべての要素、または 1 つの列のすべての要素を、インプレースで 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
2 つの行または 2 つの列をインプレースで交換します。
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
1 つの行または列を配列または 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
Matrix::null(m) は、すべての要素が Zero::zero() と厳密に等しいときに 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
is_invertible() は、LU 分解で許容誤差を下回るピボットが見つからなければ 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 のコピーに対して部分ピボット選択付き Gauss 消去を行い、見つかったピボットの数を返します。
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]
ピボットは厳密に 1、ピボット列のそれ以外の要素は厳密に 0 となり、途中で絶対値が許容誤差以下の要素は 0 に設定されます。元の行列が必要な場合は先にコピーしてください。
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
Matrix::is_symmetric(a) は、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を返します。 のように絶対値が等しく符号が逆の 2 つの優勢固有値があると収束しません。- 非正方行列または空行列では中断します。
- 各反復のコストは行列ベクトル積 1 回分、 です。
///|
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() は母分散 (2 パス)を返すか、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 はビューの座標を渡します。行と列の形式は、ビューの 1 つの行または列を順に訪れます。
Transpose::row_to_array, Transpose::col_to_array, Transpose::row_to_vector, Transpose::col_to_vector
ビューの 1 つの行または列をコピーします。
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
ビューの 2 つの行または列(ラップした行列にとっては列または行)をインプレースで交換します。
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) は 2 つのビューの積を返します。データを移動せずに として計算します。
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) は を 1 パスで返します。
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 |