Repository: sympy/sympy
File: sympy/solvers/ode/single.py (Python)

Code before:
    References
    ==========
    - Abramowitz & Stegun, Handbook of Mathematical Functions, 9.1.52
    - https://eqworld.ipmnet.ru/en/solutions/ode/ode0201.pdf
    """
    hint = "2nd_linear_bessel_symbolic"
    has_integral = False
    order = [2]

    def _matches(self):
        eq = self.ode_problem.eq_high_order_free
        f = self.ode_problem.func
        x = self.ode_problem.sym
        order = self.ode_problem.order

        if order != 2:
            return False

        # Get linear coefficients
        match = self.ode_problem.get_linear_coefficients(eq, f, order)
        if not match:
            return False

        # We need: a3*y'' + b3*y' + c3*y = 0
        # For Bessel with symbolic exponent: y'' + 0*y' + (x^k)*y = 0
        c3,b3,a3,rhs=match.values()

        # Check if b3 = 0 (no first derivative term) or a3 = 0  (no second derivative term)
        # or rhs != 0 (non-homogeneous)
        if b3 != 0 or a3 == 0 or rhs!=0:
            return False

        # Normalize: divide by coefficient of y''
        c3 = c3 / a3

        # Check if c3 is of the form A*x^k where k has free symbols
        # This indicates symbolic exponent
        A_sym = Wild('A_sym', exclude=[x])
        k_sym = Wild('k_sym', exclude=[x])

        pattern_match = c3.match(A_sym * x**k_sym)

        if not pattern_match or k_sym not in pattern_match:
            return False

        # Store the matched values
        self.match_dict = {
            'A': pattern_match[A_sym],
            'k': pattern_match[k_sym],
        }


Review comment (suggestion):
Per PEP 8 there should be spaces around the `=` here but moire importantly this should not assume anything about the order of `.values()`. Dicts can return things in different orders.

Code after:
    References
    ==========
    - Abramowitz & Stegun, Handbook of Mathematical Functions, 9.1.52
    - https://eqworld.ipmnet.ru/en/solutions/ode/ode0201.pdf
    """
    hint = "2nd_linear_bessel_transform"
    has_integral = False
    order = [2]

    def _matches(self):
        eq = self.ode_problem.eq_high_order_free
        f = self.ode_problem.func
        x = self.ode_problem.sym
        order = self.ode_problem.order

        if order != 2:
            return False

        # Get linear coefficients
        match = self.ode_problem.get_linear_coefficients(eq, f, order)
        if not match:
            return False

        # We need: a3*y'' + b3*y' + c3*y = 0
        # For Bessel with symbolic exponent: y'' + 0*y' + (x^k)*y = 0
        a3 = match[2]  # coefficient of y''
        b3 = match[1]  # coefficient of y'
        c3 = match[0]  # coefficient of y
        rhs = match[-1]  # right-hand side

        # Check if b3 = 0 (no first derivative term) or a3 = 0  (no second derivative term)
        # or rhs != 0 (non-homogeneous)
        if b3 != 0 or a3 == 0 or rhs != 0:
            return False

        # Normalize: divide by coefficient of y''
        c3 = c3 / a3

        # Check if c3 is of the form A*x^k where k has free symbols
        A_sym = Wild('A_sym', exclude=[x])
        k_sym = Wild('k_sym', exclude=[x])

        pattern_match = c3.match(A_sym * x**k_sym)

        if not pattern_match or k_sym not in pattern_match:
            return False

        k_val = pattern_match[k_sym]
        A_val = pattern_match[A_sym]

        if k_val == -2: