renf_class.hpp — Real Embedded Number Fields

Class renf_class

A Real Embedded Number Field.

All number fields are simple extensions of the rational numbers whose defining minimal polynomial has a real root.

To create a number field, use one of the factory functions; typically, by specifying the minimal polynomial of the number field and selecting a real root:

#include <e-antic/renf_class.hpp>

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

These factories return an intrusive pointer to a number field which takes care of reference counting, i.e., you do not need to worry about dangling references; any element of the number field keeps the number field itself alive.

All number fields are unique. If you are familiar with SageMath, they are “unique parents”. If you create the same number field twice, you get a reference to the same field:

#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 L = eantic::renf_class::make("x^2 - 2", "x", "1.41 +/- 1");

L->gen().parent() == *K
// -> true

&L->gen().parent() == &*K
// -> true

Number fields are hashable but not ordered, i.e., they can be used in containers such as std::unordered_set but not in std::set.

const renf_class& make()

Return the trivial number field obtained by adjoining a root of $x - 1$ to the rationals.

boost::intrusive_ptr<const renf_class> make(const ::renf_t, const string& gen)

Return the number field created from a ::renf_t, the C type underlying a renf_class.

boost::intrusive_ptr<const renf_class> make(const string& minpoly, const string& gen, const string& emb, slong prec)

Return the number field obtained by adjoining the root of minpoly which is approximately emb.

#include <e-antic/renf_class.hpp>

auto K = eantic::renf_class::make("2*x^4 - 4", "x", "1 +/- 1");

Parameter minpoly

An irreducible polynomial in the variable gen.

This minimal polynomial does not have to be totally real or monic.

Parameter gen

The name of the variable used in minpoly.

Note that two fields that differ only in the name of the generator are treated as being distinct fields.

Parameter emb

An approximation of the root of minpoly.

It makes no difference to what precision this approximation is provided but it must uniquely determine a single root of the polynomial.

Parameter prec

The default precision for all arithmetic.

When performing arithmetic in this field, all operations are performed to that precision. When necessary, the precision is dynamically increased. This only affects the performance and inner workings of libeantic, the results of arithmetic operations and comparisons are not affected by this.

boost::intrusive_ptr<const renf_class> make(const string& minpoly, const string& gen, const function<string (slong)> emb, slong prec)

Return the number field obtained by adjoining the root of minpoly which is approximately emb.

#include <e-antic/renf_class.hpp>
#if __FLINT_RELEASE < 30000
#include <arb.h>
#include <arf.h>
#else
#include <flint/arb.h>
#include <flint/arf.h>
#endif

const auto emb = [](slong prec) {
    arb_t emb;
    arb_init(emb);
    arb_sqrt_ui(emb, 2, prec);
    char* c_str = arb_get_str(emb, prec, ARB_STR_NO_RADIUS);
    std::string str(c_str);
    flint_free(c_str);
    arb_clear(emb);
    return str;
};

auto K = eantic::renf_class::make("x^2 - 2", "x", emb);

Parameter minpoly

An irreducible polynomial in the variable gen.

This minimal polynomial does not have to be totally real or monic.

Parameter gen

The name of the variable used in minpoly.

Note that two fields that differ only in the name of the generator are treated as being distinct fields.

Parameter emb

Creates approximations of the root of minpoly that is suitable for computations with precision prec.

It makes no difference to what precision this approximation is provided but it must for a sufficiently large value of prec uniquely determine a single root of the polynomial; with increasing prec it should converge to the actual root.

Parameter prec

The default precision for all arithmetic.

When performing arithmetic in this field, all operations are performed to that precision. When necessary, the precision is dynamically increased. This only affects the performance and inner workings of libeantic, the results of arithmetic operations and comparisons are not affected by this.

slong degree() const

Return the absolute degree of this number field.

const renf_elem_class& zero() const

Return the zero element of this number field.

const renf_elem_class& one() const

Return the one element of this number field.

const renf_elem_class& gen() const

Return the generator of this number field.

#include <e-antic/renf_class.hpp>

auto& K = eantic::renf_class::make();
std::cout << K.gen();
// -> 1

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

tuple<string, string, string, slong> construction() const

Return the parameters (minpoly, gen, emb, prec) that can be used to construct this field with make.

#include <e-antic/renf_class.hpp>

auto K = eantic::renf_class::make("2*x^4 - 4", "x", "1 +/- 1");

auto construction = K->construction();
auto L = eantic::renf_class::make(
  std::get<0>(construction),
  std::get<1>(construction),
  std::get<2>(construction),
  std::get<3>(construction));
K == L
// -> true

friend bool operator==(const renf_class&, const renf_class&)

Return whether two number fields are indistinguishable.

#include <e-antic/renf_class.hpp>

auto K = eantic::renf_class::make("x^2 - 2", "x", "1 +/- 1");
auto L = eantic::renf_class::make("x^2 - 2", "x", "1.41 +/- 0.1");
K == L
// -> true

auto K = eantic::renf_class::make("x^2 - 2", "x", "1 +/- 1");
auto L = eantic::renf_class::make("2*x^2 - 4", "x", "1 +/- 1");
K == L
// -> false

auto K = eantic::renf_class::make("x^2 - 2", "x", "1 +/- 1");
auto L = eantic::renf_class::make("y^2 - 2", "y", "1 +/- 1");
K == L
// -> false

K != L
// -> true

const string& gen_name() const

Return the name of the generator of this field.

string to_string() const

Return a human-readable representation of this field.

#include <e-antic/renf_class.hpp>

auto K = eantic::renf_class::make("2*x^4 - 4", "x", "1 +/- 1");
K->to_string()
// -> NumberField(2*x^4 - 4, [1.18920711500272106671749997056 +/- 1.11e-30])

// There is also an operator<< which gives the same output.
std::cout << *K;
// -> NumberField(2*x^4 - 4, [1.18920711500272106671749997056 +/- 1.11e-30])

friend ostream& operator<<(ostream&, const renf_class&)

Write a human-readable representation of this field to the output stream.

add_lvalue_reference_t< ::renf_t> renf_t() const

Return the underlying renf_t.

We do not return a const renf_t since calls in the C API might need to modify it (e.g., to refine the stored embedding) even though they are morally const.