internal API

Luna-Flow/linear-algebra/internal は、immut と mutable が共有する形状検査用のヘルパーをまとめたパッケージです。HasShape trait を定義し、さらに各前提条件について、Result[Unit, LinearAlgebraError] を返す検査付きガードと、中断するガードを提供します。

ソース: src/internal/algebra.mbt。

HasShape

HasShape は行列のような値の (rows, cols) を報告します。

pub(open) trait HasShape {
  fn shape(Self) -> (Int, Int)
}

@immut.Matrix、@immut.MatrixFn、@mutable.Matrix が実装しています。@algebra.MatrixShape と同じ役割を持ちますが、algebra より下の層に置かれているため、具体的なパッケージは実験的な algebra 層に依存せずに済みます。

HasShape::shape

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

fn HasShape::shape(Self) -> (Int, Int)

ガード

各前提条件には 2 つの形式があります。_checked 形式は、前提条件が成り立てば Ok(()) を、そうでなければ表に示した種類の Err を返します。無印の形式は () を返すか、エラーのメッセージとともに中断します。どの入力に対しても、ensure_x(m) が中断するのは ensure_x_checked(m) が Err になるときに限ります。

ガード前提条件エラーの種類
ensure_squarerows = colsNonSquareMatrix
ensure_row_in_bounds0≤r<0 \le r < rowsIndexOutOfBounds
ensure_col_in_bounds0≤c<0 \le c < colsIndexOutOfBounds
ensure_index_in_bounds行と列が範囲内(行を先に検査)IndexOutOfBounds
ensure_same_shapeshape(a) == shape(b)DimensionMismatch
ensure_mul_compatiblecols(a) = rows(b)DimensionMismatch

ensure_square, ensure_square_checked

pub fn[M : HasShape] ensure_square(M) -> Unit
pub fn[M : HasShape] ensure_square_checked(M) -> Result[Unit, @error.LinearAlgebraError]

ensure_row_in_bounds, ensure_row_in_bounds_checked

pub fn[M : HasShape] ensure_row_in_bounds(M, Int) -> Unit
pub fn[M : HasShape] ensure_row_in_bounds_checked(M, Int) -> Result[Unit, @error.LinearAlgebraError]

ensure_col_in_bounds, ensure_col_in_bounds_checked

pub fn[M : HasShape] ensure_col_in_bounds(M, Int) -> Unit
pub fn[M : HasShape] ensure_col_in_bounds_checked(M, Int) -> Result[Unit, @error.LinearAlgebraError]

ensure_index_in_bounds, ensure_index_in_bounds_checked

pub fn[M : HasShape] ensure_index_in_bounds(M, Int, Int) -> Unit
pub fn[M : HasShape] ensure_index_in_bounds_checked(M, Int, Int) -> Result[Unit, @error.LinearAlgebraError]

ensure_same_shape, ensure_same_shape_checked

pub fn[A : HasShape, B : HasShape] ensure_same_shape(A, B) -> Unit
pub fn[A : HasShape, B : HasShape] ensure_same_shape_checked(A, B) -> Result[Unit, @error.LinearAlgebraError]

ensure_mul_compatible, ensure_mul_compatible_checked

pub fn[A : HasShape, B : HasShape] ensure_mul_compatible(A, B) -> Unit
pub fn[A : HasShape, B : HasShape] ensure_mul_compatible_checked(A, B) -> Result[Unit, @error.LinearAlgebraError]

2 つのオペランドは型が異なってもかまいません。たとえば Matrix と MatrixFn です。

例

ガードはリポジトリの外からはインポートできません。その効果は、ガードの上に構築された公開メソッドを通じて確認できます。

///|
test "guards behind public methods" {
  let a = @immut.Matrix::from_2d_array([[1, 2, 3]])
  match a.matmul(a) {
    Err(e) =>
      inspect(
        e.message,
        content="Matrix dimensions are not compatible for multiplication",
      )
    Ok(_) => fail("1x3 times 1x3 is not defined")
  }
  match a.trace() {
    Err(e) => inspect(e.message, content="Matrix must be square")
    Ok(_) => fail("a 1x3 matrix has no trace")
  }
  debug_inspect(a.shape(), content="(1, 3)")
}