Repository: sympy/sympy
Pull request: Added tests to prevent oo and wrong coefficient of Min in piecewise integration for cases with both float and int 

#### References to other Issues or PRs
Fixes #20781


#### Brief description of what is fixed or changed
Test prevents the additional +oo and adds the correct (=2) coefficient in the Min function that calculates piecewise integration with two variables. the problem occurs when both variables showing range of value of x, are functionally equal but with float and int data types. 

<!-- BEGIN RELEASE NOTES -->
NO ENTRY
<!-- END RELEASE NOTES -->




Problem statement:
Sympy.integrate wrongfully returns oo when applied on Piecewise with both floats and integers of same value
# introduction
When integrating the sum of the shown two piecewise functions, it wrongfully returns oo.
This happens when floats and integers at functionally the same value appear.

IPython console for SymPy 1.7.1 (Python 3.8.5-64-bit)

# example
````
import sympy as sp
x_d = sp.symbols('x_d')    
x, y,= sp.symbols('x y')


fun1 = lambda x,a1: sp.Piecewise((0,x<a1),(1,x>=a1))
fun2 = lambda x,a2: sp.Piecewise((0,x<a2),(1,x>=a2))

fun_sum = lambda x,a1,a2: sp.Piecewise((0,x<a1),(1,x>=a1)) \
                    +sp.Piecewise((0,x<a2),(1,x>=a2))

print('### wrong output')
print('#### a1=0 a2=0.0')                    
print(sp.integrate(fun_sum((x_d),0,0.0),(x_d,-float('Inf'),x)))
print(sp.integrate(fun_sum((x_d),0,0.0),(x_d,-float('Inf'),x)))
print('#### a1=0.0 a2=0')                    
print(sp.integrate(fun_sum((x_d),0.0,0),(x_d,-float('Inf'),x)))
print(sp.integrate(fun_sum((x_d),0.0,0),(x_d,-float('Inf'),x)))
print('#### a1=1.0 a2=1')                    
print(sp.integrate(fun_sum((x_d),1.0,1),(x_d,-float('Inf'),x)))
print(sp.integrate(fun_sum((x_d),1.0,1),(x_d,-float('Inf'),x)))

print('### expected output')                    
print('#### a1=0.0 a2=0.0')                    
print(sp.integrate(fun_sum((x_d),0.0,0.0),(x_d,-float('Inf'),x)))
print(sp.integrate(fun_sum((x_d),0.0,0.0),(x_d,-float('Inf'),x)))
print('#### a1=0 a2=0')                    
print(sp.integrate(fun_sum((x_d),0,0),(x_d,-float('Inf'),x)))
print(sp.integrate(fun_sum((x_d),0,0),(x_d,-float('Inf'),x)))
````
# output
````
### wrong output
#### a1=0 a2=0.0
2*x - Min(0.0, x) + oo
2*x - Min(0.0, x) + oo
#### a1=0.0 a2=0
2*x - Min(0.0, x) + oo
2*x - Min(0.0, x) + oo
#### a1=1.0 a2=1
2*x - Min(1.0, x) + oo
2*x - Min(1.0, x) + oo
### expected output
#### a1=0.0 a2=0.0
2*x - 2*Min(0.0, x)
2*x - 2*Min(0.0, x)
#### a1=0 a2=0
2*x - 2*Min(0, x)
2*x - 2*Min(0, x)
````

Edit: simplified example

Hints from issue discussion:
Hey @oscarbenjamin @asmeurer  the problem is caused by these lines:
https://github.com/sympy/sympy/blob/14db44e03a8622da5cfe11f61ff43131ffd1fade/sympy/functions/elementary/piecewise.py#L262-L272
It took a lot of debugging. The problem is that the `current_cond` stores the conditions it had already got for example if there is a list of conditions in `cond.args = ['x <0' , 'x>1', 'x<0']` then `current_cond` will store `x < 0` only once but if there is `x < 0` as well as `x < 0.0`, they are both stored since they are treated differently and the final piecewise function made using them is messed up. Can u suggest a way to counter this. I think it has something to do with sympy based on python.
If there are all floats and one of them has `0.0` then it will be converted to `0` by this and therefore causing the above mentioned problem. The problem is caused here https://github.com/sympy/sympy/blob/14db44e03a8622da5cfe11f61ff43131ffd1fade/sympy/solvers/inequalities.py#L485 which changes `x > 0.0` to `x > 0` as `e.lhs - e.rhs` in case of `x,0.0` will give `x` rather than `x-0.0`. This later makes the inequality `x > 0`. I have made change to solve that. But if there are some integers and some floats then there will be the above problem.
thanks for your help. I have retested this with python 3.10 and sympy 1.11.1.

The bug seems to be fixed, I am closing this issue

