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"
ᶠᶠⁱ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
}
12⍝# la:i_nverse a: the inverse of a square matrix. 13"i_nverse : float -> floats" ᶠᶠⁱb̲ind< "linalg/inverse"
ᶠᶠⁱ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
}
14⍝# la:d_et a: the determinant. 15"d_et : float -> float" ᶠᶠⁱb̲ind< "linalg/det"
ᶠᶠⁱ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"
}
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"
ᶠᶠⁱ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
}
18⍝## Eigenvalues 19 20⍝# la:e_ig a: a symmetric matrix's eigenvalues, ascending. 21"e_ig : float -> floats" ᶠᶠⁱb̲ind< "linalg/eigsym"
ᶠᶠⁱ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
}
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"
ᶠᶠⁱ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
}
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"
ᶠᶠⁱ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
}
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"
ᶠᶠⁱ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
}
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"
ᶠᶠⁱ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
}
37 38⍝# The native package behind these functions. 39ˡpackage ← "linalg"