code: def besselsimp(expr):
      """
      Simplify bessel-type functions.
  
      Explanation
      ===========
  
      This routine tries to simplify bessel-type functions. Currently it only
      works on the Bessel J and I functions, however. It works by looking at all
      such functions in turn, and eliminating factors of "I" and "-1" (actually
      their polar equivalents) in front of the argument. Then, functions of
      half-integer order are rewritten using strigonometric functions and
      functions of integer order (> 1) are rewritten using functions
      of low order.  Finally, if the expression was changed, compute
      factorization of the result with factor().
  
      >>> from sympy import besselj, besseli, besselsimp, polar_lift, I, S
      >>> from sympy.abc import z, nu
      >>> besselsimp(besselj(nu, z*polar_lift(-1)))
      exp(I*pi*nu)*besselj(nu, z)
      >>> besselsimp(besseli(nu, z*polar_lift(-I)))
      exp(-I*pi*nu/2)*besselj(nu, z)
      >>> besselsimp(besseli(S(-1)/2, z))
      sqrt(2)*cosh(z)/(sqrt(pi)*sqrt(z))
      >>> besselsimp(z*besseli(0, z) + z*(besseli(2, z))/2 + besseli(1, z))
      3*z*besseli(0, z)/2
      """
      # TODO
      # - better algorithm?
      # - simplify (cos(pi*b)*besselj(b,z) - besselj(-b,z))/sin(pi*b) ...
      # - use contiguity relations?
  
      def replacer(fro, to, factors):
          factors = set(factors)
  
          def repl(nu, z):
              if factors.intersection(Mul.make_args(z)):
                  return to(nu, z)
              return fro(nu, z)
  
          return repl
  
      def torewrite(fro, to):
          def tofunc(nu, z):
              return fro(nu, z).rewrite(to)
  
          return tofunc
  
      def tominus(fro):
          def tofunc(nu, z):
              return exp(I * pi * nu) * fro(nu, exp_polar(-I * pi) * z)
  
          return tofunc
  
      orig_expr = expr
  
      ifactors = [I, exp_polar(I * pi / 2), exp_polar(-I * pi / 2)]
      expr = expr.replace(
          besselj,
          replacer(besselj, torewrite(besselj, besseli), ifactors),
      )
      expr = expr.replace(
          besseli,
          replacer(besseli, torewrite(besseli, besselj), ifactors),
      )
  
      minusfactors = [-1, exp_polar(I * pi)]
      expr = expr.replace(
          besselj, replacer(besselj, tominus(besselj), minusfactors)
      )
      expr = expr.replace(
          besseli, replacer(besseli, tominus(besseli), minusfactors)
      )
  
      z0 = Dummy("z")
  
      def expander(fro):
          def repl(nu, z):
              if (nu % 1) == S.Half:
                  return simplify(
                      trigsimp(
                          unpolarify(
                              fro(nu, z0)
                              .rewrite(besselj)
                              .rewrite(jn)
                              .expand(func=True)
                          ).subs(z0, z)
                      )
                  )
              elif nu.is_Integer and nu > 1:
                  return fro(nu, z).expand(func=True)
              return fro(nu, z)
  
          return repl
  
      expr = expr.replace(besselj, expander(besselj))
      expr = expr.replace(bessely, expander(bessely))
      expr = expr.replace(besseli, expander(besseli))
      expr = expr.replace(besselk, expander(besselk))
  
      def _bessel_simp_recursion(expr):
          def _use_recursion(bessel, expr):
              while True:
                  bessels = expr.find(lambda x: isinstance(x, bessel))
                  try:
                      for ba in sorted(
                          bessels, key=lambda x: re(x.args[0])
                      ):
                          a, x = ba.args
                          bap1 = bessel(a + 1, x)
                          bap2 = bessel(a + 2, x)
                          if expr.has(bap1) and expr.has(bap2):
                              expr = expr.subs(
                                  ba, 2 * (a + 1) / x * bap1 - bap2
                              )
                              break
                      else:
                          return expr
                  except (ValueError, TypeError):
                      return expr
  
          if expr.has(besselj):
              expr = _use_recursion(besselj, expr)
          if expr.has(bessely):
              expr = _use_recursion(bessely, expr)
          return expr
  
      expr = _bessel_simp_recursion(expr)
      if expr != orig_expr:
          expr = expr.factor()
  
      return expr
  
imports: from collections import defaultdict
  from sympy.concrete.products import Product
  from sympy.concrete.summations import Sum
  from sympy.core import Basic, S, Add, Mul, Pow, Symbol, sympify, expand_func, Function, Dummy, Expr, factor_terms, expand_power_exp, Eq
  from sympy.core.exprtools import factor_nc
  from sympy.core.parameters import global_parameters
  from sympy.core.function import expand_log, count_ops, _mexpand, nfloat, expand_mul, expand
  from sympy.core.numbers import Float, I, pi, Rational
  from sympy.core.relational import Relational
  from sympy.core.rules import Transform
  from sympy.core.sorting import ordered
  from sympy.core.sympify import _sympify
  from sympy.core.traversal import bottom_up, walk
  from sympy.functions import gamma, exp, sqrt, log, exp_polar, re
  from sympy.functions.combinatorial.factorials import CombinatorialFunction
  from sympy.functions.elementary.complexes import unpolarify, Abs, sign
  from sympy.functions.elementary.exponential import ExpBase
  from sympy.functions.elementary.hyperbolic import HyperbolicFunction
  from sympy.functions.elementary.integers import ceiling
  from sympy.functions.elementary.piecewise import Piecewise, piecewise_fold, piecewise_simplify
  from sympy.functions.elementary.trigonometric import TrigonometricFunction
  from sympy.functions.special.bessel import BesselBase, besselj, besseli, besselk, bessely, jn
  from sympy.functions.special.tensor_functions import KroneckerDelta
  from sympy.integrals.integrals import Integral
  from sympy.matrices.expressions import MatrixExpr, MatAdd, MatMul, MatPow, MatrixSymbol
  from sympy.polys import together, cancel, factor
  from sympy.polys.numberfields.minpoly import _is_sum_surds, _minimal_polynomial_sq
  from sympy.simplify.combsimp import combsimp
  from sympy.simplify.cse_opts import sub_pre, sub_post
  from sympy.simplify.hyperexpand import hyperexpand
  from sympy.simplify.powsimp import powsimp
  from sympy.simplify.radsimp import radsimp, fraction, collect_abs
  from sympy.simplify.sqrtdenest import sqrtdenest
  from sympy.simplify.trigsimp import trigsimp, exptrigsimp
  from sympy.utilities.decorator import deprecated
  from sympy.utilities.iterables import has_variety, sift, subsets, iterable
  from sympy.utilities.misc import as_int
  import mpmath
label_desc: Use image node_id 19 for calling a global function with example usage: besselsimp(expr) and returns: expr, repl, tofunc, tofunc, repl, expr, fro, fro, unknown, fro, to, simplify, fro, expr, expr