class_docstr: Quadrature rules are implemented using this class, in order to
  simplify the code and provide a common infrastructure
  for tasks such as error estimation and node caching.
  
  You can implement a custom quadrature rule by subclassing
  :class:`QuadratureRule` and implementing the appropriate
  methods. The subclass can then be used by :func:`~mpmath.quad` by
  passing it as the *method* argument.
  
  :class:`QuadratureRule` instances are supposed to be singletons.
  :class:`QuadratureRule` therefore implements instance caching
  in :func:`~mpmath.__new__`.
class_docstr_tok: ["Quadrature","rules","are","implemented","using","this","class",",","in","order","to","simplify","the","code","and","provide","a","common","infrastructure","for","tasks","such","as","error","estimation","and","node","caching",".","You","can","implement","a","custom","quadrature","rule","by","subclassing",":","class",":","`","QuadratureRule","`","and","implementing","the","appropriate","methods",".","The","subclass","can","then","be","used","by",":","func",":","`","~mpmath.quad","`","by","passing","it","as","the","*","method","*","argument",".",":","class",":","`","QuadratureRule","`","instances","are","supposed","to","be","singletons",".",":","class",":","`","QuadratureRule","`","therefore","implements","instance","caching","in",":","func",":","`","~mpmath.__new__","`","."]
docstr: Rescale standardized nodes (for `[-1, 1]`) to a general
  interval `[a, b]`. For a finite interval, a simple linear
  change of variables is used. Otherwise, the following
  transformations are used:
  
  .. math ::
  
      \lbrack a, \infty \rbrack : t = \frac{1}{x} + (a-1)
  
      \lbrack -\infty, b \rbrack : t = (b+1) - \frac{1}{x}
  
      \lbrack -\infty, \infty \rbrack : t = \frac{x}{\sqrt{1-x^2}}
docstr_tok: ["Rescale","standardized","nodes","(","for","`","[","-1",",","1","]","`",")","to","a","general","interval","`","[","a",",","b","]","`",".","For","a","finite","interval",",","a","simple","linear","change","of","variables","is","used",".","Otherwise",",","the","following","transformations","are","used",":","..","math",":",":","\\lbrack","a",",","\\infty","\\rbrack",":","t","=","\\frac","{","1","}","{","x","}","+","(","a-1",")","\\lbrack","-\\infty",",","b","\\rbrack",":","t","=","(","b+1",")","-","\\frac","{","1","}","{","x","}","\\lbrack","-\\infty",",","\\infty","\\rbrack",":","t","=","\\frac","{","x","}","{","\\sqrt","{","1-x^2","}","}"]
code: def transform_nodes(self, nodes, a, b, verbose=False):
      r"""
      Rescale standardized nodes (for `[-1, 1]`) to a general
      interval `[a, b]`. For a finite interval, a simple linear
      change of variables is used. Otherwise, the following
      transformations are used:
  
      .. math ::
  
          \lbrack a, \infty \rbrack : t = \frac{1}{x} + (a-1)
  
          \lbrack -\infty, b \rbrack : t = (b+1) - \frac{1}{x}
  
          \lbrack -\infty, \infty \rbrack : t = \frac{x}{\sqrt{1-x^2}}
  
      """
      ctx = self.ctx
      a = ctx.convert(a)
      b = ctx.convert(b)
      one = ctx.one
      if (a, b) == (-one, one):
          return nodes
      half = ctx.mpf(0.5)
      new_nodes = []
      if ctx.isinf(a) or ctx.isinf(b):
          if (a, b) == (ctx.ninf, ctx.inf):
              p05 = -half
              for x, w in nodes:
                  x2 = x * x
                  px1 = one - x2
                  spx1 = px1**p05
                  x = x * spx1
                  w *= spx1 / px1
                  new_nodes.append((x, w))
          elif a == ctx.ninf:
              b1 = b + 1
              for x, w in nodes:
                  u = 2 / (x + one)
                  x = b1 - u
                  w *= half * u**2
                  new_nodes.append((x, w))
          elif b == ctx.inf:
              a1 = a - 1
              for x, w in nodes:
                  u = 2 / (x + one)
                  x = a1 + u
                  w *= half * u**2
                  new_nodes.append((x, w))
          elif a == ctx.inf or b == ctx.ninf:
              return [
                  (x, -w)
                  for (x, w) in self.transform_nodes(
                      nodes, b, a, verbose
                  )
              ]
          else:
              raise NotImplementedError
      else:
          # Simple linear change of variables
          C = (b - a) / 2
          D = (b + a) / 2
          for x, w in nodes:
              new_nodes.append((D + C * x, C * w))
      return new_nodes
  
imports: import math
  from ..libmp.backend import xrange
label_desc: Use image node_id 5 for calling the QuadratureRule obj's underlying member method code with example usage: obj.transform_nodes(nodes, a, b, verbose) and returns: new_nodes, nodes, unknown