domain.py 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219
  1. """Implementation of :class:`Domain` class. """
  2. from typing import Any, Optional, Type
  3. from sympy.core import Basic, sympify
  4. from sympy.core.sorting import default_sort_key, ordered
  5. from sympy.external.gmpy import HAS_GMPY
  6. from sympy.polys.domains.domainelement import DomainElement
  7. from sympy.polys.orderings import lex
  8. from sympy.polys.polyerrors import UnificationFailed, CoercionFailed, DomainError
  9. from sympy.polys.polyutils import _unify_gens, _not_a_coeff
  10. from sympy.utilities import public
  11. from sympy.utilities.iterables import is_sequence
  12. @public
  13. class Domain:
  14. """Superclass for all domains in the polys domains system.
  15. See :ref:`polys-domainsintro` for an introductory explanation of the
  16. domains system.
  17. The :py:class:`~.Domain` class is an abstract base class for all of the
  18. concrete domain types. There are many different :py:class:`~.Domain`
  19. subclasses each of which has an associated ``dtype`` which is a class
  20. representing the elements of the domain. The coefficients of a
  21. :py:class:`~.Poly` are elements of a domain which must be a subclass of
  22. :py:class:`~.Domain`.
  23. Examples
  24. ========
  25. The most common example domains are the integers :ref:`ZZ` and the
  26. rationals :ref:`QQ`.
  27. >>> from sympy import Poly, symbols, Domain
  28. >>> x, y = symbols('x, y')
  29. >>> p = Poly(x**2 + y)
  30. >>> p
  31. Poly(x**2 + y, x, y, domain='ZZ')
  32. >>> p.domain
  33. ZZ
  34. >>> isinstance(p.domain, Domain)
  35. True
  36. >>> Poly(x**2 + y/2)
  37. Poly(x**2 + 1/2*y, x, y, domain='QQ')
  38. The domains can be used directly in which case the domain object e.g.
  39. (:ref:`ZZ` or :ref:`QQ`) can be used as a constructor for elements of
  40. ``dtype``.
  41. >>> from sympy import ZZ, QQ
  42. >>> ZZ(2)
  43. 2
  44. >>> ZZ.dtype # doctest: +SKIP
  45. <class 'int'>
  46. >>> type(ZZ(2)) # doctest: +SKIP
  47. <class 'int'>
  48. >>> QQ(1, 2)
  49. 1/2
  50. >>> type(QQ(1, 2)) # doctest: +SKIP
  51. <class 'sympy.polys.domains.pythonrational.PythonRational'>
  52. The corresponding domain elements can be used with the arithmetic
  53. operations ``+,-,*,**`` and depending on the domain some combination of
  54. ``/,//,%`` might be usable. For example in :ref:`ZZ` both ``//`` (floor
  55. division) and ``%`` (modulo division) can be used but ``/`` (true
  56. division) cannot. Since :ref:`QQ` is a :py:class:`~.Field` its elements
  57. can be used with ``/`` but ``//`` and ``%`` should not be used. Some
  58. domains have a :py:meth:`~.Domain.gcd` method.
  59. >>> ZZ(2) + ZZ(3)
  60. 5
  61. >>> ZZ(5) // ZZ(2)
  62. 2
  63. >>> ZZ(5) % ZZ(2)
  64. 1
  65. >>> QQ(1, 2) / QQ(2, 3)
  66. 3/4
  67. >>> ZZ.gcd(ZZ(4), ZZ(2))
  68. 2
  69. >>> QQ.gcd(QQ(2,7), QQ(5,3))
  70. 1/21
  71. >>> ZZ.is_Field
  72. False
  73. >>> QQ.is_Field
  74. True
  75. There are also many other domains including:
  76. 1. :ref:`GF(p)` for finite fields of prime order.
  77. 2. :ref:`RR` for real (floating point) numbers.
  78. 3. :ref:`CC` for complex (floating point) numbers.
  79. 4. :ref:`QQ(a)` for algebraic number fields.
  80. 5. :ref:`K[x]` for polynomial rings.
  81. 6. :ref:`K(x)` for rational function fields.
  82. 7. :ref:`EX` for arbitrary expressions.
  83. Each domain is represented by a domain object and also an implementation
  84. class (``dtype``) for the elements of the domain. For example the
  85. :ref:`K[x]` domains are represented by a domain object which is an
  86. instance of :py:class:`~.PolynomialRing` and the elements are always
  87. instances of :py:class:`~.PolyElement`. The implementation class
  88. represents particular types of mathematical expressions in a way that is
  89. more efficient than a normal SymPy expression which is of type
  90. :py:class:`~.Expr`. The domain methods :py:meth:`~.Domain.from_sympy` and
  91. :py:meth:`~.Domain.to_sympy` are used to convert from :py:class:`~.Expr`
  92. to a domain element and vice versa.
  93. >>> from sympy import Symbol, ZZ, Expr
  94. >>> x = Symbol('x')
  95. >>> K = ZZ[x] # polynomial ring domain
  96. >>> K
  97. ZZ[x]
  98. >>> type(K) # class of the domain
  99. <class 'sympy.polys.domains.polynomialring.PolynomialRing'>
  100. >>> K.dtype # class of the elements
  101. <class 'sympy.polys.rings.PolyElement'>
  102. >>> p_expr = x**2 + 1 # Expr
  103. >>> p_expr
  104. x**2 + 1
  105. >>> type(p_expr)
  106. <class 'sympy.core.add.Add'>
  107. >>> isinstance(p_expr, Expr)
  108. True
  109. >>> p_domain = K.from_sympy(p_expr)
  110. >>> p_domain # domain element
  111. x**2 + 1
  112. >>> type(p_domain)
  113. <class 'sympy.polys.rings.PolyElement'>
  114. >>> K.to_sympy(p_domain) == p_expr
  115. True
  116. The :py:meth:`~.Domain.convert_from` method is used to convert domain
  117. elements from one domain to another.
  118. >>> from sympy import ZZ, QQ
  119. >>> ez = ZZ(2)
  120. >>> eq = QQ.convert_from(ez, ZZ)
  121. >>> type(ez) # doctest: +SKIP
  122. <class 'int'>
  123. >>> type(eq) # doctest: +SKIP
  124. <class 'sympy.polys.domains.pythonrational.PythonRational'>
  125. Elements from different domains should not be mixed in arithmetic or other
  126. operations: they should be converted to a common domain first. The domain
  127. method :py:meth:`~.Domain.unify` is used to find a domain that can
  128. represent all the elements of two given domains.
  129. >>> from sympy import ZZ, QQ, symbols
  130. >>> x, y = symbols('x, y')
  131. >>> ZZ.unify(QQ)
  132. QQ
  133. >>> ZZ[x].unify(QQ)
  134. QQ[x]
  135. >>> ZZ[x].unify(QQ[y])
  136. QQ[x,y]
  137. If a domain is a :py:class:`~.Ring` then is might have an associated
  138. :py:class:`~.Field` and vice versa. The :py:meth:`~.Domain.get_field` and
  139. :py:meth:`~.Domain.get_ring` methods will find or create the associated
  140. domain.
  141. >>> from sympy import ZZ, QQ, Symbol
  142. >>> x = Symbol('x')
  143. >>> ZZ.has_assoc_Field
  144. True
  145. >>> ZZ.get_field()
  146. QQ
  147. >>> QQ.has_assoc_Ring
  148. True
  149. >>> QQ.get_ring()
  150. ZZ
  151. >>> K = QQ[x]
  152. >>> K
  153. QQ[x]
  154. >>> K.get_field()
  155. QQ(x)
  156. See also
  157. ========
  158. DomainElement: abstract base class for domain elements
  159. construct_domain: construct a minimal domain for some expressions
  160. """
  161. dtype = None # type: Optional[Type]
  162. """The type (class) of the elements of this :py:class:`~.Domain`:
  163. >>> from sympy import ZZ, QQ, Symbol
  164. >>> ZZ.dtype
  165. <class 'int'>
  166. >>> z = ZZ(2)
  167. >>> z
  168. 2
  169. >>> type(z)
  170. <class 'int'>
  171. >>> type(z) == ZZ.dtype
  172. True
  173. Every domain has an associated **dtype** ("datatype") which is the
  174. class of the associated domain elements.
  175. See also
  176. ========
  177. of_type
  178. """
  179. zero = None # type: Optional[Any]
  180. """The zero element of the :py:class:`~.Domain`:
  181. >>> from sympy import QQ
  182. >>> QQ.zero
  183. 0
  184. >>> QQ.of_type(QQ.zero)
  185. True
  186. See also
  187. ========
  188. of_type
  189. one
  190. """
  191. one = None # type: Optional[Any]
  192. """The one element of the :py:class:`~.Domain`:
  193. >>> from sympy import QQ
  194. >>> QQ.one
  195. 1
  196. >>> QQ.of_type(QQ.one)
  197. True
  198. See also
  199. ========
  200. of_type
  201. zero
  202. """
  203. is_Ring = False
  204. """Boolean flag indicating if the domain is a :py:class:`~.Ring`.
  205. >>> from sympy import ZZ
  206. >>> ZZ.is_Ring
  207. True
  208. Basically every :py:class:`~.Domain` represents a ring so this flag is
  209. not that useful.
  210. See also
  211. ========
  212. is_PID
  213. is_Field
  214. get_ring
  215. has_assoc_Ring
  216. """
  217. is_Field = False
  218. """Boolean flag indicating if the domain is a :py:class:`~.Field`.
  219. >>> from sympy import ZZ, QQ
  220. >>> ZZ.is_Field
  221. False
  222. >>> QQ.is_Field
  223. True
  224. See also
  225. ========
  226. is_PID
  227. is_Ring
  228. get_field
  229. has_assoc_Field
  230. """
  231. has_assoc_Ring = False
  232. """Boolean flag indicating if the domain has an associated
  233. :py:class:`~.Ring`.
  234. >>> from sympy import QQ
  235. >>> QQ.has_assoc_Ring
  236. True
  237. >>> QQ.get_ring()
  238. ZZ
  239. See also
  240. ========
  241. is_Field
  242. get_ring
  243. """
  244. has_assoc_Field = False
  245. """Boolean flag indicating if the domain has an associated
  246. :py:class:`~.Field`.
  247. >>> from sympy import ZZ
  248. >>> ZZ.has_assoc_Field
  249. True
  250. >>> ZZ.get_field()
  251. QQ
  252. See also
  253. ========
  254. is_Field
  255. get_field
  256. """
  257. is_FiniteField = is_FF = False
  258. is_IntegerRing = is_ZZ = False
  259. is_RationalField = is_QQ = False
  260. is_GaussianRing = is_ZZ_I = False
  261. is_GaussianField = is_QQ_I = False
  262. is_RealField = is_RR = False
  263. is_ComplexField = is_CC = False
  264. is_AlgebraicField = is_Algebraic = False
  265. is_PolynomialRing = is_Poly = False
  266. is_FractionField = is_Frac = False
  267. is_SymbolicDomain = is_EX = False
  268. is_SymbolicRawDomain = is_EXRAW = False
  269. is_FiniteExtension = False
  270. is_Exact = True
  271. is_Numerical = False
  272. is_Simple = False
  273. is_Composite = False
  274. is_PID = False
  275. """Boolean flag indicating if the domain is a `principal ideal domain`_.
  276. >>> from sympy import ZZ
  277. >>> ZZ.has_assoc_Field
  278. True
  279. >>> ZZ.get_field()
  280. QQ
  281. .. _principal ideal domain: https://en.wikipedia.org/wiki/Principal_ideal_domain
  282. See also
  283. ========
  284. is_Field
  285. get_field
  286. """
  287. has_CharacteristicZero = False
  288. rep = None # type: Optional[str]
  289. alias = None # type: Optional[str]
  290. def __init__(self):
  291. raise NotImplementedError
  292. def __str__(self):
  293. return self.rep
  294. def __repr__(self):
  295. return str(self)
  296. def __hash__(self):
  297. return hash((self.__class__.__name__, self.dtype))
  298. def new(self, *args):
  299. return self.dtype(*args)
  300. @property
  301. def tp(self):
  302. """Alias for :py:attr:`~.Domain.dtype`"""
  303. return self.dtype
  304. def __call__(self, *args):
  305. """Construct an element of ``self`` domain from ``args``. """
  306. return self.new(*args)
  307. def normal(self, *args):
  308. return self.dtype(*args)
  309. def convert_from(self, element, base):
  310. """Convert ``element`` to ``self.dtype`` given the base domain. """
  311. if base.alias is not None:
  312. method = "from_" + base.alias
  313. else:
  314. method = "from_" + base.__class__.__name__
  315. _convert = getattr(self, method)
  316. if _convert is not None:
  317. result = _convert(element, base)
  318. if result is not None:
  319. return result
  320. raise CoercionFailed("Cannot convert %s of type %s from %s to %s" % (element, type(element), base, self))
  321. def convert(self, element, base=None):
  322. """Convert ``element`` to ``self.dtype``. """
  323. if base is not None:
  324. if _not_a_coeff(element):
  325. raise CoercionFailed('%s is not in any domain' % element)
  326. return self.convert_from(element, base)
  327. if self.of_type(element):
  328. return element
  329. if _not_a_coeff(element):
  330. raise CoercionFailed('%s is not in any domain' % element)
  331. from sympy.polys.domains import ZZ, QQ, RealField, ComplexField
  332. if ZZ.of_type(element):
  333. return self.convert_from(element, ZZ)
  334. if isinstance(element, int):
  335. return self.convert_from(ZZ(element), ZZ)
  336. if HAS_GMPY:
  337. integers = ZZ
  338. if isinstance(element, integers.tp):
  339. return self.convert_from(element, integers)
  340. rationals = QQ
  341. if isinstance(element, rationals.tp):
  342. return self.convert_from(element, rationals)
  343. if isinstance(element, float):
  344. parent = RealField(tol=False)
  345. return self.convert_from(parent(element), parent)
  346. if isinstance(element, complex):
  347. parent = ComplexField(tol=False)
  348. return self.convert_from(parent(element), parent)
  349. if isinstance(element, DomainElement):
  350. return self.convert_from(element, element.parent())
  351. # TODO: implement this in from_ methods
  352. if self.is_Numerical and getattr(element, 'is_ground', False):
  353. return self.convert(element.LC())
  354. if isinstance(element, Basic):
  355. try:
  356. return self.from_sympy(element)
  357. except (TypeError, ValueError):
  358. pass
  359. else: # TODO: remove this branch
  360. if not is_sequence(element):
  361. try:
  362. element = sympify(element, strict=True)
  363. if isinstance(element, Basic):
  364. return self.from_sympy(element)
  365. except (TypeError, ValueError):
  366. pass
  367. raise CoercionFailed("Cannot convert %s of type %s to %s" % (element, type(element), self))
  368. def of_type(self, element):
  369. """Check if ``a`` is of type ``dtype``. """
  370. return isinstance(element, self.tp) # XXX: this isn't correct, e.g. PolyElement
  371. def __contains__(self, a):
  372. """Check if ``a`` belongs to this domain. """
  373. try:
  374. if _not_a_coeff(a):
  375. raise CoercionFailed
  376. self.convert(a) # this might raise, too
  377. except CoercionFailed:
  378. return False
  379. return True
  380. def to_sympy(self, a):
  381. """Convert domain element *a* to a SymPy expression (Expr).
  382. Explanation
  383. ===========
  384. Convert a :py:class:`~.Domain` element *a* to :py:class:`~.Expr`. Most
  385. public SymPy functions work with objects of type :py:class:`~.Expr`.
  386. The elements of a :py:class:`~.Domain` have a different internal
  387. representation. It is not possible to mix domain elements with
  388. :py:class:`~.Expr` so each domain has :py:meth:`~.Domain.to_sympy` and
  389. :py:meth:`~.Domain.from_sympy` methods to convert its domain elements
  390. to and from :py:class:`~.Expr`.
  391. Parameters
  392. ==========
  393. a: domain element
  394. An element of this :py:class:`~.Domain`.
  395. Returns
  396. =======
  397. expr: Expr
  398. A normal SymPy expression of type :py:class:`~.Expr`.
  399. Examples
  400. ========
  401. Construct an element of the :ref:`QQ` domain and then convert it to
  402. :py:class:`~.Expr`.
  403. >>> from sympy import QQ, Expr
  404. >>> q_domain = QQ(2)
  405. >>> q_domain
  406. 2
  407. >>> q_expr = QQ.to_sympy(q_domain)
  408. >>> q_expr
  409. 2
  410. Although the printed forms look similar these objects are not of the
  411. same type.
  412. >>> isinstance(q_domain, Expr)
  413. False
  414. >>> isinstance(q_expr, Expr)
  415. True
  416. Construct an element of :ref:`K[x]` and convert to
  417. :py:class:`~.Expr`.
  418. >>> from sympy import Symbol
  419. >>> x = Symbol('x')
  420. >>> K = QQ[x]
  421. >>> x_domain = K.gens[0] # generator x as a domain element
  422. >>> p_domain = x_domain**2/3 + 1
  423. >>> p_domain
  424. 1/3*x**2 + 1
  425. >>> p_expr = K.to_sympy(p_domain)
  426. >>> p_expr
  427. x**2/3 + 1
  428. The :py:meth:`~.Domain.from_sympy` method is used for the opposite
  429. conversion from a normal SymPy expression to a domain element.
  430. >>> p_domain == p_expr
  431. False
  432. >>> K.from_sympy(p_expr) == p_domain
  433. True
  434. >>> K.to_sympy(p_domain) == p_expr
  435. True
  436. >>> K.from_sympy(K.to_sympy(p_domain)) == p_domain
  437. True
  438. >>> K.to_sympy(K.from_sympy(p_expr)) == p_expr
  439. True
  440. The :py:meth:`~.Domain.from_sympy` method makes it easier to construct
  441. domain elements interactively.
  442. >>> from sympy import Symbol
  443. >>> x = Symbol('x')
  444. >>> K = QQ[x]
  445. >>> K.from_sympy(x**2/3 + 1)
  446. 1/3*x**2 + 1
  447. See also
  448. ========
  449. from_sympy
  450. convert_from
  451. """
  452. raise NotImplementedError
  453. def from_sympy(self, a):
  454. """Convert a SymPy expression to an element of this domain.
  455. Explanation
  456. ===========
  457. See :py:meth:`~.Domain.to_sympy` for explanation and examples.
  458. Parameters
  459. ==========
  460. expr: Expr
  461. A normal SymPy expression of type :py:class:`~.Expr`.
  462. Returns
  463. =======
  464. a: domain element
  465. An element of this :py:class:`~.Domain`.
  466. See also
  467. ========
  468. to_sympy
  469. convert_from
  470. """
  471. raise NotImplementedError
  472. def sum(self, args):
  473. return sum(args)
  474. def from_FF(K1, a, K0):
  475. """Convert ``ModularInteger(int)`` to ``dtype``. """
  476. return None
  477. def from_FF_python(K1, a, K0):
  478. """Convert ``ModularInteger(int)`` to ``dtype``. """
  479. return None
  480. def from_ZZ_python(K1, a, K0):
  481. """Convert a Python ``int`` object to ``dtype``. """
  482. return None
  483. def from_QQ_python(K1, a, K0):
  484. """Convert a Python ``Fraction`` object to ``dtype``. """
  485. return None
  486. def from_FF_gmpy(K1, a, K0):
  487. """Convert ``ModularInteger(mpz)`` to ``dtype``. """
  488. return None
  489. def from_ZZ_gmpy(K1, a, K0):
  490. """Convert a GMPY ``mpz`` object to ``dtype``. """
  491. return None
  492. def from_QQ_gmpy(K1, a, K0):
  493. """Convert a GMPY ``mpq`` object to ``dtype``. """
  494. return None
  495. def from_RealField(K1, a, K0):
  496. """Convert a real element object to ``dtype``. """
  497. return None
  498. def from_ComplexField(K1, a, K0):
  499. """Convert a complex element to ``dtype``. """
  500. return None
  501. def from_AlgebraicField(K1, a, K0):
  502. """Convert an algebraic number to ``dtype``. """
  503. return None
  504. def from_PolynomialRing(K1, a, K0):
  505. """Convert a polynomial to ``dtype``. """
  506. if a.is_ground:
  507. return K1.convert(a.LC, K0.dom)
  508. def from_FractionField(K1, a, K0):
  509. """Convert a rational function to ``dtype``. """
  510. return None
  511. def from_MonogenicFiniteExtension(K1, a, K0):
  512. """Convert an ``ExtensionElement`` to ``dtype``. """
  513. return K1.convert_from(a.rep, K0.ring)
  514. def from_ExpressionDomain(K1, a, K0):
  515. """Convert a ``EX`` object to ``dtype``. """
  516. return K1.from_sympy(a.ex)
  517. def from_ExpressionRawDomain(K1, a, K0):
  518. """Convert a ``EX`` object to ``dtype``. """
  519. return K1.from_sympy(a)
  520. def from_GlobalPolynomialRing(K1, a, K0):
  521. """Convert a polynomial to ``dtype``. """
  522. if a.degree() <= 0:
  523. return K1.convert(a.LC(), K0.dom)
  524. def from_GeneralizedPolynomialRing(K1, a, K0):
  525. return K1.from_FractionField(a, K0)
  526. def unify_with_symbols(K0, K1, symbols):
  527. if (K0.is_Composite and (set(K0.symbols) & set(symbols))) or (K1.is_Composite and (set(K1.symbols) & set(symbols))):
  528. raise UnificationFailed("Cannot unify %s with %s, given %s generators" % (K0, K1, tuple(symbols)))
  529. return K0.unify(K1)
  530. def unify(K0, K1, symbols=None):
  531. """
  532. Construct a minimal domain that contains elements of ``K0`` and ``K1``.
  533. Known domains (from smallest to largest):
  534. - ``GF(p)``
  535. - ``ZZ``
  536. - ``QQ``
  537. - ``RR(prec, tol)``
  538. - ``CC(prec, tol)``
  539. - ``ALG(a, b, c)``
  540. - ``K[x, y, z]``
  541. - ``K(x, y, z)``
  542. - ``EX``
  543. """
  544. if symbols is not None:
  545. return K0.unify_with_symbols(K1, symbols)
  546. if K0 == K1:
  547. return K0
  548. if K0.is_EXRAW:
  549. return K0
  550. if K1.is_EXRAW:
  551. return K1
  552. if K0.is_EX:
  553. return K0
  554. if K1.is_EX:
  555. return K1
  556. if K0.is_FiniteExtension or K1.is_FiniteExtension:
  557. if K1.is_FiniteExtension:
  558. K0, K1 = K1, K0
  559. if K1.is_FiniteExtension:
  560. # Unifying two extensions.
  561. # Try to ensure that K0.unify(K1) == K1.unify(K0)
  562. if list(ordered([K0.modulus, K1.modulus]))[1] == K0.modulus:
  563. K0, K1 = K1, K0
  564. return K1.set_domain(K0)
  565. else:
  566. # Drop the generator from other and unify with the base domain
  567. K1 = K1.drop(K0.symbol)
  568. K1 = K0.domain.unify(K1)
  569. return K0.set_domain(K1)
  570. if K0.is_Composite or K1.is_Composite:
  571. K0_ground = K0.dom if K0.is_Composite else K0
  572. K1_ground = K1.dom if K1.is_Composite else K1
  573. K0_symbols = K0.symbols if K0.is_Composite else ()
  574. K1_symbols = K1.symbols if K1.is_Composite else ()
  575. domain = K0_ground.unify(K1_ground)
  576. symbols = _unify_gens(K0_symbols, K1_symbols)
  577. order = K0.order if K0.is_Composite else K1.order
  578. if ((K0.is_FractionField and K1.is_PolynomialRing or
  579. K1.is_FractionField and K0.is_PolynomialRing) and
  580. (not K0_ground.is_Field or not K1_ground.is_Field) and domain.is_Field
  581. and domain.has_assoc_Ring):
  582. domain = domain.get_ring()
  583. if K0.is_Composite and (not K1.is_Composite or K0.is_FractionField or K1.is_PolynomialRing):
  584. cls = K0.__class__
  585. else:
  586. cls = K1.__class__
  587. from sympy.polys.domains.old_polynomialring import GlobalPolynomialRing
  588. if cls == GlobalPolynomialRing:
  589. return cls(domain, symbols)
  590. return cls(domain, symbols, order)
  591. def mkinexact(cls, K0, K1):
  592. prec = max(K0.precision, K1.precision)
  593. tol = max(K0.tolerance, K1.tolerance)
  594. return cls(prec=prec, tol=tol)
  595. if K1.is_ComplexField:
  596. K0, K1 = K1, K0
  597. if K0.is_ComplexField:
  598. if K1.is_ComplexField or K1.is_RealField:
  599. return mkinexact(K0.__class__, K0, K1)
  600. else:
  601. return K0
  602. if K1.is_RealField:
  603. K0, K1 = K1, K0
  604. if K0.is_RealField:
  605. if K1.is_RealField:
  606. return mkinexact(K0.__class__, K0, K1)
  607. elif K1.is_GaussianRing or K1.is_GaussianField:
  608. from sympy.polys.domains.complexfield import ComplexField
  609. return ComplexField(prec=K0.precision, tol=K0.tolerance)
  610. else:
  611. return K0
  612. if K1.is_AlgebraicField:
  613. K0, K1 = K1, K0
  614. if K0.is_AlgebraicField:
  615. if K1.is_GaussianRing:
  616. K1 = K1.get_field()
  617. if K1.is_GaussianField:
  618. K1 = K1.as_AlgebraicField()
  619. if K1.is_AlgebraicField:
  620. return K0.__class__(K0.dom.unify(K1.dom), *_unify_gens(K0.orig_ext, K1.orig_ext))
  621. else:
  622. return K0
  623. if K0.is_GaussianField:
  624. return K0
  625. if K1.is_GaussianField:
  626. return K1
  627. if K0.is_GaussianRing:
  628. if K1.is_RationalField:
  629. K0 = K0.get_field()
  630. return K0
  631. if K1.is_GaussianRing:
  632. if K0.is_RationalField:
  633. K1 = K1.get_field()
  634. return K1
  635. if K0.is_RationalField:
  636. return K0
  637. if K1.is_RationalField:
  638. return K1
  639. if K0.is_IntegerRing:
  640. return K0
  641. if K1.is_IntegerRing:
  642. return K1
  643. if K0.is_FiniteField and K1.is_FiniteField:
  644. return K0.__class__(max(K0.mod, K1.mod, key=default_sort_key))
  645. from sympy.polys.domains import EX
  646. return EX
  647. def __eq__(self, other):
  648. """Returns ``True`` if two domains are equivalent. """
  649. return isinstance(other, Domain) and self.dtype == other.dtype
  650. def __ne__(self, other):
  651. """Returns ``False`` if two domains are equivalent. """
  652. return not self == other
  653. def map(self, seq):
  654. """Rersively apply ``self`` to all elements of ``seq``. """
  655. result = []
  656. for elt in seq:
  657. if isinstance(elt, list):
  658. result.append(self.map(elt))
  659. else:
  660. result.append(self(elt))
  661. return result
  662. def get_ring(self):
  663. """Returns a ring associated with ``self``. """
  664. raise DomainError('there is no ring associated with %s' % self)
  665. def get_field(self):
  666. """Returns a field associated with ``self``. """
  667. raise DomainError('there is no field associated with %s' % self)
  668. def get_exact(self):
  669. """Returns an exact domain associated with ``self``. """
  670. return self
  671. def __getitem__(self, symbols):
  672. """The mathematical way to make a polynomial ring. """
  673. if hasattr(symbols, '__iter__'):
  674. return self.poly_ring(*symbols)
  675. else:
  676. return self.poly_ring(symbols)
  677. def poly_ring(self, *symbols, order=lex):
  678. """Returns a polynomial ring, i.e. `K[X]`. """
  679. from sympy.polys.domains.polynomialring import PolynomialRing
  680. return PolynomialRing(self, symbols, order)
  681. def frac_field(self, *symbols, order=lex):
  682. """Returns a fraction field, i.e. `K(X)`. """
  683. from sympy.polys.domains.fractionfield import FractionField
  684. return FractionField(self, symbols, order)
  685. def old_poly_ring(self, *symbols, **kwargs):
  686. """Returns a polynomial ring, i.e. `K[X]`. """
  687. from sympy.polys.domains.old_polynomialring import PolynomialRing
  688. return PolynomialRing(self, *symbols, **kwargs)
  689. def old_frac_field(self, *symbols, **kwargs):
  690. """Returns a fraction field, i.e. `K(X)`. """
  691. from sympy.polys.domains.old_fractionfield import FractionField
  692. return FractionField(self, *symbols, **kwargs)
  693. def algebraic_field(self, *extension):
  694. r"""Returns an algebraic field, i.e. `K(\alpha, \ldots)`. """
  695. raise DomainError("Cannot create algebraic field over %s" % self)
  696. def inject(self, *symbols):
  697. """Inject generators into this domain. """
  698. raise NotImplementedError
  699. def drop(self, *symbols):
  700. """Drop generators from this domain. """
  701. if self.is_Simple:
  702. return self
  703. raise NotImplementedError # pragma: no cover
  704. def is_zero(self, a):
  705. """Returns True if ``a`` is zero. """
  706. return not a
  707. def is_one(self, a):
  708. """Returns True if ``a`` is one. """
  709. return a == self.one
  710. def is_positive(self, a):
  711. """Returns True if ``a`` is positive. """
  712. return a > 0
  713. def is_negative(self, a):
  714. """Returns True if ``a`` is negative. """
  715. return a < 0
  716. def is_nonpositive(self, a):
  717. """Returns True if ``a`` is non-positive. """
  718. return a <= 0
  719. def is_nonnegative(self, a):
  720. """Returns True if ``a`` is non-negative. """
  721. return a >= 0
  722. def canonical_unit(self, a):
  723. if self.is_negative(a):
  724. return -self.one
  725. else:
  726. return self.one
  727. def abs(self, a):
  728. """Absolute value of ``a``, implies ``__abs__``. """
  729. return abs(a)
  730. def neg(self, a):
  731. """Returns ``a`` negated, implies ``__neg__``. """
  732. return -a
  733. def pos(self, a):
  734. """Returns ``a`` positive, implies ``__pos__``. """
  735. return +a
  736. def add(self, a, b):
  737. """Sum of ``a`` and ``b``, implies ``__add__``. """
  738. return a + b
  739. def sub(self, a, b):
  740. """Difference of ``a`` and ``b``, implies ``__sub__``. """
  741. return a - b
  742. def mul(self, a, b):
  743. """Product of ``a`` and ``b``, implies ``__mul__``. """
  744. return a * b
  745. def pow(self, a, b):
  746. """Raise ``a`` to power ``b``, implies ``__pow__``. """
  747. return a ** b
  748. def exquo(self, a, b):
  749. """Exact quotient of *a* and *b*. Analogue of ``a / b``.
  750. Explanation
  751. ===========
  752. This is essentially the same as ``a / b`` except that an error will be
  753. raised if the division is inexact (if there is any remainder) and the
  754. result will always be a domain element. When working in a
  755. :py:class:`~.Domain` that is not a :py:class:`~.Field` (e.g. :ref:`ZZ`
  756. or :ref:`K[x]`) ``exquo`` should be used instead of ``/``.
  757. The key invariant is that if ``q = K.exquo(a, b)`` (and ``exquo`` does
  758. not raise an exception) then ``a == b*q``.
  759. Examples
  760. ========
  761. We can use ``K.exquo`` instead of ``/`` for exact division.
  762. >>> from sympy import ZZ
  763. >>> ZZ.exquo(ZZ(4), ZZ(2))
  764. 2
  765. >>> ZZ.exquo(ZZ(5), ZZ(2))
  766. Traceback (most recent call last):
  767. ...
  768. ExactQuotientFailed: 2 does not divide 5 in ZZ
  769. Over a :py:class:`~.Field` such as :ref:`QQ`, division (with nonzero
  770. divisor) is always exact so in that case ``/`` can be used instead of
  771. :py:meth:`~.Domain.exquo`.
  772. >>> from sympy import QQ
  773. >>> QQ.exquo(QQ(5), QQ(2))
  774. 5/2
  775. >>> QQ(5) / QQ(2)
  776. 5/2
  777. Parameters
  778. ==========
  779. a: domain element
  780. The dividend
  781. b: domain element
  782. The divisor
  783. Returns
  784. =======
  785. q: domain element
  786. The exact quotient
  787. Raises
  788. ======
  789. ExactQuotientFailed: if exact division is not possible.
  790. ZeroDivisionError: when the divisor is zero.
  791. See also
  792. ========
  793. quo: Analogue of ``a // b``
  794. rem: Analogue of ``a % b``
  795. div: Analogue of ``divmod(a, b)``
  796. Notes
  797. =====
  798. Since the default :py:attr:`~.Domain.dtype` for :ref:`ZZ` is ``int``
  799. (or ``mpz``) division as ``a / b`` should not be used as it would give
  800. a ``float``.
  801. >>> ZZ(4) / ZZ(2)
  802. 2.0
  803. >>> ZZ(5) / ZZ(2)
  804. 2.5
  805. Using ``/`` with :ref:`ZZ` will lead to incorrect results so
  806. :py:meth:`~.Domain.exquo` should be used instead.
  807. """
  808. raise NotImplementedError
  809. def quo(self, a, b):
  810. """Quotient of *a* and *b*. Analogue of ``a // b``.
  811. ``K.quo(a, b)`` is equivalent to ``K.div(a, b)[0]``. See
  812. :py:meth:`~.Domain.div` for more explanation.
  813. See also
  814. ========
  815. rem: Analogue of ``a % b``
  816. div: Analogue of ``divmod(a, b)``
  817. exquo: Analogue of ``a / b``
  818. """
  819. raise NotImplementedError
  820. def rem(self, a, b):
  821. """Modulo division of *a* and *b*. Analogue of ``a % b``.
  822. ``K.rem(a, b)`` is equivalent to ``K.div(a, b)[1]``. See
  823. :py:meth:`~.Domain.div` for more explanation.
  824. See also
  825. ========
  826. quo: Analogue of ``a // b``
  827. div: Analogue of ``divmod(a, b)``
  828. exquo: Analogue of ``a / b``
  829. """
  830. raise NotImplementedError
  831. def div(self, a, b):
  832. """Quotient and remainder for *a* and *b*. Analogue of ``divmod(a, b)``
  833. Explanation
  834. ===========
  835. This is essentially the same as ``divmod(a, b)`` except that is more
  836. consistent when working over some :py:class:`~.Field` domains such as
  837. :ref:`QQ`. When working over an arbitrary :py:class:`~.Domain` the
  838. :py:meth:`~.Domain.div` method should be used instead of ``divmod``.
  839. The key invariant is that if ``q, r = K.div(a, b)`` then
  840. ``a == b*q + r``.
  841. The result of ``K.div(a, b)`` is the same as the tuple
  842. ``(K.quo(a, b), K.rem(a, b))`` except that if both quotient and
  843. remainder are needed then it is more efficient to use
  844. :py:meth:`~.Domain.div`.
  845. Examples
  846. ========
  847. We can use ``K.div`` instead of ``divmod`` for floor division and
  848. remainder.
  849. >>> from sympy import ZZ, QQ
  850. >>> ZZ.div(ZZ(5), ZZ(2))
  851. (2, 1)
  852. If ``K`` is a :py:class:`~.Field` then the division is always exact
  853. with a remainder of :py:attr:`~.Domain.zero`.
  854. >>> QQ.div(QQ(5), QQ(2))
  855. (5/2, 0)
  856. Parameters
  857. ==========
  858. a: domain element
  859. The dividend
  860. b: domain element
  861. The divisor
  862. Returns
  863. =======
  864. (q, r): tuple of domain elements
  865. The quotient and remainder
  866. Raises
  867. ======
  868. ZeroDivisionError: when the divisor is zero.
  869. See also
  870. ========
  871. quo: Analogue of ``a // b``
  872. rem: Analogue of ``a % b``
  873. exquo: Analogue of ``a / b``
  874. Notes
  875. =====
  876. If ``gmpy`` is installed then the ``gmpy.mpq`` type will be used as
  877. the :py:attr:`~.Domain.dtype` for :ref:`QQ`. The ``gmpy.mpq`` type
  878. defines ``divmod`` in a way that is undesirable so
  879. :py:meth:`~.Domain.div` should be used instead of ``divmod``.
  880. >>> a = QQ(1)
  881. >>> b = QQ(3, 2)
  882. >>> a # doctest: +SKIP
  883. mpq(1,1)
  884. >>> b # doctest: +SKIP
  885. mpq(3,2)
  886. >>> divmod(a, b) # doctest: +SKIP
  887. (mpz(0), mpq(1,1))
  888. >>> QQ.div(a, b) # doctest: +SKIP
  889. (mpq(2,3), mpq(0,1))
  890. Using ``//`` or ``%`` with :ref:`QQ` will lead to incorrect results so
  891. :py:meth:`~.Domain.div` should be used instead.
  892. """
  893. raise NotImplementedError
  894. def invert(self, a, b):
  895. """Returns inversion of ``a mod b``, implies something. """
  896. raise NotImplementedError
  897. def revert(self, a):
  898. """Returns ``a**(-1)`` if possible. """
  899. raise NotImplementedError
  900. def numer(self, a):
  901. """Returns numerator of ``a``. """
  902. raise NotImplementedError
  903. def denom(self, a):
  904. """Returns denominator of ``a``. """
  905. raise NotImplementedError
  906. def half_gcdex(self, a, b):
  907. """Half extended GCD of ``a`` and ``b``. """
  908. s, t, h = self.gcdex(a, b)
  909. return s, h
  910. def gcdex(self, a, b):
  911. """Extended GCD of ``a`` and ``b``. """
  912. raise NotImplementedError
  913. def cofactors(self, a, b):
  914. """Returns GCD and cofactors of ``a`` and ``b``. """
  915. gcd = self.gcd(a, b)
  916. cfa = self.quo(a, gcd)
  917. cfb = self.quo(b, gcd)
  918. return gcd, cfa, cfb
  919. def gcd(self, a, b):
  920. """Returns GCD of ``a`` and ``b``. """
  921. raise NotImplementedError
  922. def lcm(self, a, b):
  923. """Returns LCM of ``a`` and ``b``. """
  924. raise NotImplementedError
  925. def log(self, a, b):
  926. """Returns b-base logarithm of ``a``. """
  927. raise NotImplementedError
  928. def sqrt(self, a):
  929. """Returns square root of ``a``. """
  930. raise NotImplementedError
  931. def evalf(self, a, prec=None, **options):
  932. """Returns numerical approximation of ``a``. """
  933. return self.to_sympy(a).evalf(prec, **options)
  934. n = evalf
  935. def real(self, a):
  936. return a
  937. def imag(self, a):
  938. return self.zero
  939. def almosteq(self, a, b, tolerance=None):
  940. """Check if ``a`` and ``b`` are almost equal. """
  941. return a == b
  942. def characteristic(self):
  943. """Return the characteristic of this domain. """
  944. raise NotImplementedError('characteristic()')
  945. __all__ = ['Domain']