Repository: sympy/sympy (Python)

Issue:
sympy.vector  Implicit_Region result wrong for perimeter of unit circle  version 1.7.1
Using vector_integrate in the examples in the documentation:

from sympy.vector import ImplicitRegion
c2 = ImplicitRegion((x, y), (x - 2)**2 + (y - 1)**2 - 9)
vector_integrate(1, c2)
12*pi

should this not be 6*pi since the radius of the circle is 3?

It seems like you always get the correct answer multiplied by a factor of 2 for any given radius.  


Discussion:
@woodringct Thanks for pointing this out. This is a bug. I don't know how I messed this up! 

A PR for this has been made. It was due to an incorrect substitution.



Patch:
diff --git a/doc/src/modules/vector/vector_integration.rst b/doc/src/modules/vector/vector_integration.rst
index 9f5b732aee41..2e1384636cb6 100644
--- a/doc/src/modules/vector/vector_integration.rst
+++ b/doc/src/modules/vector/vector_integration.rst
@@ -18,7 +18,7 @@ We define a coordinate system and make necesssary imports for examples.
 >>> from sympy.vector import CoordSys3D, ParametricRegion, ImplicitRegion, vector_integrate
 >>> from sympy.abc import r, x, y, z, theta, phi
 >>> C = CoordSys3D('C')
-    
+
 Calculation of Perimeter, Surface Area, and Volume
 ==================================================
 
@@ -30,16 +30,16 @@ We can also define a circle using its implicit equation.
 
 >>> implicit_circle = ImplicitRegion((x, y), x**2 + y**2 - 4)
 
-The perimeter of a figure is equal to the absolute value of its integral over a unit scalar field. 
+The perimeter of a figure is equal to the absolute value of its integral over a unit scalar field.
 
 >>> vector_integrate(1, param_circle)
 8*pi
 >>> vector_integrate(1, implicit_circle)
-8*pi
+4*pi
 
 Suppose a user wants to calculate the perimeter of a triangle. Determining the parametric representation of a triangle can be difficult. Instead, the user can use an object of :class:`~sympy.geometry.polygon.Polygon` class in the geometry module.
 
->>> from sympy.geometry import Point, Polygon 
+>>> from sympy.geometry import Point, Polygon
 >>> triangle = Polygon(Point(1, 2), (3, 5), (1,6))
 >>> vector_integrate(1, triangle)
 sqrt(5) + sqrt(13) + 4
@@ -70,8 +70,8 @@ pi*a**4*h/2
 
 Calculation of Flux
 ===================
-                   
-1. Consider a region of space in which there is a constant vectorfield 
+
+1. Consider a region of space in which there is a constant vectorfield
 :math:`E(x, y, z) = a\mathbf{\hat{k}}`.
 A  hemisphere of radius r  lies on the x-y plane. What is the flux of the field through the sphere?
 
@@ -81,15 +81,15 @@ A  hemisphere of radius r  lies on the x-y plane. What is the flux of the field
 >>> flux
 pi*a*r**2
 
-2. Consider  a  region  of  space  in  which  there  is  a  vector  field 
-:math:`E(x, y, z) = x^2 \mathbf{\hat{k}}` above the x-y plane, and a field 
+2. Consider  a  region  of  space  in  which  there  is  a  vector  field
+:math:`E(x, y, z) = x^2 \mathbf{\hat{k}}` above the x-y plane, and a field
 :math:`E(x, y, z) = y^2 \mathbf{\hat{k}}` below the x-y plane. What is the flux of that vector field through a cube of side length L with its center at the origin?”
 
 The field is parallel to the z-axis so only the top and bottom face of the box will contribute to flux.
 
 >>> L = symbols('L', positive=True)
->>> top_face = ParametricRegion((x, y, L/2), (x, -L/2, L/2), (y, -L/2, L/2)) 
->>> bottom_face = ParametricRegion((x, y, -L/2), (x, -L/2, L/2), (y, -L/2, L/2)) 
+>>> top_face = ParametricRegion((x, y, L/2), (x, -L/2, L/2), (y, -L/2, L/2))
+>>> bottom_face = ParametricRegion((x, y, -L/2), (x, -L/2, L/2), (y, -L/2, L/2))
 >>> flux = vector_integrate(C.x**2*C.k, top_face) + vector_integrate(C.y**2*C.k, bottom_face)
 >>> flux
 L**4/6
diff --git a/sympy/vector/integrals.py b/sympy/vector/integrals.py
index 6984883f52ea..66ec14a14f6e 100644
--- a/sympy/vector/integrals.py
+++ b/sympy/vector/integrals.py
@@ -174,7 +174,7 @@ def vector_integrate(field, *region):
     >>> from sympy.vector import ImplicitRegion
     >>> c2 = ImplicitRegion((x, y), (x - 2)**2 + (y - 1)**2 - 9)
     >>> vector_integrate(1, c2)
-    12*pi
+    6*pi
 
     Integral of fields with respect to base scalars:
 
diff --git a/sympy/vector/parametricregion.py b/sympy/vector/parametricregion.py
index c3cd6f0e0a05..6c00e238d5bc 100644
--- a/sympy/vector/parametricregion.py
+++ b/sympy/vector/parametricregion.py
@@ -181,7 +181,7 @@ def _(obj, parameters=('t', 's')):
     for i in range(len(obj.variables) - 1):
         # Each parameter is replaced by its tangent to simplify intergation
         parameter = _symbol(parameters[i], real=True)
-        definition = [trigsimp(elem.subs(parameter, tan(parameter))) for elem in definition]
+        definition = [trigsimp(elem.subs(parameter, tan(parameter/2))) for elem in definition]
         bounds.append((parameter, 0, 2*pi),)
 
     definition = Tuple(*definition)


Test patch:
diff --git a/sympy/vector/tests/test_integrals.py b/sympy/vector/tests/test_integrals.py
index e5271a2111be..6d283ea8ed5b 100644
--- a/sympy/vector/tests/test_integrals.py
+++ b/sympy/vector/tests/test_integrals.py
@@ -95,9 +95,9 @@ def test_vector_integrate():
     assert vector_integrate(C.i*C.y - C.z, point) == ParametricIntegral(C.y*C.i, ParametricRegion((2, 3)))
 
     c3 = ImplicitRegion((x, y), x**2 + y**2 - 4)
-    assert vector_integrate(45, c3) == 360*pi
+    assert vector_integrate(45, c3) == 180*pi
     c4 = ImplicitRegion((x, y), (x - 3)**2 + (y - 4)**2 - 9)
-    assert vector_integrate(1, c4) == 12*pi
+    assert vector_integrate(1, c4) == 6*pi
 
     pl = Plane(Point(1, 1, 1), Point(2, 3, 4), Point(2, 2, 2))
     raises(ValueError, lambda: vector_integrate(C.x*C.z*C.i + C.k, pl))