sourceextensions/linalg/lib/Linalg.xtl
1⍝# Linalg.xtl -- the facade of the linalg extension: numerical linear
2⍝# algebra through nalgebra. Matrices are Float arrays (row by column);
3⍝# a right-hand side may be a vector or a matrix of columns.
4⍝# Import: "la:" u_se< "Linalg"
5⍝# Run with xetal-x (xetal-x --ext DIR puts this directory on XETAL_PATH).
6⍝# Each signature line is written out by the binding macro (lib/Ffi.xtlm).
7
8ᶠᶠⁱ⁼u̲se< "Ffi"
9
10⍝# a la:s_olve b: x with a x = b (a square and not singular).
11"s_olve : float float -> floats" ᶠᶠⁱb̲ind< "linalg/solve"
12⍝# la:i_nverse a: the inverse of a square matrix.
13"i_nverse : float -> floats" ᶠᶠⁱb̲ind< "linalg/inverse"
14⍝# la:d_et a: the determinant.
15"d_et : float -> float" ᶠᶠⁱb̲ind< "linalg/det"
16⍝# a la:l_stsq b: the x minimizing |a x - b| (least squares, by the SVD).
17"l_stsq : float float -> floats" ᶠᶠⁱb̲ind< "linalg/lstsq"
18⍝## Eigenvalues
19
20⍝# la:e_ig a: a symmetric matrix's eigenvalues, ascending.
21"e_ig : float -> floats" ᶠᶠⁱb̲ind< "linalg/eigsym"
22⍝# la:e_igVecs a: a symmetric matrix's eigenvectors, one column each, in
23⍝# the order of ˡᵃe̲ig.
24"e_igVecs : float -> floats" ᶠᶠⁱb̲ind< "linalg/eigvecs"
25
26⍝## The singular value decomposition
27
28⍝# a = U diag(s) V', thin (r, the smaller side, columns) with s
29⍝# descending; each function computes it again, so call each once.
30
31⍝# la:s_vdS a: the singular values s, descending.
32"s_vdS : float -> floats" ᶠᶠⁱb̲ind< "linalg/svd_s"
33⍝# la:s_vdU a: the left singular vectors U, m by r, one column each.
34"s_vdU : float -> floats" ᶠᶠⁱb̲ind< "linalg/svd_u"
35⍝# la:s_vdV a: the right singular vectors V, n by r, one column each.
36"s_vdV : float -> floats" ᶠᶠⁱb̲ind< "linalg/svd_v"
37
38⍝# The native package behind these functions.
39ˡpackage ← "linalg"
ᶠᶠⁱb̲ind< expands to
ˡs̲olve ← { a b → pa ← (f̲ormat r̲avel f̲loat a) ⎕N̲PUT "ext:linalg/solve?float=" c̲at f̲ormat s̲hape a pb ← (f̲ormat r̲avel f̲loat b) ⎕N̲PUT "ext:linalg/solve?float=" c̲at f̲ormat s̲hape b v ← n̲umbers ⎕N̲GET "ext:linalg/solve" (f̲loor n̲umbers ⎕N̲GET "ext:linalg/solve?shape") r̲eshape v }
ᶠᶠⁱb̲ind< expands to
ˡi̲nverse ← { a → pa ← (f̲ormat r̲avel f̲loat a) ⎕N̲PUT "ext:linalg/inverse?float=" c̲at f̲ormat s̲hape a v ← n̲umbers ⎕N̲GET "ext:linalg/inverse" (f̲loor n̲umbers ⎕N̲GET "ext:linalg/inverse?shape") r̲eshape v }
ᶠᶠⁱb̲ind< expands to
ˡd̲et ← { a → pa ← (f̲ormat r̲avel f̲loat a) ⎕N̲PUT "ext:linalg/det?float=" c̲at f̲ormat s̲hape a f̲irst n̲umbers ⎕N̲GET "ext:linalg/det" }
ᶠᶠⁱb̲ind< expands to
ˡl̲stsq ← { a b → pa ← (f̲ormat r̲avel f̲loat a) ⎕N̲PUT "ext:linalg/lstsq?float=" c̲at f̲ormat s̲hape a pb ← (f̲ormat r̲avel f̲loat b) ⎕N̲PUT "ext:linalg/lstsq?float=" c̲at f̲ormat s̲hape b v ← n̲umbers ⎕N̲GET "ext:linalg/lstsq" (f̲loor n̲umbers ⎕N̲GET "ext:linalg/lstsq?shape") r̲eshape v }
ᶠᶠⁱb̲ind< expands to
ˡe̲ig ← { a → pa ← (f̲ormat r̲avel f̲loat a) ⎕N̲PUT "ext:linalg/eigsym?float=" c̲at f̲ormat s̲hape a v ← n̲umbers ⎕N̲GET "ext:linalg/eigsym" (f̲loor n̲umbers ⎕N̲GET "ext:linalg/eigsym?shape") r̲eshape v }
ᶠᶠⁱb̲ind< expands to
ˡe̲igVecs ← { a → pa ← (f̲ormat r̲avel f̲loat a) ⎕N̲PUT "ext:linalg/eigvecs?float=" c̲at f̲ormat s̲hape a v ← n̲umbers ⎕N̲GET "ext:linalg/eigvecs" (f̲loor n̲umbers ⎕N̲GET "ext:linalg/eigvecs?shape") r̲eshape v }
ᶠᶠⁱb̲ind< expands to
ˡs̲vdS ← { a → pa ← (f̲ormat r̲avel f̲loat a) ⎕N̲PUT "ext:linalg/svd_s?float=" c̲at f̲ormat s̲hape a v ← n̲umbers ⎕N̲GET "ext:linalg/svd_s" (f̲loor n̲umbers ⎕N̲GET "ext:linalg/svd_s?shape") r̲eshape v }
ᶠᶠⁱb̲ind< expands to
ˡs̲vdU ← { a → pa ← (f̲ormat r̲avel f̲loat a) ⎕N̲PUT "ext:linalg/svd_u?float=" c̲at f̲ormat s̲hape a v ← n̲umbers ⎕N̲GET "ext:linalg/svd_u" (f̲loor n̲umbers ⎕N̲GET "ext:linalg/svd_u?shape") r̲eshape v }
ᶠᶠⁱb̲ind< expands to
ˡs̲vdV ← { a → pa ← (f̲ormat r̲avel f̲loat a) ⎕N̲PUT "ext:linalg/svd_v?float=" c̲at f̲ormat s̲hape a v ← n̲umbers ⎕N̲GET "ext:linalg/svd_v" (f̲loor n̲umbers ⎕N̲GET "ext:linalg/svd_v?shape") r̲eshape v }