renf_elem_class — number field elements

renf_elem_class — number field elements#

class renf_elem_class#

An element of a Real Embedded Number Field.

Each element lives in a fixed number field. If the number field is an extension of the rationals of degree \(d\), its elements are represented by rational polynomials of degree \(d - 1\).

#include <e-antic/renf_class.hpp>
#include <e-antic/renf_elem_class.hpp>

auto K = eantic::renf_class::make("x^2 - 2", "x", "1.4 +/- 1");
auto a = eantic::renf_elem_class(*K, std::vector{-1, 1});
std::cout << a;
// -> (x-1 ~ 0.41421356)

The underlying data can be accessed directly, e.g., with num_vector and den.

Note that elements do not need to worry about the lifetime of the number field they are contained in. The number field will be kept alive by smart pointers as long as elements in it are around:

#include <e-antic/renf_class.hpp>
#include <e-antic/renf_elem_class.hpp>

auto gen = eantic::renf_class::make("x^2 - 2", "x", "1.4 +/- 1")->gen();
std::cout << gen;
// -> (x ~ 1.4142136)

renf_elem_class(…)

renf_elem_class() noexcept#

Create the zero element of the rationals.

explicit renf_elem_class(const renf_class &k)#

Create the zero element in the field k.

renf_elem_class(const renf_elem_class&)#

Create a copy of this element.

renf_elem_class(renf_elem_class&&) noexcept#

Create a new element from an existing element.

renf_elem_class(const renf_class &k, const renf_elem_class&)#

Create an element in the field k from an existing element. This attempts to coerce the element into the field k. Currently, this is only implemented in trivial cases.

renf_elem_class(const renf_class &k, const std::string&)#

Create an element in the field k from a string representation of its underlying polynomial.

#include <e-antic/renf_class.hpp>
#include <e-antic/renf_elem_class.hpp>

auto K = eantic::renf_class::make("x^2 - 2", "x", "1.4 +/- 1");
eantic::renf_elem_class(*K, "x") == K->gen()
// -> true

renf_elem_class(integer/rational)

Create an element in the rationals. These are shortcuts equivalent to calling renf_elem_class(*renf_class::make(), value).

renf_elem_class(short)#
renf_elem_class(unsigned short)#
renf_elem_class(int)#
renf_elem_class(unsigned int)#
renf_elem_class(long)#
renf_elem_class(unsigned long)#
renf_elem_class(long long)#
renf_elem_class(unsigned long long)#
renf_elem_class(const mpz_class&)#
renf_elem_class(const fmpz_t)#
renf_elem_class(const mpq_class&)#
renf_elem_class(const fmpq_t)#

renf_elem_class(const renf_class&, integer/rational)

Create a rational element in the field k.

renf_elem_class(const renf_class &k, short)#
renf_elem_class(const renf_class &k, unsigned short)#
renf_elem_class(const renf_class &k, int)#
renf_elem_class(const renf_class &k, unsigned int)#
renf_elem_class(const renf_class &k, long)#
renf_elem_class(const renf_class &k, unsigned long)#
renf_elem_class(const renf_class &k, long long)#
renf_elem_class(const renf_class &k, unsigned long long)#
renf_elem_class(const renf_class &k, const mpz_class&)#
renf_elem_class(const renf_class &k, const fmpz_t)#
renf_elem_class(const renf_class &k, const mpq_class&)#
renf_elem_class(const renf_class &k, const fmpq_t)#

renf_elem_class(vector<integer/rational>)

Create the element \(\sum c_i a^i\) where \(a\) is the generator. The number of coefficients must not exceed the degree of the field.

renf_elem_class(const renf_class &k, const std::vector<int>&)#
renf_elem_class(const renf_class &k, const std::vector<unsigned int>&)#
renf_elem_class(const renf_class &k, const std::vector<long>&)#
renf_elem_class(const renf_class &k, const std::vector<unsigned long>&)#
renf_elem_class(const renf_class &k, const std::vector<mpz_class>&)#
renf_elem_class(const renf_class &k, const std::vector<mpq_class>&)#

operator=(integer/rational)

