///|
fn matrix_shape(a : Array[Array[Double]]) -> (Int32, Int32) raise DesignError {
  if a.length() == 0 || a.length() > 4096 {
    raise Budget("matrix row count must be 1..4096")
  }
  let cols = a[0].length()
  if cols == 0 || cols > 128 {
    raise Budget("matrix column count must be 1..128")
  }
  for row in a {
    if row.length() != cols {
      raise Invalid("ragged matrix")
    }
    for x in row {
      require_number(x)
    }
  }
  (a.length(), cols)
}

///|
fn zeros(rows : Int32, cols : Int32) -> Array[Array[Double]] {
  [
    for _ in 0.. Array::make(cols, 0.0)
  ]
}

///|
fn tolerance(tol : Double) -> Unit raise DesignError {
  if !finite(tol) || tol < 1.0e-14 || tol > 0.01 {
    raise Invalid("relative tolerance must be 1e-14..0.01")
  }
}

///|
pub fn transpose(
  a : Array[Array[Double]],
) -> Array[Array[Double]] raise DesignError {
  let (n, p) = matrix_shape(a)
  let result = zeros(p, n)
  for i in 0.. Array[Array[Double]] raise DesignError {
  let (n, p) = matrix_shape(a)
  let (m, q) = matrix_shape(b)
  if p != m {
    raise Invalid("matrix multiplication shape mismatch")
  }
  if q > 128 {
    raise Budget("product exceeds column budget")
  }
  let result = zeros(n, q)
  for i in 0.. Int32 raise DesignError {
  tolerance(tol)
  let (n, p) = matrix_shape(a)
  let work = [ for row in a => row.copy() ]
  // Equilibrate columns: the threshold must not depend on a user's physical units.
  for j in 0..

scale { scale = work[i][j].abs() } } if scale > 0.0 { for i in 0.. work[pivot][col].abs() { pivot = i } } if work[pivot][col].abs() <= tol { continue } let swap = work[rank] work[rank] = work[pivot] work[pivot] = swap for i in (rank + 1).. Array[Array[Double]] raise DesignError { let (n, p) = matrix_shape(a) if weights.length() != 0 && weights.length() != n { raise Invalid("weight count mismatch") } let result = zeros(p, p) for i in 0..