exact_reals#

Finitely Generated Modules in the Real Numbers with Number Field Coefficients

The classes in this module wrap libexactreal for use in SageMath. They provide ExactReals, finitely generated submodules of the real modules over a fixd real embedded number field.

EXAMPLES:

sage: from pyexactreal import ExactReals  # random output by cppyy on macOS if xcode is not installed
sage: R = ExactReals(); R
Real Numbers as (Rational Field)-Module

Typically, you want to fix some generators of your module. Here we take a random number, modeling a transcendental real:

sage: g = R.random_element(); g
ℝ(0.303644…)

Mostly, you do not need to worry about the module structure of exact reals. The module is automatically enlarged as needed:

sage: g.module()
ℚ-Module(ℝ(0.303644…))

sage: (g * g).module()
ℚ-Module(ℝ(0.303644…)^2)

sage: (g + 1137).module()
ℚ-Module(1, ℝ(0.303644…))
class pyexactreal.exact_reals.CoercionExactRealsNumberField#

Coercion morphism from a number field to the exact reals over that number field.

EXAMPLES:

sage: from pyexactreal import ExactReals
sage: R = ExactReals(QQ)
sage: R.coerce_map_from(QQ)
Generic morphism:
  From: Rational Field
  To:   Real Numbers as (Rational Field)-Module
class pyexactreal.exact_reals.ExactRealElement(parent, value)#

An element of ExactReals

This is a simple wrapper of an exactreal::Element from libexactreal to make it work in the Parent/Element framework of SageMath.

EXAMPLES:

sage: from pyexactreal import ExactReals
sage: r = ExactReals().random_element(); r
ℝ(0.120809…)

TESTS:

sage: from pyexactreal.exact_reals import ExactRealElement
sage: isinstance(r, ExactRealElement)
True

Check that zero elements can be created that are not in the trivial module:

sage: zero = ExactReals().random_element()._backend.module().zero()
sage: ExactReals()(zero)._backend.module()
-Module((0...))
ceil()#

Return the integer ceil of this real number.

EXAMPLES:

sage: from pyexactreal import ExactReals
sage: R = ExactReals()
sage: x = R.random_element()
sage: x.ceil()
1
divides(other)#

Return whether this element divides other in the module generated by their generators.

EXAMPLES:

sage: from pyexactreal import ExactReals
sage: R = ExactReals()
sage: x = R.random_element()
sage: y = R.random_element()
sage: x.divides(x)
True
sage: x.divides(y)
False
sage: x.divides(x * y)
True
floor()#

Return the integer floor of this real number.

EXAMPLES:

sage: from pyexactreal import ExactReals
sage: R = ExactReals()
sage: x = R.random_element()
sage: x.floor()
0
gcd(other)#

Return the greatest common divisor of this element and other in the module generated by their generators.

EXAMPLES:

sage: from pyexactreal import ExactReals
sage: R = ExactReals()
sage: x = R.random_element()
sage: x.gcd(x) == x
True
sage: x.gcd(1) == 1
True

Note that this not yet implemented for non-trivial cases:

sage: y = R.random_element()
sage: x.gcd(y)
Traceback (most recent call last):
...
NotImplementedError: gcd() not implemented for non-trivial elements yet
is_square()#

Return whether this element is a square in its parent.

Note

This is only implemented in trivial cases.

EXAMPLES:

sage: from pyexactreal import ExactReals
sage: R = ExactReals()
sage: x = R.random_element()
sage: x.is_square()
Traceback (most recent call last):
...
NotImplementedError: is_square() only implemented for algebraic elements
sage: (x**2).is_square()
Traceback (most recent call last):
...
NotImplementedError: is_square() only implemented for algebraic elements
sage: K.<a> = QuadraticField(2)
sage: R = ExactReals(K)
sage: x = R.random_element()
sage: x.is_square()
Traceback (most recent call last):
...
NotImplementedError: is_square() only implemented for algebraic elements
sage: y = x**2 + (a + 1)*x + 1
sage: y.is_square()
Traceback (most recent call last):
...
NotImplementedError: is_square() only implemented for algebraic elements
sage: (y**2).is_square()
Traceback (most recent call last):
...
NotImplementedError: is_square() only implemented for algebraic elements
sage: R(2).is_square()
True
sage: R(3).is_square()
False
is_unit()#

Return whether this element is a unit in its containing module.

EXAMPLES:

sage: from pyexactreal import ExactReals
sage: R = ExactReals()
sage: R.random_element().is_unit()
False
sage: R(2).is_unit()
True
module()#

Return the exactreal::Module this element lives in.

This is the actual underlying implementation from C++ and not a SageMath type. You usually should not have to use this.

EXAMPLES:

sage: from pyexactreal import ExactReals
sage: ExactReals()(1).module()
-Module(1)

TESTS:

Since modules are internally shared pointers they are not unique:

sage: R = ExactReals()
sage: R(1).module() == R(1).module()
True
sage: R(1).module() is R(1).module()
False
sage: g = R.random_element()
sage: R(g).module() == R(g).module()
True
sage: R(g).module() is R(g).module()
False