Reset this element to a rational number. The parent of the element is not preserved, i.e., it’s always the rational field. To create a rational element in the number field, use the corresponding constructor.

#include <e-antic/renf_class.hpp>
#include <e-antic/renf_elem_class.hpp>

auto K = eantic::renf_class::make("x^2 - 2", "x", "1.4 +/- 1");
auto a = K->gen();
a.parent() == *K
// -> true
a = 1;
a.parent() == *K
// -> false
a = eantic::renf_elem_class(*K, 1);
a.parent() == *K
// -> true

renf_elem_class &operator=(short)#
renf_elem_class &operator=(unsigned short)#
renf_elem_class &operator=(int)#
renf_elem_class &operator=(unsigned int)#
renf_elem_class &operator=(long)#
renf_elem_class &operator=(unsigned long)#
renf_elem_class &operator=(long long)#
renf_elem_class &operator=(unsigned long long)#
renf_elem_class &operator=(const mpz_class&)#
renf_elem_class &operator=(const mpq_class&)#
renf_elem_class &operator=(const fmpz_t)#
renf_elem_class &operator=(const fmpq_t)#

operator=(number field element)

Reset this element to another element. The parent of the element is not preserved, i.e., the resulting parent is always the parent of the argument.

renf_elem_class &operator=(const renf_elem_class&)#
renf_elem_class &operator=(renf_elem_class&&) noexcept#

string to_string() const

Return a string representation of this element. The optional flag of to_string() is passed on to renf_elem_get_str_pretty() internally. Other than that, to_string() and the explicit string conversion are just aliases of each other:

#include <e-antic/renf_class.hpp>
#include <e-antic/renf_elem_class.hpp>

auto K = eantic::renf_class::make("x^2 - 2", "x", "1.4 +/- 1");
K->gen().to_string() == static_cast<std::string>(K->gen())
// -> true

std::string to_string(int flags = 1 | 2) const#
explicit operator std::string() const#

Arithmetic in the Number Field

ELements in a number field support the usual arithmetic operators +, -, *, /. Internally, these operators are derived from the corresponding inplace operators +=, -=, *=, /=. Note that arithmetic between elements in different number fields is currently only supported in trivial cases.

renf_elem_class &operator+=(const renf_elem_class&)#
renf_elem_class &operator-=(const renf_elem_class&)#
renf_elem_class &operator*=(const renf_elem_class&)#
renf_elem_class &operator/=(const renf_elem_class&)#

Arithmetic with Integers & Rationals

Elements in a number field and integers/rationals can be combined with the usual arithmetic operators +, -, *, / and the corresponding inplace operators +=, -=, *=, /=.

renf_elem_class &operator+=(short)#
renf_elem_class &operator-=(short)#
renf_elem_class &operator*=(short)#
renf_elem_class &operator/=(short)#
renf_elem_class &operator+=(unsigned short)#
renf_elem_class &operator-=(unsigned short)#
renf_elem_class &operator*=(unsigned short)#
renf_elem_class &operator/=(unsigned short)#
renf_elem_class &operator+=(int)#
renf_elem_class &operator-=(int)#
renf_elem_class &operator*=(int)#
renf_elem_class &operator/=(int)#
renf_elem_class &operator+=(unsigned int)#
renf_elem_class &operator-=(unsigned int)#
renf_elem_class &operator*=(unsigned int)#
renf_elem_class &operator/=(unsigned int)#
renf_elem_class &operator+=(long)#
renf_elem_class &operator-=(long)#
renf_elem_class &operator*=(long)#
renf_elem_class &operator/=(long)#
renf_elem_class &operator+=(unsigned long)#
renf_elem_class &operator-=(unsigned long)#
renf_elem_class &operator*=(unsigned long)#
renf_elem_class &operator/=(unsigned long)#
renf_elem_class &operator+=(long long)#
renf_elem_class &operator-=(long long)#
renf_elem_class &operator*=(long long)#
renf_elem_class &operator/=(long long)#
renf_elem_class &operator+=(unsigned long long)#
renf_elem_class &operator-=(unsigned long long)#
renf_elem_class &operator*=(unsigned long long)#
renf_elem_class &operator/=(unsigned long long)#
renf_elem_class &operator+=(const mpz_class&)#
renf_elem_class &operator-=(const mpz_class&)#
renf_elem_class &operator*=(const mpz_class&)#
renf_elem_class &operator/=(const mpz_class&)#
renf_elem_class &operator+=(const mpq_class&)#
renf_elem_class &operator-=(const mpq_class&)#
renf_elem_class &operator*=(const mpq_class&)#
renf_elem_class &operator/=(const mpq_class&)#

