class_docstr: Represents the limiting behavior of some function.
  
  Explanation
  ===========
  
  The order of a function characterizes the function based on the limiting
  behavior of the function as it goes to some limit. Only taking the limit
  point to be a number is currently supported. This is expressed in
  big O notation [1]_.
  
  The formal definition for the order of a function `g(x)` about a point `a`
  is such that `g(x) = O(f(x))` as `x \rightarrow a` if and only if there
  exists a `\delta > 0` and an `M > 0` such that `|g(x)| \leq M|f(x)|` for
  `|x-a| < \delta`.  This is equivalent to `\limsup_{x \rightarrow a}
  |g(x)/f(x)| < \infty`.
  
  Let's illustrate it on the following example by taking the expansion of
  `\sin(x)` about 0:
  
  .. math ::
      \sin(x) = x - x^3/3! + O(x^5)
  
  where in this case `O(x^5) = x^5/5! - x^7/7! + \cdots`. By the definition
  of `O`, there is a `\delta > 0` and an `M` such that:
  
  .. math ::
      |x^5/5! - x^7/7! + ....| <= M|x^5| \text{ for } |x| < \delta
  
  or by the alternate definition:
  
  .. math ::
      \lim_{x \rightarrow 0} | (x^5/5! - x^7/7! + ....) / x^5| < \infty
  
  which surely is true, because
  
  .. math ::
      \lim_{x \rightarrow 0} | (x^5/5! - x^7/7! + ....) / x^5| = 1/5!
  
  
  As it is usually used, the order of a function can be intuitively thought
  of representing all terms of powers greater than the one specified. For
  example, `O(x^3)` corresponds to any terms proportional to `x^3,
  x^4,\ldots` and any higher power. For a polynomial, this leaves terms
  proportional to `x^2`, `x` and constants.
  
  Examples
  ========
  
  >>> from sympy import O, oo, cos, pi
  >>> from sympy.abc import x, y
  
  >>> O(x + x**2)
  O(x)
  >>> O(x + x**2, (x, 0))
  O(x)
  >>> O(x + x**2, (x, oo))
  O(x**2, (x, oo))
  
  >>> O(1 + x*y)
  O(1, x, y)
  >>> O(1 + x*y, (x, 0), (y, 0))
  O(1, x, y)
  >>> O(1 + x*y, (x, oo), (y, oo))
  O(x*y, (x, oo), (y, oo))
  
  >>> O(1) in O(1, x)
  True
  >>> O(1, x) in O(1)
  False
  >>> O(x) in O(1, x)
  True
  >>> O(x**2) in O(x)
  True
  
  >>> O(x)*x
  O(x**2)
  >>> O(x) - O(x)
  O(x)
  >>> O(cos(x))
  O(1)
  >>> O(cos(x), (x, pi/2))
  O(x - pi/2, (x, pi/2))
  
  References
  ==========
  
  .. [1] `Big O notation <https://en.wikipedia.org/wiki/Big_O_notation>`_
  
  Notes
  =====
  
  In ``O(f(x), x)`` the expression ``f(x)`` is assumed to have a leading
  term.  ``O(f(x), x)`` is automatically transformed to
  ``O(f(x).as_leading_term(x),x)``.
  
      ``O(expr*f(x), x)`` is ``O(f(x), x)``
  
      ``O(expr, x)`` is ``O(1)``
  
      ``O(0, x)`` is 0.
  
  Multivariate O is also supported:
  
      ``O(f(x, y), x, y)`` is transformed to
      ``O(f(x, y).as_leading_term(x,y).as_leading_term(y), x, y)``
  
  In the multivariate case, it is assumed the limits w.r.t. the various
  symbols commute.
  
  If no symbols are passed then all symbols in the expression are used
  and the limit point is assumed to be zero.
