def _null_space2(numpy, A, eps): # (INTERNAL) Return the nullspace and rank of matrix A # @see: <https://SciPy-Cookbook.ReadTheDocs.io/items/RankNullspace.html>, # <https://NumPy.org/doc/stable/reference/generated/numpy.linalg.svd.html>, # <https://StackOverflow.com/questions/19820921>, # <https://StackOverflow.com/questions/2992947> and # <https://StackOverflow.com/questions/5889142> A = numpy.array(A) m = max(numpy.shape(A)) if m != 4: # for this usage raise _AssertionError(shape=m, txt=modulename(_null_space2, True)) # if needed, square A, pad with zeros A = numpy.resize(A, m * m).reshape(m, m) # try: # no numpy.linalg.null_space <https://docs.SciPy.org/doc/> # return scipy.linalg.null_space(A) # XXX no scipy.linalg? # except AttributeError: # pass _, s, v = numpy.linalg.svd(A) t = max(eps, eps * s[0]) # tol, s[0] is largest singular r = numpy.sum(s > t) # rank if r == 3: # get null_space n = numpy.transpose(v[r:]) s = numpy.shape(n) if s != (m, 1): # bad null_space shape raise _AssertionError(shape=s, txt=modulename(_null_space2, True)) e = float(numpy.max(numpy.abs(numpy.dot(A, n)))) if e > t: # residual not near-zero raise _AssertionError(eps=e, txt=modulename(_null_space2, True)) else: # coincident, colinear, concentric centers, ambiguous, etc. n = None # del A, s, vh # release numpy return n, r
def _Error(clas, arg, name=NN, Error=UnitError, txt=_invalid_): '''(INTERNAL) Return an error with explanation. @arg clas: The C{units} class or sub-class. @arg arg: The original C{unit} value. @kwarg name: The instance name (C{str}). @kwarg Error: Optional error, overriding the default L{UnitError}. @kwarg txt: Optional explanation of the error (C{str}). @returns: An B{C{Error}} instance. ''' n = name if name else modulename(clas).lstrip(_UNDER_) return Error(n, arg, txt=txt)
def _Error(clas, arg, name='', Error=UnitError, txt='invalid'): '''(INTERNAL) Return an error with explanation. @arg clas: The C{units} class or sub-class. @arg arg: The original C{unit} value. @kwarg name: The instance name (C{str}). @kwarg Error: Optional error, overriding the default L{UnitError}. @kwarg txt: Explanation of the error (C{str}). @returns: An B{C{Error}} instance. ''' n = (', name=%r' % (name, )) if name else '' return Error('%s(%r%s) %s' % (modulename(clas), arg, n, txt))