mat.bend relies on unsafe/foreign
raw source on the hub · import bend-blas-lapack@0.0.0.1/mat.bend as Mat
bend-blas: the shaped layer. A Mat<rows, cols> is one row-major Array<F32> with its shape in the type, a Vec<n> likewise, and every routine below states the shape rule in its signature, so a wrong operand is a checker error naming both shapes, not a wrong answer: Mat.gemm(rows, k, cols, alpha, a, b, beta, c) needs a Mat<rows, k>, a Mat<k, cols> and a Mat<rows, cols>; a transpose is a separate def (gemm_t, gemm_tn, gemv_t), since it changes the shape. The sizes are Nat arguments that double as the type indices. The raw routines of blas.bend and lapack.bend run underneath, unchanged; the shaped forms answer the same Result, with .try twins, and consume their operands the same way (Mat.clone keeps a copy). This is the scipy.linalg to blas.bend's scipy.linalg.blas, plus the shapes.
3 imports
import Base import ./blas.bend as B import ./lapack.bend as L
Types
type Mat source · line 17 · raw
@-rows:Nat -> @-cols:Nat -> Type
MatA@-rows:Nat -> @-cols:Nat -> @a:Array<F32> -> Mat<rows, cols>
type Vec source · line 20 · raw
@-n:Nat -> Type
VecA@-n:Nat -> @a:Array<F32> -> Vec<n>
Definitions
def depth.go source · line 27 · raw
@fuel:Nat -> @+n:U32 -> @+d:Nat -> @+cap:U32 -> Nat
the depth of the smallest power-of-two block holding count floats
def depth source · line 34 · raw
@+count:Nat -> Nat
def fill.go source · line 37 · raw
@xs:List<&2, F32> -> @+i:U32 -> @a:Array<F32> -> Array<F32>
def array.of source · line 46 · raw
@+count:Nat -> @xs:List<&2, F32> -> Array<F32>
an array of the smallest power-of-two size holding count floats, the first ones from xs (cut or padded with 0.0), the rest 0.0
def take.go source · line 49 · raw
@n:Nat -> @+i:U32 -> @r:Pair(Array<F32>, F32) -> @acc:List<&2, F32> -> List<&2, F32>
def list.of source · line 59 · raw
@+count:Nat -> @a:Array<F32> -> List<&2, F32>
the first count floats of an array, as a list
def rows.of source · line 67 · raw
@rows:Nat -> @+cols:Nat -> @+xs:List<&2, F32> -> List<&2, List<&2, F32>>
xs cut into rows of cols
def F32.show.of source · line 74 · raw
@x:F32 -> String
def row.show source · line 77 · raw
@xs:List<&2, F32> -> String
def Mat.from_list source · line 81 · raw
@+rows:Nat -> @+cols:Nat -> @xs:List<&2, F32> -> Mat<rows, cols>
rows * cols floats, row-major, cut or padded with 0.0
def Mat.zeros source · line 84 · raw
@+rows:Nat -> @+cols:Nat -> Mat<rows, cols>
def Mat.to_list source · line 87 · raw
@+rows:Nat -> @+cols:Nat -> @m:Mat<rows, cols> -> List<&2, F32>
def Mat.to_rows source · line 91 · raw
@+rows:Nat -> @+cols:Nat -> @m:Mat<rows, cols> -> List<&2, List<&2, F32>>
def Mat.show source · line 94 · raw
@+rows:Nat -> @+cols:Nat -> @m:Mat<rows, cols> -> String
def Mat.clone.fin source · line 97 · raw
@-rows:Nat -> @-cols:Nat -> @r:Pair(Array<F32>, Array<F32>) -> Pair(Mat<rows, cols>, Mat<rows, cols>)
def Mat.clone source · line 102 · raw
@+rows:Nat -> @+cols:Nat -> @m:Mat<rows, cols> -> Pair(Mat<rows, cols>, Mat<rows, cols>)
a Mat is affine: two copies, to be opened by matching in a def of its own
def Vec.from_list source · line 106 · raw
@+n:Nat -> @xs:List<&2, F32> -> Vec<n>
def Vec.zeros source · line 109 · raw
@+n:Nat -> Vec<n>
def Vec.to_list source · line 112 · raw
@+n:Nat -> @v:Vec<n> -> List<&2, F32>
def Vec.show source · line 116 · raw
@+n:Nat -> @v:Vec<n> -> String
def Vec.clone.fin source · line 119 · raw
@-n:Nat -> @r:Pair(Array<F32>, Array<F32>) -> Pair(Vec<n>, Vec<n>)
def Vec.clone source · line 123 · raw
@+n:Nat -> @v:Vec<n> -> Pair(Vec<n>, Vec<n>)
def Mat.wrap source · line 128 · raw
@-rows:Nat -> @-cols:Nat -> @r:Result<&1, &1, Pair(U32, String), Array<F32>> -> IO(Result<&1, &1, Pair(U32, String), Mat<rows, cols>>)
the raw answers, shaped
def Vec.wrap source · line 131 · raw
@-n:Nat -> @r:Result<&1, &1, Pair(U32, String), Array<F32>> -> IO(Result<&1, &1, Pair(U32, String), Vec<n>>)
def Mat.gemm source · line 138 · raw
@+rows:Nat -> @+k:Nat -> @+cols:Nat -> @alpha:F32 -> @a:Mat<rows, k> -> @b:Mat<k, cols> -> @beta:F32 -> @c:Mat<rows, cols> -> IO(Result<&1, &1, Pair(U32, String), Mat<rows, cols>>)
C = alpha A B + beta C
def Mat.gemm.try source · line 144 · raw
@+rows:Nat -> @+k:Nat -> @+cols:Nat -> @alpha:F32 -> @a:Mat<rows, k> -> @b:Mat<k, cols> -> @beta:F32 -> @c:Mat<rows, cols> -> IO(Mat<rows, cols>)
def Mat.gemm_t source · line 148 · raw
@+rows:Nat -> @+k:Nat -> @+cols:Nat -> @alpha:F32 -> @a:Mat<rows, k> -> @b:Mat<cols, k> -> @beta:F32 -> @c:Mat<rows, cols> -> IO(Result<&1, &1, Pair(U32, String), Mat<rows, cols>>)
C = alpha A B^T + beta C, B stored cols x k
def Mat.gemm_t.try source · line 154 · raw
@+rows:Nat -> @+k:Nat -> @+cols:Nat -> @alpha:F32 -> @a:Mat<rows, k> -> @b:Mat<cols, k> -> @beta:F32 -> @c:Mat<rows, cols> -> IO(Mat<rows, cols>)
def Mat.gemm_tn source · line 158 · raw
@+rows:Nat -> @+k:Nat -> @+cols:Nat -> @alpha:F32 -> @a:Mat<k, rows> -> @b:Mat<k, cols> -> @beta:F32 -> @c:Mat<rows, cols> -> IO(Result<&1, &1, Pair(U32, String), Mat<rows, cols>>)
C = alpha A^T B + beta C, A stored k x rows
def Mat.gemm_tn.try source · line 164 · raw
@+rows:Nat -> @+k:Nat -> @+cols:Nat -> @alpha:F32 -> @a:Mat<k, rows> -> @b:Mat<k, cols> -> @beta:F32 -> @c:Mat<rows, cols> -> IO(Mat<rows, cols>)
def Mat.gemv source · line 168 · raw
@+rows:Nat -> @+cols:Nat -> @alpha:F32 -> @a:Mat<rows, cols> -> @x:Vec<cols> -> @beta:F32 -> @y:Vec<rows> -> IO(Result<&1, &1, Pair(U32, String), Vec<rows>>)
y = alpha A x + beta y
def Mat.gemv.try source · line 174 · raw
@+rows:Nat -> @+cols:Nat -> @alpha:F32 -> @a:Mat<rows, cols> -> @x:Vec<cols> -> @beta:F32 -> @y:Vec<rows> -> IO(Vec<rows>)
def Mat.gemv_t source · line 178 · raw
@+rows:Nat -> @+cols:Nat -> @alpha:F32 -> @a:Mat<rows, cols> -> @x:Vec<rows> -> @beta:F32 -> @y:Vec<cols> -> IO(Result<&1, &1, Pair(U32, String), Vec<cols>>)
y = alpha A^T x + beta y
def Mat.gemv_t.try source · line 184 · raw
@+rows:Nat -> @+cols:Nat -> @alpha:F32 -> @a:Mat<rows, cols> -> @x:Vec<rows> -> @beta:F32 -> @y:Vec<cols> -> IO(Vec<cols>)
def Mat.ger source · line 188 · raw
@+rows:Nat -> @+cols:Nat -> @alpha:F32 -> @x:Vec<rows> -> @y:Vec<cols> -> @a:Mat<rows, cols> -> IO(Result<&1, &1, Pair(U32, String), Mat<rows, cols>>)
A = alpha x y^T + A
def Mat.ger.try source · line 194 · raw
@+rows:Nat -> @+cols:Nat -> @alpha:F32 -> @x:Vec<rows> -> @y:Vec<cols> -> @a:Mat<rows, cols> -> IO(Mat<rows, cols>)
def Vec.dot source · line 197 · raw
@+n:Nat -> @x:Vec<n> -> @y:Vec<n> -> IO(Result<&1, &1, Pair(U32, String), F32>)
def Vec.dot.try source · line 202 · raw
@+n:Nat -> @x:Vec<n> -> @y:Vec<n> -> IO(F32)
def Vec.nrm2 source · line 205 · raw
@+n:Nat -> @x:Vec<n> -> IO(Result<&1, &1, Pair(U32, String), F32>)
def Vec.nrm2.try source · line 209 · raw
@+n:Nat -> @x:Vec<n> -> IO(F32)
def Vec.asum source · line 212 · raw
@+n:Nat -> @x:Vec<n> -> IO(Result<&1, &1, Pair(U32, String), F32>)
def Vec.asum.try source · line 216 · raw
@+n:Nat -> @x:Vec<n> -> IO(F32)
def Vec.iamax source · line 219 · raw
@+n:Nat -> @x:Vec<n> -> IO(Result<&1, &1, Pair(U32, String), U32>)
def Vec.iamax.try source · line 223 · raw
@+n:Nat -> @x:Vec<n> -> IO(U32)
def Vec.axpy source · line 227 · raw
@+n:Nat -> @alpha:F32 -> @x:Vec<n> -> @y:Vec<n> -> IO(Result<&1, &1, Pair(U32, String), Vec<n>>)
y = alpha x + y
def Vec.axpy.try source · line 232 · raw
@+n:Nat -> @alpha:F32 -> @x:Vec<n> -> @y:Vec<n> -> IO(Vec<n>)
def Vec.scal source · line 235 · raw
@+n:Nat -> @alpha:F32 -> @x:Vec<n> -> IO(Result<&1, &1, Pair(U32, String), Vec<n>>)
def Vec.scal.try source · line 239 · raw
@+n:Nat -> @alpha:F32 -> @x:Vec<n> -> IO(Vec<n>)
def Mat.solve source · line 246 · raw
@+n:Nat -> @+nrhs:Nat -> @a:Mat<n, n> -> @b:Mat<n, nrhs> -> IO(Result<&1, &1, Pair(U32, String), Mat<n, nrhs>>)
X = A^-1 B; Fail with the zero pivot as the code when A is singular
def Mat.solve.try source · line 251 · raw
@+n:Nat -> @+nrhs:Nat -> @a:Mat<n, n> -> @b:Mat<n, nrhs> -> IO(Mat<n, nrhs>)
def Mat.cholesky source · line 255 · raw
@+n:Nat -> @a:Mat<n, n> -> IO(Result<&1, &1, Pair(U32, String), Mat<n, n>>)
the lower Cholesky factor L of a symmetric positive definite A
def Mat.cholesky.try source · line 259 · raw
@+n:Nat -> @a:Mat<n, n> -> IO(Mat<n, n>)
def Mat.cholesky_solve source · line 263 · raw
@+n:Nat -> @+nrhs:Nat -> @l:Mat<n, n> -> @b:Mat<n, nrhs> -> IO(Result<&1, &1, Pair(U32, String), Mat<n, nrhs>>)
X = A^-1 B given L from Mat.cholesky
def Mat.cholesky_solve.try source · line 268 · raw
@+n:Nat -> @+nrhs:Nat -> @l:Mat<n, n> -> @b:Mat<n, nrhs> -> IO(Mat<n, nrhs>)
def Mat.svd_values source · line 272 · raw
@+m:Nat -> @+n:Nat -> @a:Mat<m, n> -> IO(Result<&1, &1, Pair(U32, String), Vec<Nat.min(m, n)>>)
the singular values, largest first
def Mat.svd_values.try source · line 276 · raw
@+m:Nat -> @+n:Nat -> @a:Mat<m, n> -> IO(Vec<Nat.min(m, n)>)
def Mat.svd.fin source · line 279 · raw
@-m:Nat -> @-n:Nat -> @s:Array<F32> -> @uv:Pair(Array<F32>, Array<F32>) -> IO(Result<&1, &1, Pair(U32, String), Pair(Vec<Nat.min(m, n)>, Pair(Mat<m, Nat.min(m, n)>, Mat<Nat.min(m, n), n>))>)
def Mat.svd.wrap source · line 284 · raw
@-m:Nat -> @-n:Nat -> @r:Result<&1, &1, Pair(U32, String), Pair(Array<F32>, Pair(Array<F32>, Array<F32>))> -> IO(Result<&1, &1, Pair(U32, String), Pair(Vec<Nat.min(m, n)>, Pair(Mat<m, Nat.min(m, n)>, Mat<Nat.min(m, n), n>))>)
def Mat.svd source · line 294 · raw
@+m:Nat -> @+n:Nat -> @a:Mat<m, n> -> IO(Result<&1, &1, Pair(U32, String), Pair(Vec<Nat.min(m, n)>, Pair(Mat<m, Nat.min(m, n)>, Mat<Nat.min(m, n), n>))>)
the thin SVD: (s, (u, vt)) with A = u diag(s) vt
def Mat.svd.try source · line 298 · raw
@+m:Nat -> @+n:Nat -> @a:Mat<m, n> -> IO(Pair(Vec<Nat.min(m, n)>, Pair(Mat<m, Nat.min(m, n)>, Mat<Nat.min(m, n), n>)))
def Mat.eigh.wrap source · line 301 · raw
@-n:Nat -> @r:Result<&1, &1, Pair(U32, String), Pair(Array<F32>, Array<F32>)> -> IO(Result<&1, &1, Pair(U32, String), Pair(Vec<n>, Mat<n, n>)>)
def Mat.eigh source · line 311 · raw
@+n:Nat -> @a:Mat<n, n> -> IO(Result<&1, &1, Pair(U32, String), Pair(Vec<n>, Mat<n, n>)>)
the eigenvalues ascending and the eigenvectors as the rows of the Mat
def Mat.eigh.try source · line 315 · raw
@+n:Nat -> @a:Mat<n, n> -> IO(Pair(Vec<n>, Mat<n, n>))