class_docstr_tok: ["Represents","the","limiting","behavior","of","some","function",".","Explanation","===========","The","order","of","a","function","characterizes","the","function","based","on","the","limiting","behavior","of","the","function","as","it","goes","to","some","limit",".","Only","taking","the","limit","point","to","be","a","number","is","currently","supported",".","This","is","expressed","in","big","O","notation","[","1","]","_",".","The","formal","definition","for","the","order","of","a","function","`","g","(","x",")","`","about","a","point","`","a","`","is","such","that","`","g","(","x",")","=","O","(","f","(","x",")",")","`","as","`","x","\\rightarrow","a","`","if","and","only","if","there","exists","a","`","\\delta",">","0","`","and","an","`","M",">","0","`","such","that","`","|g","(","x",")","|","\\leq","M|f","(","x",")","|","`","for","`","|x-a|","<","\\delta","`",".","This","is","equivalent","to","`","\\limsup_","{","x","\\rightarrow","a","}","|g","(","x",")","\/f","(","x",")","|","<","\\infty","`",".","Let","'s","illustrate","it","on","the","following","example","by","taking","the","expansion","of","`","\\sin","(","x",")","`","about","0",":","..","math",":",":","\\sin","(","x",")","=","x","-","x^3\/3","!","+","O","(","x^5",")","where","in","this","case","`","O","(","x^5",")","=","x^5\/5","!","-","x^7\/7","!","+","\\cdots","`",".","By","the","definition","of","`","O","`",",","there","is","a","`","\\delta",">","0","`","and","an","`","M","`","such","that",":","..","math",":",":","|x^5\/5","!","-","x^7\/7","!","+","....","|","<","=","M|x^5|","\\text","{","for","}","|x|","<","\\delta","or","by","the","alternate","definition",":","..","math",":",":","\\lim_","{","x","\\rightarrow","0","}","|","(","x^5\/5","!","-","x^7\/7","!","+","....",")","\/","x^5|","<","\\infty","which","surely","is","true",",","because","..","math",":",":","\\lim_","{","x","\\rightarrow","0","}","|","(","x^5\/5","!","-","x^7\/7","!","+","....",")","\/","x^5|","=","1\/5","!","As","it","is","usually","used",",","the","order","of","a","function","can","be","intuitively","thought","of","representing","all","terms","of","powers","greater","than","the","one","specified",".","For","example",",","`","O","(","x^3",")","`","corresponds","to","any","terms","proportional","to","`","x^3",",","x^4",",","\\ldots","`","and","any","higher","power",".","For","a","polynomial",",","this","leaves","terms","proportional","to","`","x^2","`",",","`","x","`","and","constants",".","Examples","========",">",">",">","from","sympy","import","O",",","oo",",","cos",",","pi",">",">",">","from","sympy.abc","import","x",",","y",">",">",">","O","(","x","+","x","*","*","2",")","O","(","x",")",">",">",">","O","(","x","+","x","*","*","2",",","(","x",",","0",")",")","O","(","x",")",">",">",">","O","(","x","+","x","*","*","2",",","(","x",",","oo",")",")","O","(","x","*","*","2",",","(","x",",","oo",")",")",">",">",">","O","(","1","+","x","*","y",")","O","(","1",",","x",",","y",")",">",">",">","O","(","1","+","x","*","y",",","(","x",",","0",")",",","(","y",",","0",")",")","O","(","1",",","x",",","y",")",">",">",">","O","(","1","+","x","*","y",",","(","x",",","oo",")",",","(","y",",","oo",")",")","O","(","x","*","y",",","(","x",",","oo",")",",","(","y",",","oo",")",")",">",">",">","O","(","1",")","in","O","(","1",",","x",")","True",">",">",">","O","(","1",",","x",")","in","O","(","1",")","False",">",">",">","O","(","x",")","in","O","(","1",",","x",")","True",">",">",">","O","(","x","*","*","2",")","in","O","(","x",")","True",">",">",">","O","(","x",")","*","x","O","(","x","*","*","2",")",">",">",">","O","(","x",")","-","O","(","x",")","O","(","x",")",">",">",">","O","(","cos","(","x",")",")","O","(","1",")",">",">",">","O","(","cos","(","x",")",",","(","x",",","pi\/2",")",")","O","(","x","-","pi\/2",",","(","x",",","pi\/2",")",")","References","==========","..","[","1","]","`","Big","O","notation","<","https",":","\/\/en.wikipedia.org\/wiki\/Big_O_notation",">","`","_","Notes","=====","In","``","O","(","f","(","x",")",",","x",")","``","the","expression","``","f","(","x",")","``","is","assumed","to","have","a","leading","term",".","``","O","(","f","(","x",")",",","x",")","``","is","automatically","transformed","to","``","O","(","f","(","x",")",".as_leading_term","(","x",")",",","x",")","``",".","``","O","(","expr","*","f","(","x",")",",","x",")","``","is","``","O","(","f","(","x",")",",","x",")","``","``","O","(","expr",",","x",")","``","is","``","O","(","1",")","``","``","O","(","0",",","x",")","``","is","0",".","Multivariate","O","is","also","supported",":","``","O","(","f","(","x",",","y",")",",","x",",","y",")","``","is","transformed","to","``","O","(","f","(","x",",","y",")",".as_leading_term","(","x",",","y",")",".as_leading_term","(","y",")",",","x",",","y",")","``","In","the","multivariate","case",",","it","is","assumed","the","limits","w.r.t",".","the","various","symbols","commute",".","If","no","symbols","are","passed","then","all","symbols","in","the","expression","are","used","and","the","limit","point","is","assumed","to","be","zero","."]
code: def __new__(cls, expr, *args, **kwargs):
      expr = sympify(expr)
  
      if not args:
          if expr.is_Order:
              variables = expr.variables
              point = expr.point
          else:
              variables = list(expr.free_symbols)
              point = [S.Zero] * len(variables)
      else:
          args = list(args if is_sequence(args) else [args])
          variables, point = [], []
          if is_sequence(args[0]):
              for a in args:
                  v, p = list(map(sympify, a))
                  variables.append(v)
                  point.append(p)
          else:
              variables = list(map(sympify, args))
              point = [S.Zero] * len(variables)
  
      if not all(v.is_symbol for v in variables):
          raise TypeError(
              "Variables are not symbols, got %s" % variables
          )
  
      if len(list(uniq(variables))) != len(variables):
          raise ValueError(
              "Variables are supposed to be unique symbols, got %s"
              % variables
          )
  
      if expr.is_Order:
          expr_vp = dict(expr.args[1:])
          new_vp = dict(expr_vp)
          vp = dict(zip(variables, point))
          for v, p in vp.items():
              if v in new_vp.keys():
                  if p != new_vp[v]:
                      raise NotImplementedError(
                          "Mixing Order at different points is not supported."
                      )
              else:
                  new_vp[v] = p
          if set(expr_vp.keys()) == set(new_vp.keys()):
              return expr
          else:
              variables = list(new_vp.keys())
              point = [new_vp[v] for v in variables]
  
      if expr is S.NaN:
          return S.NaN
  
      if any(x in p.free_symbols for x in variables for p in point):
          raise ValueError("Got %s as a point." % point)
  
      if variables:
          if any(p != point[0] for p in point):
              raise NotImplementedError(
                  "Multivariable orders at different points are not supported."
              )
          if point[0] in (S.Infinity, S.Infinity * S.ImaginaryUnit):
              s = {k: 1 / Dummy() for k in variables}
              rs = {1 / v: 1 / k for k, v in s.items()}
              ps = [S.Zero for p in point]
          elif point[0] in (
              S.NegativeInfinity,
              S.NegativeInfinity * S.ImaginaryUnit,
          ):
              s = {k: -1 / Dummy() for k in variables}
              rs = {-1 / v: -1 / k for k, v in s.items()}
              ps = [S.Zero for p in point]
          elif point[0] is not S.Zero:
              s = {k: Dummy() + point[0] for k in variables}
              rs = {
                  (v - point[0]).together(): k - point[0]
                  for k, v in s.items()
              }
              ps = [S.Zero for p in point]
          else:
              s = ()
              rs = ()
              ps = list(point)
  
          expr = expr.subs(s)
  
          if expr.is_Add:
              expr = expr.factor()
  
          if s:
              args = tuple([r[0] for r in rs.items()])
          else:
              args = tuple(variables)
  
          if len(variables) > 1:
              # XXX: better way?  We need this expand() to
              # workaround e.g: expr = x*(x + y).
              # (x*(x + y)).as_leading_term(x, y) currently returns
              # x*y (wrong order term!).  That's why we want to deal with
              # expand()'ed expr (handled in "if expr.is_Add" branch below).
              expr = expr.expand()
  
          old_expr = None
          while old_expr != expr:
              old_expr = expr
              if expr.is_Add:
                  lst = expr.extract_leading_order(args)
                  expr = Add(*[f.expr for (e, f) in lst])
  
              elif expr:
                  try:
                      expr = expr.as_leading_term(*args)
                  except PoleError:
                      if isinstance(expr, Function) or all(
                          isinstance(arg, Function) for arg in expr.args
                      ):
                          # It is not possible to simplify an expression
                          # containing only functions (which raise error on
                          # call to leading term) further
                          pass
                      else:
                          orders = []
                          pts = tuple(zip(args, ps))
                          for arg in expr.args:
                              try:
                                  lt = arg.as_leading_term(*args)
                              except PoleError:
                                  lt = arg
                              if lt not in args:
                                  order = Order(lt)
                              else:
                                  order = Order(lt, *pts)
                              orders.append(order)
                          if expr.is_Add:
                              new_expr = Order(Add(*orders), *pts)
                              if new_expr.is_Add:
                                  new_expr = Order(
                                      Add(
                                          *[
                                              a.expr
                                              for a in new_expr.args
                                          ]
                                      ),
                                      *pts,
                                  )
                              expr = new_expr.expr
                          elif expr.is_Mul:
                              expr = Mul(*[a.expr for a in orders])
                          elif expr.is_Pow:
                              e = expr.exp
                              b = expr.base
                              expr = exp(e * log(b))
  
                  # It would probably be better to handle this somewhere
                  # else. This is needed for a testcase in which there is a
                  # symbol with the assumptions zero=True.
                  if expr.is_zero:
                      expr = S.Zero
                  else:
                      expr = expr.as_independent(*args, as_Add=False)[1]
  
                  expr = expand_power_base(expr)
                  expr = expand_log(expr)
  
                  if len(args) == 1:
                      # The definition of O(f(x)) symbol explicitly stated that
                      # the argument of f(x) is irrelevant.  That's why we can
                      # combine some power exponents (only "on top" of the
                      # expression tree for f(x)), e.g.:
                      # x**p * (-x)**q -> x**(p+q) for real p, q.
                      x = args[0]
                      margs = list(
                          Mul.make_args(
                              expr.as_independent(x, as_Add=False)[1]
                          )
                      )
  
                      for i, t in enumerate(margs):
                          if t.is_Pow:
                              b, q = t.args
                              if (
                                  b in (x, -x)
                                  and q.is_real
                                  and not q.has(x)
                              ):
                                  margs[i] = x**q
                              elif b.is_Pow and not b.exp.has(x):
                                  b, r = b.args
                                  if b in (x, -x) and r.is_real:
                                      margs[i] = x ** (r * q)
                              elif (
                                  b.is_Mul
                                  and b.args[0] is S.NegativeOne
                              ):
                                  b = -b
                                  if b.is_Pow and not b.exp.has(x):
                                      b, r = b.args
                                      if b in (x, -x) and r.is_real:
                                          margs[i] = x ** (r * q)
  
                      expr = Mul(*margs)
  
          expr = expr.subs(rs)
  
      if expr.is_Order:
          expr = expr.expr
  
      if not expr.has(*variables) and not expr.is_zero:
          expr = S.One
  
      # create Order instance:
      vp = dict(zip(variables, point))
      variables.sort(key=default_sort_key)
      point = [vp[v] for v in variables]
      args = (expr,) + Tuple(*zip(variables, point))
      obj = Expr.__new__(cls, *args)
      return obj
  
imports: from sympy.core import S, sympify, Expr, Dummy, Add, Mul
  from sympy.core.cache import cacheit
  from sympy.core.containers import Tuple
  from sympy.core.function import Function, PoleError, expand_power_base, expand_log
  from sympy.core.sorting import default_sort_key
  from sympy.functions.elementary.exponential import exp, log
  from sympy.sets.sets import Complement
  from sympy.utilities.iterables import uniq, is_sequence
label_desc: Use image node_id 1 for calling the Order obj's underlying member method code with example usage: obj.__new__(cls, expr) and returns: obj, S, expr