==================
e-antic Change Log
==================

.. current developments

v1.3.0
====================

**Added:**

* Added support for FLINT 2.8 and 2.9
* Added short and unsigned short operators to C++ interface.



v1.2.3
====================

**Added:**

* Added automatic update on conda-forge with every release.

**Fixed:**

* Fixed soname which was not bumped in the 1.2.2 release.



v1.2.2
====================

**Fixed:**

* Fixed conda channels used for binder notebooks.
* Fixed compilation errors on recent compilers by upgrading catch2 dependency used for testing.
* Fixed deserialization of renf_class from old Python pickles. (#242 sometimes crashed when called from Python since cppyy had trouble with the exceptions being thrown.)
* Fixed "installation with conda" page in our documentation (#240)
* Added logo to documentation. (#239)
* Fixed serialization with cereal 1.3.1+.
* Fixed compiler warnings about missing prototypes for test functions.



v1.2.1
====================

**Fixed:**

* Fixed serialization of `renf_class` with cereal>=1.3.2 (#224)

* Fixed deserialization of objects serialized with e-antic prior to 1.0.0



v1.2.0
====================

**Performance:**

* Improved conversion from vectors of rational coefficients to `renf_elem_class` by using a faster code path in FLINT.

* Improved conversion from SageMath number fields to pyeantic `RealEmbeddedNumberField`. This **adds a dependency** of pyeantic on gmpxxyy.



v1.1.1
====================

**Deprecated:**

* Deprecated arithmetic between elements in different number fields in the C++ interface. Before, an operation such as `a + b` was possible even if `a` and `b` lived in different number fields if at least one of them was actually a rational number. This led to inconsistent parent fields of the resulting element. We still allow such operations if the parent of `a` or `b` is the rational field (`renf_class::make()`) otherwise a deprecation warning is printed. To fully opt in to the new behaviour set the environment variable `LIBEANTIC_STRICT_BINOP` to any value; this raises an exception instead of printing a warning.

**Fixed:**

* Fixed a compilation error on some xenial systems.
* Fixed import order in pyeantic's setup.py script.
* Fixed inclusion of .map files in distribution tarball even if building without version script support.

**Performance:**

* Improved performance of `RealEmbeddedNumberField` in Python interface by caching results. In particular the costly conversion from `renf_class`.



v1.1.0
====================

**Added:**

* automatic integration checks for [Normaliz](https://github.com/Normaliz/Normaliz)
* Added support for Python 3.10; we are now automatically testing pyeantic with
  Python 3.10.
* Added `renf_class` that uses a root with dynamic precision. (Makes it easier to specify a root when the roots of the minimal polynomial are very close to each other.)

**Changed:**

* We do not claim anymore that `_cmp` functions return -1, 0, 1. Instead we
  only make a statement about the sign of the integer returned. In practice we
  still return -1, 0, 1 for the time being.
* Header file `e-antic.h` is now called `local.h`. There is still a header file
  `e-antic.h` that includes all of e-antic's C interface, so in particular
  `local.h`.
* Header file `renfxx_fwd.hpp` is now called `forward.hpp`. The old header file
  `renfxx_fwd.hpp` can still be used.
* Header file `renfxx.h` is now called `e-antic.hpp`. The old header file
  `renfxx.h` can still be used.
* Dropped explicit support for Python 3.6 which has reached its end of life. It
  should still work but we are not testing it explicitly in our CI anymore.

**Fixed:**

* We do not assume anymore that `_cmp` functions return -1, 0, 1. FLINT, GMP,
  and Arb only guarantee that these functions return a negative, zero, or
  positive integer. In practice their implementations return -1, 0, 1, however
  in some obscure case on Fedora/i686, this was not the case.
* Removed unused includes that cannot be resolved on Windows.
* Fixed a compiler warning on Fedora.
* Improved the error message when arb headers cannot be found. Fedora installs the arb headers into /usr/include/arb instead of /usr/include.
* Added missing `LIBEANTIC_API` declarators so building with `-fvisibility=hidden` produces a usable libeanticxx.so.
* Updated installation instructions for installation from conda-forge. The
  e-antic package there has been renamed to libeantic. The package `e-antic`
  still exists but is now essentially an alias for `libeantic` and `pyeantic`.
* Worked around doctesting issues in SageMath 9.4.
* Fixed failing SageMath tests when pytest is installed.
* Fixed construction of `RealEmbeddedNumberField` in Python when roots of the minimal polynomial are very close to each other.



v1.0.3
====================

**Fixed:**

* Cleaned up the README and our Zenodo site.

* Fixed linking of C++ test programs.



v1.0.2
====================

**Fixed:**

* removed docbuild warnings for latest version of mkdocs.
* Fixed parsing of trivial number fields in pyeantic. #197
* Conversion from `NumberField` to `RealEmbeddedNumberField` when defining polynomial is not in `x`.



v1.0.1
====================

**Fixed:**

* `./configure` now checks for cppyythonizations which are required to run Python tests
* allow creation of `RealEmbeddedNumberField` from an intrusive pointer in pyeantic.
* Skip tests requiring realalg and sage when configured --without-realalg and --without-sage, respectively.
* Disable pyeantic testing --without-pytest.



v1.0.0
====================

**Added:**

* Added `renf_class::construction()` which produces the parameters that can be used to create a `renf_class` with `renf_class::make()`.
* Run CI on macOS & Linux
* Added `renf_class::get_pword` to extract the number field set with `renf_class::set_pword` to ease migration of legacy code.
* Added `.map` files so only API symbols get exported when running `./configure --with-version-script`.
* Added visibility attributes to header files; this will be necessary on Windows and allows compilation with `-fvisibility=hidden`
* Conda packages are now uploaded automatically to the flatsurf channel with every release.
* Integrated the Python wrapper pyeantic into the e-antic repository
* Added `renf_elem_class::floordiv()` to perform `(a/b).floor()` more efficiently
* Floor division of `renf_elem_t`
* Added the missing implementations of free `floor`, `ceil`, and `pow` functions to the C++ library.
* Added `renf_elem_swap(renf_elem_t, renf_elem_t)`
* There is now `e-antic/renfxx_fwd.hpp` if you only need forward declarations
  of `renf_class` and `renf_elem_class`.
* `renf_elem_class` can now be created from signed and unsigned long long.
* `renf_elem_class` can now be created from vectors of primitive integers, e.g.,
  ```
  renf_elem_class x(K, {1, 2, 3}); // = 3*x^2 + 2*x + 1
  ```
  where before the entries of the vector had to be `mpz_class`.
* Move semantics `&&` have been added to `renf_elem_class`.
* There is now support for serialization with cereal. See t-cereal.cpp for
  examples on how to use it.
* The release process has been automated with [rever](https://regro.github.io/rever-docs/)

**Changed:**

* Split `renfxx.h` into `renf_elem_class.hpp` and `renf_class.hpp` headers. The
  original header still exists and simply includes the two novel headers.
* Split the header `e-antic/poly_extra.h` into `e-antic/fmpz_poly_extra.h` and
  `e-antic/fmpq_poly_extra.h`. Typically, you do not want to include either of
  those as they are mostly meant to be used internally.
* C++ Comparison operators of `renf_elem_class` are now free so they participate in
  implicit casts in the same way like the boost generated free operators that
  are derived from them.
* The C++ interface now requires C++14.
* All C++ classes are now declared in the namespace `eantic`.
* The semantics of the C++ `operator =` have changed. In e-antic 0.1 the
  following would create the unit in the field K.
  ```
  renf_elem_class x(K);
  x = 1;
  ```
  Now the above statement makes x a rational number. More generally, an
  assignment resets the number field so that after `x = y` the condition
  `x.nf == renf_elem_class(y).nf` holds. To mimic the old behavior you need
  to rewrite the above as
  ```
  renf_elem_class x(K);
  x = renf_elem_class(K, 1);
  ```
* The C++ `renf_class` is now hidden behind a factory to get smart pointer
  semantics everywhere. Create a `renf_class` by calling `renf_class::make(…)`.
  This returns a smart pointer, so you might have to replace some `.` with
  `->`.
* The change of semantics in assignment also affects reading from streams (in
  order to create `renf_elem_class`). Before the following would parse an element
  into a number field:
  ```
  renf_elem_class x(K);
  in >> x;
  ```
  Now this only works if the stream contains a rational number. (Otherwise an
  exception is raised.) As `in >> x` also resets `x.nf`. The above code should
  be replaced with:
  ```
  renf_elem_class x;
  K.set_pword(in);
  in >> x;
  ```
* `string renf_class::gen_name` is now a method so it needs to be called.
* Many operations that threw an exception before when domains were mixed, now
  abort program execution (typically through a call to `assert()`.) You are not
  supposed to mix domains unless explicitly stated otherwise.
* `renf_class.operator==` now also checks that the generator name is the same.
  Similarly, `renf_class.operator=` now also resets the generator name.
* Changed renf_elem generator in C++ unit tests to always start with the zero
  element since it probably does not get generated by chance and can obviously
  cause a lot of trouble.

**Deprecated:**

* Some methods have been deprecated and might be removed in a future release,
  mostly to make the interface more consistent. The deprecation warnings give
  hints which methods to use instead.

**Removed:**

* `renf_elem_class(string&)` has been removed. If you want to parse a rational
  number, use `renf_elem_class(mpq_class(string))`. If you want to parse into a
  number field, use `renf_elem_class(renf_class&, string&)`.
* `renf_elem_class::operator=(string&)` has been removed. If you want to parse
  a rational into an element, use `x = mpq_class(string)`. If you want to parse
  into a number field, use `x = renf_elem_class(x.parent(), string)`.
* `renf_elem_class(vector<...>)` have been removed as it would have thrown an
  exception always anyway.
* `renf_elem_class::operator=(vector<...>)` have been removed due to the change
  of semantics of `=`. If `x` is not a rational you get the same behaviour as
  before with `x = renf_elem_class(x.parent(), {1, 2, 3})`.
* `renf_class::xalloc()` has been removed and replaced by an implementation
  detail.

**Fixed:**

* Compatible with FLINT 2.7
* Removed dependency of `renfxx_cereal.h` on Arb and FLINT, i.e., one does not need to `-larb -lflint` anymore when using cereal.
* Set pins in Conda packages as they are in https://github.com/conda-forge/conda-forge-pinning-feedstock
* `E_ANTIC_RELEASE` now reports the correct version number, i.e., 10000.
* e-antic had claimed to be thread safe via an open MP pragma (in the number
  field refinement). In some cases, there was a problem with thread-safety. We
  now require users to explicitly mark multithreaded sections by forbidding
  mutations to a renf, see `renf_set_immutable`. As a result, there are some
  operations that cannot be done anymore in a multi-threaded environment but
  they now fail properly (instead of leading to random crashes.)

**Performance:**

* Speed up arithmetic between `renf_elem_class` in C++ interface.
* Speed up creation of trivial number fields by a factor of seven.
* Speed up `renf_class::operator==`



v1.0.0-rc.16
====================

**Fixed:**

* Fixed arithmetic with rationals in different number fields.



v1.0.0-rc.15
====================

**Fixed:**

* Made lexical_cast include work with more versions of boost.



v1.0.0-rc.14
====================

**Changed:**

* Split `renfxx.h` into `renf_elem_class.hpp` and `renf_class.hpp` headers. The
  original header still exists and simply includes the two novel headers.

**Performance:**

* Speed up arithmetic between `renf_elem_class` in C++ interface.
* Speed up creation of trivial number fields by a factor of seven.



v1.0.0-rc.13
====================

**Added:**

* Added `renf_class::construction()` which produces the parameters that can be used to create a `renf_class` with `renf_class::make()`.

**Fixed:**

* compatible with FLINT 2.7
* Removed dependency of `renfxx_cereal.h` on Arb and FLINT, i.e., one does not need to `-larb -lflint` anymore when using cereal.



v1.0.0-rc.12
====================

**Added:**

* run CI on macOS & Linux
* added `renf_class::get_pword` to extract the number field set with `renf_class::set_pword` to ease migration of legacy code.
* added `.map` files so only API symbols get exported when running `./configure --with-version-script`.
+ added visibility attributes to header files; this will be necessary on Windows and allows compilation with `-fvisibility=hidden`

**Fixed:**

* set pins in Conda packages as they are in https://github.com/conda-forge/conda-forge-pinning-feedstock
* adapt to changes in cppyy 1.9.0
* `E_ANTIC_RELEASE` now reports the correct version number, i.e., 10000.



v1.0.0-rc.11
====================

**Fixed:**

* fixed pyeantic version bump in rever script



v1.0.0-rc.10
====================

**Added:**

* Conda packages are now uploaded automatically to the flatsurf channel with every release.
* integrated pyeantic into the e-antic repository



v1.0.0-rc.9
====================

**Changed:**

* Split the header `e-antic/poly_extra.h` into `e-antic/fmpz_poly_extra.h` and
  `e-antic/fmpq_poly_extra.h`. Typically, you do not want to include either of
  those as they are mostly meant to be used internally.

**Fixed:**

* Either side of a floor division may now be rational.



v1.0.0-rc.8
====================

**Added:**

* `renf_elem_class::floordiv()` to perform `(a/b).floor()` more efficiently

**Changed:**

* changed renf_elem generator to always start with the zero element since it
  probably does not get generated by chance and can obviously cause a lot of
  trouble.



v1.0.0-rc.7
====================



v1.0.0-rc.6
====================



v1.0.0-rc.5
====================

**Added:**

* floor division of `renf_elem_t`
* added the missing implementations of free `floor`, `ceil`, and `pow` functions to the C++ library.

**Changed:**

* simplified testing of binary operators
* Comparison operators of `renf_elem_class` are now free so they participate in
  implicit casts in the same way like the boost generated free operators that
  are derived from them.

**Fixed:**

* Adapted to changes in unique-factory.
* implemented `renf_elem_class(renf_class, std::vector)` constructors that went missing in 39e1215e421e128b230fb62ff88ae0ac9b6414e7.

**Performance:**

* Speed up `renf_class::operator==`



v1.0.0-rc.3
====================

**Fixed:**

* release tarball was missing some header files with long names



v1.0.0-rc.2
====================

**Added:**

* ` renf_elem_swap(renf_elem_t, renf_elem_t)`
* There is now `e-antic/renfxx_fwd.h` if you only need forward declarations of
  `renf_class` and `renf_elem_class`.
* `renf_elem_class` can now be created from signed and unsigned long long.
* `renf_elem_class` can now be created from vectors of primitive integers, e.g.,
  ```
  renf_elem_class x(K, {1, 2, 3}); // = 3*x^2 + 2*x + 1
  ```
  where before the entries of the vector had to be `mpz_class`.
* Move semantics `&&` have been added to `renf_elem_class`.
* There is now support for serialization with cereal. See t-cereal.cpp for
  examples on how to use it.
* the release process has been automated with [rever](https://regro.github.io/rever-docs/)

**Changed:**

* `e-antic/renfxx.h` now requires C++17.
* All classes are now declared in the namespace `eantic`.
* The semantics of `operator =` have changed. In e-antic 0.1 the following
  would create the unit in the field K.
  ```
  renf_elem_class x(K);
  x = 1;
  ```
  Now the above statement makes x a rational number. More generally, an
  assignment resets the number field so that after `x = y` the condition
  `x.nf == renf_elem_class(y).nf` holds. To mimic the old behavior you need
  to rewrite the above as
  ```
  renf_elem_class x(K);
  x = renf_elem_class(K, 1);
  ```
* `renf_class` is now hidden behind a factory to get shared_ptr semantics
  everywhere. Create a `renf_class` by calling `renf_class::make(…)`. This
	returns a smart pointer, so you might have to replace some `.` with `->`.
* The change of semantics in assignment also affects reading from streams (in
  order to create `renf_elem_class`). Before the following would parse an element
  into a number field:
  ```
  renf_elem_class x(K);
  in >> x;
  ```
  Now this only works if the stream contains a rational number. (Otherwise an
  exception is raised.) As `in >> x` also resets `x.nf`. The above code should
  be replaced with:
  ```
  renf_elem_class x;
  K.set_pword(in);
  in >> x;
  ```
* `string renf_class::gen_name` is now a method so it needs to be called.
* Many operations that threw an exception before when domains were mixed, now
  abort program execution (typically through a call to `assert()`.) You are not
  supposed to mix domains unless explicitly stated otherwise.
* `renf_class.operator==` now also checks that the generator name is the same.
  Similarly, `renf_class.operator=` now also resets the generator name.

**Deprecated:**

* Some methods have been deprecated and might be removed in a future release,
  mostly to make the interface more consistent. The deprecation warnings give
  hints which methods to use instead.

**Removed:**

* `renf_elem_class(string&)` has been removed. If you want to parse a rational
  number, use `renf_elem_class(mpq_class(string))`. If you want to parse into a
  number field, use `renf_elem_class(renf_class&, string&)`.
* `renf_elem_class::operator=(string&)` has been removed. If you want to parse
  a rational into an element, use `x = mpq_class(string)`. If you want to parse
  into a number field, use `x = renf_elem_class(x.parent(), string)`.
* `renf_elem_class(vector<...>)` have been removed as it would have thrown an
  exception always anyway.
* `renf_elem_class::operator=(vector<...>)` have been removed due to the change
  of semantics of `=`. If `x` is not a rational you get the same behaviour as
  before with `x = renf_elem_class(x.parent(), {1, 2, 3})`.
* `renf_class::xalloc()` has been removed and replaced by an implementation
  detail.

**Fixed:**

* e-antic had claimed to be thread safe via an open MP pragma (in the number
  field refinement). In some cases, there was a problem with thread-safety. We
  now require users to explicitly mark multithreaded sections by forbidding
  mutations to a renf, see `renf_set_immutable`. As a result, there are some
  operations that cannot be done anymore in a multi-threaded environment but
  they now fail properly (instead of leading to random crashes.)



v0.1
====

**Added:**

* real roots isolation and refinement (poly_extra.h)
* renf structure (renf.h)
* renf_elem structures (renf_elem.h)
* C++ interface (renfxx.h)