Relational Operators

Elements can be compared with the usual operators ==, !=, <, <=, >=, >. Internally, these operators are all derived from the definition of == and <.

friend bool operator==(const renf_elem_class&, const renf_elem_class&)#
friend bool operator<(const renf_elem_class&, const renf_elem_class&)#

Relational Operators with Integers & Rationals

Elements in a number field and integers/rationals can be compared with the usual relational operators ==, !=, <, <=, >=, >.

friend bool operator==(const renf_elem_class&, short)#
friend bool operator<(const renf_elem_class&, short)#
friend bool operator>(const renf_elem_class&, short)#
friend bool operator==(const renf_elem_class&, unsigned short)#
friend bool operator<(const renf_elem_class&, unsigned short)#
friend bool operator>(const renf_elem_class&, unsigned short)#
friend bool operator==(const renf_elem_class&, int)#
friend bool operator<(const renf_elem_class&, int)#
friend bool operator>(const renf_elem_class&, int)#
friend bool operator==(const renf_elem_class&, unsigned int)#
friend bool operator<(const renf_elem_class&, unsigned int)#
friend bool operator>(const renf_elem_class&, unsigned int)#
friend bool operator==(const renf_elem_class&, long)#
friend bool operator<(const renf_elem_class&, long)#
friend bool operator>(const renf_elem_class&, long)#
friend bool operator==(const renf_elem_class&, unsigned long)#
friend bool operator<(const renf_elem_class&, unsigned long)#
friend bool operator>(const renf_elem_class&, unsigned long)#
friend bool operator==(const renf_elem_class&, long long)#
friend bool operator<(const renf_elem_class&, long long)#
friend bool operator>(const renf_elem_class&, long long)#
friend bool operator==(const renf_elem_class&, unsigned long long)#
friend bool operator<(const renf_elem_class&, unsigned long long)#
friend bool operator>(const renf_elem_class&, unsigned long long)#
friend bool operator==(const renf_elem_class&, const mpz_class&)#
friend bool operator<(const renf_elem_class&, const mpz_class&)#
friend bool operator>(const renf_elem_class&, const mpz_class&)#
friend bool operator==(const renf_elem_class&, const mpq_class&)#
friend bool operator<(const renf_elem_class&, const mpq_class&)#
friend bool operator>(const renf_elem_class&, const mpq_class&)#

I/O

Elements can be written to streams and read from streams. However, reading non-rational elements from a stream is discouraged as it relies on the deprecated set_pword() method.

#include <strstream>
#include <e-antic/renf_class.hpp>
#include <e-antic/renf_elem_class.hpp>

auto K = eantic::renf_class::make("x^2 - 2", "x", "1.4 +/- 1");
auto a = K->gen();
std::strstream s;
s << a << std::ends;
std::cout << s.str();
// -> (x ~ 1.4142136)

s.seekp(0);
// Before we can read from the stream, we must attach the number field to it.
K->set_pword(s);
s >> a;

friend std::ostream &operator<<(std::ostream&, const renf_elem_class&)#
friend std::istream &operator>>(std::istream&, renf_elem_class&)#

Public Functions

inline const renf_class &parent() const#

Return the containing number field.

bool is_zero() const#

Return whether this element is the zero element in its field.

bool is_one() const#

Return whether this element is the one element in its field.

bool is_integer() const#

Return whether this element is a rational integer.

#include <e-antic/renf_class.hpp>
#include <e-antic/renf_elem_class.hpp>

auto K = eantic::renf_class::make("x^2 - 2", "x", "1.4 +/- 1");
K->gen().is_integer()
// -> false

K->one().is_integer()
// -> true

bool is_rational() const#

Return whether this element is a rational number.

