Repository: sympy/sympy

Issue:
coefficients in Bernoulli DE
Hello, everyone! 

I've ran into problems using Bernoulli equation with certain coefficients. I wanted to solve this equation with `dsolve(de, f(x))`
```
de = Eq(f(x).diff(x), 20*f(x)**2 - 500*f(x)/7200)
```
but got stuck on a long executing time. I checked the reduced coefficients
```
de = Eq(f(x).diff(x), 2*f(x)**2 - 5*f(x)/7)
```
and got this answer:
```
Eq(x - 7*log(f(x) - 5/14)/5 + 7*log(f(x))/5, C1)
```
By using `classify_ode` I found out that equations aren't completely classified. They aren't classified as 'Bernoulli' so I can't use a hint to point the type manually. I checked all available coefficients from -2 to 2 and it turns out that equations based on some of them aren't classified as Bernoulli equations. 
```
from sympy import *
f = Function("f")
x = symbols("x")
for i in range(-2,3,1):
    for j in range(-2,3,1):
        if i != 0 and j != 0:
            de = Eq(f(x).diff(x), i*f(x) + j*f(x)**2)
            if classify_ode(de).count('Bernoulli') == 0:
                print(de) 
# gives
#Eq(Derivative(f(x), x), -2*f(x)**2 - 2*f(x))
#Eq(Derivative(f(x), x), -2*f(x)**2 - f(x))
#Eq(Derivative(f(x), x), -2*f(x)**2 + f(x))
#Eq(Derivative(f(x), x), -2*f(x)**2 + 2*f(x))
```
Using `dsolve` leads to the correct answers for this four equations. However changing `-2*f(x)**2` to `-0.5*f(x)**2` leads to incomplete answers.

I am running SymPy 1.9. I checked live version with SymPy 1.5.1 and have similar results, except that the type is classified as Bernoulli and I can manually specify it with `hint='Bernoulli'` and get the right answers.

Any suggestions to solve the initial equation with SymPy 1.9?

 Thanks in advance

Discussion:

Patch:
diff --git a/sympy/core/operations.py b/sympy/core/operations.py
index cd0e56fa15..02cccf55e1 100644
--- a/sympy/core/operations.py
+++ b/sympy/core/operations.py
@@ -213,6 +213,7 @@ def _matches_commutative(self, expr, repl_dict=None, old=False):
         equivalent.
 
         """
+        from .function import _coeff_isneg
         # make sure expr is Expr if pattern is Expr
         from .expr import Expr
         if isinstance(self, Expr) and not isinstance(expr, Expr):
@@ -254,7 +255,10 @@ def _matches_commutative(self, expr, repl_dict=None, old=False):
                 return None
             newexpr = self._combine_inverse(expr, exact)
             if not old and (expr.is_Add or expr.is_Mul):
-                if newexpr.count_ops() > expr.count_ops():
+                check = newexpr
+                if _coeff_isneg(check):
+                    check = -check
+                if check.count_ops() > expr.count_ops():
                     return None
             newpattern = self._new_rawargs(*wild_part)
             return newpattern.matches(newexpr, repl_dict)


Test patch:
diff --git a/sympy/core/tests/test_match.py b/sympy/core/tests/test_match.py
index 1f30400419..caa25e3c9d 100644
--- a/sympy/core/tests/test_match.py
+++ b/sympy/core/tests/test_match.py
@@ -756,3 +756,11 @@ def test_match_bound():
     assert Sum(x, (x, 1, 2)).match(Sum(y, (y, 1, W))) == {W: 2}
     assert Sum(x, (x, 1, 2)).match(Sum(V, (V, 1, W))) == {W: 2, V:x}
     assert Sum(x, (x, 1, 2)).match(Sum(V, (V, 1, 2))) == {V:x}
+
+
+def test_issue_22462():
+    x, f = symbols('x'), Function('f')
+    n, Q = symbols('n Q', cls=Wild)
+    pattern = -Q*f(x)**n
+    eq = 5*f(x)**2
+    assert pattern.matches(eq) == {n: 2, Q: -5}
diff --git a/sympy/solvers/ode/tests/test_ode.py b/sympy/solvers/ode/tests/test_ode.py
index c53d38d38b..fe3faf1c0d 100644
--- a/sympy/solvers/ode/tests/test_ode.py
+++ b/sympy/solvers/ode/tests/test_ode.py
@@ -740,14 +740,16 @@ def test_undetermined_coefficients_match():
     assert _undetermined_coefficients_match(cos(x**2), x) == {'test': False}
     assert _undetermined_coefficients_match(2**(x**2), x) == {'test': False}
 
-def test_issue_4785():
+
+def test_issue_4785_22462():
     from sympy.abc import A
     eq = x + A*(x + diff(f(x), x) + f(x)) + diff(f(x), x) + f(x) + 2
     assert classify_ode(eq, f(x)) == ('factorable', '1st_exact', '1st_linear',
-        'almost_linear', '1st_power_series', 'lie_group',
+        'Bernoulli', 'almost_linear', '1st_power_series', 'lie_group',
         'nth_linear_constant_coeff_undetermined_coefficients',
         'nth_linear_constant_coeff_variation_of_parameters',
-        '1st_exact_Integral', '1st_linear_Integral', 'almost_linear_Integral',
+        '1st_exact_Integral', '1st_linear_Integral', 'Bernoulli_Integral',
+        'almost_linear_Integral',
         'nth_linear_constant_coeff_variation_of_parameters_Integral')
     # issue 4864
     eq = (x**2 + f(x)**2)*f(x).diff(x) - 2*x*f(x)
@@ -760,6 +762,7 @@ def test_issue_4785():
         '1st_homogeneous_coeff_subs_indep_div_dep_Integral',
         '1st_homogeneous_coeff_subs_dep_div_indep_Integral')
 
+
 def test_issue_4825():
     raises(ValueError, lambda: dsolve(f(x, y).diff(x) - y*f(x, y), f(x)))
     assert classify_ode(f(x, y).diff(x) - y*f(x, y), f(x), dict=True) == \
@@ -1059,3 +1062,10 @@ def test_issue_22604():
     assert x1sol == Eq(x1(t), sqrt(3 - sqrt(5))*(sqrt(10) + 5*sqrt(2))*cos(sqrt(2)*t*sqrt(3 - sqrt(5))/2)/20 + \
                        (-5*sqrt(2) + sqrt(10))*sqrt(sqrt(5) + 3)*cos(sqrt(2)*t*sqrt(sqrt(5) + 3)/2)/20)
     assert x2sol == Eq(x2(t), (sqrt(5) + 5)*cos(sqrt(2)*t*sqrt(3 - sqrt(5))/2)/10 + (5 - sqrt(5))*cos(sqrt(2)*t*sqrt(sqrt(5) + 3)/2)/10)
+
+
+def test_issue_22462():
+    for de in [
+            Eq(f(x).diff(x), -20*f(x)**2 - 500*f(x)/7200),
+            Eq(f(x).diff(x), -2*f(x)**2 - 5*f(x)/7)]:
+        assert 'Bernoulli' in classify_ode(de, f(x))