# output
````
#### a1=0 a2=0.0
2*x - 2*Min(0, x)
2*x - 2*Min(0, x)
#### a1=0.0 a2=0
2*x - 2*Min(0, x)
2*x - 2*Min(0, x)
#### a1=1.0 a2=1
2*x - 2*Min(1, x)
2*x - 2*Min(1, x)
````
The fix should be bisected and a test should be added to show that the problem is fixed.
This was also fixed by commit 6336e467274c67673bad286c9151f7b6e131c0d7 from gh-22286

Commit message: added tests for #20781

Patch to review:
diff --git a/.mailmap b/.mailmap
index ed9268cc06c1..dd2a1322503d 100644
--- a/.mailmap
+++ b/.mailmap
@@ -612,6 +612,8 @@ Gaurav Jain <gjain369@gmail.com> Gaurav Jain <72644006+gjain-7@users.noreply.git
 Gautam Menghani <gum3ng@protonmail.com> gautammenghani <gautammenghani14@gmail.com>
 Gautam Menghani <gum3ng@protonmail.com> gum3ng <78410304+gum3ng@users.noreply.github.com>
 Gautam Menghani <gum3ng@protonmail.com> gum3ng <gum3ng@protonmail.com>
+Geetika Vadali <geetika.vadali4@gmail.com> Geetika V <geetika047btcsai21@igdtuw.ac.in>
+Geetika Vadali <geetika.vadali4@gmail.com> Geetika Vadali <123307246+geetHonve@users.noreply.github.com>
 Geoffry Song <goffrie@gmail.com>
 George Korepanov <gkorepanov.gk@gmail.com>
 George Waksman <waksman@gwax.com>
diff --git a/sympy/integrals/tests/test_integrals.py b/sympy/integrals/tests/test_integrals.py
index f2c01ae9d104..04b5173a67b5 100644
--- a/sympy/integrals/tests/test_integrals.py
+++ b/sympy/integrals/tests/test_integrals.py
@@ -2098,6 +2098,16 @@ def test_issue_20782():
     assert integrate(f, (x, -oo, 1)) == 1
     assert integrate(-f, (x, -oo, 1)) == -1
 
+def test_issue_20781():
+    x_d = Symbol('x_d')
+    fun_sum = lambda x, a1, a2: Piecewise((0, x<a1),(1, x>=a1)) + Piecewise((0, x<a2),(1, x>=a2))
+
+    assert integrate(fun_sum((x_d), 0, 0.0), (x_d, -float('Inf'), x)) == 2*x - 2*Min(0, x)
+    assert integrate(fun_sum((x_d), 0, 0.0), (x_d, -float('Inf'), x)) == 2*x - 2*Min(0, x)
+    assert integrate(fun_sum((x_d), 0.0, 0), (x_d, -float('Inf'), x)) == 2*x - 2*Min(0, x)
+    assert integrate(fun_sum((x_d), 0.0, 0), (x_d, -float('Inf'), x)) == 2*x - 2*Min(0, x)
+    assert integrate(fun_sum((x_d), 1.0, 1), (x_d, -float('Inf'), x)) == 2*x - 2*Min(1, x)
+    assert integrate(fun_sum((x_d), 1.0, 1), (x_d, -float('Inf'), x)) == 2*x - 2*Min(1, x)
 
 @slow
 def test_issue_19427():


Code review comments:
diff_hunk: @@ -2098,6 +2098,16 @@ def test_issue_20782():
     assert integrate(f, (x, -oo, 1)) == 1
     assert integrate(-f, (x, -oo, 1)) == -1
 
+def test_issue_20781():
+    x_d = Symbol('x_d')
+    fun_sum = lambda x, a1, a2: Piecewise((0, x<a1),(1, x>=a1)) + Piecewise((0, x<a2),(1, x>=a2))
+
+    assert integrate(fun_sum((x_d), 0, 0.0), (x_d, -float('Inf'), x)) == 2*x - 2*Min(0, x)
+    assert integrate(fun_sum((x_d), 0, 0.0), (x_d, -float('Inf'), x)) == 2*x - 2*Min(0, x)
+    assert integrate(fun_sum((x_d), 0.0, 0), (x_d, -float('Inf'), x)) == 2*x - 2*Min(0, x)
+    assert integrate(fun_sum((x_d), 0.0, 0), (x_d, -float('Inf'), x)) == 2*x - 2*Min(0, x)
+    assert integrate(fun_sum((x_d), 1.0, 1), (x_d, -float('Inf'), x)) == 2*x - 2*Min(1, x)
+    assert integrate(fun_sum((x_d), 1.0, 1), (x_d, -float('Inf'), x)) == 2*x - 2*Min(1, x)
path: sympy/integrals/tests/test_integrals.py
text: @user1:
I see the tests are correct, but what is the motivation behind the repetition in consecutive tests?

@author:
i seem to have copied from the issue. let me remove the repeated lines