class_docstr: Store for derivatives of expressions.
  
  Explanation
  ===========
  
  The standard form of the derivative of a Bessel function of order n
  contains two Bessel functions of orders n-1 and n+1, respectively.
  Such forms cannot be used in parallel Risch algorithm, because
  there is a linear recurrence relation between the three functions
  while the algorithm expects that functions and derivatives are
  represented in terms of algebraically independent transcendentals.
  
  The solution is to take two of the functions, e.g., those of orders
  n and n-1, and to express the derivatives in terms of the pair.
  To guarantee that the proper form is used the two derivatives are
  cached as soon as one is encountered.
  
  Derivatives of other functions are also cached at no extra cost.
  All derivatives are with respect to the same variable `x`.
class_docstr_tok: ["Store","for","derivatives","of","expressions",".","Explanation","===========","The","standard","form","of","the","derivative","of","a","Bessel","function","of","order","n","contains","two","Bessel","functions","of","orders","n-1","and","n+1",",","respectively",".","Such","forms","can","not","be","used","in","parallel","Risch","algorithm",",","because","there","is","a","linear","recurrence","relation","between","the","three","functions","while","the","algorithm","expects","that","functions","and","derivatives","are","represented","in","terms","of","algebraically","independent","transcendentals",".","The","solution","is","to","take","two","of","the","functions",",","e.g.",",","those","of","orders","n","and","n-1",",","and","to","express","the","derivatives","in","terms","of","the","pair",".","To","guarantee","that","the","proper","form","is","used","the","two","derivatives","are","cached","as","soon","as","one","is","encountered",".","Derivatives","of","other","functions","are","also","cached","at","no","extra","cost",".","All","derivatives","are","with","respect","to","the","same","variable","`","x","`","."]
code: def get_diff(self, f):
      cache = self.cache
  
      if f in cache:
          pass
      elif not hasattr(f, "func") or not _bessel_table.has(f.func):
          cache[f] = cancel(f.diff(self.x))
      else:
          n, z = f.args
          d0, d1 = _bessel_table.diffs(f.func, n, z)
          dz = self.get_diff(z)
          cache[f] = d0 * dz
          cache[f.func(n - 1, z)] = d1 * dz
  
      return cache[f]
  
imports: from __future__ import annotations
  from itertools import permutations
  from functools import reduce
  from sympy.core.add import Add
  from sympy.core.basic import Basic
  from sympy.core.mul import Mul
  from sympy.core.symbol import Wild, Dummy, Symbol
  from sympy.core.basic import sympify
  from sympy.core.numbers import Rational, pi, I
  from sympy.core.relational import Eq, Ne
  from sympy.core.singleton import S
  from sympy.core.sorting import ordered
  from sympy.core.traversal import iterfreeargs
  from sympy.functions import exp, sin, cos, tan, cot, asin, atan
  from sympy.functions import log, sinh, cosh, tanh, coth, asinh
  from sympy.functions import sqrt, erf, erfi, li, Ei
  from sympy.functions import besselj, bessely, besseli, besselk
  from sympy.functions import hankel1, hankel2, jn, yn
  from sympy.functions.elementary.complexes import Abs, re, im, sign, arg
  from sympy.functions.elementary.exponential import LambertW
  from sympy.functions.elementary.integers import floor, ceiling
  from sympy.functions.elementary.piecewise import Piecewise
  from sympy.functions.special.delta_functions import Heaviside, DiracDelta
  from sympy.simplify.radsimp import collect
  from sympy.logic.boolalg import And, Or
  from sympy.utilities.iterables import uniq
  from sympy.polys import quo, gcd, lcm, factor_list, cancel, PolynomialError
  from sympy.polys.monomials import itermonomials
  from sympy.polys.polyroots import root_factors
  from sympy.polys.rings import PolyRing
  from sympy.polys.solvers import solve_lin_sys
  from sympy.polys.constructor import construct_domain
  from sympy.integrals.integrals import integrate
label_desc: Use image node_id 2 for calling the DiffCache obj's underlying member method code with example usage: obj.get_diff(f) and returns: cache