m2m模型翻译
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

7336 lines
264 KiB

6 months ago
  1. """
  2. Utility functions for Rubi integration.
  3. See: http://www.apmaths.uwo.ca/~arich/IntegrationRules/PortableDocumentFiles/Integration%20utility%20functions.pdf
  4. """
  5. from sympy.external import import_module
  6. matchpy = import_module("matchpy")
  7. from sympy.concrete.summations import Sum
  8. from sympy.core.add import Add
  9. from sympy.core.basic import Basic
  10. from sympy.core.containers import Dict
  11. from sympy.core.evalf import N
  12. from sympy.core.expr import UnevaluatedExpr
  13. from sympy.core.exprtools import factor_terms
  14. from sympy.core.function import (Function, WildFunction, expand, expand_trig)
  15. from sympy.core.mul import Mul
  16. from sympy.core.numbers import (E, Float, I, Integer, Rational, oo, pi, zoo)
  17. from sympy.core.power import Pow
  18. from sympy.core.singleton import S
  19. from sympy.core.symbol import (Dummy, Symbol, Wild, symbols)
  20. from sympy.core.sympify import sympify
  21. from sympy.core.traversal import postorder_traversal
  22. from sympy.functions.combinatorial.factorials import factorial
  23. from sympy.functions.elementary.complexes import im, re, Abs, sign
  24. from sympy.functions.elementary.exponential import exp as sym_exp, log as sym_log, LambertW
  25. from sympy.functions.elementary.hyperbolic import acosh, asinh, atanh, acoth, acsch, asech, cosh, sinh, tanh, coth, sech, csch
  26. from sympy.functions.elementary.integers import floor, frac
  27. from sympy.functions.elementary.miscellaneous import (Max, Min, sqrt)
  28. from sympy.functions.elementary.trigonometric import atan, acsc, asin, acot, acos, asec, atan2, sin, cos, tan, cot, csc, sec
  29. from sympy.functions.special.elliptic_integrals import elliptic_f, elliptic_e, elliptic_pi
  30. from sympy.functions.special.error_functions import erf, fresnelc, fresnels, erfc, erfi, Ei, expint, li, Si, Ci, Shi, Chi
  31. from sympy.functions.special.gamma_functions import (digamma, gamma, loggamma, polygamma, uppergamma)
  32. from sympy.functions.special.hyper import (appellf1, hyper, TupleArg)
  33. from sympy.functions.special.zeta_functions import polylog, zeta
  34. from sympy.integrals.integrals import Integral
  35. from sympy.logic.boolalg import And, Or
  36. from sympy.ntheory.factor_ import (factorint, factorrat)
  37. from sympy.polys.partfrac import apart
  38. from sympy.polys.polyerrors import (PolynomialDivisionFailed, PolynomialError, UnificationFailed)
  39. from sympy.polys.polytools import (discriminant, factor, gcd, lcm, poly, sqf, sqf_list, Poly, degree, quo, rem, total_degree)
  40. from sympy.sets.sets import FiniteSet
  41. from sympy.simplify.powsimp import powdenest
  42. from sympy.simplify.radsimp import collect
  43. from sympy.simplify.simplify import fraction, simplify, cancel, powsimp, nsimplify
  44. from sympy.utilities.decorator import doctest_depends_on
  45. from sympy.utilities.iterables import flatten
  46. from sympy.core.random import randint
  47. class rubi_unevaluated_expr(UnevaluatedExpr):
  48. """
  49. This is needed to convert `exp` as `Pow`.
  50. SymPy's UnevaluatedExpr has an issue with `is_commutative`.
  51. """
  52. @property
  53. def is_commutative(self):
  54. from sympy.core.logic import fuzzy_and
  55. return fuzzy_and(a.is_commutative for a in self.args)
  56. _E = rubi_unevaluated_expr(E)
  57. class rubi_exp(Function):
  58. """
  59. SymPy's exp is not identified as `Pow`. So it is not matched with `Pow`.
  60. Like `a = exp(2)` is not identified as `Pow(E, 2)`. Rubi rules need it.
  61. So, another exp has been created only for rubi module.
  62. Examples
  63. ========
  64. >>> from sympy import Pow, exp as sym_exp
  65. >>> isinstance(sym_exp(2), Pow)
  66. False
  67. >>> from sympy.integrals.rubi.utility_function import rubi_exp
  68. >>> isinstance(rubi_exp(2), Pow)
  69. True
  70. """
  71. @classmethod
  72. def eval(cls, *args):
  73. return Pow(_E, args[0])
  74. class rubi_log(Function):
  75. """
  76. For rule matching different `exp` has been used. So for proper results,
  77. `log` is modified little only for case when it encounters rubi's `exp`.
  78. For other cases it is same.
  79. Examples
  80. ========
  81. >>> from sympy.integrals.rubi.utility_function import rubi_exp, rubi_log
  82. >>> a = rubi_exp(2)
  83. >>> rubi_log(a)
  84. 2
  85. """
  86. @classmethod
  87. def eval(cls, *args):
  88. if args[0].has(_E):
  89. return sym_log(args[0]).doit()
  90. else:
  91. return sym_log(args[0])
  92. if matchpy:
  93. from matchpy import Arity, Operation, CustomConstraint, Pattern, ReplacementRule, ManyToOneReplacer
  94. from sympy.integrals.rubi.symbol import WC
  95. from matchpy import is_match, replace_all
  96. class UtilityOperator(Operation):
  97. name = 'UtilityOperator'
  98. arity = Arity.variadic
  99. commutative = False
  100. associative = True
  101. Operation.register(rubi_log)
  102. Operation.register(rubi_exp)
  103. A_, B_, C_, F_, G_, a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_, l_, m_, \
  104. n_, p_, q_, r_, t_, u_, v_, s_, w_, x_, z_ = [WC(i) for i in 'ABCFGabcdefghijklmnpqrtuvswxz']
  105. a, b, c, d, e = symbols('a b c d e')
  106. Int = Integral
  107. def replace_pow_exp(z):
  108. """
  109. This function converts back rubi's `exp` to general SymPy's `exp`.
  110. Examples
  111. ========
  112. >>> from sympy.integrals.rubi.utility_function import rubi_exp, replace_pow_exp
  113. >>> expr = rubi_exp(5)
  114. >>> expr
  115. E**5
  116. >>> replace_pow_exp(expr)
  117. exp(5)
  118. """
  119. z = S(z)
  120. if z.has(_E):
  121. z = z.replace(_E, E)
  122. return z
  123. def Simplify(expr):
  124. expr = simplify(expr)
  125. return expr
  126. def Set(expr, value):
  127. return {expr: value}
  128. def With(subs, expr):
  129. if isinstance(subs, dict):
  130. k = list(subs.keys())[0]
  131. expr = expr.xreplace({k: subs[k]})
  132. else:
  133. for i in subs:
  134. k = list(i.keys())[0]
  135. expr = expr.xreplace({k: i[k]})
  136. return expr
  137. def Module(subs, expr):
  138. return With(subs, expr)
  139. def Scan(f, expr):
  140. # evaluates f applied to each element of expr in turn.
  141. for i in expr:
  142. yield f(i)
  143. def MapAnd(f, l, x=None):
  144. # MapAnd[f,l] applies f to the elements of list l until False is returned; else returns True
  145. if x:
  146. for i in l:
  147. if f(i, x) == False:
  148. return False
  149. return True
  150. else:
  151. for i in l:
  152. if f(i) == False:
  153. return False
  154. return True
  155. def FalseQ(u):
  156. if isinstance(u, (Dict, dict)):
  157. return FalseQ(*list(u.values()))
  158. return u == False
  159. def ZeroQ(*expr):
  160. if len(expr) == 1:
  161. if isinstance(expr[0], list):
  162. return list(ZeroQ(i) for i in expr[0])
  163. else:
  164. return Simplify(expr[0]) == 0
  165. else:
  166. return all(ZeroQ(i) for i in expr)
  167. def OneQ(a):
  168. if a == S(1):
  169. return True
  170. return False
  171. def NegativeQ(u):
  172. u = Simplify(u)
  173. if u in (zoo, oo):
  174. return False
  175. if u.is_comparable:
  176. res = u < 0
  177. if not res.is_Relational:
  178. return res
  179. return False
  180. def NonzeroQ(expr):
  181. return Simplify(expr) != 0
  182. def FreeQ(nodes, var):
  183. if isinstance(nodes, list):
  184. return not any(S(expr).has(var) for expr in nodes)
  185. else:
  186. nodes = S(nodes)
  187. return not nodes.has(var)
  188. def NFreeQ(nodes, var):
  189. """ Note that in rubi 4.10.8 this function was not defined in `Integration Utility Functions.m`,
  190. but was used in rules. So explicitly its returning `False`
  191. """
  192. return False
  193. # return not FreeQ(nodes, var)
  194. def List(*var):
  195. return list(var)
  196. def PositiveQ(var):
  197. var = Simplify(var)
  198. if var in (zoo, oo):
  199. return False
  200. if var.is_comparable:
  201. res = var > 0
  202. if not res.is_Relational:
  203. return res
  204. return False
  205. def PositiveIntegerQ(*args):
  206. return all(var.is_Integer and PositiveQ(var) for var in args)
  207. def NegativeIntegerQ(*args):
  208. return all(var.is_Integer and NegativeQ(var) for var in args)
  209. def IntegerQ(var):
  210. var = Simplify(var)
  211. if isinstance(var, (int, Integer)):
  212. return True
  213. else:
  214. return var.is_Integer
  215. def IntegersQ(*var):
  216. return all(IntegerQ(i) for i in var)
  217. def _ComplexNumberQ(var):
  218. i = S(im(var))
  219. if isinstance(i, (Integer, Float)):
  220. return i != 0
  221. else:
  222. return False
  223. def ComplexNumberQ(*var):
  224. """
  225. ComplexNumberQ(m, n,...) returns True if m, n, ... are all explicit complex numbers, else it returns False.
  226. Examples
  227. ========
  228. >>> from sympy.integrals.rubi.utility_function import ComplexNumberQ
  229. >>> from sympy import I
  230. >>> ComplexNumberQ(1 + I*2, I)
  231. True
  232. >>> ComplexNumberQ(2, I)
  233. False
  234. """
  235. return all(_ComplexNumberQ(i) for i in var)
  236. def PureComplexNumberQ(*var):
  237. return all((_ComplexNumberQ(i) and re(i)==0) for i in var)
  238. def RealNumericQ(u):
  239. return u.is_real
  240. def PositiveOrZeroQ(u):
  241. return u.is_real and u >= 0
  242. def NegativeOrZeroQ(u):
  243. return u.is_real and u <= 0
  244. def FractionOrNegativeQ(u):
  245. return FractionQ(u) or NegativeQ(u)
  246. def NegQ(var):
  247. return Not(PosQ(var)) and NonzeroQ(var)
  248. def Equal(a, b):
  249. return a == b
  250. def Unequal(a, b):
  251. return a != b
  252. def IntPart(u):
  253. # IntPart[u] returns the sum of the integer terms of u.
  254. if ProductQ(u):
  255. if IntegerQ(First(u)):
  256. return First(u)*IntPart(Rest(u))
  257. elif IntegerQ(u):
  258. return u
  259. elif FractionQ(u):
  260. return IntegerPart(u)
  261. elif SumQ(u):
  262. res = 0
  263. for i in u.args:
  264. res += IntPart(i)
  265. return res
  266. return 0
  267. def FracPart(u):
  268. # FracPart[u] returns the sum of the non-integer terms of u.
  269. if ProductQ(u):
  270. if IntegerQ(First(u)):
  271. return First(u)*FracPart(Rest(u))
  272. if IntegerQ(u):
  273. return 0
  274. elif FractionQ(u):
  275. return FractionalPart(u)
  276. elif SumQ(u):
  277. res = 0
  278. for i in u.args:
  279. res += FracPart(i)
  280. return res
  281. else:
  282. return u
  283. def RationalQ(*nodes):
  284. return all(var.is_Rational for var in nodes)
  285. def ProductQ(expr):
  286. return S(expr).is_Mul
  287. def SumQ(expr):
  288. return expr.is_Add
  289. def NonsumQ(expr):
  290. return not SumQ(expr)
  291. def Subst(a, x, y):
  292. if None in [a, x, y]:
  293. return None
  294. if a.has(Function('Integrate')):
  295. # substituting in `Function(Integrate)` won't take care of properties of Integral
  296. a = a.replace(Function('Integrate'), Integral)
  297. return a.subs(x, y)
  298. # return a.xreplace({x: y})
  299. def First(expr, d=None):
  300. """
  301. Gives the first element if it exists, or d otherwise.
  302. Examples
  303. ========
  304. >>> from sympy.integrals.rubi.utility_function import First
  305. >>> from sympy.abc import a, b, c
  306. >>> First(a + b + c)
  307. a
  308. >>> First(a*b*c)
  309. a
  310. """
  311. if isinstance(expr, list):
  312. return expr[0]
  313. if isinstance(expr, Symbol):
  314. return expr
  315. else:
  316. if SumQ(expr) or ProductQ(expr):
  317. l = Sort(expr.args)
  318. return l[0]
  319. else:
  320. return expr.args[0]
  321. def Rest(expr):
  322. """
  323. Gives rest of the elements if it exists
  324. Examples
  325. ========
  326. >>> from sympy.integrals.rubi.utility_function import Rest
  327. >>> from sympy.abc import a, b, c
  328. >>> Rest(a + b + c)
  329. b + c
  330. >>> Rest(a*b*c)
  331. b*c
  332. """
  333. if isinstance(expr, list):
  334. return expr[1:]
  335. else:
  336. if SumQ(expr) or ProductQ(expr):
  337. l = Sort(expr.args)
  338. return expr.func(*l[1:])
  339. else:
  340. return expr.args[1]
  341. def SqrtNumberQ(expr):
  342. # SqrtNumberQ[u] returns True if u^2 is a rational number; else it returns False.
  343. if PowerQ(expr):
  344. m = expr.base
  345. n = expr.exp
  346. return (IntegerQ(n) and SqrtNumberQ(m)) or (IntegerQ(n-S(1)/2) and RationalQ(m))
  347. elif expr.is_Mul:
  348. return all(SqrtNumberQ(i) for i in expr.args)
  349. else:
  350. return RationalQ(expr) or expr == I
  351. def SqrtNumberSumQ(u):
  352. return SumQ(u) and SqrtNumberQ(First(u)) and SqrtNumberQ(Rest(u)) or ProductQ(u) and SqrtNumberQ(First(u)) and SqrtNumberSumQ(Rest(u))
  353. def LinearQ(expr, x):
  354. """
  355. LinearQ(expr, x) returns True iff u is a polynomial of degree 1.
  356. Examples
  357. ========
  358. >>> from sympy.integrals.rubi.utility_function import LinearQ
  359. >>> from sympy.abc import x, y, a
  360. >>> LinearQ(a, x)
  361. False
  362. >>> LinearQ(3*x + y**2, x)
  363. True
  364. >>> LinearQ(3*x + y**2, y)
  365. False
  366. """
  367. if isinstance(expr, list):
  368. return all(LinearQ(i, x) for i in expr)
  369. elif expr.is_polynomial(x):
  370. if degree(Poly(expr, x), gen=x) == 1:
  371. return True
  372. return False
  373. def Sqrt(a):
  374. return sqrt(a)
  375. def ArcCosh(a):
  376. return acosh(a)
  377. class Util_Coefficient(Function):
  378. def doit(self):
  379. if len(self.args) == 2:
  380. n = 1
  381. else:
  382. n = Simplify(self.args[2])
  383. if NumericQ(n):
  384. expr = expand(self.args[0])
  385. if isinstance(n, (int, Integer)):
  386. return expr.coeff(self.args[1], n)
  387. else:
  388. return expr.coeff(self.args[1]**n)
  389. else:
  390. return self
  391. def Coefficient(expr, var, n=1):
  392. """
  393. Coefficient(expr, var) gives the coefficient of form in the polynomial expr.
  394. Coefficient(expr, var, n) gives the coefficient of var**n in expr.
  395. Examples
  396. ========
  397. >>> from sympy.integrals.rubi.utility_function import Coefficient
  398. >>> from sympy.abc import x, a, b, c
  399. >>> Coefficient(7 + 2*x + 4*x**3, x, 1)
  400. 2
  401. >>> Coefficient(a + b*x + c*x**3, x, 0)
  402. a
  403. >>> Coefficient(a + b*x + c*x**3, x, 4)
  404. 0
  405. >>> Coefficient(b*x + c*x**3, x, 3)
  406. c
  407. """
  408. if NumericQ(n):
  409. if expr == 0 or n in (zoo, oo):
  410. return 0
  411. expr = expand(expr)
  412. if isinstance(n, (int, Integer)):
  413. return expr.coeff(var, n)
  414. else:
  415. return expr.coeff(var**n)
  416. return Util_Coefficient(expr, var, n)
  417. def Denominator(var):
  418. var = Simplify(var)
  419. if isinstance(var, Pow):
  420. if isinstance(var.exp, Integer):
  421. if var.exp > 0:
  422. return Pow(Denominator(var.base), var.exp)
  423. elif var.exp < 0:
  424. return Pow(Numerator(var.base), -1*var.exp)
  425. elif isinstance(var, Add):
  426. var = factor(var)
  427. return fraction(var)[1]
  428. def Hypergeometric2F1(a, b, c, z):
  429. return hyper([a, b], [c], z)
  430. def Not(var):
  431. if isinstance(var, bool):
  432. return not var
  433. elif var.is_Relational:
  434. var = False
  435. return not var
  436. def FractionalPart(a):
  437. return frac(a)
  438. def IntegerPart(a):
  439. return floor(a)
  440. def AppellF1(a, b1, b2, c, x, y):
  441. return appellf1(a, b1, b2, c, x, y)
  442. def EllipticPi(*args):
  443. return elliptic_pi(*args)
  444. def EllipticE(*args):
  445. return elliptic_e(*args)
  446. def EllipticF(Phi, m):
  447. return elliptic_f(Phi, m)
  448. def ArcTan(a, b = None):
  449. if b is None:
  450. return atan(a)
  451. else:
  452. return atan2(a, b)
  453. def ArcCot(a):
  454. return acot(a)
  455. def ArcCoth(a):
  456. return acoth(a)
  457. def ArcTanh(a):
  458. return atanh(a)
  459. def ArcSin(a):
  460. return asin(a)
  461. def ArcSinh(a):
  462. return asinh(a)
  463. def ArcCos(a):
  464. return acos(a)
  465. def ArcCsc(a):
  466. return acsc(a)
  467. def ArcSec(a):
  468. return asec(a)
  469. def ArcCsch(a):
  470. return acsch(a)
  471. def ArcSech(a):
  472. return asech(a)
  473. def Sinh(u):
  474. return sinh(u)
  475. def Tanh(u):
  476. return tanh(u)
  477. def Cosh(u):
  478. return cosh(u)
  479. def Sech(u):
  480. return sech(u)
  481. def Csch(u):
  482. return csch(u)
  483. def Coth(u):
  484. return coth(u)
  485. def LessEqual(*args):
  486. for i in range(0, len(args) - 1):
  487. try:
  488. if args[i] > args[i + 1]:
  489. return False
  490. except (IndexError, NotImplementedError):
  491. return False
  492. return True
  493. def Less(*args):
  494. for i in range(0, len(args) - 1):
  495. try:
  496. if args[i] >= args[i + 1]:
  497. return False
  498. except (IndexError, NotImplementedError):
  499. return False
  500. return True
  501. def Greater(*args):
  502. for i in range(0, len(args) - 1):
  503. try:
  504. if args[i] <= args[i + 1]:
  505. return False
  506. except (IndexError, NotImplementedError):
  507. return False
  508. return True
  509. def GreaterEqual(*args):
  510. for i in range(0, len(args) - 1):
  511. try:
  512. if args[i] < args[i + 1]:
  513. return False
  514. except (IndexError, NotImplementedError):
  515. return False
  516. return True
  517. def FractionQ(*args):
  518. """
  519. FractionQ(m, n,...) returns True if m, n, ... are all explicit fractions, else it returns False.
  520. Examples
  521. ========
  522. >>> from sympy import S
  523. >>> from sympy.integrals.rubi.utility_function import FractionQ
  524. >>> FractionQ(S('3'))
  525. False
  526. >>> FractionQ(S('3')/S('2'))
  527. True
  528. """
  529. return all(i.is_Rational for i in args) and all(Denominator(i) != S(1) for i in args)
  530. def IntLinearcQ(a, b, c, d, m, n, x):
  531. # returns True iff (a+b*x)^m*(c+d*x)^n is integrable wrt x in terms of non-hypergeometric functions.
  532. return IntegerQ(m) or IntegerQ(n) or IntegersQ(S(3)*m, S(3)*n) or IntegersQ(S(4)*m, S(4)*n) or IntegersQ(S(2)*m, S(6)*n) or IntegersQ(S(6)*m, S(2)*n) or IntegerQ(m + n)
  533. Defer = UnevaluatedExpr
  534. def Expand(expr):
  535. return expr.expand()
  536. def IndependentQ(u, x):
  537. """
  538. If u is free from x IndependentQ(u, x) returns True else False.
  539. Examples
  540. ========
  541. >>> from sympy.integrals.rubi.utility_function import IndependentQ
  542. >>> from sympy.abc import x, a, b
  543. >>> IndependentQ(a + b*x, x)
  544. False
  545. >>> IndependentQ(a + b, x)
  546. True
  547. """
  548. return FreeQ(u, x)
  549. def PowerQ(expr):
  550. return expr.is_Pow or ExpQ(expr)
  551. def IntegerPowerQ(u):
  552. if isinstance(u, sym_exp): #special case for exp
  553. return IntegerQ(u.args[0])
  554. return PowerQ(u) and IntegerQ(u.args[1])
  555. def PositiveIntegerPowerQ(u):
  556. if isinstance(u, sym_exp):
  557. return IntegerQ(u.args[0]) and PositiveQ(u.args[0])
  558. return PowerQ(u) and IntegerQ(u.args[1]) and PositiveQ(u.args[1])
  559. def FractionalPowerQ(u):
  560. if isinstance(u, sym_exp):
  561. return FractionQ(u.args[0])
  562. return PowerQ(u) and FractionQ(u.args[1])
  563. def AtomQ(expr):
  564. expr = sympify(expr)
  565. if isinstance(expr, list):
  566. return False
  567. if expr in [None, True, False, _E]: # [None, True, False] are atoms in mathematica and _E is also an atom
  568. return True
  569. # elif isinstance(expr, list):
  570. # return all(AtomQ(i) for i in expr)
  571. else:
  572. return expr.is_Atom
  573. def ExpQ(u):
  574. u = replace_pow_exp(u)
  575. return Head(u) in (sym_exp, rubi_exp)
  576. def LogQ(u):
  577. return u.func in (sym_log, Log)
  578. def Head(u):
  579. return u.func
  580. def MemberQ(l, u):
  581. if isinstance(l, list):
  582. return u in l
  583. else:
  584. return u in l.args
  585. def TrigQ(u):
  586. if AtomQ(u):
  587. x = u
  588. else:
  589. x = Head(u)
  590. return MemberQ([sin, cos, tan, cot, sec, csc], x)
  591. def SinQ(u):
  592. return Head(u) == sin
  593. def CosQ(u):
  594. return Head(u) == cos
  595. def TanQ(u):
  596. return Head(u) == tan
  597. def CotQ(u):
  598. return Head(u) == cot
  599. def SecQ(u):
  600. return Head(u) == sec
  601. def CscQ(u):
  602. return Head(u) == csc
  603. def Sin(u):
  604. return sin(u)
  605. def Cos(u):
  606. return cos(u)
  607. def Tan(u):
  608. return tan(u)
  609. def Cot(u):
  610. return cot(u)
  611. def Sec(u):
  612. return sec(u)
  613. def Csc(u):
  614. return csc(u)
  615. def HyperbolicQ(u):
  616. if AtomQ(u):
  617. x = u
  618. else:
  619. x = Head(u)
  620. return MemberQ([sinh, cosh, tanh, coth, sech, csch], x)
  621. def SinhQ(u):
  622. return Head(u) == sinh
  623. def CoshQ(u):
  624. return Head(u) == cosh
  625. def TanhQ(u):
  626. return Head(u) == tanh
  627. def CothQ(u):
  628. return Head(u) == coth
  629. def SechQ(u):
  630. return Head(u) == sech
  631. def CschQ(u):
  632. return Head(u) == csch
  633. def InverseTrigQ(u):
  634. if AtomQ(u):
  635. x = u
  636. else:
  637. x = Head(u)
  638. return MemberQ([asin, acos, atan, acot, asec, acsc], x)
  639. def SinCosQ(f):
  640. return MemberQ([sin, cos, sec, csc], Head(f))
  641. def SinhCoshQ(f):
  642. return MemberQ([sinh, cosh, sech, csch], Head(f))
  643. def LeafCount(expr):
  644. return len(list(postorder_traversal(expr)))
  645. def Numerator(u):
  646. u = Simplify(u)
  647. if isinstance(u, Pow):
  648. if isinstance(u.exp, Integer):
  649. if u.exp > 0:
  650. return Pow(Numerator(u.base), u.exp)
  651. elif u.exp < 0:
  652. return Pow(Denominator(u.base), -1*u.exp)
  653. elif isinstance(u, Add):
  654. u = factor(u)
  655. return fraction(u)[0]
  656. def NumberQ(u):
  657. if isinstance(u, (int, float)):
  658. return True
  659. return u.is_number
  660. def NumericQ(u):
  661. return N(u).is_number
  662. def Length(expr):
  663. """
  664. Returns number of elements in the expression just as SymPy's len.
  665. Examples
  666. ========
  667. >>> from sympy.integrals.rubi.utility_function import Length
  668. >>> from sympy.abc import x, a, b
  669. >>> from sympy import cos, sin
  670. >>> Length(a + b)
  671. 2
  672. >>> Length(sin(a)*cos(a))
  673. 2
  674. """
  675. if isinstance(expr, list):
  676. return len(expr)
  677. return len(expr.args)
  678. def ListQ(u):
  679. return isinstance(u, list)
  680. def Im(u):
  681. u = S(u)
  682. return im(u.doit())
  683. def Re(u):
  684. u = S(u)
  685. return re(u.doit())
  686. def InverseHyperbolicQ(u):
  687. if not u.is_Atom:
  688. u = Head(u)
  689. return u in [acosh, asinh, atanh, acoth, acsch, acsch]
  690. def InverseFunctionQ(u):
  691. # returns True if u is a call on an inverse function; else returns False.
  692. return LogQ(u) or InverseTrigQ(u) and Length(u) <= 1 or InverseHyperbolicQ(u) or u.func == polylog
  693. def TrigHyperbolicFreeQ(u, x):
  694. # If u is free of trig, hyperbolic and calculus functions involving x, TrigHyperbolicFreeQ[u,x] returns true; else it returns False.
  695. if AtomQ(u):
  696. return True
  697. else:
  698. if TrigQ(u) | HyperbolicQ(u) | CalculusQ(u):
  699. return FreeQ(u, x)
  700. else:
  701. for i in u.args:
  702. if not TrigHyperbolicFreeQ(i, x):
  703. return False
  704. return True
  705. def InverseFunctionFreeQ(u, x):
  706. # If u is free of inverse, calculus and hypergeometric functions involving x, InverseFunctionFreeQ[u,x] returns true; else it returns False.
  707. if AtomQ(u):
  708. return True
  709. else:
  710. if InverseFunctionQ(u) or CalculusQ(u) or u.func in (hyper, appellf1):
  711. return FreeQ(u, x)
  712. else:
  713. for i in u.args:
  714. if not ElementaryFunctionQ(i):
  715. return False
  716. return True
  717. def RealQ(u):
  718. if ListQ(u):
  719. return MapAnd(RealQ, u)
  720. elif NumericQ(u):
  721. return ZeroQ(Im(N(u)))
  722. elif PowerQ(u):
  723. u = u.base
  724. v = u.exp
  725. return RealQ(u) & RealQ(v) & (IntegerQ(v) | PositiveOrZeroQ(u))
  726. elif u.is_Mul:
  727. return all(RealQ(i) for i in u.args)
  728. elif u.is_Add:
  729. return all(RealQ(i) for i in u.args)
  730. elif u.is_Function:
  731. f = u.func
  732. u = u.args[0]
  733. if f in [sin, cos, tan, cot, sec, csc, atan, acot, erf]:
  734. return RealQ(u)
  735. else:
  736. if f in [asin, acos]:
  737. return LessEqual(-1, u, 1)
  738. else:
  739. if f == sym_log:
  740. return PositiveOrZeroQ(u)
  741. else:
  742. return False
  743. else:
  744. return False
  745. def EqQ(u, v):
  746. return ZeroQ(u - v)
  747. def FractionalPowerFreeQ(u):
  748. if AtomQ(u):
  749. return True
  750. elif FractionalPowerQ(u):
  751. return False
  752. def ComplexFreeQ(u):
  753. if AtomQ(u) and Not(ComplexNumberQ(u)):
  754. return True
  755. else:
  756. return False
  757. def PolynomialQ(u, x = None):
  758. if x is None :
  759. return u.is_polynomial()
  760. if isinstance(x, Pow):
  761. if isinstance(x.exp, Integer):
  762. deg = degree(u, x.base)
  763. if u.is_polynomial(x):
  764. if deg % x.exp !=0 :
  765. return False
  766. try:
  767. p = Poly(u, x.base)
  768. except PolynomialError:
  769. return False
  770. c_list = p.all_coeffs()
  771. coeff_list = c_list[:-1:x.exp]
  772. coeff_list += [c_list[-1]]
  773. for i in coeff_list:
  774. if not i == 0:
  775. index = c_list.index(i)
  776. c_list[index] = 0
  777. if all(i == 0 for i in c_list):
  778. return True
  779. else:
  780. return False
  781. else:
  782. return False
  783. elif isinstance(x.exp, (Float, Rational)): #not full - proof
  784. if FreeQ(simplify(u), x.base) and Exponent(u, x.base) == 0:
  785. if not all(FreeQ(u, i) for i in x.base.free_symbols):
  786. return False
  787. if isinstance(x, Mul):
  788. return all(PolynomialQ(u, i) for i in x.args)
  789. return u.is_polynomial(x)
  790. def FactorSquareFree(u):
  791. return sqf(u)
  792. def PowerOfLinearQ(expr, x):
  793. u = Wild('u')
  794. w = Wild('w')
  795. m = Wild('m')
  796. n = Wild('n')
  797. Match = expr.match(u**m)
  798. if PolynomialQ(Match[u], x) and FreeQ(Match[m], x):
  799. if IntegerQ(Match[m]):
  800. e = FactorSquareFree(Match[u]).match(w**n)
  801. if FreeQ(e[n], x) and LinearQ(e[w], x):
  802. return True
  803. else:
  804. return False
  805. else:
  806. return LinearQ(Match[u], x)
  807. else:
  808. return False
  809. def Exponent(expr, x):
  810. expr = Expand(S(expr))
  811. if S(expr).is_number or (not expr.has(x)):
  812. return 0
  813. if PolynomialQ(expr, x):
  814. if isinstance(x, Rational):
  815. return degree(Poly(expr, x), x)
  816. return degree(expr, gen = x)
  817. else:
  818. return 0
  819. def ExponentList(expr, x):
  820. expr = Expand(S(expr))
  821. if S(expr).is_number or (not expr.has(x)):
  822. return [0]
  823. if expr.is_Add:
  824. expr = collect(expr, x)
  825. lst = []
  826. k = 1
  827. for t in expr.args:
  828. if t.has(x):
  829. if isinstance(x, Rational):
  830. lst += [degree(Poly(t, x), x)]
  831. else:
  832. lst += [degree(t, gen = x)]
  833. else:
  834. if k == 1:
  835. lst += [0]
  836. k += 1
  837. lst.sort()
  838. return lst
  839. else:
  840. if isinstance(x, Rational):
  841. return [degree(Poly(expr, x), x)]
  842. else:
  843. return [degree(expr, gen = x)]
  844. def QuadraticQ(u, x):
  845. # QuadraticQ(u, x) returns True iff u is a polynomial of degree 2 and not a monomial of the form a x^2
  846. if ListQ(u):
  847. for expr in u:
  848. if Not(PolyQ(expr, x, 2) and Not(Coefficient(expr, x, 0) == 0 and Coefficient(expr, x, 1) == 0)):
  849. return False
  850. return True
  851. else:
  852. return PolyQ(u, x, 2) and Not(Coefficient(u, x, 0) == 0 and Coefficient(u, x, 1) == 0)
  853. def LinearPairQ(u, v, x):
  854. # LinearPairQ(u, v, x) returns True iff u and v are linear not equal x but u/v is a constant wrt x
  855. return LinearQ(u, x) and LinearQ(v, x) and NonzeroQ(u-x) and ZeroQ(Coefficient(u, x, 0)*Coefficient(v, x, 1)-Coefficient(u, x, 1)*Coefficient(v, x, 0))
  856. def BinomialParts(u, x):
  857. if PolynomialQ(u, x):
  858. if Exponent(u, x) > 0:
  859. lst = ExponentList(u, x)
  860. if len(lst)==1:
  861. return [0, Coefficient(u, x, Exponent(u, x)), Exponent(u, x)]
  862. elif len(lst) == 2 and lst[0] == 0:
  863. return [Coefficient(u, x, 0), Coefficient(u, x, Exponent(u, x)), Exponent(u, x)]
  864. else:
  865. return False
  866. else:
  867. return False
  868. elif PowerQ(u):
  869. if u.base == x and FreeQ(u.exp, x):
  870. return [0, 1, u.exp]
  871. else:
  872. return False
  873. elif ProductQ(u):
  874. if FreeQ(First(u), x):
  875. lst2 = BinomialParts(Rest(u), x)
  876. if AtomQ(lst2):
  877. return False
  878. else:
  879. return [First(u)*lst2[0], First(u)*lst2[1], lst2[2]]
  880. elif FreeQ(Rest(u), x):
  881. lst1 = BinomialParts(First(u), x)
  882. if AtomQ(lst1):
  883. return False
  884. else:
  885. return [Rest(u)*lst1[0], Rest(u)*lst1[1], lst1[2]]
  886. lst1 = BinomialParts(First(u), x)
  887. if AtomQ(lst1):
  888. return False
  889. lst2 = BinomialParts(Rest(u), x)
  890. if AtomQ(lst2):
  891. return False
  892. a = lst1[0]
  893. b = lst1[1]
  894. m = lst1[2]
  895. c = lst2[0]
  896. d = lst2[1]
  897. n = lst2[2]
  898. if ZeroQ(a):
  899. if ZeroQ(c):
  900. return [0, b*d, m + n]
  901. elif ZeroQ(m + n):
  902. return [b*d, b*c, m]
  903. else:
  904. return False
  905. if ZeroQ(c):
  906. if ZeroQ(m + n):
  907. return [b*d, a*d, n]
  908. else:
  909. return False
  910. if EqQ(m, n) and ZeroQ(a*d + b*c):
  911. return [a*c, b*d, 2*m]
  912. else:
  913. return False
  914. elif SumQ(u):
  915. if FreeQ(First(u),x):
  916. lst2 = BinomialParts(Rest(u), x)
  917. if AtomQ(lst2):
  918. return False
  919. else:
  920. return [First(u) + lst2[0], lst2[1], lst2[2]]
  921. elif FreeQ(Rest(u), x):
  922. lst1 = BinomialParts(First(u), x)
  923. if AtomQ(lst1):
  924. return False
  925. else:
  926. return[Rest(u) + lst1[0], lst1[1], lst1[2]]
  927. lst1 = BinomialParts(First(u), x)
  928. if AtomQ(lst1):
  929. return False
  930. lst2 = BinomialParts(Rest(u),x)
  931. if AtomQ(lst2):
  932. return False
  933. if EqQ(lst1[2], lst2[2]):
  934. return [lst1[0] + lst2[0], lst1[1] + lst2[1], lst1[2]]
  935. else:
  936. return False
  937. else:
  938. return False
  939. def TrinomialParts(u, x):
  940. # If u is equivalent to a trinomial of the form a + b*x^n + c*x^(2*n) where n!=0, b!=0 and c!=0, TrinomialParts[u,x] returns the list {a,b,c,n}; else it returns False.
  941. u = sympify(u)
  942. if PolynomialQ(u, x):
  943. lst = CoefficientList(u, x)
  944. if len(lst)<3 or EvenQ(sympify(len(lst))) or ZeroQ((len(lst)+1)/2):
  945. return False
  946. #Catch(
  947. # Scan(Function(if ZeroQ(lst), Null, Throw(False), Drop(Drop(Drop(lst, [(len(lst)+1)/2]), 1), -1];
  948. # [First(lst), lst[(len(lst)+1)/2], Last(lst), (len(lst)-1)/2]):
  949. if PowerQ(u):
  950. if EqQ(u.exp, 2):
  951. lst = BinomialParts(u.base, x)
  952. if not lst or ZeroQ(lst[0]):
  953. return False
  954. else:
  955. return [lst[0]**2, 2*lst[0]*lst[1], lst[1]**2, lst[2]]
  956. else:
  957. return False
  958. if ProductQ(u):
  959. if FreeQ(First(u), x):
  960. lst2 = TrinomialParts(Rest(u), x)
  961. if not lst2:
  962. return False
  963. else:
  964. return [First(u)*lst2[0], First(u)*lst2[1], First(u)*lst2[2], lst2[3]]
  965. if FreeQ(Rest(u), x):
  966. lst1 = TrinomialParts(First(u), x)
  967. if not lst1:
  968. return False
  969. else:
  970. return [Rest(u)*lst1[0], Rest(u)*lst1[1], Rest(u)*lst1[2], lst1[3]]
  971. lst1 = BinomialParts(First(u), x)
  972. if not lst1:
  973. return False
  974. lst2 = BinomialParts(Rest(u), x)
  975. if not lst2:
  976. return False
  977. a = lst1[0]
  978. b = lst1[1]
  979. m = lst1[2]
  980. c = lst2[0]
  981. d = lst2[1]
  982. n = lst2[2]
  983. if EqQ(m, n) and NonzeroQ(a*d+b*c):
  984. return [a*c, a*d + b*c, b*d, m]
  985. else:
  986. return False
  987. if SumQ(u):
  988. if FreeQ(First(u), x):
  989. lst2 = TrinomialParts(Rest(u), x)
  990. if not lst2:
  991. return False
  992. else:
  993. return [First(u)+lst2[0], lst2[1], lst2[2], lst2[3]]
  994. if FreeQ(Rest(u), x):
  995. lst1 = TrinomialParts(First(u), x)
  996. if not lst1:
  997. return False
  998. else:
  999. return [Rest(u)+lst1[0], lst1[1], lst1[2], lst1[3]]
  1000. lst1 = TrinomialParts(First(u), x)
  1001. if not lst1:
  1002. lst3 = BinomialParts(First(u), x)
  1003. if not lst3:
  1004. return False
  1005. lst2 = TrinomialParts(Rest(u), x)
  1006. if not lst2:
  1007. lst4 = BinomialParts(Rest(u), x)
  1008. if not lst4:
  1009. return False
  1010. if EqQ(lst3[2], 2*lst4[2]):
  1011. return [lst3[0]+lst4[0], lst4[1], lst3[1], lst4[2]]
  1012. if EqQ(lst4[2], 2*lst3[2]):
  1013. return [lst3[0]+lst4[0], lst3[1], lst4[1], lst3[2]]
  1014. else:
  1015. return False
  1016. if EqQ(lst3[2], lst2[3]) and NonzeroQ(lst3[1]+lst2[1]):
  1017. return [lst3[0]+lst2[0], lst3[1]+lst2[1], lst2[2], lst2[3]]
  1018. if EqQ(lst3[2], 2*lst2[3]) and NonzeroQ(lst3[1]+lst2[2]):
  1019. return [lst3[0]+lst2[0], lst2[1], lst3[1]+lst2[2], lst2[3]]
  1020. else:
  1021. return False
  1022. lst2 = TrinomialParts(Rest(u), x)
  1023. if AtomQ(lst2):
  1024. lst4 = BinomialParts(Rest(u), x)
  1025. if not lst4:
  1026. return False
  1027. if EqQ(lst4[2], lst1[3]) and NonzeroQ(lst1[1]+lst4[0]):
  1028. return [lst1[0]+lst4[0], lst1[1]+lst4[1], lst1[2], lst1[3]]
  1029. if EqQ(lst4[2], 2*lst1[3]) and NonzeroQ(lst1[2]+lst4[1]):
  1030. return [lst1[0]+lst4[0], lst1[1], lst1[2]+lst4[1], lst1[3]]
  1031. else:
  1032. return False
  1033. if EqQ(lst1[3], lst2[3]) and NonzeroQ(lst1[1]+lst2[1]) and NonzeroQ(lst1[2]+lst2[2]):
  1034. return [lst1[0]+lst2[0], lst1[1]+lst2[1], lst1[2]+lst2[2], lst1[3]]
  1035. else:
  1036. return False
  1037. else:
  1038. return False
  1039. def PolyQ(u, x, n=None):
  1040. # returns True iff u is a polynomial of degree n.
  1041. if ListQ(u):
  1042. return all(PolyQ(i, x) for i in u)
  1043. if n is None:
  1044. if u == x:
  1045. return False
  1046. elif isinstance(x, Pow):
  1047. n = x.exp
  1048. x_base = x.base
  1049. if FreeQ(n, x_base):
  1050. if PositiveIntegerQ(n):
  1051. return PolyQ(u, x_base) and (PolynomialQ(u, x) or PolynomialQ(Together(u), x))
  1052. elif AtomQ(n):
  1053. return PolynomialQ(u, x) and FreeQ(CoefficientList(u, x), x_base)
  1054. else:
  1055. return False
  1056. return PolynomialQ(u, x) or PolynomialQ(u, Together(x))
  1057. else:
  1058. return PolynomialQ(u, x) and Coefficient(u, x, n) != 0 and Exponent(u, x) == n
  1059. def EvenQ(u):
  1060. # gives True if expr is an even integer, and False otherwise.
  1061. return isinstance(u, (Integer, int)) and u%2 == 0
  1062. def OddQ(u):
  1063. # gives True if expr is an odd integer, and False otherwise.
  1064. return isinstance(u, (Integer, int)) and u%2 == 1
  1065. def PerfectSquareQ(u):
  1066. # (* If u is a rational number whose squareroot is rational or if u is of the form u1^n1 u2^n2 ...
  1067. # and n1, n2, ... are even, PerfectSquareQ[u] returns True; else it returns False. *)
  1068. if RationalQ(u):
  1069. return Greater(u, 0) and RationalQ(Sqrt(u))
  1070. elif PowerQ(u):
  1071. return EvenQ(u.exp)
  1072. elif ProductQ(u):
  1073. return PerfectSquareQ(First(u)) and PerfectSquareQ(Rest(u))
  1074. elif SumQ(u):
  1075. s = Simplify(u)
  1076. if NonsumQ(s):
  1077. return PerfectSquareQ(s)
  1078. return False
  1079. else:
  1080. return False
  1081. def NiceSqrtAuxQ(u):
  1082. if RationalQ(u):
  1083. return u > 0
  1084. elif PowerQ(u):
  1085. return EvenQ(u.exp)
  1086. elif ProductQ(u):
  1087. return NiceSqrtAuxQ(First(u)) and NiceSqrtAuxQ(Rest(u))
  1088. elif SumQ(u):
  1089. s = Simplify(u)
  1090. return NonsumQ(s) and NiceSqrtAuxQ(s)
  1091. else:
  1092. return False
  1093. def NiceSqrtQ(u):
  1094. return Not(NegativeQ(u)) and NiceSqrtAuxQ(u)
  1095. def Together(u):
  1096. return factor(u)
  1097. def PosAux(u):
  1098. if RationalQ(u):
  1099. return u>0
  1100. elif NumberQ(u):
  1101. if ZeroQ(Re(u)):
  1102. return Im(u) > 0
  1103. else:
  1104. return Re(u) > 0
  1105. elif NumericQ(u):
  1106. v = N(u)
  1107. if ZeroQ(Re(v)):
  1108. return Im(v) > 0
  1109. else:
  1110. return Re(v) > 0
  1111. elif PowerQ(u):
  1112. if OddQ(u.exp):
  1113. return PosAux(u.base)
  1114. else:
  1115. return True
  1116. elif ProductQ(u):
  1117. if PosAux(First(u)):
  1118. return PosAux(Rest(u))
  1119. else:
  1120. return not PosAux(Rest(u))
  1121. elif SumQ(u):
  1122. return PosAux(First(u))
  1123. else:
  1124. res = u > 0
  1125. if res in(True, False):
  1126. return res
  1127. return True
  1128. def PosQ(u):
  1129. # If u is not 0 and has a positive form, PosQ[u] returns True, else it returns False.
  1130. return PosAux(TogetherSimplify(u))
  1131. def CoefficientList(u, x):
  1132. if PolynomialQ(u, x):
  1133. return list(reversed(Poly(u, x).all_coeffs()))
  1134. else:
  1135. return []
  1136. def ReplaceAll(expr, args):
  1137. if isinstance(args, list):
  1138. n_args = {}
  1139. for i in args:
  1140. n_args.update(i)
  1141. return expr.subs(n_args)
  1142. return expr.subs(args)
  1143. def ExpandLinearProduct(v, u, a, b, x):
  1144. # If u is a polynomial in x, ExpandLinearProduct[v,u,a,b,x] expands v*u into a sum of terms of the form c*v*(a+b*x)^n.
  1145. if FreeQ([a, b], x) and PolynomialQ(u, x):
  1146. lst = CoefficientList(ReplaceAll(u, {x: (x - a)/b}), x)
  1147. lst = [SimplifyTerm(i, x) for i in lst]
  1148. res = 0
  1149. for k in range(1, len(lst)+1):
  1150. res = res + Simplify(v*lst[k-1]*(a + b*x)**(k - 1))
  1151. return res
  1152. return u*v
  1153. def GCD(*args):
  1154. args = S(args)
  1155. if len(args) == 1:
  1156. if isinstance(args[0], (int, Integer)):
  1157. return args[0]
  1158. else:
  1159. return S(1)
  1160. return gcd(*args)
  1161. def ContentFactor(expn):
  1162. return factor_terms(expn)
  1163. def NumericFactor(u):
  1164. # returns the real numeric factor of u.
  1165. if NumberQ(u):
  1166. if ZeroQ(Im(u)):
  1167. return u
  1168. elif ZeroQ(Re(u)):
  1169. return Im(u)
  1170. else:
  1171. return S(1)
  1172. elif PowerQ(u):
  1173. if RationalQ(u.base) and RationalQ(u.exp):
  1174. if u.exp > 0:
  1175. return 1/Denominator(u.base)
  1176. else:
  1177. return 1/(1/Denominator(u.base))
  1178. else:
  1179. return S(1)
  1180. elif ProductQ(u):
  1181. return Mul(*[NumericFactor(i) for i in u.args])
  1182. elif SumQ(u):
  1183. if LeafCount(u) < 50:
  1184. c = ContentFactor(u)
  1185. if SumQ(c):
  1186. return S(1)
  1187. else:
  1188. return NumericFactor(c)
  1189. else:
  1190. m = NumericFactor(First(u))
  1191. n = NumericFactor(Rest(u))
  1192. if m < 0 and n < 0:
  1193. return -GCD(-m, -n)
  1194. else:
  1195. return GCD(m, n)
  1196. return S(1)
  1197. def NonnumericFactors(u):
  1198. if NumberQ(u):
  1199. if ZeroQ(Im(u)):
  1200. return S(1)
  1201. elif ZeroQ(Re(u)):
  1202. return I
  1203. return u
  1204. elif PowerQ(u):
  1205. if RationalQ(u.base) and FractionQ(u.exp):
  1206. return u/NumericFactor(u)
  1207. return u
  1208. elif ProductQ(u):
  1209. result = 1
  1210. for i in u.args:
  1211. result *= NonnumericFactors(i)
  1212. return result
  1213. elif SumQ(u):
  1214. if LeafCount(u) < 50:
  1215. i = ContentFactor(u)
  1216. if SumQ(i):
  1217. return u
  1218. else:
  1219. return NonnumericFactors(i)
  1220. n = NumericFactor(u)
  1221. result = 0
  1222. for i in u.args:
  1223. result += i/n
  1224. return result
  1225. return u
  1226. def MakeAssocList(u, x, alst=None):
  1227. # (* MakeAssocList[u,x,alst] returns an association list of gensymed symbols with the nonatomic
  1228. # parameters of a u that are not integer powers, products or sums. *)
  1229. if alst is None:
  1230. alst = []
  1231. u = replace_pow_exp(u)
  1232. x = replace_pow_exp(x)
  1233. if AtomQ(u):
  1234. return alst
  1235. elif IntegerPowerQ(u):
  1236. return MakeAssocList(u.base, x, alst)
  1237. elif ProductQ(u) or SumQ(u):
  1238. return MakeAssocList(Rest(u), x, MakeAssocList(First(u), x, alst))
  1239. elif FreeQ(u, x):
  1240. tmp = []
  1241. for i in alst:
  1242. if PowerQ(i):
  1243. if i.exp == u:
  1244. tmp.append(i)
  1245. break
  1246. elif len(i.args) > 1: # make sure args has length > 1, else causes index error some times
  1247. if i.args[1] == u:
  1248. tmp.append(i)
  1249. break
  1250. if tmp == []:
  1251. alst.append(u)
  1252. return alst
  1253. return alst
  1254. def GensymSubst(u, x, alst=None):
  1255. # (* GensymSubst[u,x,alst] returns u with the kernels in alst free of x replaced by gensymed names. *)
  1256. if alst is None:
  1257. alst =[]
  1258. u = replace_pow_exp(u)
  1259. x = replace_pow_exp(x)
  1260. if AtomQ(u):
  1261. return u
  1262. elif IntegerPowerQ(u):
  1263. return GensymSubst(u.base, x, alst)**u.exp
  1264. elif ProductQ(u) or SumQ(u):
  1265. return u.func(*[GensymSubst(i, x, alst) for i in u.args])
  1266. elif FreeQ(u, x):
  1267. tmp = []
  1268. for i in alst:
  1269. if PowerQ(i):
  1270. if i.exp == u:
  1271. tmp.append(i)
  1272. break
  1273. elif len(i.args) > 1: # make sure args has length > 1, else causes index error some times
  1274. if i.args[1] == u:
  1275. tmp.append(i)
  1276. break
  1277. if tmp == []:
  1278. return u
  1279. return tmp[0][0]
  1280. return u
  1281. def KernelSubst(u, x, alst):
  1282. # (* KernelSubst[u,x,alst] returns u with the gensymed names in alst replaced by kernels free of x. *)
  1283. if AtomQ(u):
  1284. tmp = []
  1285. for i in alst:
  1286. if i.args[0] == u:
  1287. tmp.append(i)
  1288. break
  1289. if tmp == []:
  1290. return u
  1291. elif len(tmp[0].args) > 1: # make sure args has length > 1, else causes index error some times
  1292. return tmp[0].args[1]
  1293. elif IntegerPowerQ(u):
  1294. tmp = KernelSubst(u.base, x, alst)
  1295. if u.exp < 0 and ZeroQ(tmp):
  1296. return 'Indeterminate'
  1297. return tmp**u.exp
  1298. elif ProductQ(u) or SumQ(u):
  1299. return u.func(*[KernelSubst(i, x, alst) for i in u.args])
  1300. return u
  1301. def ExpandExpression(u, x):
  1302. if AlgebraicFunctionQ(u, x) and Not(RationalFunctionQ(u, x)):
  1303. v = ExpandAlgebraicFunction(u, x)
  1304. else:
  1305. v = S(0)
  1306. if SumQ(v):
  1307. return ExpandCleanup(v, x)
  1308. v = SmartApart(u, x)
  1309. if SumQ(v):
  1310. return ExpandCleanup(v, x)
  1311. v = SmartApart(RationalFunctionFactors(u, x), x, x)
  1312. if SumQ(v):
  1313. w = NonrationalFunctionFactors(u, x)
  1314. return ExpandCleanup(v.func(*[i*w for i in v.args]), x)
  1315. v = Expand(u)
  1316. if SumQ(v):
  1317. return ExpandCleanup(v, x)
  1318. v = Expand(u)
  1319. if SumQ(v):
  1320. return ExpandCleanup(v, x)
  1321. return SimplifyTerm(u, x)
  1322. def Apart(u, x):
  1323. if RationalFunctionQ(u, x):
  1324. return apart(u, x)
  1325. return u
  1326. def SmartApart(*args):
  1327. if len(args) == 2:
  1328. u, x = args
  1329. alst = MakeAssocList(u, x)
  1330. tmp = KernelSubst(Apart(GensymSubst(u, x, alst), x), x, alst)
  1331. if tmp == 'Indeterminate':
  1332. return u
  1333. return tmp
  1334. u, v, x = args
  1335. alst = MakeAssocList(u, x)
  1336. tmp = KernelSubst(Apart(GensymSubst(u, x, alst), x), x, alst)
  1337. if tmp == 'Indeterminate':
  1338. return u
  1339. return tmp
  1340. def MatchQ(expr, pattern, *var):
  1341. # returns the matched arguments after matching pattern with expression
  1342. match = expr.match(pattern)
  1343. if match:
  1344. return tuple(match[i] for i in var)
  1345. else:
  1346. return None
  1347. def PolynomialQuotientRemainder(p, q, x):
  1348. return [PolynomialQuotient(p, q, x), PolynomialRemainder(p, q, x)]
  1349. def FreeFactors(u, x):
  1350. # returns the product of the factors of u free of x.
  1351. if ProductQ(u):
  1352. result = 1
  1353. for i in u.args:
  1354. if FreeQ(i, x):
  1355. result *= i
  1356. return result
  1357. elif FreeQ(u, x):
  1358. return u
  1359. else:
  1360. return S(1)
  1361. def NonfreeFactors(u, x):
  1362. """
  1363. Returns the product of the factors of u not free of x.
  1364. Examples
  1365. ========
  1366. >>> from sympy.integrals.rubi.utility_function import NonfreeFactors
  1367. >>> from sympy.abc import x, a, b
  1368. >>> NonfreeFactors(a, x)
  1369. 1
  1370. >>> NonfreeFactors(x + a, x)
  1371. a + x
  1372. >>> NonfreeFactors(a*b*x, x)
  1373. x
  1374. """
  1375. if ProductQ(u):
  1376. result = 1
  1377. for i in u.args:
  1378. if not FreeQ(i, x):
  1379. result *= i
  1380. return result
  1381. elif FreeQ(u, x):
  1382. return 1
  1383. else:
  1384. return u
  1385. def RemoveContentAux(expr, x):
  1386. return RemoveContentAux_replacer.replace(UtilityOperator(expr, x))
  1387. def RemoveContent(u, x):
  1388. v = NonfreeFactors(u, x)
  1389. w = Together(v)
  1390. if EqQ(FreeFactors(w, x), 1):
  1391. return RemoveContentAux(v, x)
  1392. else:
  1393. return RemoveContentAux(NonfreeFactors(w, x), x)
  1394. def FreeTerms(u, x):
  1395. """
  1396. Returns the sum of the terms of u free of x.
  1397. Examples
  1398. ========
  1399. >>> from sympy.integrals.rubi.utility_function import FreeTerms
  1400. >>> from sympy.abc import x, a, b
  1401. >>> FreeTerms(a, x)
  1402. a
  1403. >>> FreeTerms(x*a, x)
  1404. 0
  1405. >>> FreeTerms(a*x + b, x)
  1406. b
  1407. """
  1408. if SumQ(u):
  1409. result = 0
  1410. for i in u.args:
  1411. if FreeQ(i, x):
  1412. result += i
  1413. return result
  1414. elif FreeQ(u, x):
  1415. return u
  1416. else:
  1417. return 0
  1418. def NonfreeTerms(u, x):
  1419. # returns the sum of the terms of u free of x.
  1420. if SumQ(u):
  1421. result = S(0)
  1422. for i in u.args:
  1423. if not FreeQ(i, x):
  1424. result += i
  1425. return result
  1426. elif not FreeQ(u, x):
  1427. return u
  1428. else:
  1429. return S(0)
  1430. def ExpandAlgebraicFunction(expr, x):
  1431. if ProductQ(expr):
  1432. u_ = Wild('u', exclude=[x])
  1433. n_ = Wild('n', exclude=[x])
  1434. v_ = Wild('v')
  1435. pattern = u_*v_
  1436. match = expr.match(pattern)
  1437. if match:
  1438. keys = [u_, v_]
  1439. if len(keys) == len(match):
  1440. u, v = tuple([match[i] for i in keys])
  1441. if SumQ(v):
  1442. u, v = v, u
  1443. if not FreeQ(u, x) and SumQ(u):
  1444. result = 0
  1445. for i in u.args:
  1446. result += i*v
  1447. return result
  1448. pattern = u_**n_*v_
  1449. match = expr.match(pattern)
  1450. if match:
  1451. keys = [u_, n_, v_]
  1452. if len(keys) == len(match):
  1453. u, n, v = tuple([match[i] for i in keys])
  1454. if PositiveIntegerQ(n) and SumQ(u):
  1455. w = Expand(u**n)
  1456. result = 0
  1457. for i in w.args:
  1458. result += i*v
  1459. return result
  1460. return expr
  1461. def CollectReciprocals(expr, x):
  1462. # Basis: e/(a+b x)+f/(c+d x)==(c e+a f+(d e+b f) x)/(a c+(b c+a d) x+b d x^2)
  1463. if SumQ(expr):
  1464. u_ = Wild('u')
  1465. a_ = Wild('a', exclude=[x])
  1466. b_ = Wild('b', exclude=[x])
  1467. c_ = Wild('c', exclude=[x])
  1468. d_ = Wild('d', exclude=[x])
  1469. e_ = Wild('e', exclude=[x])
  1470. f_ = Wild('f', exclude=[x])
  1471. pattern = u_ + e_/(a_ + b_*x) + f_/(c_+d_*x)
  1472. match = expr.match(pattern)
  1473. if match:
  1474. try: # .match() does not work peoperly always
  1475. keys = [u_, a_, b_, c_, d_, e_, f_]
  1476. u, a, b, c, d, e, f = tuple([match[i] for i in keys])
  1477. if ZeroQ(b*c + a*d) & ZeroQ(d*e + b*f):
  1478. return CollectReciprocals(u + (c*e + a*f)/(a*c + b*d*x**2),x)
  1479. elif ZeroQ(b*c + a*d) & ZeroQ(c*e + a*f):
  1480. return CollectReciprocals(u + (d*e + b*f)*x/(a*c + b*d*x**2),x)
  1481. except:
  1482. pass
  1483. return expr
  1484. def ExpandCleanup(u, x):
  1485. v = CollectReciprocals(u, x)
  1486. if SumQ(v):
  1487. res = 0
  1488. for i in v.args:
  1489. res += SimplifyTerm(i, x)
  1490. v = res
  1491. if SumQ(v):
  1492. return UnifySum(v, x)
  1493. else:
  1494. return v
  1495. else:
  1496. return v
  1497. def AlgebraicFunctionQ(u, x, flag=False):
  1498. if ListQ(u):
  1499. if u == []:
  1500. return True
  1501. elif AlgebraicFunctionQ(First(u), x, flag):
  1502. return AlgebraicFunctionQ(Rest(u), x, flag)
  1503. else:
  1504. return False
  1505. elif AtomQ(u) or FreeQ(u, x):
  1506. return True
  1507. elif PowerQ(u):
  1508. if RationalQ(u.exp) | flag & FreeQ(u.exp, x):
  1509. return AlgebraicFunctionQ(u.base, x, flag)
  1510. elif ProductQ(u) | SumQ(u):
  1511. for i in u.args:
  1512. if not AlgebraicFunctionQ(i, x, flag):
  1513. return False
  1514. return True
  1515. return False
  1516. def Coeff(expr, form, n=1):
  1517. if n == 1:
  1518. return Coefficient(Together(expr), form, n)
  1519. else:
  1520. coef1 = Coefficient(expr, form, n)
  1521. coef2 = Coefficient(Together(expr), form, n)
  1522. if Simplify(coef1 - coef2) == 0:
  1523. return coef1
  1524. else:
  1525. return coef2
  1526. def LeadTerm(u):
  1527. if SumQ(u):
  1528. return First(u)
  1529. return u
  1530. def RemainingTerms(u):
  1531. if SumQ(u):
  1532. return Rest(u)
  1533. return u
  1534. def LeadFactor(u):
  1535. # returns the leading factor of u.
  1536. if ComplexNumberQ(u) and Re(u) == 0:
  1537. if Im(u) == S(1):
  1538. return u
  1539. else:
  1540. return LeadFactor(Im(u))
  1541. elif ProductQ(u):
  1542. return LeadFactor(First(u))
  1543. return u
  1544. def RemainingFactors(u):
  1545. # returns the remaining factors of u.
  1546. if ComplexNumberQ(u) and Re(u) == 0:
  1547. if Im(u) == 1:
  1548. return S(1)
  1549. else:
  1550. return I*RemainingFactors(Im(u))
  1551. elif ProductQ(u):
  1552. return RemainingFactors(First(u))*Rest(u)
  1553. return S(1)
  1554. def LeadBase(u):
  1555. """
  1556. returns the base of the leading factor of u.
  1557. Examples
  1558. ========
  1559. >>> from sympy.integrals.rubi.utility_function import LeadBase
  1560. >>> from sympy.abc import a, b, c
  1561. >>> LeadBase(a**b)
  1562. a
  1563. >>> LeadBase(a**b*c)
  1564. a
  1565. """
  1566. v = LeadFactor(u)
  1567. if PowerQ(v):
  1568. return v.base
  1569. return v
  1570. def LeadDegree(u):
  1571. # returns the degree of the leading factor of u.
  1572. v = LeadFactor(u)
  1573. if PowerQ(v):
  1574. return v.exp
  1575. return v
  1576. def Numer(expr):
  1577. # returns the numerator of u.
  1578. if PowerQ(expr):
  1579. if expr.exp < 0:
  1580. return 1
  1581. if ProductQ(expr):
  1582. return Mul(*[Numer(i) for i in expr.args])
  1583. return Numerator(expr)
  1584. def Denom(u):
  1585. # returns the denominator of u
  1586. if PowerQ(u):
  1587. if u.exp < 0:
  1588. return u.args[0]**(-u.args[1])
  1589. elif ProductQ(u):
  1590. return Mul(*[Denom(i) for i in u.args])
  1591. return Denominator(u)
  1592. def hypergeom(n, d, z):
  1593. return hyper(n, d, z)
  1594. def Expon(expr, form):
  1595. return Exponent(Together(expr), form)
  1596. def MergeMonomials(expr, x):
  1597. u_ = Wild('u')
  1598. p_ = Wild('p', exclude=[x, 1, 0])
  1599. a_ = Wild('a', exclude=[x])
  1600. b_ = Wild('b', exclude=[x, 0])
  1601. c_ = Wild('c', exclude=[x])
  1602. d_ = Wild('d', exclude=[x, 0])
  1603. n_ = Wild('n', exclude=[x])
  1604. m_ = Wild('m', exclude=[x])
  1605. # Basis: If m/n\[Element]\[DoubleStruckCapitalZ], then z^m (c z^n)^p==(c z^n)^(m/n+p)/c^(m/n)
  1606. pattern = u_*(a_ + b_*x)**m_*(c_*(a_ + b_*x)**n_)**p_
  1607. match = expr.match(pattern)
  1608. if match:
  1609. keys = [u_, a_, b_, m_, c_, n_, p_]
  1610. if len(keys) == len(match):
  1611. u, a, b, m, c, n, p = tuple([match[i] for i in keys])
  1612. if IntegerQ(m/n):
  1613. if u*(c*(a + b*x)**n)**(m/n + p)/c**(m/n) is S.NaN:
  1614. return expr
  1615. else:
  1616. return u*(c*(a + b*x)**n)**(m/n + p)/c**(m/n)
  1617. # Basis: If m\[Element]\[DoubleStruckCapitalZ] \[And] b c-a d==0, then (a+b z)^m==b^m/d^m (c+d z)^m
  1618. pattern = u_*(a_ + b_*x)**m_*(c_ + d_*x)**n_
  1619. match = expr.match(pattern)
  1620. if match:
  1621. keys = [u_, a_, b_, m_, c_, d_, n_]
  1622. if len(keys) == len(match):
  1623. u, a, b, m, c, d, n = tuple([match[i] for i in keys])
  1624. if IntegerQ(m) and ZeroQ(b*c - a*d):
  1625. if u*b**m/d**m*(c + d*x)**(m + n) is S.NaN:
  1626. return expr
  1627. else:
  1628. return u*b**m/d**m*(c + d*x)**(m + n)
  1629. return expr
  1630. def PolynomialDivide(u, v, x):
  1631. quo = PolynomialQuotient(u, v, x)
  1632. rem = PolynomialRemainder(u, v, x)
  1633. s = 0
  1634. for i in ExponentList(quo, x):
  1635. s += Simp(Together(Coefficient(quo, x, i)*x**i), x)
  1636. quo = s
  1637. rem = Together(rem)
  1638. free = FreeFactors(rem, x)
  1639. rem = NonfreeFactors(rem, x)
  1640. monomial = x**Min(*ExponentList(rem, x))
  1641. if NegQ(Coefficient(rem, x, 0)):
  1642. monomial = -monomial
  1643. s = 0
  1644. for i in ExponentList(rem, x):
  1645. s += Simp(Together(Coefficient(rem, x, i)*x**i/monomial), x)
  1646. rem = s
  1647. if BinomialQ(v, x):
  1648. return quo + free*monomial*rem/ExpandToSum(v, x)
  1649. else:
  1650. return quo + free*monomial*rem/v
  1651. def BinomialQ(u, x, n=None):
  1652. """
  1653. If u is equivalent to an expression of the form a + b*x**n, BinomialQ(u, x, n) returns True, else it returns False.
  1654. Examples
  1655. ========
  1656. >>> from sympy.integrals.rubi.utility_function import BinomialQ
  1657. >>> from sympy.abc import x
  1658. >>> BinomialQ(x**9, x)
  1659. True
  1660. >>> BinomialQ((1 + x)**3, x)
  1661. False
  1662. """
  1663. if ListQ(u):
  1664. for i in u:
  1665. if Not(BinomialQ(i, x, n)):
  1666. return False
  1667. return True
  1668. elif NumberQ(x):
  1669. return False
  1670. return ListQ(BinomialParts(u, x))
  1671. def TrinomialQ(u, x):
  1672. """
  1673. If u is equivalent to an expression of the form a + b*x**n + c*x**(2*n) where n, b and c are not 0,
  1674. TrinomialQ(u, x) returns True, else it returns False.
  1675. Examples
  1676. ========
  1677. >>> from sympy.integrals.rubi.utility_function import TrinomialQ
  1678. >>> from sympy.abc import x
  1679. >>> TrinomialQ((7 + 2*x**6 + 3*x**12), x)
  1680. True
  1681. >>> TrinomialQ(x**2, x)
  1682. False
  1683. """
  1684. if ListQ(u):
  1685. for i in u.args:
  1686. if Not(TrinomialQ(i, x)):
  1687. return False
  1688. return True
  1689. check = False
  1690. u = replace_pow_exp(u)
  1691. if PowerQ(u):
  1692. if u.exp == 2 and BinomialQ(u.base, x):
  1693. check = True
  1694. return ListQ(TrinomialParts(u,x)) and Not(QuadraticQ(u, x)) and Not(check)
  1695. def GeneralizedBinomialQ(u, x):
  1696. """
  1697. If u is equivalent to an expression of the form a*x**q+b*x**n where n, q and b are not 0,
  1698. GeneralizedBinomialQ(u, x) returns True, else it returns False.
  1699. Examples
  1700. ========
  1701. >>> from sympy.integrals.rubi.utility_function import GeneralizedBinomialQ
  1702. >>> from sympy.abc import a, x, q, b, n
  1703. >>> GeneralizedBinomialQ(a*x**q, x)
  1704. False
  1705. """
  1706. if ListQ(u):
  1707. return all(GeneralizedBinomialQ(i, x) for i in u)
  1708. return ListQ(GeneralizedBinomialParts(u, x))
  1709. def GeneralizedTrinomialQ(u, x):
  1710. """
  1711. If u is equivalent to an expression of the form a*x**q+b*x**n+c*x**(2*n-q) where n, q, b and c are not 0,
  1712. GeneralizedTrinomialQ(u, x) returns True, else it returns False.
  1713. Examples
  1714. ========
  1715. >>> from sympy.integrals.rubi.utility_function import GeneralizedTrinomialQ
  1716. >>> from sympy.abc import x
  1717. >>> GeneralizedTrinomialQ(7 + 2*x**6 + 3*x**12, x)
  1718. False
  1719. """
  1720. if ListQ(u):
  1721. return all(GeneralizedTrinomialQ(i, x) for i in u)
  1722. return ListQ(GeneralizedTrinomialParts(u, x))
  1723. def FactorSquareFreeList(poly):
  1724. r = sqf_list(poly)
  1725. result = [[1, 1]]
  1726. for i in r[1]:
  1727. result.append(list(i))
  1728. return result
  1729. def PerfectPowerTest(u, x):
  1730. # If u (x) is equivalent to a polynomial raised to an integer power greater than 1,
  1731. # PerfectPowerTest[u,x] returns u (x) as an expanded polynomial raised to the power;
  1732. # else it returns False.
  1733. if PolynomialQ(u, x):
  1734. lst = FactorSquareFreeList(u)
  1735. gcd = 0
  1736. v = 1
  1737. if lst[0] == [1, 1]:
  1738. lst = Rest(lst)
  1739. for i in lst:
  1740. gcd = GCD(gcd, i[1])
  1741. if gcd > 1:
  1742. for i in lst:
  1743. v = v*i[0]**(i[1]/gcd)
  1744. return Expand(v)**gcd
  1745. else:
  1746. return False
  1747. return False
  1748. def SquareFreeFactorTest(u, x):
  1749. # If u (x) can be square free factored, SquareFreeFactorTest[u,x] returns u (x) in
  1750. # factored form; else it returns False.
  1751. if PolynomialQ(u, x):
  1752. v = FactorSquareFree(u)
  1753. if PowerQ(v) or ProductQ(v):
  1754. return v
  1755. return False
  1756. return False
  1757. def RationalFunctionQ(u, x):
  1758. # If u is a rational function of x, RationalFunctionQ[u,x] returns True; else it returns False.
  1759. if AtomQ(u) or FreeQ(u, x):
  1760. return True
  1761. elif IntegerPowerQ(u):
  1762. return RationalFunctionQ(u.base, x)
  1763. elif ProductQ(u) or SumQ(u):
  1764. for i in u.args:
  1765. if Not(RationalFunctionQ(i, x)):
  1766. return False
  1767. return True
  1768. return False
  1769. def RationalFunctionFactors(u, x):
  1770. # RationalFunctionFactors[u,x] returns the product of the factors of u that are rational functions of x.
  1771. if ProductQ(u):
  1772. res = 1
  1773. for i in u.args:
  1774. if RationalFunctionQ(i, x):
  1775. res *= i
  1776. return res
  1777. elif RationalFunctionQ(u, x):
  1778. return u
  1779. return S(1)
  1780. def NonrationalFunctionFactors(u, x):
  1781. if ProductQ(u):
  1782. res = 1
  1783. for i in u.args:
  1784. if not RationalFunctionQ(i, x):
  1785. res *= i
  1786. return res
  1787. elif RationalFunctionQ(u, x):
  1788. return S(1)
  1789. return u
  1790. def Reverse(u):
  1791. if isinstance(u, list):
  1792. return list(reversed(u))
  1793. else:
  1794. l = list(u.args)
  1795. return u.func(*list(reversed(l)))
  1796. def RationalFunctionExponents(u, x):
  1797. """
  1798. u is a polynomial or rational function of x.
  1799. RationalFunctionExponents(u, x) returns a list of the exponent of the
  1800. numerator of u and the exponent of the denominator of u.
  1801. Examples
  1802. ========
  1803. >>> from sympy.integrals.rubi.utility_function import RationalFunctionExponents
  1804. >>> from sympy.abc import x, a
  1805. >>> RationalFunctionExponents(x, x)
  1806. [1, 0]
  1807. >>> RationalFunctionExponents(x**(-1), x)
  1808. [0, 1]
  1809. >>> RationalFunctionExponents(x**(-1)*a, x)
  1810. [0, 1]
  1811. """
  1812. if PolynomialQ(u, x):
  1813. return [Exponent(u, x), 0]
  1814. elif IntegerPowerQ(u):
  1815. if PositiveQ(u.exp):
  1816. return u.exp*RationalFunctionExponents(u.base, x)
  1817. return (-u.exp)*Reverse(RationalFunctionExponents(u.base, x))
  1818. elif ProductQ(u):
  1819. lst1 = RationalFunctionExponents(First(u), x)
  1820. lst2 = RationalFunctionExponents(Rest(u), x)
  1821. return [lst1[0] + lst2[0], lst1[1] + lst2[1]]
  1822. elif SumQ(u):
  1823. v = Together(u)
  1824. if SumQ(v):
  1825. lst1 = RationalFunctionExponents(First(u), x)
  1826. lst2 = RationalFunctionExponents(Rest(u), x)
  1827. return [Max(lst1[0] + lst2[1], lst2[0] + lst1[1]), lst1[1] + lst2[1]]
  1828. else:
  1829. return RationalFunctionExponents(v, x)
  1830. return [0, 0]
  1831. def RationalFunctionExpand(expr, x):
  1832. # expr is a polynomial or rational function of x.
  1833. # RationalFunctionExpand[u,x] returns the expansion of the factors of u that are rational functions times the other factors.
  1834. def cons_f1(n):
  1835. return FractionQ(n)
  1836. cons1 = CustomConstraint(cons_f1)
  1837. def cons_f2(x, v):
  1838. if not isinstance(x, Symbol):
  1839. return False
  1840. return UnsameQ(v, x)
  1841. cons2 = CustomConstraint(cons_f2)
  1842. def With1(n, u, x, v):
  1843. w = RationalFunctionExpand(u, x)
  1844. return If(SumQ(w), Add(*[i*v**n for i in w.args]), v**n*w)
  1845. pattern1 = Pattern(UtilityOperator(u_*v_**n_, x_), cons1, cons2)
  1846. rule1 = ReplacementRule(pattern1, With1)
  1847. def With2(u, x):
  1848. v = ExpandIntegrand(u, x)
  1849. def _consf_u(a, b, c, d, p, m, n, x):
  1850. return And(FreeQ(List(a, b, c, d, p), x), IntegersQ(m, n), Equal(m, Add(n, S(-1))))
  1851. cons_u = CustomConstraint(_consf_u)
  1852. pat = Pattern(UtilityOperator(x_**WC('m', S(1))*(x_*WC('d', S(1)) + c_)**p_/(x_**n_*WC('b', S(1)) + a_), x_), cons_u)
  1853. result_matchq = is_match(UtilityOperator(u, x), pat)
  1854. if UnsameQ(v, u) and not result_matchq:
  1855. return v
  1856. else:
  1857. v = ExpandIntegrand(RationalFunctionFactors(u, x), x)
  1858. w = NonrationalFunctionFactors(u, x)
  1859. if SumQ(v):
  1860. return Add(*[i*w for i in v.args])
  1861. else:
  1862. return v*w
  1863. pattern2 = Pattern(UtilityOperator(u_, x_))
  1864. rule2 = ReplacementRule(pattern2, With2)
  1865. expr = expr.replace(sym_exp, rubi_exp)
  1866. res = replace_all(UtilityOperator(expr, x), [rule1, rule2])
  1867. return replace_pow_exp(res)
  1868. def ExpandIntegrand(expr, x, extra=None):
  1869. expr = replace_pow_exp(expr)
  1870. if extra is not None:
  1871. extra, x = x, extra
  1872. w = ExpandIntegrand(extra, x)
  1873. r = NonfreeTerms(w, x)
  1874. if SumQ(r):
  1875. result = [expr*FreeTerms(w, x)]
  1876. for i in r.args:
  1877. result.append(MergeMonomials(expr*i, x))
  1878. return r.func(*result)
  1879. else:
  1880. return expr*FreeTerms(w, x) + MergeMonomials(expr*r, x)
  1881. else:
  1882. u_ = Wild('u', exclude=[0, 1])
  1883. a_ = Wild('a', exclude=[x])
  1884. b_ = Wild('b', exclude=[x, 0])
  1885. F_ = Wild('F', exclude=[0])
  1886. c_ = Wild('c', exclude=[x])
  1887. d_ = Wild('d', exclude=[x, 0])
  1888. n_ = Wild('n', exclude=[0, 1])
  1889. pattern = u_*(a_ + b_*F_)**n_
  1890. match = expr.match(pattern)
  1891. if match:
  1892. if MemberQ([asin, acos, asinh, acosh], match[F_].func):
  1893. keys = [u_, a_, b_, F_, n_]
  1894. if len(match) == len(keys):
  1895. u, a, b, F, n = tuple([match[i] for i in keys])
  1896. match = F.args[0].match(c_ + d_*x)
  1897. if match:
  1898. keys = c_, d_
  1899. if len(keys) == len(match):
  1900. c, d = tuple([match[i] for i in keys])
  1901. if PolynomialQ(u, x):
  1902. F = F.func
  1903. return ExpandLinearProduct((a + b*F(c + d*x))**n, u, c, d, x)
  1904. expr = expr.replace(sym_exp, rubi_exp)
  1905. res = replace_all(UtilityOperator(expr, x), ExpandIntegrand_rules, max_count = 1)
  1906. return replace_pow_exp(res)
  1907. def SimplerQ(u, v):
  1908. # If u is simpler than v, SimplerQ(u, v) returns True, else it returns False. SimplerQ(u, u) returns False
  1909. if IntegerQ(u):
  1910. if IntegerQ(v):
  1911. if Abs(u)==Abs(v):
  1912. return v<0
  1913. else:
  1914. return Abs(u)<Abs(v)
  1915. else:
  1916. return True
  1917. elif IntegerQ(v):
  1918. return False
  1919. elif FractionQ(u):
  1920. if FractionQ(v):
  1921. if Denominator(u) == Denominator(v):
  1922. return SimplerQ(Numerator(u), Numerator(v))
  1923. else:
  1924. return Denominator(u)<Denominator(v)
  1925. else:
  1926. return True
  1927. elif FractionQ(v):
  1928. return False
  1929. elif (Re(u)==0 or Re(u) == 0) and (Re(v)==0 or Re(v) == 0):
  1930. return SimplerQ(Im(u), Im(v))
  1931. elif ComplexNumberQ(u):
  1932. if ComplexNumberQ(v):
  1933. if Re(u) == Re(v):
  1934. return SimplerQ(Im(u), Im(v))
  1935. else:
  1936. return SimplerQ(Re(u),Re(v))
  1937. else:
  1938. return False
  1939. elif NumberQ(u):
  1940. if NumberQ(v):
  1941. return OrderedQ([u,v])
  1942. else:
  1943. return True
  1944. elif NumberQ(v):
  1945. return False
  1946. elif AtomQ(u) or (Head(u) == re) or (Head(u) == im):
  1947. if AtomQ(v) or (Head(u) == re) or (Head(u) == im):
  1948. return OrderedQ([u,v])
  1949. else:
  1950. return True
  1951. elif AtomQ(v) or (Head(u) == re) or (Head(u) == im):
  1952. return False
  1953. elif Head(u) == Head(v):
  1954. if Length(u) == Length(v):
  1955. for i in range(len(u.args)):
  1956. if not u.args[i] == v.args[i]:
  1957. return SimplerQ(u.args[i], v.args[i])
  1958. return False
  1959. return Length(u) < Length(v)
  1960. elif LeafCount(u) < LeafCount(v):
  1961. return True
  1962. elif LeafCount(v) < LeafCount(u):
  1963. return False
  1964. return Not(OrderedQ([v,u]))
  1965. def SimplerSqrtQ(u, v):
  1966. # If Rt(u, 2) is simpler than Rt(v, 2), SimplerSqrtQ(u, v) returns True, else it returns False. SimplerSqrtQ(u, u) returns False
  1967. if NegativeQ(v) and Not(NegativeQ(u)):
  1968. return True
  1969. if NegativeQ(u) and Not(NegativeQ(v)):
  1970. return False
  1971. sqrtu = Rt(u, S(2))
  1972. sqrtv = Rt(v, S(2))
  1973. if IntegerQ(sqrtu):
  1974. if IntegerQ(sqrtv):
  1975. return sqrtu<sqrtv
  1976. else:
  1977. return True
  1978. if IntegerQ(sqrtv):
  1979. return False
  1980. if RationalQ(sqrtu):
  1981. if RationalQ(sqrtv):
  1982. return sqrtu<sqrtv
  1983. else:
  1984. return True
  1985. if RationalQ(sqrtv):
  1986. return False
  1987. if PosQ(u):
  1988. if PosQ(v):
  1989. return LeafCount(sqrtu)<LeafCount(sqrtv)
  1990. else:
  1991. return True
  1992. if PosQ(v):
  1993. return False
  1994. if LeafCount(sqrtu)<LeafCount(sqrtv):
  1995. return True
  1996. if LeafCount(sqrtv)<LeafCount(sqrtu):
  1997. return False
  1998. else:
  1999. return Not(OrderedQ([v, u]))
  2000. def SumSimplerQ(u, v):
  2001. """
  2002. If u + v is simpler than u, SumSimplerQ(u, v) returns True, else it returns False.
  2003. If for every term w of v there is a term of u equal to n*w where n<-1/2, u + v will be simpler than u.
  2004. Examples
  2005. ========
  2006. >>> from sympy.integrals.rubi.utility_function import SumSimplerQ
  2007. >>> from sympy.abc import x
  2008. >>> from sympy import S
  2009. >>> SumSimplerQ(S(4 + x),S(3 + x**3))
  2010. False
  2011. """
  2012. if RationalQ(u, v):
  2013. if v == S(0):
  2014. return False
  2015. elif v > S(0):
  2016. return u < -S(1)
  2017. else:
  2018. return u >= -v
  2019. else:
  2020. return SumSimplerAuxQ(Expand(u), Expand(v))
  2021. def BinomialDegree(u, x):
  2022. # if u is a binomial. BinomialDegree[u,x] returns the degree of x in u.
  2023. bp = BinomialParts(u, x)
  2024. if bp == False:
  2025. return bp
  2026. return bp[2]
  2027. def TrinomialDegree(u, x):
  2028. # If u is equivalent to a trinomial of the form a + b*x^n + c*x^(2*n) where n!=0, b!=0 and c!=0, TrinomialDegree[u,x] returns n
  2029. t = TrinomialParts(u, x)
  2030. if t:
  2031. return t[3]
  2032. return t
  2033. def CancelCommonFactors(u, v):
  2034. def _delete_cases(a, b):
  2035. # only for CancelCommonFactors
  2036. lst = []
  2037. deleted = False
  2038. for i in a.args:
  2039. if i == b and not deleted:
  2040. deleted = True
  2041. continue
  2042. lst.append(i)
  2043. return a.func(*lst)
  2044. # CancelCommonFactors[u,v] returns {u',v'} are the noncommon factors of u and v respectively.
  2045. if ProductQ(u):
  2046. if ProductQ(v):
  2047. if MemberQ(v, First(u)):
  2048. return CancelCommonFactors(Rest(u), _delete_cases(v, First(u)))
  2049. else:
  2050. lst = CancelCommonFactors(Rest(u), v)
  2051. return [First(u)*lst[0], lst[1]]
  2052. else:
  2053. if MemberQ(u, v):
  2054. return [_delete_cases(u, v), 1]
  2055. else:
  2056. return[u, v]
  2057. elif ProductQ(v):
  2058. if MemberQ(v, u):
  2059. return [1, _delete_cases(v, u)]
  2060. else:
  2061. return [u, v]
  2062. return[u, v]
  2063. def SimplerIntegrandQ(u, v, x):
  2064. lst = CancelCommonFactors(u, v)
  2065. u1 = lst[0]
  2066. v1 = lst[1]
  2067. if Head(u1) == Head(v1) and Length(u1) == 1 and Length(v1) == 1:
  2068. return SimplerIntegrandQ(u1.args[0], v1.args[0], x)
  2069. if 4*LeafCount(u1) < 3*LeafCount(v1):
  2070. return True
  2071. if RationalFunctionQ(u1, x):
  2072. if RationalFunctionQ(v1, x):
  2073. t1 = 0
  2074. t2 = 0
  2075. for i in RationalFunctionExponents(u1, x):
  2076. t1 += i
  2077. for i in RationalFunctionExponents(v1, x):
  2078. t2 += i
  2079. return t1 < t2
  2080. else:
  2081. return True
  2082. else:
  2083. return False
  2084. def GeneralizedBinomialDegree(u, x):
  2085. b = GeneralizedBinomialParts(u, x)
  2086. if b:
  2087. return b[2] - b[3]
  2088. def GeneralizedBinomialParts(expr, x):
  2089. expr = Expand(expr)
  2090. if GeneralizedBinomialMatchQ(expr, x):
  2091. a = Wild('a', exclude=[x])
  2092. b = Wild('b', exclude=[x])
  2093. n = Wild('n', exclude=[x])
  2094. q = Wild('q', exclude=[x])
  2095. Match = expr.match(a*x**q + b*x**n)
  2096. if Match and PosQ(Match[q] - Match[n]):
  2097. return [Match[b], Match[a], Match[q], Match[n]]
  2098. else:
  2099. return False
  2100. def GeneralizedTrinomialDegree(u, x):
  2101. t = GeneralizedTrinomialParts(u, x)
  2102. if t:
  2103. return t[3] - t[4]
  2104. def GeneralizedTrinomialParts(expr, x):
  2105. expr = Expand(expr)
  2106. if GeneralizedTrinomialMatchQ(expr, x):
  2107. a = Wild('a', exclude=[x, 0])
  2108. b = Wild('b', exclude=[x, 0])
  2109. c = Wild('c', exclude=[x])
  2110. n = Wild('n', exclude=[x, 0])
  2111. q = Wild('q', exclude=[x])
  2112. Match = expr.match(a*x**q + b*x**n+c*x**(2*n-q))
  2113. if Match and expr.is_Add:
  2114. return [Match[c], Match[b], Match[a], Match[n], 2*Match[n]-Match[q]]
  2115. else:
  2116. return False
  2117. def MonomialQ(u, x):
  2118. # If u is of the form a*x^n where n!=0 and a!=0, MonomialQ[u,x] returns True; else False
  2119. if isinstance(u, list):
  2120. return all(MonomialQ(i, x) for i in u)
  2121. else:
  2122. a = Wild('a', exclude=[x])
  2123. b = Wild('b', exclude=[x])
  2124. re = u.match(a*x**b)
  2125. if re:
  2126. return True
  2127. return False
  2128. def MonomialSumQ(u, x):
  2129. # if u(x) is a sum and each term is free of x or an expression of the form a*x^n, MonomialSumQ(u, x) returns True; else it returns False
  2130. if SumQ(u):
  2131. for i in u.args:
  2132. if Not(FreeQ(i, x) or MonomialQ(i, x)):
  2133. return False
  2134. return True
  2135. @doctest_depends_on(modules=('matchpy',))
  2136. def MinimumMonomialExponent(u, x):
  2137. """
  2138. u is sum whose terms are monomials. MinimumMonomialExponent(u, x) returns the exponent of the term having the smallest exponent
  2139. Examples
  2140. ========
  2141. >>> from sympy.integrals.rubi.utility_function import MinimumMonomialExponent
  2142. >>> from sympy.abc import x
  2143. >>> MinimumMonomialExponent(x**2 + 5*x**2 + 3*x**5, x)
  2144. 2
  2145. >>> MinimumMonomialExponent(x**2 + 5*x**2 + 1, x)
  2146. 0
  2147. """
  2148. n =MonomialExponent(First(u), x)
  2149. for i in u.args:
  2150. if PosQ(n - MonomialExponent(i, x)):
  2151. n = MonomialExponent(i, x)
  2152. return n
  2153. def MonomialExponent(u, x):
  2154. # u is a monomial. MonomialExponent(u, x) returns the exponent of x in u
  2155. a = Wild('a', exclude=[x])
  2156. b = Wild('b', exclude=[x])
  2157. re = u.match(a*x**b)
  2158. if re:
  2159. return re[b]
  2160. def LinearMatchQ(u, x):
  2161. # LinearMatchQ(u, x) returns True iff u matches patterns of the form a+b*x where a and b are free of x
  2162. if isinstance(u, list):
  2163. return all(LinearMatchQ(i, x) for i in u)
  2164. else:
  2165. a = Wild('a', exclude=[x])
  2166. b = Wild('b', exclude=[x])
  2167. re = u.match(a + b*x)
  2168. if re:
  2169. return True
  2170. return False
  2171. def PowerOfLinearMatchQ(u, x):
  2172. if isinstance(u, list):
  2173. for i in u:
  2174. if not PowerOfLinearMatchQ(i, x):
  2175. return False
  2176. return True
  2177. else:
  2178. a = Wild('a', exclude=[x])
  2179. b = Wild('b', exclude=[x, 0])
  2180. m = Wild('m', exclude=[x, 0])
  2181. Match = u.match((a + b*x)**m)
  2182. if Match:
  2183. return True
  2184. else:
  2185. return False
  2186. def QuadraticMatchQ(u, x):
  2187. if ListQ(u):
  2188. return all(QuadraticMatchQ(i, x) for i in u)
  2189. pattern1 = Pattern(UtilityOperator(x_**2*WC('c', 1) + x_*WC('b', 1) + WC('a', 0), x_), CustomConstraint(lambda a, b, c, x: FreeQ([a, b, c], x)))
  2190. pattern2 = Pattern(UtilityOperator(x_**2*WC('c', 1) + WC('a', 0), x_), CustomConstraint(lambda a, c, x: FreeQ([a, c], x)))
  2191. u1 = UtilityOperator(u, x)
  2192. return is_match(u1, pattern1) or is_match(u1, pattern2)
  2193. def CubicMatchQ(u, x):
  2194. if isinstance(u, list):
  2195. return all(CubicMatchQ(i, x) for i in u)
  2196. else:
  2197. pattern1 = Pattern(UtilityOperator(x_**3*WC('d', 1) + x_**2*WC('c', 1) + x_*WC('b', 1) + WC('a', 0), x_), CustomConstraint(lambda a, b, c, d, x: FreeQ([a, b, c, d], x)))
  2198. pattern2 = Pattern(UtilityOperator(x_**3*WC('d', 1) + x_*WC('b', 1) + WC('a', 0), x_), CustomConstraint(lambda a, b, d, x: FreeQ([a, b, d], x)))
  2199. pattern3 = Pattern(UtilityOperator(x_**3*WC('d', 1) + x_**2*WC('c', 1) + WC('a', 0), x_), CustomConstraint(lambda a, c, d, x: FreeQ([a, c, d], x)))
  2200. pattern4 = Pattern(UtilityOperator(x_**3*WC('d', 1) + WC('a', 0), x_), CustomConstraint(lambda a, d, x: FreeQ([a, d], x)))
  2201. u1 = UtilityOperator(u, x)
  2202. if is_match(u1, pattern1) or is_match(u1, pattern2) or is_match(u1, pattern3) or is_match(u1, pattern4):
  2203. return True
  2204. else:
  2205. return False
  2206. def BinomialMatchQ(u, x):
  2207. if isinstance(u, list):
  2208. return all(BinomialMatchQ(i, x) for i in u)
  2209. else:
  2210. pattern = Pattern(UtilityOperator(x_**WC('n', S(1))*WC('b', S(1)) + WC('a', S(0)), x_) , CustomConstraint(lambda a, b, n, x: FreeQ([a,b,n],x)))
  2211. u = UtilityOperator(u, x)
  2212. return is_match(u, pattern)
  2213. def TrinomialMatchQ(u, x):
  2214. if isinstance(u, list):
  2215. return all(TrinomialMatchQ(i, x) for i in u)
  2216. else:
  2217. pattern = Pattern(UtilityOperator(x_**WC('j', S(1))*WC('c', S(1)) + x_**WC('n', S(1))*WC('b', S(1)) + WC('a', S(0)), x_) , CustomConstraint(lambda a, b, c, n, x: FreeQ([a, b, c, n], x)), CustomConstraint(lambda j, n: ZeroQ(j-2*n) ))
  2218. u = UtilityOperator(u, x)
  2219. return is_match(u, pattern)
  2220. def GeneralizedBinomialMatchQ(u, x):
  2221. if isinstance(u, list):
  2222. return all(GeneralizedBinomialMatchQ(i, x) for i in u)
  2223. else:
  2224. a = Wild('a', exclude=[x, 0])
  2225. b = Wild('b', exclude=[x, 0])
  2226. n = Wild('n', exclude=[x, 0])
  2227. q = Wild('q', exclude=[x, 0])
  2228. Match = u.match(a*x**q + b*x**n)
  2229. if Match and len(Match) == 4 and Match[q] != 0 and Match[n] != 0:
  2230. return True
  2231. else:
  2232. return False
  2233. def GeneralizedTrinomialMatchQ(u, x):
  2234. if isinstance(u, list):
  2235. return all(GeneralizedTrinomialMatchQ(i, x) for i in u)
  2236. else:
  2237. a = Wild('a', exclude=[x, 0])
  2238. b = Wild('b', exclude=[x, 0])
  2239. n = Wild('n', exclude=[x, 0])
  2240. c = Wild('c', exclude=[x, 0])
  2241. q = Wild('q', exclude=[x, 0])
  2242. Match = u.match(a*x**q + b*x**n + c*x**(2*n - q))
  2243. if Match and len(Match) == 5 and 2*Match[n] - Match[q] != 0 and Match[n] != 0:
  2244. return True
  2245. else:
  2246. return False
  2247. def QuotientOfLinearsMatchQ(u, x):
  2248. if isinstance(u, list):
  2249. return all(QuotientOfLinearsMatchQ(i, x) for i in u)
  2250. else:
  2251. a = Wild('a', exclude=[x])
  2252. b = Wild('b', exclude=[x])
  2253. d = Wild('d', exclude=[x])
  2254. c = Wild('c', exclude=[x])
  2255. e = Wild('e')
  2256. Match = u.match(e*(a + b*x)/(c + d*x))
  2257. if Match and len(Match) == 5:
  2258. return True
  2259. else:
  2260. return False
  2261. def PolynomialTermQ(u, x):
  2262. a = Wild('a', exclude=[x])
  2263. n = Wild('n', exclude=[x])
  2264. Match = u.match(a*x**n)
  2265. if Match and IntegerQ(Match[n]) and Greater(Match[n], S(0)):
  2266. return True
  2267. else:
  2268. return False
  2269. def PolynomialTerms(u, x):
  2270. s = 0
  2271. for i in u.args:
  2272. if PolynomialTermQ(i, x):
  2273. s = s + i
  2274. return s
  2275. def NonpolynomialTerms(u, x):
  2276. s = 0
  2277. for i in u.args:
  2278. if not PolynomialTermQ(i, x):
  2279. s = s + i
  2280. return s
  2281. def PseudoBinomialParts(u, x):
  2282. if PolynomialQ(u, x) and Greater(Expon(u, x), S(2)):
  2283. n = Expon(u, x)
  2284. d = Rt(Coefficient(u, x, n), n)
  2285. c = d**(-n + S(1))*Coefficient(u, x, n + S(-1))/n
  2286. a = Simplify(u - (c + d*x)**n)
  2287. if NonzeroQ(a) and FreeQ(a, x):
  2288. return [a, S(1), c, d, n]
  2289. else:
  2290. return False
  2291. else:
  2292. return False
  2293. def NormalizePseudoBinomial(u, x):
  2294. lst = PseudoBinomialParts(u, x)
  2295. if lst:
  2296. return (lst[0] + lst[1]*(lst[2] + lst[3]*x)**lst[4])
  2297. def PseudoBinomialPairQ(u, v, x):
  2298. lst1 = PseudoBinomialParts(u, x)
  2299. if AtomQ(lst1):
  2300. return False
  2301. else:
  2302. lst2 = PseudoBinomialParts(v, x)
  2303. if AtomQ(lst2):
  2304. return False
  2305. else:
  2306. return Drop(lst1, 2) == Drop(lst2, 2)
  2307. def PseudoBinomialQ(u, x):
  2308. lst = PseudoBinomialParts(u, x)
  2309. if lst:
  2310. return True
  2311. else:
  2312. return False
  2313. def PolynomialGCD(f, g):
  2314. return gcd(f, g)
  2315. def PolyGCD(u, v, x):
  2316. # (* u and v are polynomials in x. *)
  2317. # (* PolyGCD[u,v,x] returns the factors of the gcd of u and v dependent on x. *)
  2318. return NonfreeFactors(PolynomialGCD(u, v), x)
  2319. def AlgebraicFunctionFactors(u, x, flag=False):
  2320. # (* AlgebraicFunctionFactors[u,x] returns the product of the factors of u that are algebraic functions of x. *)
  2321. if ProductQ(u):
  2322. result = 1
  2323. for i in u.args:
  2324. if AlgebraicFunctionQ(i, x, flag):
  2325. result *= i
  2326. return result
  2327. if AlgebraicFunctionQ(u, x, flag):
  2328. return u
  2329. return 1
  2330. def NonalgebraicFunctionFactors(u, x):
  2331. """
  2332. NonalgebraicFunctionFactors[u,x] returns the product of the factors of u that are not algebraic functions of x.
  2333. Examples
  2334. ========
  2335. >>> from sympy.integrals.rubi.utility_function import NonalgebraicFunctionFactors
  2336. >>> from sympy.abc import x
  2337. >>> from sympy import sin
  2338. >>> NonalgebraicFunctionFactors(sin(x), x)
  2339. sin(x)
  2340. >>> NonalgebraicFunctionFactors(x, x)
  2341. 1
  2342. """
  2343. if ProductQ(u):
  2344. result = 1
  2345. for i in u.args:
  2346. if not AlgebraicFunctionQ(i, x):
  2347. result *= i
  2348. return result
  2349. if AlgebraicFunctionQ(u, x):
  2350. return 1
  2351. return u
  2352. def QuotientOfLinearsP(u, x):
  2353. if LinearQ(u, x):
  2354. return True
  2355. elif SumQ(u):
  2356. if FreeQ(u.args[0], x):
  2357. return QuotientOfLinearsP(Rest(u), x)
  2358. elif LinearQ(Numerator(u), x) and LinearQ(Denominator(u), x):
  2359. return True
  2360. elif ProductQ(u):
  2361. if FreeQ(First(u), x):
  2362. return QuotientOfLinearsP(Rest(u), x)
  2363. elif Numerator(u) == 1 and PowerQ(u):
  2364. return QuotientOfLinearsP(Denominator(u), x)
  2365. return u == x or FreeQ(u, x)
  2366. def QuotientOfLinearsParts(u, x):
  2367. # If u is equivalent to an expression of the form (a+b*x)/(c+d*x), QuotientOfLinearsParts[u,x]
  2368. # returns the list {a, b, c, d}.
  2369. if LinearQ(u, x):
  2370. return [Coefficient(u, x, 0), Coefficient(u, x, 1), 1, 0]
  2371. elif PowerQ(u):
  2372. if Numerator(u) == 1:
  2373. u = Denominator(u)
  2374. r = QuotientOfLinearsParts(u, x)
  2375. return [r[2], r[3], r[0], r[1]]
  2376. elif SumQ(u):
  2377. a = First(u)
  2378. if FreeQ(a, x):
  2379. u = Rest(u)
  2380. r = QuotientOfLinearsParts(u, x)
  2381. return [r[0] + a*r[2], r[1] + a*r[3], r[2], r[3]]
  2382. elif ProductQ(u):
  2383. a = First(u)
  2384. if FreeQ(a, x):
  2385. r = QuotientOfLinearsParts(Rest(u), x)
  2386. return [a*r[0], a*r[1], r[2], r[3]]
  2387. a = Numerator(u)
  2388. d = Denominator(u)
  2389. if LinearQ(a, x) and LinearQ(d, x):
  2390. return [Coefficient(a, x, 0), Coefficient(a, x, 1), Coefficient(d, x, 0), Coefficient(d, x, 1)]
  2391. elif u == x:
  2392. return [0, 1, 1, 0]
  2393. elif FreeQ(u, x):
  2394. return [u, 0, 1, 0]
  2395. return [u, 0, 1, 0]
  2396. def QuotientOfLinearsQ(u, x):
  2397. # (*QuotientOfLinearsQ[u,x] returns True iff u is equivalent to an expression of the form (a+b x)/(c+d x) where b!=0 and d!=0.*)
  2398. if ListQ(u):
  2399. for i in u:
  2400. if not QuotientOfLinearsQ(i, x):
  2401. return False
  2402. return True
  2403. q = QuotientOfLinearsParts(u, x)
  2404. return QuotientOfLinearsP(u, x) and NonzeroQ(q[1]) and NonzeroQ(q[3])
  2405. def Flatten(l):
  2406. return flatten(l)
  2407. def Sort(u, r=False):
  2408. return sorted(u, key=lambda x: x.sort_key(), reverse=r)
  2409. # (*Definition: A number is absurd if it is a rational number, a positive rational number raised to a fractional power, or a product of absurd numbers.*)
  2410. def AbsurdNumberQ(u):
  2411. # (* AbsurdNumberQ[u] returns True if u is an absurd number, else it returns False. *)
  2412. if PowerQ(u):
  2413. v = u.exp
  2414. u = u.base
  2415. return RationalQ(u) and u > 0 and FractionQ(v)
  2416. elif ProductQ(u):
  2417. return all(AbsurdNumberQ(i) for i in u.args)
  2418. return RationalQ(u)
  2419. def AbsurdNumberFactors(u):
  2420. # (* AbsurdNumberFactors[u] returns the product of the factors of u that are absurd numbers. *)
  2421. if AbsurdNumberQ(u):
  2422. return u
  2423. elif ProductQ(u):
  2424. result = S(1)
  2425. for i in u.args:
  2426. if AbsurdNumberQ(i):
  2427. result *= i
  2428. return result
  2429. return NumericFactor(u)
  2430. def NonabsurdNumberFactors(u):
  2431. # (* NonabsurdNumberFactors[u] returns the product of the factors of u that are not absurd numbers. *)
  2432. if AbsurdNumberQ(u):
  2433. return S(1)
  2434. elif ProductQ(u):
  2435. result = 1
  2436. for i in u.args:
  2437. result *= NonabsurdNumberFactors(i)
  2438. return result
  2439. return NonnumericFactors(u)
  2440. def SumSimplerAuxQ(u, v):
  2441. if SumQ(v):
  2442. return (RationalQ(First(v)) or SumSimplerAuxQ(u,First(v))) and (RationalQ(Rest(v)) or SumSimplerAuxQ(u,Rest(v)))
  2443. elif SumQ(u):
  2444. return SumSimplerAuxQ(First(u), v) or SumSimplerAuxQ(Rest(u), v)
  2445. else:
  2446. return v!=0 and NonnumericFactors(u)==NonnumericFactors(v) and (NumericFactor(u)/NumericFactor(v)<-1/2 or NumericFactor(u)/NumericFactor(v)==-1/2 and NumericFactor(u)<0)
  2447. def Prepend(l1, l2):
  2448. if not isinstance(l2, list):
  2449. return [l2] + l1
  2450. return l2 + l1
  2451. def Drop(lst, n):
  2452. if isinstance(lst, list):
  2453. if isinstance(n, list):
  2454. lst = lst[:(n[0]-1)] + lst[n[1]:]
  2455. elif n > 0:
  2456. lst = lst[n:]
  2457. elif n < 0:
  2458. lst = lst[:-n]
  2459. else:
  2460. return lst
  2461. return lst
  2462. return lst.func(*[i for i in Drop(list(lst.args), n)])
  2463. def CombineExponents(lst):
  2464. if Length(lst) < 2:
  2465. return lst
  2466. elif lst[0][0] == lst[1][0]:
  2467. return CombineExponents(Prepend(Drop(lst,2),[lst[0][0], lst[0][1] + lst[1][1]]))
  2468. return Prepend(CombineExponents(Rest(lst)), First(lst))
  2469. def FactorInteger(n, l=None):
  2470. if isinstance(n, (int, Integer)):
  2471. return sorted(factorint(n, limit=l).items())
  2472. else:
  2473. return sorted(factorrat(n, limit=l).items())
  2474. def FactorAbsurdNumber(m):
  2475. # (* m must be an absurd number. FactorAbsurdNumber[m] returns the prime factorization of m *)
  2476. # (* as list of base-degree pairs where the bases are prime numbers and the degrees are rational. *)
  2477. if RationalQ(m):
  2478. return FactorInteger(m)
  2479. elif PowerQ(m):
  2480. r = FactorInteger(m.base)
  2481. return [r[0], r[1]*m.exp]
  2482. # CombineExponents[Sort[Flatten[Map[FactorAbsurdNumber,Apply[List,m]],1], Function[i1[[1]]<i2[[1]]]]]
  2483. return list((m.as_base_exp(),))
  2484. def SubstForInverseFunction(*args):
  2485. """
  2486. SubstForInverseFunction(u, v, w, x) returns u with subexpressions equal to v replaced by x and x replaced by w.
  2487. Examples
  2488. ========
  2489. >>> from sympy.integrals.rubi.utility_function import SubstForInverseFunction
  2490. >>> from sympy.abc import x, a, b
  2491. >>> SubstForInverseFunction(a, a, b, x)
  2492. a
  2493. >>> SubstForInverseFunction(x**a, x**a, b, x)
  2494. x
  2495. >>> SubstForInverseFunction(a*x**a, a, b, x)
  2496. a*b**a
  2497. """
  2498. if len(args) == 3:
  2499. u, v, x = args[0], args[1], args[2]
  2500. return SubstForInverseFunction(u, v, (-Coefficient(v.args[0], x, 0) + InverseFunction(Head(v))(x))/Coefficient(v.args[0], x, 1), x)
  2501. elif len(args) == 4:
  2502. u, v, w, x = args[0], args[1], args[2], args[3]
  2503. if AtomQ(u):
  2504. if u == x:
  2505. return w
  2506. return u
  2507. elif Head(u) == Head(v) and ZeroQ(u.args[0] - v.args[0]):
  2508. return x
  2509. res = [SubstForInverseFunction(i, v, w, x) for i in u.args]
  2510. return u.func(*res)
  2511. def SubstForFractionalPower(u, v, n, w, x):
  2512. # (* SubstForFractionalPower[u,v,n,w,x] returns u with subexpressions equal to v^(m/n) replaced
  2513. # by x^m and x replaced by w. *)
  2514. if AtomQ(u):
  2515. if u == x:
  2516. return w
  2517. return u
  2518. elif FractionalPowerQ(u):
  2519. if ZeroQ(u.base - v):
  2520. return x**(n*u.exp)
  2521. res = [SubstForFractionalPower(i, v, n, w, x) for i in u.args]
  2522. return u.func(*res)
  2523. def SubstForFractionalPowerOfQuotientOfLinears(u, x):
  2524. # (* If u has a subexpression of the form ((a+b*x)/(c+d*x))^(m/n) where m and n>1 are integers,
  2525. # SubstForFractionalPowerOfQuotientOfLinears[u,x] returns the list {v,n,(a+b*x)/(c+d*x),b*c-a*d} where v is u
  2526. # with subexpressions of the form ((a+b*x)/(c+d*x))^(m/n) replaced by x^m and x replaced
  2527. lst = FractionalPowerOfQuotientOfLinears(u, 1, False, x)
  2528. if AtomQ(lst) or AtomQ(lst[1]):
  2529. return False
  2530. n = lst[0]
  2531. tmp = lst[1]
  2532. lst = QuotientOfLinearsParts(tmp, x)
  2533. a, b, c, d = lst[0], lst[1], lst[2], lst[3]
  2534. if ZeroQ(d):
  2535. return False
  2536. lst = Simplify(x**(n - 1)*SubstForFractionalPower(u, tmp, n, (-a + c*x**n)/(b - d*x**n), x)/(b - d*x**n)**2)
  2537. return [NonfreeFactors(lst, x), n, tmp, FreeFactors(lst, x)*(b*c - a*d)]
  2538. def FractionalPowerOfQuotientOfLinears(u, n, v, x):
  2539. # (* If u has a subexpression of the form ((a+b*x)/(c+d*x))^(m/n),
  2540. # FractionalPowerOfQuotientOfLinears[u,1,False,x] returns {n,(a+b*x)/(c+d*x)}; else it returns False. *)
  2541. if AtomQ(u) or FreeQ(u, x):
  2542. return [n, v]
  2543. elif CalculusQ(u):
  2544. return False
  2545. elif FractionalPowerQ(u):
  2546. if QuotientOfLinearsQ(u.base, x) and Not(LinearQ(u.base, x)) and (FalseQ(v) or ZeroQ(u.base - v)):
  2547. return [LCM(Denominator(u.exp), n), u.base]
  2548. lst = [n, v]
  2549. for i in u.args:
  2550. lst = FractionalPowerOfQuotientOfLinears(i, lst[0], lst[1],x)
  2551. if AtomQ(lst):
  2552. return False
  2553. return lst
  2554. def SubstForFractionalPowerQ(u, v, x):
  2555. # (* If the substitution x=v^(1/n) will not complicate algebraic subexpressions of u,
  2556. # SubstForFractionalPowerQ[u,v,x] returns True; else it returns False. *)
  2557. if AtomQ(u) or FreeQ(u, x):
  2558. return True
  2559. elif FractionalPowerQ(u):
  2560. return SubstForFractionalPowerAuxQ(u, v, x)
  2561. return all(SubstForFractionalPowerQ(i, v, x) for i in u.args)
  2562. def SubstForFractionalPowerAuxQ(u, v, x):
  2563. if AtomQ(u):
  2564. return False
  2565. elif FractionalPowerQ(u):
  2566. if ZeroQ(u.base - v):
  2567. return True
  2568. return any(SubstForFractionalPowerAuxQ(i, v, x) for i in u.args)
  2569. def FractionalPowerOfSquareQ(u):
  2570. # (* If a subexpression of u is of the form ((v+w)^2)^n where n is a fraction, *)
  2571. # (* FractionalPowerOfSquareQ[u] returns (v+w)^2; else it returns False. *)
  2572. if AtomQ(u):
  2573. return False
  2574. elif FractionalPowerQ(u):
  2575. a_ = Wild('a', exclude=[0])
  2576. b_ = Wild('b', exclude=[0])
  2577. c_ = Wild('c', exclude=[0])
  2578. match = u.base.match(a_*(b_ + c_)**(S(2)))
  2579. if match:
  2580. keys = [a_, b_, c_]
  2581. if len(keys) == len(match):
  2582. a, b, c = tuple(match[i] for i in keys)
  2583. if NonsumQ(a):
  2584. return (b + c)**S(2)
  2585. for i in u.args:
  2586. tmp = FractionalPowerOfSquareQ(i)
  2587. if Not(FalseQ(tmp)):
  2588. return tmp
  2589. return False
  2590. def FractionalPowerSubexpressionQ(u, v, w):
  2591. # (* If a subexpression of u is of the form w^n where n is a fraction but not equal to v, *)
  2592. # (* FractionalPowerSubexpressionQ[u,v,w] returns True; else it returns False. *)
  2593. if AtomQ(u):
  2594. return False
  2595. elif FractionalPowerQ(u):
  2596. if PositiveQ(u.base/w):
  2597. return Not(u.base == v) and LeafCount(w) < 3*LeafCount(v)
  2598. for i in u.args:
  2599. if FractionalPowerSubexpressionQ(i, v, w):
  2600. return True
  2601. return False
  2602. def Apply(f, lst):
  2603. return f(*lst)
  2604. def FactorNumericGcd(u):
  2605. # (* FactorNumericGcd[u] returns u with the gcd of the numeric coefficients of terms of sums factored out. *)
  2606. if PowerQ(u):
  2607. if RationalQ(u.exp):
  2608. return FactorNumericGcd(u.base)**u.exp
  2609. elif ProductQ(u):
  2610. res = [FactorNumericGcd(i) for i in u.args]
  2611. return Mul(*res)
  2612. elif SumQ(u):
  2613. g = GCD([NumericFactor(i) for i in u.args])
  2614. r = Add(*[i/g for i in u.args])
  2615. return g*r
  2616. return u
  2617. def MergeableFactorQ(bas, deg, v):
  2618. # (* MergeableFactorQ[bas,deg,v] returns True iff bas equals the base of a factor of v or bas is a factor of every term of v. *)
  2619. if bas == v:
  2620. return RationalQ(deg + S(1)) and (deg + 1>=0 or RationalQ(deg) and deg>0)
  2621. elif PowerQ(v):
  2622. if bas == v.base:
  2623. return RationalQ(deg+v.exp) and (deg+v.exp>=0 or RationalQ(deg) and deg>0)
  2624. return SumQ(v.base) and IntegerQ(v.exp) and (Not(IntegerQ(deg) or IntegerQ(deg/v.exp))) and MergeableFactorQ(bas, deg/v.exp, v.base)
  2625. elif ProductQ(v):
  2626. return MergeableFactorQ(bas, deg, First(v)) or MergeableFactorQ(bas, deg, Rest(v))
  2627. return SumQ(v) and MergeableFactorQ(bas, deg, First(v)) and MergeableFactorQ(bas, deg, Rest(v))
  2628. def MergeFactor(bas, deg, v):
  2629. # (* If MergeableFactorQ[bas,deg,v], MergeFactor[bas,deg,v] return the product of bas^deg and v,
  2630. # but with bas^deg merged into the factor of v whose base equals bas. *)
  2631. if bas == v:
  2632. return bas**(deg + 1)
  2633. elif PowerQ(v):
  2634. if bas == v.base:
  2635. return bas**(deg + v.exp)
  2636. return MergeFactor(bas, deg/v.exp, v.base**v.exp)
  2637. elif ProductQ(v):
  2638. if MergeableFactorQ(bas, deg, First(v)):
  2639. return MergeFactor(bas, deg, First(v))*Rest(v)
  2640. return First(v)*MergeFactor(bas, deg, Rest(v))
  2641. return MergeFactor(bas, deg, First(v)) + MergeFactor(bas, deg, Rest(v))
  2642. def MergeFactors(u, v):
  2643. # (* MergeFactors[u,v] returns the product of u and v, but with the mergeable factors of u merged into v. *)
  2644. if ProductQ(u):
  2645. return MergeFactors(Rest(u), MergeFactors(First(u), v))
  2646. elif PowerQ(u):
  2647. if MergeableFactorQ(u.base, u.exp, v):
  2648. return MergeFactor(u.base, u.exp, v)
  2649. elif RationalQ(u.exp) and u.exp < -1 and MergeableFactorQ(u.base, -S(1), v):
  2650. return MergeFactors(u.base**(u.exp + 1), MergeFactor(u.base, -S(1), v))
  2651. return u*v
  2652. elif MergeableFactorQ(u, S(1), v):
  2653. return MergeFactor(u, S(1), v)
  2654. return u*v
  2655. def TrigSimplifyQ(u):
  2656. # (* TrigSimplifyQ[u] returns True if TrigSimplify[u] actually simplifies u; else False. *)
  2657. return ActivateTrig(u) != TrigSimplify(u)
  2658. def TrigSimplify(u):
  2659. # (* TrigSimplify[u] returns a bottom-up trig simplification of u. *)
  2660. return ActivateTrig(TrigSimplifyRecur(u))
  2661. def TrigSimplifyRecur(u):
  2662. if AtomQ(u):
  2663. return u
  2664. return TrigSimplifyAux(u.func(*[TrigSimplifyRecur(i) for i in u.args]))
  2665. def Order(expr1, expr2):
  2666. if expr1 == expr2:
  2667. return 0
  2668. elif expr1.sort_key() > expr2.sort_key():
  2669. return -1
  2670. return 1
  2671. def FactorOrder(u, v):
  2672. if u == 1:
  2673. if v == 1:
  2674. return 0
  2675. return -1
  2676. elif v == 1:
  2677. return 1
  2678. return Order(u, v)
  2679. def Smallest(num1, num2=None):
  2680. if num2 is None:
  2681. lst = num1
  2682. num = lst[0]
  2683. for i in Rest(lst):
  2684. num = Smallest(num, i)
  2685. return num
  2686. return Min(num1, num2)
  2687. def OrderedQ(l):
  2688. return l == Sort(l)
  2689. def MinimumDegree(deg1, deg2):
  2690. if RationalQ(deg1):
  2691. if RationalQ(deg2):
  2692. return Min(deg1, deg2)
  2693. return deg1
  2694. elif RationalQ(deg2):
  2695. return deg2
  2696. deg = Simplify(deg1- deg2)
  2697. if RationalQ(deg):
  2698. if deg > 0:
  2699. return deg2
  2700. return deg1
  2701. elif OrderedQ([deg1, deg2]):
  2702. return deg1
  2703. return deg2
  2704. def PositiveFactors(u):
  2705. # (* PositiveFactors[u] returns the positive factors of u *)
  2706. if ZeroQ(u):
  2707. return S(1)
  2708. elif RationalQ(u):
  2709. return Abs(u)
  2710. elif PositiveQ(u):
  2711. return u
  2712. elif ProductQ(u):
  2713. res = 1
  2714. for i in u.args:
  2715. res *= PositiveFactors(i)
  2716. return res
  2717. return 1
  2718. def Sign(u):
  2719. return sign(u)
  2720. def NonpositiveFactors(u):
  2721. # (* NonpositiveFactors[u] returns the nonpositive factors of u *)
  2722. if ZeroQ(u):
  2723. return u
  2724. elif RationalQ(u):
  2725. return Sign(u)
  2726. elif PositiveQ(u):
  2727. return S(1)
  2728. elif ProductQ(u):
  2729. res = S(1)
  2730. for i in u.args:
  2731. res *= NonpositiveFactors(i)
  2732. return res
  2733. return u
  2734. def PolynomialInAuxQ(u, v, x):
  2735. if u == v:
  2736. return True
  2737. elif AtomQ(u):
  2738. return u != x
  2739. elif PowerQ(u):
  2740. if PowerQ(v):
  2741. if u.base == v.base:
  2742. return PositiveIntegerQ(u.exp/v.exp)
  2743. return PositiveIntegerQ(u.exp) and PolynomialInAuxQ(u.base, v, x)
  2744. elif SumQ(u) or ProductQ(u):
  2745. for i in u.args:
  2746. if Not(PolynomialInAuxQ(i, v, x)):
  2747. return False
  2748. return True
  2749. return False
  2750. def PolynomialInQ(u, v, x):
  2751. """
  2752. If u is a polynomial in v(x), PolynomialInQ(u, v, x) returns True, else it returns False.
  2753. Examples
  2754. ========
  2755. >>> from sympy.integrals.rubi.utility_function import PolynomialInQ
  2756. >>> from sympy.abc import x
  2757. >>> from sympy import log, S
  2758. >>> PolynomialInQ(S(1), log(x), x)
  2759. True
  2760. >>> PolynomialInQ(log(x), log(x), x)
  2761. True
  2762. >>> PolynomialInQ(1 + log(x)**2, log(x), x)
  2763. True
  2764. """
  2765. return PolynomialInAuxQ(u, NonfreeFactors(NonfreeTerms(v, x), x), x)
  2766. def ExponentInAux(u, v, x):
  2767. if u == v:
  2768. return S(1)
  2769. elif AtomQ(u):
  2770. return S(0)
  2771. elif PowerQ(u):
  2772. if PowerQ(v):
  2773. if u.base == v.base:
  2774. return u.exp/v.exp
  2775. return u.exp*ExponentInAux(u.base, v, x)
  2776. elif ProductQ(u):
  2777. return Add(*[ExponentInAux(i, v, x) for i in u.args])
  2778. return Max(*[ExponentInAux(i, v, x) for i in u.args])
  2779. def ExponentIn(u, v, x):
  2780. return ExponentInAux(u, NonfreeFactors(NonfreeTerms(v, x), x), x)
  2781. def PolynomialInSubstAux(u, v, x):
  2782. if u == v:
  2783. return x
  2784. elif AtomQ(u):
  2785. return u
  2786. elif PowerQ(u):
  2787. if PowerQ(v):
  2788. if u.base == v.base:
  2789. return x**(u.exp/v.exp)
  2790. return PolynomialInSubstAux(u.base, v, x)**u.exp
  2791. return u.func(*[PolynomialInSubstAux(i, v, x) for i in u.args])
  2792. def PolynomialInSubst(u, v, x):
  2793. # If u is a polynomial in v[x], PolynomialInSubst[u,v,x] returns the polynomial u in x.
  2794. w = NonfreeTerms(v, x)
  2795. return ReplaceAll(PolynomialInSubstAux(u, NonfreeFactors(w, x), x), {x: x - FreeTerms(v, x)/FreeFactors(w, x)})
  2796. def Distrib(u, v):
  2797. # Distrib[u,v] returns the sum of u times each term of v.
  2798. if SumQ(v):
  2799. return Add(*[u*i for i in v.args])
  2800. return u*v
  2801. def DistributeDegree(u, m):
  2802. # DistributeDegree[u,m] returns the product of the factors of u each raised to the mth degree.
  2803. if AtomQ(u):
  2804. return u**m
  2805. elif PowerQ(u):
  2806. return u.base**(u.exp*m)
  2807. elif ProductQ(u):
  2808. return Mul(*[DistributeDegree(i, m) for i in u.args])
  2809. return u**m
  2810. def FunctionOfPower(*args):
  2811. """
  2812. FunctionOfPower[u,x] returns the gcd of the integer degrees of x in u.
  2813. Examples
  2814. ========
  2815. >>> from sympy.integrals.rubi.utility_function import FunctionOfPower
  2816. >>> from sympy.abc import x
  2817. >>> FunctionOfPower(x, x)
  2818. 1
  2819. >>> FunctionOfPower(x**3, x)
  2820. 3
  2821. """
  2822. if len(args) == 2:
  2823. return FunctionOfPower(args[0], None, args[1])
  2824. u, n, x = args
  2825. if FreeQ(u, x):
  2826. return n
  2827. elif u == x:
  2828. return S(1)
  2829. elif PowerQ(u):
  2830. if u.base == x and IntegerQ(u.exp):
  2831. if n is None:
  2832. return u.exp
  2833. return GCD(n, u.exp)
  2834. tmp = n
  2835. for i in u.args:
  2836. tmp = FunctionOfPower(i, tmp, x)
  2837. return tmp
  2838. def DivideDegreesOfFactors(u, n):
  2839. """
  2840. DivideDegreesOfFactors[u,n] returns the product of the base of the factors of u raised to the degree of the factors divided by n.
  2841. Examples
  2842. ========
  2843. >>> from sympy import S
  2844. >>> from sympy.integrals.rubi.utility_function import DivideDegreesOfFactors
  2845. >>> from sympy.abc import a, b
  2846. >>> DivideDegreesOfFactors(a**b, S(3))
  2847. a**(b/3)
  2848. """
  2849. if ProductQ(u):
  2850. return Mul(*[LeadBase(i)**(LeadDegree(i)/n) for i in u.args])
  2851. return LeadBase(u)**(LeadDegree(u)/n)
  2852. def MonomialFactor(u, x):
  2853. # MonomialFactor[u,x] returns the list {n,v} where x^n*v==u and n is free of x.
  2854. if AtomQ(u):
  2855. if u == x:
  2856. return [S(1), S(1)]
  2857. return [S(0), u]
  2858. elif PowerQ(u):
  2859. if IntegerQ(u.exp):
  2860. lst = MonomialFactor(u.base, x)
  2861. return [lst[0]*u.exp, lst[1]**u.exp]
  2862. elif u.base == x and FreeQ(u.exp, x):
  2863. return [u.exp, S(1)]
  2864. return [S(0), u]
  2865. elif ProductQ(u):
  2866. lst1 = MonomialFactor(First(u), x)
  2867. lst2 = MonomialFactor(Rest(u), x)
  2868. return [lst1[0] + lst2[0], lst1[1]*lst2[1]]
  2869. elif SumQ(u):
  2870. lst = [MonomialFactor(i, x) for i in u.args]
  2871. deg = lst[0][0]
  2872. for i in Rest(lst):
  2873. deg = MinimumDegree(deg, i[0])
  2874. if ZeroQ(deg) or RationalQ(deg) and deg < 0:
  2875. return [S(0), u]
  2876. return [deg, Add(*[x**(i[0] - deg)*i[1] for i in lst])]
  2877. return [S(0), u]
  2878. def FullSimplify(expr):
  2879. return Simplify(expr)
  2880. def FunctionOfLinearSubst(u, a, b, x):
  2881. if FreeQ(u, x):
  2882. return u
  2883. elif LinearQ(u, x):
  2884. tmp = Coefficient(u, x, 1)
  2885. if tmp == b:
  2886. tmp = S(1)
  2887. else:
  2888. tmp = tmp/b
  2889. return Coefficient(u, x, S(0)) - a*tmp + tmp*x
  2890. elif PowerQ(u):
  2891. if FreeQ(u.base, x):
  2892. return E**(FullSimplify(FunctionOfLinearSubst(Log(u.base)*u.exp, a, b, x)))
  2893. lst = MonomialFactor(u, x)
  2894. if ProductQ(u) and NonzeroQ(lst[0]):
  2895. if RationalQ(LeadFactor(lst[1])) and LeadFactor(lst[1]) < 0:
  2896. return -FunctionOfLinearSubst(DivideDegreesOfFactors(-lst[1], lst[0])*x, a, b, x)**lst[0]
  2897. return FunctionOfLinearSubst(DivideDegreesOfFactors(lst[1], lst[0])*x, a, b, x)**lst[0]
  2898. return u.func(*[FunctionOfLinearSubst(i, a, b, x) for i in u.args])
  2899. def FunctionOfLinear(*args):
  2900. # (* If u (x) is equivalent to an expression of the form f (a+b*x) and not the case that a==0 and
  2901. # b==1, FunctionOfLinear[u,x] returns the list {f (x),a,b}; else it returns False. *)
  2902. if len(args) == 2:
  2903. u, x = args
  2904. lst = FunctionOfLinear(u, False, False, x, False)
  2905. if AtomQ(lst) or FalseQ(lst[0]) or (lst[0] == 0 and lst[1] == 1):
  2906. return False
  2907. return [FunctionOfLinearSubst(u, lst[0], lst[1], x), lst[0], lst[1]]
  2908. u, a, b, x, flag = args
  2909. if FreeQ(u, x):
  2910. return [a, b]
  2911. elif CalculusQ(u):
  2912. return False
  2913. elif LinearQ(u, x):
  2914. if FalseQ(a):
  2915. return [Coefficient(u, x, 0), Coefficient(u, x, 1)]
  2916. lst = CommonFactors([b, Coefficient(u, x, 1)])
  2917. if ZeroQ(Coefficient(u, x, 0)) and Not(flag):
  2918. return [0, lst[0]]
  2919. elif ZeroQ(b*Coefficient(u, x, 0) - a*Coefficient(u, x, 1)):
  2920. return [a/lst[1], lst[0]]
  2921. return [0, 1]
  2922. elif PowerQ(u):
  2923. if FreeQ(u.base, x):
  2924. return FunctionOfLinear(Log(u.base)*u.exp, a, b, x, False)
  2925. lst = MonomialFactor(u, x)
  2926. if ProductQ(u) and NonzeroQ(lst[0]):
  2927. if False and IntegerQ(lst[0]) and lst[0] != -1 and FreeQ(lst[1], x):
  2928. if RationalQ(LeadFactor(lst[1])) and LeadFactor(lst[1]) < 0:
  2929. return FunctionOfLinear(DivideDegreesOfFactors(-lst[1], lst[0])*x, a, b, x, False)
  2930. return FunctionOfLinear(DivideDegreesOfFactors(lst[1], lst[0])*x, a, b, x, False)
  2931. return False
  2932. lst = [a, b]
  2933. for i in u.args:
  2934. lst = FunctionOfLinear(i, lst[0], lst[1], x, SumQ(u))
  2935. if AtomQ(lst):
  2936. return False
  2937. return lst
  2938. def NormalizeIntegrand(u, x):
  2939. v = NormalizeLeadTermSigns(NormalizeIntegrandAux(u, x))
  2940. if v == NormalizeLeadTermSigns(u):
  2941. return u
  2942. else:
  2943. return v
  2944. def NormalizeIntegrandAux(u, x):
  2945. if SumQ(u):
  2946. l = 0
  2947. for i in u.args:
  2948. l += NormalizeIntegrandAux(i, x)
  2949. return l
  2950. if ProductQ(MergeMonomials(u, x)):
  2951. l = 1
  2952. for i in MergeMonomials(u, x).args:
  2953. l *= NormalizeIntegrandFactor(i, x)
  2954. return l
  2955. else:
  2956. return NormalizeIntegrandFactor(MergeMonomials(u, x), x)
  2957. def NormalizeIntegrandFactor(u, x):
  2958. if PowerQ(u):
  2959. if FreeQ(u.exp, x):
  2960. bas = NormalizeIntegrandFactorBase(u.base, x)
  2961. deg = u.exp
  2962. if IntegerQ(deg) and SumQ(bas):
  2963. if all(MonomialQ(i, x) for i in bas.args):
  2964. mi = MinimumMonomialExponent(bas, x)
  2965. q = 0
  2966. for i in bas.args:
  2967. q += Simplify(i/x**mi)
  2968. return x**(mi*deg)*q**deg
  2969. else:
  2970. return bas**deg
  2971. else:
  2972. return bas**deg
  2973. if PowerQ(u):
  2974. if FreeQ(u.base, x):
  2975. return u.base**NormalizeIntegrandFactorBase(u.exp, x)
  2976. bas = NormalizeIntegrandFactorBase(u, x)
  2977. if SumQ(bas):
  2978. if all(MonomialQ(i, x) for i in bas.args):
  2979. mi = MinimumMonomialExponent(bas, x)
  2980. z = 0
  2981. for j in bas.args:
  2982. z += j/x**mi
  2983. return x**mi*z
  2984. else:
  2985. return bas
  2986. else:
  2987. return bas
  2988. def NormalizeIntegrandFactorBase(expr, x):
  2989. m = Wild('m', exclude=[x])
  2990. u = Wild('u')
  2991. match = expr.match(x**m*u)
  2992. if match and SumQ(u):
  2993. l = 0
  2994. for i in u.args:
  2995. l += NormalizeIntegrandFactorBase((x**m*i), x)
  2996. return l
  2997. if BinomialQ(expr, x):
  2998. if BinomialMatchQ(expr, x):
  2999. return expr
  3000. else:
  3001. return ExpandToSum(expr, x)
  3002. elif TrinomialQ(expr, x):
  3003. if TrinomialMatchQ(expr, x):
  3004. return expr
  3005. else:
  3006. return ExpandToSum(expr, x)
  3007. elif ProductQ(expr):
  3008. l = 1
  3009. for i in expr.args:
  3010. l *= NormalizeIntegrandFactor(i, x)
  3011. return l
  3012. elif PolynomialQ(expr, x) and Exponent(expr, x) <= 4:
  3013. return ExpandToSum(expr, x)
  3014. elif SumQ(expr):
  3015. w = Wild('w')
  3016. m = Wild('m', exclude=[x])
  3017. v = TogetherSimplify(expr)
  3018. if SumQ(v) or v.match(x**m*w) and SumQ(w) or LeafCount(v) > LeafCount(expr) + 2:
  3019. return UnifySum(expr, x)
  3020. else:
  3021. return NormalizeIntegrandFactorBase(v, x)
  3022. else:
  3023. return expr
  3024. def NormalizeTogether(u):
  3025. return NormalizeLeadTermSigns(Together(u))
  3026. def NormalizeLeadTermSigns(u):
  3027. if ProductQ(u):
  3028. t = 1
  3029. for i in u.args:
  3030. lst = SignOfFactor(i)
  3031. if lst[0] == 1:
  3032. t *= lst[1]
  3033. else:
  3034. t *= AbsorbMinusSign(lst[1])
  3035. return t
  3036. else:
  3037. lst = SignOfFactor(u)
  3038. if lst[0] == 1:
  3039. return lst[1]
  3040. else:
  3041. return AbsorbMinusSign(lst[1])
  3042. def AbsorbMinusSign(expr, *x):
  3043. m = Wild('m', exclude=[x])
  3044. u = Wild('u')
  3045. v = Wild('v')
  3046. match = expr.match(u*v**m)
  3047. if match:
  3048. if len(match) == 3:
  3049. if SumQ(match[v]) and OddQ(match[m]):
  3050. return match[u]*(-match[v])**match[m]
  3051. return -expr
  3052. def NormalizeSumFactors(u):
  3053. if AtomQ(u):
  3054. return u
  3055. elif ProductQ(u):
  3056. k = 1
  3057. for i in u.args:
  3058. k *= NormalizeSumFactors(i)
  3059. return SignOfFactor(k)[0]*SignOfFactor(k)[1]
  3060. elif SumQ(u):
  3061. k = 0
  3062. for i in u.args:
  3063. k += NormalizeSumFactors(i)
  3064. return k
  3065. else:
  3066. return u
  3067. def SignOfFactor(u):
  3068. if RationalQ(u) and u < 0 or SumQ(u) and NumericFactor(First(u)) < 0:
  3069. return [-1, -u]
  3070. elif IntegerPowerQ(u):
  3071. if SumQ(u.base) and NumericFactor(First(u.base)) < 0:
  3072. return [(-1)**u.exp, (-u.base)**u.exp]
  3073. elif ProductQ(u):
  3074. k = 1
  3075. h = 1
  3076. for i in u.args:
  3077. k *= SignOfFactor(i)[0]
  3078. h *= SignOfFactor(i)[1]
  3079. return [k, h]
  3080. return [1, u]
  3081. def NormalizePowerOfLinear(u, x):
  3082. v = FactorSquareFree(u)
  3083. if PowerQ(v):
  3084. if LinearQ(v.base, x) and FreeQ(v.exp, x):
  3085. return ExpandToSum(v.base, x)**v.exp
  3086. return ExpandToSum(v, x)
  3087. def SimplifyIntegrand(u, x):
  3088. v = NormalizeLeadTermSigns(NormalizeIntegrandAux(Simplify(u), x))
  3089. if 5*LeafCount(v) < 4*LeafCount(u):
  3090. return v
  3091. if v != NormalizeLeadTermSigns(u):
  3092. return v
  3093. else:
  3094. return u
  3095. def SimplifyTerm(u, x):
  3096. v = Simplify(u)
  3097. w = Together(v)
  3098. if LeafCount(v) < LeafCount(w):
  3099. return NormalizeIntegrand(v, x)
  3100. else:
  3101. return NormalizeIntegrand(w, x)
  3102. def TogetherSimplify(u):
  3103. v = Together(Simplify(Together(u)))
  3104. return FixSimplify(v)
  3105. def SmartSimplify(u):
  3106. v = Simplify(u)
  3107. w = factor(v)
  3108. if LeafCount(w) < LeafCount(v):
  3109. v = w
  3110. if Not(FalseQ(w == FractionalPowerOfSquareQ(v))) and FractionalPowerSubexpressionQ(u, w, Expand(w)):
  3111. v = SubstForExpn(v, w, Expand(w))
  3112. else:
  3113. v = FactorNumericGcd(v)
  3114. return FixSimplify(v)
  3115. def SubstForExpn(u, v, w):
  3116. if u == v:
  3117. return w
  3118. if AtomQ(u):
  3119. return u
  3120. else:
  3121. k = 0
  3122. for i in u.args:
  3123. k += SubstForExpn(i, v, w)
  3124. return k
  3125. def ExpandToSum(u, *x):
  3126. if len(x) == 1:
  3127. x = x[0]
  3128. expr = 0
  3129. if PolyQ(S(u), x):
  3130. for t in ExponentList(u, x):
  3131. expr += Coeff(u, x, t)*x**t
  3132. return expr
  3133. if BinomialQ(u, x):
  3134. i = BinomialParts(u, x)
  3135. expr += i[0] + i[1]*x**i[2]
  3136. return expr
  3137. if TrinomialQ(u, x):
  3138. i = TrinomialParts(u, x)
  3139. expr += i[0] + i[1]*x**i[3] + i[2]*x**(2*i[3])
  3140. return expr
  3141. if GeneralizedBinomialMatchQ(u, x):
  3142. i = GeneralizedBinomialParts(u, x)
  3143. expr += i[0]*x**i[3] + i[1]*x**i[2]
  3144. return expr
  3145. if GeneralizedTrinomialMatchQ(u, x):
  3146. i = GeneralizedTrinomialParts(u, x)
  3147. expr += i[0]*x**i[4] + i[1]*x**i[3] + i[2]*x**(2*i[3]-i[4])
  3148. return expr
  3149. else:
  3150. return Expand(u)
  3151. else:
  3152. v = x[0]
  3153. x = x[1]
  3154. w = ExpandToSum(v, x)
  3155. r = NonfreeTerms(w, x)
  3156. if SumQ(r):
  3157. k = u*FreeTerms(w, x)
  3158. for i in r.args:
  3159. k += MergeMonomials(u*i, x)
  3160. return k
  3161. else:
  3162. return u*FreeTerms(w, x) + MergeMonomials(u*r, x)
  3163. def UnifySum(u, x):
  3164. if SumQ(u):
  3165. t = 0
  3166. lst = []
  3167. for i in u.args:
  3168. lst += [i]
  3169. for j in UnifyTerms(lst, x):
  3170. t += j
  3171. return t
  3172. else:
  3173. return SimplifyTerm(u, x)
  3174. def UnifyTerms(lst, x):
  3175. if lst==[]:
  3176. return lst
  3177. else:
  3178. return UnifyTerm(First(lst), UnifyTerms(Rest(lst), x), x)
  3179. def UnifyTerm(term, lst, x):
  3180. if lst==[]:
  3181. return [term]
  3182. tmp = Simplify(First(lst)/term)
  3183. if FreeQ(tmp, x):
  3184. return Prepend(Rest(lst), [(1+tmp)*term])
  3185. else:
  3186. return Prepend(UnifyTerm(term, Rest(lst), x), [First(lst)])
  3187. def CalculusQ(u):
  3188. return False
  3189. def FunctionOfInverseLinear(*args):
  3190. # (* If u is a function of an inverse linear binomial of the form 1/(a+b*x),
  3191. # FunctionOfInverseLinear[u,x] returns the list {a,b}; else it returns False. *)
  3192. if len(args) == 2:
  3193. u, x = args
  3194. return FunctionOfInverseLinear(u, None, x)
  3195. u, lst, x = args
  3196. if FreeQ(u, x):
  3197. return lst
  3198. elif u == x:
  3199. return False
  3200. elif QuotientOfLinearsQ(u, x):
  3201. tmp = Drop(QuotientOfLinearsParts(u, x), 2)
  3202. if tmp[1] == 0:
  3203. return False
  3204. elif lst is None:
  3205. return tmp
  3206. elif ZeroQ(lst[0]*tmp[1] - lst[1]*tmp[0]):
  3207. return lst
  3208. return False
  3209. elif CalculusQ(u):
  3210. return False
  3211. tmp = lst
  3212. for i in u.args:
  3213. tmp = FunctionOfInverseLinear(i, tmp, x)
  3214. if AtomQ(tmp):
  3215. return False
  3216. return tmp
  3217. def PureFunctionOfSinhQ(u, v, x):
  3218. # (* If u is a pure function of Sinh[v] and/or Csch[v], PureFunctionOfSinhQ[u,v,x] returns True;
  3219. # else it returns False. *)
  3220. if AtomQ(u):
  3221. return u != x
  3222. elif CalculusQ(u):
  3223. return False
  3224. elif HyperbolicQ(u) and ZeroQ(u.args[0] - v):
  3225. return SinhQ(u) or CschQ(u)
  3226. for i in u.args:
  3227. if Not(PureFunctionOfSinhQ(i, v, x)):
  3228. return False
  3229. return True
  3230. def PureFunctionOfTanhQ(u, v , x):
  3231. # (* If u is a pure function of Tanh[v] and/or Coth[v], PureFunctionOfTanhQ[u,v,x] returns True;
  3232. # else it returns False. *)
  3233. if AtomQ(u):
  3234. return u != x
  3235. elif CalculusQ(u):
  3236. return False
  3237. elif HyperbolicQ(u) and ZeroQ(u.args[0] - v):
  3238. return TanhQ(u) or CothQ(u)
  3239. for i in u.args:
  3240. if Not(PureFunctionOfTanhQ(i, v, x)):
  3241. return False
  3242. return True
  3243. def PureFunctionOfCoshQ(u, v, x):
  3244. # (* If u is a pure function of Cosh[v] and/or Sech[v], PureFunctionOfCoshQ[u,v,x] returns True;
  3245. # else it returns False. *)
  3246. if AtomQ(u):
  3247. return u != x
  3248. elif CalculusQ(u):
  3249. return False
  3250. elif HyperbolicQ(u) and ZeroQ(u.args[0] - v):
  3251. return CoshQ(u) or SechQ(u)
  3252. for i in u.args:
  3253. if Not(PureFunctionOfCoshQ(i, v, x)):
  3254. return False
  3255. return True
  3256. def IntegerQuotientQ(u, v):
  3257. # (* If u/v is an integer, IntegerQuotientQ[u,v] returns True; else it returns False. *)
  3258. return IntegerQ(Simplify(u/v))
  3259. def OddQuotientQ(u, v):
  3260. # (* If u/v is odd, OddQuotientQ[u,v] returns True; else it returns False. *)
  3261. return OddQ(Simplify(u/v))
  3262. def EvenQuotientQ(u, v):
  3263. # (* If u/v is even, EvenQuotientQ[u,v] returns True; else it returns False. *)
  3264. return EvenQ(Simplify(u/v))
  3265. def FindTrigFactor(func1, func2, u, v, flag):
  3266. # (* If func[w]^m is a factor of u where m is odd and w is an integer multiple of v,
  3267. # FindTrigFactor[func1,func2,u,v,True] returns the list {w,u/func[w]^n}; else it returns False. *)
  3268. # (* If func[w]^m is a factor of u where m is odd and w is an integer multiple of v not equal to v,
  3269. # FindTrigFactor[func1,func2,u,v,False] returns the list {w,u/func[w]^n}; else it returns False. *)
  3270. if u == 1:
  3271. return False
  3272. elif (Head(LeadBase(u)) == func1 or Head(LeadBase(u)) == func2) and OddQ(LeadDegree(u)) and IntegerQuotientQ(LeadBase(u).args[0], v) and (flag or NonzeroQ(LeadBase(u).args[0] - v)):
  3273. return [LeadBase[u].args[0], RemainingFactors(u)]
  3274. lst = FindTrigFactor(func1, func2, RemainingFactors(u), v, flag)
  3275. if AtomQ(lst):
  3276. return False
  3277. return [lst[0], LeadFactor(u)*lst[1]]
  3278. def FunctionOfSinhQ(u, v, x):
  3279. # (* If u is a function of Sinh[v], FunctionOfSinhQ[u,v,x] returns True; else it returns False. *)
  3280. if AtomQ(u):
  3281. return u != x
  3282. elif CalculusQ(u):
  3283. return False
  3284. elif HyperbolicQ(u) and IntegerQuotientQ(u.args[0], v):
  3285. if OddQuotientQ(u.args[0], v):
  3286. # (* Basis: If m odd, Sinh[m*v]^n is a function of Sinh[v]. *)
  3287. return SinhQ(u) or CschQ(u)
  3288. # (* Basis: If m even, Cos[m*v]^n is a function of Sinh[v]. *)
  3289. return CoshQ(u) or SechQ(u)
  3290. elif IntegerPowerQ(u):
  3291. if HyperbolicQ(u.base) and IntegerQuotientQ(u.base.args[0], v):
  3292. if EvenQ(u.exp):
  3293. # (* Basis: If m integer and n even, Hyper[m*v]^n is a function of Sinh[v]. *)
  3294. return True
  3295. return FunctionOfSinhQ(u.base, v, x)
  3296. elif ProductQ(u):
  3297. if CoshQ(u.args[0]) and SinhQ(u.args[1]) and ZeroQ(u.args[0].args[0] - v/2) and ZeroQ(u.args[1].args[0] - v/2):
  3298. return FunctionOfSinhQ(Drop(u, 2), v, x)
  3299. lst = FindTrigFactor(Sinh, Csch, u, v, False)
  3300. if ListQ(lst) and EvenQuotientQ(lst[0], v):
  3301. # (* Basis: If m even and n odd, Sinh[m*v]^n == Cosh[v]*u where u is a function of Sinh[v]. *)
  3302. return FunctionOfSinhQ(Cosh(v)*lst[1], v, x)
  3303. lst = FindTrigFactor(Cosh, Sech, u, v, False)
  3304. if ListQ(lst) and OddQuotientQ(lst[0], v):
  3305. # (* Basis: If m odd and n odd, Cosh[m*v]^n == Cosh[v]*u where u is a function of Sinh[v]. *)
  3306. return FunctionOfSinhQ(Cosh(v)*lst[1], v, x)
  3307. lst = FindTrigFactor(Tanh, Coth, u, v, True)
  3308. if ListQ(lst):
  3309. # (* Basis: If m integer and n odd, Tanh[m*v]^n == Cosh[v]*u where u is a function of Sinh[v]. *)
  3310. return FunctionOfSinhQ(Cosh(v)*lst[1], v, x)
  3311. return all(FunctionOfSinhQ(i, v, x) for i in u.args)
  3312. return all(FunctionOfSinhQ(i, v, x) for i in u.args)
  3313. def FunctionOfCoshQ(u, v, x):
  3314. #(* If u is a function of Cosh[v], FunctionOfCoshQ[u,v,x] returns True; else it returns False. *)
  3315. if AtomQ(u):
  3316. return u != x
  3317. elif CalculusQ(u):
  3318. return False
  3319. elif HyperbolicQ(u) and IntegerQuotientQ(u.args[0], v):
  3320. # (* Basis: If m integer, Cosh[m*v]^n is a function of Cosh[v]. *)
  3321. return CoshQ(u) or SechQ(u)
  3322. elif IntegerPowerQ(u):
  3323. if HyperbolicQ(u.base) and IntegerQuotientQ(u.base.args[0], v):
  3324. if EvenQ(u.exp):
  3325. # (* Basis: If m integer and n even, Hyper[m*v]^n is a function of Cosh[v]. *)
  3326. return True
  3327. return FunctionOfCoshQ(u.base, v, x)
  3328. elif ProductQ(u):
  3329. lst = FindTrigFactor(Sinh, Csch, u, v, False)
  3330. if ListQ(lst):
  3331. # (* Basis: If m integer and n odd, Sinh[m*v]^n == Sinh[v]*u where u is a function of Cosh[v]. *)
  3332. return FunctionOfCoshQ(Sinh(v)*lst[1], v, x)
  3333. lst = FindTrigFactor(Tanh, Coth, u, v, True)
  3334. if ListQ(lst):
  3335. # (* Basis: If m integer and n odd, Tanh[m*v]^n == Sinh[v]*u where u is a function of Cosh[v]. *)
  3336. return FunctionOfCoshQ(Sinh(v)*lst[1], v, x)
  3337. return all(FunctionOfCoshQ(i, v, x) for i in u.args)
  3338. return all(FunctionOfCoshQ(i, v, x) for i in u.args)
  3339. def OddHyperbolicPowerQ(u, v, x):
  3340. if SinhQ(u) or CoshQ(u) or SechQ(u) or CschQ(u):
  3341. return OddQuotientQ(u.args[0], v)
  3342. if PowerQ(u):
  3343. return OddQ(u.exp) and OddHyperbolicPowerQ(u.base, v, x)
  3344. if ProductQ(u):
  3345. if Not(EqQ(FreeFactors(u, x), 1)):
  3346. return OddHyperbolicPowerQ(NonfreeFactors(u, x), v, x)
  3347. lst = []
  3348. for i in u.args:
  3349. if Not(FunctionOfTanhQ(i, v, x)):
  3350. lst.append(i)
  3351. if lst == []:
  3352. return True
  3353. return Length(lst)==1 and OddHyperbolicPowerQ(lst[0], v, x)
  3354. if SumQ(u):
  3355. return all(OddHyperbolicPowerQ(i, v, x) for i in u.args)
  3356. return False
  3357. def FunctionOfTanhQ(u, v, x):
  3358. #(* If u is a function of the form f[Tanh[v],Coth[v]] where f is independent of x,
  3359. # FunctionOfTanhQ[u,v,x] returns True; else it returns False. *)
  3360. if AtomQ(u):
  3361. return u != x
  3362. elif CalculusQ(u):
  3363. return False
  3364. elif HyperbolicQ(u) and IntegerQuotientQ(u.args[0], v):
  3365. return TanhQ(u) or CothQ(u) or EvenQuotientQ(u.args[0], v)
  3366. elif PowerQ(u):
  3367. if EvenQ(u.exp) and HyperbolicQ(u.base) and IntegerQuotientQ(u.base.args[0], v):
  3368. return True
  3369. elif EvenQ(u.args[1]) and SumQ(u.args[0]):
  3370. return FunctionOfTanhQ(Expand(u.args[0]**2, v, x))
  3371. if ProductQ(u):
  3372. lst = []
  3373. for i in u.args:
  3374. if Not(FunctionOfTanhQ(i, v, x)):
  3375. lst.append(i)
  3376. if lst == []:
  3377. return True
  3378. return Length(lst)==2 and OddHyperbolicPowerQ(lst[0], v, x) and OddHyperbolicPowerQ(lst[1], v, x)
  3379. return all(FunctionOfTanhQ(i, v, x) for i in u.args)
  3380. def FunctionOfTanhWeight(u, v, x):
  3381. """
  3382. u is a function of the form f(tanh(v), coth(v)) where f is independent of x.
  3383. FunctionOfTanhWeight(u, v, x) returns a nonnegative number if u is best considered a function of tanh(v), else it returns a negative number.
  3384. Examples
  3385. ========
  3386. >>> from sympy import sinh, log, tanh
  3387. >>> from sympy.abc import x
  3388. >>> from sympy.integrals.rubi.utility_function import FunctionOfTanhWeight
  3389. >>> FunctionOfTanhWeight(x, log(x), x)
  3390. 0
  3391. >>> FunctionOfTanhWeight(sinh(log(x)), log(x), x)
  3392. 0
  3393. >>> FunctionOfTanhWeight(tanh(log(x)), log(x), x)
  3394. 1
  3395. """
  3396. if AtomQ(u):
  3397. return S(0)
  3398. elif CalculusQ(u):
  3399. return S(0)
  3400. elif HyperbolicQ(u) and IntegerQuotientQ(u.args[0], v):
  3401. if TanhQ(u) and ZeroQ(u.args[0] - v):
  3402. return S(1)
  3403. elif CothQ(u) and ZeroQ(u.args[0] - v):
  3404. return S(-1)
  3405. return S(0)
  3406. elif PowerQ(u):
  3407. if EvenQ(u.exp) and HyperbolicQ(u.base) and IntegerQuotientQ(u.base.args[0], v):
  3408. if TanhQ(u.base) or CoshQ(u.base) or SechQ(u.base):
  3409. return S(1)
  3410. return S(-1)
  3411. if ProductQ(u):
  3412. if all(FunctionOfTanhQ(i, v, x) for i in u.args):
  3413. return Add(*[FunctionOfTanhWeight(i, v, x) for i in u.args])
  3414. return S(0)
  3415. return Add(*[FunctionOfTanhWeight(i, v, x) for i in u.args])
  3416. def FunctionOfHyperbolicQ(u, v, x):
  3417. # (* If u (x) is equivalent to a function of the form f (Sinh[v],Cosh[v],Tanh[v],Coth[v],Sech[v],Csch[v])
  3418. # where f is independent of x, FunctionOfHyperbolicQ[u,v,x] returns True; else it returns False. *)
  3419. if AtomQ(u):
  3420. return u != x
  3421. elif CalculusQ(u):
  3422. return False
  3423. elif HyperbolicQ(u) and IntegerQuotientQ(u.args[0], v):
  3424. return True
  3425. return all(FunctionOfHyperbolicQ(i, v, x) for i in u.args)
  3426. def SmartNumerator(expr):
  3427. if PowerQ(expr):
  3428. n = expr.exp
  3429. u = expr.base
  3430. if RationalQ(n) and n < 0:
  3431. return SmartDenominator(u**(-n))
  3432. elif ProductQ(expr):
  3433. return Mul(*[SmartNumerator(i) for i in expr.args])
  3434. return Numerator(expr)
  3435. def SmartDenominator(expr):
  3436. if PowerQ(expr):
  3437. u = expr.base
  3438. n = expr.exp
  3439. if RationalQ(n) and n < 0:
  3440. return SmartNumerator(u**(-n))
  3441. elif ProductQ(expr):
  3442. return Mul(*[SmartDenominator(i) for i in expr.args])
  3443. return Denominator(expr)
  3444. def ActivateTrig(u):
  3445. return u
  3446. def ExpandTrig(*args):
  3447. if len(args) == 2:
  3448. u, x = args
  3449. return ActivateTrig(ExpandIntegrand(u, x))
  3450. u, v, x = args
  3451. w = ExpandTrig(v, x)
  3452. z = ActivateTrig(u)
  3453. if SumQ(w):
  3454. return w.func(*[z*i for i in w.args])
  3455. return z*w
  3456. def TrigExpand(u):
  3457. return expand_trig(u)
  3458. # SubstForTrig[u_,sin_,cos_,v_,x_] :=
  3459. # If[AtomQ[u],
  3460. # u,
  3461. # If[TrigQ[u] && IntegerQuotientQ[u[[1]],v],
  3462. # If[u[[1]]===v || ZeroQ[u[[1]]-v],
  3463. # If[SinQ[u],
  3464. # sin,
  3465. # If[CosQ[u],
  3466. # cos,
  3467. # If[TanQ[u],
  3468. # sin/cos,
  3469. # If[CotQ[u],
  3470. # cos/sin,
  3471. # If[SecQ[u],
  3472. # 1/cos,
  3473. # 1/sin]]]]],
  3474. # Map[Function[SubstForTrig[#,sin,cos,v,x]],
  3475. # ReplaceAll[TrigExpand[Head[u][Simplify[u[[1]]/v]*x]],x->v]]],
  3476. # If[ProductQ[u] && CosQ[u[[1]]] && SinQ[u[[2]]] && ZeroQ[u[[1,1]]-v/2] && ZeroQ[u[[2,1]]-v/2],
  3477. # sin/2*SubstForTrig[Drop[u,2],sin,cos,v,x],
  3478. # Map[Function[SubstForTrig[#,sin,cos,v,x]],u]]]]
  3479. def SubstForTrig(u, sin_ , cos_, v, x):
  3480. # (* u (v) is an expression of the form f (Sin[v],Cos[v],Tan[v],Cot[v],Sec[v],Csc[v]). *)
  3481. # (* SubstForTrig[u,sin,cos,v,x] returns the expression f (sin,cos,sin/cos,cos/sin,1/cos,1/sin). *)
  3482. if AtomQ(u):
  3483. return u
  3484. elif TrigQ(u) and IntegerQuotientQ(u.args[0], v):
  3485. if u.args[0] == v or ZeroQ(u.args[0] - v):
  3486. if SinQ(u):
  3487. return sin_
  3488. elif CosQ(u):
  3489. return cos_
  3490. elif TanQ(u):
  3491. return sin_/cos_
  3492. elif CotQ(u):
  3493. return cos_/sin_
  3494. elif SecQ(u):
  3495. return 1/cos_
  3496. return 1/sin_
  3497. r = ReplaceAll(TrigExpand(Head(u)(Simplify(u.args[0]/v*x))), {x: v})
  3498. return r.func(*[SubstForTrig(i, sin_, cos_, v, x) for i in r.args])
  3499. if ProductQ(u) and CosQ(u.args[0]) and SinQ(u.args[1]) and ZeroQ(u.args[0].args[0] - v/2) and ZeroQ(u.args[1].args[0] - v/2):
  3500. return sin(x)/2*SubstForTrig(Drop(u, 2), sin_, cos_, v, x)
  3501. return u.func(*[SubstForTrig(i, sin_, cos_, v, x) for i in u.args])
  3502. def SubstForHyperbolic(u, sinh_, cosh_, v, x):
  3503. # (* u (v) is an expression of the form f (Sinh[v],Cosh[v],Tanh[v],Coth[v],Sech[v],Csch[v]). *)
  3504. # (* SubstForHyperbolic[u,sinh,cosh,v,x] returns the expression
  3505. # f (sinh,cosh,sinh/cosh,cosh/sinh,1/cosh,1/sinh). *)
  3506. if AtomQ(u):
  3507. return u
  3508. elif HyperbolicQ(u) and IntegerQuotientQ(u.args[0], v):
  3509. if u.args[0] == v or ZeroQ(u.args[0] - v):
  3510. if SinhQ(u):
  3511. return sinh_
  3512. elif CoshQ(u):
  3513. return cosh_
  3514. elif TanhQ(u):
  3515. return sinh_/cosh_
  3516. elif CothQ(u):
  3517. return cosh_/sinh_
  3518. if SechQ(u):
  3519. return 1/cosh_
  3520. return 1/sinh_
  3521. r = ReplaceAll(TrigExpand(Head(u)(Simplify(u.args[0]/v)*x)), {x: v})
  3522. return r.func(*[SubstForHyperbolic(i, sinh_, cosh_, v, x) for i in r.args])
  3523. elif ProductQ(u) and CoshQ(u.args[0]) and SinhQ(u.args[1]) and ZeroQ(u.args[0].args[0] - v/2) and ZeroQ(u.args[1].args[0] - v/2):
  3524. return sinh(x)/2*SubstForHyperbolic(Drop(u, 2), sinh_, cosh_, v, x)
  3525. return u.func(*[SubstForHyperbolic(i, sinh_, cosh_, v, x) for i in u.args])
  3526. def InertTrigFreeQ(u):
  3527. return FreeQ(u, sin) and FreeQ(u, cos) and FreeQ(u, tan) and FreeQ(u, cot) and FreeQ(u, sec) and FreeQ(u, csc)
  3528. def LCM(a, b):
  3529. return lcm(a, b)
  3530. def SubstForFractionalPowerOfLinear(u, x):
  3531. # (* If u has a subexpression of the form (a+b*x)^(m/n) where m and n>1 are integers,
  3532. # SubstForFractionalPowerOfLinear[u,x] returns the list {v,n,a+b*x,1/b} where v is u
  3533. # with subexpressions of the form (a+b*x)^(m/n) replaced by x^m and x replaced
  3534. # by -a/b+x^n/b, and all times x^(n-1); else it returns False. *)
  3535. lst = FractionalPowerOfLinear(u, S(1), False, x)
  3536. if AtomQ(lst) or FalseQ(lst[1]):
  3537. return False
  3538. n = lst[0]
  3539. a = Coefficient(lst[1], x, 0)
  3540. b = Coefficient(lst[1], x, 1)
  3541. tmp = Simplify(x**(n-1)*SubstForFractionalPower(u, lst[1], n, -a/b + x**n/b, x))
  3542. return [NonfreeFactors(tmp, x), n, lst[1], FreeFactors(tmp, x)/b]
  3543. def FractionalPowerOfLinear(u, n, v, x):
  3544. # If u has a subexpression of the form (a + b*x)**(m/n), FractionalPowerOfLinear(u, 1, False, x) returns [n, a + b*x], else it returns False.
  3545. if AtomQ(u) or FreeQ(u, x):
  3546. return [n, v]
  3547. elif CalculusQ(u):
  3548. return False
  3549. elif FractionalPowerQ(u):
  3550. if LinearQ(u.base, x) and (FalseQ(v) or ZeroQ(u.base - v)):
  3551. return [LCM(Denominator(u.exp), n), u.base]
  3552. lst = [n, v]
  3553. for i in u.args:
  3554. lst = FractionalPowerOfLinear(i, lst[0], lst[1], x)
  3555. if AtomQ(lst):
  3556. return False
  3557. return lst
  3558. def InverseFunctionOfLinear(u, x):
  3559. # (* If u has a subexpression of the form g[a+b*x] where g is an inverse function,
  3560. # InverseFunctionOfLinear[u,x] returns g[a+b*x]; else it returns False. *)
  3561. if AtomQ(u) or CalculusQ(u) or FreeQ(u, x):
  3562. return False
  3563. elif InverseFunctionQ(u) and LinearQ(u.args[0], x):
  3564. return u
  3565. for i in u.args:
  3566. tmp = InverseFunctionOfLinear(i, x)
  3567. if Not(AtomQ(tmp)):
  3568. return tmp
  3569. return False
  3570. def InertTrigQ(*args):
  3571. if len(args) == 1:
  3572. f = args[0]
  3573. l = [sin,cos,tan,cot,sec,csc]
  3574. return any(Head(f) == i for i in l)
  3575. elif len(args) == 2:
  3576. f, g = args
  3577. if f == g:
  3578. return InertTrigQ(f)
  3579. return InertReciprocalQ(f, g) or InertReciprocalQ(g, f)
  3580. else:
  3581. f, g, h = args
  3582. return InertTrigQ(g, f) and InertTrigQ(g, h)
  3583. def InertReciprocalQ(f, g):
  3584. return (f.func == sin and g.func == csc) or (f.func == cos and g.func == sec) or (f.func == tan and g.func == cot)
  3585. def DeactivateTrig(u, x):
  3586. # (* u is a function of trig functions of a linear function of x. *)
  3587. # (* DeactivateTrig[u,x] returns u with the trig functions replaced with inert trig functions. *)
  3588. return FixInertTrigFunction(DeactivateTrigAux(u, x), x)
  3589. def FixInertTrigFunction(u, x):
  3590. return u
  3591. def DeactivateTrigAux(u, x):
  3592. if AtomQ(u):
  3593. return u
  3594. elif TrigQ(u) and LinearQ(u.args[0], x):
  3595. v = ExpandToSum(u.args[0], x)
  3596. if SinQ(u):
  3597. return sin(v)
  3598. elif CosQ(u):
  3599. return cos(v)
  3600. elif TanQ(u):
  3601. return tan(u)
  3602. elif CotQ(u):
  3603. return cot(v)
  3604. elif SecQ(u):
  3605. return sec(v)
  3606. return csc(v)
  3607. elif HyperbolicQ(u) and LinearQ(u.args[0], x):
  3608. v = ExpandToSum(I*u.args[0], x)
  3609. if SinhQ(u):
  3610. return -I*sin(v)
  3611. elif CoshQ(u):
  3612. return cos(v)
  3613. elif TanhQ(u):
  3614. return -I*tan(v)
  3615. elif CothQ(u):
  3616. I*cot(v)
  3617. elif SechQ(u):
  3618. return sec(v)
  3619. return I*csc(v)
  3620. return u.func(*[DeactivateTrigAux(i, x) for i in u.args])
  3621. def PowerOfInertTrigSumQ(u, func, x):
  3622. p_ = Wild('p', exclude=[x])
  3623. q_ = Wild('q', exclude=[x])
  3624. a_ = Wild('a', exclude=[x])
  3625. b_ = Wild('b', exclude=[x])
  3626. c_ = Wild('c', exclude=[x])
  3627. d_ = Wild('d', exclude=[x])
  3628. n_ = Wild('n', exclude=[x])
  3629. w_ = Wild('w')
  3630. pattern = (a_ + b_*(c_*func(w_))**p_)**n_
  3631. match = u.match(pattern)
  3632. if match:
  3633. keys = [a_, b_, c_, n_, p_, w_]
  3634. if len(keys) == len(match):
  3635. return True
  3636. pattern = (a_ + b_*(d_*func(w_))**p_ + c_*(d_*func(w_))**q_)**n_
  3637. match = u.match(pattern)
  3638. if match:
  3639. keys = [a_, b_, c_, d_, n_, p_, q_, w_]
  3640. if len(keys) == len(match):
  3641. return True
  3642. return False
  3643. def PiecewiseLinearQ(*args):
  3644. # (* If the derivative of u wrt x is a constant wrt x, PiecewiseLinearQ[u,x] returns True;
  3645. # else it returns False. *)
  3646. if len(args) == 3:
  3647. u, v, x = args
  3648. return PiecewiseLinearQ(u, x) and PiecewiseLinearQ(v, x)
  3649. u, x = args
  3650. if LinearQ(u, x):
  3651. return True
  3652. c_ = Wild('c', exclude=[x])
  3653. F_ = Wild('F', exclude=[x])
  3654. v_ = Wild('v')
  3655. match = u.match(Log(c_*F_**v_))
  3656. if match:
  3657. if len(match) == 3:
  3658. if LinearQ(match[v_], x):
  3659. return True
  3660. try:
  3661. F = type(u)
  3662. G = type(u.args[0])
  3663. v = u.args[0].args[0]
  3664. if LinearQ(v, x):
  3665. if MemberQ([[atanh, tanh], [atanh, coth], [acoth, coth], [acoth, tanh], [atan, tan], [atan, cot], [acot, cot], [acot, tan]], [F, G]):
  3666. return True
  3667. except:
  3668. pass
  3669. return False
  3670. def KnownTrigIntegrandQ(lst, u, x):
  3671. if u == 1:
  3672. return True
  3673. a_ = Wild('a', exclude=[x])
  3674. b_ = Wild('b', exclude=[x, 0])
  3675. func_ = WildFunction('func')
  3676. m_ = Wild('m', exclude=[x])
  3677. A_ = Wild('A', exclude=[x])
  3678. B_ = Wild('B', exclude=[x, 0])
  3679. C_ = Wild('C', exclude=[x, 0])
  3680. match = u.match((a_ + b_*func_)**m_)
  3681. if match:
  3682. func = match[func_]
  3683. if LinearQ(func.args[0], x) and MemberQ(lst, func.func):
  3684. return True
  3685. match = u.match((a_ + b_*func_)**m_*(A_ + B_*func_))
  3686. if match:
  3687. func = match[func_]
  3688. if LinearQ(func.args[0], x) and MemberQ(lst, func.func):
  3689. return True
  3690. match = u.match(A_ + C_*func_**2)
  3691. if match:
  3692. func = match[func_]
  3693. if LinearQ(func.args[0], x) and MemberQ(lst, func.func):
  3694. return True
  3695. match = u.match(A_ + B_*func_ + C_*func_**2)
  3696. if match:
  3697. func = match[func_]
  3698. if LinearQ(func.args[0], x) and MemberQ(lst, func.func):
  3699. return True
  3700. match = u.match((a_ + b_*func_)**m_*(A_ + C_*func_**2))
  3701. if match:
  3702. func = match[func_]
  3703. if LinearQ(func.args[0], x) and MemberQ(lst, func.func):
  3704. return True
  3705. match = u.match((a_ + b_*func_)**m_*(A_ + B_*func_ + C_*func_**2))
  3706. if match:
  3707. func = match[func_]
  3708. if LinearQ(func.args[0], x) and MemberQ(lst, func.func):
  3709. return True
  3710. return False
  3711. def KnownSineIntegrandQ(u, x):
  3712. return KnownTrigIntegrandQ([sin, cos], u, x)
  3713. def KnownTangentIntegrandQ(u, x):
  3714. return KnownTrigIntegrandQ([tan], u, x)
  3715. def KnownCotangentIntegrandQ(u, x):
  3716. return KnownTrigIntegrandQ([cot], u, x)
  3717. def KnownSecantIntegrandQ(u, x):
  3718. return KnownTrigIntegrandQ([sec, csc], u, x)
  3719. def TryPureTanSubst(u, x):
  3720. a_ = Wild('a', exclude=[x])
  3721. b_ = Wild('b', exclude=[x])
  3722. c_ = Wild('c', exclude=[x])
  3723. G_ = Wild('G')
  3724. F = u.func
  3725. try:
  3726. if MemberQ([atan, acot, atanh, acoth], F):
  3727. match = u.args[0].match(c_*(a_ + b_*G_))
  3728. if match:
  3729. if len(match) == 4:
  3730. G = match[G_]
  3731. if MemberQ([tan, cot, tanh, coth], G.func):
  3732. if LinearQ(G.args[0], x):
  3733. return True
  3734. except:
  3735. pass
  3736. return False
  3737. def TryTanhSubst(u, x):
  3738. if LogQ(u):
  3739. return False
  3740. elif not FalseQ(FunctionOfLinear(u, x)):
  3741. return False
  3742. a_ = Wild('a', exclude=[x])
  3743. m_ = Wild('m', exclude=[x])
  3744. p_ = Wild('p', exclude=[x])
  3745. r_, s_, t_, n_, b_, f_, g_ = map(Wild, 'rstnbfg')
  3746. match = u.match(r_*(s_ + t_)**n_)
  3747. if match:
  3748. if len(match) == 4:
  3749. r, s, t, n = [match[i] for i in [r_, s_, t_, n_]]
  3750. if IntegerQ(n) and PositiveQ(n):
  3751. return False
  3752. match = u.match(1/(a_ + b_*f_**n_))
  3753. if match:
  3754. if len(match) == 4:
  3755. a, b, f, n = [match[i] for i in [a_, b_, f_, n_]]
  3756. if SinhCoshQ(f) and IntegerQ(n) and n > 2:
  3757. return False
  3758. match = u.match(f_*g_)
  3759. if match:
  3760. if len(match) == 2:
  3761. f, g = match[f_], match[g_]
  3762. if SinhCoshQ(f) and SinhCoshQ(g):
  3763. if IntegersQ(f.args[0]/x, g.args[0]/x):
  3764. return False
  3765. match = u.match(r_*(a_*s_**m_)**p_)
  3766. if match:
  3767. if len(match) == 5:
  3768. r, a, s, m, p = [match[i] for i in [r_, a_, s_, m_, p_]]
  3769. if Not(m==2 and (s == Sech(x) or s == Csch(x))):
  3770. return False
  3771. if u != ExpandIntegrand(u, x):
  3772. return False
  3773. return True
  3774. def TryPureTanhSubst(u, x):
  3775. F = u.func
  3776. a_ = Wild('a', exclude=[x])
  3777. G_ = Wild('G')
  3778. if F == sym_log:
  3779. return False
  3780. match = u.args[0].match(a_*G_)
  3781. if match and len(match) == 2:
  3782. G = match[G_].func
  3783. if MemberQ([atanh, acoth], F) and MemberQ([tanh, coth], G):
  3784. return False
  3785. if u != ExpandIntegrand(u, x):
  3786. return False
  3787. return True
  3788. def AbsurdNumberGCD(*seq):
  3789. # (* m, n, ... must be absurd numbers. AbsurdNumberGCD[m,n,...] returns the gcd of m, n, ... *)
  3790. lst = list(seq)
  3791. if Length(lst) == 1:
  3792. return First(lst)
  3793. return AbsurdNumberGCDList(FactorAbsurdNumber(First(lst)), FactorAbsurdNumber(AbsurdNumberGCD(*Rest(lst))))
  3794. def AbsurdNumberGCDList(lst1, lst2):
  3795. # (* lst1 and lst2 must be absurd number prime factorization lists. *)
  3796. # (* AbsurdNumberGCDList[lst1,lst2] returns the gcd of the absurd numbers represented by lst1 and lst2. *)
  3797. if lst1 == []:
  3798. return Mul(*[i[0]**Min(i[1],0) for i in lst2])
  3799. elif lst2 == []:
  3800. return Mul(*[i[0]**Min(i[1],0) for i in lst1])
  3801. elif lst1[0][0] == lst2[0][0]:
  3802. if lst1[0][1] <= lst2[0][1]:
  3803. return lst1[0][0]**lst1[0][1]*AbsurdNumberGCDList(Rest(lst1), Rest(lst2))
  3804. return lst1[0][0]**lst2[0][1]*AbsurdNumberGCDList(Rest(lst1), Rest(lst2))
  3805. elif lst1[0][0] < lst2[0][0]:
  3806. if lst1[0][1] < 0:
  3807. return lst1[0][0]**lst1[0][1]*AbsurdNumberGCDList(Rest(lst1), lst2)
  3808. return AbsurdNumberGCDList(Rest(lst1), lst2)
  3809. elif lst2[0][1] < 0:
  3810. return lst2[0][0]**lst2[0][1]*AbsurdNumberGCDList(lst1, Rest(lst2))
  3811. return AbsurdNumberGCDList(lst1, Rest(lst2))
  3812. def ExpandTrigExpand(u, F, v, m, n, x):
  3813. w = Expand(TrigExpand(F.xreplace({x: n*x}))**m).xreplace({x: v})
  3814. if SumQ(w):
  3815. t = 0
  3816. for i in w.args:
  3817. t += u*i
  3818. return t
  3819. else:
  3820. return u*w
  3821. def ExpandTrigReduce(*args):
  3822. if len(args) == 3:
  3823. u = args[0]
  3824. v = args[1]
  3825. x = args[2]
  3826. w = ExpandTrigReduce(v, x)
  3827. if SumQ(w):
  3828. t = 0
  3829. for i in w.args:
  3830. t += u*i
  3831. return t
  3832. else:
  3833. return u*w
  3834. else:
  3835. u = args[0]
  3836. x = args[1]
  3837. return ExpandTrigReduceAux(u, x)
  3838. def ExpandTrigReduceAux(u, x):
  3839. v = TrigReduce(u).expand()
  3840. if SumQ(v):
  3841. t = 0
  3842. for i in v.args:
  3843. t += NormalizeTrig(i, x)
  3844. return t
  3845. return NormalizeTrig(v, x)
  3846. def NormalizeTrig(v, x):
  3847. a = Wild('a', exclude=[x])
  3848. n = Wild('n', exclude=[x, 0])
  3849. F = Wild('F')
  3850. expr = a*F**n
  3851. M = v.match(expr)
  3852. if M and len(M[F].args) == 1 and PolynomialQ(M[F].args[0], x) and Exponent(M[F].args[0], x) > 0:
  3853. u = M[F].args[0]
  3854. return M[a]*M[F].xreplace({u: ExpandToSum(u, x)})**M[n]
  3855. else:
  3856. return v
  3857. #=================================
  3858. def TrigToExp(expr):
  3859. ex = expr.rewrite(sin, sym_exp).rewrite(cos, sym_exp).rewrite(tan, sym_exp).rewrite(sec, sym_exp).rewrite(csc, sym_exp).rewrite(cot, sym_exp)
  3860. return ex.replace(sym_exp, rubi_exp)
  3861. def ExpandTrigToExp(u, *args):
  3862. if len(args) == 1:
  3863. x = args[0]
  3864. return ExpandTrigToExp(1, u, x)
  3865. else:
  3866. v = args[0]
  3867. x = args[1]
  3868. w = TrigToExp(v)
  3869. k = 0
  3870. if SumQ(w):
  3871. for i in w.args:
  3872. k += SimplifyIntegrand(u*i, x)
  3873. w = k
  3874. else:
  3875. w = SimplifyIntegrand(u*w, x)
  3876. return ExpandIntegrand(FreeFactors(w, x), NonfreeFactors(w, x),x)
  3877. #======================================
  3878. def TrigReduce(i):
  3879. """
  3880. TrigReduce(expr) rewrites products and powers of trigonometric functions in expr in terms of trigonometric functions with combined arguments.
  3881. Examples
  3882. ========
  3883. >>> from sympy import sin, cos
  3884. >>> from sympy.integrals.rubi.utility_function import TrigReduce
  3885. >>> from sympy.abc import x
  3886. >>> TrigReduce(cos(x)**2)
  3887. cos(2*x)/2 + 1/2
  3888. >>> TrigReduce(cos(x)**2*sin(x))
  3889. sin(x)/4 + sin(3*x)/4
  3890. >>> TrigReduce(cos(x)**2+sin(x))
  3891. sin(x) + cos(2*x)/2 + 1/2
  3892. """
  3893. if SumQ(i):
  3894. t = 0
  3895. for k in i.args:
  3896. t += TrigReduce(k)
  3897. return t
  3898. if ProductQ(i):
  3899. if any(PowerQ(k) for k in i.args):
  3900. if (i.rewrite((sin, sinh), sym_exp).rewrite((cos, cosh), sym_exp).expand().rewrite(sym_exp, sin)).has(I, cosh, sinh):
  3901. return i.rewrite((sin, sinh), sym_exp).rewrite((cos, cosh), sym_exp).expand().rewrite(sym_exp, sin).simplify()
  3902. else:
  3903. return i.rewrite((sin, sinh), sym_exp).rewrite((cos, cosh), sym_exp).expand().rewrite(sym_exp, sin)
  3904. else:
  3905. a = Wild('a')
  3906. b = Wild('b')
  3907. v = Wild('v')
  3908. Match = i.match(v*sin(a)*cos(b))
  3909. if Match:
  3910. a = Match[a]
  3911. b = Match[b]
  3912. v = Match[v]
  3913. return i.subs(v*sin(a)*cos(b), v*S(1)/2*(sin(a + b) + sin(a - b)))
  3914. Match = i.match(v*sin(a)*sin(b))
  3915. if Match:
  3916. a = Match[a]
  3917. b = Match[b]
  3918. v = Match[v]
  3919. return i.subs(v*sin(a)*sin(b), v*S(1)/2*cos(a - b) - cos(a + b))
  3920. Match = i.match(v*cos(a)*cos(b))
  3921. if Match:
  3922. a = Match[a]
  3923. b = Match[b]
  3924. v = Match[v]
  3925. return i.subs(v*cos(a)*cos(b), v*S(1)/2*cos(a + b) + cos(a - b))
  3926. Match = i.match(v*sinh(a)*cosh(b))
  3927. if Match:
  3928. a = Match[a]
  3929. b = Match[b]
  3930. v = Match[v]
  3931. return i.subs(v*sinh(a)*cosh(b), v*S(1)/2*(sinh(a + b) + sinh(a - b)))
  3932. Match = i.match(v*sinh(a)*sinh(b))
  3933. if Match:
  3934. a = Match[a]
  3935. b = Match[b]
  3936. v = Match[v]
  3937. return i.subs(v*sinh(a)*sinh(b), v*S(1)/2*cosh(a - b) - cosh(a + b))
  3938. Match = i.match(v*cosh(a)*cosh(b))
  3939. if Match:
  3940. a = Match[a]
  3941. b = Match[b]
  3942. v = Match[v]
  3943. return i.subs(v*cosh(a)*cosh(b), v*S(1)/2*cosh(a + b) + cosh(a - b))
  3944. if PowerQ(i):
  3945. if i.has(sin, sinh):
  3946. if (i.rewrite((sin, sinh), sym_exp).expand().rewrite(sym_exp, sin)).has(I, cosh, sinh):
  3947. return i.rewrite((sin, sinh), sym_exp).expand().rewrite(sym_exp, sin).simplify()
  3948. else:
  3949. return i.rewrite((sin, sinh), sym_exp).expand().rewrite(sym_exp, sin)
  3950. if i.has(cos, cosh):
  3951. if (i.rewrite((cos, cosh), sym_exp).expand().rewrite(sym_exp, cos)).has(I, cosh, sinh):
  3952. return i.rewrite((cos, cosh), sym_exp).expand().rewrite(sym_exp, cos).simplify()
  3953. else:
  3954. return i.rewrite((cos, cosh), sym_exp).expand().rewrite(sym_exp, cos)
  3955. return i
  3956. def FunctionOfTrig(u, *args):
  3957. # If u is a function of trig functions of v where v is a linear function of x,
  3958. # FunctionOfTrig[u,x] returns v; else it returns False.
  3959. if len(args) == 1:
  3960. x = args[0]
  3961. v = FunctionOfTrig(u, None, x)
  3962. if v:
  3963. return v
  3964. else:
  3965. return False
  3966. else:
  3967. v, x = args
  3968. if AtomQ(u):
  3969. if u == x:
  3970. return False
  3971. else:
  3972. return v
  3973. if TrigQ(u) and LinearQ(u.args[0], x):
  3974. if v is None:
  3975. return u.args[0]
  3976. else:
  3977. a = Coefficient(v, x, 0)
  3978. b = Coefficient(v, x, 1)
  3979. c = Coefficient(u.args[0], x, 0)
  3980. d = Coefficient(u.args[0], x, 1)
  3981. if ZeroQ(a*d - b*c) and RationalQ(b/d):
  3982. return a/Numerator(b/d) + b*x/Numerator(b/d)
  3983. else:
  3984. return False
  3985. if HyperbolicQ(u) and LinearQ(u.args[0], x):
  3986. if v is None:
  3987. return I*u.args[0]
  3988. a = Coefficient(v, x, 0)
  3989. b = Coefficient(v, x, 1)
  3990. c = I*Coefficient(u.args[0], x, 0)
  3991. d = I*Coefficient(u.args[0], x, 1)
  3992. if ZeroQ(a*d - b*c) and RationalQ(b/d):
  3993. return a/Numerator(b/d) + b*x/Numerator(b/d)
  3994. else:
  3995. return False
  3996. if CalculusQ(u):
  3997. return False
  3998. else:
  3999. w = v
  4000. for i in u.args:
  4001. w = FunctionOfTrig(i, w, x)
  4002. if FalseQ(w):
  4003. return False
  4004. return w
  4005. def AlgebraicTrigFunctionQ(u, x):
  4006. # If u is algebraic function of trig functions, AlgebraicTrigFunctionQ(u,x) returns True; else it returns False.
  4007. if AtomQ(u):
  4008. return True
  4009. elif TrigQ(u) and LinearQ(u.args[0], x):
  4010. return True
  4011. elif HyperbolicQ(u) and LinearQ(u.args[0], x):
  4012. return True
  4013. elif PowerQ(u):
  4014. if FreeQ(u.exp, x):
  4015. return AlgebraicTrigFunctionQ(u.base, x)
  4016. elif ProductQ(u) or SumQ(u):
  4017. for i in u.args:
  4018. if not AlgebraicTrigFunctionQ(i, x):
  4019. return False
  4020. return True
  4021. return False
  4022. def FunctionOfHyperbolic(u, *x):
  4023. # If u is a function of hyperbolic trig functions of v where v is linear in x,
  4024. # FunctionOfHyperbolic(u,x) returns v; else it returns False.
  4025. if len(x) == 1:
  4026. x = x[0]
  4027. v = FunctionOfHyperbolic(u, None, x)
  4028. if v is None:
  4029. return False
  4030. else:
  4031. return v
  4032. else:
  4033. v = x[0]
  4034. x = x[1]
  4035. if AtomQ(u):
  4036. if u == x:
  4037. return False
  4038. return v
  4039. if HyperbolicQ(u) and LinearQ(u.args[0], x):
  4040. if v is None:
  4041. return u.args[0]
  4042. a = Coefficient(v, x, 0)
  4043. b = Coefficient(v, x, 1)
  4044. c = Coefficient(u.args[0], x, 0)
  4045. d = Coefficient(u.args[0], x, 1)
  4046. if ZeroQ(a*d - b*c) and RationalQ(b/d):
  4047. return a/Numerator(b/d) + b*x/Numerator(b/d)
  4048. else:
  4049. return False
  4050. if CalculusQ(u):
  4051. return False
  4052. w = v
  4053. for i in u.args:
  4054. if w == FunctionOfHyperbolic(i, w, x):
  4055. return False
  4056. return w
  4057. def FunctionOfQ(v, u, x, PureFlag=False):
  4058. # v is a function of x. If u is a function of v, FunctionOfQ(v, u, x) returns True; else it returns False. *)
  4059. if FreeQ(u, x):
  4060. return False
  4061. elif AtomQ(v):
  4062. return True
  4063. elif ProductQ(v) and Not(EqQ(FreeFactors(v, x), 1)):
  4064. return FunctionOfQ(NonfreeFactors(v, x), u, x, PureFlag)
  4065. elif PureFlag:
  4066. if SinQ(v) or CscQ(v):
  4067. return PureFunctionOfSinQ(u, v.args[0], x)
  4068. elif CosQ(v) or SecQ(v):
  4069. return PureFunctionOfCosQ(u, v.args[0], x)
  4070. elif TanQ(v):
  4071. return PureFunctionOfTanQ(u, v.args[0], x)
  4072. elif CotQ(v):
  4073. return PureFunctionOfCotQ(u, v.args[0], x)
  4074. elif SinhQ(v) or CschQ(v):
  4075. return PureFunctionOfSinhQ(u, v.args[0], x)
  4076. elif CoshQ(v) or SechQ(v):
  4077. return PureFunctionOfCoshQ(u, v.args[0], x)
  4078. elif TanhQ(v):
  4079. return PureFunctionOfTanhQ(u, v.args[0], x)
  4080. elif CothQ(v):
  4081. return PureFunctionOfCothQ(u, v.args[0], x)
  4082. else:
  4083. return FunctionOfExpnQ(u, v, x) != False
  4084. elif SinQ(v) or CscQ(v):
  4085. return FunctionOfSinQ(u, v.args[0], x)
  4086. elif CosQ(v) or SecQ(v):
  4087. return FunctionOfCosQ(u, v.args[0], x)
  4088. elif TanQ(v) or CotQ(v):
  4089. FunctionOfTanQ(u, v.args[0], x)
  4090. elif SinhQ(v) or CschQ(v):
  4091. return FunctionOfSinhQ(u, v.args[0], x)
  4092. elif CoshQ(v) or SechQ(v):
  4093. return FunctionOfCoshQ(u, v.args[0], x)
  4094. elif TanhQ(v) or CothQ(v):
  4095. return FunctionOfTanhQ(u, v.args[0], x)
  4096. return FunctionOfExpnQ(u, v, x) != False
  4097. def FunctionOfExpnQ(u, v, x):
  4098. if u == v:
  4099. return 1
  4100. if AtomQ(u):
  4101. if u == x:
  4102. return False
  4103. else:
  4104. return 0
  4105. if CalculusQ(u):
  4106. return False
  4107. if PowerQ(u):
  4108. if FreeQ(u.exp, x):
  4109. if ZeroQ(u.base - v):
  4110. if IntegerQ(u.exp):
  4111. return u.exp
  4112. else:
  4113. return 1
  4114. if PowerQ(v):
  4115. if FreeQ(v.exp, x) and ZeroQ(u.base-v.base):
  4116. if RationalQ(v.exp):
  4117. if RationalQ(u.exp) and IntegerQ(u.exp/v.exp) and (v.exp>0 or u.exp<0):
  4118. return u.exp/v.exp
  4119. else:
  4120. return False
  4121. if IntegerQ(Simplify(u.exp/v.exp)):
  4122. return Simplify(u.exp/v.exp)
  4123. else:
  4124. return False
  4125. return FunctionOfExpnQ(u.base, v, x)
  4126. if ProductQ(u) and Not(EqQ(FreeFactors(u, x), 1)):
  4127. return FunctionOfExpnQ(NonfreeFactors(u, x), v, x)
  4128. if ProductQ(u) and ProductQ(v):
  4129. deg1 = FunctionOfExpnQ(First(u), First(v), x)
  4130. if deg1==False:
  4131. return False
  4132. deg2 = FunctionOfExpnQ(Rest(u), Rest(v), x);
  4133. if deg1==deg2 and FreeQ(Simplify(u/v^deg1), x):
  4134. return deg1
  4135. else:
  4136. return False
  4137. lst = []
  4138. for i in u.args:
  4139. if FunctionOfExpnQ(i, v, x) is False:
  4140. return False
  4141. lst.append(FunctionOfExpnQ(i, v, x))
  4142. return Apply(GCD, lst)
  4143. def PureFunctionOfSinQ(u, v, x):
  4144. # If u is a pure function of Sin(v) and/or Csc(v), PureFunctionOfSinQ(u, v, x) returns True; else it returns False.
  4145. if AtomQ(u):
  4146. return u!=x
  4147. if CalculusQ(u):
  4148. return False
  4149. if TrigQ(u) and ZeroQ(u.args[0]-v):
  4150. return SinQ(u) or CscQ(u)
  4151. for i in u.args:
  4152. if Not(PureFunctionOfSinQ(i, v, x)):
  4153. return False
  4154. return True
  4155. def PureFunctionOfCosQ(u, v, x):
  4156. # If u is a pure function of Cos(v) and/or Sec(v), PureFunctionOfCosQ(u, v, x) returns True; else it returns False.
  4157. if AtomQ(u):
  4158. return u!=x
  4159. if CalculusQ(u):
  4160. return False
  4161. if TrigQ(u) and ZeroQ(u.args[0]-v):
  4162. return CosQ(u) or SecQ(u)
  4163. for i in u.args:
  4164. if Not(PureFunctionOfCosQ(i, v, x)):
  4165. return False
  4166. return True
  4167. def PureFunctionOfTanQ(u, v, x):
  4168. # If u is a pure function of Tan(v) and/or Cot(v), PureFunctionOfTanQ(u, v, x) returns True; else it returns False.
  4169. if AtomQ(u):
  4170. return u!=x
  4171. if CalculusQ(u):
  4172. return False
  4173. if TrigQ(u) and ZeroQ(u.args[0]-v):
  4174. return TanQ(u) or CotQ(u)
  4175. for i in u.args:
  4176. if Not(PureFunctionOfTanQ(i, v, x)):
  4177. return False
  4178. return True
  4179. def PureFunctionOfCotQ(u, v, x):
  4180. # If u is a pure function of Cot(v), PureFunctionOfCotQ(u, v, x) returns True; else it returns False.
  4181. if AtomQ(u):
  4182. return u!=x
  4183. if CalculusQ(u):
  4184. return False
  4185. if TrigQ(u) and ZeroQ(u.args[0]-v):
  4186. return CotQ(u)
  4187. for i in u.args:
  4188. if Not(PureFunctionOfCotQ(i, v, x)):
  4189. return False
  4190. return True
  4191. def FunctionOfCosQ(u, v, x):
  4192. # If u is a function of Cos[v], FunctionOfCosQ[u,v,x] returns True; else it returns False.
  4193. if AtomQ(u):
  4194. return u != x
  4195. elif CalculusQ(u):
  4196. return False
  4197. elif TrigQ(u) and IntegerQuotientQ(u.args[0], v):
  4198. # Basis: If m integer, Cos[m*v]^n is a function of Cos[v]. *)
  4199. return CosQ(u) or SecQ(u)
  4200. elif IntegerPowerQ(u):
  4201. if TrigQ(u.base) and IntegerQuotientQ(u.base.args[0], v):
  4202. if EvenQ(u.exp):
  4203. # Basis: If m integer and n even, Trig[m*v]^n is a function of Cos[v]. *)
  4204. return True
  4205. return FunctionOfCosQ(u.base, v, x)
  4206. elif ProductQ(u):
  4207. lst = FindTrigFactor(sin, csc, u, v, False)
  4208. if ListQ(lst):
  4209. # (* Basis: If m integer and n odd, Sin[m*v]^n == Sin[v]*u where u is a function of Cos[v]. *)
  4210. return FunctionOfCosQ(Sin(v)*lst[1], v, x)
  4211. lst = FindTrigFactor(tan, cot, u, v, True)
  4212. if ListQ(lst):
  4213. # (* Basis: If m integer and n odd, Tan[m*v]^n == Sin[v]*u where u is a function of Cos[v]. *)
  4214. return FunctionOfCosQ(Sin(v)*lst[1], v, x)
  4215. return all(FunctionOfCosQ(i, v, x) for i in u.args)
  4216. return all(FunctionOfCosQ(i, v, x) for i in u.args)
  4217. def FunctionOfSinQ(u, v, x):
  4218. # If u is a function of Sin[v], FunctionOfSinQ[u,v,x] returns True; else it returns False.
  4219. if AtomQ(u):
  4220. return u != x
  4221. elif CalculusQ(u):
  4222. return False
  4223. elif TrigQ(u) and IntegerQuotientQ(u.args[0], v):
  4224. if OddQuotientQ(u.args[0], v):
  4225. # Basis: If m odd, Sin[m*v]^n is a function of Sin[v].
  4226. return SinQ(u) or CscQ(u)
  4227. # Basis: If m even, Cos[m*v]^n is a function of Sin[v].
  4228. return CosQ(u) or SecQ(u)
  4229. elif IntegerPowerQ(u):
  4230. if TrigQ(u.base) and IntegerQuotientQ(u.base.args[0], v):
  4231. if EvenQ(u.exp):
  4232. # Basis: If m integer and n even, Hyper[m*v]^n is a function of Sin[v].
  4233. return True
  4234. return FunctionOfSinQ(u.base, v, x)
  4235. elif ProductQ(u):
  4236. if CosQ(u.args[0]) and SinQ(u.args[1]) and ZeroQ(u.args[0].args[0] - v/2) and ZeroQ(u.args[1].args[0] - v/2):
  4237. return FunctionOfSinQ(Drop(u, 2), v, x)
  4238. lst = FindTrigFactor(sin, csch, u, v, False)
  4239. if ListQ(lst) and EvenQuotientQ(lst[0], v):
  4240. # Basis: If m even and n odd, Sin[m*v]^n == Cos[v]*u where u is a function of Sin[v].
  4241. return FunctionOfSinQ(Cos(v)*lst[1], v, x)
  4242. lst = FindTrigFactor(cos, sec, u, v, False)
  4243. if ListQ(lst) and OddQuotientQ(lst[0], v):
  4244. # Basis: If m odd and n odd, Cos[m*v]^n == Cos[v]*u where u is a function of Sin[v].
  4245. return FunctionOfSinQ(Cos(v)*lst[1], v, x)
  4246. lst = FindTrigFactor(tan, cot, u, v, True)
  4247. if ListQ(lst):
  4248. # Basis: If m integer and n odd, Tan[m*v]^n == Cos[v]*u where u is a function of Sin[v].
  4249. return FunctionOfSinQ(Cos(v)*lst[1], v, x)
  4250. return all(FunctionOfSinQ(i, v, x) for i in u.args)
  4251. return all(FunctionOfSinQ(i, v, x) for i in u.args)
  4252. def OddTrigPowerQ(u, v, x):
  4253. if SinQ(u) or CosQ(u) or SecQ(u) or CscQ(u):
  4254. return OddQuotientQ(u.args[0], v)
  4255. if PowerQ(u):
  4256. return OddQ(u.exp) and OddTrigPowerQ(u.base, v, x)
  4257. if ProductQ(u):
  4258. if not FreeFactors(u, x) == 1:
  4259. return OddTrigPowerQ(NonfreeFactors(u, x), v, x)
  4260. lst = []
  4261. for i in u.args:
  4262. if Not(FunctionOfTanQ(i, v, x)):
  4263. lst.append(i)
  4264. if lst == []:
  4265. return True
  4266. return Length(lst)==1 and OddTrigPowerQ(lst[0], v, x)
  4267. if SumQ(u):
  4268. return all(OddTrigPowerQ(i, v, x) for i in u.args)
  4269. return False
  4270. def FunctionOfTanQ(u, v, x):
  4271. # If u is a function of the form f[Tan[v],Cot[v]] where f is independent of x,
  4272. # FunctionOfTanQ[u,v,x] returns True; else it returns False.
  4273. if AtomQ(u):
  4274. return u != x
  4275. elif CalculusQ(u):
  4276. return False
  4277. elif TrigQ(u) and IntegerQuotientQ(u.args[0], v):
  4278. return TanQ(u) or CotQ(u) or EvenQuotientQ(u.args[0], v)
  4279. elif PowerQ(u):
  4280. if EvenQ(u.exp) and TrigQ(u.base) and IntegerQuotientQ(u.base.args[0], v):
  4281. return True
  4282. elif EvenQ(u.exp) and SumQ(u.base):
  4283. return FunctionOfTanQ(Expand(u.base**2, v, x))
  4284. if ProductQ(u):
  4285. lst = []
  4286. for i in u.args:
  4287. if Not(FunctionOfTanQ(i, v, x)):
  4288. lst.append(i)
  4289. if lst == []:
  4290. return True
  4291. return Length(lst)==2 and OddTrigPowerQ(lst[0], v, x) and OddTrigPowerQ(lst[1], v, x)
  4292. return all(FunctionOfTanQ(i, v, x) for i in u.args)
  4293. def FunctionOfTanWeight(u, v, x):
  4294. # (* u is a function of the form f[Tan[v],Cot[v]] where f is independent of x.
  4295. # FunctionOfTanWeight[u,v,x] returns a nonnegative number if u is best considered a function
  4296. # of Tan[v]; else it returns a negative number. *)
  4297. if AtomQ(u):
  4298. return S(0)
  4299. elif CalculusQ(u):
  4300. return S(0)
  4301. elif TrigQ(u) and IntegerQuotientQ(u.args[0], v):
  4302. if TanQ(u) and ZeroQ(u.args[0] - v):
  4303. return S(1)
  4304. elif CotQ(u) and ZeroQ(u.args[0] - v):
  4305. return S(-1)
  4306. return S(0)
  4307. elif PowerQ(u):
  4308. if EvenQ(u.exp) and TrigQ(u.base) and IntegerQuotientQ(u.base.args[0], v):
  4309. if TanQ(u.base) or CosQ(u.base) or SecQ(u.base):
  4310. return S(1)
  4311. return S(-1)
  4312. if ProductQ(u):
  4313. if all(FunctionOfTanQ(i, v, x) for i in u.args):
  4314. return Add(*[FunctionOfTanWeight(i, v, x) for i in u.args])
  4315. return S(0)
  4316. return Add(*[FunctionOfTanWeight(i, v, x) for i in u.args])
  4317. def FunctionOfTrigQ(u, v, x):
  4318. # If u (x) is equivalent to a function of the form f (Sin[v],Cos[v],Tan[v],Cot[v],Sec[v],Csc[v]) where f is independent of x, FunctionOfTrigQ[u,v,x] returns True; else it returns False.
  4319. if AtomQ(u):
  4320. return u != x
  4321. elif CalculusQ(u):
  4322. return False
  4323. elif TrigQ(u) and IntegerQuotientQ(u.args[0], v):
  4324. return True
  4325. return all(FunctionOfTrigQ(i, v, x) for i in u.args)
  4326. def FunctionOfDensePolynomialsQ(u, x):
  4327. # If all occurrences of x in u (x) are in dense polynomials, FunctionOfDensePolynomialsQ[u,x] returns True; else it returns False.
  4328. if FreeQ(u, x):
  4329. return True
  4330. if PolynomialQ(u, x):
  4331. return Length(ExponentList(u, x)) > 1
  4332. return all(FunctionOfDensePolynomialsQ(i, x) for i in u.args)
  4333. def FunctionOfLog(u, *args):
  4334. # If u (x) is equivalent to an expression of the form f (Log[a*x^n]), FunctionOfLog[u,x] returns
  4335. # the list {f (x),a*x^n,n}; else it returns False.
  4336. if len(args) == 1:
  4337. x = args[0]
  4338. lst = FunctionOfLog(u, False, False, x)
  4339. if AtomQ(lst) or FalseQ(lst[1]) or not isinstance(x, Symbol):
  4340. return False
  4341. else:
  4342. return lst
  4343. else:
  4344. v = args[0]
  4345. n = args[1]
  4346. x = args[2]
  4347. if AtomQ(u):
  4348. if u==x:
  4349. return False
  4350. else:
  4351. return [u, v, n]
  4352. if CalculusQ(u):
  4353. return False
  4354. lst = BinomialParts(u.args[0], x)
  4355. if LogQ(u) and ListQ(lst) and ZeroQ(lst[0]):
  4356. if FalseQ(v) or u.args[0] == v:
  4357. return [x, u.args[0], lst[2]]
  4358. else:
  4359. return False
  4360. lst = [0, v, n]
  4361. l = []
  4362. for i in u.args:
  4363. lst = FunctionOfLog(i, lst[1], lst[2], x)
  4364. if AtomQ(lst):
  4365. return False
  4366. else:
  4367. l.append(lst[0])
  4368. return [u.func(*l), lst[1], lst[2]]
  4369. def PowerVariableExpn(u, m, x):
  4370. # If m is an integer, u is an expression of the form f((c*x)**n) and g=GCD(m,n)>1,
  4371. # PowerVariableExpn(u,m,x) returns the list {x**(m/g)*f((c*x)**(n/g)),g,c}; else it returns False.
  4372. if IntegerQ(m):
  4373. lst = PowerVariableDegree(u, m, 1, x)
  4374. if not lst:
  4375. return False
  4376. else:
  4377. return [x**(m/lst[0])*PowerVariableSubst(u, lst[0], x), lst[0], lst[1]]
  4378. else:
  4379. return False
  4380. def PowerVariableDegree(u, m, c, x):
  4381. if FreeQ(u, x):
  4382. return [m, c]
  4383. if AtomQ(u) or CalculusQ(u):
  4384. return False
  4385. if PowerQ(u):
  4386. if FreeQ(u.base/x, x):
  4387. if ZeroQ(m) or m == u.exp and c == u.base/x:
  4388. return [u.exp, u.base/x]
  4389. if IntegerQ(u.exp) and IntegerQ(m) and GCD(m, u.exp)>1 and c==u.base/x:
  4390. return [GCD(m, u.exp), c]
  4391. else:
  4392. return False
  4393. lst = [m, c]
  4394. for i in u.args:
  4395. if PowerVariableDegree(i, lst[0], lst[1], x) == False:
  4396. return False
  4397. lst1 = PowerVariableDegree(i, lst[0], lst[1], x)
  4398. if not lst1:
  4399. return False
  4400. else:
  4401. return lst1
  4402. def PowerVariableSubst(u, m, x):
  4403. if FreeQ(u, x) or AtomQ(u) or CalculusQ(u):
  4404. return u
  4405. if PowerQ(u):
  4406. if FreeQ(u.base/x, x):
  4407. return x**(u.exp/m)
  4408. if ProductQ(u):
  4409. l = 1
  4410. for i in u.args:
  4411. l *= (PowerVariableSubst(i, m, x))
  4412. return l
  4413. if SumQ(u):
  4414. l = 0
  4415. for i in u.args:
  4416. l += (PowerVariableSubst(i, m, x))
  4417. return l
  4418. return u
  4419. def EulerIntegrandQ(expr, x):
  4420. a = Wild('a', exclude=[x])
  4421. b = Wild('b', exclude=[x])
  4422. n = Wild('n', exclude=[x, 0])
  4423. m = Wild('m', exclude=[x, 0])
  4424. p = Wild('p', exclude=[x, 0])
  4425. u = Wild('u')
  4426. v = Wild('v')
  4427. # Pattern 1
  4428. M = expr.match((a*x + b*u**n)**p)
  4429. if M:
  4430. if len(M) == 5 and FreeQ([M[a], M[b]], x) and IntegerQ(M[n] + 1/2) and QuadraticQ(M[u], x) and Not(RationalQ(M[p])) or NegativeIntegerQ(M[p]) and Not(BinomialQ(M[u], x)):
  4431. return True
  4432. # Pattern 2
  4433. M = expr.match(v**m*(a*x + b*u**n)**p)
  4434. if M:
  4435. if len(M) == 6 and FreeQ([M[a], M[b]], x) and ZeroQ(M[u] - M[v]) and IntegersQ(2*M[m], M[n] + 1/2) and QuadraticQ(M[u], x) and Not(RationalQ(M[p])) or NegativeIntegerQ(M[p]) and Not(BinomialQ(M[u], x)):
  4436. return True
  4437. # Pattern 3
  4438. M = expr.match(u**n*v**p)
  4439. if M:
  4440. if len(M) == 3 and NegativeIntegerQ(M[p]) and IntegerQ(M[n] + 1/2) and QuadraticQ(M[u], x) and QuadraticQ(M[v], x) and Not(BinomialQ(M[v], x)):
  4441. return True
  4442. else:
  4443. return False
  4444. def FunctionOfSquareRootOfQuadratic(u, *args):
  4445. if len(args) == 1:
  4446. x = args[0]
  4447. pattern = Pattern(UtilityOperator(x_**WC('m', 1)*(a_ + x**WC('n', 1)*WC('b', 1))**p_, x), CustomConstraint(lambda a, b, m, n, p, x: FreeQ([a, b, m, n, p], x)))
  4448. M = is_match(UtilityOperator(u, args[0]), pattern)
  4449. if M:
  4450. return False
  4451. tmp = FunctionOfSquareRootOfQuadratic(u, False, x)
  4452. if AtomQ(tmp) or FalseQ(tmp[0]):
  4453. return False
  4454. tmp = tmp[0]
  4455. a = Coefficient(tmp, x, 0)
  4456. b = Coefficient(tmp, x, 1)
  4457. c = Coefficient(tmp, x, 2)
  4458. if ZeroQ(a) and ZeroQ(b) or ZeroQ(b**2-4*a*c):
  4459. return False
  4460. if PosQ(c):
  4461. sqrt = Rt(c, S(2));
  4462. q = a*sqrt + b*x + sqrt*x**2
  4463. r = b + 2*sqrt*x
  4464. return [Simplify(SquareRootOfQuadraticSubst(u, q/r, (-a+x**2)/r, x)*q/r**2), Simplify(sqrt*x + Sqrt(tmp)), 2]
  4465. if PosQ(a):
  4466. sqrt = Rt(a, S(2))
  4467. q = c*sqrt - b*x + sqrt*x**2
  4468. r = c - x**2
  4469. return [Simplify(SquareRootOfQuadraticSubst(u, q/r, (-b+2*sqrt*x)/r, x)*q/r**2), Simplify((-sqrt+Sqrt(tmp))/x), 1]
  4470. sqrt = Rt(b**2 - 4*a*c, S(2))
  4471. r = c - x**2
  4472. return[Simplify(-sqrt*SquareRootOfQuadraticSubst(u, -sqrt*x/r, -(b*c+c*sqrt+(-b+sqrt)*x**2)/(2*c*r), x)*x/r**2), FullSimplify(2*c*Sqrt(tmp)/(b-sqrt+2*c*x)), 3]
  4473. else:
  4474. v = args[0]
  4475. x = args[1]
  4476. if AtomQ(u) or FreeQ(u, x):
  4477. return [v]
  4478. if PowerQ(u):
  4479. if FreeQ(u.exp, x):
  4480. if FractionQ(u.exp) and Denominator(u.exp) == 2 and PolynomialQ(u.base, x) and Exponent(u.base, x) == 2:
  4481. if FalseQ(v) or u.base == v:
  4482. return [u.base]
  4483. else:
  4484. return False
  4485. return FunctionOfSquareRootOfQuadratic(u.base, v, x)
  4486. if ProductQ(u) or SumQ(u):
  4487. lst = [v]
  4488. lst1 = []
  4489. for i in u.args:
  4490. if FunctionOfSquareRootOfQuadratic(i, lst[0], x) == False:
  4491. return False
  4492. lst1 = FunctionOfSquareRootOfQuadratic(i, lst[0], x)
  4493. return lst1
  4494. else:
  4495. return False
  4496. def SquareRootOfQuadraticSubst(u, vv, xx, x):
  4497. # SquareRootOfQuadraticSubst(u, vv, xx, x) returns u with fractional powers replaced by vv raised to the power and x replaced by xx.
  4498. if AtomQ(u) or FreeQ(u, x):
  4499. if u==x:
  4500. return xx
  4501. return u
  4502. if PowerQ(u):
  4503. if FreeQ(u.exp, x):
  4504. if FractionQ(u.exp) and Denominator(u.exp)==2 and PolynomialQ(u.base, x) and Exponent(u.base, x)==2:
  4505. return vv**Numerator(u.exp)
  4506. return SquareRootOfQuadraticSubst(u.base, vv, xx, x)**u.exp
  4507. elif SumQ(u):
  4508. t = 0
  4509. for i in u.args:
  4510. t += SquareRootOfQuadraticSubst(i, vv, xx, x)
  4511. return t
  4512. elif ProductQ(u):
  4513. t = 1
  4514. for i in u.args:
  4515. t *= SquareRootOfQuadraticSubst(i, vv, xx, x)
  4516. return t
  4517. def Divides(y, u, x):
  4518. # If u divided by y is free of x, Divides[y,u,x] returns the quotient; else it returns False.
  4519. v = Simplify(u/y)
  4520. if FreeQ(v, x):
  4521. return v
  4522. else:
  4523. return False
  4524. def DerivativeDivides(y, u, x):
  4525. """
  4526. If y not equal to x, y is easy to differentiate wrt x, and u divided by the derivative of y
  4527. is free of x, DerivativeDivides[y,u,x] returns the quotient; else it returns False.
  4528. """
  4529. from matchpy import is_match
  4530. pattern0 = Pattern(Mul(a , b_), CustomConstraint(lambda a, b : FreeQ(a, b)))
  4531. def f1(y, u, x):
  4532. if PolynomialQ(y, x):
  4533. return PolynomialQ(u, x) and Exponent(u, x) == Exponent(y, x) - 1
  4534. else:
  4535. return EasyDQ(y, x)
  4536. if is_match(y, pattern0):
  4537. return False
  4538. elif f1(y, u, x):
  4539. v = D(y ,x)
  4540. if EqQ(v, 0):
  4541. return False
  4542. else:
  4543. v = Simplify(u/v)
  4544. if FreeQ(v, x):
  4545. return v
  4546. else:
  4547. return False
  4548. else:
  4549. return False
  4550. def EasyDQ(expr, x):
  4551. # If u is easy to differentiate wrt x, EasyDQ(u, x) returns True; else it returns False *)
  4552. u = Wild('u',exclude=[1])
  4553. m = Wild('m',exclude=[x, 0])
  4554. M = expr.match(u*x**m)
  4555. if M:
  4556. return EasyDQ(M[u], x)
  4557. if AtomQ(expr) or FreeQ(expr, x) or Length(expr)==0:
  4558. return True
  4559. elif CalculusQ(expr):
  4560. return False
  4561. elif Length(expr)==1:
  4562. return EasyDQ(expr.args[0], x)
  4563. elif BinomialQ(expr, x) or ProductOfLinearPowersQ(expr, x):
  4564. return True
  4565. elif RationalFunctionQ(expr, x) and RationalFunctionExponents(expr, x)==[1, 1]:
  4566. return True
  4567. elif ProductQ(expr):
  4568. if FreeQ(First(expr), x):
  4569. return EasyDQ(Rest(expr), x)
  4570. elif FreeQ(Rest(expr), x):
  4571. return EasyDQ(First(expr), x)
  4572. else:
  4573. return False
  4574. elif SumQ(expr):
  4575. return EasyDQ(First(expr), x) and EasyDQ(Rest(expr), x)
  4576. elif Length(expr)==2:
  4577. if FreeQ(expr.args[0], x):
  4578. EasyDQ(expr.args[1], x)
  4579. elif FreeQ(expr.args[1], x):
  4580. return EasyDQ(expr.args[0], x)
  4581. else:
  4582. return False
  4583. return False
  4584. def ProductOfLinearPowersQ(u, x):
  4585. # ProductOfLinearPowersQ(u, x) returns True iff u is a product of factors of the form v^n where v is linear in x
  4586. v = Wild('v')
  4587. n = Wild('n', exclude=[x])
  4588. M = u.match(v**n)
  4589. return FreeQ(u, x) or M and LinearQ(M[v], x) or ProductQ(u) and ProductOfLinearPowersQ(First(u), x) and ProductOfLinearPowersQ(Rest(u), x)
  4590. def Rt(u, n):
  4591. return RtAux(TogetherSimplify(u), n)
  4592. def NthRoot(u, n):
  4593. return nsimplify(u**(S(1)/n))
  4594. def AtomBaseQ(u):
  4595. # If u is an atom or an atom raised to an odd degree, AtomBaseQ(u) returns True; else it returns False
  4596. return AtomQ(u) or PowerQ(u) and OddQ(u.args[1]) and AtomBaseQ(u.args[0])
  4597. def SumBaseQ(u):
  4598. # If u is a sum or a sum raised to an odd degree, SumBaseQ(u) returns True; else it returns False
  4599. return SumQ(u) or PowerQ(u) and OddQ(u.args[1]) and SumBaseQ(u.args[0])
  4600. def NegSumBaseQ(u):
  4601. # If u is a sum or a sum raised to an odd degree whose lead term has a negative form, NegSumBaseQ(u) returns True; else it returns False
  4602. return SumQ(u) and NegQ(First(u)) or PowerQ(u) and OddQ(u.args[1]) and NegSumBaseQ(u.args[0])
  4603. def AllNegTermQ(u):
  4604. # If all terms of u have a negative form, AllNegTermQ(u) returns True; else it returns False
  4605. if PowerQ(u):
  4606. if OddQ(u.exp):
  4607. return AllNegTermQ(u.base)
  4608. if SumQ(u):
  4609. return NegQ(First(u)) and AllNegTermQ(Rest(u))
  4610. return NegQ(u)
  4611. def SomeNegTermQ(u):
  4612. # If some term of u has a negative form, SomeNegTermQ(u) returns True; else it returns False
  4613. if PowerQ(u):
  4614. if OddQ(u.exp):
  4615. return SomeNegTermQ(u.base)
  4616. if SumQ(u):
  4617. return NegQ(First(u)) or SomeNegTermQ(Rest(u))
  4618. return NegQ(u)
  4619. def TrigSquareQ(u):
  4620. # If u is an expression of the form Sin(z)^2 or Cos(z)^2, TrigSquareQ(u) returns True, else it returns False
  4621. return PowerQ(u) and EqQ(u.args[1], 2) and MemberQ([sin, cos], Head(u.args[0]))
  4622. def RtAux(u, n):
  4623. if PowerQ(u):
  4624. return u.base**(u.exp/n)
  4625. if ComplexNumberQ(u):
  4626. a = Re(u)
  4627. b = Im(u)
  4628. if Not(IntegerQ(a) and IntegerQ(b)) and IntegerQ(a/(a**2 + b**2)) and IntegerQ(b/(a**2 + b**2)):
  4629. # Basis: a+b*I==1/(a/(a^2+b^2)-b/(a^2+b^2)*I)
  4630. return S(1)/RtAux(a/(a**2 + b**2) - b/(a**2 + b**2)*I, n)
  4631. else:
  4632. return NthRoot(u, n)
  4633. if ProductQ(u):
  4634. lst = SplitProduct(PositiveQ, u)
  4635. if ListQ(lst):
  4636. return RtAux(lst[0], n)*RtAux(lst[1], n)
  4637. lst = SplitProduct(NegativeQ, u)
  4638. if ListQ(lst):
  4639. if EqQ(lst[0], -1):
  4640. v = lst[1]
  4641. if PowerQ(v):
  4642. if NegativeQ(v.exp):
  4643. return 1/RtAux(-v.base**(-v.exp), n)
  4644. if ProductQ(v):
  4645. if ListQ(SplitProduct(SumBaseQ, v)):
  4646. lst = SplitProduct(AllNegTermQ, v)
  4647. if ListQ(lst):
  4648. return RtAux(-lst[0], n)*RtAux(lst[1], n)
  4649. lst = SplitProduct(NegSumBaseQ, v)
  4650. if ListQ(lst):
  4651. return RtAux(-lst[0], n)*RtAux(lst[1], n)
  4652. lst = SplitProduct(SomeNegTermQ, v)
  4653. if ListQ(lst):
  4654. return RtAux(-lst[0], n)*RtAux(lst[1], n)
  4655. lst = SplitProduct(SumBaseQ, v)
  4656. return RtAux(-lst[0], n)*RtAux(lst[1], n)
  4657. lst = SplitProduct(AtomBaseQ, v)
  4658. if ListQ(lst):
  4659. return RtAux(-lst[0], n)*RtAux(lst[1], n)
  4660. else:
  4661. return RtAux(-First(v), n)*RtAux(Rest(v), n)
  4662. if OddQ(n):
  4663. return -RtAux(v, n)
  4664. else:
  4665. return NthRoot(u, n)
  4666. else:
  4667. return RtAux(-lst[0], n)*RtAux(-lst[1], n)
  4668. lst = SplitProduct(AllNegTermQ, u)
  4669. if ListQ(lst) and ListQ(SplitProduct(SumBaseQ, lst[1])):
  4670. return RtAux(-lst[0], n)*RtAux(-lst[1], n)
  4671. lst = SplitProduct(NegSumBaseQ, u)
  4672. if ListQ(lst) and ListQ(SplitProduct(NegSumBaseQ, lst[1])):
  4673. return RtAux(-lst[0], n)*RtAux(-lst[1], n)
  4674. return u.func(*[RtAux(i, n) for i in u.args])
  4675. v = TrigSquare(u)
  4676. if Not(AtomQ(v)):
  4677. return RtAux(v, n)
  4678. if OddQ(n) and NegativeQ(u):
  4679. return -RtAux(-u, n)
  4680. if OddQ(n) and NegQ(u) and PosQ(-u):
  4681. return -RtAux(-u, n)
  4682. else:
  4683. return NthRoot(u, n)
  4684. def TrigSquare(u):
  4685. # If u is an expression of the form a-a*Sin(z)^2 or a-a*Cos(z)^2, TrigSquare(u) returns Cos(z)^2 or Sin(z)^2 respectively,
  4686. # else it returns False.
  4687. if SumQ(u):
  4688. for i in u.args:
  4689. v = SplitProduct(TrigSquareQ, i)
  4690. if v == False or SplitSum(v, u) == False:
  4691. return False
  4692. lst = SplitSum(SplitProduct(TrigSquareQ, i))
  4693. if lst and ZeroQ(lst[1][2] + lst[1]):
  4694. if Head(lst[0][0].args[0]) == sin:
  4695. return lst[1]*cos(lst[1][1][1][1])**2
  4696. return lst[1]*sin(lst[1][1][1][1])**2
  4697. else:
  4698. return False
  4699. else:
  4700. return False
  4701. def IntSum(u, x):
  4702. # If u is free of x or of the form c*(a+b*x)^m, IntSum[u,x] returns the antiderivative of u wrt x;
  4703. # else it returns d*Int[v,x] where d*v=u and d is free of x.
  4704. return Add(*[Integral(i, x) for i in u.args])
  4705. def IntTerm(expr, x):
  4706. # If u is of the form c*(a+b*x)**m, IntTerm(u,x) returns the antiderivative of u wrt x;
  4707. # else it returns d*Int(v,x) where d*v=u and d is free of x.
  4708. c = Wild('c', exclude=[x])
  4709. m = Wild('m', exclude=[x, 0])
  4710. v = Wild('v')
  4711. M = expr.match(c/v)
  4712. if M and len(M) == 2 and FreeQ(M[c], x) and LinearQ(M[v], x):
  4713. return Simp(M[c]*Log(RemoveContent(M[v], x))/Coefficient(M[v], x, 1), x)
  4714. M = expr.match(c*v**m)
  4715. if M and len(M) == 3 and NonzeroQ(M[m] + 1) and LinearQ(M[v], x):
  4716. return Simp(M[c]*M[v]**(M[m] + 1)/(Coefficient(M[v], x, 1)*(M[m] + 1)), x)
  4717. if SumQ(expr):
  4718. t = 0
  4719. for i in expr.args:
  4720. t += IntTerm(i, x)
  4721. return t
  4722. else:
  4723. u = expr
  4724. return Dist(FreeFactors(u,x), Integral(NonfreeFactors(u, x), x), x)
  4725. def Map2(f, lst1, lst2):
  4726. result = []
  4727. for i in range(0, len(lst1)):
  4728. result.append(f(lst1[i], lst2[i]))
  4729. return result
  4730. def ConstantFactor(u, x):
  4731. # (* ConstantFactor[u,x] returns a 2-element list of the factors of u[x] free of x and the
  4732. # factors not free of u[x]. Common constant factors of the terms of sums are also collected. *)
  4733. if FreeQ(u, x):
  4734. return [u, S(1)]
  4735. elif AtomQ(u):
  4736. return [S(1), u]
  4737. elif PowerQ(u):
  4738. if FreeQ(u.exp, x):
  4739. lst = ConstantFactor(u.base, x)
  4740. if IntegerQ(u.exp):
  4741. return [lst[0]**u.exp, lst[1]**u.exp]
  4742. tmp = PositiveFactors(lst[0])
  4743. if tmp == 1:
  4744. return [S(1), u]
  4745. return [tmp**u.exp, (NonpositiveFactors(lst[0])*lst[1])**u.exp]
  4746. elif ProductQ(u):
  4747. lst = [ConstantFactor(i, x) for i in u.args]
  4748. return [Mul(*[First(i) for i in lst]), Mul(*[i[1] for i in lst])]
  4749. elif SumQ(u):
  4750. lst1 = [ConstantFactor(i, x) for i in u.args]
  4751. if SameQ(*[i[1] for i in lst1]):
  4752. return [Add(*[i[0] for i in lst]), lst1[0][1]]
  4753. lst2 = CommonFactors([First(i) for i in lst1])
  4754. return [First(lst2), Add(*Map2(Mul, Rest(lst2), [i[1] for i in lst1]))]
  4755. return [S(1), u]
  4756. def SameQ(*args):
  4757. for i in range(0, len(args) - 1):
  4758. if args[i] != args[i+1]:
  4759. return False
  4760. return True
  4761. def ReplacePart(lst, a, b):
  4762. lst[b] = a
  4763. return lst
  4764. def CommonFactors(lst):
  4765. # (* If lst is a list of n terms, CommonFactors[lst] returns a n+1-element list whose first
  4766. # element is the product of the factors common to all terms of lst, and whose remaining
  4767. # elements are quotients of each term divided by the common factor. *)
  4768. lst1 = [NonabsurdNumberFactors(i) for i in lst]
  4769. lst2 = [AbsurdNumberFactors(i) for i in lst]
  4770. num = AbsurdNumberGCD(*lst2)
  4771. common = num
  4772. lst2 = [i/num for i in lst2]
  4773. while (True):
  4774. lst3 = [LeadFactor(i) for i in lst1]
  4775. if SameQ(*lst3):
  4776. common = common*lst3[0]
  4777. lst1 = [RemainingFactors(i) for i in lst1]
  4778. elif (all((LogQ(i) and IntegerQ(First(i)) and First(i) > 0) for i in lst3) and
  4779. all(RationalQ(i) for i in [FullSimplify(j/First(lst3)) for j in lst3])):
  4780. lst4 = [FullSimplify(j/First(lst3)) for j in lst3]
  4781. num = GCD(*lst4)
  4782. common = common*Log((First(lst3)[0])**num)
  4783. lst2 = [lst2[i]*lst4[i]/num for i in range(0, len(lst2))]
  4784. lst1 = [RemainingFactors(i) for i in lst1]
  4785. lst4 = [LeadDegree(i) for i in lst1]
  4786. if SameQ(*[LeadBase(i) for i in lst1]) and RationalQ(*lst4):
  4787. num = Smallest(lst4)
  4788. base = LeadBase(lst1[0])
  4789. if num != 0:
  4790. common = common*base**num
  4791. lst2 = [lst2[i]*base**(lst4[i] - num) for i in range(0, len(lst2))]
  4792. lst1 = [RemainingFactors(i) for i in lst1]
  4793. elif (Length(lst1) == 2 and ZeroQ(LeadBase(lst1[0]) + LeadBase(lst1[1])) and
  4794. NonzeroQ(lst1[0] - 1) and IntegerQ(lst4[0]) and FractionQ(lst4[1])):
  4795. num = Min(*lst4)
  4796. base = LeadBase(lst1[1])
  4797. if num != 0:
  4798. common = common*base**num
  4799. lst2 = [lst2[0]*(-1)**lst4[0], lst2[1]]
  4800. lst2 = [lst2[i]*base**(lst4[i] - num) for i in range(0, len(lst2))]
  4801. lst1 = [RemainingFactors(i) for i in lst1]
  4802. elif (Length(lst1) == 2 and ZeroQ(lst1[0] + LeadBase(lst1[1])) and
  4803. NonzeroQ(lst1[1] - 1) and IntegerQ(lst1[1]) and FractionQ(lst4[0])):
  4804. num = Min(*lst4)
  4805. base = LeadBase(lst1[0])
  4806. if num != 0:
  4807. common = common*base**num
  4808. lst2 = [lst2[0], lst2[1]*(-1)**lst4[1]]
  4809. lst2 = [lst2[i]*base**(lst4[i] - num) for i in range(0, len(lst2))]
  4810. lst1 = [RemainingFactors(i) for i in lst1]
  4811. else:
  4812. num = MostMainFactorPosition(lst3)
  4813. lst2 = ReplacePart(lst2, lst3[num]*lst2[num], num)
  4814. lst1 = ReplacePart(lst1, RemainingFactors(lst1[num]), num)
  4815. if all(i==1 for i in lst1):
  4816. return Prepend(lst2, common)
  4817. def MostMainFactorPosition(lst):
  4818. factor = S(1)
  4819. num = 0
  4820. for i in range(0, Length(lst)):
  4821. if FactorOrder(lst[i], factor) > 0:
  4822. factor = lst[i]
  4823. num = i
  4824. return num
  4825. SbaseS, SexponS = None, None
  4826. SexponFlagS = False
  4827. def FunctionOfExponentialQ(u, x):
  4828. # (* FunctionOfExponentialQ[u,x] returns True iff u is a function of F^v where F is a constant and v is linear in x, *)
  4829. # (* and such an exponential explicitly occurs in u (i.e. not just implicitly in hyperbolic functions). *)
  4830. global SbaseS, SexponS, SexponFlagS
  4831. SbaseS, SexponS = None, None
  4832. SexponFlagS = False
  4833. res = FunctionOfExponentialTest(u, x)
  4834. return res and SexponFlagS
  4835. def FunctionOfExponential(u, x):
  4836. global SbaseS, SexponS, SexponFlagS
  4837. # (* u is a function of F^v where v is linear in x. FunctionOfExponential[u,x] returns F^v. *)
  4838. SbaseS, SexponS = None, None
  4839. SexponFlagS = False
  4840. FunctionOfExponentialTest(u, x)
  4841. return SbaseS**SexponS
  4842. def FunctionOfExponentialFunction(u, x):
  4843. global SbaseS, SexponS, SexponFlagS
  4844. # (* u is a function of F^v where v is linear in x. FunctionOfExponentialFunction[u,x] returns u with F^v replaced by x. *)
  4845. SbaseS, SexponS = None, None
  4846. SexponFlagS = False
  4847. FunctionOfExponentialTest(u, x)
  4848. return SimplifyIntegrand(FunctionOfExponentialFunctionAux(u, x), x)
  4849. def FunctionOfExponentialFunctionAux(u, x):
  4850. # (* u is a function of F^v where v is linear in x, and the fluid variables $base$=F and $expon$=v. *)
  4851. # (* FunctionOfExponentialFunctionAux[u,x] returns u with F^v replaced by x. *)
  4852. global SbaseS, SexponS, SexponFlagS
  4853. if AtomQ(u):
  4854. return u
  4855. elif PowerQ(u):
  4856. if FreeQ(u.base, x) and LinearQ(u.exp, x):
  4857. if ZeroQ(Coefficient(SexponS, x, 0)):
  4858. return u.base**Coefficient(u.exp, x, 0)*x**FullSimplify(Log(u.base)*Coefficient(u.exp, x, 1)/(Log(SbaseS)*Coefficient(SexponS, x, 1)))
  4859. return x**FullSimplify(Log(u.base)*Coefficient(u.exp, x, 1)/(Log(SbaseS)*Coefficient(SexponS, x, 1)))
  4860. elif HyperbolicQ(u) and LinearQ(u.args[0], x):
  4861. tmp = x**FullSimplify(Coefficient(u.args[0], x, 1)/(Log(SbaseS)*Coefficient(SexponS, x, 1)))
  4862. if SinhQ(u):
  4863. return tmp/2 - 1/(2*tmp)
  4864. elif CoshQ(u):
  4865. return tmp/2 + 1/(2*tmp)
  4866. elif TanhQ(u):
  4867. return (tmp - 1/tmp)/(tmp + 1/tmp)
  4868. elif CothQ(u):
  4869. return (tmp + 1/tmp)/(tmp - 1/tmp)
  4870. elif SechQ(u):
  4871. return 2/(tmp + 1/tmp)
  4872. return 2/(tmp - 1/tmp)
  4873. if PowerQ(u):
  4874. if FreeQ(u.base, x) and SumQ(u.exp):
  4875. return FunctionOfExponentialFunctionAux(u.base**First(u.exp), x)*FunctionOfExponentialFunctionAux(u.base**Rest(u.exp), x)
  4876. return u.func(*[FunctionOfExponentialFunctionAux(i, x) for i in u.args])
  4877. def FunctionOfExponentialTest(u, x):
  4878. # (* FunctionOfExponentialTest[u,x] returns True iff u is a function of F^v where F is a constant and v is linear in x. *)
  4879. # (* Before it is called, the fluid variables $base$ and $expon$ should be set to Null and $exponFlag$ to False. *)
  4880. # (* If u is a function of F^v, $base$ and $expon$ are set to F and v, respectively. *)
  4881. # (* If an explicit exponential occurs in u, $exponFlag$ is set to True. *)
  4882. global SbaseS, SexponS, SexponFlagS
  4883. if FreeQ(u, x):
  4884. return True
  4885. elif u == x or CalculusQ(u):
  4886. return False
  4887. elif PowerQ(u):
  4888. if FreeQ(u.base, x) and LinearQ(u.exp, x):
  4889. SexponFlagS = True
  4890. return FunctionOfExponentialTestAux(u.base, u.exp, x)
  4891. elif HyperbolicQ(u) and LinearQ(u.args[0], x):
  4892. return FunctionOfExponentialTestAux(E, u.args[0], x)
  4893. if PowerQ(u):
  4894. if FreeQ(u.base, x) and SumQ(u.exp):
  4895. return FunctionOfExponentialTest(u.base**First(u.exp), x) and FunctionOfExponentialTest(u.base**Rest(u.exp), x)
  4896. return all(FunctionOfExponentialTest(i, x) for i in u.args)
  4897. def FunctionOfExponentialTestAux(base, expon, x):
  4898. global SbaseS, SexponS, SexponFlagS
  4899. if SbaseS is None:
  4900. SbaseS = base
  4901. SexponS = expon
  4902. return True
  4903. tmp = FullSimplify(Log(base)*Coefficient(expon, x, 1)/(Log(SbaseS)*Coefficient(SexponS, x, 1)))
  4904. if Not(RationalQ(tmp)):
  4905. return False
  4906. elif ZeroQ(Coefficient(SexponS, x, 0)) or NonzeroQ(tmp - FullSimplify(Log(base)*Coefficient(expon, x, 0)/(Log(SbaseS)*Coefficient(SexponS, x, 0)))):
  4907. if PositiveIntegerQ(base, SbaseS) and base < SbaseS:
  4908. SbaseS = base
  4909. SexponS = expon
  4910. tmp = 1/tmp
  4911. SexponS = Coefficient(SexponS, x, 1)*x/Denominator(tmp)
  4912. if tmp < 0 and NegQ(Coefficient(SexponS, x, 1)):
  4913. SexponS = -SexponS
  4914. return True
  4915. SexponS = SexponS/Denominator(tmp)
  4916. if tmp < 0 and NegQ(Coefficient(SexponS, x, 1)):
  4917. SexponS = -SexponS
  4918. return True
  4919. def stdev(lst):
  4920. """Calculates the standard deviation for a list of numbers."""
  4921. num_items = len(lst)
  4922. mean = sum(lst) / num_items
  4923. differences = [x - mean for x in lst]
  4924. sq_differences = [d ** 2 for d in differences]
  4925. ssd = sum(sq_differences)
  4926. variance = ssd / num_items
  4927. sd = sqrt(variance)
  4928. return sd
  4929. def rubi_test(expr, x, optimal_output, expand=False, _hyper_check=False, _diff=False, _numerical=False):
  4930. #Returns True if (expr - optimal_output) is equal to 0 or a constant
  4931. #expr: integrated expression
  4932. #x: integration variable
  4933. #expand=True equates `expr` with `optimal_output` in expanded form
  4934. #_hyper_check=True evaluates numerically
  4935. #_diff=True differentiates the expressions before equating
  4936. #_numerical=True equates the expressions at random `x`. Normally used for large expressions.
  4937. from sympy.simplify.simplify import nsimplify
  4938. if not expr.has(csc, sec, cot, csch, sech, coth):
  4939. optimal_output = process_trig(optimal_output)
  4940. if expr == optimal_output:
  4941. return True
  4942. if simplify(expr) == simplify(optimal_output):
  4943. return True
  4944. if nsimplify(expr) == nsimplify(optimal_output):
  4945. return True
  4946. if expr.has(sym_exp):
  4947. expr = powsimp(powdenest(expr), force=True)
  4948. if simplify(expr) == simplify(powsimp(optimal_output, force=True)):
  4949. return True
  4950. res = expr - optimal_output
  4951. if _numerical:
  4952. args = res.free_symbols
  4953. rand_val = []
  4954. try:
  4955. for i in range(0, 5): # check at 5 random points
  4956. rand_x = randint(1, 40)
  4957. substitutions = {s: rand_x for s in args}
  4958. rand_val.append(float(abs(res.subs(substitutions).n())))
  4959. if stdev(rand_val) < Pow(10, -3):
  4960. return True
  4961. except:
  4962. pass
  4963. # return False
  4964. dres = res.diff(x)
  4965. if _numerical:
  4966. args = dres.free_symbols
  4967. rand_val = []
  4968. try:
  4969. for i in range(0, 5): # check at 5 random points
  4970. rand_x = randint(1, 40)
  4971. substitutions = {s: rand_x for s in args}
  4972. rand_val.append(float(abs(dres.subs(substitutions).n())))
  4973. if stdev(rand_val) < Pow(10, -3):
  4974. return True
  4975. # return False
  4976. except:
  4977. pass
  4978. # return False
  4979. r = Simplify(nsimplify(res))
  4980. if r == 0 or (not r.has(x)):
  4981. return True
  4982. if _diff:
  4983. if dres == 0:
  4984. return True
  4985. elif Simplify(dres) == 0:
  4986. return True
  4987. if expand: # expands the expression and equates
  4988. e = res.expand()
  4989. if Simplify(e) == 0 or (not e.has(x)):
  4990. return True
  4991. return False
  4992. def If(cond, t, f):
  4993. # returns t if condition is true else f
  4994. if cond:
  4995. return t
  4996. return f
  4997. def IntQuadraticQ(a, b, c, d, e, m, p, x):
  4998. # (* IntQuadraticQ[a,b,c,d,e,m,p,x] returns True iff (d+e*x)^m*(a+b*x+c*x^2)^p is integrable wrt x in terms of non-Appell functions. *)
  4999. return IntegerQ(p) or PositiveIntegerQ(m) or IntegersQ(2*m, 2*p) or IntegersQ(m, 4*p) or IntegersQ(m, p + S(1)/3) and (ZeroQ(c**2*d**2 - b*c*d*e + b**2*e**2 - 3*a*c*e**2) or ZeroQ(c**2*d**2 - b*c*d*e - 2*b**2*e**2 + 9*a*c*e**2))
  5000. def IntBinomialQ(*args):
  5001. #(* IntBinomialQ(a,b,c,n,m,p,x) returns True iff (c*x)^m*(a+b*x^n)^p is integrable wrt x in terms of non-hypergeometric functions. *)
  5002. if len(args) == 8:
  5003. a, b, c, d, n, p, q, x = args
  5004. return IntegersQ(p,q) or PositiveIntegerQ(p) or PositiveIntegerQ(q) or (ZeroQ(n-2) or ZeroQ(n-4)) and (IntegersQ(p,4*q) or IntegersQ(4*p,q)) or ZeroQ(n-2) and (IntegersQ(2*p,2*q) or IntegersQ(3*p,q) and ZeroQ(b*c+3*a*d) or IntegersQ(p,3*q) and ZeroQ(3*b*c+a*d))
  5005. elif len(args) == 7:
  5006. a, b, c, n, m, p, x = args
  5007. return IntegerQ(2*p) or IntegerQ((m+1)/n + p) or (ZeroQ(n - 2) or ZeroQ(n - 4)) and IntegersQ(2*m, 4*p) or ZeroQ(n - 2) and IntegerQ(6*p) and (IntegerQ(m) or IntegerQ(m - p))
  5008. elif len(args) == 10:
  5009. a, b, c, d, e, m, n, p, q, x = args
  5010. return IntegersQ(p,q) or PositiveIntegerQ(p) or PositiveIntegerQ(q) or ZeroQ(n-2) and IntegerQ(m) and IntegersQ(2*p,2*q) or ZeroQ(n-4) and (IntegersQ(m,p,2*q) or IntegersQ(m,2*p,q))
  5011. def RectifyTangent(*args):
  5012. # (* RectifyTangent(u,a,b,r,x) returns an expression whose derivative equals the derivative of r*ArcTan(a+b*Tan(u)) wrt x. *)
  5013. if len(args) == 5:
  5014. u, a, b, r, x = args
  5015. t1 = Together(a)
  5016. t2 = Together(b)
  5017. if (PureComplexNumberQ(t1) or (ProductQ(t1) and any(PureComplexNumberQ(i) for i in t1.args))) and (PureComplexNumberQ(t2) or ProductQ(t2) and any(PureComplexNumberQ(i) for i in t2.args)):
  5018. c = a/I
  5019. d = b/I
  5020. if NegativeQ(d):
  5021. return RectifyTangent(u, -a, -b, -r, x)
  5022. e = SmartDenominator(Together(c + d*x))
  5023. c = c*e
  5024. d = d*e
  5025. if EvenQ(Denominator(NumericFactor(Together(u)))):
  5026. return I*r*Log(RemoveContent(Simplify((c+e)**2+d**2)+Simplify((c+e)**2-d**2)*Cos(2*u)+Simplify(2*(c+e)*d)*Sin(2*u),x))/4 - I*r*Log(RemoveContent(Simplify((c-e)**2+d**2)+Simplify((c-e)**2-d**2)*Cos(2*u)+Simplify(2*(c-e)*d)*Sin(2*u),x))/4
  5027. return I*r*Log(RemoveContent(Simplify((c+e)**2)+Simplify(2*(c+e)*d)*Cos(u)*Sin(u)-Simplify((c+e)**2-d**2)*Sin(u)**2,x))/4 - I*r*Log(RemoveContent(Simplify((c-e)**2)+Simplify(2*(c-e)*d)*Cos(u)*Sin(u)-Simplify((c-e)**2-d**2)*Sin(u)**2,x))/4
  5028. elif NegativeQ(b):
  5029. return RectifyTangent(u, -a, -b, -r, x)
  5030. elif EvenQ(Denominator(NumericFactor(Together(u)))):
  5031. return r*SimplifyAntiderivative(u,x) + r*ArcTan(Simplify((2*a*b*Cos(2*u)-(1+a**2-b**2)*Sin(2*u))/(a**2+(1+b)**2+(1+a**2-b**2)*Cos(2*u)+2*a*b*Sin(2*u))))
  5032. return r*SimplifyAntiderivative(u,x) - r*ArcTan(ActivateTrig(Simplify((a*b-2*a*b*cos(u)**2+(1+a**2-b**2)*cos(u)*sin(u))/(b*(1+b)+(1+a**2-b**2)*cos(u)**2+2*a*b*cos(u)*sin(u)))))
  5033. u, a, b, x = args
  5034. t = Together(a)
  5035. if PureComplexNumberQ(t) or (ProductQ(t) and any(PureComplexNumberQ(i) for i in t.args)):
  5036. c = a/I
  5037. if NegativeQ(c):
  5038. return RectifyTangent(u, -a, -b, x)
  5039. if ZeroQ(c - 1):
  5040. if EvenQ(Denominator(NumericFactor(Together(u)))):
  5041. return I*b*ArcTanh(Sin(2*u))/2
  5042. return I*b*ArcTanh(2*cos(u)*sin(u))/2
  5043. e = SmartDenominator(c)
  5044. c = c*e
  5045. return I*b*Log(RemoveContent(e*Cos(u)+c*Sin(u),x))/2 - I*b*Log(RemoveContent(e*Cos(u)-c*Sin(u),x))/2
  5046. elif NegativeQ(a):
  5047. return RectifyTangent(u, -a, -b, x)
  5048. elif ZeroQ(a - 1):
  5049. return b*SimplifyAntiderivative(u, x)
  5050. elif EvenQ(Denominator(NumericFactor(Together(u)))):
  5051. c = Simplify((1 + a)/(1 - a))
  5052. numr = SmartNumerator(c)
  5053. denr = SmartDenominator(c)
  5054. return b*SimplifyAntiderivative(u,x) - b*ArcTan(NormalizeLeadTermSigns(denr*Sin(2*u)/(numr+denr*Cos(2*u)))),
  5055. elif PositiveQ(a - 1):
  5056. c = Simplify(1/(a - 1))
  5057. numr = SmartNumerator(c)
  5058. denr = SmartDenominator(c)
  5059. return b*SimplifyAntiderivative(u,x) + b*ArcTan(NormalizeLeadTermSigns(denr*Cos(u)*Sin(u)/(numr+denr*Sin(u)**2))),
  5060. c = Simplify(a/(1 - a))
  5061. numr = SmartNumerator(c)
  5062. denr = SmartDenominator(c)
  5063. return b*SimplifyAntiderivative(u,x) - b*ArcTan(NormalizeLeadTermSigns(denr*Cos(u)*Sin(u)/(numr+denr*Cos(u)**2)))
  5064. def RectifyCotangent(*args):
  5065. #(* RectifyCotangent[u,a,b,r,x] returns an expression whose derivative equals the derivative of r*ArcTan[a+b*Cot[u]] wrt x. *)
  5066. if len(args) == 5:
  5067. u, a, b, r, x = args
  5068. t1 = Together(a)
  5069. t2 = Together(b)
  5070. if (PureComplexNumberQ(t1) or (ProductQ(t1) and any(PureComplexNumberQ(i) for i in t1.args))) and (PureComplexNumberQ(t2) or ProductQ(t2) and any(PureComplexNumberQ(i) for i in t2.args)):
  5071. c = a/I
  5072. d = b/I
  5073. if NegativeQ(d):
  5074. return RectifyTangent(u,-a,-b,-r,x)
  5075. e = SmartDenominator(Together(c + d*x))
  5076. c = c*e
  5077. d = d*e
  5078. if EvenQ(Denominator(NumericFactor(Together(u)))):
  5079. return I*r*Log(RemoveContent(Simplify((c+e)**2+d**2)-Simplify((c+e)**2-d**2)*Cos(2*u)+Simplify(2*(c+e)*d)*Sin(2*u),x))/4 - I*r*Log(RemoveContent(Simplify((c-e)**2+d**2)-Simplify((c-e)**2-d**2)*Cos(2*u)+Simplify(2*(c-e)*d)*Sin(2*u),x))/4
  5080. return I*r*Log(RemoveContent(Simplify((c+e)**2)-Simplify((c+e)**2-d**2)*Cos(u)**2+Simplify(2*(c+e)*d)*Cos(u)*Sin(u),x))/4 - I*r*Log(RemoveContent(Simplify((c-e)**2)-Simplify((c-e)**2-d**2)*Cos(u)**2+Simplify(2*(c-e)*d)*Cos(u)*Sin(u),x))/4
  5081. elif NegativeQ(b):
  5082. return RectifyCotangent(u,-a,-b,-r,x)
  5083. elif EvenQ(Denominator(NumericFactor(Together(u)))):
  5084. return -r*SimplifyAntiderivative(u,x) - r*ArcTan(Simplify((2*a*b*Cos(2*u)+(1+a**2-b**2)*Sin(2*u))/(a**2+(1+b)**2-(1+a**2-b**2)*Cos(2*u)+2*a*b*Sin(2*u))))
  5085. return -r*SimplifyAntiderivative(u,x) - r*ArcTan(ActivateTrig(Simplify((a*b-2*a*b*sin(u)**2+(1+a**2-b**2)*cos(u)*sin(u))/(b*(1+b)+(1+a**2-b**2)*sin(u)**2+2*a*b*cos(u)*sin(u)))))
  5086. u, a, b, x = args
  5087. t = Together(a)
  5088. if PureComplexNumberQ(t) or (ProductQ(t) and any(PureComplexNumberQ(i) for i in t.args)):
  5089. c = a/I
  5090. if NegativeQ(c):
  5091. return RectifyCotangent(u,-a,-b,x)
  5092. elif ZeroQ(c - 1):
  5093. if EvenQ(Denominator(NumericFactor(Together(u)))):
  5094. return -I*b*ArcTanh(Sin(2*u))/2
  5095. return -I*b*ArcTanh(2*Cos(u)*Sin(u))/2
  5096. e = SmartDenominator(c)
  5097. c = c*e
  5098. return -I*b*Log(RemoveContent(c*Cos(u)+e*Sin(u),x))/2 + I*b*Log(RemoveContent(c*Cos(u)-e*Sin(u),x))/2
  5099. elif NegativeQ(a):
  5100. return RectifyCotangent(u,-a,-b,x)
  5101. elif ZeroQ(a-1):
  5102. return b*SimplifyAntiderivative(u,x)
  5103. elif EvenQ(Denominator(NumericFactor(Together(u)))):
  5104. c = Simplify(a - 1)
  5105. numr = SmartNumerator(c)
  5106. denr = SmartDenominator(c)
  5107. return b*SimplifyAntiderivative(u,x) - b*ArcTan(NormalizeLeadTermSigns(denr*Cos(u)*Sin(u)/(numr+denr*Cos(u)**2)))
  5108. c = Simplify(a/(1-a))
  5109. numr = SmartNumerator(c)
  5110. denr = SmartDenominator(c)
  5111. return b*SimplifyAntiderivative(u,x) + b*ArcTan(NormalizeLeadTermSigns(denr*Cos(u)*Sin(u)/(numr+denr*Sin(u)**2)))
  5112. def Inequality(*args):
  5113. f = args[1::2]
  5114. e = args[0::2]
  5115. r = []
  5116. for i in range(0, len(f)):
  5117. r.append(f[i](e[i], e[i + 1]))
  5118. return all(r)
  5119. def Condition(r, c):
  5120. # returns r if c is True
  5121. if c:
  5122. return r
  5123. else:
  5124. raise NotImplementedError('In Condition()')
  5125. def Simp(u, x):
  5126. u = replace_pow_exp(u)
  5127. return NormalizeSumFactors(SimpHelp(u, x))
  5128. def SimpHelp(u, x):
  5129. if AtomQ(u):
  5130. return u
  5131. elif FreeQ(u, x):
  5132. v = SmartSimplify(u)
  5133. if LeafCount(v) <= LeafCount(u):
  5134. return v
  5135. return u
  5136. elif ProductQ(u):
  5137. #m = MatchQ[Rest[u],a_.+n_*Pi+b_.*v_ /; FreeQ[{a,b},x] && Not[FreeQ[v,x]] && EqQ[n^2,1/4]]
  5138. #if EqQ(First(u), S(1)/2) and m:
  5139. # if
  5140. #If[EqQ[First[u],1/2] && MatchQ[Rest[u],a_.+n_*Pi+b_.*v_ /; FreeQ[{a,b},x] && Not[FreeQ[v,x]] && EqQ[n^2,1/4]],
  5141. # If[MatchQ[Rest[u],n_*Pi+b_.*v_ /; FreeQ[b,x] && Not[FreeQ[v,x]] && EqQ[n^2,1/4]],
  5142. # Map[Function[1/2*#],Rest[u]],
  5143. # If[MatchQ[Rest[u],m_*a_.+n_*Pi+p_*b_.*v_ /; FreeQ[{a,b},x] && Not[FreeQ[v,x]] && IntegersQ[m/2,p/2]],
  5144. # Map[Function[1/2*#],Rest[u]],
  5145. # u]],
  5146. v = FreeFactors(u, x)
  5147. w = NonfreeFactors(u, x)
  5148. v = NumericFactor(v)*SmartSimplify(NonnumericFactors(v)*x**2)/x**2
  5149. if ProductQ(w):
  5150. w = Mul(*[SimpHelp(i,x) for i in w.args])
  5151. else:
  5152. w = SimpHelp(w, x)
  5153. w = FactorNumericGcd(w)
  5154. v = MergeFactors(v, w)
  5155. if ProductQ(v):
  5156. return Mul(*[SimpFixFactor(i, x) for i in v.args])
  5157. return v
  5158. elif SumQ(u):
  5159. Pi = pi
  5160. a_ = Wild('a', exclude=[x])
  5161. b_ = Wild('b', exclude=[x, 0])
  5162. n_ = Wild('n', exclude=[x, 0, 0])
  5163. pattern = a_ + n_*Pi + b_*x
  5164. match = u.match(pattern)
  5165. m = False
  5166. if match:
  5167. if EqQ(match[n_]**3, S(1)/16):
  5168. m = True
  5169. if m:
  5170. return u
  5171. elif PolynomialQ(u, x) and Exponent(u, x) <= 0:
  5172. return SimpHelp(Coefficient(u, x, 0), x)
  5173. elif PolynomialQ(u, x) and Exponent(u, x) == 1 and Coefficient(u, x, 0) == 0:
  5174. return SimpHelp(Coefficient(u, x, 1), x)*x
  5175. v = 0
  5176. w = 0
  5177. for i in u.args:
  5178. if FreeQ(i, x):
  5179. v = i + v
  5180. else:
  5181. w = i + w
  5182. v = SmartSimplify(v)
  5183. if SumQ(w):
  5184. w = Add(*[SimpHelp(i, x) for i in w.args])
  5185. else:
  5186. w = SimpHelp(w, x)
  5187. return v + w
  5188. return u.func(*[SimpHelp(i, x) for i in u.args])
  5189. def SplitProduct(func, u):
  5190. #(* If func[v] is True for a factor v of u, SplitProduct[func,u] returns {v, u/v} where v is the first such factor; else it returns False. *)
  5191. if ProductQ(u):
  5192. if func(First(u)):
  5193. return [First(u), Rest(u)]
  5194. lst = SplitProduct(func, Rest(u))
  5195. if AtomQ(lst):
  5196. return False
  5197. return [lst[0], First(u)*lst[1]]
  5198. if func(u):
  5199. return [u, 1]
  5200. return False
  5201. def SplitSum(func, u):
  5202. # (* If func[v] is nonatomic for a term v of u, SplitSum[func,u] returns {func[v], u-v} where v is the first such term; else it returns False. *)
  5203. if SumQ(u):
  5204. if Not(AtomQ(func(First(u)))):
  5205. return [func(First(u)), Rest(u)]
  5206. lst = SplitSum(func, Rest(u))
  5207. if AtomQ(lst):
  5208. return False
  5209. return [lst[0], First(u) + lst[1]]
  5210. elif Not(AtomQ(func(u))):
  5211. return [func(u), 0]
  5212. return False
  5213. def SubstFor(*args):
  5214. if len(args) == 4:
  5215. w, v, u, x = args
  5216. # u is a function of v. SubstFor(w,v,u,x) returns w times u with v replaced by x.
  5217. return SimplifyIntegrand(w*SubstFor(v, u, x), x)
  5218. v, u, x = args
  5219. # u is a function of v. SubstFor(v, u, x) returns u with v replaced by x.
  5220. if AtomQ(v):
  5221. return Subst(u, v, x)
  5222. elif Not(EqQ(FreeFactors(v, x), 1)):
  5223. return SubstFor(NonfreeFactors(v, x), u, x/FreeFactors(v, x))
  5224. elif SinQ(v):
  5225. return SubstForTrig(u, x, Sqrt(1 - x**2), v.args[0], x)
  5226. elif CosQ(v):
  5227. return SubstForTrig(u, Sqrt(1 - x**2), x, v.args[0], x)
  5228. elif TanQ(v):
  5229. return SubstForTrig(u, x/Sqrt(1 + x**2), 1/Sqrt(1 + x**2), v.args[0], x)
  5230. elif CotQ(v):
  5231. return SubstForTrig(u, 1/Sqrt(1 + x**2), x/Sqrt(1 + x**2), v.args[0], x)
  5232. elif SecQ(v):
  5233. return SubstForTrig(u, 1/Sqrt(1 - x**2), 1/x, v.args[0], x)
  5234. elif CscQ(v):
  5235. return SubstForTrig(u, 1/x, 1/Sqrt(1 - x**2), v.args[0], x)
  5236. elif SinhQ(v):
  5237. return SubstForHyperbolic(u, x, Sqrt(1 + x**2), v.args[0], x)
  5238. elif CoshQ(v):
  5239. return SubstForHyperbolic(u, Sqrt( - 1 + x**2), x, v.args[0], x)
  5240. elif TanhQ(v):
  5241. return SubstForHyperbolic(u, x/Sqrt(1 - x**2), 1/Sqrt(1 - x**2), v.args[0], x)
  5242. elif CothQ(v):
  5243. return SubstForHyperbolic(u, 1/Sqrt( - 1 + x**2), x/Sqrt( - 1 + x**2), v.args[0], x)
  5244. elif SechQ(v):
  5245. return SubstForHyperbolic(u, 1/Sqrt( - 1 + x**2), 1/x, v.args[0], x)
  5246. elif CschQ(v):
  5247. return SubstForHyperbolic(u, 1/x, 1/Sqrt(1 + x**2), v.args[0], x)
  5248. else:
  5249. return SubstForAux(u, v, x)
  5250. def SubstForAux(u, v, x):
  5251. # u is a function of v. SubstForAux(u, v, x) returns u with v replaced by x.
  5252. if u==v:
  5253. return x
  5254. elif AtomQ(u):
  5255. if PowerQ(v):
  5256. if FreeQ(v.exp, x) and ZeroQ(u - v.base):
  5257. return x**Simplify(1/v.exp)
  5258. return u
  5259. elif PowerQ(u):
  5260. if FreeQ(u.exp, x):
  5261. if ZeroQ(u.base - v):
  5262. return x**u.exp
  5263. if PowerQ(v):
  5264. if FreeQ(v.exp, x) and ZeroQ(u.base - v.base):
  5265. return x**Simplify(u.exp/v.exp)
  5266. return SubstForAux(u.base, v, x)**u.exp
  5267. elif ProductQ(u) and Not(EqQ(FreeFactors(u, x), 1)):
  5268. return FreeFactors(u, x)*SubstForAux(NonfreeFactors(u, x), v, x)
  5269. elif ProductQ(u) and ProductQ(v):
  5270. return SubstForAux(First(u), First(v), x)
  5271. return u.func(*[SubstForAux(i, v, x) for i in u.args])
  5272. def FresnelS(x):
  5273. return fresnels(x)
  5274. def FresnelC(x):
  5275. return fresnelc(x)
  5276. def Erf(x):
  5277. return erf(x)
  5278. def Erfc(x):
  5279. return erfc(x)
  5280. def Erfi(x):
  5281. return erfi(x)
  5282. class Gamma(Function):
  5283. @classmethod
  5284. def eval(cls,*args):
  5285. a = args[0]
  5286. if len(args) == 1:
  5287. return gamma(a)
  5288. else:
  5289. b = args[1]
  5290. if (NumericQ(a) and NumericQ(b)) or a == 1:
  5291. return uppergamma(a, b)
  5292. def FunctionOfTrigOfLinearQ(u, x):
  5293. # If u is an algebraic function of trig functions of a linear function of x,
  5294. # FunctionOfTrigOfLinearQ[u,x] returns True; else it returns False.
  5295. if FunctionOfTrig(u, None, x) and AlgebraicTrigFunctionQ(u, x) and FunctionOfLinear(FunctionOfTrig(u, None, x), x):
  5296. return True
  5297. else:
  5298. return False
  5299. def ElementaryFunctionQ(u):
  5300. # ElementaryExpressionQ[u] returns True if u is a sum, product, or power and all the operands
  5301. # are elementary expressions; or if u is a call on a trig, hyperbolic, or inverse function
  5302. # and all the arguments are elementary expressions; else it returns False.
  5303. if AtomQ(u):
  5304. return True
  5305. elif SumQ(u) or ProductQ(u) or PowerQ(u) or TrigQ(u) or HyperbolicQ(u) or InverseFunctionQ(u):
  5306. for i in u.args:
  5307. if not ElementaryFunctionQ(i):
  5308. return False
  5309. return True
  5310. return False
  5311. def Complex(a, b):
  5312. return a + I*b
  5313. def UnsameQ(a, b):
  5314. return a != b
  5315. @doctest_depends_on(modules=('matchpy',))
  5316. def _SimpFixFactor():
  5317. replacer = ManyToOneReplacer()
  5318. pattern1 = Pattern(UtilityOperator(Pow(Add(Mul(Complex(S(0), c_), WC('a', S(1))), Mul(Complex(S(0), d_), WC('b', S(1)))), WC('p', S(1))), x_), CustomConstraint(lambda p: IntegerQ(p)))
  5319. rule1 = ReplacementRule(pattern1, lambda b, c, x, a, p, d : Mul(Pow(I, p), SimpFixFactor(Pow(Add(Mul(a, c), Mul(b, d)), p), x)))
  5320. replacer.add(rule1)
  5321. pattern2 = Pattern(UtilityOperator(Pow(Add(Mul(Complex(S(0), d_), WC('a', S(1))), Mul(Complex(S(0), e_), WC('b', S(1))), Mul(Complex(S(0), f_), WC('c', S(1)))), WC('p', S(1))), x_), CustomConstraint(lambda p: IntegerQ(p)))
  5322. rule2 = ReplacementRule(pattern2, lambda b, c, x, f, a, p, e, d : Mul(Pow(I, p), SimpFixFactor(Pow(Add(Mul(a, d), Mul(b, e), Mul(c, f)), p), x)))
  5323. replacer.add(rule2)
  5324. pattern3 = Pattern(UtilityOperator(Pow(Add(Mul(WC('a', S(1)), Pow(c_, r_)), Mul(WC('b', S(1)), Pow(x_, WC('n', S(1))))), WC('p', S(1))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda c, x: FreeQ(c, x)), CustomConstraint(lambda n, p: IntegersQ(n, p)), CustomConstraint(lambda c: AtomQ(c)), CustomConstraint(lambda r: RationalQ(r)), CustomConstraint(lambda r: Less(r, S(0))))
  5325. rule3 = ReplacementRule(pattern3, lambda b, c, r, n, x, a, p : Mul(Pow(c, Mul(r, p)), SimpFixFactor(Pow(Add(a, Mul(Mul(b, Pow(Pow(c, r), S(-1))), Pow(x, n))), p), x)))
  5326. replacer.add(rule3)
  5327. pattern4 = Pattern(UtilityOperator(Pow(Add(WC('a', S(0)), Mul(WC('b', S(1)), Pow(c_, r_), Pow(x_, WC('n', S(1))))), WC('p', S(1))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda c, x: FreeQ(c, x)), CustomConstraint(lambda n, p: IntegersQ(n, p)), CustomConstraint(lambda c: AtomQ(c)), CustomConstraint(lambda r: RationalQ(r)), CustomConstraint(lambda r: Less(r, S(0))))
  5328. rule4 = ReplacementRule(pattern4, lambda b, c, r, n, x, a, p : Mul(Pow(c, Mul(r, p)), SimpFixFactor(Pow(Add(Mul(a, Pow(Pow(c, r), S(-1))), Mul(b, Pow(x, n))), p), x)))
  5329. replacer.add(rule4)
  5330. pattern5 = Pattern(UtilityOperator(Pow(Add(Mul(WC('a', S(1)), Pow(c_, WC('s', S(1)))), Mul(WC('b', S(1)), Pow(c_, WC('r', S(1))), Pow(x_, WC('n', S(1))))), WC('p', S(1))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda c, x: FreeQ(c, x)), CustomConstraint(lambda n, p: IntegersQ(n, p)), CustomConstraint(lambda r, s: RationalQ(s, r)), CustomConstraint(lambda r, s: Inequality(S(0), Less, s, LessEqual, r)), CustomConstraint(lambda p, c, s: UnsameQ(Pow(c, Mul(s, p)), S(-1))))
  5331. rule5 = ReplacementRule(pattern5, lambda b, c, r, n, x, a, p, s : Mul(Pow(c, Mul(s, p)), SimpFixFactor(Pow(Add(a, Mul(b, Pow(c, Add(r, Mul(S(-1), s))), Pow(x, n))), p), x)))
  5332. replacer.add(rule5)
  5333. pattern6 = Pattern(UtilityOperator(Pow(Add(Mul(WC('a', S(1)), Pow(c_, WC('s', S(1)))), Mul(WC('b', S(1)), Pow(c_, WC('r', S(1))), Pow(x_, WC('n', S(1))))), WC('p', S(1))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda c, x: FreeQ(c, x)), CustomConstraint(lambda n, p: IntegersQ(n, p)), CustomConstraint(lambda r, s: RationalQ(s, r)), CustomConstraint(lambda s, r: Less(S(0), r, s)), CustomConstraint(lambda p, c, r: UnsameQ(Pow(c, Mul(r, p)), S(-1))))
  5334. rule6 = ReplacementRule(pattern6, lambda b, c, r, n, x, a, p, s : Mul(Pow(c, Mul(r, p)), SimpFixFactor(Pow(Add(Mul(a, Pow(c, Add(s, Mul(S(-1), r)))), Mul(b, Pow(x, n))), p), x)))
  5335. replacer.add(rule6)
  5336. return replacer
  5337. @doctest_depends_on(modules=('matchpy',))
  5338. def SimpFixFactor(expr, x):
  5339. r = SimpFixFactor_replacer.replace(UtilityOperator(expr, x))
  5340. if isinstance(r, UtilityOperator):
  5341. return expr
  5342. return r
  5343. @doctest_depends_on(modules=('matchpy',))
  5344. def _FixSimplify():
  5345. Plus = Add
  5346. def cons_f1(n):
  5347. return OddQ(n)
  5348. cons1 = CustomConstraint(cons_f1)
  5349. def cons_f2(m):
  5350. return RationalQ(m)
  5351. cons2 = CustomConstraint(cons_f2)
  5352. def cons_f3(n):
  5353. return FractionQ(n)
  5354. cons3 = CustomConstraint(cons_f3)
  5355. def cons_f4(u):
  5356. return SqrtNumberSumQ(u)
  5357. cons4 = CustomConstraint(cons_f4)
  5358. def cons_f5(v):
  5359. return SqrtNumberSumQ(v)
  5360. cons5 = CustomConstraint(cons_f5)
  5361. def cons_f6(u):
  5362. return PositiveQ(u)
  5363. cons6 = CustomConstraint(cons_f6)
  5364. def cons_f7(v):
  5365. return PositiveQ(v)
  5366. cons7 = CustomConstraint(cons_f7)
  5367. def cons_f8(v):
  5368. return SqrtNumberSumQ(S(1)/v)
  5369. cons8 = CustomConstraint(cons_f8)
  5370. def cons_f9(m):
  5371. return IntegerQ(m)
  5372. cons9 = CustomConstraint(cons_f9)
  5373. def cons_f10(u):
  5374. return NegativeQ(u)
  5375. cons10 = CustomConstraint(cons_f10)
  5376. def cons_f11(n, m, a, b):
  5377. return RationalQ(a, b, m, n)
  5378. cons11 = CustomConstraint(cons_f11)
  5379. def cons_f12(a):
  5380. return Greater(a, S(0))
  5381. cons12 = CustomConstraint(cons_f12)
  5382. def cons_f13(b):
  5383. return Greater(b, S(0))
  5384. cons13 = CustomConstraint(cons_f13)
  5385. def cons_f14(p):
  5386. return PositiveIntegerQ(p)
  5387. cons14 = CustomConstraint(cons_f14)
  5388. def cons_f15(p):
  5389. return IntegerQ(p)
  5390. cons15 = CustomConstraint(cons_f15)
  5391. def cons_f16(p, n):
  5392. return Greater(-n + p, S(0))
  5393. cons16 = CustomConstraint(cons_f16)
  5394. def cons_f17(a, b):
  5395. return SameQ(a + b, S(0))
  5396. cons17 = CustomConstraint(cons_f17)
  5397. def cons_f18(n):
  5398. return Not(IntegerQ(n))
  5399. cons18 = CustomConstraint(cons_f18)
  5400. def cons_f19(c, a, b, d):
  5401. return ZeroQ(-a*d + b*c)
  5402. cons19 = CustomConstraint(cons_f19)
  5403. def cons_f20(a):
  5404. return Not(RationalQ(a))
  5405. cons20 = CustomConstraint(cons_f20)
  5406. def cons_f21(t):
  5407. return IntegerQ(t)
  5408. cons21 = CustomConstraint(cons_f21)
  5409. def cons_f22(n, m):
  5410. return RationalQ(m, n)
  5411. cons22 = CustomConstraint(cons_f22)
  5412. def cons_f23(n, m):
  5413. return Inequality(S(0), Less, m, LessEqual, n)
  5414. cons23 = CustomConstraint(cons_f23)
  5415. def cons_f24(p, n, m):
  5416. return RationalQ(m, n, p)
  5417. cons24 = CustomConstraint(cons_f24)
  5418. def cons_f25(p, n, m):
  5419. return Inequality(S(0), Less, m, LessEqual, n, LessEqual, p)
  5420. cons25 = CustomConstraint(cons_f25)
  5421. def cons_f26(p, n, m, q):
  5422. return Inequality(S(0), Less, m, LessEqual, n, LessEqual, p, LessEqual, q)
  5423. cons26 = CustomConstraint(cons_f26)
  5424. def cons_f27(w):
  5425. return Not(RationalQ(w))
  5426. cons27 = CustomConstraint(cons_f27)
  5427. def cons_f28(n):
  5428. return Less(n, S(0))
  5429. cons28 = CustomConstraint(cons_f28)
  5430. def cons_f29(n, w, v):
  5431. return ZeroQ(v + w**(-n))
  5432. cons29 = CustomConstraint(cons_f29)
  5433. def cons_f30(n):
  5434. return IntegerQ(n)
  5435. cons30 = CustomConstraint(cons_f30)
  5436. def cons_f31(w, v):
  5437. return ZeroQ(v + w)
  5438. cons31 = CustomConstraint(cons_f31)
  5439. def cons_f32(p, n):
  5440. return IntegerQ(n/p)
  5441. cons32 = CustomConstraint(cons_f32)
  5442. def cons_f33(w, v):
  5443. return ZeroQ(v - w)
  5444. cons33 = CustomConstraint(cons_f33)
  5445. def cons_f34(p, n):
  5446. return IntegersQ(n, n/p)
  5447. cons34 = CustomConstraint(cons_f34)
  5448. def cons_f35(a):
  5449. return AtomQ(a)
  5450. cons35 = CustomConstraint(cons_f35)
  5451. def cons_f36(b):
  5452. return AtomQ(b)
  5453. cons36 = CustomConstraint(cons_f36)
  5454. pattern1 = Pattern(UtilityOperator((w_ + Complex(S(0), b_)*WC('v', S(1)))**WC('n', S(1))*Complex(S(0), a_)*WC('u', S(1))), cons1)
  5455. def replacement1(n, u, w, v, a, b):
  5456. return (S(-1))**(n/S(2) + S(1)/2)*a*u*FixSimplify((b*v - w*Complex(S(0), S(1)))**n)
  5457. rule1 = ReplacementRule(pattern1, replacement1)
  5458. def With2(m, n, u, w, v):
  5459. z = u**(m/GCD(m, n))*v**(n/GCD(m, n))
  5460. if Or(AbsurdNumberQ(z), SqrtNumberSumQ(z)):
  5461. return True
  5462. return False
  5463. pattern2 = Pattern(UtilityOperator(u_**WC('m', S(1))*v_**n_*WC('w', S(1))), cons2, cons3, cons4, cons5, cons6, cons7, CustomConstraint(With2))
  5464. def replacement2(m, n, u, w, v):
  5465. z = u**(m/GCD(m, n))*v**(n/GCD(m, n))
  5466. return FixSimplify(w*z**GCD(m, n))
  5467. rule2 = ReplacementRule(pattern2, replacement2)
  5468. def With3(m, n, u, w, v):
  5469. z = u**(m/GCD(m, -n))*v**(n/GCD(m, -n))
  5470. if Or(AbsurdNumberQ(z), SqrtNumberSumQ(z)):
  5471. return True
  5472. return False
  5473. pattern3 = Pattern(UtilityOperator(u_**WC('m', S(1))*v_**n_*WC('w', S(1))), cons2, cons3, cons4, cons8, cons6, cons7, CustomConstraint(With3))
  5474. def replacement3(m, n, u, w, v):
  5475. z = u**(m/GCD(m, -n))*v**(n/GCD(m, -n))
  5476. return FixSimplify(w*z**GCD(m, -n))
  5477. rule3 = ReplacementRule(pattern3, replacement3)
  5478. def With4(m, n, u, w, v):
  5479. z = v**(n/GCD(m, n))*(-u)**(m/GCD(m, n))
  5480. if Or(AbsurdNumberQ(z), SqrtNumberSumQ(z)):
  5481. return True
  5482. return False
  5483. pattern4 = Pattern(UtilityOperator(u_**WC('m', S(1))*v_**n_*WC('w', S(1))), cons9, cons3, cons4, cons5, cons10, cons7, CustomConstraint(With4))
  5484. def replacement4(m, n, u, w, v):
  5485. z = v**(n/GCD(m, n))*(-u)**(m/GCD(m, n))
  5486. return FixSimplify(-w*z**GCD(m, n))
  5487. rule4 = ReplacementRule(pattern4, replacement4)
  5488. def With5(m, n, u, w, v):
  5489. z = v**(n/GCD(m, -n))*(-u)**(m/GCD(m, -n))
  5490. if Or(AbsurdNumberQ(z), SqrtNumberSumQ(z)):
  5491. return True
  5492. return False
  5493. pattern5 = Pattern(UtilityOperator(u_**WC('m', S(1))*v_**n_*WC('w', S(1))), cons9, cons3, cons4, cons8, cons10, cons7, CustomConstraint(With5))
  5494. def replacement5(m, n, u, w, v):
  5495. z = v**(n/GCD(m, -n))*(-u)**(m/GCD(m, -n))
  5496. return FixSimplify(-w*z**GCD(m, -n))
  5497. rule5 = ReplacementRule(pattern5, replacement5)
  5498. def With6(p, m, n, u, w, v, a, b):
  5499. c = a**(m/p)*b**n
  5500. if RationalQ(c):
  5501. return True
  5502. return False
  5503. pattern6 = Pattern(UtilityOperator(a_**m_*(b_**n_*WC('v', S(1)) + u_)**WC('p', S(1))*WC('w', S(1))), cons11, cons12, cons13, cons14, CustomConstraint(With6))
  5504. def replacement6(p, m, n, u, w, v, a, b):
  5505. c = a**(m/p)*b**n
  5506. return FixSimplify(w*(a**(m/p)*u + c*v)**p)
  5507. rule6 = ReplacementRule(pattern6, replacement6)
  5508. pattern7 = Pattern(UtilityOperator(a_**WC('m', S(1))*(a_**n_*WC('u', S(1)) + b_**WC('p', S(1))*WC('v', S(1)))*WC('w', S(1))), cons2, cons3, cons15, cons16, cons17)
  5509. def replacement7(p, m, n, u, w, v, a, b):
  5510. return FixSimplify(a**(m + n)*w*((S(-1))**p*a**(-n + p)*v + u))
  5511. rule7 = ReplacementRule(pattern7, replacement7)
  5512. def With8(m, d, n, w, c, a, b):
  5513. q = b/d
  5514. if FreeQ(q, Plus):
  5515. return True
  5516. return False
  5517. pattern8 = Pattern(UtilityOperator((a_ + b_)**WC('m', S(1))*(c_ + d_)**n_*WC('w', S(1))), cons9, cons18, cons19, CustomConstraint(With8))
  5518. def replacement8(m, d, n, w, c, a, b):
  5519. q = b/d
  5520. return FixSimplify(q**m*w*(c + d)**(m + n))
  5521. rule8 = ReplacementRule(pattern8, replacement8)
  5522. pattern9 = Pattern(UtilityOperator((a_**WC('m', S(1))*WC('u', S(1)) + a_**WC('n', S(1))*WC('v', S(1)))**WC('t', S(1))*WC('w', S(1))), cons20, cons21, cons22, cons23)
  5523. def replacement9(m, n, u, w, v, a, t):
  5524. return FixSimplify(a**(m*t)*w*(a**(-m + n)*v + u)**t)
  5525. rule9 = ReplacementRule(pattern9, replacement9)
  5526. pattern10 = Pattern(UtilityOperator((a_**WC('m', S(1))*WC('u', S(1)) + a_**WC('n', S(1))*WC('v', S(1)) + a_**WC('p', S(1))*WC('z', S(1)))**WC('t', S(1))*WC('w', S(1))), cons20, cons21, cons24, cons25)
  5527. def replacement10(p, m, n, u, w, v, a, z, t):
  5528. return FixSimplify(a**(m*t)*w*(a**(-m + n)*v + a**(-m + p)*z + u)**t)
  5529. rule10 = ReplacementRule(pattern10, replacement10)
  5530. pattern11 = Pattern(UtilityOperator((a_**WC('m', S(1))*WC('u', S(1)) + a_**WC('n', S(1))*WC('v', S(1)) + a_**WC('p', S(1))*WC('z', S(1)) + a_**WC('q', S(1))*WC('y', S(1)))**WC('t', S(1))*WC('w', S(1))), cons20, cons21, cons24, cons26)
  5531. def replacement11(p, m, n, u, q, w, v, a, z, y, t):
  5532. return FixSimplify(a**(m*t)*w*(a**(-m + n)*v + a**(-m + p)*z + a**(-m + q)*y + u)**t)
  5533. rule11 = ReplacementRule(pattern11, replacement11)
  5534. pattern12 = Pattern(UtilityOperator((sqrt(v_)*WC('b', S(1)) + sqrt(v_)*WC('c', S(1)) + sqrt(v_)*WC('d', S(1)) + sqrt(v_)*WC('a', S(1)) + WC('u', S(0)))*WC('w', S(1))))
  5535. def replacement12(d, u, w, v, c, a, b):
  5536. return FixSimplify(w*(u + sqrt(v)*FixSimplify(a + b + c + d)))
  5537. rule12 = ReplacementRule(pattern12, replacement12)
  5538. pattern13 = Pattern(UtilityOperator((sqrt(v_)*WC('b', S(1)) + sqrt(v_)*WC('c', S(1)) + sqrt(v_)*WC('a', S(1)) + WC('u', S(0)))*WC('w', S(1))))
  5539. def replacement13(u, w, v, c, a, b):
  5540. return FixSimplify(w*(u + sqrt(v)*FixSimplify(a + b + c)))
  5541. rule13 = ReplacementRule(pattern13, replacement13)
  5542. pattern14 = Pattern(UtilityOperator((sqrt(v_)*WC('b', S(1)) + sqrt(v_)*WC('a', S(1)) + WC('u', S(0)))*WC('w', S(1))))
  5543. def replacement14(u, w, v, a, b):
  5544. return FixSimplify(w*(u + sqrt(v)*FixSimplify(a + b)))
  5545. rule14 = ReplacementRule(pattern14, replacement14)
  5546. pattern15 = Pattern(UtilityOperator(v_**m_*w_**n_*WC('u', S(1))), cons2, cons27, cons3, cons28, cons29)
  5547. def replacement15(m, n, u, w, v):
  5548. return -FixSimplify(u*v**(m + S(-1)))
  5549. rule15 = ReplacementRule(pattern15, replacement15)
  5550. pattern16 = Pattern(UtilityOperator(v_**m_*w_**WC('n', S(1))*WC('u', S(1))), cons2, cons27, cons30, cons31)
  5551. def replacement16(m, n, u, w, v):
  5552. return (S(-1))**n*FixSimplify(u*v**(m + n))
  5553. rule16 = ReplacementRule(pattern16, replacement16)
  5554. pattern17 = Pattern(UtilityOperator(w_**WC('n', S(1))*(-v_**WC('p', S(1)))**m_*WC('u', S(1))), cons2, cons27, cons32, cons33)
  5555. def replacement17(p, m, n, u, w, v):
  5556. return (S(-1))**(n/p)*FixSimplify(u*(-v**p)**(m + n/p))
  5557. rule17 = ReplacementRule(pattern17, replacement17)
  5558. pattern18 = Pattern(UtilityOperator(w_**WC('n', S(1))*(-v_**WC('p', S(1)))**m_*WC('u', S(1))), cons2, cons27, cons34, cons31)
  5559. def replacement18(p, m, n, u, w, v):
  5560. return (S(-1))**(n + n/p)*FixSimplify(u*(-v**p)**(m + n/p))
  5561. rule18 = ReplacementRule(pattern18, replacement18)
  5562. pattern19 = Pattern(UtilityOperator((a_ - b_)**WC('m', S(1))*(a_ + b_)**WC('m', S(1))*WC('u', S(1))), cons9, cons35, cons36)
  5563. def replacement19(m, u, a, b):
  5564. return u*(a**S(2) - b**S(2))**m
  5565. rule19 = ReplacementRule(pattern19, replacement19)
  5566. pattern20 = Pattern(UtilityOperator((S(729)*c - e*(-S(20)*e + S(540)))**WC('m', S(1))*WC('u', S(1))), cons2)
  5567. def replacement20(m, u):
  5568. return u*(a*e**S(2) - b*d*e + c*d**S(2))**m
  5569. rule20 = ReplacementRule(pattern20, replacement20)
  5570. pattern21 = Pattern(UtilityOperator((S(729)*c + e*(S(20)*e + S(-540)))**WC('m', S(1))*WC('u', S(1))), cons2)
  5571. def replacement21(m, u):
  5572. return u*(a*e**S(2) - b*d*e + c*d**S(2))**m
  5573. rule21 = ReplacementRule(pattern21, replacement21)
  5574. pattern22 = Pattern(UtilityOperator(u_))
  5575. def replacement22(u):
  5576. return u
  5577. rule22 = ReplacementRule(pattern22, replacement22)
  5578. return [rule1, rule2, rule3, rule4, rule5, rule6, rule7, rule8, rule9, rule10, rule11, rule12, rule13, rule14, rule15, rule16, rule17, rule18, rule19, rule20, rule21, rule22, ]
  5579. @doctest_depends_on(modules=('matchpy',))
  5580. def FixSimplify(expr):
  5581. if isinstance(expr, (list, tuple, TupleArg)):
  5582. return [replace_all(UtilityOperator(i), FixSimplify_rules) for i in expr]
  5583. return replace_all(UtilityOperator(expr), FixSimplify_rules)
  5584. @doctest_depends_on(modules=('matchpy',))
  5585. def _SimplifyAntiderivativeSum():
  5586. replacer = ManyToOneReplacer()
  5587. pattern1 = Pattern(UtilityOperator(Add(Mul(Log(Add(a_, Mul(WC('b', S(1)), Pow(Tan(u_), WC('n', S(1)))))), WC('A', S(1))), Mul(Log(Cos(u_)), WC('B', S(1))), WC('v', S(0))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda A, x: FreeQ(A, x)), CustomConstraint(lambda B, x: FreeQ(B, x)), CustomConstraint(lambda n: IntegerQ(n)), CustomConstraint(lambda B, A, n: ZeroQ(Add(Mul(n, A), Mul(S(1), B)))))
  5588. rule1 = ReplacementRule(pattern1, lambda n, x, v, b, B, A, u, a : Add(SimplifyAntiderivativeSum(v, x), Mul(A, Log(RemoveContent(Add(Mul(a, Pow(Cos(u), n)), Mul(b, Pow(Sin(u), n))), x)))))
  5589. replacer.add(rule1)
  5590. pattern2 = Pattern(UtilityOperator(Add(Mul(Log(Add(Mul(Pow(Cot(u_), WC('n', S(1))), WC('b', S(1))), a_)), WC('A', S(1))), Mul(Log(Sin(u_)), WC('B', S(1))), WC('v', S(0))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda A, x: FreeQ(A, x)), CustomConstraint(lambda B, x: FreeQ(B, x)), CustomConstraint(lambda n: IntegerQ(n)), CustomConstraint(lambda B, A, n: ZeroQ(Add(Mul(n, A), Mul(S(1), B)))))
  5591. rule2 = ReplacementRule(pattern2, lambda n, x, v, b, B, A, a, u : Add(SimplifyAntiderivativeSum(v, x), Mul(A, Log(RemoveContent(Add(Mul(a, Pow(Sin(u), n)), Mul(b, Pow(Cos(u), n))), x)))))
  5592. replacer.add(rule2)
  5593. pattern3 = Pattern(UtilityOperator(Add(Mul(Log(Add(a_, Mul(WC('b', S(1)), Pow(Tan(u_), WC('n', S(1)))))), WC('A', S(1))), Mul(Log(Add(c_, Mul(WC('d', S(1)), Pow(Tan(u_), WC('n', S(1)))))), WC('B', S(1))), WC('v', S(0))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda c, x: FreeQ(c, x)), CustomConstraint(lambda d, x: FreeQ(d, x)), CustomConstraint(lambda A, x: FreeQ(A, x)), CustomConstraint(lambda B, x: FreeQ(B, x)), CustomConstraint(lambda n: IntegerQ(n)), CustomConstraint(lambda B, A: ZeroQ(Add(A, B))))
  5594. rule3 = ReplacementRule(pattern3, lambda n, x, v, b, A, B, u, c, d, a : Add(SimplifyAntiderivativeSum(v, x), Mul(A, Log(RemoveContent(Add(Mul(a, Pow(Cos(u), n)), Mul(b, Pow(Sin(u), n))), x))), Mul(B, Log(RemoveContent(Add(Mul(c, Pow(Cos(u), n)), Mul(d, Pow(Sin(u), n))), x)))))
  5595. replacer.add(rule3)
  5596. pattern4 = Pattern(UtilityOperator(Add(Mul(Log(Add(Mul(Pow(Cot(u_), WC('n', S(1))), WC('b', S(1))), a_)), WC('A', S(1))), Mul(Log(Add(Mul(Pow(Cot(u_), WC('n', S(1))), WC('d', S(1))), c_)), WC('B', S(1))), WC('v', S(0))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda c, x: FreeQ(c, x)), CustomConstraint(lambda d, x: FreeQ(d, x)), CustomConstraint(lambda A, x: FreeQ(A, x)), CustomConstraint(lambda B, x: FreeQ(B, x)), CustomConstraint(lambda n: IntegerQ(n)), CustomConstraint(lambda B, A: ZeroQ(Add(A, B))))
  5597. rule4 = ReplacementRule(pattern4, lambda n, x, v, b, A, B, c, a, d, u : Add(SimplifyAntiderivativeSum(v, x), Mul(A, Log(RemoveContent(Add(Mul(b, Pow(Cos(u), n)), Mul(a, Pow(Sin(u), n))), x))), Mul(B, Log(RemoveContent(Add(Mul(d, Pow(Cos(u), n)), Mul(c, Pow(Sin(u), n))), x)))))
  5598. replacer.add(rule4)
  5599. pattern5 = Pattern(UtilityOperator(Add(Mul(Log(Add(a_, Mul(WC('b', S(1)), Pow(Tan(u_), WC('n', S(1)))))), WC('A', S(1))), Mul(Log(Add(c_, Mul(WC('d', S(1)), Pow(Tan(u_), WC('n', S(1)))))), WC('B', S(1))), Mul(Log(Add(e_, Mul(WC('f', S(1)), Pow(Tan(u_), WC('n', S(1)))))), WC('C', S(1))), WC('v', S(0))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda c, x: FreeQ(c, x)), CustomConstraint(lambda d, x: FreeQ(d, x)), CustomConstraint(lambda e, x: FreeQ(e, x)), CustomConstraint(lambda f, x: FreeQ(f, x)), CustomConstraint(lambda A, x: FreeQ(A, x)), CustomConstraint(lambda B, x: FreeQ(B, x)), CustomConstraint(lambda C, x: FreeQ(C, x)), CustomConstraint(lambda n: IntegerQ(n)), CustomConstraint(lambda B, A, C: ZeroQ(Add(A, B, C))))
  5600. rule5 = ReplacementRule(pattern5, lambda n, e, x, v, b, A, B, u, c, f, d, a, C : Add(SimplifyAntiderivativeSum(v, x), Mul(A, Log(RemoveContent(Add(Mul(a, Pow(Cos(u), n)), Mul(b, Pow(Sin(u), n))), x))), Mul(B, Log(RemoveContent(Add(Mul(c, Pow(Cos(u), n)), Mul(d, Pow(Sin(u), n))), x))), Mul(C, Log(RemoveContent(Add(Mul(e, Pow(Cos(u), n)), Mul(f, Pow(Sin(u), n))), x)))))
  5601. replacer.add(rule5)
  5602. pattern6 = Pattern(UtilityOperator(Add(Mul(Log(Add(Mul(Pow(Cot(u_), WC('n', S(1))), WC('b', S(1))), a_)), WC('A', S(1))), Mul(Log(Add(Mul(Pow(Cot(u_), WC('n', S(1))), WC('d', S(1))), c_)), WC('B', S(1))), Mul(Log(Add(Mul(Pow(Cot(u_), WC('n', S(1))), WC('f', S(1))), e_)), WC('C', S(1))), WC('v', S(0))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda c, x: FreeQ(c, x)), CustomConstraint(lambda d, x: FreeQ(d, x)), CustomConstraint(lambda e, x: FreeQ(e, x)), CustomConstraint(lambda f, x: FreeQ(f, x)), CustomConstraint(lambda A, x: FreeQ(A, x)), CustomConstraint(lambda B, x: FreeQ(B, x)), CustomConstraint(lambda C, x: FreeQ(C, x)), CustomConstraint(lambda n: IntegerQ(n)), CustomConstraint(lambda B, A, C: ZeroQ(Add(A, B, C))))
  5603. rule6 = ReplacementRule(pattern6, lambda n, e, x, v, b, A, B, c, a, f, d, u, C : Add(SimplifyAntiderivativeSum(v, x), Mul(A, Log(RemoveContent(Add(Mul(b, Pow(Cos(u), n)), Mul(a, Pow(Sin(u), n))), x))), Mul(B, Log(RemoveContent(Add(Mul(d, Pow(Cos(u), n)), Mul(c, Pow(Sin(u), n))), x))), Mul(C, Log(RemoveContent(Add(Mul(f, Pow(Cos(u), n)), Mul(e, Pow(Sin(u), n))), x)))))
  5604. replacer.add(rule6)
  5605. return replacer
  5606. @doctest_depends_on(modules=('matchpy',))
  5607. def SimplifyAntiderivativeSum(expr, x):
  5608. r = SimplifyAntiderivativeSum_replacer.replace(UtilityOperator(expr, x))
  5609. if isinstance(r, UtilityOperator):
  5610. return expr
  5611. return r
  5612. @doctest_depends_on(modules=('matchpy',))
  5613. def _SimplifyAntiderivative():
  5614. replacer = ManyToOneReplacer()
  5615. pattern2 = Pattern(UtilityOperator(Log(Mul(c_, u_)), x_), CustomConstraint(lambda c, x: FreeQ(c, x)))
  5616. rule2 = ReplacementRule(pattern2, lambda x, c, u : SimplifyAntiderivative(Log(u), x))
  5617. replacer.add(rule2)
  5618. pattern3 = Pattern(UtilityOperator(Log(Pow(u_, n_)), x_), CustomConstraint(lambda n, x: FreeQ(n, x)))
  5619. rule3 = ReplacementRule(pattern3, lambda x, n, u : Mul(n, SimplifyAntiderivative(Log(u), x)))
  5620. replacer.add(rule3)
  5621. pattern7 = Pattern(UtilityOperator(Log(Pow(f_, u_)), x_), CustomConstraint(lambda f, x: FreeQ(f, x)))
  5622. rule7 = ReplacementRule(pattern7, lambda x, f, u : Mul(Log(f), SimplifyAntiderivative(u, x)))
  5623. replacer.add(rule7)
  5624. pattern8 = Pattern(UtilityOperator(Log(Add(a_, Mul(WC('b', S(1)), Tan(u_)))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda b, a: ZeroQ(Add(Pow(a, S(2)), Pow(b, S(2))))))
  5625. rule8 = ReplacementRule(pattern8, lambda x, b, u, a : Add(Mul(Mul(b, Pow(a, S(1))), SimplifyAntiderivative(u, x)), Mul(S(1), SimplifyAntiderivative(Log(Cos(u)), x))))
  5626. replacer.add(rule8)
  5627. pattern9 = Pattern(UtilityOperator(Log(Add(Mul(Cot(u_), WC('b', S(1))), a_)), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda b, a: ZeroQ(Add(Pow(a, S(2)), Pow(b, S(2))))))
  5628. rule9 = ReplacementRule(pattern9, lambda x, b, u, a : Add(Mul(Mul(Mul(S(1), b), Pow(a, S(1))), SimplifyAntiderivative(u, x)), Mul(S(1), SimplifyAntiderivative(Log(Sin(u)), x))))
  5629. replacer.add(rule9)
  5630. pattern10 = Pattern(UtilityOperator(ArcTan(Mul(WC('a', S(1)), Tan(u_))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda a: PositiveQ(Pow(a, S(2)))), CustomConstraint(lambda u: ComplexFreeQ(u)))
  5631. rule10 = ReplacementRule(pattern10, lambda x, u, a : RectifyTangent(u, a, S(1), x))
  5632. replacer.add(rule10)
  5633. pattern11 = Pattern(UtilityOperator(ArcCot(Mul(WC('a', S(1)), Tan(u_))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda a: PositiveQ(Pow(a, S(2)))), CustomConstraint(lambda u: ComplexFreeQ(u)))
  5634. rule11 = ReplacementRule(pattern11, lambda x, u, a : RectifyTangent(u, a, S(1), x))
  5635. replacer.add(rule11)
  5636. pattern12 = Pattern(UtilityOperator(ArcCot(Mul(WC('a', S(1)), Tanh(u_))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda u: ComplexFreeQ(u)))
  5637. rule12 = ReplacementRule(pattern12, lambda x, u, a : Mul(S(1), SimplifyAntiderivative(ArcTan(Mul(a, Tanh(u))), x)))
  5638. replacer.add(rule12)
  5639. pattern13 = Pattern(UtilityOperator(ArcTanh(Mul(WC('a', S(1)), Tan(u_))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda a: PositiveQ(Pow(a, S(2)))), CustomConstraint(lambda u: ComplexFreeQ(u)))
  5640. rule13 = ReplacementRule(pattern13, lambda x, u, a : RectifyTangent(u, Mul(I, a), Mul(S(1), I), x))
  5641. replacer.add(rule13)
  5642. pattern14 = Pattern(UtilityOperator(ArcCoth(Mul(WC('a', S(1)), Tan(u_))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda a: PositiveQ(Pow(a, S(2)))), CustomConstraint(lambda u: ComplexFreeQ(u)))
  5643. rule14 = ReplacementRule(pattern14, lambda x, u, a : RectifyTangent(u, Mul(I, a), Mul(S(1), I), x))
  5644. replacer.add(rule14)
  5645. pattern15 = Pattern(UtilityOperator(ArcTanh(Tanh(u_)), x_))
  5646. rule15 = ReplacementRule(pattern15, lambda x, u : SimplifyAntiderivative(u, x))
  5647. replacer.add(rule15)
  5648. pattern16 = Pattern(UtilityOperator(ArcCoth(Tanh(u_)), x_))
  5649. rule16 = ReplacementRule(pattern16, lambda x, u : SimplifyAntiderivative(u, x))
  5650. replacer.add(rule16)
  5651. pattern17 = Pattern(UtilityOperator(ArcCot(Mul(Cot(u_), WC('a', S(1)))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda a: PositiveQ(Pow(a, S(2)))), CustomConstraint(lambda u: ComplexFreeQ(u)))
  5652. rule17 = ReplacementRule(pattern17, lambda x, u, a : RectifyCotangent(u, a, S(1), x))
  5653. replacer.add(rule17)
  5654. pattern18 = Pattern(UtilityOperator(ArcTan(Mul(Cot(u_), WC('a', S(1)))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda a: PositiveQ(Pow(a, S(2)))), CustomConstraint(lambda u: ComplexFreeQ(u)))
  5655. rule18 = ReplacementRule(pattern18, lambda x, u, a : RectifyCotangent(u, a, S(1), x))
  5656. replacer.add(rule18)
  5657. pattern19 = Pattern(UtilityOperator(ArcTan(Mul(Coth(u_), WC('a', S(1)))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda u: ComplexFreeQ(u)))
  5658. rule19 = ReplacementRule(pattern19, lambda x, u, a : Mul(S(1), SimplifyAntiderivative(ArcTan(Mul(Tanh(u), Pow(a, S(1)))), x)))
  5659. replacer.add(rule19)
  5660. pattern20 = Pattern(UtilityOperator(ArcCoth(Mul(Cot(u_), WC('a', S(1)))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda a: PositiveQ(Pow(a, S(2)))), CustomConstraint(lambda u: ComplexFreeQ(u)))
  5661. rule20 = ReplacementRule(pattern20, lambda x, u, a : RectifyCotangent(u, Mul(I, a), I, x))
  5662. replacer.add(rule20)
  5663. pattern21 = Pattern(UtilityOperator(ArcTanh(Mul(Cot(u_), WC('a', S(1)))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda a: PositiveQ(Pow(a, S(2)))), CustomConstraint(lambda u: ComplexFreeQ(u)))
  5664. rule21 = ReplacementRule(pattern21, lambda x, u, a : RectifyCotangent(u, Mul(I, a), I, x))
  5665. replacer.add(rule21)
  5666. pattern22 = Pattern(UtilityOperator(ArcCoth(Coth(u_)), x_))
  5667. rule22 = ReplacementRule(pattern22, lambda x, u : SimplifyAntiderivative(u, x))
  5668. replacer.add(rule22)
  5669. pattern23 = Pattern(UtilityOperator(ArcTanh(Mul(Coth(u_), WC('a', S(1)))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda u: ComplexFreeQ(u)))
  5670. rule23 = ReplacementRule(pattern23, lambda x, u, a : SimplifyAntiderivative(ArcTanh(Mul(Tanh(u), Pow(a, S(1)))), x))
  5671. replacer.add(rule23)
  5672. pattern24 = Pattern(UtilityOperator(ArcTanh(Coth(u_)), x_))
  5673. rule24 = ReplacementRule(pattern24, lambda x, u : SimplifyAntiderivative(u, x))
  5674. replacer.add(rule24)
  5675. pattern25 = Pattern(UtilityOperator(ArcTan(Mul(WC('c', S(1)), Add(a_, Mul(WC('b', S(1)), Tan(u_))))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda c, x: FreeQ(c, x)), CustomConstraint(lambda c, a: PositiveQ(Mul(Pow(a, S(2)), Pow(c, S(2))))), CustomConstraint(lambda c, b: PositiveQ(Mul(Pow(b, S(2)), Pow(c, S(2))))), CustomConstraint(lambda u: ComplexFreeQ(u)))
  5676. rule25 = ReplacementRule(pattern25, lambda x, a, b, u, c : RectifyTangent(u, Mul(a, c), Mul(b, c), S(1), x))
  5677. replacer.add(rule25)
  5678. pattern26 = Pattern(UtilityOperator(ArcTanh(Mul(WC('c', S(1)), Add(a_, Mul(WC('b', S(1)), Tan(u_))))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda c, x: FreeQ(c, x)), CustomConstraint(lambda c, a: PositiveQ(Mul(Pow(a, S(2)), Pow(c, S(2))))), CustomConstraint(lambda c, b: PositiveQ(Mul(Pow(b, S(2)), Pow(c, S(2))))), CustomConstraint(lambda u: ComplexFreeQ(u)))
  5679. rule26 = ReplacementRule(pattern26, lambda x, a, b, u, c : RectifyTangent(u, Mul(I, a, c), Mul(I, b, c), Mul(S(1), I), x))
  5680. replacer.add(rule26)
  5681. pattern27 = Pattern(UtilityOperator(ArcTan(Mul(WC('c', S(1)), Add(Mul(Cot(u_), WC('b', S(1))), a_))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda c, x: FreeQ(c, x)), CustomConstraint(lambda c, a: PositiveQ(Mul(Pow(a, S(2)), Pow(c, S(2))))), CustomConstraint(lambda c, b: PositiveQ(Mul(Pow(b, S(2)), Pow(c, S(2))))), CustomConstraint(lambda u: ComplexFreeQ(u)))
  5682. rule27 = ReplacementRule(pattern27, lambda x, a, b, u, c : RectifyCotangent(u, Mul(a, c), Mul(b, c), S(1), x))
  5683. replacer.add(rule27)
  5684. pattern28 = Pattern(UtilityOperator(ArcTanh(Mul(WC('c', S(1)), Add(Mul(Cot(u_), WC('b', S(1))), a_))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda c, x: FreeQ(c, x)), CustomConstraint(lambda c, a: PositiveQ(Mul(Pow(a, S(2)), Pow(c, S(2))))), CustomConstraint(lambda c, b: PositiveQ(Mul(Pow(b, S(2)), Pow(c, S(2))))), CustomConstraint(lambda u: ComplexFreeQ(u)))
  5685. rule28 = ReplacementRule(pattern28, lambda x, a, b, u, c : RectifyCotangent(u, Mul(I, a, c), Mul(I, b, c), Mul(S(1), I), x))
  5686. replacer.add(rule28)
  5687. pattern29 = Pattern(UtilityOperator(ArcTan(Add(WC('a', S(0)), Mul(WC('b', S(1)), Tan(u_)), Mul(WC('c', S(1)), Pow(Tan(u_), S(2))))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda c, x: FreeQ(c, x)), CustomConstraint(lambda u: ComplexFreeQ(u)))
  5688. rule29 = ReplacementRule(pattern29, lambda x, a, b, u, c : If(EvenQ(Denominator(NumericFactor(Together(u)))), ArcTan(NormalizeTogether(Mul(Add(a, c, S(1), Mul(Add(a, Mul(S(1), c), S(1)), Cos(Mul(S(2), u))), Mul(b, Sin(Mul(S(2), u)))), Pow(Add(a, c, S(1), Mul(Add(a, Mul(S(1), c), S(1)), Cos(Mul(S(2), u))), Mul(b, Sin(Mul(S(2), u)))), S(1))))), ArcTan(NormalizeTogether(Mul(Add(c, Mul(Add(a, Mul(S(1), c), S(1)), Pow(Cos(u), S(2))), Mul(b, Cos(u), Sin(u))), Pow(Add(c, Mul(Add(a, Mul(S(1), c), S(1)), Pow(Cos(u), S(2))), Mul(b, Cos(u), Sin(u))), S(1)))))))
  5689. replacer.add(rule29)
  5690. pattern30 = Pattern(UtilityOperator(ArcTan(Add(WC('a', S(0)), Mul(WC('b', S(1)), Add(WC('d', S(0)), Mul(WC('e', S(1)), Tan(u_)))), Mul(WC('c', S(1)), Pow(Add(WC('f', S(0)), Mul(WC('g', S(1)), Tan(u_))), S(2))))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda c, x: FreeQ(c, x)), CustomConstraint(lambda u: ComplexFreeQ(u)))
  5691. rule30 = ReplacementRule(pattern30, lambda x, d, a, e, f, b, u, c, g : SimplifyAntiderivative(ArcTan(Add(a, Mul(b, d), Mul(c, Pow(f, S(2))), Mul(Add(Mul(b, e), Mul(S(2), c, f, g)), Tan(u)), Mul(c, Pow(g, S(2)), Pow(Tan(u), S(2))))), x))
  5692. replacer.add(rule30)
  5693. pattern31 = Pattern(UtilityOperator(ArcTan(Add(WC('a', S(0)), Mul(WC('c', S(1)), Pow(Tan(u_), S(2))))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda c, x: FreeQ(c, x)), CustomConstraint(lambda u: ComplexFreeQ(u)))
  5694. rule31 = ReplacementRule(pattern31, lambda x, c, u, a : If(EvenQ(Denominator(NumericFactor(Together(u)))), ArcTan(NormalizeTogether(Mul(Add(a, c, S(1), Mul(Add(a, Mul(S(1), c), S(1)), Cos(Mul(S(2), u)))), Pow(Add(a, c, S(1), Mul(Add(a, Mul(S(1), c), S(1)), Cos(Mul(S(2), u)))), S(1))))), ArcTan(NormalizeTogether(Mul(Add(c, Mul(Add(a, Mul(S(1), c), S(1)), Pow(Cos(u), S(2)))), Pow(Add(c, Mul(Add(a, Mul(S(1), c), S(1)), Pow(Cos(u), S(2)))), S(1)))))))
  5695. replacer.add(rule31)
  5696. pattern32 = Pattern(UtilityOperator(ArcTan(Add(WC('a', S(0)), Mul(WC('c', S(1)), Pow(Add(WC('f', S(0)), Mul(WC('g', S(1)), Tan(u_))), S(2))))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda c, x: FreeQ(c, x)), CustomConstraint(lambda u: ComplexFreeQ(u)))
  5697. rule32 = ReplacementRule(pattern32, lambda x, a, f, u, c, g : SimplifyAntiderivative(ArcTan(Add(a, Mul(c, Pow(f, S(2))), Mul(Mul(S(2), c, f, g), Tan(u)), Mul(c, Pow(g, S(2)), Pow(Tan(u), S(2))))), x))
  5698. replacer.add(rule32)
  5699. return replacer
  5700. @doctest_depends_on(modules=('matchpy',))
  5701. def SimplifyAntiderivative(expr, x):
  5702. r = SimplifyAntiderivative_replacer.replace(UtilityOperator(expr, x))
  5703. if isinstance(r, UtilityOperator):
  5704. if ProductQ(expr):
  5705. u, c = S(1), S(1)
  5706. for i in expr.args:
  5707. if FreeQ(i, x):
  5708. c *= i
  5709. else:
  5710. u *= i
  5711. if FreeQ(c, x) and c != S(1):
  5712. v = SimplifyAntiderivative(u, x)
  5713. if SumQ(v) and NonsumQ(u):
  5714. return Add(*[c*i for i in v.args])
  5715. return c*v
  5716. elif LogQ(expr):
  5717. F = expr.args[0]
  5718. if MemberQ([cot, sec, csc, coth, sech, csch], Head(F)):
  5719. return -SimplifyAntiderivative(Log(1/F), x)
  5720. if MemberQ([Log, atan, acot], Head(expr)):
  5721. F = Head(expr)
  5722. G = expr.args[0]
  5723. if MemberQ([cot, sec, csc, coth, sech, csch], Head(G)):
  5724. return -SimplifyAntiderivative(F(1/G), x)
  5725. if MemberQ([atanh, acoth], Head(expr)):
  5726. F = Head(expr)
  5727. G = expr.args[0]
  5728. if MemberQ([cot, sec, csc, coth, sech, csch], Head(G)):
  5729. return SimplifyAntiderivative(F(1/G), x)
  5730. u = expr
  5731. if FreeQ(u, x):
  5732. return S(0)
  5733. elif LogQ(u):
  5734. return Log(RemoveContent(u.args[0], x))
  5735. elif SumQ(u):
  5736. return SimplifyAntiderivativeSum(Add(*[SimplifyAntiderivative(i, x) for i in u.args]), x)
  5737. return u
  5738. else:
  5739. return r
  5740. @doctest_depends_on(modules=('matchpy',))
  5741. def _TrigSimplifyAux():
  5742. replacer = ManyToOneReplacer()
  5743. pattern1 = Pattern(UtilityOperator(Mul(WC('u', S(1)), Pow(Add(Mul(WC('a', S(1)), Pow(v_, WC('m', S(1)))), Mul(WC('b', S(1)), Pow(v_, WC('n', S(1))))), p_))), CustomConstraint(lambda v: InertTrigQ(v)), CustomConstraint(lambda p: IntegerQ(p)), CustomConstraint(lambda n, m: RationalQ(m, n)), CustomConstraint(lambda n, m: Less(m, n)))
  5744. rule1 = ReplacementRule(pattern1, lambda n, a, p, m, u, v, b : Mul(u, Pow(v, Mul(m, p)), Pow(TrigSimplifyAux(Add(a, Mul(b, Pow(v, Add(n, Mul(S(-1), m)))))), p)))
  5745. replacer.add(rule1)
  5746. pattern2 = Pattern(UtilityOperator(Add(Mul(Pow(cos(u_), S('2')), WC('a', S(1))), WC('v', S(0)), Mul(WC('b', S(1)), Pow(sin(u_), S('2'))))), CustomConstraint(lambda b, a: SameQ(a, b)))
  5747. rule2 = ReplacementRule(pattern2, lambda u, v, b, a : Add(a, v))
  5748. replacer.add(rule2)
  5749. pattern3 = Pattern(UtilityOperator(Add(WC('v', S(0)), Mul(WC('a', S(1)), Pow(sec(u_), S('2'))), Mul(WC('b', S(1)), Pow(tan(u_), S('2'))))), CustomConstraint(lambda b, a: SameQ(a, Mul(S(-1), b))))
  5750. rule3 = ReplacementRule(pattern3, lambda u, v, b, a : Add(a, v))
  5751. replacer.add(rule3)
  5752. pattern4 = Pattern(UtilityOperator(Add(Mul(Pow(csc(u_), S('2')), WC('a', S(1))), Mul(Pow(cot(u_), S('2')), WC('b', S(1))), WC('v', S(0)))), CustomConstraint(lambda b, a: SameQ(a, Mul(S(-1), b))))
  5753. rule4 = ReplacementRule(pattern4, lambda u, v, b, a : Add(a, v))
  5754. replacer.add(rule4)
  5755. pattern5 = Pattern(UtilityOperator(Pow(Add(Mul(Pow(cos(u_), S('2')), WC('a', S(1))), WC('v', S(0)), Mul(WC('b', S(1)), Pow(sin(u_), S('2')))), n_)))
  5756. rule5 = ReplacementRule(pattern5, lambda n, a, u, v, b : Pow(Add(Mul(Add(b, Mul(S(-1), a)), Pow(Sin(u), S('2'))), a, v), n))
  5757. replacer.add(rule5)
  5758. pattern6 = Pattern(UtilityOperator(Add(WC('w', S(0)), u_, Mul(WC('v', S(1)), Pow(sin(z_), S('2'))))), CustomConstraint(lambda u, v: SameQ(u, Mul(S(-1), v))))
  5759. rule6 = ReplacementRule(pattern6, lambda u, w, z, v : Add(Mul(u, Pow(Cos(z), S('2'))), w))
  5760. replacer.add(rule6)
  5761. pattern7 = Pattern(UtilityOperator(Add(Mul(Pow(cos(z_), S('2')), WC('v', S(1))), WC('w', S(0)), u_)), CustomConstraint(lambda u, v: SameQ(u, Mul(S(-1), v))))
  5762. rule7 = ReplacementRule(pattern7, lambda z, w, v, u : Add(Mul(u, Pow(Sin(z), S('2'))), w))
  5763. replacer.add(rule7)
  5764. pattern8 = Pattern(UtilityOperator(Add(WC('w', S(0)), u_, Mul(WC('v', S(1)), Pow(tan(z_), S('2'))))), CustomConstraint(lambda u, v: SameQ(u, v)))
  5765. rule8 = ReplacementRule(pattern8, lambda u, w, z, v : Add(Mul(u, Pow(Sec(z), S('2'))), w))
  5766. replacer.add(rule8)
  5767. pattern9 = Pattern(UtilityOperator(Add(Mul(Pow(cot(z_), S('2')), WC('v', S(1))), WC('w', S(0)), u_)), CustomConstraint(lambda u, v: SameQ(u, v)))
  5768. rule9 = ReplacementRule(pattern9, lambda z, w, v, u : Add(Mul(u, Pow(Csc(z), S('2'))), w))
  5769. replacer.add(rule9)
  5770. pattern10 = Pattern(UtilityOperator(Add(WC('w', S(0)), u_, Mul(WC('v', S(1)), Pow(sec(z_), S('2'))))), CustomConstraint(lambda u, v: SameQ(u, Mul(S(-1), v))))
  5771. rule10 = ReplacementRule(pattern10, lambda u, w, z, v : Add(Mul(v, Pow(Tan(z), S('2'))), w))
  5772. replacer.add(rule10)
  5773. pattern11 = Pattern(UtilityOperator(Add(Mul(Pow(csc(z_), S('2')), WC('v', S(1))), WC('w', S(0)), u_)), CustomConstraint(lambda u, v: SameQ(u, Mul(S(-1), v))))
  5774. rule11 = ReplacementRule(pattern11, lambda z, w, v, u : Add(Mul(v, Pow(Cot(z), S('2'))), w))
  5775. replacer.add(rule11)
  5776. pattern12 = Pattern(UtilityOperator(Mul(WC('u', S(1)), Pow(Add(Mul(cos(v_), WC('b', S(1))), a_), S(-1)), Pow(sin(v_), S('2')))), CustomConstraint(lambda b, a: ZeroQ(Add(Pow(a, S('2')), Mul(S(-1), Pow(b, S('2')))))))
  5777. rule12 = ReplacementRule(pattern12, lambda u, v, b, a : Mul(u, Add(Mul(S(1), Pow(a, S(-1))), Mul(S(-1), Mul(Cos(v), Pow(b, S(-1)))))))
  5778. replacer.add(rule12)
  5779. pattern13 = Pattern(UtilityOperator(Mul(Pow(cos(v_), S('2')), WC('u', S(1)), Pow(Add(a_, Mul(WC('b', S(1)), sin(v_))), S(-1)))), CustomConstraint(lambda b, a: ZeroQ(Add(Pow(a, S('2')), Mul(S(-1), Pow(b, S('2')))))))
  5780. rule13 = ReplacementRule(pattern13, lambda u, v, b, a : Mul(u, Add(Mul(S(1), Pow(a, S(-1))), Mul(S(-1), Mul(Sin(v), Pow(b, S(-1)))))))
  5781. replacer.add(rule13)
  5782. pattern14 = Pattern(UtilityOperator(Mul(WC('u', S(1)), Pow(tan(v_), WC('n', S(1))), Pow(Add(a_, Mul(WC('b', S(1)), Pow(tan(v_), WC('n', S(1))))), S(-1)))), CustomConstraint(lambda n: PositiveIntegerQ(n)), CustomConstraint(lambda a: NonsumQ(a)))
  5783. rule14 = ReplacementRule(pattern14, lambda n, a, u, v, b : Mul(u, Pow(Add(b, Mul(a, Pow(Cot(v), n))), S(-1))))
  5784. replacer.add(rule14)
  5785. pattern15 = Pattern(UtilityOperator(Mul(Pow(cot(v_), WC('n', S(1))), WC('u', S(1)), Pow(Add(Mul(Pow(cot(v_), WC('n', S(1))), WC('b', S(1))), a_), S(-1)))), CustomConstraint(lambda n: PositiveIntegerQ(n)), CustomConstraint(lambda a: NonsumQ(a)))
  5786. rule15 = ReplacementRule(pattern15, lambda n, a, u, v, b : Mul(u, Pow(Add(b, Mul(a, Pow(Tan(v), n))), S(-1))))
  5787. replacer.add(rule15)
  5788. pattern16 = Pattern(UtilityOperator(Mul(WC('u', S(1)), Pow(sec(v_), WC('n', S(1))), Pow(Add(a_, Mul(WC('b', S(1)), Pow(sec(v_), WC('n', S(1))))), S(-1)))), CustomConstraint(lambda n: PositiveIntegerQ(n)), CustomConstraint(lambda a: NonsumQ(a)))
  5789. rule16 = ReplacementRule(pattern16, lambda n, a, u, v, b : Mul(u, Pow(Add(b, Mul(a, Pow(Cos(v), n))), S(-1))))
  5790. replacer.add(rule16)
  5791. pattern17 = Pattern(UtilityOperator(Mul(Pow(csc(v_), WC('n', S(1))), WC('u', S(1)), Pow(Add(Mul(Pow(csc(v_), WC('n', S(1))), WC('b', S(1))), a_), S(-1)))), CustomConstraint(lambda n: PositiveIntegerQ(n)), CustomConstraint(lambda a: NonsumQ(a)))
  5792. rule17 = ReplacementRule(pattern17, lambda n, a, u, v, b : Mul(u, Pow(Add(b, Mul(a, Pow(Sin(v), n))), S(-1))))
  5793. replacer.add(rule17)
  5794. pattern18 = Pattern(UtilityOperator(Mul(WC('u', S(1)), Pow(Add(a_, Mul(WC('b', S(1)), Pow(sec(v_), WC('n', S(1))))), S(-1)), Pow(tan(v_), WC('n', S(1))))), CustomConstraint(lambda n: PositiveIntegerQ(n)), CustomConstraint(lambda a: NonsumQ(a)))
  5795. rule18 = ReplacementRule(pattern18, lambda n, a, u, v, b : Mul(u, Mul(Pow(Sin(v), n), Pow(Add(b, Mul(a, Pow(Cos(v), n))), S(-1)))))
  5796. replacer.add(rule18)
  5797. pattern19 = Pattern(UtilityOperator(Mul(Pow(cot(v_), WC('n', S(1))), WC('u', S(1)), Pow(Add(Mul(Pow(csc(v_), WC('n', S(1))), WC('b', S(1))), a_), S(-1)))), CustomConstraint(lambda n: PositiveIntegerQ(n)), CustomConstraint(lambda a: NonsumQ(a)))
  5798. rule19 = ReplacementRule(pattern19, lambda n, a, u, v, b : Mul(u, Mul(Pow(Cos(v), n), Pow(Add(b, Mul(a, Pow(Sin(v), n))), S(-1)))))
  5799. replacer.add(rule19)
  5800. pattern20 = Pattern(UtilityOperator(Mul(WC('u', S(1)), Pow(Add(Mul(WC('a', S(1)), Pow(sec(v_), WC('n', S(1)))), Mul(WC('b', S(1)), Pow(tan(v_), WC('n', S(1))))), WC('p', S(1))))), CustomConstraint(lambda n, p: IntegersQ(n, p)))
  5801. rule20 = ReplacementRule(pattern20, lambda n, a, p, u, v, b : Mul(u, Pow(Sec(v), Mul(n, p)), Pow(Add(a, Mul(b, Pow(Sin(v), n))), p)))
  5802. replacer.add(rule20)
  5803. pattern21 = Pattern(UtilityOperator(Mul(Pow(Add(Mul(Pow(csc(v_), WC('n', S(1))), WC('a', S(1))), Mul(Pow(cot(v_), WC('n', S(1))), WC('b', S(1)))), WC('p', S(1))), WC('u', S(1)))), CustomConstraint(lambda n, p: IntegersQ(n, p)))
  5804. rule21 = ReplacementRule(pattern21, lambda n, a, p, u, v, b : Mul(u, Pow(Csc(v), Mul(n, p)), Pow(Add(a, Mul(b, Pow(Cos(v), n))), p)))
  5805. replacer.add(rule21)
  5806. pattern22 = Pattern(UtilityOperator(Mul(WC('u', S(1)), Pow(Add(Mul(WC('b', S(1)), Pow(sin(v_), WC('n', S(1)))), Mul(WC('a', S(1)), Pow(tan(v_), WC('n', S(1))))), WC('p', S(1))))), CustomConstraint(lambda n, p: IntegersQ(n, p)))
  5807. rule22 = ReplacementRule(pattern22, lambda n, a, p, u, v, b : Mul(u, Pow(Tan(v), Mul(n, p)), Pow(Add(a, Mul(b, Pow(Cos(v), n))), p)))
  5808. replacer.add(rule22)
  5809. pattern23 = Pattern(UtilityOperator(Mul(Pow(Add(Mul(Pow(cot(v_), WC('n', S(1))), WC('a', S(1))), Mul(Pow(cos(v_), WC('n', S(1))), WC('b', S(1)))), WC('p', S(1))), WC('u', S(1)))), CustomConstraint(lambda n, p: IntegersQ(n, p)))
  5810. rule23 = ReplacementRule(pattern23, lambda n, a, p, u, v, b : Mul(u, Pow(Cot(v), Mul(n, p)), Pow(Add(a, Mul(b, Pow(Sin(v), n))), p)))
  5811. replacer.add(rule23)
  5812. pattern24 = Pattern(UtilityOperator(Mul(Pow(cos(v_), WC('m', S(1))), WC('u', S(1)), Pow(Add(WC('a', S(0)), Mul(WC('c', S(1)), Pow(sec(v_), WC('n', S(1)))), Mul(WC('b', S(1)), Pow(tan(v_), WC('n', S(1))))), WC('p', S(1))))), CustomConstraint(lambda n, p, m: IntegersQ(m, n, p)))
  5813. rule24 = ReplacementRule(pattern24, lambda n, a, c, p, m, u, v, b : Mul(u, Pow(Cos(v), Add(m, Mul(S(-1), Mul(n, p)))), Pow(Add(c, Mul(b, Pow(Sin(v), n)), Mul(a, Pow(Cos(v), n))), p)))
  5814. replacer.add(rule24)
  5815. pattern25 = Pattern(UtilityOperator(Mul(WC('u', S(1)), Pow(sec(v_), WC('m', S(1))), Pow(Add(WC('a', S(0)), Mul(WC('c', S(1)), Pow(sec(v_), WC('n', S(1)))), Mul(WC('b', S(1)), Pow(tan(v_), WC('n', S(1))))), WC('p', S(1))))), CustomConstraint(lambda n, p, m: IntegersQ(m, n, p)))
  5816. rule25 = ReplacementRule(pattern25, lambda n, a, c, p, m, u, v, b : Mul(u, Pow(Sec(v), Add(m, Mul(n, p))), Pow(Add(c, Mul(b, Pow(Sin(v), n)), Mul(a, Pow(Cos(v), n))), p)))
  5817. replacer.add(rule25)
  5818. pattern26 = Pattern(UtilityOperator(Mul(Pow(Add(WC('a', S(0)), Mul(Pow(cot(v_), WC('n', S(1))), WC('b', S(1))), Mul(Pow(csc(v_), WC('n', S(1))), WC('c', S(1)))), WC('p', S(1))), WC('u', S(1)), Pow(sin(v_), WC('m', S(1))))), CustomConstraint(lambda n, p, m: IntegersQ(m, n, p)))
  5819. rule26 = ReplacementRule(pattern26, lambda n, a, c, p, m, u, v, b : Mul(u, Pow(Sin(v), Add(m, Mul(S(-1), Mul(n, p)))), Pow(Add(c, Mul(b, Pow(Cos(v), n)), Mul(a, Pow(Sin(v), n))), p)))
  5820. replacer.add(rule26)
  5821. pattern27 = Pattern(UtilityOperator(Mul(Pow(csc(v_), WC('m', S(1))), Pow(Add(WC('a', S(0)), Mul(Pow(cot(v_), WC('n', S(1))), WC('b', S(1))), Mul(Pow(csc(v_), WC('n', S(1))), WC('c', S(1)))), WC('p', S(1))), WC('u', S(1)))), CustomConstraint(lambda n, p, m: IntegersQ(m, n, p)))
  5822. rule27 = ReplacementRule(pattern27, lambda n, a, c, p, m, u, v, b : Mul(u, Pow(Csc(v), Add(m, Mul(n, p))), Pow(Add(c, Mul(b, Pow(Cos(v), n)), Mul(a, Pow(Sin(v), n))), p)))
  5823. replacer.add(rule27)
  5824. pattern28 = Pattern(UtilityOperator(Mul(WC('u', S(1)), Pow(Add(Mul(Pow(csc(v_), WC('m', S(1))), WC('a', S(1))), Mul(WC('b', S(1)), Pow(sin(v_), WC('n', S(1))))), WC('p', S(1))))), CustomConstraint(lambda n, m: IntegersQ(m, n)))
  5825. rule28 = ReplacementRule(pattern28, lambda n, a, p, m, u, v, b : If(And(ZeroQ(Add(m, n, S(-2))), ZeroQ(Add(a, b))), Mul(u, Pow(Mul(a, Mul(Pow(Cos(v), S('2')), Pow(Pow(Sin(v), m), S(-1)))), p)), Mul(u, Pow(Mul(Add(a, Mul(b, Pow(Sin(v), Add(m, n)))), Pow(Pow(Sin(v), m), S(-1))), p))))
  5826. replacer.add(rule28)
  5827. pattern29 = Pattern(UtilityOperator(Mul(WC('u', S(1)), Pow(Add(Mul(Pow(cos(v_), WC('n', S(1))), WC('b', S(1))), Mul(WC('a', S(1)), Pow(sec(v_), WC('m', S(1))))), WC('p', S(1))))), CustomConstraint(lambda n, m: IntegersQ(m, n)))
  5828. rule29 = ReplacementRule(pattern29, lambda n, a, p, m, u, v, b : If(And(ZeroQ(Add(m, n, S(-2))), ZeroQ(Add(a, b))), Mul(u, Pow(Mul(a, Mul(Pow(Sin(v), S('2')), Pow(Pow(Cos(v), m), S(-1)))), p)), Mul(u, Pow(Mul(Add(a, Mul(b, Pow(Cos(v), Add(m, n)))), Pow(Pow(Cos(v), m), S(-1))), p))))
  5829. replacer.add(rule29)
  5830. pattern30 = Pattern(UtilityOperator(u_))
  5831. rule30 = ReplacementRule(pattern30, lambda u : u)
  5832. replacer.add(rule30)
  5833. return replacer
  5834. @doctest_depends_on(modules=('matchpy',))
  5835. def TrigSimplifyAux(expr):
  5836. return TrigSimplifyAux_replacer.replace(UtilityOperator(expr))
  5837. def Cancel(expr):
  5838. return cancel(expr)
  5839. class Util_Part(Function):
  5840. def doit(self):
  5841. i = Simplify(self.args[0])
  5842. if len(self.args) > 2 :
  5843. lst = list(self.args[1:])
  5844. else:
  5845. lst = self.args[1]
  5846. if isinstance(i, (int, Integer)):
  5847. if isinstance(lst, list):
  5848. return lst[i - 1]
  5849. elif AtomQ(lst):
  5850. return lst
  5851. return lst.args[i - 1]
  5852. else:
  5853. return self
  5854. def Part(lst, i): #see i = -1
  5855. if isinstance(lst, list):
  5856. return Util_Part(i, *lst).doit()
  5857. return Util_Part(i, lst).doit()
  5858. def PolyLog(n, p, z=None):
  5859. return polylog(n, p)
  5860. def D(f, x):
  5861. try:
  5862. return f.diff(x)
  5863. except ValueError:
  5864. return Function('D')(f, x)
  5865. def IntegralFreeQ(u):
  5866. return FreeQ(u, Integral)
  5867. def Dist(u, v, x):
  5868. #Dist(u,v) returns the sum of u times each term of v, provided v is free of Int
  5869. u = replace_pow_exp(u) # to replace back to SymPy's exp
  5870. v = replace_pow_exp(v)
  5871. w = Simp(u*x**2, x)/x**2
  5872. if u == 1:
  5873. return v
  5874. elif u == 0:
  5875. return 0
  5876. elif NumericFactor(u) < 0 and NumericFactor(-u) > 0:
  5877. return -Dist(-u, v, x)
  5878. elif SumQ(v):
  5879. return Add(*[Dist(u, i, x) for i in v.args])
  5880. elif IntegralFreeQ(v):
  5881. return Simp(u*v, x)
  5882. elif w != u and FreeQ(w, x) and w == Simp(w, x) and w == Simp(w*x**2, x)/x**2:
  5883. return Dist(w, v, x)
  5884. else:
  5885. return Simp(u*v, x)
  5886. def PureFunctionOfCothQ(u, v, x):
  5887. # If u is a pure function of Coth[v], PureFunctionOfCothQ[u,v,x] returns True;
  5888. if AtomQ(u):
  5889. return u != x
  5890. elif CalculusQ(u):
  5891. return False
  5892. elif HyperbolicQ(u) and ZeroQ(u.args[0] - v):
  5893. return CothQ(u)
  5894. return all(PureFunctionOfCothQ(i, v, x) for i in u.args)
  5895. def LogIntegral(z):
  5896. return li(z)
  5897. def ExpIntegralEi(z):
  5898. return Ei(z)
  5899. def ExpIntegralE(a, b):
  5900. return expint(a, b).evalf()
  5901. def SinIntegral(z):
  5902. return Si(z)
  5903. def CosIntegral(z):
  5904. return Ci(z)
  5905. def SinhIntegral(z):
  5906. return Shi(z)
  5907. def CoshIntegral(z):
  5908. return Chi(z)
  5909. class PolyGamma(Function):
  5910. @classmethod
  5911. def eval(cls, *args):
  5912. if len(args) == 2:
  5913. return polygamma(args[0], args[1])
  5914. return digamma(args[0])
  5915. def LogGamma(z):
  5916. return loggamma(z)
  5917. class ProductLog(Function):
  5918. @classmethod
  5919. def eval(cls, *args):
  5920. if len(args) == 2:
  5921. return LambertW(args[1], args[0]).evalf()
  5922. return LambertW(args[0]).evalf()
  5923. def Factorial(a):
  5924. return factorial(a)
  5925. def Zeta(*args):
  5926. return zeta(*args)
  5927. def HypergeometricPFQ(a, b, c):
  5928. return hyper(a, b, c)
  5929. def Sum_doit(exp, args):
  5930. """
  5931. This function perform summation using SymPy's `Sum`.
  5932. Examples
  5933. ========
  5934. >>> from sympy.integrals.rubi.utility_function import Sum_doit
  5935. >>> from sympy.abc import x
  5936. >>> Sum_doit(2*x + 2, [x, 0, 1.7])
  5937. 6
  5938. """
  5939. exp = replace_pow_exp(exp)
  5940. if not isinstance(args[2], (int, Integer)):
  5941. new_args = [args[0], args[1], Floor(args[2])]
  5942. return Sum(exp, new_args).doit()
  5943. return Sum(exp, args).doit()
  5944. def PolynomialQuotient(p, q, x):
  5945. try:
  5946. p = poly(p, x)
  5947. q = poly(q, x)
  5948. except:
  5949. p = poly(p)
  5950. q = poly(q)
  5951. try:
  5952. return quo(p, q).as_expr()
  5953. except (PolynomialDivisionFailed, UnificationFailed):
  5954. return p/q
  5955. def PolynomialRemainder(p, q, x):
  5956. try:
  5957. p = poly(p, x)
  5958. q = poly(q, x)
  5959. except:
  5960. p = poly(p)
  5961. q = poly(q)
  5962. try:
  5963. return rem(p, q).as_expr()
  5964. except (PolynomialDivisionFailed, UnificationFailed):
  5965. return S(0)
  5966. def Floor(x, a = None):
  5967. if a is None:
  5968. return floor(x)
  5969. return a*floor(x/a)
  5970. def Factor(var):
  5971. return factor(var)
  5972. def Rule(a, b):
  5973. return {a: b}
  5974. def Distribute(expr, *args):
  5975. if len(args) == 1:
  5976. if isinstance(expr, args[0]):
  5977. return expr
  5978. else:
  5979. return expr.expand()
  5980. if len(args) == 2:
  5981. if isinstance(expr, args[1]):
  5982. return expr.expand()
  5983. else:
  5984. return expr
  5985. return expr.expand()
  5986. def CoprimeQ(*args):
  5987. args = S(args)
  5988. g = gcd(*args)
  5989. if g == 1:
  5990. return True
  5991. return False
  5992. def Discriminant(a, b):
  5993. try:
  5994. return discriminant(a, b)
  5995. except PolynomialError:
  5996. return Function('Discriminant')(a, b)
  5997. def Negative(x):
  5998. return x < S(0)
  5999. def Quotient(m, n):
  6000. return Floor(m/n)
  6001. def process_trig(expr):
  6002. """
  6003. This function processes trigonometric expressions such that all `cot` is
  6004. rewritten in terms of `tan`, `sec` in terms of `cos`, `csc` in terms of `sin` and
  6005. similarly for `coth`, `sech` and `csch`.
  6006. Examples
  6007. ========
  6008. >>> from sympy.integrals.rubi.utility_function import process_trig
  6009. >>> from sympy.abc import x
  6010. >>> from sympy import coth, cot, csc
  6011. >>> process_trig(x*cot(x))
  6012. x/tan(x)
  6013. >>> process_trig(coth(x)*csc(x))
  6014. 1/(sin(x)*tanh(x))
  6015. """
  6016. expr = expr.replace(lambda x: isinstance(x, cot), lambda x: 1/tan(x.args[0]))
  6017. expr = expr.replace(lambda x: isinstance(x, sec), lambda x: 1/cos(x.args[0]))
  6018. expr = expr.replace(lambda x: isinstance(x, csc), lambda x: 1/sin(x.args[0]))
  6019. expr = expr.replace(lambda x: isinstance(x, coth), lambda x: 1/tanh(x.args[0]))
  6020. expr = expr.replace(lambda x: isinstance(x, sech), lambda x: 1/cosh(x.args[0]))
  6021. expr = expr.replace(lambda x: isinstance(x, csch), lambda x: 1/sinh(x.args[0]))
  6022. return expr
  6023. def _ExpandIntegrand():
  6024. Plus = Add
  6025. Times = Mul
  6026. def cons_f1(m):
  6027. return PositiveIntegerQ(m)
  6028. cons1 = CustomConstraint(cons_f1)
  6029. def cons_f2(d, c, b, a):
  6030. return ZeroQ(-a*d + b*c)
  6031. cons2 = CustomConstraint(cons_f2)
  6032. def cons_f3(a, x):
  6033. return FreeQ(a, x)
  6034. cons3 = CustomConstraint(cons_f3)
  6035. def cons_f4(b, x):
  6036. return FreeQ(b, x)
  6037. cons4 = CustomConstraint(cons_f4)
  6038. def cons_f5(c, x):
  6039. return FreeQ(c, x)
  6040. cons5 = CustomConstraint(cons_f5)
  6041. def cons_f6(d, x):
  6042. return FreeQ(d, x)
  6043. cons6 = CustomConstraint(cons_f6)
  6044. def cons_f7(e, x):
  6045. return FreeQ(e, x)
  6046. cons7 = CustomConstraint(cons_f7)
  6047. def cons_f8(f, x):
  6048. return FreeQ(f, x)
  6049. cons8 = CustomConstraint(cons_f8)
  6050. def cons_f9(g, x):
  6051. return FreeQ(g, x)
  6052. cons9 = CustomConstraint(cons_f9)
  6053. def cons_f10(h, x):
  6054. return FreeQ(h, x)
  6055. cons10 = CustomConstraint(cons_f10)
  6056. def cons_f11(e, b, c, f, n, p, F, x, d, m):
  6057. if not isinstance(x, Symbol):
  6058. return False
  6059. return FreeQ(List(F, b, c, d, e, f, m, n, p), x)
  6060. cons11 = CustomConstraint(cons_f11)
  6061. def cons_f12(F, x):
  6062. return FreeQ(F, x)
  6063. cons12 = CustomConstraint(cons_f12)
  6064. def cons_f13(m, x):
  6065. return FreeQ(m, x)
  6066. cons13 = CustomConstraint(cons_f13)
  6067. def cons_f14(n, x):
  6068. return FreeQ(n, x)
  6069. cons14 = CustomConstraint(cons_f14)
  6070. def cons_f15(p, x):
  6071. return FreeQ(p, x)
  6072. cons15 = CustomConstraint(cons_f15)
  6073. def cons_f16(e, b, c, f, n, a, p, F, x, d, m):
  6074. if not isinstance(x, Symbol):
  6075. return False
  6076. return FreeQ(List(F, a, b, c, d, e, f, m, n, p), x)
  6077. cons16 = CustomConstraint(cons_f16)
  6078. def cons_f17(n, m):
  6079. return IntegersQ(m, n)
  6080. cons17 = CustomConstraint(cons_f17)
  6081. def cons_f18(n):
  6082. return Less(n, S(0))
  6083. cons18 = CustomConstraint(cons_f18)
  6084. def cons_f19(x, u):
  6085. if not isinstance(x, Symbol):
  6086. return False
  6087. return PolynomialQ(u, x)
  6088. cons19 = CustomConstraint(cons_f19)
  6089. def cons_f20(G, F, u):
  6090. return SameQ(F(u)*G(u), S(1))
  6091. cons20 = CustomConstraint(cons_f20)
  6092. def cons_f21(q, x):
  6093. return FreeQ(q, x)
  6094. cons21 = CustomConstraint(cons_f21)
  6095. def cons_f22(F):
  6096. return MemberQ(List(ArcSin, ArcCos, ArcSinh, ArcCosh), F)
  6097. cons22 = CustomConstraint(cons_f22)
  6098. def cons_f23(j, n):
  6099. return ZeroQ(j - S(2)*n)
  6100. cons23 = CustomConstraint(cons_f23)
  6101. def cons_f24(A, x):
  6102. return FreeQ(A, x)
  6103. cons24 = CustomConstraint(cons_f24)
  6104. def cons_f25(B, x):
  6105. return FreeQ(B, x)
  6106. cons25 = CustomConstraint(cons_f25)
  6107. def cons_f26(m, u, x):
  6108. if not isinstance(x, Symbol):
  6109. return False
  6110. def _cons_f_u(d, w, c, p, x):
  6111. return And(FreeQ(List(c, d), x), IntegerQ(p), Greater(p, m))
  6112. cons_u = CustomConstraint(_cons_f_u)
  6113. pat = Pattern(UtilityOperator((c_ + x_*WC('d', S(1)))**p_*WC('w', S(1)), x_), cons_u)
  6114. result_matchq = is_match(UtilityOperator(u, x), pat)
  6115. return Not(And(PositiveIntegerQ(m), result_matchq))
  6116. cons26 = CustomConstraint(cons_f26)
  6117. def cons_f27(b, v, n, a, x, u, m):
  6118. if not isinstance(x, Symbol):
  6119. return False
  6120. return And(FreeQ(List(a, b, m), x), NegativeIntegerQ(n), Not(IntegerQ(m)), PolynomialQ(u, x), PolynomialQ(v, x),\
  6121. RationalQ(m), Less(m, -1), GreaterEqual(Exponent(u, x), (-n - IntegerPart(m))*Exponent(v, x)))
  6122. cons27 = CustomConstraint(cons_f27)
  6123. def cons_f28(v, n, x, u, m):
  6124. if not isinstance(x, Symbol):
  6125. return False
  6126. return And(FreeQ(List(a, b, m), x), NegativeIntegerQ(n), Not(IntegerQ(m)), PolynomialQ(u, x),\
  6127. PolynomialQ(v, x), GreaterEqual(Exponent(u, x), -n*Exponent(v, x)))
  6128. cons28 = CustomConstraint(cons_f28)
  6129. def cons_f29(n):
  6130. return PositiveIntegerQ(n/S(4))
  6131. cons29 = CustomConstraint(cons_f29)
  6132. def cons_f30(n):
  6133. return IntegerQ(n)
  6134. cons30 = CustomConstraint(cons_f30)
  6135. def cons_f31(n):
  6136. return Greater(n, S(1))
  6137. cons31 = CustomConstraint(cons_f31)
  6138. def cons_f32(n, m):
  6139. return Less(S(0), m, n)
  6140. cons32 = CustomConstraint(cons_f32)
  6141. def cons_f33(n, m):
  6142. return OddQ(n/GCD(m, n))
  6143. cons33 = CustomConstraint(cons_f33)
  6144. def cons_f34(a, b):
  6145. return PosQ(a/b)
  6146. cons34 = CustomConstraint(cons_f34)
  6147. def cons_f35(n, m, p):
  6148. return IntegersQ(m, n, p)
  6149. cons35 = CustomConstraint(cons_f35)
  6150. def cons_f36(n, m, p):
  6151. return Less(S(0), m, p, n)
  6152. cons36 = CustomConstraint(cons_f36)
  6153. def cons_f37(q, n, m, p):
  6154. return IntegersQ(m, n, p, q)
  6155. cons37 = CustomConstraint(cons_f37)
  6156. def cons_f38(n, q, m, p):
  6157. return Less(S(0), m, p, q, n)
  6158. cons38 = CustomConstraint(cons_f38)
  6159. def cons_f39(n):
  6160. return IntegerQ(n/S(2))
  6161. cons39 = CustomConstraint(cons_f39)
  6162. def cons_f40(p):
  6163. return NegativeIntegerQ(p)
  6164. cons40 = CustomConstraint(cons_f40)
  6165. def cons_f41(n, m):
  6166. return IntegersQ(m, n/S(2))
  6167. cons41 = CustomConstraint(cons_f41)
  6168. def cons_f42(n, m):
  6169. return Unequal(m, n/S(2))
  6170. cons42 = CustomConstraint(cons_f42)
  6171. def cons_f43(c, b, a):
  6172. return NonzeroQ(-S(4)*a*c + b**S(2))
  6173. cons43 = CustomConstraint(cons_f43)
  6174. def cons_f44(j, n, m):
  6175. return IntegersQ(m, n, j)
  6176. cons44 = CustomConstraint(cons_f44)
  6177. def cons_f45(n, m):
  6178. return Less(S(0), m, S(2)*n)
  6179. cons45 = CustomConstraint(cons_f45)
  6180. def cons_f46(n, m, p):
  6181. return Not(And(Equal(m, n), Equal(p, S(-1))))
  6182. cons46 = CustomConstraint(cons_f46)
  6183. def cons_f47(v, x):
  6184. if not isinstance(x, Symbol):
  6185. return False
  6186. return PolynomialQ(v, x)
  6187. cons47 = CustomConstraint(cons_f47)
  6188. def cons_f48(v, x):
  6189. if not isinstance(x, Symbol):
  6190. return False
  6191. return BinomialQ(v, x)
  6192. cons48 = CustomConstraint(cons_f48)
  6193. def cons_f49(v, x, u):
  6194. if not isinstance(x, Symbol):
  6195. return False
  6196. return Inequality(Exponent(u, x), Equal, Exponent(v, x) + S(-1), GreaterEqual, S(2))
  6197. cons49 = CustomConstraint(cons_f49)
  6198. def cons_f50(v, x, u):
  6199. if not isinstance(x, Symbol):
  6200. return False
  6201. return GreaterEqual(Exponent(u, x), Exponent(v, x))
  6202. cons50 = CustomConstraint(cons_f50)
  6203. def cons_f51(p):
  6204. return Not(IntegerQ(p))
  6205. cons51 = CustomConstraint(cons_f51)
  6206. def With2(e, b, c, f, n, a, g, h, x, d, m):
  6207. tmp = a*h - b*g
  6208. k = Symbol('k')
  6209. return f**(e*(c + d*x)**n)*SimplifyTerm(h**(-m)*tmp**m, x)/(g + h*x) + Sum_doit(f**(e*(c + d*x)**n)*(a + b*x)**(-k + m)*SimplifyTerm(b*h**(-k)*tmp**(k - 1), x), List(k, 1, m))
  6210. pattern2 = Pattern(UtilityOperator(f_**((x_*WC('d', S(1)) + WC('c', S(0)))**WC('n', S(1))*WC('e', S(1)))*(x_*WC('b', S(1)) + WC('a', S(0)))**WC('m', S(1))/(x_*WC('h', S(1)) + WC('g', S(0))), x_), cons3, cons4, cons5, cons6, cons7, cons8, cons9, cons10, cons1, cons2)
  6211. rule2 = ReplacementRule(pattern2, With2)
  6212. pattern3 = Pattern(UtilityOperator(F_**((x_*WC('d', S(1)) + WC('c', S(0)))**WC('n', S(1))*WC('b', S(1)))*x_**WC('m', S(1))*(e_ + x_*WC('f', S(1)))**WC('p', S(1)), x_), cons12, cons4, cons5, cons6, cons7, cons8, cons13, cons14, cons15, cons11)
  6213. def replacement3(e, b, c, f, n, p, F, x, d, m):
  6214. return If(And(PositiveIntegerQ(m, p), LessEqual(m, p), Or(EqQ(n, S(1)), ZeroQ(-c*f + d*e))), ExpandLinearProduct(F**(b*(c + d*x)**n)*(e + f*x)**p, x**m, e, f, x), If(PositiveIntegerQ(p), Distribute(F**(b*(c + d*x)**n)*x**m*(e + f*x)**p, Plus, Times), ExpandIntegrand(F**(b*(c + d*x)**n), x**m*(e + f*x)**p, x)))
  6215. rule3 = ReplacementRule(pattern3, replacement3)
  6216. pattern4 = Pattern(UtilityOperator(F_**((x_*WC('d', S(1)) + WC('c', S(0)))**WC('n', S(1))*WC('b', S(1)) + WC('a', S(0)))*x_**WC('m', S(1))*(e_ + x_*WC('f', S(1)))**WC('p', S(1)), x_), cons12, cons3, cons4, cons5, cons6, cons7, cons8, cons13, cons14, cons15, cons16)
  6217. def replacement4(e, b, c, f, n, a, p, F, x, d, m):
  6218. return If(And(PositiveIntegerQ(m, p), LessEqual(m, p), Or(EqQ(n, S(1)), ZeroQ(-c*f + d*e))), ExpandLinearProduct(F**(a + b*(c + d*x)**n)*(e + f*x)**p, x**m, e, f, x), If(PositiveIntegerQ(p), Distribute(F**(a + b*(c + d*x)**n)*x**m*(e + f*x)**p, Plus, Times), ExpandIntegrand(F**(a + b*(c + d*x)**n), x**m*(e + f*x)**p, x)))
  6219. rule4 = ReplacementRule(pattern4, replacement4)
  6220. def With5(b, v, c, n, a, F, u, x, d, m):
  6221. if not isinstance(x, Symbol) or not (FreeQ([F, a, b, c, d], x) and IntegersQ(m, n) and n < 0):
  6222. return False
  6223. w = ExpandIntegrand((a + b*x)**m*(c + d*x)**n, x)
  6224. w = ReplaceAll(w, Rule(x, F**v))
  6225. if SumQ(w):
  6226. return True
  6227. return False
  6228. pattern5 = Pattern(UtilityOperator((F_**v_*WC('b', S(1)) + a_)**WC('m', S(1))*(F_**v_*WC('d', S(1)) + c_)**n_*WC('u', S(1)), x_), cons12, cons3, cons4, cons5, cons6, cons17, cons18, CustomConstraint(With5))
  6229. def replacement5(b, v, c, n, a, F, u, x, d, m):
  6230. w = ReplaceAll(ExpandIntegrand((a + b*x)**m*(c + d*x)**n, x), Rule(x, F**v))
  6231. return w.func(*[u*i for i in w.args])
  6232. rule5 = ReplacementRule(pattern5, replacement5)
  6233. def With6(e, b, c, f, n, a, x, u, d, m):
  6234. if not isinstance(x, Symbol) or not (FreeQ([a, b, c, d, e, f, m, n], x) and PolynomialQ(u,x)):
  6235. return False
  6236. v = ExpandIntegrand(u*(a + b*x)**m, x)
  6237. if SumQ(v):
  6238. return True
  6239. return False
  6240. pattern6 = Pattern(UtilityOperator(f_**((x_*WC('d', S(1)) + WC('c', S(0)))**WC('n', S(1))*WC('e', S(1)))*u_*(x_*WC('b', S(1)) + WC('a', S(0)))**WC('m', S(1)), x_), cons3, cons4, cons5, cons6, cons7, cons8, cons13, cons14, cons19, CustomConstraint(With6))
  6241. def replacement6(e, b, c, f, n, a, x, u, d, m):
  6242. v = ExpandIntegrand(u*(a + b*x)**m, x)
  6243. return Distribute(f**(e*(c + d*x)**n)*v, Plus, Times)
  6244. rule6 = ReplacementRule(pattern6, replacement6)
  6245. pattern7 = Pattern(UtilityOperator(u_*(x_*WC('b', S(1)) + WC('a', S(0)))**WC('m', S(1))*Log((x_**WC('n', S(1))*WC('e', S(1)) + WC('d', S(0)))**WC('p', S(1))*WC('c', S(1))), x_), cons3, cons4, cons5, cons6, cons7, cons13, cons14, cons15, cons19)
  6246. def replacement7(e, b, c, n, a, p, x, u, d, m):
  6247. return ExpandIntegrand(Log(c*(d + e*x**n)**p), u*(a + b*x)**m, x)
  6248. rule7 = ReplacementRule(pattern7, replacement7)
  6249. pattern8 = Pattern(UtilityOperator(f_**((x_*WC('d', S(1)) + WC('c', S(0)))**WC('n', S(1))*WC('e', S(1)))*u_, x_), cons5, cons6, cons7, cons8, cons14, cons19)
  6250. def replacement8(e, c, f, n, x, u, d):
  6251. return If(EqQ(n, S(1)), ExpandIntegrand(f**(e*(c + d*x)**n), u, x), ExpandLinearProduct(f**(e*(c + d*x)**n), u, c, d, x))
  6252. rule8 = ReplacementRule(pattern8, replacement8)
  6253. # pattern9 = Pattern(UtilityOperator(F_**u_*(G_*u_*WC('b', S(1)) + a_)**WC('n', S(1)), x_), cons3, cons4, cons17, cons20)
  6254. # def replacement9(b, G, n, a, F, u, x, m):
  6255. # return ReplaceAll(ExpandIntegrand(x**(-m)*(a + b*x)**n, x), Rule(x, G(u)))
  6256. # rule9 = ReplacementRule(pattern9, replacement9)
  6257. pattern10 = Pattern(UtilityOperator(u_*(WC('a', S(0)) + WC('b', S(1))*Log(((x_*WC('f', S(1)) + WC('e', S(0)))**WC('p', S(1))*WC('d', S(1)))**WC('q', S(1))*WC('c', S(1))))**n_, x_), cons3, cons4, cons5, cons6, cons7, cons8, cons14, cons15, cons21, cons19)
  6258. def replacement10(e, b, c, f, n, a, p, x, u, d, q):
  6259. return ExpandLinearProduct((a + b*Log(c*(d*(e + f*x)**p)**q))**n, u, e, f, x)
  6260. rule10 = ReplacementRule(pattern10, replacement10)
  6261. # pattern11 = Pattern(UtilityOperator(u_*(F_*(x_*WC('d', S(1)) + WC('c', S(0)))*WC('b', S(1)) + WC('a', S(0)))**n_, x_), cons3, cons4, cons5, cons6, cons14, cons19, cons22)
  6262. # def replacement11(b, c, n, a, F, u, x, d):
  6263. # return ExpandLinearProduct((a + b*F(c + d*x))**n, u, c, d, x)
  6264. # rule11 = ReplacementRule(pattern11, replacement11)
  6265. pattern12 = Pattern(UtilityOperator(WC('u', S(1))/(x_**n_*WC('a', S(1)) + sqrt(c_ + x_**j_*WC('d', S(1)))*WC('b', S(1))), x_), cons3, cons4, cons5, cons6, cons14, cons23)
  6266. def replacement12(b, c, n, a, x, u, d, j):
  6267. return ExpandIntegrand(u*(a*x**n - b*sqrt(c + d*x**(S(2)*n)))/(-b**S(2)*c + x**(S(2)*n)*(a**S(2) - b**S(2)*d)), x)
  6268. rule12 = ReplacementRule(pattern12, replacement12)
  6269. pattern13 = Pattern(UtilityOperator((a_ + x_*WC('b', S(1)))**m_/(c_ + x_*WC('d', S(1))), x_), cons3, cons4, cons5, cons6, cons1)
  6270. def replacement13(b, c, a, x, d, m):
  6271. if RationalQ(a, b, c, d):
  6272. return ExpandExpression((a + b*x)**m/(c + d*x), x)
  6273. else:
  6274. tmp = a*d - b*c
  6275. k = Symbol("k")
  6276. return Sum_doit((a + b*x)**(-k + m)*SimplifyTerm(b*d**(-k)*tmp**(k + S(-1)), x), List(k, S(1), m)) + SimplifyTerm(d**(-m)*tmp**m, x)/(c + d*x)
  6277. rule13 = ReplacementRule(pattern13, replacement13)
  6278. pattern14 = Pattern(UtilityOperator((A_ + x_*WC('B', S(1)))*(a_ + x_*WC('b', S(1)))**WC('m', S(1))/(c_ + x_*WC('d', S(1))), x_), cons3, cons4, cons5, cons6, cons24, cons25, cons1)
  6279. def replacement14(b, B, A, c, a, x, d, m):
  6280. if RationalQ(a, b, c, d, A, B):
  6281. return ExpandExpression((A + B*x)*(a + b*x)**m/(c + d*x), x)
  6282. else:
  6283. tmp1 = (A*d - B*c)/d
  6284. tmp2 = ExpandIntegrand((a + b*x)**m/(c + d*x), x)
  6285. tmp2 = If(SumQ(tmp2), tmp2.func(*[SimplifyTerm(tmp1*i, x) for i in tmp2.args]), SimplifyTerm(tmp1*tmp2, x))
  6286. return SimplifyTerm(B/d, x)*(a + b*x)**m + tmp2
  6287. rule14 = ReplacementRule(pattern14, replacement14)
  6288. def With15(b, a, x, u, m):
  6289. tmp1 = ExpandLinearProduct((a + b*x)**m, u, a, b, x)
  6290. if not IntegerQ(m):
  6291. return tmp1
  6292. else:
  6293. tmp2 = ExpandExpression(u*(a + b*x)**m, x)
  6294. if SumQ(tmp2) and LessEqual(LeafCount(tmp2), LeafCount(tmp1) + S(2)):
  6295. return tmp2
  6296. else:
  6297. return tmp1
  6298. pattern15 = Pattern(UtilityOperator(u_*(a_ + x_*WC('b', S(1)))**m_, x_), cons3, cons4, cons13, cons19, cons26)
  6299. rule15 = ReplacementRule(pattern15, With15)
  6300. pattern16 = Pattern(UtilityOperator(u_*v_**n_*(a_ + x_*WC('b', S(1)))**m_, x_), cons27)
  6301. def replacement16(b, v, n, a, x, u, m):
  6302. s = PolynomialQuotientRemainder(u, v**(-n)*(a+b*x)**(-IntegerPart(m)), x)
  6303. return ExpandIntegrand((a + b*x)**FractionalPart(m)*s[0], x) + ExpandIntegrand(v**n*(a + b*x)**m*s[1], x)
  6304. rule16 = ReplacementRule(pattern16, replacement16)
  6305. pattern17 = Pattern(UtilityOperator(u_*v_**n_*(a_ + x_*WC('b', S(1)))**m_, x_), cons28)
  6306. def replacement17(b, v, n, a, x, u, m):
  6307. s = PolynomialQuotientRemainder(u, v**(-n),x)
  6308. return ExpandIntegrand((a + b*x)**(m)*s[0], x) + ExpandIntegrand(v**n*(a + b*x)**m*s[1], x)
  6309. rule17 = ReplacementRule(pattern17, replacement17)
  6310. def With18(b, n, a, x, u):
  6311. r = Numerator(Rt(-a/b, S(2)))
  6312. s = Denominator(Rt(-a/b, S(2)))
  6313. return r/(S(2)*a*(r + s*u**(n/S(2)))) + r/(S(2)*a*(r - s*u**(n/S(2))))
  6314. pattern18 = Pattern(UtilityOperator(S(1)/(a_ + u_**n_*WC('b', S(1))), x_), cons3, cons4, cons29)
  6315. rule18 = ReplacementRule(pattern18, With18)
  6316. def With19(b, n, a, x, u):
  6317. k = Symbol("k")
  6318. r = Numerator(Rt(-a/b, n))
  6319. s = Denominator(Rt(-a/b, n))
  6320. return Sum_doit(r/(a*n*(-(-1)**(2*k/n)*s*u + r)), List(k, 1, n))
  6321. pattern19 = Pattern(UtilityOperator(S(1)/(a_ + u_**n_*WC('b', S(1))), x_), cons3, cons4, cons30, cons31)
  6322. rule19 = ReplacementRule(pattern19, With19)
  6323. def With20(b, n, a, x, u, m):
  6324. k = Symbol("k")
  6325. g = GCD(m, n)
  6326. r = Numerator(Rt(a/b, n/GCD(m, n)))
  6327. s = Denominator(Rt(a/b, n/GCD(m, n)))
  6328. return If(CoprimeQ(g + m, n), Sum_doit((-1)**(-2*k*m/n)*r*(-r/s)**(m/g)/(a*n*((-1)**(2*g*k/n)*s*u**g + r)), List(k, 1, n/g)), Sum_doit((-1)**(2*k*(g + m)/n)*r*(-r/s)**(m/g)/(a*n*((-1)**(2*g*k/n)*r + s*u**g)), List(k, 1, n/g)))
  6329. pattern20 = Pattern(UtilityOperator(u_**WC('m', S(1))/(a_ + u_**n_*WC('b', S(1))), x_), cons3, cons4, cons17, cons32, cons33, cons34)
  6330. rule20 = ReplacementRule(pattern20, With20)
  6331. def With21(b, n, a, x, u, m):
  6332. k = Symbol("k")
  6333. g = GCD(m, n)
  6334. r = Numerator(Rt(-a/b, n/GCD(m, n)))
  6335. s = Denominator(Rt(-a/b, n/GCD(m, n)))
  6336. return If(Equal(n/g, S(2)), s/(S(2)*b*(r + s*u**g)) - s/(S(2)*b*(r - s*u**g)), If(CoprimeQ(g + m, n), Sum_doit((S(-1))**(-S(2)*k*m/n)*r*(r/s)**(m/g)/(a*n*(-(S(-1))**(S(2)*g*k/n)*s*u**g + r)), List(k, S(1), n/g)), Sum_doit((S(-1))**(S(2)*k*(g + m)/n)*r*(r/s)**(m/g)/(a*n*((S(-1))**(S(2)*g*k/n)*r - s*u**g)), List(k, S(1), n/g))))
  6337. pattern21 = Pattern(UtilityOperator(u_**WC('m', S(1))/(a_ + u_**n_*WC('b', S(1))), x_), cons3, cons4, cons17, cons32)
  6338. rule21 = ReplacementRule(pattern21, With21)
  6339. def With22(b, c, n, a, x, u, d, m):
  6340. k = Symbol("k")
  6341. r = Numerator(Rt(-a/b, n))
  6342. s = Denominator(Rt(-a/b, n))
  6343. return Sum_doit((c*r + (-1)**(-2*k*m/n)*d*r*(r/s)**m)/(a*n*(-(-1)**(2*k/n)*s*u + r)), List(k, 1, n))
  6344. pattern22 = Pattern(UtilityOperator((c_ + u_**WC('m', S(1))*WC('d', S(1)))/(a_ + u_**n_*WC('b', S(1))), x_), cons3, cons4, cons5, cons6, cons17, cons32)
  6345. rule22 = ReplacementRule(pattern22, With22)
  6346. def With23(e, b, c, n, a, p, x, u, d, m):
  6347. k = Symbol("k")
  6348. r = Numerator(Rt(-a/b, n))
  6349. s = Denominator(Rt(-a/b, n))
  6350. return Sum_doit((c*r + (-1)**(-2*k*p/n)*e*r*(r/s)**p + (-1)**(-2*k*m/n)*d*r*(r/s)**m)/(a*n*(-(-1)**(2*k/n)*s*u + r)), List(k, 1, n))
  6351. pattern23 = Pattern(UtilityOperator((u_**p_*WC('e', S(1)) + u_**WC('m', S(1))*WC('d', S(1)) + WC('c', S(0)))/(a_ + u_**n_*WC('b', S(1))), x_), cons3, cons4, cons5, cons6, cons7, cons35, cons36)
  6352. rule23 = ReplacementRule(pattern23, With23)
  6353. def With24(e, b, c, f, n, a, p, x, u, d, q, m):
  6354. k = Symbol("k")
  6355. r = Numerator(Rt(-a/b, n))
  6356. s = Denominator(Rt(-a/b, n))
  6357. return Sum_doit((c*r + (-1)**(-2*k*q/n)*f*r*(r/s)**q + (-1)**(-2*k*p/n)*e*r*(r/s)**p + (-1)**(-2*k*m/n)*d*r*(r/s)**m)/(a*n*(-(-1)**(2*k/n)*s*u + r)), List(k, 1, n))
  6358. pattern24 = Pattern(UtilityOperator((u_**p_*WC('e', S(1)) + u_**q_*WC('f', S(1)) + u_**WC('m', S(1))*WC('d', S(1)) + WC('c', S(0)))/(a_ + u_**n_*WC('b', S(1))), x_), cons3, cons4, cons5, cons6, cons7, cons8, cons37, cons38)
  6359. rule24 = ReplacementRule(pattern24, With24)
  6360. def With25(c, n, a, p, x, u):
  6361. q = Symbol('q')
  6362. return ReplaceAll(ExpandIntegrand(c**(-p), (c*x - q)**p*(c*x + q)**p, x), List(Rule(q, Rt(-a*c, S(2))), Rule(x, u**(n/S(2)))))
  6363. pattern25 = Pattern(UtilityOperator((a_ + u_**WC('n', S(1))*WC('c', S(1)))**p_, x_), cons3, cons5, cons39, cons40)
  6364. rule25 = ReplacementRule(pattern25, With25)
  6365. def With26(c, n, a, p, x, u, m):
  6366. q = Symbol('q')
  6367. return ReplaceAll(ExpandIntegrand(c**(-p), x**m*(c*x**(n/S(2)) - q)**p*(c*x**(n/S(2)) + q)**p, x), List(Rule(q, Rt(-a*c, S(2))), Rule(x, u)))
  6368. pattern26 = Pattern(UtilityOperator(u_**WC('m', S(1))*(u_**WC('n', S(1))*WC('c', S(1)) + WC('a', S(0)))**p_, x_), cons3, cons5, cons41, cons40, cons32, cons42)
  6369. rule26 = ReplacementRule(pattern26, With26)
  6370. def With27(b, c, n, a, p, x, u, j):
  6371. q = Symbol('q')
  6372. return ReplaceAll(ExpandIntegrand(S(4)**(-p)*c**(-p), (b + S(2)*c*x - q)**p*(b + S(2)*c*x + q)**p, x), List(Rule(q, Rt(-S(4)*a*c + b**S(2), S(2))), Rule(x, u**n)))
  6373. pattern27 = Pattern(UtilityOperator((u_**WC('j', S(1))*WC('c', S(1)) + u_**WC('n', S(1))*WC('b', S(1)) + WC('a', S(0)))**p_, x_), cons3, cons4, cons5, cons30, cons23, cons40, cons43)
  6374. rule27 = ReplacementRule(pattern27, With27)
  6375. def With28(b, c, n, a, p, x, u, j, m):
  6376. q = Symbol('q')
  6377. return ReplaceAll(ExpandIntegrand(S(4)**(-p)*c**(-p), x**m*(b + S(2)*c*x**n - q)**p*(b + S(2)*c*x**n + q)**p, x), List(Rule(q, Rt(-S(4)*a*c + b**S(2), S(2))), Rule(x, u)))
  6378. pattern28 = Pattern(UtilityOperator(u_**WC('m', S(1))*(u_**WC('j', S(1))*WC('c', S(1)) + u_**WC('n', S(1))*WC('b', S(1)) + WC('a', S(0)))**p_, x_), cons3, cons4, cons5, cons44, cons23, cons40, cons45, cons46, cons43)
  6379. rule28 = ReplacementRule(pattern28, With28)
  6380. def With29(b, c, n, a, x, u, d, j):
  6381. q = Rt(-a/b, S(2))
  6382. return -(c - d*q)/(S(2)*b*q*(q + u**n)) - (c + d*q)/(S(2)*b*q*(q - u**n))
  6383. pattern29 = Pattern(UtilityOperator((u_**WC('n', S(1))*WC('d', S(1)) + WC('c', S(0)))/(a_ + u_**WC('j', S(1))*WC('b', S(1))), x_), cons3, cons4, cons5, cons6, cons14, cons23)
  6384. rule29 = ReplacementRule(pattern29, With29)
  6385. def With30(e, b, c, f, n, a, g, x, u, d, j):
  6386. q = Rt(-S(4)*a*c + b**S(2), S(2))
  6387. r = TogetherSimplify((-b*e*g + S(2)*c*(d + e*f))/q)
  6388. return (e*g - r)/(b + 2*c*u**n + q) + (e*g + r)/(b + 2*c*u**n - q)
  6389. pattern30 = Pattern(UtilityOperator(((u_**WC('n', S(1))*WC('g', S(1)) + WC('f', S(0)))*WC('e', S(1)) + WC('d', S(0)))/(u_**WC('j', S(1))*WC('c', S(1)) + u_**WC('n', S(1))*WC('b', S(1)) + WC('a', S(0))), x_), cons3, cons4, cons5, cons6, cons7, cons8, cons9, cons14, cons23, cons43)
  6390. rule30 = ReplacementRule(pattern30, With30)
  6391. def With31(v, x, u):
  6392. lst = CoefficientList(u, x)
  6393. i = Symbol('i')
  6394. return x**Exponent(u, x)*lst[-1]/v + Sum_doit(x**(i - 1)*Part(lst, i), List(i, 1, Exponent(u, x)))/v
  6395. pattern31 = Pattern(UtilityOperator(u_/v_, x_), cons19, cons47, cons48, cons49)
  6396. rule31 = ReplacementRule(pattern31, With31)
  6397. pattern32 = Pattern(UtilityOperator(u_/v_, x_), cons19, cons47, cons50)
  6398. def replacement32(v, x, u):
  6399. return PolynomialDivide(u, v, x)
  6400. rule32 = ReplacementRule(pattern32, replacement32)
  6401. pattern33 = Pattern(UtilityOperator(u_*(x_*WC('a', S(1)))**p_, x_), cons51, cons19)
  6402. def replacement33(x, a, u, p):
  6403. return ExpandToSum((a*x)**p, u, x)
  6404. rule33 = ReplacementRule(pattern33, replacement33)
  6405. pattern34 = Pattern(UtilityOperator(v_**p_*WC('u', S(1)), x_), cons51)
  6406. def replacement34(v, x, u, p):
  6407. return ExpandIntegrand(NormalizeIntegrand(v**p, x), u, x)
  6408. rule34 = ReplacementRule(pattern34, replacement34)
  6409. pattern35 = Pattern(UtilityOperator(u_, x_))
  6410. def replacement35(x, u):
  6411. return ExpandExpression(u, x)
  6412. rule35 = ReplacementRule(pattern35, replacement35)
  6413. return [ rule2,rule3, rule4, rule5, rule6, rule7, rule8, rule10, rule12, rule13, rule14, rule15, rule16, rule17, rule18, rule19, rule20, rule21, rule22, rule23, rule24, rule25, rule26, rule27, rule28, rule29, rule30, rule31, rule32, rule33, rule34, rule35]
  6414. def _RemoveContentAux():
  6415. def cons_f1(b, a):
  6416. return IntegersQ(a, b)
  6417. cons1 = CustomConstraint(cons_f1)
  6418. def cons_f2(b, a):
  6419. return Equal(a + b, S(0))
  6420. cons2 = CustomConstraint(cons_f2)
  6421. def cons_f3(m):
  6422. return RationalQ(m)
  6423. cons3 = CustomConstraint(cons_f3)
  6424. def cons_f4(m, n):
  6425. return RationalQ(m, n)
  6426. cons4 = CustomConstraint(cons_f4)
  6427. def cons_f5(m, n):
  6428. return GreaterEqual(-m + n, S(0))
  6429. cons5 = CustomConstraint(cons_f5)
  6430. def cons_f6(a, x):
  6431. return FreeQ(a, x)
  6432. cons6 = CustomConstraint(cons_f6)
  6433. def cons_f7(m, n, p):
  6434. return RationalQ(m, n, p)
  6435. cons7 = CustomConstraint(cons_f7)
  6436. def cons_f8(m, p):
  6437. return GreaterEqual(-m + p, S(0))
  6438. cons8 = CustomConstraint(cons_f8)
  6439. pattern1 = Pattern(UtilityOperator(a_**m_*WC('u', S(1)) + b_*WC('v', S(1)), x_), cons1, cons2, cons3)
  6440. def replacement1(v, x, a, u, m, b):
  6441. return If(Greater(m, S(1)), RemoveContentAux(a**(m + S(-1))*u - v, x), RemoveContentAux(-a**(-m + S(1))*v + u, x))
  6442. rule1 = ReplacementRule(pattern1, replacement1)
  6443. pattern2 = Pattern(UtilityOperator(a_**WC('m', S(1))*WC('u', S(1)) + a_**WC('n', S(1))*WC('v', S(1)), x_), cons6, cons4, cons5)
  6444. def replacement2(n, v, x, u, m, a):
  6445. return RemoveContentAux(a**(-m + n)*v + u, x)
  6446. rule2 = ReplacementRule(pattern2, replacement2)
  6447. pattern3 = Pattern(UtilityOperator(a_**WC('m', S(1))*WC('u', S(1)) + a_**WC('n', S(1))*WC('v', S(1)) + a_**WC('p', S(1))*WC('w', S(1)), x_), cons6, cons7, cons5, cons8)
  6448. def replacement3(n, v, x, p, u, w, m, a):
  6449. return RemoveContentAux(a**(-m + n)*v + a**(-m + p)*w + u, x)
  6450. rule3 = ReplacementRule(pattern3, replacement3)
  6451. pattern4 = Pattern(UtilityOperator(u_, x_))
  6452. def replacement4(u, x):
  6453. return If(And(SumQ(u), NegQ(First(u))), -u, u)
  6454. rule4 = ReplacementRule(pattern4, replacement4)
  6455. return [rule1, rule2, rule3, rule4, ]
  6456. IntHide = Int
  6457. Log = rubi_log
  6458. Null = None
  6459. if matchpy:
  6460. RemoveContentAux_replacer = ManyToOneReplacer(* _RemoveContentAux())
  6461. ExpandIntegrand_rules = _ExpandIntegrand()
  6462. TrigSimplifyAux_replacer = _TrigSimplifyAux()
  6463. SimplifyAntiderivative_replacer = _SimplifyAntiderivative()
  6464. SimplifyAntiderivativeSum_replacer = _SimplifyAntiderivativeSum()
  6465. FixSimplify_rules = _FixSimplify()
  6466. SimpFixFactor_replacer = _SimpFixFactor()