Introduction to polexpr
polexpr is a TeX and LaTeX macro package.
To use it with Plain or formats other than LaTeX:
To use it with LaTeX:
polexpr loads xintexpr and extends its syntax with a polynomial type.
Polynomials are defined via the \poldef parser and
can then be manipulated via TeX macros for various operations such
as obtaining G.C.D.s, computing derivatives, or indefinite
integrals… many of these functionalities are available directly
via functions in the syntax recognized by the
Apart from the final step of internally creating some TeX macros
associated with the polynomial name, this is all done completely
expandably, and a polynomial expression can be fetched directly to
\xinteval for a completely expandable operation from start to
For polynomials fully declared via
\poldef, root localization
implementing the Sturm algorithm is available via macros.
Arbitrarily long decimal expansion of all real roots can be
obtained, and all rational roots can be found exactly.
The legacy documentation section which showed examples of root localization has been moved to the polexpr-examples.pdf document, where both the TeX code and its output are displayed.
To access this document (if the previous link for some reason does not work):
Usage via xintsession
The simplest manner to get a feeling for the package abilities regarding in particular root localization is to use it on the command line via the xintsession interface. Here is an example:
$ rlwrap etex xintsession [...xintsession welcome message...] Starting in exact mode (floating point evaluations use 16 digits) >>> &pol pol mode (i.e. function definitions use \poldef) >>> f(x) := x^7 - x^6 - 2x + 1; f = x^7-x^6-2*x+1 --> &GenFloat(f) lets f become usable as function in fp mode --> &ROOTS(f) (resp. &ROOTS(f,N)) finds all rational roots exactly and all irrational roots with at least 10 (resp. N) fractional digits >>> &ROOTS(f) Solving for real roots of f and assigning them (please wait...) (mult. 1) Rootf_1 = -1.0719678841... (mult. 1) Rootf_2 = 0.4962386948... (mult. 1) Rootf_3 = 1.3151140860... Square-free irrational part: x^7-x^6-2*x+1 --> &REFINEROOTS(f,N) to extend real irr. roots to N fractional digits >>> &REFINEROOTS(f,40) Refining real roots of f to 40 digits (please wait...) (mult. 1) Rootf_1 = -1.0719678841080266034109100331975342338141... (mult. 1) Rootf_2 = 0.4962386948771497344730618510143671567979... (mult. 1) Rootf_3 = 1.3151140860165192656960005018679846354234...
The xintsession interface allows to define polynomial variables via its
&pol mode. It also exposes all polynomial functions added to the
xintexpr syntax by
polexpr. Further, as seen in the
example above it also covers some of the
currently implemented via user macros. This is to be considered a work
in progress, the above
&REFINEROOTS may be renamed
into something else, and may have been so already since this
documentation was written.
Any input on the command line at the xintsession
>>> prompt which
starts with a backslash is executed as TeX macros, so all macros of
polexpr are in fact already available, including those typesetting
material in background of the interactive session on command line. The
&REFINEROOTS direct their outputs to the
terminal rather than to the TeX page as would the typesetting macros
License is LPPL 1.3c
This work is distributed under the conditions of the LaTeX Project Public License version 1.3c.
See README.md for details.
In memoriam: Jürgen Gilg (1966-2022)
My first contact with Jürgen was in January 2018, and his little question about usage of xintexpr for differentiating polynomials proved the direct cause for the creation of polexpr. His regular comments and questions (often, jointly with Thomas Söll) largely contributed to motivate the author into investing time and effort into the somewhat strange occupation of developing such unusual TeX/LaTeX packages. The topics of our discussions evolved over the years and were not limited to TeX, LaTeX, PSTricks or PostScript matters.
I learned to discover and appreciate his unassuming and kind character. He was very conscientious in all his projects with others and was often overly generous in his appreciation of people’s contributions. On receiving the sad news of his unexpected and untimely death, I initially thought I had been knowing him for at least 10 years, but it is actually only a bit more than 4 years… I will sorely miss this friendship with a gentle soul from over the Rhine.
I dedicate the work which has gone into polexpr to Jürgen’s memory.