domain.py 37 KB

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