次元情報 (つまり列の数や行の数) が付属した永続化行列を サイズを伴う行列 (matrix-with-size) と呼びます。 観型 VT が与えられたとき、観型 VT の要素を M 列と N 行含むサイズを伴う行列の型は mtrxszref(VT, M, N) です。 本質的に、この型の値は3つの型 arrayref(VT, N), size_t(M), size_t(N) を構成要素とするボックス化レコードです。 サイズを伴う永続化行列に関する様々な関数のインターフェイスを prelude/SATS/matrixref.sats に見つけることができます。
次の関数はサイズを伴う行列を生成するのに一般的に使用されます:
fun{a:t0p} mtrxszref_make_elt (m: size_t, n: size_t, x0: a): mtrxref (a) // end of [mtrxszref_make_elt]
行列セルの内容物にアクセスしたり更新したりするために、 次の2つの関数 mtrxszref_get_at と mtrxszref_set_at を使うことができます:
fun{a:t0p} mtrxszref_get_at (M: mtrxszref(a), i: size_t, j: size_t): (a) fun{a:t0p} mtrxszref_set_at (M: mtrxszref(a), i: size_t, j: size_t, x: a): void
簡単な例として、次のコードは与えられたサイズを伴う行列の中身の転置行列を取る関数を実装しています:
// extern fun{a:t0p} mtrxszref_transpose (M: mtrxszref(a)): void // implement{a} mtrxszref_transpose (M) = let // val n = M.nrow() // val ((*void*)) = assertloc (M.nrow() = M.ncol()) // fun loop ( i: size_t, j: size_t ) : void = if j < n then let val x = M[i,j] val () = M[i,j] := M[j,i] val () = M[j,i] := x in loop(i, succ(j)) end else let val i1 = succ (i) in if i1 < n then loop(i1, succ(i1)) else () end // end of [if] // in if n > 0 then loop(i2sz(0), i2sz(1)) else () end // end of [mtrxszref_transpose]
サイズを伴う配列と同様に、サイズを伴う行列は依存型行列よりも簡単にプログラミングできます。 けれども、後者はコンパイル時にエラーを効果的に検出することができず、実行時のコード実行で検出します。 ATS でプログラミングする際、サイズを伴う行列からはじめて、その恩恵が明確になった後で行列に置き換えるのは妥当でしょう。
この章で紹介したコードの全体は オンライン から入手できます。