docs: def cotangent(x, null=(-np.inf, np.inf), rtol=default_rtol, atol=default_atol):
      '''
      cotangent(x) is equivalent to cot(x) except that it also works on sparse arrays.
  
      The optional argument null (default, (-numpy.inf, numpy.inf)) may be specified to indicate what
      value(s) should be assigned when x == 0 or pi. If only one number is given, then it is used for
      both values; otherwise the first value corresponds to 0 and the second to pi.  A value of x is
      considered to be equal to one of these valids based on numpy.isclose. The optional arguments
      rtol and atol are passed along to isclose. If null is None, then no replacement is performed.
      '''
      if sps.issparse(x): x = x.toarray()
      else:               x = np.asarray(x)
      if rtol is None: rtol = default_rtol
      if atol is None: atol = default_atol
      try:    (nln,nlp) = null
      except Exception: (nln,nlp) = (null,null)
      x = np.mod(x + hpi, tau) - hpi
      ii = None if nln is None else np.where(np.isclose(x, 0,  rtol=rtol, atol=atol))
      jj = None if nlp is None else np.where(np.isclose(x, pi, rtol=rtol, atol=atol))
      x = np.tan(x)
      if ii: x[ii] = 1
      if jj: x[jj] = 1
      x = 1.0 / x
      if ii: x[ii] = nln
      if jj: x[jj] = nlp
      return x