However, the objects backing these shared pointers are unique:

sage: M,N = R(1).module(), R(1).module()
sage: M.__smartptr__().get() is N.__smartptr__().get()
True
sage: M,N = R(g).module(), R(g).module()
sage: M.__smartptr__().get() is N.__smartptr__().get()
True
simplify()#

Remove unnecessary generators from the internal representation of this element and return this element.

EXAMPLES:

sage: from pyexactreal import ExactReals
sage: R = ExactReals()
sage: x = R.random_element()
sage: y = (x + 1) * (x - 1) - x*x
sage: y._backend.module()
-Module(1, (...)^2)
sage: y.simplify()
-1
sage: y._backend.module()
-Module(1)

Note that this happens automatically for some arithmetic operations:

sage: (x * x / x)._backend.module()
-Module((...))
class pyexactreal.exact_reals.ExactReals(base=None, category=None)#

The Real Numbers as a module over the number field base.

This serves as a common parent for all exact-real elements, i.e., elements in a finite module with transcendental or rational generators.

EXAMPLES:

sage: from pyexactreal import ExactReals
sage: R = ExactReals(); R
Real Numbers as (Rational Field)-Module
sage: RZ = ExactReals(ZZ); RZ
Real Numbers as (Integer Ring)-Module
sage: K.<a> = NumberField(x^2 - 2, embedding=AA(sqrt(2)))
sage: RK = ExactReals(K); RK
Real Numbers as (Real Embedded Number Field in a with defining polynomial x^2 - 2 with a = 1.414213562373095?)-Module

TESTS:

sage: R.one()._test_pickling() # first run prints some warnings from third-party C++ header files
...
sage: TestSuite(R).run(skip=["_test_fraction_field"])
sage: TestSuite(RZ).run(skip=["_test_fraction_field"])
sage: TestSuite(RK).run(skip=["_test_fraction_field"])
sage: R ** 2
Ambient free module of rank 2 over the integral domain Real Numbers as (Rational Field)-Module
Element#

alias of ExactRealElement

an_element()#

Return a typical element of a finitely generated module.

EXAMPLES:

sage: from pyexactreal import ExactReals
sage: ExactReals().an_element()
0
characteristic()#

Return zero, the characteristic of the reals.

EXAMPLES:

sage: from pyexactreal import ExactReals
sage: ExactReals().characteristic()
0
fraction_field()#

Return the field of fractions; not implemented.

EXAMPLES:

sage: from pyexactreal import ExactReals
sage: K = ExactReals().fraction_field()
Traceback (most recent call last):
...
NotImplementedError: ExactReals.fraction_field() is not implemented yet because gcd() is incomplete and __floordiv__ rounds to integers instead of performing exact division as expected by SageMath's FractionField_generic.
is_field(proof=None)#

Return whether this module is a field, i.e., return False.

In principle, when defined over a number field, one could argue this structure is a field since the inverse of any transcendental could show up as a random_element(). However, since no field operations on the elements are possible, we do not claim this to be a field.

EXAMPLES:

sage: from pyexactreal import ExactReals
sage: ExactReals().is_field()
False
is_integral_domain(proof=None)#

Return whether this module is an integral domain, i.e., return True.

EXAMPLES:

sage: from pyexactreal import ExactReals
sage: ExactReals().is_integral_domain()
True
sage: ExactReals() in IntegralDomains()
True
random_element(approximation=None)#

Return a random real element.

EXAMPLES:

sage: from pyexactreal import ExactReals
sage: ExactReals().random_element() # random output
ℝ(0.303644…)

Random elements can be created with a prescribe double approximation:

sage: ExactReals().random_element(3.141) # random output
ℝ(3.141=14485305783880426147p-62 + ℝ(0.778995…)p-62)

Note that elements which approximate a double zero are extremely small and might not be what you want:

sage: ExactReals().random_element(0) # random output
ℝ(-0=-7703581330722908899p-1139 + ℝ(0.707557…)p-1139)

We can also specify a range of doubles which should contain a random real:

sage: ExactReals().random_element([1.414, 3.141]) # random output
ℝ(2.34463=10559275352730893p-52 + ℝ(0.884672…)p-52)

TESTS:

Verify that the automatic seed works:

sage: R = ExactReals()
sage: R.random_element() != R.random_element()
True
rational(q)#

Return the rational q as the element generating the module generated by q. Note that this is not the same as q times the generator of the module generated by 1.

EXAMPLES:

sage: from pyexactreal import ExactReals
sage: x = ExactReals().rational(2); x
2
sage: y = ExactReals().rational(3); y
3
sage: x + y
Traceback (most recent call last):
...
TypeError: ...
    logic_error: at most one generator can be rational
some_elements()#

Return some typical elements of this ring.

EXAMPLES:

sage: from pyexactreal import ExactReals
sage: ExactReals().some_elements()
[0,
 1,
 1,
 ℝ(0...…),
 ℝ(0...…) + 1,
 ℝ(0...…) + 1,
 ℝ(0...…) + ℝ(0...…),
 ℝ(0...…)*ℝ(0...…),
 ℝ(0...…)^2]