def determinant(a): """determinant(a) -> ||a|| *a* may be either rank-2 or rank-3. If it is rank-2, it must square. >>> A = [[1,2,3], [3,4,5], [5,6,7]] >>> _isClose(determinant(A), 0) 1 If *a* is rank-3, it is treated as an array of rank-2 matrices and must be square along the last 2 axes. >>> A = [[[1, 3], [2j, 3j]], [[2, 4], [4j, 4j]], [[3, 5], [6j, 5j]]] >>> _isClose(determinant(A), [-3j, -8j, -15j]) 1 If *a* is not square along its last two axes, a LinAlgError is raised. >>> determinant(na.asarray(A)[...,:1]) Traceback (most recent call last): ... LinearAlgebraError: Array (or it submatrices) must be square """ a = na.asarray(a) _assertRank((2,3), a) _assertSubmatrixSquareness(a) stretched = (len(a.shape) == 2) if stretched: a = a[na.NewAxis,] t = _commonType(a) a = _castCopyAndTranspose(t, a, indices=(0,2,1)) n_cases, n = a.shape[:2] if _array_kind[t] == 1: lapack_routine = lapack_lite2.zgetrf else: lapack_routine = lapack_lite2.dgetrf no_pivoting = na.arrayrange(1, n+1) pivots = na.zeros((n,), 'l') all_pivots = na.zeros((n_cases, n,), 'l') sum , not_equal = na.sum, na.not_equal stride = n * n * a.itemsize() pivots_stride = n * pivots.itemsize() view = a[0].view() view_pivots = all_pivots[0] a_i = view.copy() for i in range(n_cases): if i: a_i._copyFrom(view) outcome = lapack_routine(n, n, a_i, n, pivots, 0) view_pivots._copyFrom(pivots) view._copyFrom(a_i) view._byteoffset += stride view_pivots._byteoffset += pivots_stride signs = na.where(sum(not_equal(all_pivots, no_pivoting), 1) % 2, -1, 1).astype(t) for i in range(n): signs *= a[:,i,i] if stretched: signs = signs[0] return signs