Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def eval(cls, arg):
if arg.is_Number:
if arg is S.NaN:
return S.NaN
elif arg is S.Infinity:
return S.Infinity
elif intlike(arg):
if arg.is_positive:
return factorial(arg - 1)
else:
return S.ComplexInfinity
elif arg.is_Rational:
if arg.q == 2:
n = abs(arg.p) // arg.q
if arg.is_positive:
k, coeff = n, S.One
else:
n = k = n + 1
def _print_Pow(self, expr, **kwargs):
PREC = precedence(expr)
if expr.exp == -1:
return '1/%s' % (self.parenthesize(expr.base, PREC))
elif expr.exp == 0.5 or expr.exp == S(1) / 2:
return 'sqrt(%s)' % self._print(expr.base)
elif expr.exp == -0.5 or expr.exp == -S(1) / 2:
return '1/sqrt(%s)' % self._print(expr.base)
else:
return '{base}^{exp}'.format(
base=self.parenthesize(expr.base, PREC),
exp=self.parenthesize(expr.exp, PREC))
==========================
Method:
[1] http://cgm.cs.mcgill.ca/~orm/mind2p.html
Uses rotating calipers:
[2] http://en.wikipedia.org/wiki/Rotating_calipers
and antipodal points:
[3] http://en.wikipedia.org/wiki/Antipodal_point
"""
e1 = self
'''Tests for a possible intersection between the polygons and outputs a warning'''
e1_center = e1.centroid
e2_center = e2.centroid
e1_max_radius = S.Zero
e2_max_radius = S.Zero
for vertex in e1.vertices:
r = Point.distance(e1_center, vertex)
if e1_max_radius < r:
e1_max_radius = r
for vertex in e2.vertices:
r = Point.distance(e2_center, vertex)
if e2_max_radius < r:
e2_max_radius = r
center_dist = Point.distance(e1_center, e2_center)
if center_dist <= e1_max_radius + e2_max_radius:
warnings.warn("Polygons may intersect producing erroneous output")
'''
Find the upper rightmost vertex of e1 and the lowest leftmost vertex of e2
'''
e1_ymax = Point(0, -oo)
def _eval_rewrite_as_hyper(self, z):
return pi*z**3/6 * hyper([S(3)/4], [S(3)/2, S(7)/4], -pi**2*z**4/16)
s *= S.ImaginaryUnit
if ai.is_negative:
# can't use sign(ai) here since ai might not be
# a Number
s = -s
else:
unk.append(a)
if c is S.One and len(unk) == len(args):
return None
return s * cls(arg._new_rawargs(*unk))
if arg is S.NaN:
return S.NaN
if arg.is_zero: # it may be an Expr that is zero
return S.Zero
if arg.is_positive:
return S.One
if arg.is_negative:
return S.NegativeOne
if arg.is_Function:
if isinstance(arg, sign):
return arg
if arg.is_imaginary:
if arg.is_Pow and arg.exp is S.Half:
# we catch this because non-trivial sqrt args are not expanded
# e.g. sqrt(1-sqrt(2)) --x--> to I*sqrt(sqrt(2) - 1)
return S.ImaginaryUnit
arg2 = -S.ImaginaryUnit * arg
if arg2.is_positive:
return S.ImaginaryUnit
if arg2.is_negative:
return -S.ImaginaryUnit
def riemann_cyclic_replace(t_r):
"""
replace Riemann tensor with an equivalent expression
``R(m,n,p,q) -> 2/3*R(m,n,p,q) - 1/3*R(m,q,n,p) + 1/3*R(m,p,n,q)``
"""
free = sorted(t_r.free, key=lambda x: x[1])
m, n, p, q = [x[0] for x in free]
t0 = S(2)/3*t_r
t1 = - S(1)/3*t_r.substitute_indices((m,m),(n,q),(p,n),(q,p))
t2 = S(1)/3*t_r.substitute_indices((m,m),(n,p),(p,n),(q,q))
t3 = t0 + t1 + t2
return t3
if n == 0:
if z is S.NaN:
return S.NaN
elif z.is_Rational:
p, q = z.as_numer_denom()
# only expand for small denominators to avoid creating long expressions
if q <= 5:
return expand_func(polygamma(n, z, evaluate=False))
elif z in (S.Infinity, S.NegativeInfinity):
return S.Infinity
else:
t = z.extract_multiplicatively(S.ImaginaryUnit)
if t in (S.Infinity, S.NegativeInfinity):
return S.Infinity
def add(formula, an, ap, bm, bq, arg=t, fac=S(1), cond=True, hint=True):
table.setdefault(_mytype(formula, z), []).append((formula,
[(fac, meijerg(an, ap, bm, bq, arg))], cond, hint))
from sympy.polys import apart
# First we need to figure out if the summation coefficient is a rational
# function of the summation index, and construct that rational function.
abuckets, bbuckets = sift(func.ap, _mod1), sift(func.bq, _mod1)
paired = {}
for key, value in abuckets.items():
if key != 0 and not key in bbuckets:
return None
bvalue = bbuckets[key]
paired[key] = (list(value), list(bvalue))
bbuckets.pop(key, None)
if bbuckets != {}:
return None
if not S(0) in abuckets:
return None
aints, bints = paired[S(0)]
# Account for the additional n! in denominator
paired[S(0)] = (aints, bints + [1])
t = Dummy('t')
numer = S(1)
denom = S(1)
for key, (avalue, bvalue) in paired.items():
if len(avalue) != len(bvalue):
return None
# Note that since order has been reduced fully, all the b are
# bigger than all the a they differ from by an integer. In particular
# if there are any negative b left, this function is not well-defined.
for a, b in zip(avalue, bvalue):
if (a - b).is_positive:
e1_connections[side.p2] = [side.p1]
for side in e2.sides:
if side.p1 in e2_connections:
e2_connections[side.p1].append(side.p2)
else:
e2_connections[side.p1] = [side.p2]
if side.p2 in e2_connections:
e2_connections[side.p2].append(side.p1)
else:
e2_connections[side.p2] = [side.p1]
e1_current = e1_ymax
e2_current = e2_ymin
support_line = Line(Point(S.Zero, S.Zero), Point(S.One, S.Zero))
'''
Determine which point in e1 and e2 will be selected after e2_ymin and e1_ymax,
this information combined with the above produced dictionaries determines the
path that will be taken around the polygons
'''
point1 = e1_connections[e1_ymax][0]
point2 = e1_connections[e1_ymax][1]
angle1 = support_line.angle_between(Line(e1_ymax, point1))
angle2 = support_line.angle_between(Line(e1_ymax, point2))
if angle1 < angle2:
e1_next = point1
elif angle2 < angle1:
e1_next = point2
elif Point.distance(e1_ymax, point1) > Point.distance(e1_ymax, point2):
e1_next = point2