#include <e-antic/renf_class.hpp>
#include <e-antic/renf_elem_class.hpp>

auto K = eantic::renf_class::make("x^2 - 2", "x", "1.4 +/- 1");
K->gen().is_rational()
// -> false

K->one().is_rational()
// -> true

std::add_lvalue_reference_t<::renf_elem_t> renf_elem_t() const#
mpz_class num() const#

Return the numerator of this element. The element must be rational for this to work, see num_content for non-rational elements.

mpz_class den() const#

Return the denominator of this element. For non-rational elements, this returns the least common multiple of the denominators of the coefficients when written as \(\sum c_i a^i\) where \(a\) is the field generator.

explicit operator mpz_class() const#

Convert this element to a GMP integer. The element must be an integer.

#include <e-antic/renf_class.hpp>
#include <e-antic/renf_elem_class.hpp>

auto K = eantic::renf_class::make("x^2 - 2", "x", "1.4 +/- 1");
std::cout << static_cast<mpz_class>(K->one());
// -> 1

explicit operator mpq_class() const#

Convert this element to a GMP rational number. The element must be a rational.

#include <e-antic/renf_class.hpp>
#include <e-antic/renf_elem_class.hpp>

auto K = eantic::renf_class::make("x^2 - 2", "x", "1.4 +/- 1");
std::cout << static_cast<mpq_class>(K->one());
// -> 1

std::vector<mpz_class> num_vector() const#

Return the numerators of the coefficients of this element when written as \(\sum c_i a^i\) where \(a\) is the field generator.

mpz_class num_content() const#

Return the greatest common divisor of num_vector.

#include <e-antic/renf_class.hpp>
#include <e-antic/renf_elem_class.hpp>

auto K = eantic::renf_class::make("x^2 - 2", "x", "1.4 +/- 1");
std::cout << (4*K->gen() + 2).num_content();
// -> 2
std::cout << K->zero().num_content();
// -> 0

mpz_class floor() const#

Return the integer floor of this element.

#include <e-antic/renf_class.hpp>
#include <e-antic/renf_elem_class.hpp>

auto K = eantic::renf_class::make("x^2 - 2", "x", "1.4 +/- 1");
std::cout << K->gen().floor();
// -> 1
std::cout << (-K->gen()).floor();
// -> -2

mpz_class ceil() const#

Return the integer ceil of this element.

#include <e-antic/renf_class.hpp>
#include <e-antic/renf_elem_class.hpp>

auto K = eantic::renf_class::make("x^2 - 2", "x", "1.4 +/- 1");
std::cout << K->gen().ceil();
// -> 2
std::cout << (-K->gen()).ceil();
// -> -1

int sgn() const#

Return the sign of this element. Returns one of -1, 0 or +1.

explicit operator double() const#

Return the double closest to this element. Ties are broken with ARF_RND_NEAR.

#include <e-antic/renf_class.hpp>
#include <e-antic/renf_elem_class.hpp>

auto K = eantic::renf_class::make("x^2 - 2", "x", "1.4 +/- 1");
std::cout << static_cast<double>(K->gen());
// -> 1.41421

renf_elem_class operator-() const#

Return the negative of this element.

#include <e-antic/renf_class.hpp>
#include <e-antic/renf_elem_class.hpp>

auto K = eantic::renf_class::make("x^2 - 2", "x", "1.4 +/- 1");
std::cout << -K->gen();
// -> (-x ~ -1.4142136)

renf_elem_class operator+() const#

Return the positive of this element. Returns the element unchanged.

explicit operator bool() const#

Return whether this element is non-zero.

#include <e-antic/renf_class.hpp>
#include <e-antic/renf_elem_class.hpp>

auto K = eantic::renf_class::make("x^2 - 2", "x", "1.4 +/- 1");
bool(K->gen())
// -> true

mpz_class floordiv(const renf_elem_class &rhs) const#

Return the integer floor of the division of this element by rhs.

renf_elem_class pow(int exponent) const#

Return an integer power of this element.

Friends

friend void swap(renf_elem_class &lhs, renf_elem_class &rhs) noexcept#

Efficiently swap two number field elements.