次元 m, n の永続化行列は、単にサイズが m*n の永続化配列です。 C言語と同様に、ATS における行列表現は列優先 (row-major) です。 別の言い方をすると、次元 m, n の行列内の要素 (i, j) は、その行列を表現する配列内の要素 i*n+j です。
観型 VT と2つの整数 M と N が与えられたとき、 型 matrixref(VT, M, N) は観型 VT の要素を含む次元 M, N の永続化行列を表わします。 matrixref 値にどのような次元情報も付随しません。 永続化行列に関する様々な関数のインターフェイスを SATS ファイル prelude/SATS/matrixref.sats に見つけることができます。 これは atsopt によって自動的に読み込まれます。
次の関数は matrixref 値を生成するのに一般的に使用されます:
fun{a:t0p} matrixref_make_elt{m,n:int} (m: size_t m, n: size_t n, x0: a):<!wrt> matrixref (a, m, n) // end of [matrixref_make_elt]
また、次のキャスト関数が呼び出されると、配列を行列に変化させます:
castfn arrayref2matrixref {a:vt0p}{m,n:nat} (A: arrayref (a, m*n)):<> matrixref (a, m, n) // end of [arrayref2matrixref]
行列セルの内容物にアクセスしたり更新するために、次の2つの関数 matrixref_get_at と matrixref_set_at を呼び出すことができます:
// fun{a:t0p} matrixref_get_at {m,n:int} ( A: matrixref (a, m, n), i: sizeLt(m), n: size_t(n), j: sizeLt(n) ) :<!ref> (a) // end of [matrixref_get_at] // fun{a:t0p} matrixref_set_at {m,n:int} ( A: matrixref (INV(a), m, n), i: sizeLt (m), n: size_t n, j: sizeLt (n), x: a ) :<!refwrt> void // end of [matrixref_set_at] //
次は、与えられた正方行列を転置行列にする関数の実装です:
// extern fun{a:t0p} matrixref_transpose {n:nat} ( M: matrixref (a, n, n), n: size_t (n) ) : void // end of [matrixref_transpose] // implement{a} matrixref_transpose {n} (M, n) = let // macdef mget (i, j) = matrixref_get_at (M, ,(i), n, ,(j)) macdef mset (i, j, x) = matrixref_set_at (M, ,(i), n, ,(j), ,(x)) // fun loop {i,j:nat | i < j; j <= n } .<n-i,n-j>. ( i: size_t (i), j: size_t (j) ) : void = if j < n then let val x = mget(i, j) val () = mset(i, j, mget(j, i)) val () = mset(j, i, x) in loop (i, j+1) 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 [matrixref_transpose]
この章で紹介したコード全体は オンライン から入手できます。