summaryrefslogtreecommitdiff
path: root/macros
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2021-03-30 03:00:56 +0000
committerNorbert Preining <norbert@preining.info>2021-03-30 03:00:56 +0000
commit93809c868bf15852ddc7b50542713131a5d8c05f (patch)
tree3c741be9d43fdee2f3ecdb17d463deb188d881a8 /macros
parent3c5dd0d2f091e5e866af1de0327171b253ec9178 (diff)
CTAN sync 202103300300
Diffstat (limited to 'macros')
-rw-r--r--macros/generic/polexpr/README.md (renamed from macros/latex/contrib/polexpr/README.md)95
-rw-r--r--macros/generic/polexpr/polexpr.html4086
-rw-r--r--macros/generic/polexpr/polexpr.sty1057
-rw-r--r--macros/generic/polexpr/polexprcore.tex1366
-rw-r--r--macros/generic/polexpr/polexprexpr.tex179
-rw-r--r--macros/generic/polexpr/polexprsturm.tex (renamed from macros/latex/contrib/polexpr/polexpr.sty)1813
-rw-r--r--macros/generic/xint/CHANGES.html177
-rw-r--r--macros/generic/xint/README.md8
-rw-r--r--macros/generic/xint/sourcexint.pdfbin1026778 -> 1031328 bytes
-rw-r--r--macros/generic/xint/xint.dtx852
-rw-r--r--macros/generic/xint/xint.pdfbin1006708 -> 1012827 bytes
-rw-r--r--macros/latex/contrib/pkuthss/doc/example.pdfbin93675 -> 95861 bytes
-rw-r--r--macros/latex/contrib/pkuthss/doc/example/chap/abs.tex6
-rw-r--r--macros/latex/contrib/pkuthss/doc/example/chap/origin.tex10
-rw-r--r--macros/latex/contrib/pkuthss/doc/example/thesis.tex37
-rw-r--r--macros/latex/contrib/pkuthss/doc/pkuthss.pdfbin315791 -> 325590 bytes
-rw-r--r--macros/latex/contrib/pkuthss/doc/readme/ChangeLog.txt16
-rw-r--r--macros/latex/contrib/pkuthss/doc/readme/chap/pkuthss-abs.tex6
-rw-r--r--macros/latex/contrib/pkuthss/doc/readme/chap/pkuthss-ack.tex5
-rw-r--r--macros/latex/contrib/pkuthss/doc/readme/chap/pkuthss-chap2.tex43
-rw-r--r--macros/latex/contrib/pkuthss/doc/readme/chap/pkuthss-chap3.tex21
-rw-r--r--macros/latex/contrib/pkuthss/doc/readme/chap/pkuthss-copy.tex4
-rw-r--r--macros/latex/contrib/pkuthss/doc/readme/pkuthss-english.patch68
-rw-r--r--macros/latex/contrib/pkuthss/doc/readme/pkuthss.bib37
-rw-r--r--macros/latex/contrib/pkuthss/doc/readme/pkuthss.tex30
-rw-r--r--macros/latex/contrib/pkuthss/tex/pkulogo.pdfbin3530 -> 3530 bytes
-rw-r--r--macros/latex/contrib/pkuthss/tex/pkuthss-gbk.def14
-rw-r--r--macros/latex/contrib/pkuthss/tex/pkuthss-utf8.def14
-rw-r--r--macros/latex/contrib/pkuthss/tex/pkuthss.cls97
-rw-r--r--macros/latex/contrib/pkuthss/tex/pkuword.pdfbin6280 -> 6280 bytes
-rw-r--r--macros/latex/contrib/polexpr/polexpr.html2911
-rw-r--r--macros/latex/contrib/polexpr/polexpr.txt2598
-rw-r--r--macros/latex/contrib/srdp-mathematik/README.txt56
-rw-r--r--macros/latex/contrib/srdp-mathematik/srdp-mathematik.pdfbin161583 -> 176727 bytes
-rw-r--r--macros/latex/contrib/srdp-mathematik/srdp-mathematik.sty54
-rw-r--r--macros/latex/contrib/srdp-mathematik/srdp-mathematik.tex238
-rw-r--r--macros/xetex/latex/xesoul/README5
-rw-r--r--macros/xetex/latex/xesoul/xesoul.dtx103
-rw-r--r--macros/xetex/latex/xesoul/xesoul.ins53
-rw-r--r--macros/xetex/latex/xesoul/xesoul.pdfbin0 -> 23237 bytes
40 files changed, 8204 insertions, 7855 deletions
diff --git a/macros/latex/contrib/polexpr/README.md b/macros/generic/polexpr/README.md
index a901b56adc..b32b8f056d 100644
--- a/macros/latex/contrib/polexpr/README.md
+++ b/macros/generic/polexpr/README.md
@@ -1,46 +1,43 @@
Package polexpr README
======================
-License
--------
+Usage
+-----
-Copyright (C) 2018-2020 Jean-François Burnol
+The package can be used with TeX based formats incorporating the
+e-TeX primitives. The `\expanded` primitive available generally
+since TeXLive 2019 is required.
-See documentation of package [xint](http://www.ctan.org/pkg/xint) for
-contact information.
+ \input polexpr.sty
-This Work may be distributed and/or modified under the conditions of the
-LaTeX Project Public License version 1.3c. This version of this license
-is in
+with Plain or other non-LaTeX macro formats, or:
-> <http://www.latex-project.org/lppl/lppl-1-3c.txt>
+ \usepackage{polexpr}
-and version 1.3 or later is part of all distributions of LaTeX version
-2005/12/01 or later.
+with the LaTeX macro format.
-This Work has the LPPL maintenance status author-maintained.
-
-The Author of this Work is Jean-François Burnol.
-
-This Work consists of the package file polexpr.sty, this README.md and
-the documentation file polexpr.txt.
+The package currently requires xintexpr.sty `1.4d` or later.
Abstract
--------
-The package provides `\poldef`. This a parser of polynomial expressions
-based upon the `\xintdeffunc` mechanism of xintexpr.
+The package provides a parser `\poldef` of algebraic polynomial
+expressions. As it is based on
+[xintexpr](http://www.ctan.org/pkg/xint)
+the coefficients are allowed to be arbitrary rational numbers.
-The parsed expressions use the operations of algebra (inclusive of
-composition of functions) with standard operators, fractional numbers
-(possibly in scientific notation) and previously defined polynomial
-functions or other constructs as recognized by the `\xintexpr` numerical
-parser.
+Once defined, a polynomial is usable by its name either as a numerical
+function in `\xintexpr/\xinteval`, or for additional polynomial
+definitions, or as argument to the package macros. The localization of
+real roots to arbitrary precision as well as the determination of all
+rational roots is implemented via such macros.
-The polynomials are then not only genuine `\xintexpr` (and
-`\xintfloatexpr`) numerical functions but additionally are known to the
-package via their coefficients. This allows dedicated macros to
-implement polynomial algorithmics.
+Since release `0.8`, polexpr extends the
+[xintexpr](http://www.ctan.org/pkg/xint) syntax to recognize
+polynomials as a new variable type (and not only as functions).
+Functionality which previously was implemented via macros such as the
+computation of a greatest common divisor is now available directly in
+`\xintexpr`, `\xinteval` or `\poldef` via infix or functional syntax.
Releases
--------
@@ -62,7 +59,7 @@ Releases
- Main new feature: root localization via [Sturm
Theorem](https://en.wikipedia.org/wiki/Sturm%27s_theorem).
- 0.4.1 (2018/03/01)
- Synced with xint 1.3.
+ Synced with xintexpr 1.3.
- 0.4.2 (2018/03/03)
Documentation fix.
- 0.5 (2018/04/08)
@@ -82,21 +79,45 @@ Releases
Bugfix: 20000000000 is too big for \numexpr, shouldn't I know that?
Thanks to Jürgen Gilg for report.
- 0.7.5 (2020/01/31)
- Synced with xint 1.4. Requires it.
+ Synced with xintexpr 1.4. Requires it.
+- 0.8 (2021/03/29)
+ Complete refactoring of the package core for better integration with
+ and enhancement of xintexpr 1.4.
-Files of 0.7.5 release:
+Files of 0.8 release:
+- polexpr.sty, polexprcore.tex, polexprexpr.tex, polexprsturm.tex,
- README.md,
-- polexpr.sty (package file),
-- polexpr.txt (documentation),
-- polexpr.html (conversion via
- [DocUtils](http://docutils.sourceforge.net/docs/index.html)
- rst2html.py)
+- polexpr.html (documentation)
Acknowledgments
---------------
Thanks to Jürgen Gilg whose question about
-[xint](http://www.ctan.org/pkg/xint) usage for differentiating
+[xintexpr](http://www.ctan.org/pkg/xintexpr) usage for differentiating
polynomials was the initial trigger leading to this package, and to
Jürgen Gilg and Thomas Söll for testing it on some concrete problems.
+
+License
+-------
+
+Copyright (C) 2018-2021 Jean-François Burnol
+
+See documentation of package [xintexpr](http://www.ctan.org/pkg/xint) for
+contact information.
+
+This Work may be distributed and/or modified under the conditions of the
+LaTeX Project Public License version 1.3c. This version of this license
+is in
+
+> <http://www.latex-project.org/lppl/lppl-1-3c.txt>
+
+and version 1.3 or later is part of all distributions of LaTeX version
+2005/12/01 or later.
+
+This Work has the LPPL maintenance status author-maintained.
+
+The Author of this Work is Jean-François Burnol.
+
+This Work consists of the package files polexpr.sty, polexprcore.tex,
+polexprexpr.tex, polexprsturm.tex, this README.md and polexpr.html.
diff --git a/macros/generic/polexpr/polexpr.html b/macros/generic/polexpr/polexpr.html
new file mode 100644
index 0000000000..81cd2b4b7c
--- /dev/null
+++ b/macros/generic/polexpr/polexpr.html
@@ -0,0 +1,4086 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta charset="utf-8"/>
+<meta name="generator" content="Docutils 0.16: http://docutils.sourceforge.net/" />
+<title>Package polexpr documentation</title>
+<style type="text/css">
+
+/* Minimal style sheet for the HTML output of Docutils. */
+/* */
+/* :Author: Günter Milde, based on html4css1.css by David Goodger */
+/* :Id: $Id: minimal.css 8397 2019-09-20 11:09:34Z milde $ */
+/* :Copyright: © 2015 Günter Milde. */
+/* :License: Released under the terms of the `2-Clause BSD license`_, */
+/* in short: */
+/* */
+/* Copying and distribution of this file, with or without modification, */
+/* are permitted in any medium without royalty provided the copyright */
+/* notice and this notice are preserved. */
+/* */
+/* This file is offered as-is, without any warranty. */
+/* */
+/* .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause */
+
+/* This CSS2.1_ stylesheet defines rules for Docutils elements without */
+/* HTML equivalent. It is required to make the document semantic visible. */
+/* */
+/* .. _CSS2.1: http://www.w3.org/TR/CSS2 */
+/* .. _validates: http://jigsaw.w3.org/css-validator/validator$link */
+
+/* alignment of text and inline objects inside block objects*/
+.align-left { text-align: left; }
+.align-right { text-align: right; }
+.align-center { clear: both; text-align: center; }
+.align-top { vertical-align: top; }
+.align-middle { vertical-align: middle; }
+.align-bottom { vertical-align: bottom; }
+
+/* titles */
+h1.title, p.subtitle {
+ text-align: center;
+}
+p.topic-title,
+p.sidebar-title,
+p.rubric,
+p.admonition-title,
+p.system-message-title {
+ font-weight: bold;
+}
+h1 + p.subtitle,
+h1 + p.section-subtitle {
+ font-size: 1.6em;
+}
+h2 + p.section-subtitle { font-size: 1.28em; }
+p.subtitle,
+p.section-subtitle,
+p.sidebar-subtitle {
+ font-weight: bold;
+ margin-top: -0.5em;
+}
+p.sidebar-title,
+p.rubric {
+ font-size: larger;
+}
+p.rubric { color: maroon; }
+a.toc-backref {
+ color: black;
+ text-decoration: none; }
+
+/* Warnings, Errors */
+div.caution p.admonition-title,
+div.attention p.admonition-title,
+div.danger p.admonition-title,
+div.error p.admonition-title,
+div.warning p.admonition-title,
+div.system-messages h1,
+div.error,
+span.problematic,
+p.system-message-title {
+ color: red;
+}
+
+/* inline literals */
+span.docutils.literal {
+ font-family: monospace;
+ white-space: pre-wrap;
+}
+/* do not wraph at hyphens and similar: */
+.literal > span.pre { white-space: nowrap; }
+
+/* Lists */
+
+/* compact and simple lists: no margin between items */
+.simple li, .compact li,
+.simple ul, .compact ul,
+.simple ol, .compact ol,
+.simple > li p, .compact > li p,
+dl.simple > dd, dl.compact > dd {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+/* Table of Contents */
+div.topic.contents { margin: 0.5em 0; }
+div.topic.contents ul {
+ list-style-type: none;
+ padding-left: 1.5em;
+}
+
+/* Enumerated Lists */
+ol.arabic { list-style: decimal }
+ol.loweralpha { list-style: lower-alpha }
+ol.upperalpha { list-style: upper-alpha }
+ol.lowerroman { list-style: lower-roman }
+ol.upperroman { list-style: upper-roman }
+
+dt span.classifier { font-style: italic }
+dt span.classifier:before {
+ font-style: normal;
+ margin: 0.5em;
+ content: ":";
+}
+
+/* Field Lists and drivatives */
+/* bold field name, content starts on the same line */
+dl.field-list > dt,
+dl.option-list > dt,
+dl.docinfo > dt,
+dl.footnote > dt,
+dl.citation > dt {
+ font-weight: bold;
+ clear: left;
+ float: left;
+ margin: 0;
+ padding: 0;
+ padding-right: 0.5em;
+}
+/* Offset for field content (corresponds to the --field-name-limit option) */
+dl.field-list > dd,
+dl.option-list > dd,
+dl.docinfo > dd {
+ margin-left: 9em; /* ca. 14 chars in the test examples */
+}
+/* start field-body on a new line after long field names */
+dl.field-list > dd > *:first-child,
+dl.option-list > dd > *:first-child
+{
+ display: inline-block;
+ width: 100%;
+ margin: 0;
+}
+/* field names followed by a colon */
+dl.field-list > dt:after,
+dl.docinfo > dt:after {
+ content: ":";
+}
+
+/* Bibliographic Fields (docinfo) */
+pre.address { font: inherit; }
+dd.authors > p { margin: 0; }
+
+/* Option Lists */
+dl.option-list { margin-left: 1.5em; }
+dl.option-list > dt { font-weight: normal; }
+span.option { white-space: nowrap; }
+
+/* Footnotes and Citations */
+dl.footnote.superscript > dd {margin-left: 1em; }
+dl.footnote.brackets > dd {margin-left: 2em; }
+dl > dt.label { font-weight: normal; }
+a.footnote-reference.brackets:before,
+dt.label > span.brackets:before { content: "["; }
+a.footnote-reference.brackets:after,
+dt.label > span.brackets:after { content: "]"; }
+a.footnote-reference.superscript,
+dl.footnote.superscript > dt.label {
+ vertical-align: super;
+ font-size: smaller;
+}
+dt.label > span.fn-backref { margin-left: 0.2em; }
+dt.label > span.fn-backref > a { font-style: italic; }
+
+/* Line Blocks */
+div.line-block { display: block; }
+div.line-block div.line-block {
+ margin-top: 0;
+ margin-bottom: 0;
+ margin-left: 40px;
+}
+
+/* Figures, Images, and Tables */
+.figure.align-left,
+figure.align-left,
+img.align-left,
+object.align-left,
+table.align-left {
+ margin-right: auto;
+}
+.figure.align-center,
+figure.align-center,
+img.align-center,
+object.align-center,
+table.align-center {
+ margin-left: auto;
+ margin-right: auto;
+}
+.figure.align-right,
+figure.align-right,
+img.align-right,
+object.align-right,
+table.align-right {
+ margin-left: auto;
+}
+.figure.align-center, .figure.align-right,
+figure.align-center, figure.align-right,
+img.align-center, img.align-right,
+object.align-center, object.align-right {
+ display: block;
+}
+/* reset inner alignment in figures and tables */
+.figure.align-left, .figure.align-right,
+figure.align-left, figure.align-right,
+table.align-left, table.align-center, table.align-right {
+ text-align: inherit;
+}
+
+/* Admonitions and System Messages */
+div.admonition,
+div.system-message,
+div.sidebar,
+aside.sidebar {
+ margin: 1em 1.5em;
+ border: medium outset;
+ padding-top: 0.5em;
+ padding-bottom: 0.5em;
+ padding-right: 1em;
+ padding-left: 1em;
+}
+
+/* Sidebar */
+div.sidebar,
+aside.sidebar {
+ width: 30%;
+ max-width: 26em;
+ float: right;
+ clear: right;
+}
+
+/* Text Blocks */
+blockquote,
+div.topic,
+pre.literal-block,
+pre.doctest-block,
+pre.math,
+pre.code {
+ margin-left: 1.5em;
+ margin-right: 1.5em;
+}
+pre.code .ln { color: gray; } /* line numbers */
+
+/* Tables */
+table { border-collapse: collapse; }
+td, th {
+ border-style: solid;
+ border-color: silver;
+ padding: 0 1ex;
+ border-width: thin;
+}
+td > p:first-child, th > p:first-child { margin-top: 0; }
+td > p, th > p { margin-bottom: 0; }
+
+table > caption {
+ text-align: left;
+ margin-bottom: 0.25em
+}
+
+table.borderless td, table.borderless th {
+ border: 0;
+ padding: 0;
+ padding-right: 0.5em /* separate table cells */
+}
+
+/* Document Header and Footer */
+/* div.header, */
+/* header { border-bottom: 1px solid black; } */
+/* div.footer, */
+/* footer { border-top: 1px solid black; } */
+
+/* new HTML5 block elements: set display for older browsers */
+header, section, footer, aside, nav, main, article, figure {
+ display: block;
+}
+
+</style>
+<style type="text/css">
+
+/* CSS31_ style sheet for the output of Docutils HTML writers. */
+/* Rules for easy reading and pre-defined style variants. */
+/* */
+/* :Author: Günter Milde, based on html4css1.css by David Goodger */
+/* :Id: $Id: plain.css 8397 2019-09-20 11:09:34Z milde $ */
+/* :Copyright: © 2015 Günter Milde. */
+/* :License: Released under the terms of the `2-Clause BSD license`_, */
+/* in short: */
+/* */
+/* Copying and distribution of this file, with or without modification, */
+/* are permitted in any medium without royalty provided the copyright */
+/* notice and this notice are preserved. */
+/* */
+/* This file is offered as-is, without any warranty. */
+/* */
+/* .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause */
+/* .. _CSS3: http://www.w3.org/TR/CSS3 */
+
+
+/* Document Structure */
+/* ****************** */
+
+/* "page layout" */
+body {
+ margin: 0;
+ background-color: #dbdbdb;
+}
+div.document,
+main {
+ line-height:1.3;
+ counter-reset: table;
+ /* counter-reset: figure; */
+ /* avoid long lines --> better reading */
+ /* OTOH: lines should not be too short because of missing hyphenation, */
+ max-width: 50em;
+ padding: 1px 2%; /* 1px on top avoids grey bar above title (mozilla) */
+ margin: auto;
+ background-color: white;
+}
+
+/* Sections */
+
+/* Transitions */
+
+hr.docutils {
+ width: 80%;
+ margin-top: 1em;
+ margin-bottom: 1em;
+ clear: both;
+}
+
+/* Paragraphs */
+/* ========== */
+
+/* vertical space (parskip) */
+p, ol, ul, dl,
+div.line-block,
+div.topic,
+table {
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
+}
+p:first-child { margin-top: 0; }
+/* (:last-child is new in CSS 3) */
+p:last-child { margin-bottom: 0; }
+
+h1, h2, h3, h4, h5, h6,
+dl > dd {
+ margin-bottom: 0.5em;
+}
+
+/* Lists */
+/* ===== */
+
+/* Definition Lists */
+
+/* lists nested in definition lists */
+/* (:only-child is new in CSS 3) */
+dd > ul:only-child, dd > ol:only-child { padding-left: 1em; }
+
+/* Description Lists */
+/* styled like in most dictionaries, encyclopedias etc. */
+dl.description > dt {
+ font-weight: bold;
+ clear: left;
+ float: left;
+ margin: 0;
+ padding: 0;
+ padding-right: 0.5em;
+}
+
+/* Field Lists */
+
+/* example for custom field-name width */
+dl.field-list.narrow > dd {
+ margin-left: 5em;
+}
+/* run-in: start field-body on same line after long field names */
+dl.field-list.run-in > dd p {
+ display: block;
+}
+
+/* Bibliographic Fields */
+
+/* generally, bibliographic fields use special definition list dl.docinfo */
+/* but dedication and abstract are placed into "topic" divs */
+div.abstract p.topic-title {
+ text-align: center;
+}
+div.dedication {
+ margin: 2em 5em;
+ text-align: center;
+ font-style: italic;
+}
+div.dedication p.topic-title {
+ font-style: normal;
+}
+
+/* Citations */
+dl.citation dt.label {
+ font-weight: bold;
+}
+span.fn-backref {
+ font-weight: normal;
+}
+
+/* Text Blocks */
+/* =========== */
+
+/* Literal Blocks */
+
+pre.literal-block,
+pre.doctest-block,
+pre.math,
+pre.code {
+ font-family: monospace;
+}
+
+/* Block Quotes */
+
+blockquote > table,
+div.topic > table {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+blockquote p.attribution,
+div.topic p.attribution {
+ text-align: right;
+ margin-left: 20%;
+}
+
+/* Tables */
+/* ====== */
+
+/* th { vertical-align: bottom; } */
+
+table tr { text-align: left; }
+
+/* "booktabs" style (no vertical lines) */
+table.booktabs {
+ border: 0;
+ border-top: 2px solid;
+ border-bottom: 2px solid;
+ border-collapse: collapse;
+}
+table.booktabs * {
+ border: 0;
+}
+table.booktabs th {
+ border-bottom: thin solid;
+}
+
+/* numbered tables (counter defined in div.document) */
+table.numbered > caption:before {
+ counter-increment: table;
+ content: "Table " counter(table) ": ";
+ font-weight: bold;
+}
+
+/* Explicit Markup Blocks */
+/* ====================== */
+
+/* Footnotes and Citations */
+/* ----------------------- */
+
+/* line on the left */
+dl.footnote {
+ padding-left: 1ex;
+ border-left: solid;
+ border-left-width: thin;
+}
+
+/* Directives */
+/* ---------- */
+
+/* Body Elements */
+/* ~~~~~~~~~~~~~ */
+
+/* Images and Figures */
+
+/* let content flow to the side of aligned images and figures */
+.figure.align-left,
+figure.align-left,
+img.align-left,
+object.align-left {
+ display: block;
+ clear: left;
+ float: left;
+ margin-right: 1em;
+}
+.figure.align-right,
+figure.align-right,
+img.align-right,
+object.align-right {
+ display: block;
+ clear: right;
+ float: right;
+ margin-left: 1em;
+}
+/* Stop floating sidebars, images and figures at section level 1,2,3 */
+h1, h2, h3 { clear: both; }
+
+/* Sidebar */
+
+/* Move right. In a layout with fixed margins, */
+/* it can be moved into the margin. */
+div.sidebar,
+aside.sidebar {
+ width: 30%;
+ max-width: 26em;
+ margin-left: 1em;
+ margin-right: -2%;
+ background-color: #ffffee;
+}
+
+/* Code */
+
+pre.code { padding: 0.7ex }
+pre.code, code { background-color: #eeeeee }
+pre.code .ln { color: gray; } /* line numbers */
+/* basic highlighting: for a complete scheme, see */
+/* http://docutils.sourceforge.net/sandbox/stylesheets/ */
+pre.code .comment, code .comment { color: #5C6576 }
+pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
+pre.code .literal.string, code .literal.string { color: #0C5404 }
+pre.code .name.builtin, code .name.builtin { color: #352B84 }
+pre.code .deleted, code .deleted { background-color: #DEB0A1}
+pre.code .inserted, code .inserted { background-color: #A3D289}
+
+/* Math */
+/* styled separately (see math.css for math-output=HTML) */
+
+/* Epigraph */
+/* Highlights */
+/* Pull-Quote */
+/* Compound Paragraph */
+/* Container */
+
+/* can be styled in a custom stylesheet */
+
+/* Document Header and Footer */
+
+footer, header,
+div.footer, div.header {
+ font-size: smaller;
+ clear: both;
+ padding: 0.5em 2%;
+ background-color: #ebebee;
+ border: none;
+}
+
+/* Inline Markup */
+/* ============= */
+
+/* Emphasis */
+/* em */
+/* Strong Emphasis */
+/* strong */
+/* Interpreted Text */
+/* span.interpreted */
+/* Title Reference */
+/* cite */
+
+/* Inline Literals */
+/* possible values: normal, nowrap, pre, pre-wrap, pre-line */
+/* span.docutils.literal { white-space: pre-wrap; } */
+
+/* Hyperlink References */
+a { text-decoration: none; }
+
+/* External Targets */
+/* span.target.external */
+/* Internal Targets */
+/* span.target.internal */
+/* Footnote References */
+/* a.footnote-reference */
+/* Citation References */
+/* a.citation-reference */
+
+</style>
+</head>
+<body>
+<div class="document" id="package-polexpr-documentation">
+<h1 class="title">Package polexpr documentation</h1>
+<p class="subtitle" id="id1">0.8 (2021/03/29)</p>
+
+<div class="contents topic" id="contents">
+<p class="topic-title">Contents</p>
+<ul class="simple">
+<li><p><a class="reference internal" href="#usage" id="id41">Usage</a></p></li>
+<li><p><a class="reference internal" href="#abstract" id="id42">Abstract</a></p></li>
+<li><p><a class="reference internal" href="#prerequisites" id="id43">Prerequisites</a></p></li>
+<li><p><a class="reference internal" href="#quick-syntax-overview" id="id44">Quick syntax overview</a></p></li>
+<li><p><a class="reference internal" href="#the-polexpr-0-8-extensions-to-the-xintexpr-syntax" id="id45">The polexpr <span class="docutils literal">0.8</span> extensions to the <span class="docutils literal">\xintexpr</span> syntax</a></p>
+<ul>
+<li><p><a class="reference internal" href="#warning-about-unstability-of-the-new-syntax" id="id46">Warning about unstability of the new syntax</a></p></li>
+<li><p><a class="reference internal" href="#infix-operators" id="id47">Infix operators <span class="docutils literal">+, <span class="pre">-,</span> *, /, **, ^</span></a></p></li>
+<li><p><a class="reference internal" href="#experimental-infix-operators" id="id48">Experimental infix operators <span class="docutils literal">//, /:</span></a></p></li>
+<li><p><a class="reference internal" href="#comparison-operators" id="id49">Comparison operators <span class="docutils literal">&lt;, &gt;, &lt;=, &gt;=, ==, !=</span></a></p></li>
+<li><p><a class="reference internal" href="#pol-nutple-expression" id="id50"><span class="docutils literal"><span class="pre">pol(&lt;nutple</span> expression&gt;)</span></a></p></li>
+<li><p><a class="reference internal" href="#xinteval-pol-expr" id="id51"><span class="docutils literal"><span class="pre">\xinteval{&lt;pol.</span> <span class="pre">expr.&gt;}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#evalp-pol-expr-pol-expr" id="id52"><span class="docutils literal"><span class="pre">evalp(&lt;pol.</span> <span class="pre">expr.&gt;,</span> &lt;pol. expr&gt;)</span></a></p></li>
+<li><p><a class="reference internal" href="#deg-pol-expr" id="id53"><span class="docutils literal"><span class="pre">deg(&lt;pol.</span> <span class="pre">expr.&gt;)</span></span></a></p></li>
+<li><p><a class="reference internal" href="#coeffs-pol-expr" id="id54"><span class="docutils literal"><span class="pre">coeffs(&lt;pol.</span> <span class="pre">expr.&gt;)</span></span></a></p></li>
+<li><p><a class="reference internal" href="#coeff-pol-expr-num-expr" id="id55"><span class="docutils literal"><span class="pre">coeff(&lt;pol.</span> <span class="pre">expr.&gt;,</span> &lt;num. <span class="pre">expr.&gt;)</span></span></a></p></li>
+<li><p><a class="reference internal" href="#lcoeff-pol-expr" id="id56"><span class="docutils literal"><span class="pre">lcoeff(&lt;pol.</span> <span class="pre">expr.&gt;)</span></span></a></p></li>
+<li><p><a class="reference internal" href="#monicpart-pol-expr" id="id57"><span class="docutils literal"><span class="pre">monicpart(&lt;pol.</span> <span class="pre">expr.&gt;)</span></span></a></p></li>
+<li><p><a class="reference internal" href="#icontent-pol-expr" id="id58"><span class="docutils literal"><span class="pre">icontent(&lt;pol.</span> <span class="pre">expr.&gt;)</span></span></a></p></li>
+<li><p><a class="reference internal" href="#primpart-pol-expr" id="id59"><span class="docutils literal"><span class="pre">primpart(&lt;pol.</span> <span class="pre">expr.&gt;)</span></span></a></p></li>
+<li><p><a class="reference internal" href="#quorem-pol-expr-pol-expr" id="id60"><span class="docutils literal"><span class="pre">quorem(&lt;pol.</span> <span class="pre">expr.&gt;,</span> &lt;pol. <span class="pre">expr.&gt;)</span></span></a></p></li>
+<li><p><a class="reference internal" href="#quo-pol-expr-pol-expr" id="id61"><span class="docutils literal"><span class="pre">quo(&lt;pol.</span> <span class="pre">expr.&gt;,</span> &lt;pol. <span class="pre">expr.&gt;)</span></span></a></p></li>
+<li><p><a class="reference internal" href="#rem-pol-expr-pol-expr" id="id62"><span class="docutils literal"><span class="pre">rem(&lt;pol.</span> <span class="pre">expr.&gt;,</span> &lt;pol. <span class="pre">expr.&gt;)</span></span></a></p></li>
+<li><p><a class="reference internal" href="#prem-pol-expr-1-pol-expr-2" id="id63"><span class="docutils literal"><span class="pre">prem(&lt;pol.</span> expr. 1&gt;, &lt;pol. expr. 2&gt;)</span></a></p></li>
+<li><p><a class="reference internal" href="#divmod-pol-expr-1-pol-expr-2" id="id64"><span class="docutils literal"><span class="pre">divmod(&lt;pol.</span> expr. 1&gt;, &lt;pol. expr. 2&gt;)</span></a></p></li>
+<li><p><a class="reference internal" href="#mod-pol-expr-1-pol-expr-2" id="id65"><span class="docutils literal"><span class="pre">mod(&lt;pol.</span> expr. 1&gt;, &lt;pol. expr. 2&gt;)</span></a></p></li>
+<li><p><a class="reference internal" href="#polgcd-pol-expr-1-pol-expr-2" id="id66"><span class="docutils literal"><span class="pre">polgcd(&lt;pol.</span> expr. 1&gt;, &lt;pol. expr. 2&gt;, <span class="pre">...)</span></span></a></p></li>
+<li><p><a class="reference internal" href="#resultant-pol-expr-1-pol-expr-2" id="id67"><span class="docutils literal"><span class="pre">resultant(&lt;pol.</span> expr. 1&gt;, &lt;pol. expr. 2&gt;)</span></a></p></li>
+<li><p><a class="reference internal" href="#disc-pol-expr" id="id68"><span class="docutils literal"><span class="pre">disc(&lt;pol.</span> <span class="pre">expr.&gt;)</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polpowmod-pol-expr-1-num-expr-pol-expr-2" id="id69"><span class="docutils literal"><span class="pre">polpowmod(&lt;pol.</span> expr. 1&gt;, &lt;num. <span class="pre">expr.&gt;,</span> &lt;pol. expr. 2&gt;)</span></a></p></li>
+<li><p><a class="reference internal" href="#rdcoeffs-pol-expr" id="id70"><span class="docutils literal"><span class="pre">rdcoeffs(&lt;pol.</span> <span class="pre">expr.&gt;)</span></span></a></p></li>
+<li><p><a class="reference internal" href="#rdzcoeffs-pol-expr" id="id71"><span class="docutils literal"><span class="pre">rdzcoeffs(&lt;pol.</span> <span class="pre">expr.&gt;)</span></span></a></p></li>
+<li><p><a class="reference internal" href="#diff1-pol-expr" id="id72"><span class="docutils literal"><span class="pre">diff1(&lt;pol.</span> <span class="pre">expr.&gt;)</span></span></a></p></li>
+<li><p><a class="reference internal" href="#diff2-pol-expr" id="id73"><span class="docutils literal"><span class="pre">diff2(&lt;pol.</span> <span class="pre">expr.&gt;)</span></span></a></p></li>
+<li><p><a class="reference internal" href="#diffn-pol-expr-p-num-expr-n" id="id74"><span class="docutils literal"><span class="pre">diffn(&lt;pol.</span> expr. P&gt;, &lt;num. expr. n&gt;)</span></a></p></li>
+<li><p><a class="reference internal" href="#antider-pol-expr-p" id="id75"><span class="docutils literal"><span class="pre">antider(&lt;pol.</span> expr. P&gt;)</span></a></p></li>
+<li><p><a class="reference internal" href="#intfrom-pol-expr-p-pol-expr-c" id="id76"><span class="docutils literal"><span class="pre">intfrom(&lt;pol.</span> expr. P&gt;, &lt;pol. expr. c&gt;)</span></a></p></li>
+<li><p><a class="reference internal" href="#integral-pol-expr-p-pol-expr-a-pol-expr-b" id="id77"><span class="docutils literal"><span class="pre">integral(&lt;pol.</span> expr. P&gt;, [&lt;pol. expr. a&gt;, &lt;pol. expr. <span class="pre">b&gt;])</span></span></a></p></li>
+</ul>
+</li>
+<li><p><a class="reference internal" href="#examples-of-localization-of-roots" id="id78">Examples of localization of roots</a></p>
+<ul>
+<li><p><a class="reference internal" href="#a-typical-example" id="id79">A typical example</a></p></li>
+<li><p><a class="reference internal" href="#a-degree-four-polynomial-with-nearby-roots" id="id80">A degree four polynomial with nearby roots</a></p></li>
+<li><p><a class="reference internal" href="#the-degree-nine-polynomial-with-0-99-0-999-0-9999-as-triple-roots" id="id81">The degree nine polynomial with 0.99, 0.999, 0.9999 as triple roots</a></p></li>
+<li><p><a class="reference internal" href="#a-degree-five-polynomial-with-three-rational-roots" id="id82">A degree five polynomial with three rational roots</a></p></li>
+<li><p><a class="reference internal" href="#a-mignotte-type-polynomial" id="id83">A Mignotte type polynomial</a></p></li>
+<li><p><a class="reference internal" href="#the-wilkinson-polynomial" id="id84">The Wilkinson polynomial</a></p></li>
+<li><p><a class="reference internal" href="#the-second-wilkinson-polynomial" id="id85">The second Wilkinson polynomial</a></p></li>
+<li><p><a class="reference internal" href="#the-degree-41-polynomial-with-2-1-9-1-8-0-0-1-1-9-2-as-roots" id="id86">The degree 41 polynomial with -2, -1.9, -1.8, ..., 0, 0.1, ..., 1.9, 2 as roots</a></p></li>
+<li><p><a class="reference internal" href="#roots-of-chebyshev-polynomials" id="id87">Roots of Chebyshev polynomials</a></p></li>
+</ul>
+</li>
+<li><p><a class="reference internal" href="#non-expandable-macros" id="id88">Non-expandable macros</a></p>
+<ul>
+<li><p><a class="reference internal" href="#poldef-polname-letter-expression-using-the-letter-as-indeterminate" id="id89"><span class="docutils literal">\poldef <span class="pre">polname(letter):=</span> expression using the letter as indeterminate;</span></a></p></li>
+<li><p><a class="reference internal" href="#poldef-letter-polname-expression-using-the-letter-as-indeterminate" id="id90"><span class="docutils literal"><span class="pre">\PolDef[letter]{polname}{expression</span> using the letter as indeterminate}</span></a></p></li>
+<li><p><a class="reference internal" href="#polgenfloatvariant-polname" id="id91"><span class="docutils literal">\PolGenFloatVariant{polname}</span></a></p></li>
+<li><p><a class="reference internal" href="#pollet-polname-2-polname-1" id="id92"><span class="docutils literal"><span class="pre">\PolLet{polname_2}={polname_1}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polgloballet-polname-2-polname-1" id="id93"><span class="docutils literal"><span class="pre">\PolGlobalLet{polname_2}={polname_1}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polassign-polname-toarray-macro" id="id94"><span class="docutils literal"><span class="pre">\PolAssign{polname}\toarray\macro</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polget-polname-fromarray-macro" id="id95"><span class="docutils literal"><span class="pre">\PolGet{polname}\fromarray\macro</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polfromcsv-polname-csv" id="id96"><span class="docutils literal"><span class="pre">\PolFromCSV{polname}{&lt;csv&gt;}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#poltypeset-pol-expr" id="id97"><span class="docutils literal"><span class="pre">\PolTypeset{&lt;pol.</span> <span class="pre">expr.&gt;}</span></span></a></p>
+<ul>
+<li><p><a class="reference internal" href="#poltypesetcmd-raw-coeff" id="id98"><span class="docutils literal">\PolTypesetCmd{raw_coeff}</span></a></p></li>
+<li><p><a class="reference internal" href="#poltypesetone-raw-coeff" id="id99"><span class="docutils literal">\PolTypesetOne{raw_coeff}</span></a></p></li>
+<li><p><a class="reference internal" href="#id9" id="id100"><span class="docutils literal">\PolTypesetMonomialCmd</span></a></p></li>
+<li><p><a class="reference internal" href="#poltypesetcmdprefix-raw-coeff" id="id101"><span class="docutils literal">\PolTypesetCmdPrefix{raw_coeff}</span></a></p></li>
+</ul>
+</li>
+<li><p><a class="reference internal" href="#id11" id="id102"><span class="docutils literal"><span class="pre">\PolTypeset*{&lt;pol.</span> <span class="pre">expr.&gt;}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#poldiff-polname-1-polname-2" id="id103"><span class="docutils literal"><span class="pre">\PolDiff{polname_1}{polname_2}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#poldiff-n-polname-1-polname-2" id="id104"><span class="docutils literal"><span class="pre">\PolDiff[N]{polname_1}{polname_2}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polantidiff-polname-1-polname-2" id="id105"><span class="docutils literal"><span class="pre">\PolAntiDiff{polname_1}{polname_2}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polantidiff-n-polname-1-polname-2" id="id106"><span class="docutils literal"><span class="pre">\PolAntiDiff[N]{polname_1}{polname_2}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#poldivide-polname-1-polname-2-polname-q-polname-r" id="id107"><span class="docutils literal"><span class="pre">\PolDivide{polname_1}{polname_2}{polname_Q}{polname_R}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polquo-polname-1-polname-2-polname-q" id="id108"><span class="docutils literal"><span class="pre">\PolQuo{polname_1}{polname_2}{polname_Q}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polrem-polname-1-polname-2-polname-r" id="id109"><span class="docutils literal"><span class="pre">\PolRem{polname_1}{polname_2}{polname_R}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polgcd-polname-1-polname-2-polname-gcd" id="id110"><span class="docutils literal"><span class="pre">\PolGCD{polname_1}{polname_2}{polname_GCD}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#non-expandable-macros-related-to-the-root-localization-routines" id="id111">Non-expandable macros related to the root localization routines</a></p>
+<ul>
+<li><p><a class="reference internal" href="#poltosturm-polname-sturmname" id="id112"><span class="docutils literal"><span class="pre">\PolToSturm{polname}{sturmname}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#id13" id="id113"><span class="docutils literal"><span class="pre">\PolToSturm*{polname}{sturmname}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polsettosturmchainsignchangesat-macro-sturmname-fraction" id="id114"><span class="docutils literal"><span class="pre">\PolSetToSturmChainSignChangesAt{\macro}{sturmname}{fraction}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polsettonbofzeroswithin-macro-sturmname-value-a-value-b" id="id115"><span class="docutils literal"><span class="pre">\PolSetToNbOfZerosWithin{\macro}{sturmname}{value_a}{value_b}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polsturmisolatezeros-sturmname" id="id116"><span class="docutils literal">\PolSturmIsolateZeros{sturmname}</span></a></p></li>
+<li><p><a class="reference internal" href="#id15" id="id117"><span class="docutils literal"><span class="pre">\PolSturmIsolateZeros*{sturmname}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#id17" id="id118"><span class="docutils literal"><span class="pre">\PolSturmIsolateZeros**{sturmname}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polsturmisolatezerosandgetmultiplicities-sturmname" id="id119"><span class="docutils literal">\PolSturmIsolateZerosAndGetMultiplicities{sturmname}</span></a></p></li>
+<li><p><a class="reference internal" href="#polsturmisolatezerosgetmultiplicitiesandrationalroots-sturmname" id="id120"><span class="docutils literal">\PolSturmIsolateZerosGetMultiplicitiesAndRationalRoots{sturmname}</span></a></p></li>
+<li><p><a class="reference internal" href="#polsturmisolatezerosandfindrationalroots-sturmname" id="id121"><span class="docutils literal">\PolSturmIsolateZerosAndFindRationalRoots{sturmname}</span></a></p></li>
+<li><p><a class="reference internal" href="#polrefineinterval-sturmname-index" id="id122"><span class="docutils literal"><span class="pre">\PolRefineInterval*{sturmname}{index}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polrefineinterval-n-sturmname-index" id="id123"><span class="docutils literal"><span class="pre">\PolRefineInterval[N]{sturmname}{index}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polensureintervallength-sturmname-index-e" id="id124"><span class="docutils literal"><span class="pre">\PolEnsureIntervalLength{sturmname}{index}{E}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polensureintervallengths-sturmname-e" id="id125"><span class="docutils literal"><span class="pre">\PolEnsureIntervalLengths{sturmname}{E}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polprintintervals-varname-sturmname" id="id126"><span class="docutils literal"><span class="pre">\PolPrintIntervals[varname]{sturmname}</span></span></a></p>
+<ul>
+<li><p><a class="reference internal" href="#polprintintervalsnorealroots" id="id127"><span class="docutils literal">\PolPrintIntervalsNoRealRoots</span></a></p></li>
+<li><p><a class="reference internal" href="#polprintintervalsbeginenv" id="id128"><span class="docutils literal">\PolPrintIntervalsBeginEnv</span></a></p></li>
+<li><p><a class="reference internal" href="#polprintintervalsendenv" id="id129"><span class="docutils literal">\PolPrintIntervalsEndEnv</span></a></p></li>
+<li><p><a class="reference internal" href="#polprintintervalsknownroot" id="id130"><span class="docutils literal">\PolPrintIntervalsKnownRoot</span></a></p></li>
+<li><p><a class="reference internal" href="#polprintintervalsunknownroot" id="id131"><span class="docutils literal">\PolPrintIntervalsUnknownRoot</span></a></p></li>
+<li><p><a class="reference internal" href="#id18" id="id132"><span class="docutils literal">\PolPrintIntervalsPrintExactZero</span></a></p></li>
+<li><p><a class="reference internal" href="#id19" id="id133"><span class="docutils literal">\PolPrintIntervalsPrintLeftEndPoint</span></a></p></li>
+<li><p><a class="reference internal" href="#id20" id="id134"><span class="docutils literal">\PolPrintIntervalsPrintRightEndPoint</span></a></p></li>
+</ul>
+</li>
+<li><p><a class="reference internal" href="#id22" id="id135"><span class="docutils literal"><span class="pre">\PolPrintIntervals*[varname]{sturmname}</span></span></a></p>
+<ul>
+<li><p><a class="reference internal" href="#polprintintervalsprintmultiplicity" id="id136"><span class="docutils literal">\PolPrintIntervalsPrintMultiplicity</span></a></p></li>
+</ul>
+</li>
+</ul>
+</li>
+<li><p><a class="reference internal" href="#polmapcoeffs-macro-polname" id="id137"><span class="docutils literal"><span class="pre">\PolMapCoeffs{\macro}{polname}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polreducecoeffs-polname" id="id138"><span class="docutils literal">\PolReduceCoeffs{polname}</span></a></p></li>
+<li><p><a class="reference internal" href="#id24" id="id139"><span class="docutils literal"><span class="pre">\PolReduceCoeffs*{polname}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polmakemonic-polname" id="id140"><span class="docutils literal">\PolMakeMonic{polname}</span></a></p></li>
+<li><p><a class="reference internal" href="#polmakeprimitive-polname" id="id141"><span class="docutils literal">\PolMakePrimitive{polname}</span></a></p></li>
+</ul>
+</li>
+<li><p><a class="reference internal" href="#expandable-macros" id="id142">Expandable macros</a></p>
+<ul>
+<li><p><a class="reference internal" href="#poleval-polname-atexpr-numerical-expression" id="id143"><span class="docutils literal"><span class="pre">\PolEval{polname}\AtExpr{numerical</span> expression}</span></a></p></li>
+<li><p><a class="reference internal" href="#poleval-polname-at-fraction" id="id144"><span class="docutils literal"><span class="pre">\PolEval{polname}\At{fraction}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polevalreduced-polname-atexpr-numerical-expression" id="id145"><span class="docutils literal"><span class="pre">\PolEvalReduced{polname}\AtExpr{numerical</span> expression}</span></a></p></li>
+<li><p><a class="reference internal" href="#polevalreduced-polname-at-fraction" id="id146"><span class="docutils literal"><span class="pre">\PolEvalReduced{polname}\At{fraction}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polfloateval-polname-atexpr-numerical-expression" id="id147"><span class="docutils literal"><span class="pre">\PolFloatEval{polname}\AtExpr{numerical</span> expression}</span></a></p></li>
+<li><p><a class="reference internal" href="#polfloateval-polname-at-fraction" id="id148"><span class="docutils literal"><span class="pre">\PolFloatEval{polname}\At{fraction}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polifcoeffisplusorminusone-a-b" id="id149"><span class="docutils literal"><span class="pre">\PolIfCoeffIsPlusOrMinusOne{A}{B}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polleadingcoeff-polname" id="id150"><span class="docutils literal">\PolLeadingCoeff{polname}</span></a></p></li>
+<li><p><a class="reference internal" href="#polnthcoeff-polname-number" id="id151"><span class="docutils literal"><span class="pre">\PolNthCoeff{polname}{number}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#poldegree-polname" id="id152"><span class="docutils literal">\PolDegree{polname}</span></a></p></li>
+<li><p><a class="reference internal" href="#policontent-polname" id="id153"><span class="docutils literal">\PolIContent{polname}</span></a></p></li>
+<li><p><a class="reference internal" href="#poltoexpr-pol-expr" id="id154"><span class="docutils literal"><span class="pre">\PolToExpr{&lt;pol.</span> <span class="pre">expr.&gt;}</span></span></a></p>
+<ul>
+<li><p><a class="reference internal" href="#id31" id="id155"><span class="docutils literal">\PolToExprVar</span></a></p></li>
+<li><p><a class="reference internal" href="#poltoexprinvar" id="id156"><span class="docutils literal">\PolToExprInVar</span></a></p></li>
+<li><p><a class="reference internal" href="#id32" id="id157"><span class="docutils literal">\PolToExprTimes</span></a></p></li>
+<li><p><a class="reference internal" href="#poltoexprcaret" id="id158"><span class="docutils literal">\PolToExprCaret</span></a></p></li>
+<li><p><a class="reference internal" href="#poltoexprcmd-raw-coeff" id="id159"><span class="docutils literal">\PolToExprCmd{raw_coeff}</span></a></p></li>
+<li><p><a class="reference internal" href="#poltoexproneterm-raw-coeff-number" id="id160"><span class="docutils literal"><span class="pre">\PolToExprOneTerm{raw_coeff}{number}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#poltoexpronetermstylea-raw-coeff-number" id="id161"><span class="docutils literal"><span class="pre">\PolToExprOneTermStyleA{raw_coeff}{number}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#poltoexpronetermstyleb-raw-coeff-number" id="id162"><span class="docutils literal"><span class="pre">\PolToExprOneTermStyleB{raw_coeff}{number}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#poltoexprtermprefix-raw-coeff" id="id163"><span class="docutils literal">\PolToExprTermPrefix{raw_coeff}</span></a></p></li>
+</ul>
+</li>
+<li><p><a class="reference internal" href="#id34" id="id164"><span class="docutils literal"><span class="pre">\PolToExpr*{&lt;pol.</span> <span class="pre">expr.&gt;}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#poltofloatexpr-pol-expr" id="id165"><span class="docutils literal"><span class="pre">\PolToFloatExpr{&lt;pol.</span> <span class="pre">expr.&gt;}</span></span></a></p>
+<ul>
+<li><p><a class="reference internal" href="#poltofloatexproneterm-raw-coeff-number" id="id166"><span class="docutils literal"><span class="pre">\PolToFloatExprOneTerm{raw_coeff}{number}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#poltofloatexprcmd-raw-coeff" id="id167"><span class="docutils literal">\PolToFloatExprCmd{raw_coeff}</span></a></p></li>
+</ul>
+</li>
+<li><p><a class="reference internal" href="#id38" id="id168"><span class="docutils literal"><span class="pre">\PolToFloatExpr*{&lt;pol.</span> <span class="pre">expr.&gt;}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#poltolist-polname" id="id169"><span class="docutils literal">\PolToList{polname}</span></a></p></li>
+<li><p><a class="reference internal" href="#poltocsv-polname" id="id170"><span class="docutils literal">\PolToCSV{polname}</span></a></p></li>
+<li><p><a class="reference internal" href="#expandable-macros-related-to-the-root-localization-routines" id="id171">Expandable macros related to the root localization routines</a></p>
+<ul>
+<li><p><a class="reference internal" href="#polsturmchainlength-sturmname" id="id172"><span class="docutils literal">\PolSturmChainLength{sturmname}</span></a></p></li>
+<li><p><a class="reference internal" href="#polsturmifzeroexactlyknown-sturmname-index-a-b" id="id173"><span class="docutils literal"><span class="pre">\PolSturmIfZeroExactlyKnown{sturmname}{index}{A}{B}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polsturmisolatedzeroleft-sturmname-index" id="id174"><span class="docutils literal"><span class="pre">\PolSturmIsolatedZeroLeft{sturmname}{index}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polsturmisolatedzeroright-sturmname-index" id="id175"><span class="docutils literal"><span class="pre">\PolSturmIsolatedZeroRight{sturmname}{index}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polsturmisolatedzeromultiplicity-sturmname-index" id="id176"><span class="docutils literal"><span class="pre">\PolSturmIsolatedZeroMultiplicity{sturmname}{index}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polsturmnbofisolatedzeros-sturmname" id="id177"><span class="docutils literal">\PolSturmNbOfIsolatedZeros{sturmname}</span></a></p></li>
+<li><p><a class="reference internal" href="#polsturmnbofrootsof-sturmname-lessthanorequalto-value" id="id178"><span class="docutils literal"><span class="pre">\PolSturmNbOfRootsOf{sturmname}\LessThanOrEqualTo{value}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polsturmnbofrootsof-sturmname-lessthanorequaltoexpr-expression" id="id179"><span class="docutils literal"><span class="pre">\PolSturmNbOfRootsOf{sturmname}\LessThanOrEqualToExpr{expression}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polsturmnbwithmultofrootsof-sturmname-lessthanorequalto-value" id="id180"><span class="docutils literal"><span class="pre">\PolSturmNbWithMultOfRootsOf{sturmname}\LessThanOrEqualTo{value}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polsturmnbwithmultofrootsof-sturmname-lessthanorequaltoexpr-expression" id="id181"><span class="docutils literal"><span class="pre">\PolSturmNbWithMultOfRootsOf{sturmname}\LessThanOrEqualToExpr{expression}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polsturmnbofrationalroots-sturmname" id="id182"><span class="docutils literal">\PolSturmNbOfRationalRoots{sturmname}</span></a></p></li>
+<li><p><a class="reference internal" href="#polsturmnbofrationalrootswithmultiplicities-sturmname" id="id183"><span class="docutils literal">\PolSturmNbOfRationalRootsWithMultiplicities{sturmname}</span></a></p></li>
+<li><p><a class="reference internal" href="#polsturmrationalroot-sturmname-k" id="id184"><span class="docutils literal"><span class="pre">\PolSturmRationalRoot{sturmname}{k}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polsturmrationalrootindex-sturmname-k" id="id185"><span class="docutils literal"><span class="pre">\PolSturmRationalRootIndex{sturmname}{k}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polsturmrationalrootmultiplicity-sturmname-k" id="id186"><span class="docutils literal"><span class="pre">\PolSturmRationalRootMultiplicity{sturmname}{k}</span></span></a></p></li>
+<li><p><a class="reference internal" href="#polintervalwidth-sturmname-index" id="id187"><span class="docutils literal"><span class="pre">\PolIntervalWidth{sturmname}{index}</span></span></a></p></li>
+</ul>
+</li>
+<li><p><a class="reference internal" href="#expandable-macros-for-use-within-execution-of-polprintintervals" id="id188">Expandable macros for use within execution of <span class="docutils literal">\PolPrintIntervals</span></a></p>
+<ul>
+<li><p><a class="reference internal" href="#polprintintervalsthevar" id="id189"><span class="docutils literal">\PolPrintIntervalsTheVar</span></a></p></li>
+<li><p><a class="reference internal" href="#polprintintervalstheindex" id="id190"><span class="docutils literal">\PolPrintIntervalsTheIndex</span></a></p></li>
+<li><p><a class="reference internal" href="#polprintintervalsthesturmname" id="id191"><span class="docutils literal">\PolPrintIntervalsTheSturmName</span></a></p></li>
+<li><p><a class="reference internal" href="#polprintintervalstheleftendpoint" id="id192"><span class="docutils literal">\PolPrintIntervalsTheLeftEndPoint</span></a></p></li>
+<li><p><a class="reference internal" href="#polprintintervalstherightendpoint" id="id193"><span class="docutils literal">\PolPrintIntervalsTheRightEndPoint</span></a></p></li>
+<li><p><a class="reference internal" href="#polprintintervalsthemultiplicity" id="id194"><span class="docutils literal">\PolPrintIntervalsTheMultiplicity</span></a></p></li>
+</ul>
+</li>
+</ul>
+</li>
+<li><p><a class="reference internal" href="#booleans-with-default-setting-as-indicated" id="id195">Booleans (with default setting as indicated)</a></p>
+<ul>
+<li><p><a class="reference internal" href="#xintverbosefalse" id="id196"><span class="docutils literal">\xintverbosefalse</span></a></p></li>
+<li><p><a class="reference internal" href="#polnewpolverbosefalse" id="id197"><span class="docutils literal">\polnewpolverbosefalse</span></a></p></li>
+<li><p><a class="reference internal" href="#poltypesetallfalse" id="id198"><span class="docutils literal">\poltypesetallfalse</span></a></p></li>
+<li><p><a class="reference internal" href="#poltoexprallfalse" id="id199"><span class="docutils literal">\poltoexprallfalse</span></a></p></li>
+</ul>
+</li>
+<li><p><a class="reference internal" href="#utilies" id="id200">Utilies</a></p>
+<ul>
+<li><p><a class="reference internal" href="#poldectostring-decimal-number" id="id201"><span class="docutils literal">\PolDecToString{decimal number}</span></a></p></li>
+<li><p><a class="reference internal" href="#polexprsetup" id="id202"><span class="docutils literal">\polexprsetup</span></a></p></li>
+</ul>
+</li>
+<li><p><a class="reference internal" href="#technicalities" id="id203">Technicalities</a></p></li>
+<li><p><a class="reference internal" href="#change-log" id="id204">CHANGE LOG</a></p></li>
+<li><p><a class="reference internal" href="#acknowledgments" id="id205">Acknowledgments</a></p></li>
+</ul>
+</div>
+<div class="section" id="usage">
+<h1><a class="toc-backref" href="#id41">Usage</a></h1>
+<p>The package can be used with TeX based formats incorporating the e-TeX
+primitives. The <span class="docutils literal">\expanded</span> primitive available generally since
+TeXLive 2019 is required.</p>
+<pre class="literal-block">\input polexpr.sty</pre>
+<p>with Plain or other non-LaTeX macro formats, or:</p>
+<pre class="literal-block">\usepackage{polexpr}</pre>
+<p>with the LaTeX macro format.</p>
+<p>The package requires <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> <span class="docutils literal">1.4d</span> or later.</p>
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p>Until <span class="docutils literal">0.8</span> the package only had a LaTeX interface. As a result,
+parts of this documentation may still give examples using LaTeX syntax such
+as <span class="docutils literal">\newcommand</span>. Please convert to the syntax appropriate to the
+TeX macro format used if needed.</p>
+</div>
+</div>
+<div class="section" id="abstract">
+<h1><a class="toc-backref" href="#id42">Abstract</a></h1>
+<p>The package provides a parser <span class="docutils literal">\poldef</span> of algebraic polynomial
+expressions. As it is based on <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a>
+the coefficients are allowed to be arbitrary rational numbers.</p>
+<p>Once defined, a polynomial is usable by its name either as a numerical
+function in <span class="docutils literal"><span class="pre">\xintexpr/\xinteval</span></span>, or for additional polynomial
+definitions, or as argument to the package macros. The localization of
+real roots to arbitrary precision as well as the determination of all
+rational roots is implemented via such macros.</p>
+<p>Since release <span class="docutils literal">0.8</span>, polexpr extends the <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a>
+syntax to recognize
+polynomials as a new variable type (and not only as functions).
+Functionality which previously was implemented via macros such as the
+computation of a greatest common divisor is now available directly in
+<span class="docutils literal">\xintexpr</span>, <span class="docutils literal">\xinteval</span> or <span class="docutils literal">\poldef</span> via infix or functional
+syntax.</p>
+</div>
+<div class="section" id="prerequisites">
+<h1><a class="toc-backref" href="#id43">Prerequisites</a></h1>
+<ul>
+<li><p>The user must have some understanding of TeX as a macro-expansion
+based programming interface, and in particular of how <span class="docutils literal">\edef</span>
+differs from <span class="docutils literal">\def</span>: functionalities of the package as described in
+the <a class="reference internal" href="#expandable-macros">Expandable macros</a> section are suitable for usage in <span class="docutils literal">\edef</span>,
+<span class="docutils literal">\write</span> or <span class="docutils literal">\xinteval</span> context. At <span class="docutils literal">0.8</span> some of these
+macros have an even more convenient functional interface inside
+<span class="docutils literal">\xinteval</span>, as is described in a <a class="reference internal" href="#polexpr08">dedicated section</a>.</p>
+<p>Despite its name <span class="docutils literal">\poldef</span> is more to be seen as an <span class="docutils literal">\edef</span>
+although it does not define a TeX macro (at user level); and of course
+<span class="docutils literal">\edef</span> would do usually nothing on the typical input parsed by
+<span class="docutils literal">\poldef</span> which generally has no backslash in it: but if this input
+does contain macros, they will then be expanded fully and are supposed to
+produce recognizable syntax elements in this expansion only context.</p>
+<p>Note that the <span class="docutils literal">def</span> in <span class="docutils literal">\poldef</span> reminds us that the macro does
+some assignments hence is not usable in expandable only context. Its
+whole point is rather to define entities which, them, can then be used
+in the expandable only <span class="docutils literal">\xinteval</span> (or <span class="docutils literal">\poldef</span>) context.</p>
+</li>
+<li><p>The user must have some familiarity with <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> and in
+particular must know what <span class="docutils literal">\xintexpr</span>, <span class="docutils literal">\xinttheexpr</span>,
+<span class="docutils literal">\xinteval</span> and <span class="docutils literal">\xintfloatexpr</span>, <span class="docutils literal">\xintthefloatexpr</span>,
+<span class="docutils literal">\xintfloateval</span> mean and what are the good practices with them.</p></li>
+<li><p>The user will become quickly aware that exact computations with
+fractions easily lead to very big ones in very few steps; see
+<a class="reference internal" href="#polreducecoeffs-polname">\PolReduceCoeffs{polname}</a> in this context.</p></li>
+<li><p>Finally, it is mandatory to read the entire documentation before
+starting to use the package.</p></li>
+</ul>
+</div>
+<div class="section" id="quick-syntax-overview">
+<h1><a class="toc-backref" href="#id44">Quick syntax overview</a></h1>
+<p>The syntax is:</p>
+<pre class="literal-block">\poldef polname(x):= expression in variable x;</pre>
+<ul>
+<li><p>In place of <span class="docutils literal">x</span> an arbitrary <em>dummy variable</em> is authorized,
+i.e. per default one <span class="docutils literal">a, .., z, A, .., Z</span> (more letters can be declared
+under Unicode engines).</p></li>
+<li><p><span class="docutils literal">polname</span> consists of letters, digits, and the <span class="docutils literal">_</span> and <span class="docutils literal">'</span>
+characters. It <strong>must</strong> start with a letter: do not use the
+underscore <span class="docutils literal">_</span> as <em>first character</em> of a polynomial name (even
+if of catcode letter). No warning is emitted but dire consequences
+will result.</p>
+<div class="admonition hint">
+<p class="admonition-title">Hint</p>
+<p>The <span class="docutils literal">&#64;</span> is usable too, independently of whether it is of catcode
+letter or other. This has always been the case, but was not
+documented by polexpr prior to <span class="docutils literal">0.8</span>, as the author has never
+found the time to provide some official guidelines on how to name
+temporary variables and the <span class="docutils literal">&#64;</span> is used already as such internally
+to package; time has still not yet been found for <span class="docutils literal">0.8</span> to review
+the situation but it seems reasonable to recommend at any rate to
+restrict usage of <span class="docutils literal">&#64;</span> to scratch variables of defined macros and
+to avoid using it to name document variable.</p>
+</div>
+</li>
+<li><p>The colon before the equality sign is optional and its catcode does
+not matter.</p></li>
+<li><p>The semi-colon at the end of the expression is mandatory. Its catcode
+does not matter if <span class="docutils literal">\poldef</span> is not used inside the argument of
+another macro.</p></li>
+</ul>
+<p>There is an alternative syntax</p>
+<pre class="literal-block">\PolDef[optional letter]{polname}{expression in the letter}</pre>
+<p>Its optional first argument defaults to <span class="docutils literal">x</span>.</p>
+<dl>
+<dt><span class="docutils literal">\poldef <span class="pre">f(x):=</span> 1 - x + quo(x^5,1 - x + x^2);</span></dt>
+<dd><p>defines polynomial <span class="docutils literal">f</span>. The indeterminate <span class="docutils literal">x</span> must be
+only submitted to algebraic operations.</p>
+<p>The <span class="docutils literal">quo()</span> function (new at <span class="docutils literal">0.8</span>) computes the euclidean
+division quotient.</p>
+</dd>
+</dl>
+<div class="admonition important">
+<p class="admonition-title">Important</p>
+<p>For backwards compatibility one can currently also use:</p>
+<pre class="literal-block">\poldef f(x):= 1 - x + x^5/(1 - x + x^2);</pre>
+<p>Due to precedence rules the first operand is <span class="docutils literal">x^5</span>, not of course
+<span class="docutils literal"><span class="pre">1-x+x^5</span></span>.</p>
+<p>Note that <span class="docutils literal"><span class="pre">(1-x^2)/(1-x)</span></span> produces <span class="docutils literal">1+x</span>
+but <span class="docutils literal"><span class="pre">(1/(1-x))*(1-x^2)</span></span> produces zero! One also has to be aware
+of some precedence rules, for example:</p>
+<pre class="literal-block">\poldef k(x):= (x-1)(x-2)(x-3)(x-4)/(x^2-5x+4);</pre>
+<p>does compute a degree 2 polynomial because the tacit multiplication
+ties more than the division operator.</p>
+<p>In short, it is safer to use the <span class="docutils literal">quo()</span> function which avoids
+surprises.</p>
+</div>
+<div class="admonition attention" id="warningtacit">
+<p class="admonition-title">Attention!</p>
+<p>Tacit multiplication means that
+<span class="docutils literal">1/2 x^2</span> skips the space and is treated like <span class="docutils literal"><span class="pre">1/(2*x^2)</span></span>.
+But then it gives zero!</p>
+<p>Thus one must use <span class="docutils literal">(1/2)x^2</span> or <span class="docutils literal">1/2*x^2</span> or
+<span class="docutils literal"><span class="pre">(1/2)*x^2</span></span> for disambiguation: <span class="docutils literal">x - 1/2*x^2 + <span class="pre">1/3*x^3...</span></span>. It is
+simpler to move the denominator to the right: <span class="docutils literal">x - x^2/2 + x^3/3 - ...</span>.</p>
+<p>It is worth noting that <span class="docutils literal"><span class="pre">1/2(x-1)(x-2)</span></span> suffers the same issue:
+<a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a>'s tacit multiplication always &quot;ties more&quot;, hence this
+gets interpreted as <span class="docutils literal"><span class="pre">1/(2*(x-1)*(x-2))</span></span> which gives zero by
+polynomial division. Thus, use in such cases one of
+<span class="docutils literal"><span class="pre">(1/2)(x-1)(x-2)</span></span>, <span class="docutils literal"><span class="pre">1/2*(x-1)(x-2)</span></span> or <span class="docutils literal"><span class="pre">(x-1)(x-2)/2</span></span>.</p>
+</div>
+<div class="admonition warning">
+<p class="admonition-title">Warning</p>
+<p>The package does not currently know rational functions, but in order
+to leave open this as a future possibility, the usage of <span class="docutils literal">/</span> to stand
+for the
+euclidean quotient is <strong>deprecated</strong>.</p>
+<p>Please start using rather the <span class="docutils literal">quo()</span> function. It is possible
+that in a future major relase <span class="docutils literal">A/B</span> with <span class="docutils literal">B</span> a non-scalar will
+raise an error. Or, who knows, rational functions will be
+implemented sometime during the next decades, and then <span class="docutils literal">A/B</span> will
+naturally be the rational function.</p>
+</div>
+<div class="admonition important">
+<p class="admonition-title">Important</p>
+<p><span class="docutils literal">\poldef <span class="pre">P(x):=...;</span></span> defines <span class="docutils literal">P</span> both as a <em>function</em>,
+to be used as:</p>
+<pre class="literal-block">P(..numeric or even polynomial expression..)</pre>
+<p>and as a <em>variable</em> which can used inside polynomial expressions or
+as argument to some polynomial specific functions such as <span class="docutils literal">deg()</span>
+or <span class="docutils literal">polgcd()</span> <a class="footnote-reference brackets" href="#id3" id="id2">1</a>.</p>
+<dl class="footnote brackets">
+<dt class="label" id="id3"><span class="brackets"><a class="fn-backref" href="#id2">1</a></span></dt>
+<dd><p>Functional syntax accepts expressions as arguments; but the
+TeX <strong>macros</strong> described in the documentation, even the
+expandable ones, work only (there are a few exceptions to the
+general rule) with arguments being <em>names of declared
+polynomials</em>.</p>
+</dd>
+</dl>
+<p>One needs to have a clear understanding of the difference between
+<span class="docutils literal">P</span> used a function and <span class="docutils literal">P</span> used as a variable: if <span class="docutils literal">P</span> and
+<span class="docutils literal">Q</span> are both declared polynomials then:</p>
+<pre class="literal-block">(P+Q)(3)% &lt;--- attention!</pre>
+<p>is currently evaluated as <span class="docutils literal"><span class="pre">(P+Q)*3</span></span>, because <span class="docutils literal">P+Q</span> is not known
+as a <em>function</em>, but <em>only as a variable of polynomial type</em>.
+Even worse:</p>
+<pre class="literal-block">(P)(3)% &lt;--- attention!</pre>
+<p>will compute <span class="docutils literal">P*3</span>, because one can not in current <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> syntax
+enclose a function name in parentheses: consequently it is the variable
+which is used here. There is a <em>meager possibility</em> that in future
+some internal changes to <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> would let <span class="docutils literal"><span class="pre">(P)(3)</span></span> actually
+compute <span class="docutils literal">P(3)</span> and <span class="docutils literal"><span class="pre">(P+Q)(3)</span></span> compute <span class="docutils literal">P(3) + Q(3)</span>, but note
+that <span class="docutils literal"><span class="pre">(P)(P)</span></span> will then do <span class="docutils literal">P(P)</span> and not <span class="docutils literal">P*P</span>,
+the latter, current interpretation, looking more
+intuitive. Anyway, do not rely too extensively on tacit <span class="docutils literal">*</span> and use
+explicit <span class="docutils literal"><span class="pre">(P+Q)*(1+2)</span></span> if this is what is intended.</p>
+<p>As an alternative to explicit <span class="docutils literal"><span class="pre">P(3)+Q(3)</span></span> there is <span class="docutils literal">evalp(P+Q,3)</span>.</p>
+</div>
+<dl>
+<dt><span class="docutils literal"><span class="pre">\PolLet{g}={f}</span></span></dt>
+<dd><p>saves a copy of <span class="docutils literal">f</span> under name <span class="docutils literal">g</span>. Also usable without <span class="docutils literal">=</span>.</p>
+<p>Has exactly the same effect as <span class="docutils literal">\poldef <span class="pre">g(x):=f;</span></span> or <span class="docutils literal">\poldef <span class="pre">g(w):=f(w);</span></span>.</p>
+</dd>
+<dt><span class="docutils literal">\poldef <span class="pre">f(z):=</span> f^2;</span></dt>
+<dd><p>redefines <span class="docutils literal">f</span> in terms of itself. Prior to <span class="docutils literal">0.8</span> one needed
+the right hand side to be <span class="docutils literal"><span class="pre">f(z)^2</span></span>. Also, now <span class="docutils literal">sqr(f)</span> is
+possible (also <span class="docutils literal">sqr(f(x))</span> but not <span class="docutils literal"><span class="pre">sqr(f)(x)</span></span>).</p>
+</dd>
+</dl>
+<div class="admonition important">
+<p class="admonition-title">Important</p>
+<p>Note that <span class="docutils literal">f^2(z)</span> or <span class="docutils literal"><span class="pre">sqr(f)(z)</span></span> will give a logical but
+perhaps unexpected result: first <span class="docutils literal">f^2</span> is computed, then the
+opening parenthesis is seen which inserts a tacit multiplication
+<span class="docutils literal">*</span>, so in the end it is as if the input had been <span class="docutils literal">f^2 * z</span>.
+Although <span class="docutils literal">f</span> is both a variable and a function, <span class="docutils literal">f^2</span> is
+computed as a polynomial <em>variable</em> and ceases being a function.</p>
+</div>
+<dl>
+<dt><span class="docutils literal">\poldef <span class="pre">f(T):=</span> f(f);</span></dt>
+<dd><p>again modifies <span class="docutils literal">f</span>. Here it is used both as variable and as
+a function. Prior to <span class="docutils literal">0.8</span> it needed to be <span class="docutils literal">f(f(T))</span>.</p>
+</dd>
+<dt><span class="docutils literal">\poldef <span class="pre">k(z):=</span> <span class="pre">f-g(g^2)^2;</span></span></dt>
+<dd><p>if everybody followed, this should now define the zero polynomial...
+And <span class="docutils literal"><span class="pre">f-sqr(g(sqr(g)))</span></span> computes the same thing.</p>
+<p>We can check this in a typeset document like this:</p>
+<pre class="literal-block">\poldef f(x):= 1 - x + quo(x^5,1 - x + x^2);%
+\PolLet{g}={f}%
+\poldef f(z):= f^2;%
+\poldef f(T):= f(f);%
+\poldef k(w):= f-sqr(g(sqr(g)));%
+$$f(x) = \vcenter{\hsize10cm \PolTypeset{f}} $$
+$$g(z) = \PolTypeset{g} $$
+$$k(z) = \PolTypeset{k} $$
+\immediate\write128{f(x)=\PolToExpr{f}}% ah, here we see it also</pre>
+</dd>
+<dt><span class="docutils literal">\poldef <span class="pre">f'(x):=</span> diff1(f);</span></dt>
+<dd><p>(new at <span class="docutils literal">0.8</span>)</p>
+</dd>
+<dt><span class="docutils literal"><span class="pre">\PolDiff{f}{f'}</span></span></dt>
+<dd><p>Both set <span class="docutils literal">f'</span> (or any other chosen name) to the derivative
+of <span class="docutils literal">f</span>.</p>
+</dd>
+</dl>
+<div class="admonition important">
+<p class="admonition-title">Important</p>
+<p>This is not done automatically. If some new definition needs to use
+the derivative of some available polynomial, that derivative
+polynomial must have been previously defined: something such as
+<span class="docutils literal"><span class="pre">f'(3)^2</span></span> will not work without a prior definition of <span class="docutils literal">f'</span>.</p>
+<p>But one can now use <span class="docutils literal">diff1(f)</span> for on-the-spot construction with no
+permanent declaration, so here <span class="docutils literal"><span class="pre">evalp(diff1(f),3)^2</span></span>. And
+<span class="docutils literal"><span class="pre">diff1(f)^2</span></span> is same as <span class="docutils literal"><span class="pre">f'^2</span></span>, assuming here <span class="docutils literal">f'</span> was declared
+to be the derived polynomial.</p>
+<p>Notice that the name <span class="docutils literal">diff1()</span> is experimental and may change. Use
+<span class="docutils literal"><span class="pre">\PolDiff{f}{f'}</span></span> as the stable interface.</p>
+</div>
+<dl>
+<dt><span class="docutils literal">\PolTypeset{P}</span></dt>
+<dd><p>Typesets (switching to math mode if in text mode):</p>
+<pre class="literal-block">\poldef f(x):=(3+x)^5;%
+\PolDiff{f}{f'}\PolDiff{f'}{f''}\PolDiff{f''}{f'''}%
+$$f(z) = \PolTypeset[z]{f} $$
+$$f'(z) = \PolTypeset[z]{f'} $$
+$$f''(z) = \PolTypeset[z]{f''} $$
+$$f'''(z)= \PolTypeset[z]{f'''} $$</pre>
+<p>See <a class="reference internal" href="#poltypeset">the documentation</a> for the configurability
+via macros.</p>
+<p>Since <span class="docutils literal">0.8</span> <a class="reference internal" href="#poltypeset">\PolTypeset</a> accepts directly an
+expression, it does not have to be a pre-declared polynomial name:</p>
+<pre class="literal-block">\PolTypeset{mul(x-i,i=1..5)}</pre>
+</dd>
+<dt><span class="docutils literal">\PolToExpr{P}</span></dt>
+<dd><p>Expandably (contrarily to <a class="reference internal" href="#poltypeset">\PolTypeset</a>)
+produces <span class="docutils literal">c_n*x^n + ... + c_0</span> starting from the leading
+coefficient. The <span class="docutils literal">+</span> signs are omitted if followed by negative
+coefficients.</p>
+<p>This is useful for console or file output. This syntax is Maple and
+PSTricks <span class="docutils literal">\psplot[algebraic]</span> compatible; and also it is
+compatible with <span class="docutils literal">\poldef</span> input syntax, of course. See
+<a class="reference internal" href="#poltoexprcaret">\PolToExprCaret</a> for configuration of the <span class="docutils literal">^</span>, for example to
+use rather <span class="docutils literal">**</span> for Python syntax compliance.</p>
+<p>Changed at <span class="docutils literal">0.8</span>: the <span class="docutils literal">^</span> in output is by default of catcode 12
+so in a draft document one can use <span class="docutils literal">\PolToExpr{P}</span> inside the
+typesetting flow (without requiring math mode, where the <span class="docutils literal">*</span> would
+be funny and <span class="docutils literal">^12</span> would only put the <span class="docutils literal">1</span> as exponent anyhow;
+but arguably in text mode the <span class="docutils literal">+</span> and <span class="docutils literal">-</span> are not satisfactory
+for math, except sometimes in monospace typeface, and anyhow TeX is
+unable to break the expression across lines, barring special help).</p>
+<p>See <a class="reference internal" href="#poltoexpr-pol-expr">\PolToExpr{&lt;pol. expr.&gt;}</a> and related macros for customization.</p>
+<p>Extended at <span class="docutils literal">0.8</span> to accept as argument not only the name of a
+polynomial variable but more generally any polynomial expression.</p>
+</dd>
+</dl>
+</div>
+<div class="section" id="the-polexpr-0-8-extensions-to-the-xintexpr-syntax">
+<span id="polexpr08"></span><h1><a class="toc-backref" href="#id45">The polexpr <span class="docutils literal">0.8</span> extensions to the <span class="docutils literal">\xintexpr</span> syntax</a></h1>
+<p>All the syntax elements described in this section can be used in the
+<span class="docutils literal"><span class="pre">\xintexpr/\xinteval</span></span> context (where polynomials can be obtained from
+the <span class="docutils literal"><span class="pre">pol([])</span></span> constructor, once polexpr is loaded): their usage is
+not limited to only <span class="docutils literal">\poldef</span> context.</p>
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p>If a variable <span class="docutils literal">myPol</span> defined via <span class="docutils literal">\xintdefvar</span> turns out
+to be a polynomial, the difference with those declared via <span class="docutils literal">\poldef</span>
+will be:</p>
+<ol class="arabic">
+<li><p><span class="docutils literal">myPol</span> is not usable as <em>function</em>, but only as a variable.
+Attention that <span class="docutils literal">f(x)</span> if <span class="docutils literal">f</span> is only a variable (even a
+polynomial one) will actually compute <span class="docutils literal">f * x</span>.</p></li>
+<li><p><span class="docutils literal">myPol</span> is not known to the polexpr package, hence for example the
+macros to achieve localization of its roots are unavailable.</p>
+<p>In a parallel universe I perhaps have implemented this expandably
+which means it could then be accessible with syntax such as
+<span class="docutils literal"><span class="pre">rightmostroot(pol([42,1,34,2,-8,1]))</span></span> but...</p>
+</li>
+</ol>
+</div>
+<div class="section" id="warning-about-unstability-of-the-new-syntax">
+<h2><a class="toc-backref" href="#id46">Warning about unstability of the new syntax</a></h2>
+<div class="admonition warning">
+<p class="admonition-title">Warning</p>
+<p>Consider the entirety of this section as <strong>UNSTABLE</strong> and
+<strong>EXPERIMENTAL</strong> (except perhaps regarding <span class="docutils literal">+</span>, <span class="docutils literal">-</span> and <span class="docutils literal">*</span>).</p>
+<p>And this applies even to items not explicitly flagged with one of
+<strong>unstable</strong>, <strong>Unstable</strong>, or <strong>UNSTABLE</strong> which only reflect that
+documentation was written over a period of time exceeding one minute,
+enough for the author mood changes to kick in.</p>
+<p>It is hard to find good names at the start of a life-long extension
+program of functionalities, and perhaps in future it will be
+preferred to rename everything or give to some functions other
+meanings. Such quasi-complete renamings happened already a few times
+during the week devoted to development.</p>
+</div>
+</div>
+<div class="section" id="infix-operators">
+<h2><a class="toc-backref" href="#id47">Infix operators <span class="docutils literal">+, <span class="pre">-,</span> *, /, **, ^</span></a></h2>
+<blockquote>
+<p>As has been explained in the <a class="reference internal" href="#quick-syntax-overview">Quick syntax overview</a> these infix
+operators have been made polynomial aware, not only in the
+<span class="docutils literal">\poldef</span> context, but generally in any <span class="docutils literal"><span class="pre">\xintexpr/\xinteval</span></span>
+context, inclusive of <span class="docutils literal">\xintdeffunc</span>.</p>
+<p>Conversely functions declared via <span class="docutils literal">\xintdeffunc</span> and making use of
+these operators will automatically be able to accept polynomials
+declared from <span class="docutils literal">\poldef</span> as variables.</p>
+<p>Usage of <span class="docutils literal">/</span> for euclidean division of polynomials is <strong>deprecated</strong>.
+Only in case of a scalar denominator is it to be considered stable.
+Please use rather <span class="docutils literal">quo()</span>.</p>
+</blockquote>
+<div class="admonition warning">
+<p class="admonition-title">Warning</p>
+<p>The <span class="docutils literal">pow(x,a)</span> function of <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> for <span class="docutils literal">x^a</span> with fractional
+<span class="docutils literal">a</span> will not (with current <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> <span class="docutils literal">1.4d</span>) accept a polynomial
+as first variable even if the second argument is an integer.</p>
+<p>It is possible (via <span class="docutils literal">\poormanloghack</span>) to instruct <span class="docutils literal">\xintexpr</span> to
+let <span class="docutils literal"><span class="pre">x**a</span></span> or <span class="docutils literal">x^a</span> be as <span class="docutils literal">pow(x,a)</span>. If this is done <span class="docutils literal">**</span>
+(resp. <span class="docutils literal">^</span>) will become unusable with polynomials (i.e. will create
+a low-level TeX error).</p>
+<p>And vice versa if polexpr gets loaded after the <span class="docutils literal">\poormanloghack</span>
+was used, <span class="docutils literal">**</span> and <span class="docutils literal">^</span> in <span class="docutils literal"><span class="pre">\xintexpr/\xinteval</span></span> will again only
+accept integer powers.</p>
+<p>Thus employ <span class="docutils literal">\poormanloghack</span> for at most one of <span class="docutils literal">**</span> or <span class="docutils literal">^</span>
+in order to keep one of them available for polynomials and integer
+powers.</p>
+</div>
+</div>
+<div class="section" id="experimental-infix-operators">
+<h2><a class="toc-backref" href="#id48">Experimental infix operators <span class="docutils literal">//, /:</span></a></h2>
+<blockquote>
+<p>Here is the tentative behaviour of <span class="docutils literal"><span class="pre">A//B</span></span> according to types:</p>
+<ul class="simple">
+<li><p><span class="docutils literal">A</span> non scalar and <span class="docutils literal">B</span> non scalar: euclidean quotient,</p></li>
+<li><p><span class="docutils literal">A</span> scalar and <span class="docutils literal">B</span> scalar: floored division,</p></li>
+<li><p><span class="docutils literal">A</span> scalar and <span class="docutils literal">B</span> non scalar: produces zero,</p></li>
+<li><p><span class="docutils literal">A</span> non scalar and <span class="docutils literal">B</span> scalar: coefficient per
+coefficient floored division.</p></li>
+</ul>
+<p>This is an <strong>experimental</strong> overloading of the <span class="docutils literal">//</span> and <span class="docutils literal">/:</span>
+from <span class="docutils literal">\xintexpr</span>.</p>
+<p>The behaviour in the last case, but not only, is to be considerd
+<strong>unstable</strong>. The alternative would be for <span class="docutils literal"><span class="pre">A//B</span></span> with <span class="docutils literal">B</span>
+scalar to act as <span class="docutils literal">quo(A,B)</span>. But, we have currently chosen to let
+<span class="docutils literal">//B</span> for a scalar <span class="docutils literal">B</span> act coefficient-wise on the numerator.
+Beware that it thus means it can be employed with the idea of doing
+euclidean division only by checking that <span class="docutils literal">B</span> is non-scalar.</p>
+<p>The <span class="docutils literal">/:</span> operator provides the associated remainder so always
+<span class="docutils literal">A</span> is reconstructed from <span class="docutils literal"><span class="pre">(A//B)*B</span> + <span class="pre">A/:B</span></span>.</p>
+<p>If <span class="docutils literal">:</span> is active character use <span class="docutils literal">/\string:</span> (it is safer to use
+<span class="docutils literal">/\string :</span> if it is not known if <span class="docutils literal">:</span> has catcode other, letter,
+or is active, but note that <span class="docutils literal">/:</span> is fine and needs no precaution if
+<span class="docutils literal">:</span> has catcode letter, it is only an active <span class="docutils literal">:</span> which is
+problematic, like for all other characters possibly used in an
+expression).</p>
+<blockquote>
+<p><strong>UNSTABLE</strong></p>
+<p>As explained above, there are (among other things) hesitations
+about behaviour with <span class="docutils literal">pol2</span> a scalar.</p>
+</blockquote>
+</blockquote>
+</div>
+<div class="section" id="comparison-operators">
+<h2><a class="toc-backref" href="#id49">Comparison operators <span class="docutils literal">&lt;, &gt;, &lt;=, &gt;=, ==, !=</span></a></h2>
+<blockquote>
+<p><strong>NOT YET IMPLEMENTED</strong></p>
+<p>As the internal representation by <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> and <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> of
+fractions does not currently require them to be in reduced terms,
+such operations would be a bit costly as they could not benefit from
+the <span class="docutils literal">\pdfstrcmp</span> engine primitive. In fact <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> does not use
+it yet anywhere, even for normalized pure integers, although it could
+speed up signifcantly certain aspects of core arithmetic.</p>
+<p>Equality of polynomials can currently be tested by computing the
+difference, which is a bit costly. And of course the <span class="docutils literal">deg()</span>
+function allows comparing degrees. In this context note the
+following syntax:</p>
+<pre class="literal-block">(deg(Q)) ?? { zero } { non-zero scalar } { non-scalar }</pre>
+<p>for branching.</p>
+</blockquote>
+</div>
+<div class="section" id="pol-nutple-expression">
+<h2><a class="toc-backref" href="#id50"><span class="docutils literal"><span class="pre">pol(&lt;nutple</span> expression&gt;)</span></a></h2>
+<blockquote>
+<p>This converts a nutple <span class="docutils literal"><span class="pre">[c0,c1,...,cN]</span></span> into the polynomial
+variable having these coefficients. Attention that the square
+brackets are <strong>mandatory</strong>, except of course if the argument is
+actually an expression producing such a &quot;nutple&quot;.</p>
+<blockquote>
+<p>Currently, this process will not normalize the coefficients (such
+as reducing to lowest terms), it only trims out the leading zero
+coefficients.</p>
+</blockquote>
+<p>Inside <span class="docutils literal">\xintexpr</span>, this is the only (allowed) way to create ex
+nihilo a polynomial variable; inside <span class="docutils literal">\poldef</span> it is an alternative
+input syntax which is more efficient than typing <span class="docutils literal">c0 + c1 * x + c2 * x^2 + ...</span>.</p>
+</blockquote>
+<div class="admonition important">
+<p class="admonition-title">Important</p>
+<p>Whenever an expression with polynomials collapses to a constant, it
+becomes a scalar. There is currently no distinction during the
+parsing of expressions by <span class="docutils literal">\poldef</span>
+or <span class="docutils literal">\xintexpr</span> between constant polynomial variables and scalar
+variables.</p>
+<p>Naturally, <span class="docutils literal">\poldef</span> can be used to declare a constant polynomial
+<span class="docutils literal">P</span>, then <span class="docutils literal">P</span> can also be used as function having a value
+independent of argument, but as a variable, it is non-distinguishable
+from a scalar (of course functions such as <span class="docutils literal">deg()</span> tacitly
+consider scalars to be constant polynomials).</p>
+<p>Notice that we tend to use the vocable &quot;variable&quot; to refer to
+arbitrary expressions used as function arguments, without implying
+that we are actually referring to pre-declared variables in the sense
+of <span class="docutils literal">\xintdefvar</span>.</p>
+</div>
+</div>
+<div class="section" id="xinteval-pol-expr">
+<h2><a class="toc-backref" href="#id51"><span class="docutils literal"><span class="pre">\xinteval{&lt;pol.</span> <span class="pre">expr.&gt;}</span></span></a></h2>
+<blockquote>
+<p>This is documented here for lack of a better place: it evaluates the
+polynomial expression then outputs the &quot;string&quot; <span class="docutils literal"><span class="pre">pol([c0,</span> c1, <span class="pre">...,</span> cN])</span>
+if the degree <span class="docutils literal">N</span> is at least one (and the usual scalar output else).</p>
+<p>The &quot;pol&quot; word uses letter catcodes, which is actually mandatory for
+this output to be usable as input, but it does not make sense to use
+this inside <span class="docutils literal">\poldef</span> or <span class="docutils literal">\xintexpr</span> at it means basically
+executing <span class="docutils literal"><span class="pre">pol(coeffs(..expression..))</span></span> which is but a convoluted
+way to obtain the same result as <span class="docutils literal"><span class="pre">(..expression..)</span></span> (the
+parentheses delimiting the polynomial expression).</p>
+<p>For example, <span class="docutils literal"><span class="pre">\xinteval{(1+pol([0,1]))^10}</span></span> expands (in two steps)
+to:</p>
+<pre class="literal-block">pol([1, 10, 45, 120, 210, 252, 210, 120, 45, 10, 1])</pre>
+<p>You do need loading polexpr for this, else of course <span class="docutils literal"><span class="pre">pol([])</span></span>
+remains unknown to <span class="docutils literal">\xinteval{}</span> as well as the polynomial algebra !
+This example can also be done as
+<span class="docutils literal"><span class="pre">\xinteval{subs((1+x)^10,x=pol([0,1]))}</span></span>.</p>
+<p>I hesitated using as output the polynomial notation as produced by
+<a class="reference internal" href="#poltoexpr">\PolToExpr{}</a>, but finally opted for this.</p>
+</blockquote>
+</div>
+<div class="section" id="evalp-pol-expr-pol-expr">
+<h2><a class="toc-backref" href="#id52"><span class="docutils literal"><span class="pre">evalp(&lt;pol.</span> <span class="pre">expr.&gt;,</span> &lt;pol. expr&gt;)</span></a></h2>
+<blockquote>
+<p>Evaluates the first argument as a polynomial function of the
+second. Usually the second argument will be scalar, but this is not
+required:</p>
+<pre class="literal-block">\poldef K(x):= evalp(-3x^3-5x+1,-27x^4+5x-2);</pre>
+<p>If the first argument is an already declared polynomial <span class="docutils literal">P</span>, use
+rather the functional form <span class="docutils literal">P()</span> (which can accept a numerical as
+well as polynomial argument) as it is more efficient.</p>
+<p>One can also use <span class="docutils literal">subs()</span> syntax <a class="footnote-reference brackets" href="#id5" id="id4">2</a> (see <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> documentation):</p>
+<pre class="literal-block">\poldef K(x):= subs(-3y^3-5y+1, y = -27x^4+5x-2);</pre>
+<p>but the <span class="docutils literal">evalp()</span> will use a Horner evaluation scheme which is
+usually more efficient.</p>
+<dl class="footnote brackets">
+<dt class="label" id="id5"><span class="brackets"><a class="fn-backref" href="#id4">2</a></span></dt>
+<dd><p>by the way Maple uses the opposite, hence wrong, order
+<span class="docutils literal"><span class="pre">subs(x=...,</span> P)</span> but was written before computer science
+reached the <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> heights. However it makes validating
+Maple results by polexpr sometimes cumbersome, but perhaps
+they will update it at some point.</p>
+</dd>
+</dl>
+<blockquote>
+<p><strong>name unstable</strong></p>
+<p><span class="docutils literal">poleval</span>? <span class="docutils literal">evalpol</span>? <span class="docutils literal">peval</span>? <span class="docutils literal">evalp</span>? <span class="docutils literal">value</span>?
+<span class="docutils literal">eval</span>? <span class="docutils literal">evalat</span>? <span class="docutils literal">eval1at2</span>? <span class="docutils literal">evalat2nd</span>?</p>
+<p>Life is so complicated when one asks questions. Not everybody does,
+though, as is amply demonstrated these days.</p>
+<p><strong>syntax unstable</strong></p>
+<p>I am hesitating about permuting the order of the arguments.</p>
+</blockquote>
+</blockquote>
+</div>
+<div class="section" id="deg-pol-expr">
+<h2><a class="toc-backref" href="#id53"><span class="docutils literal"><span class="pre">deg(&lt;pol.</span> <span class="pre">expr.&gt;)</span></span></a></h2>
+<blockquote>
+<p>Computes the degree.</p>
+</blockquote>
+<div class="admonition important">
+<p class="admonition-title">Important</p>
+<p>As <span class="docutils literal">\xintexpr</span> does not yet support infinities, the degree of
+the zero polynomial is <span class="docutils literal"><span class="pre">-1</span></span>. Beware that this breaks additivity
+of degrees, but <span class="docutils literal"><span class="pre">deg(P)&lt;0</span></span> correctly detects the zero polynomial,
+and <span class="docutils literal"><span class="pre">deg(P)&lt;=0</span></span> detects scalars.</p>
+</div>
+</div>
+<div class="section" id="coeffs-pol-expr">
+<h2><a class="toc-backref" href="#id54"><span class="docutils literal"><span class="pre">coeffs(&lt;pol.</span> <span class="pre">expr.&gt;)</span></span></a></h2>
+<blockquote>
+<p>Produces the nutple <span class="docutils literal"><span class="pre">[c0,c1,...,cN]</span></span> of coefficients. The highest
+degree coefficient is always non zero (except for the zero
+polynomial...).</p>
+<blockquote>
+<p><strong>name unstable</strong></p>
+<p>I am considering in particular using <span class="docutils literal">polcoeffs()</span> to avoid
+having to overload <span class="docutils literal">coeffs()</span> in future when matrix type
+will be added to <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a>.</p>
+</blockquote>
+</blockquote>
+</div>
+<div class="section" id="coeff-pol-expr-num-expr">
+<h2><a class="toc-backref" href="#id55"><span class="docutils literal"><span class="pre">coeff(&lt;pol.</span> <span class="pre">expr.&gt;,</span> &lt;num. <span class="pre">expr.&gt;)</span></span></a></h2>
+<blockquote>
+<p>As expected. Produces zero if <span class="docutils literal">n</span> is negative or higher than the
+degree.</p>
+<blockquote>
+<p><strong>name and syntax unstable</strong></p>
+<p>I am hesitating with <span class="docutils literal">coeff(n,pol)</span> syntax and also perhaps
+using <span class="docutils literal">polcoeff()</span> in order to avoid having to overload
+<span class="docutils literal">coeff()</span> when matrix type will be added to <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a>.</p>
+</blockquote>
+</blockquote>
+</div>
+<div class="section" id="lcoeff-pol-expr">
+<h2><a class="toc-backref" href="#id56"><span class="docutils literal"><span class="pre">lcoeff(&lt;pol.</span> <span class="pre">expr.&gt;)</span></span></a></h2>
+<blockquote>
+<p>The leading coefficient.</p>
+</blockquote>
+</div>
+<div class="section" id="monicpart-pol-expr">
+<h2><a class="toc-backref" href="#id57"><span class="docutils literal"><span class="pre">monicpart(&lt;pol.</span> <span class="pre">expr.&gt;)</span></span></a></h2>
+<blockquote>
+<p>Divides by the leading coefficient, except that <span class="docutils literal"><span class="pre">monicpart(0)==0</span></span>.</p>
+<blockquote>
+<p><strong>unstable</strong></p>
+<p>Currently the coefficients are reduced to lowest terms (contrarily
+to legacy behaviour of <a class="reference internal" href="#polmakemonic">\PolMakeMonic</a>), and
+additionally the <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> <span class="docutils literal">\xintREZ</span> macro is applied which
+extracts powers of ten from numerator or denominator and stores
+them internally separately. This is generally beneficial to
+efficiency of multiplication.</p>
+</blockquote>
+</blockquote>
+</div>
+<div class="section" id="icontent-pol-expr">
+<h2><a class="toc-backref" href="#id58"><span class="docutils literal"><span class="pre">icontent(&lt;pol.</span> <span class="pre">expr.&gt;)</span></span></a></h2>
+<blockquote>
+<p>The gcd of the (possibly fractional) polynomial coefficients. It is
+always produced as an irreducible (non-negative) fraction. According
+to Gauss theorem the content of a product is the product of the
+contents.</p>
+<blockquote>
+<p><strong>name unstable</strong></p>
+<p>Some hesitation with using <span class="docutils literal">content()</span> rather.</p>
+</blockquote>
+</blockquote>
+</div>
+<div class="section" id="primpart-pol-expr">
+<h2><a class="toc-backref" href="#id59"><span class="docutils literal"><span class="pre">primpart(&lt;pol.</span> <span class="pre">expr.&gt;)</span></span></a></h2>
+<blockquote>
+<p>The quotient (except for the zero polynomial) by
+<span class="docutils literal"><span class="pre">icontent(&lt;pol.</span> <span class="pre">expr.&gt;)</span></span>. This is thus a polynomial with
+integer coefficients having <span class="docutils literal">1</span> as greatest common divisor. The
+sign of the leading coefficient is the same as in the original.</p>
+<p>And <span class="docutils literal"><span class="pre">primpart(0)==0</span></span>.</p>
+<p>The trailing zeros of the integer coefficients are extracted
+into a power of ten exponent part, in the internal representation.</p>
+</blockquote>
+</div>
+<div class="section" id="quorem-pol-expr-pol-expr">
+<h2><a class="toc-backref" href="#id60"><span class="docutils literal"><span class="pre">quorem(&lt;pol.</span> <span class="pre">expr.&gt;,</span> &lt;pol. <span class="pre">expr.&gt;)</span></span></a></h2>
+<blockquote>
+<p>Produces a nutple <span class="docutils literal">[Q,R]</span> with <span class="docutils literal">Q</span> the euclidean quotient and
+<span class="docutils literal">R</span> the remainder.</p>
+<blockquote>
+<p><strong>name unstable</strong></p>
+<p><span class="docutils literal">poldiv()</span>?</p>
+</blockquote>
+</blockquote>
+</div>
+<div class="section" id="quo-pol-expr-pol-expr">
+<h2><a class="toc-backref" href="#id61"><span class="docutils literal"><span class="pre">quo(&lt;pol.</span> <span class="pre">expr.&gt;,</span> &lt;pol. <span class="pre">expr.&gt;)</span></span></a></h2>
+<blockquote>
+<p>The euclidean quotient.</p>
+<p>The deprecated <span class="docutils literal">pol1/pol2</span> syntax computes the same polynomial.</p>
+</blockquote>
+</div>
+<div class="section" id="rem-pol-expr-pol-expr">
+<h2><a class="toc-backref" href="#id62"><span class="docutils literal"><span class="pre">rem(&lt;pol.</span> <span class="pre">expr.&gt;,</span> &lt;pol. <span class="pre">expr.&gt;)</span></span></a></h2>
+<blockquote>
+<p>The euclidean remainder. If <span class="docutils literal">pol2</span> is a (non-zero) scalar, this is
+zero.</p>
+<p>There is no infix operator associated to this, for lack of evident
+notation. Please advise.</p>
+<p><span class="docutils literal">/:</span> can be used if one is certain that <span class="docutils literal">pol2</span> is of
+degree at least one. But read the warning about it being unstable
+even in that case.</p>
+</blockquote>
+</div>
+<div class="section" id="prem-pol-expr-1-pol-expr-2">
+<span id="prem"></span><h2><a class="toc-backref" href="#id63"><span class="docutils literal"><span class="pre">prem(&lt;pol.</span> expr. 1&gt;, &lt;pol. expr. 2&gt;)</span></a></h2>
+<blockquote>
+<p>Produces a nutple <span class="docutils literal">[m, spR]</span> where <span class="docutils literal">spR</span> is the (special) pseudo
+Euclidean remainder. Its description is:</p>
+<ul>
+<li><p>the standard euclidean remainder <span class="docutils literal">R</span> is <span class="docutils literal">spR/m</span></p></li>
+<li><p><span class="docutils literal">m = b^f</span> with <span class="docutils literal">b</span> equal to the <strong>absolute value</strong> of the
+leading coefficient of <span class="docutils literal">pol2</span>,</p></li>
+<li><p><span class="docutils literal">f</span> is the number of non-zero coefficients in the euclidean
+quotient, if <span class="docutils literal"><span class="pre">deg(pol2)&gt;0</span></span> (even if the remainder vanishes).</p>
+<p>If <span class="docutils literal">pol2</span> is a scalar however, the function outputs <span class="docutils literal">[1,0]</span>.</p>
+</li>
+</ul>
+<p>With these definitions one can show that if both <span class="docutils literal">pol1</span> and
+<span class="docutils literal">pol2</span> have integer coefficients, then this is also the case of
+<span class="docutils literal">spR</span>, which makes its interest (and also <span class="docutils literal">m*Q</span> has integer
+coefficients, with <span class="docutils literal">Q</span> the euclidean quotient, if <span class="docutils literal"><span class="pre">deg(pol2)&gt;0</span></span>).
+Also, <span class="docutils literal">prem()</span> is computed faster than <span class="docutils literal">rem()</span> for such integer
+coefficients polynomials.</p>
+<div class="admonition hint">
+<p class="admonition-title">Hint</p>
+<p>If you want the euclidean quotient <span class="docutils literal">R</span> evaluated via <span class="docutils literal">spR/m</span>
+(which may be faster, even with non integer coefficients) use
+<span class="docutils literal"><span class="pre">subs(last(x)/first(x),x=prem(P,Q))</span></span> syntax as it avoids
+computing <span class="docutils literal">prem(P,Q)</span> twice. This does the trick both in
+<span class="docutils literal">\poldef</span> or in <span class="docutils literal">\xintdefvar</span>.</p>
+<p>However, as is explained in the <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> documentation, using
+such syntax in an <span class="docutils literal">\xintdeffunc</span> is (a.t.t.o.w) illusory, due to
+technicalities of how <span class="docutils literal">subs()</span> gets converted into nested
+expandable macros. One needs an auxiliary function like this:</p>
+<pre class="literal-block">\xintdeffunc lastoverfirst(x):=last(x)/first(x);
+\xintdeffunc myR(x)=lastoverfirst(prem(x));</pre>
+<p>Then, <span class="docutils literal">myR(pol1,pol2)</span> will evaluate <span class="docutils literal">prem(pol1,pol2)</span> only
+once and compute a polynomial identical to the euclidean
+remainder (internal representations of coefficients may differ).</p>
+</div>
+<p>In this case of integer coefficients polynomials, the polexpr
+internal representation of the integer coefficients in the pseudo
+remainder will be with unit denominators only if that was already the
+case for those of <span class="docutils literal">pol1</span> and <span class="docutils literal">pol2</span> (no automatic reduction to
+lowest terms is made prior or after computation).</p>
+<p>Pay attention here that <span class="docutils literal">b</span> is the <strong>absolute value</strong> of the
+leading coefficient of <span class="docutils literal">pol2</span>. Thus the coefficients of the
+pseudo-remainder have the same signs as those of the standard
+remainder. This diverges from Maple's function with the same name.</p>
+</blockquote>
+</div>
+<div class="section" id="divmod-pol-expr-1-pol-expr-2">
+<h2><a class="toc-backref" href="#id64"><span class="docutils literal"><span class="pre">divmod(&lt;pol.</span> expr. 1&gt;, &lt;pol. expr. 2&gt;)</span></a></h2>
+<blockquote>
+<p>Overloads the scalar <span class="docutils literal">divmod()</span> and associates it with the
+experimental <span class="docutils literal">//</span> and <span class="docutils literal">/:</span> as extended to the polynomial type.</p>
+<p>In particular when both <span class="docutils literal">pol1</span> and <span class="docutils literal">pol2</span> are scalars, this is
+the usual <span class="docutils literal">divmod()</span> (as in Python) and for <span class="docutils literal">pol1</span> and <span class="docutils literal">pol2</span>
+non constant polynomials, this is the same as <span class="docutils literal">quorem()</span>.</p>
+<blockquote>
+<p><strong>Highly unstable</strong> overloading of <span class="docutils literal">\xinteval</span>'s <span class="docutils literal">divmod()</span>.</p>
+</blockquote>
+</blockquote>
+</div>
+<div class="section" id="mod-pol-expr-1-pol-expr-2">
+<h2><a class="toc-backref" href="#id65"><span class="docutils literal"><span class="pre">mod(&lt;pol.</span> expr. 1&gt;, &lt;pol. expr. 2&gt;)</span></a></h2>
+<blockquote>
+<p>The <span class="docutils literal">R</span> of the <span class="docutils literal">divmod()</span> output. Same as <span class="docutils literal">R</span> of <span class="docutils literal">quorem()</span>
+when the second argument <span class="docutils literal">pol2</span> is of degree at least one.</p>
+<blockquote>
+<p><strong>Highly unstable</strong> overloading of <span class="docutils literal">\xinteval</span>'s <span class="docutils literal">mod()</span>.</p>
+</blockquote>
+</blockquote>
+</div>
+<div class="section" id="polgcd-pol-expr-1-pol-expr-2">
+<h2><a class="toc-backref" href="#id66"><span class="docutils literal"><span class="pre">polgcd(&lt;pol.</span> expr. 1&gt;, &lt;pol. expr. 2&gt;, <span class="pre">...)</span></span></a></h2>
+<blockquote>
+<p>Evaluates to the greatest common polynomial divisor of all the
+polynomial inputs. The output is a <strong>primitive</strong> (in particular,
+with integer coefficients) polynomial. It is zero if and only if all
+inputs vanish.</p>
+<p>Attention, there must be either at least two polynomial variables, or
+alternatively, only one argument which then must be a bracketed list
+or some expression or variable evaluating to such a &quot;nutple&quot; whose
+items are polynomials (see the documentation of the scalar <span class="docutils literal">gcd()</span>
+in <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a>).</p>
+<blockquote>
+<p>The two variable case could (and was, during development) have been
+defined at user level like this:</p>
+<pre class="literal-block">\xintdeffunc polgcd_(P,Q):=
+ (deg(Q))??{P}{1}{polgcd_(Q,primpart(last(prem(P,Q))))};
+\xintdeffunc polgcd(P,Q):=polgcd_(primpart(P),primpart(Q));%</pre>
+<p>This is basically what is done internally for two polynomials, up
+to some internal optimizations.</p>
+</blockquote>
+<p><strong>UNSTABLE</strong></p>
+<p>I hesitate between returning a <em>primitive</em> or a <em>monic</em> polynomial.
+Maple returns a primitive polynomial if all inputs <a class="footnote-reference brackets" href="#id7" id="id6">3</a> have integer
+coefficients, else it returns a monic polynomial, but this is
+complicated technically for us to add such a check and would add
+serious overhead.</p>
+<p>Internally, computations are done using primitive
+integer-coefficients polynomials (as can be seen in the function
+template above). So I decided finally to output a primitive
+polynomial, as one can always apply <span class="docutils literal">monicpart()</span> to it.</p>
+<p>Attention that this is at odds with behaviour of the legacy
+<a class="reference internal" href="#polgcd">\PolGCD</a> (non expandable) macro.</p>
+<dl class="footnote brackets">
+<dt class="label" id="id7"><span class="brackets"><a class="fn-backref" href="#id6">3</a></span></dt>
+<dd><p>actually, only two polynomial arguments are allowed by Maple's
+<span class="docutils literal">gcd()</span> as far as I know.</p>
+</dd>
+</dl>
+</blockquote>
+</div>
+<div class="section" id="resultant-pol-expr-1-pol-expr-2">
+<h2><a class="toc-backref" href="#id67"><span class="docutils literal"><span class="pre">resultant(&lt;pol.</span> expr. 1&gt;, &lt;pol. expr. 2&gt;)</span></a></h2>
+<blockquote>
+<p>The resultant.</p>
+<blockquote>
+<p><strong>NOT YET IMPLEMENTED</strong></p>
+</blockquote>
+</blockquote>
+</div>
+<div class="section" id="disc-pol-expr">
+<h2><a class="toc-backref" href="#id68"><span class="docutils literal"><span class="pre">disc(&lt;pol.</span> <span class="pre">expr.&gt;)</span></span></a></h2>
+<blockquote>
+<p>The discriminant.</p>
+<blockquote>
+<p><strong>NOT YET IMPLEMENTED</strong></p>
+</blockquote>
+</blockquote>
+</div>
+<div class="section" id="polpowmod-pol-expr-1-num-expr-pol-expr-2">
+<h2><a class="toc-backref" href="#id69"><span class="docutils literal"><span class="pre">polpowmod(&lt;pol.</span> expr. 1&gt;, &lt;num. <span class="pre">expr.&gt;,</span> &lt;pol. expr. 2&gt;)</span></a></h2>
+<blockquote>
+<p>Modular exponentiation: <span class="docutils literal">mod(pol1^N, pol2)</span> in a more efficient
+manner than first computing <span class="docutils literal">pol1^N</span> then reducing modulo <span class="docutils literal">pol2</span>.</p>
+<p>Attention that this is using the <span class="docutils literal">mod()</span> operation, whose current
+experimental status is as follows:</p>
+<ul class="simple">
+<li><p>if <span class="docutils literal"><span class="pre">deg(pol2)&gt;0</span></span>, the euclidean remainder operation,</p></li>
+<li><p>if <span class="docutils literal">pol2</span> is a scalar, coefficient-wise reduction modulo <span class="docutils literal">pol2</span>.</p></li>
+</ul>
+<p><strong>UNSTABLE</strong></p>
+<blockquote>
+<p>This is currently implemented at high level via <span class="docutils literal">\xintdeffunc</span> and
+recursive definitions, which were copied over from a scalar example
+in the <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> manual:</p>
+<pre class="literal-block">\xintdeffunc polpowmod_(P, m, Q) :=
+ isone(m)?
+ % m=1: return P modulo Q
+ { mod(P,Q) }
+ % m &gt; 1: test if odd or even and do recursive call
+ { odd(m)? { mod(P*sqr(polpowmod_(P, m//2, Q)), Q) }
+ { mod( sqr(polpowmod_(P, m//2, Q)), Q) }
+ }
+ ;%
+\xintdeffunc polpowmod(P, m, Q) := (m)?{polpowmod_(P, m, Q)}{1};%</pre>
+<p>Negative exponents are not currently implemented.</p>
+<p>For example:</p>
+<pre class="literal-block">\xinteval{subs(polpowmod(1+x,100,x^7),x=pol([0,1]))}
+\xinteval{subs(polpowmod(1+x,20,10), x=pol([0,1]))}</pre>
+<p>produce respectively:</p>
+<pre class="literal-block">pol([1, 100, 4950, 161700, 3921225, 75287520, 1192052400])
+pol([1, 0, 0, 0, 5, 4, 0, 0, 0, 0, 6, 0, 0, 0, 0, 4, 5, 0, 0, 0, 1])</pre>
+</blockquote>
+</blockquote>
+</div>
+<div class="section" id="rdcoeffs-pol-expr">
+<h2><a class="toc-backref" href="#id70"><span class="docutils literal"><span class="pre">rdcoeffs(&lt;pol.</span> <span class="pre">expr.&gt;)</span></span></a></h2>
+<blockquote>
+<p>This operates on the internal representation of the coefficients,
+reducing them to lowest terms.</p>
+<blockquote>
+<p><strong>name HIGHLY undecided</strong></p>
+</blockquote>
+</blockquote>
+</div>
+<div class="section" id="rdzcoeffs-pol-expr">
+<h2><a class="toc-backref" href="#id71"><span class="docutils literal"><span class="pre">rdzcoeffs(&lt;pol.</span> <span class="pre">expr.&gt;)</span></span></a></h2>
+<blockquote>
+<p>This operates on the internal representation of the coefficients,
+reducing them to lowest terms then extracting from numerator
+or denominator the maximal power of ten to store as a decimal
+exponent.</p>
+<p>This is sometimes favourable to more efficient polynomial algebra
+computations.</p>
+<blockquote>
+<p><strong>name HIGHLY undecided</strong></p>
+</blockquote>
+</blockquote>
+</div>
+<div class="section" id="diff1-pol-expr">
+<h2><a class="toc-backref" href="#id72"><span class="docutils literal"><span class="pre">diff1(&lt;pol.</span> <span class="pre">expr.&gt;)</span></span></a></h2>
+<blockquote>
+<p>The first derivative.</p>
+<blockquote>
+<p><strong>name UNSTABLE</strong></p>
+<p>This name may be used in future to be the partial derivative with
+respect to a first variable.</p>
+</blockquote>
+</blockquote>
+</div>
+<div class="section" id="diff2-pol-expr">
+<h2><a class="toc-backref" href="#id73"><span class="docutils literal"><span class="pre">diff2(&lt;pol.</span> <span class="pre">expr.&gt;)</span></span></a></h2>
+<blockquote>
+<p>The second derivative.</p>
+<blockquote>
+<p><strong>name UNSTABLE</strong></p>
+<p>This name may be used in future to be the partial derivative with
+respect to a second variable.</p>
+</blockquote>
+</blockquote>
+</div>
+<div class="section" id="diffn-pol-expr-p-num-expr-n">
+<h2><a class="toc-backref" href="#id74"><span class="docutils literal"><span class="pre">diffn(&lt;pol.</span> expr. P&gt;, &lt;num. expr. n&gt;)</span></a></h2>
+<blockquote>
+<p>The <span class="docutils literal">n</span>th derivative of <span class="docutils literal">P</span>. For <span class="docutils literal">n&lt;0</span> computes iterated primitives
+vanishing at the origin.</p>
+<p>The coefficients are not reduced to lowest terms.</p>
+<blockquote>
+<p><strong>name and syntax UNSTABLE</strong></p>
+<p>I am also considering reversing the order of the arguments.</p>
+</blockquote>
+</blockquote>
+</div>
+<div class="section" id="antider-pol-expr-p">
+<h2><a class="toc-backref" href="#id75"><span class="docutils literal"><span class="pre">antider(&lt;pol.</span> expr. P&gt;)</span></a></h2>
+<blockquote>
+<p>The primitive of <span class="docutils literal">P</span> with no constant term. Same as <span class="docutils literal"><span class="pre">diffn(P,-1)</span></span>.</p>
+</blockquote>
+</div>
+<div class="section" id="intfrom-pol-expr-p-pol-expr-c">
+<h2><a class="toc-backref" href="#id76"><span class="docutils literal"><span class="pre">intfrom(&lt;pol.</span> expr. P&gt;, &lt;pol. expr. c&gt;)</span></a></h2>
+<blockquote>
+<p>The primitive of <span class="docutils literal">P</span> vanishing at <span class="docutils literal">c</span>, i.e. <span class="docutils literal">\int_c^x P(t)dt</span>.</p>
+<p>Also <span class="docutils literal">c</span> can be a polynomial... so if <span class="docutils literal">c</span> is monomial <span class="docutils literal">x</span>
+this will give zero!</p>
+<blockquote>
+<p><strong>UNSTABLE</strong></p>
+<p>Allowing general polynomial variable for <span class="docutils literal">c</span> adds a bit of
+overhead to the case of a pure scalar. So I am hesitating
+maintaining this feature whose interest appears dubious.</p>
+</blockquote>
+</blockquote>
+</div>
+<div class="section" id="integral-pol-expr-p-pol-expr-a-pol-expr-b">
+<h2><a class="toc-backref" href="#id77"><span class="docutils literal"><span class="pre">integral(&lt;pol.</span> expr. P&gt;, [&lt;pol. expr. a&gt;, &lt;pol. expr. <span class="pre">b&gt;])</span></span></a></h2>
+<blockquote>
+<p><span class="docutils literal">\int_a^b P(t)dt</span>.</p>
+<p>The brackets here are not denoting an optional argument
+but a <em>mandatory</em> nutple argument <span class="docutils literal">[a, b]</span> with <em>two items</em>.</p>
+<p><span class="docutils literal">a</span> and <span class="docutils literal">b</span> are not restricted to be scalars, they can be
+polynomials.</p>
+<blockquote>
+<p>To compute <span class="docutils literal"><span class="pre">\int_{x-1}^x</span> P(t)dt</span> it is more efficient to use
+<span class="docutils literal"><span class="pre">intfrom(x-1)</span></span>.</p>
+<p>Similary to compute <span class="docutils literal"><span class="pre">\int_x^{x+1}</span> P(t)dt</span>, use <span class="docutils literal"><span class="pre">-intfrom(x+1)</span></span>.</p>
+<p><strong>UNSTABLE</strong></p>
+<p>Am I right to allow general polynomials <span class="docutils literal">a</span> and <span class="docutils literal">b</span> hence add
+overhead to the pure scalar case ?</p>
+</blockquote>
+</blockquote>
+</div>
+</div>
+<div class="section" id="examples-of-localization-of-roots">
+<h1><a class="toc-backref" href="#id78">Examples of localization of roots</a></h1>
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p>As of <span class="docutils literal">0.8</span>, <span class="docutils literal">polexpr</span> is usable with Plain TeX and not only with
+LaTeX, the examples of this section have been converted to use a
+syntax which (at least at time of writing, March 2021) works in both.</p>
+<p>This is done in order for the examples to be easy to copy-paste to
+documents using either macro format.</p>
+</div>
+<ul>
+<li><p>To make printed decimal numbers more enjoyable than via
+<span class="docutils literal">\xintSignedFrac</span> (or <span class="docutils literal">\xintSignedFwOver</span> with Plain):</p>
+<pre class="literal-block">\def\PolTypesetOne#1{\PolDecToString{\xintREZ{#1}}}%</pre>
+<p><span class="docutils literal">\PolDecToString</span> will use decimal notation to incorporate the power
+of ten part; and the <span class="docutils literal">\xintREZ</span> will have the effect to suppress
+trailing zeros if present in raw numerator (if those digits end up
+after decimal mark.) Notice that the above are expandable macros and
+that one can also do:</p>
+<pre class="literal-block">\def\PolToExprCmd#1{\PolDecToString{\xintREZ{#1}}}%</pre>
+<p>to modify output of <a class="reference internal" href="#poltoexpr-pol-expr">\PolToExpr{&lt;pol. expr.&gt;}</a>.</p>
+</li>
+<li><p>For extra info in log file use <span class="docutils literal">\xintverbosetrue</span>.</p></li>
+</ul>
+<div class="section" id="a-typical-example">
+<h2><a class="toc-backref" href="#id79">A typical example</a></h2>
+<p>In this example the polynomial is square-free.</p>
+<pre class="literal-block">\poldef f(x) := x^7 - x^6 - 2x + 1;
+
+\PolToSturm{f}{f}
+\PolSturmIsolateZeros{f}
+The \PolTypeset{f} polynomial has \PolSturmNbOfIsolatedZeros{f} distinct real
+roots which are located in the following intervals:
+\PolPrintIntervals{f}
+Here is the second root with ten more decimal digits:
+\PolRefineInterval[10]{f}{2}
+$$\PolSturmIsolatedZeroLeft{f}{2}&lt;Z_2&lt;\PolSturmIsolatedZeroRight{f}{2}$$
+And here is the first root with twenty digits after decimal mark:
+\PolEnsureIntervalLength{f}{1}{-20}
+$$\PolSturmIsolatedZeroLeft{f}{1}&lt;Z_1&lt;\PolSturmIsolatedZeroRight{f}{1}$$
+The first element of the Sturm chain has degree $\PolDegree{f_0}$. As
+this is the original degreee $\PolDegree{f}$ we know that $f$ is square free.
+Its derivative is up to a constant \PolTypeset{f_1} (in this example
+it is identical with it).
+\PolToSturm{f_1}{f_1}\PolSturmIsolateZeros{f_1}%
+The derivative has \PolSturmNbOfIsolatedZeros{f_1} distinct real
+roots:
+\PolPrintIntervals[W]{f_1}
+\PolEnsureIntervalLengths{f_1}{-10}%
+Here they are with ten digits after decimal mark:
+\PolPrintIntervals[W]{f_1}
+\PolDiff{f_1}{f''}
+\PolToSturm{f''}{f''}
+\PolSturmIsolateZeros{f''}
+The second derivative is \PolTypeset{f''}.
+It has \PolSturmNbOfIsolatedZeros{f''} distinct real
+roots:
+\PolPrintIntervals[X]{f''}
+Here is the positive one with 20 digits after decimal mark:
+\PolEnsureIntervalLength{f''}{2}{-20}%
+$$X_2 = \PolSturmIsolatedZeroLeft{f''}{2}\dots$$
+The more mathematically advanced among our dear readers will be able
+to give the exact value for $X_2$!</pre>
+</div>
+<div class="section" id="a-degree-four-polynomial-with-nearby-roots">
+<h2><a class="toc-backref" href="#id80">A degree four polynomial with nearby roots</a></h2>
+<p>Notice that this example is a bit outdated as <span class="docutils literal">0.7</span> release has
+added <span class="docutils literal"><span class="pre">\PolSturmIsolateZeros**{sturmname}</span></span> which would find exactly
+the roots. The steps here retain their interest when one is interested
+in finding isolating intervals for example to prepare some demonstration
+of dichotomy method.</p>
+<pre class="literal-block">\PolDef{Q}{(x-1.050001)(x-1.105001)(x-1.110501)(x-1.111051)}
+\PolTypeset{Q}
+\PolToSturm{Q}{Q} % it is allowed to use same prefix for Sturm chain
+\PolSturmIsolateZeros{Q}
+\PolPrintIntervals{Q}
+% reports 1.0 &lt; Z_1 &lt; 1.1, 1.10 &lt; Z_2 &lt; 1.11, 1.110 &lt; Z_3 &lt; 1.111, and 1.111 &lt; Z_4 &lt; 1.112
+% but the above bounds do not allow minimizing separation between roots
+% so we refine:
+\PolRefineInterval*{Q}{1}
+\PolRefineInterval*{Q}{2}
+\PolRefineInterval*{Q}{3}
+\PolRefineInterval*{Q}{4}
+\PolPrintIntervals{Q}
+% reports 1.05 &lt; Z_1 &lt; 1.06, 1.105 &lt; Z_2 &lt; 1.106, 1.1105 &lt; Z_3 &lt; 1.1106,
+% and 1.11105 &lt; Z_4 &lt; 1.11106.
+\PolEnsureIntervalLengths{Q}{-6}
+\PolPrintIntervals{Q}
+% of course finds here all roots exactly</pre>
+</div>
+<div class="section" id="the-degree-nine-polynomial-with-0-99-0-999-0-9999-as-triple-roots">
+<h2><a class="toc-backref" href="#id81">The degree nine polynomial with 0.99, 0.999, 0.9999 as triple roots</a></h2>
+<pre class="literal-block">% define a user command (xinttools is loaded automatically by polexpr)
+\def\showmultiplicities#1{% #1 = &quot;sturmname&quot;
+\xintFor* ##1 in {\xintSeq{1}{\PolSturmNbOfIsolatedZeros{#1}}}\do{%
+ The multiplicity is \PolSturmIsolatedZeroMultiplicity{#1}{##1}
+ \PolSturmIfZeroExactlyKnown{#1}{##1}%
+ {at the root $x=\PolSturmIsolatedZeroLeft{#1}{##1}$}
+ {for the root such that
+ $\PolSturmIsolatedZeroLeft{#1}{##1}&lt;x&lt;\PolSturmIsolatedZeroRight{#1}{##1}$}
+ \par
+}}%
+\PolDef{f}{(x-0.99)^3(x-0.999)^3(x-0.9999)^3}
+\def\PolTypesetOne#1{\PolDecToString{\xintREZ{#1}}}
+\PolTypeset{f}\par
+\PolToSturm{f}{f}% it is allowed to use &quot;polname&quot; as &quot;sturmname&quot; too
+\PolSturmIsolateZerosAndGetMultiplicities{f}% use the &quot;sturmname&quot; here
+% or \PolSturmIsolateZeros*{f} which is exactly the same, but shorter..
+
+\showmultiplicities{f}</pre>
+<p>In this example, the output will look like this (but using math mode):</p>
+<pre class="literal-block">x^9 - 8.9667x^8 + 35.73400293x^7 - 83.070418400109x^6 + 124.143648875193123x^5
+- 123.683070924326075877x^4 + 82.149260397553075617891x^3
+- 35.07602992699900159127007x^2 + 8.7364078733314648368671733x
+- 0.967100824643585986488103299
+
+The multiplicity is 3 at the root x = 0.99
+The multiplicity is 3 at the root x = 0.999
+The multiplicity is 3 at the root x = 0.9999</pre>
+<p>On first pass, these rational roots were found (due to their relative
+magnitudes, using <span class="docutils literal">\PolSturmIsolateZeros**</span> was not needed here). But
+multiplicity computation works also with (decimal) roots not yet
+identified or with non-decimal or irrational roots.</p>
+<p>It is fun to modify only a tiny bit the polynomial and see if polexpr
+survives:</p>
+<pre class="literal-block">\PolDef{g}{f(x)+1e-27}
+\PolTypeset{g}\par
+\PolToSturm{g}{g}
+\PolSturmIsolateZeros*{g}
+
+\showmultiplicities{g}</pre>
+<p>This produces:</p>
+<pre class="literal-block">x^9 - 8.9667x^8 + 35.73400293x^7 - 83.070418400109x^6 + 124.143648875193123x^5
+- 123.683070924326075877x^4 + 82.149260397553075617891x^3
+- 35.07602992699900159127007x^2 + 8.7364078733314648368671733x
+- 0.967100824643585986488103298
+
+The multiplicity is 1 for the root such that 0.98 &lt; x &lt; 0.99
+The multiplicity is 1 for the root such that 0.9991 &lt; x &lt; 0.9992
+The multiplicity is 1 for the root such that 0.9997 &lt; x &lt; 0.9998</pre>
+<p>Which means that the multiplicity-3 roots each became a real and a pair of
+complex ones. Let's see them better:</p>
+<pre class="literal-block">\PolEnsureIntervalLengths{g}{-10}
+
+\showmultiplicities{g}</pre>
+<p>which produces:</p>
+<pre class="literal-block">The multiplicity is 1 for the root such that 0.9899888032 &lt; x &lt; 0.9899888033
+The multiplicity is 1 for the root such that 0.9991447980 &lt; x &lt; 0.9991447981
+The multiplicity is 1 for the root such that 0.9997663986 &lt; x &lt; 0.9997663987</pre>
+</div>
+<div class="section" id="a-degree-five-polynomial-with-three-rational-roots">
+<h2><a class="toc-backref" href="#id82">A degree five polynomial with three rational roots</a></h2>
+<pre class="literal-block">\poldef Q(x) := 1581755751184441 x^5
+ -14907697165025339 x^4
+ +48415668972339336 x^3
+ -63952057791306264 x^2
+ +46833913221154895 x
+ -49044360626280925;
+
+\PolToSturm{Q}{Q}
+ \def\PolTypesetCmdPrefix#1{\allowbreak\xintiiifSgn{#1}{}{+}{+}}%
+ $Q_0(x) = \PolTypeset{Q_0}$
+\PolSturmIsolateZeros**{Q}
+\PolPrintIntervals{Q}
+
+$Q_{norr}(x) = \PolTypeset{Q_norr}$</pre>
+<p>Here, all real roots are rational:</p>
+<pre class="literal-block">Z_1 = 833719/265381
+Z_2 = 165707065/52746197
+Z_3 = 355/113
+
+Q_norr(x) = x^2 + 1</pre>
+<p>And let's get their decimal expansion too:</p>
+<pre class="literal-block">% print decimal expansion of the found roots
+\def\PolPrintIntervalsPrintExactZero
+ {\xintTrunc{20}{\PolPrintIntervalsTheLeftEndPoint}\dots}
+\PolPrintIntervals{Q}
+
+Z_1 = 3.14159265358107777120...
+Z_2 = 3.14159265358979340254...
+Z_3 = 3.14159292035398230088...</pre>
+</div>
+<div class="section" id="a-mignotte-type-polynomial">
+<h2><a class="toc-backref" href="#id83">A Mignotte type polynomial</a></h2>
+<pre class="literal-block">\PolDef{P}{x^10 - (10x-1)^2}%
+\PolTypeset{P} % prints it in expanded form
+\PolToSturm{P}{P} % we can use same prefix for Sturm chain
+\PolSturmIsolateZeros{P} % finds 4 real roots
+This polynomial has \PolSturmNbOfIsolatedZeros{P} distinct real roots:
+\PolPrintIntervals{P}%
+% reports -2 &lt; Z_1 &lt; -1, 0.09 &lt; Z_2 &lt; 0.10, 0.1 &lt; Z_3 &lt; 0.2, 1 &lt; Z_4 &lt; 2
+Let us refine the second and third intervals to separate the corresponding
+roots:
+\PolRefineInterval*{P}{2}% will refine to 0.0999990 &lt; Z_2 &lt; 0.0999991
+\PolRefineInterval*{P}{3}% will refine to 0.100001 &lt; Z_3 &lt; 0.100002
+\PolPrintIntervals{P}%
+Let us now get to know all roots with 10 digits after decimal mark:
+\PolEnsureIntervalLengths{P}{-10}%
+\PolPrintIntervals{P}% now all roots are known 10 decimal digits after mark
+Finally, we display 20 digits of the second root:
+\PolEnsureIntervalLength{P}{2}{-20}% makes Z_2 known with 20 digits after mark
+$$\PolSturmIsolatedZeroLeft{P}{2}&lt;Z_2&lt;\PolSturmIsolatedZeroRight{P}{2}$$</pre>
+<p>The last line produces:</p>
+<pre class="literal-block">0.09999900004999650028 &lt; Z_2 &lt; 0.09999900004999650029</pre>
+</div>
+<div class="section" id="the-wilkinson-polynomial">
+<h2><a class="toc-backref" href="#id84">The Wilkinson polynomial</a></h2>
+<p>See <a class="reference external" href="https://en.wikipedia.org/wiki/Wilkinson%27s_polynomial">Wilkinson polynomial</a>.</p>
+<pre class="literal-block">%\xintverbosetrue % for the curious...
+
+\poldef f(x) := mul((x - i), i = 1..20);
+
+\def\PolTypesetCmdPrefix#1{\allowbreak\xintiiifSgn{#1}{}{+}{+}}%
+\def\PolTypesetOne#1{\xintDecToString{#1}}%
+
+\noindent\PolTypeset{f}
+
+\PolToSturm{f}{f}
+\PolSturmIsolateZeros{f}
+\PolPrintIntervals{f}
+
+% \vfill\eject
+
+% This page is commented out because it takes about 30s on a 2GHz CPU
+% \poldef g(x) := f(x) - 2**{-23} x**19;
+
+% \PolToSturm{g}{g}
+% \noindent\PolTypeset{g_0}% integer coefficient primitive polynomial
+
+% \PolSturmIsolateZeros{g}
+% \PolEnsureIntervalLengths{g}{-10}
+
+% \let\PolPrintIntervalsPrintMultiplicity\empty
+% \PolPrintIntervals*{g}</pre>
+<p>The first polynomial:</p>
+<pre class="literal-block">f(x) = x**20
+- 210 x**19
++ 20615 x**18
+- 1256850 x**17
++ 53327946 x**16
+- 1672280820 x**15
++ 40171771630 x**14
+- 756111184500 x**13
++ 11310276995381 x**12
+- 135585182899530 x**11
++ 1307535010540395 x**10
+- 10142299865511450 x**9
++ 63030812099294896 x**8
+- 311333643161390640 x**7
++ 1206647803780373360 x**6
+- 3599979517947607200 x**5
++ 8037811822645051776 x**4
+- 12870931245150988800 x**3
++ 13803759753640704000 x**2
+- 8752948036761600000 x
++ 2432902008176640000</pre>
+<p>is handled fast enough, but the modified one <span class="docutils literal">f(x) - <span class="pre">2**-23</span> <span class="pre">x**19</span></span> takes about 20x longer.</p>
+<p>The Sturm chain polynomials
+have integer coefficients with up to 321 digits, whereas (surprisingly
+perhaps) those of the Sturm chain polynomials derived from <span class="docutils literal">f</span> never
+have more than 21 digits ...</p>
+<p>Once the Sturm chain is computed and the zeros isolated, obtaining their
+decimal digits is relatively faster. Here is for the ten real roots of
+<span class="docutils literal">f(x) - <span class="pre">2**-23</span> <span class="pre">x**19</span></span> as computed by the code above:</p>
+<pre class="literal-block">Z_1 = 0.9999999999...
+Z_2 = 2.0000000000...
+Z_3 = 2.9999999999...
+Z_4 = 4.0000000002...
+Z_5 = 4.9999999275...
+Z_6 = 6.0000069439...
+Z_7 = 6.9996972339...
+Z_8 = 8.0072676034...
+Z_9 = 8.9172502485...
+Z_10 = 20.8469081014...</pre>
+</div>
+<div class="section" id="the-second-wilkinson-polynomial">
+<h2><a class="toc-backref" href="#id85">The second Wilkinson polynomial</a></h2>
+<pre class="literal-block">\poldef f(x) := mul(x - 2^-i, i = 1..20);
+
+%\PolTypeset{f}
+
+\PolToSturm{f}{f}
+\PolSturmIsolateZeros**{f}
+\PolPrintIntervals{f}</pre>
+<p>This takes more time than the polynomial with 1, 2, .., 20 as roots but
+less than the latter modified by the <span class="docutils literal"><span class="pre">2**-23</span></span> tiny change to one of its
+coefficient.</p>
+<p>Here is the output (with release 0.7.2):</p>
+<pre class="literal-block">Z_1 = 0.00000095367431640625
+Z_2 = 0.0000019073486328125
+Z_3 = 0.000003814697265625
+Z_4 = 0.00000762939453125
+Z_5 = 0.0000152587890625
+Z_6 = 0.000030517578125
+Z_7 = 0.00006103515625
+Z_8 = 0.0001220703125
+Z_9 = 1/4096
+Z_10 = 1/2048
+Z_11 = 1/1024
+Z_12 = 1/512
+Z_13 = 1/256
+Z_14 = 1/128
+Z_15 = 0.015625
+Z_16 = 0.03125
+Z_17 = 0.0625
+Z_18 = 0.125
+Z_19 = 0.25
+Z_20 = 0.5</pre>
+<p>There is some incoherence in output format which has its source in the
+fact that some roots are found in branches which can only find decimal
+roots, whereas some are found in branches which could find general
+fractions and they use <span class="docutils literal">\xintIrr</span> before storage of the found root.
+This may evolve in future.</p>
+</div>
+<div class="section" id="the-degree-41-polynomial-with-2-1-9-1-8-0-0-1-1-9-2-as-roots">
+<h2><a class="toc-backref" href="#id86">The degree 41 polynomial with -2, -1.9, -1.8, ..., 0, 0.1, ..., 1.9, 2 as roots</a></h2>
+<pre class="literal-block">\PolDef{P}{mul((x-i*1e-1), i=-20..20)}% i/10 is same but less efficient</pre>
+<p>In the defining expression we could have used <span class="docutils literal">i/10</span> but this gives
+less efficient internal form for the coefficients (the <span class="docutils literal">10</span>'s end up
+in denominators).</p>
+<p>Using <span class="docutils literal">\PolToExpr{P}</span> after having done</p>
+<pre class="literal-block">\def\PolToExprCmd#1{\PolDecToString{\xintREZ{#1}}}</pre>
+<p>we get this expanded form:</p>
+<pre class="literal-block">x^41
+-28.7*x^39
++375.7117*x^37
+-2975.11006*x^35
++15935.28150578*x^33
+-61167.527674162*x^31
++173944.259366417394*x^29
+-373686.963560544648*x^27
++613012.0665016658846445*x^25
+-771182.31133138163125495*x^23
++743263.86672885754888959569*x^21
+-545609.076599482896371978698*x^19
++301748.325708943677229642930528*x^17
+-123655.8987669450434698869844544*x^15
++36666.1782054884005855608205864192*x^13
+-7607.85821367459445649518380016128*x^11
++1053.15135918687298508885950223794176*x^9
+-90.6380005918141132650786081964032*x^7
++4.33701563847327366842552218288128*x^5
+-0.0944770968420804735498178265088*x^3
++0.00059190121813899276854174416896*x</pre>
+<p>which shows coefficients with up to 36 significant digits...</p>
+<p>Stress test: not a hard challenge to <span class="docutils literal">xint + polexpr</span>, but be a bit
+patient!</p>
+<pre class="literal-block">\PolDef{P}{mul((x-i*1e-1), i=-20..20)}%
+\PolToSturm{P}{S} % dutifully computes S_0, ..., S_{41}
+% the [1] optional argument limits the search to interval (-10,10)
+\PolSturmIsolateZeros[1]{S} % finds *exactly* (but a bit slowly) all 41 roots!
+\PolPrintIntervals{S} % nice, isn't it?</pre>
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p>Release <span class="docutils literal">0.5</span> has <em>experimental</em> addition of optional argument
+<span class="docutils literal">E</span> to <span class="docutils literal">\PolSturmIsolateZeros</span>. It instructs to search roots only
+in interval <span class="docutils literal"><span class="pre">(-10^E,</span> 10^E)</span>. Important: the extremities are
+<em>assumed to not be roots</em>. In this example, the <span class="docutils literal">[1]</span> in
+<span class="docutils literal"><span class="pre">\PolSturmIsolateZeros[1]{S}</span></span> gives some speed gain; without it, it
+turns out in this case that <span class="docutils literal">polexpr</span> would have started with
+<span class="docutils literal"><span class="pre">(-10^6,</span> 10^6)</span> interval.</p>
+<p>Please note that this will probably get replaced in future by the
+specification of a general interval. Do not rely on meaning of this
+optional argument keeping the same.</p>
+</div>
+</div>
+<div class="section" id="roots-of-chebyshev-polynomials">
+<h2><a class="toc-backref" href="#id87">Roots of Chebyshev polynomials</a></h2>
+<pre class="literal-block">\newcount\mycount
+\poldef T_0(x) := 1;
+\poldef T_1(x) := x;
+\mycount 2
+\xintloop
+ \poldef T_\the\mycount(x) :=
+ 2x*T_\the\numexpr\mycount-1(x)
+ - T_\the\numexpr\mycount-2(x);
+\ifnum\mycount&lt;15
+\advance\mycount 1
+\repeat
+
+$$T_{15} = \PolTypeset[X]{T_15}$$
+\PolToSturm{T_15}{T_15}
+\PolSturmIsolateZeros{T_15}
+\PolEnsureIntervalLengths{T_15}{-10}
+\PolPrintIntervals{T_15}</pre>
+</div>
+</div>
+<div class="section" id="non-expandable-macros">
+<h1><a class="toc-backref" href="#id88">Non-expandable macros</a></h1>
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p>At <span class="docutils literal">0.8</span> <span class="docutils literal">polexpr</span> is usable with Plain TeX and not only with
+LaTeX. Some examples given in this section may be using LaTeX syntax
+such as <span class="docutils literal">\renewcommand</span>. Convert to TeX primitives as appropriate
+if testing with a non LaTeX macro format.</p>
+</div>
+<div class="section" id="poldef-polname-letter-expression-using-the-letter-as-indeterminate">
+<span id="poldef"></span><h2><a class="toc-backref" href="#id89"><span class="docutils literal">\poldef <span class="pre">polname(letter):=</span> expression using the letter as indeterminate;</span></a></h2>
+<blockquote>
+<p>This evaluates the <em>polynomial expression</em> and stores the
+coefficients in a private structure accessible later via other
+package macros, when used with argument the chosen <span class="docutils literal">polname</span>. Of
+course the <em>expression</em> can use other previously defined
+polynomials.</p>
+<p>Polynomial names must start with a letter and are constituted of
+letters, digits, underscores and the right tick <span class="docutils literal">'</span>.</p>
+<p>The whole <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> syntax is authorized:</p>
+<pre class="literal-block">\poldef mypol(z) := add((-1)^i z^(2i+1)/(2i+1)!, i = 0..10);</pre>
+<p>With fractional coefficients, beware the <a class="reference internal" href="#warningtacit">tacit multiplication issue</a>.</p>
+<p>Furthermore:</p>
+<ul class="simple">
+<li><p>a variable <span class="docutils literal">mypol</span> is defined which can be used in <span class="docutils literal">\poldef</span>
+as well as in <span class="docutils literal">\xinteval</span> for algebraic computations or as
+argument to polynomial aware functions,</p></li>
+<li><p>a function <span class="docutils literal">mypol()</span> is defined which can be used in <span class="docutils literal">\poldef</span>
+as well as in <span class="docutils literal">\xinteval</span>. It accepts there as argument scalars
+and also other polynomials (via their names, thanks to previous
+item).</p></li>
+</ul>
+<p>Notice that any function defined via <span class="docutils literal">\xintdeffunc</span> and using
+only algebraic operations (and ople indexing or slicing operations)
+should work fine in <span class="docutils literal"><span class="pre">\xintexpr/\xinteval</span></span> with such polynomial
+names as argument.</p>
+<p>In the case of a constant polynomial, the <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> variable (not the
+internal data structure on which the package macros operate)
+associated to it is indistinguishable from a scalar, it is actually
+a scalar and has lost all traces from its origins as a polynomial
+(so for example can be used as argument to the <span class="docutils literal">cos()</span> function).
+<strong>THIS MAY CHANGE</strong></p>
+<p>The <em>function</em> on the other hand remains a one-argument function,
+which simply has a constant value.</p>
+<div class="admonition attention">
+<p class="admonition-title">Attention!</p>
+<p>The function <span class="docutils literal">mypol()</span> is defined <strong>only</strong> for
+<span class="docutils literal"><span class="pre">\xintexpr/\xinteval</span></span>
+context. It will be unknown to <span class="docutils literal">\xintfloateval</span>.</p>
+<p>Worse, a
+previously existing floating point function of the same name will
+be let undefined again, to avoid hard to debug mismatches between
+exact and floating point polynomials. This also applies when the
+polynomial is produced not via <span class="docutils literal">\poldef</span> or <span class="docutils literal">\PolDef</span> but
+as result of usage of the other package macros.</p>
+<p>See <a class="reference internal" href="#polgenfloatvariant-polname">\PolGenFloatVariant{polname}</a> to generate a <strong>function</strong>
+usable in <span class="docutils literal">\xintfloateval</span>. Such a function can only be
+used with scalar input, see next warning.</p>
+</div>
+<div class="admonition attention">
+<p class="admonition-title">Attention!</p>
+<p>Using the <strong>variable</strong> <span class="docutils literal">mypol</span> inside <span class="docutils literal">\xintfloateval</span> will
+generate low-level errors because the infix operators there are
+not polynomial-aware, and the polynomial specific functions such
+as <span class="docutils literal">deg()</span> are only defined for usage inside <span class="docutils literal">\xintexpr</span>.</p>
+<p>In short, currently polynomials defined via <span class="docutils literal">polexpr</span> can
+be used in floating point context only for numerical evaluations,
+via <strong>functions</strong> obtained from <a class="reference internal" href="#polgenfloatvariant-polname">\PolGenFloatVariant{polname}</a>
+usage.</p>
+<p>Changes to the original polynomial via package macros are not
+automatically mapped to the numerical floating point evaluator
+which must be manually updated as necessary when the original
+rational coefficient polynomial is modified.</p>
+<p><strong>THIS MAY CHANGE</strong></p>
+</div>
+<p>The original expression is lost after parsing, and in particular the
+package provides no way to typeset it (of course the package
+provides macros to typeset the computed polynomial). Typesetting
+the original expression has to be done manually, if needed.</p>
+</blockquote>
+</div>
+<div class="section" id="poldef-letter-polname-expression-using-the-letter-as-indeterminate">
+<span id="id8"></span><h2><a class="toc-backref" href="#id90"><span class="docutils literal"><span class="pre">\PolDef[letter]{polname}{expression</span> using the letter as indeterminate}</span></a></h2>
+<blockquote>
+<p>Does the same as <a class="reference internal" href="#poldef">\poldef</a> in an undelimited macro
+format (thus avoiding potential problems with the catcode of the
+semi-colon in presence of some packages.) In absence of the
+<span class="docutils literal">[letter]</span> optional argument, the variable is assumed to be <span class="docutils literal">x</span>.</p>
+</blockquote>
+</div>
+<div class="section" id="polgenfloatvariant-polname">
+<span id="polgenfloatvariant"></span><h2><a class="toc-backref" href="#id91"><span class="docutils literal">\PolGenFloatVariant{polname}</span></a></h2>
+<blockquote>
+<p>Makes the polynomial also usable in the <span class="docutils literal">\xintfloatexpr</span> parser.
+It will therein evaluates via an Horner scheme with coefficients
+already pre-rounded to the float precision.</p>
+<p>See also <a class="reference internal" href="#poltofloatexpr-pol-expr">\PolToFloatExpr{&lt;pol. expr.&gt;}</a>.</p>
+<div class="admonition attention">
+<p class="admonition-title">Attention!</p>
+<p>Any operation, for example generating the derivative polynomial,
+or dividing two polynomials or using the <span class="docutils literal">\PolLet</span>, <strong>must</strong> be
+followed by explicit usage of <span class="docutils literal">\PolGenFloatVariant{polname}</span> if
+the new polynomial is to be used in <span class="docutils literal">\xintfloateval</span> <strong>as a
+function</strong>.</p>
+</div>
+</blockquote>
+</div>
+<div class="section" id="pollet-polname-2-polname-1">
+<span id="pollet"></span><h2><a class="toc-backref" href="#id92"><span class="docutils literal"><span class="pre">\PolLet{polname_2}={polname_1}</span></span></a></h2>
+<blockquote>
+<p>Makes a copy of the already defined polynomial <span class="docutils literal">polname_1</span> to a
+new one <span class="docutils literal">polname_2</span>. Same effect as
+<span class="docutils literal"><span class="pre">\PolDef{polname_2}{polname_1(x)}</span></span> but with less overhead. The
+<span class="docutils literal">=</span> is optional.</p>
+</blockquote>
+</div>
+<div class="section" id="polgloballet-polname-2-polname-1">
+<span id="polgloballet"></span><h2><a class="toc-backref" href="#id93"><span class="docutils literal"><span class="pre">\PolGlobalLet{polname_2}={polname_1}</span></span></a></h2>
+<blockquote>
+<p>Acts globally.</p>
+</blockquote>
+</div>
+<div class="section" id="polassign-polname-toarray-macro">
+<span id="polassign"></span><h2><a class="toc-backref" href="#id94"><span class="docutils literal"><span class="pre">\PolAssign{polname}\toarray\macro</span></span></a></h2>
+<blockquote>
+<p>Defines a one-argument expandable macro <span class="docutils literal"><span class="pre">\macro{#1}</span></span> which expands
+to the (raw) #1th polynomial coefficient.</p>
+<ul class="simple">
+<li><p>Attention, coefficients here are indexed starting at 1.</p></li>
+<li><p>With #1=-1, -2, ..., <span class="docutils literal"><span class="pre">\macro{#1}</span></span> returns leading coefficients.</p></li>
+<li><p>With #1=0, returns the number of coefficients, i.e. <span class="docutils literal">1 + deg f</span>
+for non-zero polynomials.</p></li>
+<li><p>Out-of-range #1's return <span class="docutils literal">0/1[0]</span>.</p></li>
+</ul>
+<p>See also <a class="reference internal" href="#polnthcoeff-polname-number">\PolNthCoeff{polname}{number}</a>. The main difference is that
+with <span class="docutils literal">\PolAssign</span>, <span class="docutils literal">\macro</span> is made a prefix to <span class="docutils literal">1 + deg f</span>
+already defined (hidden to user) macros holding individually the
+coefficients but <a class="reference internal" href="#polnthcoeff-polname-number">\PolNthCoeff{polname}{number}</a> does each time the job
+to expandably recover the <span class="docutils literal">Nth</span> coefficient, and due to
+expandability can not store it in a macro for future usage (of course,
+it can be an argument in an <span class="docutils literal">\edef</span>.) The other difference
+is the shift by one in indexing, mentioned above (negative
+indices act the same in both.)</p>
+</blockquote>
+</div>
+<div class="section" id="polget-polname-fromarray-macro">
+<span id="polget"></span><h2><a class="toc-backref" href="#id95"><span class="docutils literal"><span class="pre">\PolGet{polname}\fromarray\macro</span></span></a></h2>
+<blockquote>
+<p>Does the converse operation to
+<span class="docutils literal"><span class="pre">\PolAssign{polname}\toarray\macro</span></span>. Each individual
+<span class="docutils literal">\macro{number}</span> gets expanded in an <span class="docutils literal">\edef</span> and then normalized
+via <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a>'s macro <span class="docutils literal">\xintRaw</span>.</p>
+<p>The leading zeros are removed from the polynomial.</p>
+<p>(contrived) Example:</p>
+<pre class="literal-block">\xintAssignArray{1}{-2}{5}{-3}\to\foo
+\PolGet{f}\fromarray\foo</pre>
+<p>This will define <span class="docutils literal">f</span> as would have <span class="docutils literal">\poldef <span class="pre">f(x):=1-2x+5x^2-3x^3;</span></span>.</p>
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p>Prior to <span class="docutils literal">0.5</span>, coefficients were not normalized via
+<span class="docutils literal">\xintRaw</span> for internal storage.</p>
+</div>
+</blockquote>
+</div>
+<div class="section" id="polfromcsv-polname-csv">
+<span id="polfromcsv"></span><h2><a class="toc-backref" href="#id96"><span class="docutils literal"><span class="pre">\PolFromCSV{polname}{&lt;csv&gt;}</span></span></a></h2>
+<blockquote>
+<p>Defines a polynomial directly from the comma separated list of values
+(or a macro expanding to such a list) of its coefficients, the <em>first
+item</em> gives the constant term, the <em>last item</em> gives the leading
+coefficient, except if zero, then it is dropped (iteratively). List
+items are each expanded in an <span class="docutils literal">\edef</span> and then put into normalized
+form via <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a>'s macro <span class="docutils literal">\xintRaw</span>.</p>
+<p>As leading zero coefficients are removed:</p>
+<pre class="literal-block">\PolFromCSV{f}{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}</pre>
+<p>defines the zero polynomial, which holds only one coefficient.</p>
+<p>See also expandable macro <a class="reference internal" href="#poltocsv-polname">\PolToCSV</a>.</p>
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p>Prior to <span class="docutils literal">0.5</span>, coefficients were not normalized via
+<span class="docutils literal">\xintRaw</span> for internal storage.</p>
+</div>
+</blockquote>
+</div>
+<div class="section" id="poltypeset-pol-expr">
+<span id="poltypeset"></span><h2><a class="toc-backref" href="#id97"><span class="docutils literal"><span class="pre">\PolTypeset{&lt;pol.</span> <span class="pre">expr.&gt;}</span></span></a></h2>
+<blockquote>
+<p>Typesets in descending powers, switching to math mode if in text
+mode, after evaluating the polynomial expression:</p>
+<pre class="literal-block">\PolTypeset{mul(x-i,i=1..5)}% possible since polexpr 0.8</pre>
+<p>The letter used in the input expression is by default <span class="docutils literal">x</span>,
+but can be modified by a redefinition of <a class="reference internal" href="#poltoexprinvar">\PolToExprInVar</a>.</p>
+<p>It uses also by default the letter <span class="docutils literal">x</span> on output but this one can
+be changed via an optional argument:</p>
+<pre class="literal-block">\PolTypeset[z]{polname or polynomial expression}</pre>
+<p>By default zero coefficients are skipped (use <span class="docutils literal">\poltypesetalltrue</span>
+to get all of them in output).</p>
+<p>The following macros (whose meanings will be found in the package code)
+can be re-defined for customization. Their default definitions are
+expandable, but this is not a requirement.</p>
+</blockquote>
+<div class="section" id="poltypesetcmd-raw-coeff">
+<span id="poltypesetcmd"></span><h3><a class="toc-backref" href="#id98"><span class="docutils literal">\PolTypesetCmd{raw_coeff}</span></a></h3>
+<blockquote>
+<p>Checks if the coefficient is <span class="docutils literal">1</span> or <span class="docutils literal"><span class="pre">-1</span></span> and then skips printing
+the <span class="docutils literal">1</span>, except for the constant term. Also it sets conditional
+<a class="reference internal" href="#polifcoeffisplusorminusone-a-b">\PolIfCoeffIsPlusOrMinusOne{A}{B}</a>.</p>
+<p>The actual printing of the coefficients, when not equal to plus or
+minus one is handled by <a class="reference internal" href="#poltypesetone-raw-coeff">\PolTypesetOne{raw_coeff}</a>.</p>
+</blockquote>
+</div>
+<div class="section" id="poltypesetone-raw-coeff">
+<span id="poltypesetone"></span><h3><a class="toc-backref" href="#id99"><span class="docutils literal">\PolTypesetOne{raw_coeff}</span></a></h3>
+<blockquote>
+<p>Defaults to <span class="docutils literal">\xintSignedFrac</span> (LaTeX) or <span class="docutils literal">\xintSignedFwOver</span>
+(else). But these <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> very old legacy macros are a bit
+annoyin as they insist in exhibiting a power of ten rather than
+using simpler decimal notation.</p>
+<p>As alternative one can do things such as:</p>
+<pre class="literal-block">\def\PolTypesetOne#1{\xintDecToString{\xintREZ{#1}}}
+% or with LaTeX+siunitx for example
+\renewcommand\PolTypesetOne[1]{\num{\xintPFloat[5]{#1}}}
+% (as \num of siunitx understands floating point notation)
+\renewcommand\PolTypesetOne[1]{\num{\xintRound{4}{#1}}}</pre>
+</blockquote>
+</div>
+<div class="section" id="id9">
+<span id="poltypesetmonomialcmd"></span><h3><a class="toc-backref" href="#id100"><span class="docutils literal">\PolTypesetMonomialCmd</span></a></h3>
+<blockquote>
+<p>This decides how a monomial (in variable <span class="docutils literal">\PolVar</span> and with
+exponent <span class="docutils literal">\PolIndex</span>) is to be printed. The default does nothing
+for the constant term, <span class="docutils literal">\PolVar</span> for the first degree and
+<span class="docutils literal"><span class="pre">\PolVar^{\PolIndex}</span></span> for higher degrees monomials. Beware that
+<span class="docutils literal">\PolIndex</span> expands to digit tokens and needs termination in
+<span class="docutils literal">\ifnum</span> tests.</p>
+</blockquote>
+</div>
+<div class="section" id="poltypesetcmdprefix-raw-coeff">
+<span id="poltypesetcmdprefix"></span><h3><a class="toc-backref" href="#id101"><span class="docutils literal">\PolTypesetCmdPrefix{raw_coeff}</span></a></h3>
+<blockquote>
+<p>Expands to a <span class="docutils literal">+</span> if the <span class="docutils literal">raw_coeff</span> is zero or positive, and to
+nothing if <span class="docutils literal">raw_coeff</span> is negative, as in latter case the
+<span class="docutils literal">\xintSignedFrac</span> (or <span class="docutils literal">\xintSignedFwOver</span>) used by
+<a class="reference internal" href="#poltypesetcmd-raw-coeff">\PolTypesetCmd{raw_coeff}</a> will put the <span class="docutils literal">-</span> sign in front of
+the fraction (if it is a fraction) and this will thus serve as
+separator in the typeset formula. Not used for the first term.</p>
+</blockquote>
+</div>
+</div>
+<div class="section" id="id11">
+<span id="id10"></span><h2><a class="toc-backref" href="#id102"><span class="docutils literal"><span class="pre">\PolTypeset*{&lt;pol.</span> <span class="pre">expr.&gt;}</span></span></a></h2>
+<blockquote>
+<p>Typesets in ascending powers. Use e.g. <span class="docutils literal">[h]</span> optional argument
+(after the <span class="docutils literal">*</span>) to use letter <span class="docutils literal">h</span> rather than <span class="docutils literal">x</span>.</p>
+<p>Extended at <span class="docutils literal">0.8</span> to accept general expressions and not only
+polynomial names. Redefine <a class="reference internal" href="#poltoexprinvar">\PolToExprInVar</a> to use in the
+expression another letter than default <span class="docutils literal">x</span>.</p>
+</blockquote>
+</div>
+<div class="section" id="poldiff-polname-1-polname-2">
+<span id="poldiff"></span><h2><a class="toc-backref" href="#id103"><span class="docutils literal"><span class="pre">\PolDiff{polname_1}{polname_2}</span></span></a></h2>
+<blockquote>
+<p>This sets <span class="docutils literal">polname_2</span> to the first derivative of <span class="docutils literal">polname_1</span>. It
+is allowed to issue <span class="docutils literal"><span class="pre">\PolDiff{f}{f}</span></span>, effectively replacing <span class="docutils literal">f</span>
+by <span class="docutils literal">f'</span>.</p>
+<p>Coefficients of the result <span class="docutils literal">polname_2</span> are irreducible fractions
+(see <a class="reference internal" href="#technicalities">Technicalities</a> for the whole story.)</p>
+</blockquote>
+</div>
+<div class="section" id="poldiff-n-polname-1-polname-2">
+<span id="poldiff-n"></span><h2><a class="toc-backref" href="#id104"><span class="docutils literal"><span class="pre">\PolDiff[N]{polname_1}{polname_2}</span></span></a></h2>
+<blockquote>
+<p>This sets <span class="docutils literal">polname_2</span> to the <span class="docutils literal">N</span>-th derivative of <span class="docutils literal">polname_1</span>.
+Identical arguments is allowed. With <span class="docutils literal">N=0</span>, same effect as
+<span class="docutils literal"><span class="pre">\PolLet{polname_2}={polname_1}</span></span>. With negative <span class="docutils literal">N</span>, switches to
+using <span class="docutils literal">\PolAntiDiff</span>.</p>
+</blockquote>
+</div>
+<div class="section" id="polantidiff-polname-1-polname-2">
+<span id="polantidiff"></span><h2><a class="toc-backref" href="#id105"><span class="docutils literal"><span class="pre">\PolAntiDiff{polname_1}{polname_2}</span></span></a></h2>
+<blockquote>
+<p>This sets <span class="docutils literal">polname_2</span> to the primitive of <span class="docutils literal">polname_1</span> vanishing
+at zero.</p>
+<p>Coefficients of the result <span class="docutils literal">polname_2</span> are irreducible fractions
+(see <a class="reference internal" href="#technicalities">Technicalities</a> for the whole story.)</p>
+</blockquote>
+</div>
+<div class="section" id="polantidiff-n-polname-1-polname-2">
+<span id="polantidiff-n"></span><h2><a class="toc-backref" href="#id106"><span class="docutils literal"><span class="pre">\PolAntiDiff[N]{polname_1}{polname_2}</span></span></a></h2>
+<blockquote>
+<p>This sets <span class="docutils literal">polname_2</span> to the result of <span class="docutils literal">N</span> successive integrations on
+<span class="docutils literal">polname_1</span>. With negative <span class="docutils literal">N</span>, it switches to using <span class="docutils literal">\PolDiff</span>.</p>
+</blockquote>
+</div>
+<div class="section" id="poldivide-polname-1-polname-2-polname-q-polname-r">
+<span id="poldivide"></span><h2><a class="toc-backref" href="#id107"><span class="docutils literal"><span class="pre">\PolDivide{polname_1}{polname_2}{polname_Q}{polname_R}</span></span></a></h2>
+<blockquote>
+<p>This sets <span class="docutils literal">polname_Q</span> and <span class="docutils literal">polname_R</span> to be the quotient and
+remainder in the Euclidean division of <span class="docutils literal">polname_1</span> by
+<span class="docutils literal">polname_2</span>.</p>
+</blockquote>
+</div>
+<div class="section" id="polquo-polname-1-polname-2-polname-q">
+<span id="polquo"></span><h2><a class="toc-backref" href="#id108"><span class="docutils literal"><span class="pre">\PolQuo{polname_1}{polname_2}{polname_Q}</span></span></a></h2>
+<blockquote>
+<p>This sets <span class="docutils literal">polname_Q</span> to be the quotient in the Euclidean division
+of <span class="docutils literal">polname_1</span> by <span class="docutils literal">polname_2</span>.</p>
+</blockquote>
+</div>
+<div class="section" id="polrem-polname-1-polname-2-polname-r">
+<span id="polrem"></span><h2><a class="toc-backref" href="#id109"><span class="docutils literal"><span class="pre">\PolRem{polname_1}{polname_2}{polname_R}</span></span></a></h2>
+<blockquote>
+<p>This sets <span class="docutils literal">polname_R</span> to be the remainder in the Euclidean division
+of <span class="docutils literal">polname_1</span> by <span class="docutils literal">polname_2</span>.</p>
+</blockquote>
+</div>
+<div class="section" id="polgcd-polname-1-polname-2-polname-gcd">
+<span id="polgcd"></span><h2><a class="toc-backref" href="#id110"><span class="docutils literal"><span class="pre">\PolGCD{polname_1}{polname_2}{polname_GCD}</span></span></a></h2>
+<blockquote>
+<p>This sets <span class="docutils literal">polname_GCD</span> to be the (monic) GCD of the two first
+polynomials. It is a unitary polynomial except if both <span class="docutils literal">polname_1</span>
+and <span class="docutils literal">polname_2</span> vanish, then <span class="docutils literal">polname_GCD</span> is the zero
+polynomial.</p>
+</blockquote>
+</div>
+<div class="section" id="non-expandable-macros-related-to-the-root-localization-routines">
+<h2><a class="toc-backref" href="#id111">Non-expandable macros related to the root localization routines</a></h2>
+<div class="section" id="poltosturm-polname-sturmname">
+<span id="poltosturm"></span><h3><a class="toc-backref" href="#id112"><span class="docutils literal"><span class="pre">\PolToSturm{polname}{sturmname}</span></span></a></h3>
+<blockquote>
+<p>With <span class="docutils literal">polname</span> being for example <span class="docutils literal">P</span>, the macro starts by
+computing polynomials <span class="docutils literal">P</span> and <span class="docutils literal">P'</span>, then computes the (opposite
+of the) remainder in euclidean division, iteratively.</p>
+<p>The last non-zero remainder <span class="docutils literal">P_N_</span> (where <span class="docutils literal">N</span> is obtainable as
+<a class="reference internal" href="#polsturmchainlength-sturmname">\PolSturmChainLength{sturmname}</a>) is up to a factor
+the GCD of <span class="docutils literal">P</span> and <span class="docutils literal">P'</span> hence it is a constant if and only if
+<span class="docutils literal">P</span> is square-free.</p>
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<ul class="simple">
+<li><p>Since <span class="docutils literal">0.5</span> all these polynomials are divided by their rational
+content, so they have integer coefficients with no common factor,
+and the last one if a constant is either <span class="docutils literal">1</span> or <span class="docutils literal"><span class="pre">-1</span></span>.</p></li>
+<li><p>After this normalization to primitive polynomials, they are
+stored internally as <span class="docutils literal">sturmname_k_</span>, <span class="docutils literal">k=0,1, ...</span>.</p></li>
+<li><p>These polynomials are used internally only. To keep them as
+genuine declared polynomials also after the macro call, use the
+starred variant <a class="reference internal" href="#id12">PolToSturm*</a>.</p></li>
+</ul>
+</div>
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p>It is perfectly allowed to use the polynomial name as Sturm chain name:
+<span class="docutils literal"><span class="pre">\PolToSturm{f}(f}</span></span>.</p>
+</div>
+<p>The macro then declares <span class="docutils literal">sturmname_0</span>, <span class="docutils literal">sturmname_1</span>, ..., which are
+the (non-declared) <span class="docutils literal">sturmname_k_</span> divided by the last one. Division is
+not done if this last one is the constant <span class="docutils literal">1</span> or <span class="docutils literal"><span class="pre">-1</span></span>, i.e. if the
+original polynomial was square-free. These polynomials are primitive
+polynomials too, i.e. with integer coefficients having no common factor.</p>
+<p>Thus <span class="docutils literal">sturmname_0</span> has exactly the same real and complex roots as
+polynomial <span class="docutils literal">polname</span>, but with each root now of multiplicity one:
+i.e. it is the &quot;square-free part&quot; of original polynomial <span class="docutils literal">polname</span>.</p>
+<p>Notice that <span class="docutils literal">sturmname_1</span> isn't necessarily the derivative of
+<span class="docutils literal">sturmname_0</span> due to the various normalizations.</p>
+<p>The polynomials <span class="docutils literal">sturmname_k</span> main utility is for the execution of
+<a class="reference internal" href="#polsturmisolatezeros-sturmname">\PolSturmIsolateZeros{sturmname}</a>. Be careful not to use these
+names <span class="docutils literal">sturmname_0</span>, <span class="docutils literal">sturmname_1</span>, etc... for defining other
+polynomials after having done <span class="docutils literal"><span class="pre">\PolToSturm{polname}{sturmname}</span></span> and
+before executing <span class="docutils literal">\PolSturmIsolateZeros{sturmname}</span> else the
+latter will behave erroneously.</p>
+<p><a class="reference internal" href="#polsturmchainlength-sturmname">\PolSturmChainLength{sturmname}</a> gives the index of the last
+element of the Sturm chain.</p>
+</blockquote>
+</div>
+<div class="section" id="id13">
+<span id="id12"></span><h3><a class="toc-backref" href="#id113"><span class="docutils literal"><span class="pre">\PolToSturm*{polname}{sturmname}</span></span></a></h3>
+<blockquote>
+<p>Does the same as <a class="reference internal" href="#poltosturm">un-starred version</a> and additionally it
+keeps for user usage the memory of the <em>un-normalized</em> Sturm chain
+polynomials <span class="docutils literal">sturmname_k_</span>, <span class="docutils literal">k=0,1, <span class="pre">...,</span> N</span>, with
+<span class="docutils literal">N</span> being <a class="reference internal" href="#polsturmchainlength-sturmname">\PolSturmChainLength{sturmname}</a>.</p>
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p>This behaviour was modified at <span class="docutils literal">0.6</span>, anyhow the macro was
+broken at <span class="docutils literal">0.5</span>.</p>
+</div>
+<div class="admonition hint">
+<p class="admonition-title">Hint</p>
+<p>The square-free part of <span class="docutils literal">polname</span> is <span class="docutils literal">sturmname_0</span>, and their
+quotient is the polynomial with name
+<span class="docutils literal">sturname_\PolSturmChainLength{sturmname}_</span>. It thus easy to
+set-up a loop iteratively computing the latter until the last one
+is a constant, thus obtaining the decomposition of an <span class="docutils literal">f</span> as
+a product <span class="docutils literal">c f_1 f_2 f_3 ...</span> of a constant and square-free (primitive)
+polynomials, where each <span class="docutils literal">f_i</span> divides its predecessor.</p>
+</div>
+</blockquote>
+</div>
+<div class="section" id="polsettosturmchainsignchangesat-macro-sturmname-fraction">
+<span id="polsettosturmchainsignchangesat"></span><h3><a class="toc-backref" href="#id114"><span class="docutils literal"><span class="pre">\PolSetToSturmChainSignChangesAt{\macro}{sturmname}{fraction}</span></span></a></h3>
+<blockquote>
+<p>Sets macro <span class="docutils literal">\macro</span> to the number of sign changes in the Sturm
+chain with name prefix <span class="docutils literal">sturmname</span>, at location <span class="docutils literal">fraction</span>
+(which must be in format as acceptable by the <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> macros.)</p>
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p>The author was lazy and did not provide rather an expandable
+variant, where one would do <span class="docutils literal"><span class="pre">\edef\macro{\PolNbOf...}</span></span>.</p>
+<p>This will presumably get added in a future release.</p>
+<p>After some hesitation it was decided the macro would by default
+act globally. To make the scope of its macro definition local,
+use <span class="docutils literal">[\empty]</span> as extra optional argument.</p>
+</div>
+</blockquote>
+</div>
+<div class="section" id="polsettonbofzeroswithin-macro-sturmname-value-a-value-b">
+<span id="polsettonbofzeroswithin"></span><h3><a class="toc-backref" href="#id115"><span class="docutils literal"><span class="pre">\PolSetToNbOfZerosWithin{\macro}{sturmname}{value_a}{value_b}</span></span></a></h3>
+<blockquote>
+<p>Applies the <a class="reference external" href="https://en.wikipedia.org/wiki/Sturm%27s_theorem">Sturm Theorem</a> to set <span class="docutils literal">\macro</span> to the exact number
+of <strong>distinct</strong> roots of <span class="docutils literal">sturmname_0</span> in the interval <span class="docutils literal">(value_a, value_b]</span> (the macro first re-orders the value for <span class="docutils literal">value_a &lt;= value_b</span> to hold).</p>
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p>The author was lazy and did not provide rather an expandable
+variant, where one would do <span class="docutils literal"><span class="pre">\edef\macro{\PolNbOf...}</span></span>.</p>
+<p>This will presumably get added in future.</p>
+<p>After some hesitation it was decided the macro would by default
+act globally. To make the scope of its macro definition local,
+use <span class="docutils literal">[\empty]</span> as extra optional argument.</p>
+</div>
+<p>See also the expandable
+<a class="reference internal" href="#polsturmnbofrootsof-sturmname-lessthanorequalto-value">\PolSturmNbOfRootsOf{sturmname}\LessThanOrEqualTo{value}</a>, from
+which it is immediate (with <span class="docutils literal">\numexpr</span>) to create an expandable
+variant of this macro. However the difference is that this macro
+requires only <a class="reference internal" href="#poltosturm">\PolToSturm</a> to have been executed,
+whereas the expandable variant requires prior execution of
+<a class="reference internal" href="#polsturmisolatezeros">\PolSturmIsolateZeros</a>.</p>
+<p>See also the expandable
+<a class="reference internal" href="#polsturmnbwithmultofrootsof-sturmname-lessthanorequalto-value">\PolSturmNbWithMultOfRootsOf{sturmname}\LessThanOrEqualTo{value}</a>
+which requires prior execution of
+<a class="reference internal" href="#id14">\PolSturmIsolateZeros*</a>.</p>
+</blockquote>
+</div>
+<div class="section" id="polsturmisolatezeros-sturmname">
+<span id="polsturmisolatezeros"></span><h3><a class="toc-backref" href="#id116"><span class="docutils literal">\PolSturmIsolateZeros{sturmname}</span></a></h3>
+<blockquote>
+<p>The macros locates, using <a class="reference external" href="https://en.wikipedia.org/wiki/Sturm%27s_theorem">Sturm theorem</a>, as many disjoint
+intervals as there are (real) roots.</p>
+<div class="admonition important">
+<p class="admonition-title">Important</p>
+<p>The Sturm chain must have been produced by an earlier
+<a class="reference internal" href="#poltosturm-polname-sturmname">\PolToSturm{polname}{sturmname}</a>.</p>
+<p>Why does this macro ask for argument the name of Sturm chain,
+rather than the name of a polynomial? well this is mainly for
+legacy reason, and because it is accompanied by other macros for
+which it is simpler to assume the argument will be the name of an
+already computed Sturm chain.</p>
+<p>Notice that <span class="docutils literal"><span class="pre">\PolToSturm{f}{f}</span></span> is perfectly legal (the
+<span class="docutils literal">sturmname</span> can be same as the <span class="docutils literal">polname</span>): it defines
+polynomials <span class="docutils literal">f_0</span>, <span class="docutils literal">f_1</span>, ... having <span class="docutils literal">f</span> has name prefix.</p>
+<p>Such a prior call
+to <span class="docutils literal">\PolToSturm</span> must have been made at any rate for
+<span class="docutils literal">\PolSturmIsolateZeros</span> to be usable.</p>
+</div>
+<p>After its execution they are two types of such intervals (stored in
+memory and accessible via macros or <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> variables, see below):</p>
+<ul class="simple">
+<li><p>singleton <span class="docutils literal">{a}</span>: then <span class="docutils literal">a</span> is a root, (necessarily a decimal
+number, but not all such decimal numbers are exactly identified yet).</p></li>
+<li><p>open intervals <span class="docutils literal">(a,b)</span>: then there is exactly one root <span class="docutils literal">z</span>
+such that <span class="docutils literal">a &lt; z &lt; b</span>, and the end points are guaranteed to not
+be roots.</p></li>
+</ul>
+<p>The interval boundaries are decimal numbers, originating
+in iterated decimal subdivision from initial intervals
+<span class="docutils literal"><span class="pre">(-10^E,</span> 0)</span> and <span class="docutils literal">(0, 10^E)</span> with <span class="docutils literal">E</span> chosen initially large
+enough so that all roots are enclosed; if zero is a root it is always
+identified as such. The non-singleton intervals are of the
+type <span class="docutils literal">(a/10^f, <span class="pre">(a+1)/10^f)</span></span> with <span class="docutils literal">a</span> an integer, which is
+neither <span class="docutils literal">0</span> nor <span class="docutils literal"><span class="pre">-1</span></span>. Hence either <span class="docutils literal">a</span> and <span class="docutils literal">a+1</span> are both positive
+or they are both negative.</p>
+<p>One does not <em>a priori</em> know what will be the lengths of these
+intervals (except that they are always powers of ten), they
+vary depending on how many digits two successive roots have in
+common in their respective decimal expansions.</p>
+<div class="admonition important">
+<p class="admonition-title">Important</p>
+<p>If some two consecutive intervals share an end-point, no
+information is yet gained about the separation between the two
+roots which could at this stage be arbitrarily small.</p>
+<p>See <a class="reference internal" href="#polrefineinterval-sturmname-index">\PolRefineInterval*{sturmname}{index}</a> which addresses
+this issue.</p>
+</div>
+<p>The interval boundaries (and exactly found roots) are made available
+for future computations in <span class="docutils literal">\xintexpr</span>-essions or polynomial
+definitions as variables <span class="docutils literal">&lt;sturmname&gt;L_1</span>,
+<span class="docutils literal">&lt;sturmname&gt;L_2</span>, etc..., for the left end-points and
+<span class="docutils literal">&lt;sturmname&gt;R_1</span>, <span class="docutils literal">&lt;sturmname&gt;R_2</span>, ..., for the right
+end-points.</p>
+<p>Thus for example, if <span class="docutils literal">sturmname</span> is <span class="docutils literal">f</span>, one can use the
+<a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> variables <span class="docutils literal">fL_1</span>, <span class="docutils literal">fL_2</span>, ... to refer in expressions
+to the left end-points (or to the exact root, if left and right end
+points coincide). Additionally, <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> variable <span class="docutils literal">fZ_1_isknown</span>
+will have value <span class="docutils literal">1</span> if the root in the first interval is known,
+and <span class="docutils literal">0</span> otherwise. And similarly for the other intervals.</p>
+<p>Also, macros <a class="reference internal" href="#polsturmisolatedzeroleft-sturmname-index">\PolSturmIsolatedZeroLeft{sturmname}{index}</a> and
+<a class="reference internal" href="#polsturmisolatedzeroright-sturmname-index">\PolSturmIsolatedZeroRight{sturmname}{index}</a> are provided which
+expand to these same values, written in decimal notation (i.e.
+pre-processed by <a class="reference internal" href="#poldectostring">\PolDecToString</a>.) And there
+is also <a class="reference internal" href="#polsturmifzeroexactlyknown-sturmname-index-a-b">\PolSturmIfZeroExactlyKnown{sturmname}{index}{A}{B}</a>.</p>
+<div class="admonition important">
+<p class="admonition-title">Important</p>
+<p>Trailing zeroes in the stored decimal numbers accessible via the
+macros are significant: they are also present in the decimal
+expansion of the exact root.</p>
+</div>
+<p>These variables and macros are automatically updated when one next
+uses macros such as <a class="reference internal" href="#polrefineinterval-sturmname-index">\PolRefineInterval*{sturmname}{index}</a>.</p>
+<p>The start of decimal expansion of a positive <span class="docutils literal">k</span>-th root is given
+by <a class="reference internal" href="#polsturmisolatedzeroleft">\PolSturmIsolatedZeroLeft{sturmname}{k}</a>, and for a negative root it is given
+by <a class="reference internal" href="#polsturmisolatedzeroright">PolSturmIsolatedZeroRight{sturmname}{k}</a>. These two decimal
+numbers are either both zero or both of the same sign.</p>
+<p>The number of distinct roots is obtainable expandably as
+<a class="reference internal" href="#polsturmnbofisolatedzeros-sturmname">\PolSturmNbOfIsolatedZeros{sturmname}</a>.</p>
+<p>Furthermore
+<a class="reference internal" href="#polsturmnbofrootsof-sturmname-lessthanorequalto-value">\PolSturmNbOfRootsOf{sturmname}\LessThanOrEqualTo{value}</a> and
+<a class="reference internal" href="#polsturmnbofrootsof-sturmname-lessthanorequaltoexpr-expression">\PolSturmNbOfRootsOf{sturmname}\LessThanOrEqualToExpr{expression}</a>.
+will expandably compute respectively the number of real roots at
+most equal to <span class="docutils literal">value</span> or <span class="docutils literal">expression</span>, and the same but with
+multiplicities.</p>
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p>The current polexpr implementation defines the <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> variables
+and <a class="reference external" href="http://www.ctan.org/pkg/xint">xinttools</a> arrays described above with <strong>global scpe</strong>. On the
+other hand the Sturm sequence polynomials do obey the current scope.</p>
+</div>
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p>As all computations are done <em>exactly</em> there can be no errors...
+apart those due to bad coding by author. The results are exact
+bounds for the mathematically exact real roots.</p>
+<p>Future releases will perhaps also provide macros based on Newton
+or Regula Falsi methods. Exact computations with such methods
+lead however quickly to very big fractions, and this forces usage
+of some rounding scheme for the abscissas if computation times
+are to remain reasonable. This raises issues of its own, which
+are studied in numerical mathematics.</p>
+</div>
+</blockquote>
+</div>
+<div class="section" id="id15">
+<span id="id14"></span><h3><a class="toc-backref" href="#id117"><span class="docutils literal"><span class="pre">\PolSturmIsolateZeros*{sturmname}</span></span></a></h3>
+<blockquote>
+<p>The macro does the same as <a class="reference internal" href="#polsturmisolatezeros-sturmname">\PolSturmIsolateZeros{sturmname}</a> and
+then in addition it does the extra work to determine all
+multiplicities (of the real roots):
+after executing this macro,
+<a class="reference internal" href="#polsturmisolatedzeromultiplicity-sturmname-index">\PolSturmIsolatedZeroMultiplicity{sturmname}{index}</a> will expand
+to the multiplicity of the root located in the <span class="docutils literal">index</span>-th
+interval (intervals are enumerated from left to right, with index
+starting at <span class="docutils literal">1</span>).</p>
+<p>Furthermore, if for example the <span class="docutils literal">sturmname</span> is <span class="docutils literal">f</span>, <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a>
+variables <span class="docutils literal">fM_1</span>, <span class="docutils literal">fM_2</span>... hold the multiplicities thus
+computed.</p>
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p>It is <strong>not</strong> necessary to have executed the <a class="reference internal" href="#id12">PolToSturm*</a> starred
+variant, as the non-starred variant keeps internally the memory of the
+original GCD (and even of the full non-normalized original Sturm
+chain), even though it does not make the declarations as <em>user-level</em>
+genuine polynomials.</p>
+</div>
+<p>See <a class="reference internal" href="#the-degree-nine-polynomial-with-0-99-0-999-0-9999-as-triple-roots">The degree nine polynomial with 0.99, 0.999, 0.9999 as triple
+roots</a> for an example.</p>
+</blockquote>
+</div>
+<div class="section" id="id17">
+<span id="id16"></span><h3><a class="toc-backref" href="#id118"><span class="docutils literal"><span class="pre">\PolSturmIsolateZeros**{sturmname}</span></span></a></h3>
+<blockquote>
+<p>The macro does the same as <a class="reference internal" href="#id15">\PolSturmIsolateZeros*{sturmname}</a> and
+in addition it does the extra work to determine all the <em>rational</em>
+roots.</p>
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p>After execution of this macro, a root is &quot;known&quot; if and only if
+it is rational.</p>
+</div>
+<p>Furthermore, primitive polynomial <span class="docutils literal">sturmname_sqf_norr</span> is created
+to match the (square-free) <span class="docutils literal">sturmname_0</span> from which all rational
+roots have been removed (see <a class="reference internal" href="#polexprsetup">\polexprsetup</a> for customizing this
+name). The number of distinct rational roots is thus the difference
+between the degrees of these two polynomials (see also
+<a class="reference internal" href="#polsturmnbofrationalroots-sturmname">\PolSturmNbOfRationalRoots{sturmname}</a>).</p>
+<p>And <span class="docutils literal">sturmname_norr</span> is <span class="docutils literal">sturmname_0_</span> from which all rational
+roots have been removed (see <a class="reference internal" href="#polexprsetup">\polexprsetup</a>), i.e. it contains
+the irrational roots of the original polynomial, with the same
+multiplicities.</p>
+<p>See <a class="reference internal" href="#a-degree-five-polynomial-with-three-rational-roots">A degree five polynomial with three rational
+roots</a> for an example.</p>
+</blockquote>
+</div>
+<div class="section" id="polsturmisolatezerosandgetmultiplicities-sturmname">
+<span id="polsturmisolatezerosandgetmultiplicities"></span><h3><a class="toc-backref" href="#id119"><span class="docutils literal">\PolSturmIsolateZerosAndGetMultiplicities{sturmname}</span></a></h3>
+<blockquote>
+<p>This is another name for <a class="reference internal" href="#id15">\PolSturmIsolateZeros*{sturmname}</a>.</p>
+</blockquote>
+</div>
+<div class="section" id="polsturmisolatezerosgetmultiplicitiesandrationalroots-sturmname">
+<span id="polsturmisolatezerosgetmultiplicitiesandrationalroots"></span><h3><a class="toc-backref" href="#id120"><span class="docutils literal">\PolSturmIsolateZerosGetMultiplicitiesAndRationalRoots{sturmname}</span></a></h3>
+<blockquote>
+<p>This is another name for <a class="reference internal" href="#id17">\PolSturmIsolateZeros**{sturmname}</a>.</p>
+</blockquote>
+</div>
+<div class="section" id="polsturmisolatezerosandfindrationalroots-sturmname">
+<h3><a class="toc-backref" href="#id121"><span class="docutils literal">\PolSturmIsolateZerosAndFindRationalRoots{sturmname}</span></a></h3>
+<blockquote>
+<p>This works exactly like <a class="reference internal" href="#id17">\PolSturmIsolateZeros**{sturmname}</a>
+(inclusive of declaring the polynomials <span class="docutils literal">sturmname_sqf_norr</span> and
+<span class="docutils literal">sturmname_norr</span> with no rational roots) except that it does <em>not</em>
+compute the multiplicities of the <em>non-rational</em> roots.</p>
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p>There is no macro to find the rational roots but not compute
+their multiplicities at the same time.</p>
+</div>
+<div class="admonition attention">
+<p class="admonition-title">Attention!</p>
+<p>This macro does <em>not</em> define <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> variables
+<span class="docutils literal">sturmnameM_1</span>, <span class="docutils literal">sturmnameM_2</span>, ... holding the
+multiplicities and it leaves the multiplicity array (whose accessor
+is <a class="reference internal" href="#polsturmisolatedzeromultiplicity-sturmname-index">\PolSturmIsolatedZeroMultiplicity{sturmname}{index}</a>) into
+a broken state, as all non-rational roots will supposedly have
+multiplicity one. This means that the output of
+<a class="reference internal" href="#id21">\PolPrintIntervals*</a> for example will be
+erroneous for the intervals with irrational roots.</p>
+<p>I decided to document it because finding multiplicities of the
+non rational roots is somewhat costly, and one may be interested
+only into finding the rational roots (of course random
+polynomials with integer coefficients will not have <em>any</em>
+rational root anyhow).</p>
+</div>
+</blockquote>
+</div>
+<div class="section" id="polrefineinterval-sturmname-index">
+<span id="polrefineinterval"></span><h3><a class="toc-backref" href="#id122"><span class="docutils literal"><span class="pre">\PolRefineInterval*{sturmname}{index}</span></span></a></h3>
+<blockquote>
+<p>The <span class="docutils literal">index</span>-th interval (starting indexing at one) is further
+subdivided as many times as is necessary in order for the newer
+interval to have both its end-points distinct from the end-points of
+the original interval. This means that the <span class="docutils literal">k</span>th root is then
+strictly separated from the other roots.</p>
+</blockquote>
+</div>
+<div class="section" id="polrefineinterval-n-sturmname-index">
+<span id="polrefineinterval-n"></span><h3><a class="toc-backref" href="#id123"><span class="docutils literal"><span class="pre">\PolRefineInterval[N]{sturmname}{index}</span></span></a></h3>
+<blockquote>
+<p>The <span class="docutils literal">index</span>-th interval (starting count at one) is further
+subdivided once, reducing its length by a factor of 10. This is done
+<span class="docutils literal">N</span> times if the optional argument <span class="docutils literal">[N]</span> is present.</p>
+</blockquote>
+</div>
+<div class="section" id="polensureintervallength-sturmname-index-e">
+<span id="polensureintervallength"></span><h3><a class="toc-backref" href="#id124"><span class="docutils literal"><span class="pre">\PolEnsureIntervalLength{sturmname}{index}{E}</span></span></a></h3>
+<blockquote>
+<p>The <span class="docutils literal">index</span>-th interval is subdivided until its length becomes at
+most <span class="docutils literal">10^E</span>. This means (for <span class="docutils literal">E&lt;0</span>) that the first <span class="docutils literal"><span class="pre">-E</span></span> digits
+after decimal mark of the <span class="docutils literal">k</span>th root will then be known exactly.</p>
+</blockquote>
+</div>
+<div class="section" id="polensureintervallengths-sturmname-e">
+<span id="polensureintervallengths"></span><h3><a class="toc-backref" href="#id125"><span class="docutils literal"><span class="pre">\PolEnsureIntervalLengths{sturmname}{E}</span></span></a></h3>
+<blockquote>
+<p>The intervals as obtained from <span class="docutils literal">\PolSturmIsolateZeros</span> are (if
+necessary) subdivided further by (base 10) dichotomy in order for
+each of them to have length at most <span class="docutils literal">10^E</span> (length will be shorter
+than <span class="docutils literal">10^E</span> in output only if it did not change or became zero.)</p>
+<p>This means that decimal expansions of all roots will be known with
+<span class="docutils literal"><span class="pre">-E</span></span> digits (for <span class="docutils literal">E&lt;0</span>) after decimal mark.</p>
+</blockquote>
+</div>
+<div class="section" id="polprintintervals-varname-sturmname">
+<span id="polprintintervals"></span><h3><a class="toc-backref" href="#id126"><span class="docutils literal"><span class="pre">\PolPrintIntervals[varname]{sturmname}</span></span></a></h3>
+<blockquote>
+<p>This is a convenience macro which prints the bounds for the roots
+<span class="docutils literal">Z_1</span>, <span class="docutils literal">Z_2</span>, ... (the optional argument <span class="docutils literal">varname</span> allows to
+specify a replacement for the default <span class="docutils literal">Z</span>). This will be done (by
+default) in a
+math mode <span class="docutils literal">array</span>, one interval per row, and pattern <span class="docutils literal">rcccl</span>,
+where the second and fourth column hold the <span class="docutils literal">&lt;</span> sign, except when
+the interval reduces to a singleton, which means the root is known
+exactly.</p>
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p>The explanations here and in this section are for LaTeX. With
+other TeX macro formats, the LaTeX syntax such as for example
+<span class="docutils literal"><span class="pre">\begin{array}{rcccl}</span></span> which appears in the documentation here
+is actually replaced with quasi-equivalent direct use of TeX
+primitives.</p>
+</div>
+<p>See next macros which govern its output.</p>
+</blockquote>
+<div class="section" id="polprintintervalsnorealroots">
+<h4><a class="toc-backref" href="#id127"><span class="docutils literal">\PolPrintIntervalsNoRealRoots</span></a></h4>
+<blockquote>
+<p>Executed in place of an <span class="docutils literal">array</span> environment, when there are no
+real roots. Default definition:</p>
+<pre class="literal-block">\newcommand\PolPrintIntervalsNoRealRoots{}</pre>
+</blockquote>
+</div>
+<div class="section" id="polprintintervalsbeginenv">
+<h4><a class="toc-backref" href="#id128"><span class="docutils literal">\PolPrintIntervalsBeginEnv</span></a></h4>
+<blockquote>
+<p>Default definition:</p>
+<pre class="literal-block">\newcommand\PolPrintIntervalsBeginEnv{\[\begin{array}{rcccl}}</pre>
+</blockquote>
+</div>
+<div class="section" id="polprintintervalsendenv">
+<h4><a class="toc-backref" href="#id129"><span class="docutils literal">\PolPrintIntervalsEndEnv</span></a></h4>
+<blockquote>
+<p>Default definition:</p>
+<pre class="literal-block">\newcommand\PolPrintIntervalsEndEnv{\end{array}\]}</pre>
+</blockquote>
+</div>
+<div class="section" id="polprintintervalsknownroot">
+<h4><a class="toc-backref" href="#id130"><span class="docutils literal">\PolPrintIntervalsKnownRoot</span></a></h4>
+<blockquote>
+<p>Default definition:</p>
+<pre class="literal-block">\newcommand\PolPrintIntervalsKnownRoot{%
+ &amp;&amp;\PolPrintIntervalsTheVar_{\PolPrintIntervalsTheIndex}%
+ &amp;=&amp;\PolPrintIntervalsPrintExactZero
+}</pre>
+</blockquote>
+</div>
+<div class="section" id="polprintintervalsunknownroot">
+<h4><a class="toc-backref" href="#id131"><span class="docutils literal">\PolPrintIntervalsUnknownRoot</span></a></h4>
+<blockquote>
+<p>Default definition:</p>
+<pre class="literal-block">\newcommand\PolPrintIntervalsUnknownRoot{%
+ \PolPrintIntervalsPrintLeftEndPoint&amp;&lt;&amp;%
+ \PolPrintIntervalsTheVar_{\PolPrintIntervalsTheIndex}&amp;&lt;&amp;%
+ \PolPrintIntervalsPrintRightEndPoint
+}</pre>
+</blockquote>
+</div>
+<div class="section" id="id18">
+<span id="polprintintervalsprintexactzero"></span><h4><a class="toc-backref" href="#id132"><span class="docutils literal">\PolPrintIntervalsPrintExactZero</span></a></h4>
+<blockquote>
+<p>Default definition:</p>
+<pre class="literal-block">\newcommand\PolPrintIntervalsPrintExactZero{\PolPrintIntervalsTheLeftEndPoint}</pre>
+</blockquote>
+</div>
+<div class="section" id="id19">
+<span id="polprintintervalsprintleftendpoint"></span><h4><a class="toc-backref" href="#id133"><span class="docutils literal">\PolPrintIntervalsPrintLeftEndPoint</span></a></h4>
+<blockquote>
+<p>Default definition:</p>
+<pre class="literal-block">\newcommand\PolPrintIntervalsPrintLeftEndPoint{\PolPrintIntervalsTheLeftEndPoint}</pre>
+</blockquote>
+</div>
+<div class="section" id="id20">
+<span id="polprintintervalsprintrightendpoint"></span><h4><a class="toc-backref" href="#id134"><span class="docutils literal">\PolPrintIntervalsPrintRightEndPoint</span></a></h4>
+<blockquote>
+<p>Default definition is:</p>
+<pre class="literal-block">\newcommand\PolPrintIntervalsPrintRightEndPoint{\PolPrintIntervalsTheRightEndPoint}</pre>
+</blockquote>
+</div>
+</div>
+<div class="section" id="id22">
+<span id="id21"></span><h3><a class="toc-backref" href="#id135"><span class="docutils literal"><span class="pre">\PolPrintIntervals*[varname]{sturmname}</span></span></a></h3>
+<blockquote>
+<p>This starred variant produces an alternative output (which
+displays the root multiplicity), and is provided as an
+example of customization.</p>
+<p>As replacement for <a class="reference internal" href="#polprintintervalsknownroot">\PolPrintIntervalsKnownRoot</a>,
+<a class="reference internal" href="#polprintintervalsprintexactzero">\PolPrintIntervalsPrintExactZero</a>,
+<a class="reference internal" href="#polprintintervalsunknownroot">\PolPrintIntervalsUnknownRoot</a> it uses its own
+<span class="docutils literal"><span class="pre">\POL&#64;&#64;PrintIntervals...</span></span> macros. We only reproduce here one
+definition:</p>
+<pre class="literal-block">\newcommand\POL&#64;&#64;PrintIntervalsPrintExactZero{%
+ \displaystyle
+ \xintSignedFrac{\PolPrintIntervalsTheLeftEndPoint}%
+}%</pre>
+<p>Multiplicities are printed using this auxiliary macro:</p>
+</blockquote>
+<div class="section" id="polprintintervalsprintmultiplicity">
+<h4><a class="toc-backref" href="#id136"><span class="docutils literal">\PolPrintIntervalsPrintMultiplicity</span></a></h4>
+<blockquote>
+<p>whose default definition is:</p>
+<pre class="literal-block">\newcommand\PolPrintIntervalsPrintMultiplicity{(\mbox{mult. }\PolPrintIntervalsTheMultiplicity)}</pre>
+</blockquote>
+</div>
+</div>
+</div>
+<div class="section" id="polmapcoeffs-macro-polname">
+<span id="polmapcoeffs"></span><h2><a class="toc-backref" href="#id137"><span class="docutils literal"><span class="pre">\PolMapCoeffs{\macro}{polname}</span></span></a></h2>
+<blockquote>
+<p>It modifies ('in-place': original coefficients get lost) each
+coefficient of the defined polynomial via the <em>expandable</em> macro
+<span class="docutils literal">\macro</span>. The degree is adjusted as necessary if some leading
+coefficients vanish after the operation. In replacement text of
+<span class="docutils literal">\macro</span>, <span class="docutils literal">\index</span> expands to the coefficient index (which is
+defined to be zero for the constant term).</p>
+<p>Notice that <span class="docutils literal">\macro</span> will have to handle inputs of the shape
+<span class="docutils literal">A/B[N]</span> (<a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> internal notation). This means that it probably
+will have to be expressed in terms of macros from <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> package.</p>
+<p>Example:</p>
+<pre class="literal-block">\def\foo#1{\xintMul{#1}{\the\numexpr\index*\index\relax}}</pre>
+<p>(or with <span class="docutils literal"><span class="pre">\xintSqr{\index}</span></span>) to replace <span class="docutils literal">n</span>-th coefficient
+<span class="docutils literal">f_n</span> by <span class="docutils literal">f_n*n^2</span>.</p>
+</blockquote>
+</div>
+<div class="section" id="polreducecoeffs-polname">
+<span id="polreducecoeffs"></span><h2><a class="toc-backref" href="#id138"><span class="docutils literal">\PolReduceCoeffs{polname}</span></a></h2>
+<blockquote>
+<p>About the same as <span class="docutils literal"><span class="pre">\PolMapCoeffs{\xintIrr}{polname}</span></span> (but
+maintaining a <span class="docutils literal">[0]</span> postfix for speedier <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> parsing when
+polynomial function is used for computations.) This is a
+one-argument macro, working 'in-place'.</p>
+</blockquote>
+</div>
+<div class="section" id="id24">
+<span id="id23"></span><h2><a class="toc-backref" href="#id139"><span class="docutils literal"><span class="pre">\PolReduceCoeffs*{polname}</span></span></a></h2>
+<blockquote>
+<p>This starred variant leaves un-touched the decimal exponent in the
+internal representation of the fractional coefficients, i.e. if a
+coefficient is internally <span class="docutils literal">A/B[N]</span>, then <span class="docutils literal">A/B</span> is reduced to
+smallest terms, but the <span class="docutils literal">10^N</span> part is kept as is. Note: if the
+polynomial is freshly defined directly via <a class="reference internal" href="#polfromcsv">\PolFromCSV</a> its coefficients might still be internally in some
+format like <span class="docutils literal">1.5e7</span>; the macro will anyhow always first do the
+needed conversion to strict format <span class="docutils literal">A/B[N]</span>.</p>
+<p>Evaluations with polynomials treated by this can be much faster than
+with those handled by the non-starred variant
+<a class="reference internal" href="#polreducecoeffs-polname">\PolReduceCoeffs{polname}</a>: as the numerators and denominators
+remain smaller, this proves very beneficial in favorable cases
+(especially when the coefficients are decimal numbers) to the
+expansion speed of the <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> macros used internally by
+<a class="reference internal" href="#polevalat">\PolEval</a>.</p>
+</blockquote>
+</div>
+<div class="section" id="polmakemonic-polname">
+<span id="polmakemonic"></span><h2><a class="toc-backref" href="#id140"><span class="docutils literal">\PolMakeMonic{polname}</span></a></h2>
+<blockquote>
+<p>Divides by the leading coefficient. It is recommended to execute
+<a class="reference internal" href="#id24">\PolReduceCoeffs*{polname}</a> immediately afterwards. This is not
+done automatically, due to the case the original polynomial had integer
+coefficients and we want to keep the leading one as common
+denominator.</p>
+</blockquote>
+</div>
+<div class="section" id="polmakeprimitive-polname">
+<span id="polmakeprimitive"></span><h2><a class="toc-backref" href="#id141"><span class="docutils literal">\PolMakePrimitive{polname}</span></a></h2>
+<blockquote>
+<p>Divides by the integer content see (<a class="reference internal" href="#policontent">\PolIContent</a>). This thus produces a polynomial with integer
+coefficients having no common factor. The sign of the leading
+coefficient is not modified.</p>
+</blockquote>
+</div>
+</div>
+<div class="section" id="expandable-macros">
+<h1><a class="toc-backref" href="#id142">Expandable macros</a></h1>
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p>At <span class="docutils literal">0.8</span> <span class="docutils literal">polexpr</span> is usable with Plain TeX and not only with
+LaTeX. Some examples given in this section may be using LaTeX syntax
+such as <span class="docutils literal">\renewcommand</span>. Convert to TeX primitives as appropriate
+if testing with a non LaTeX macro format.</p>
+</div>
+<p>All these macros expand completely in two steps except <span class="docutils literal">\PolToExpr</span>
+and <span class="docutils literal">\PolToFloatExpr</span> (and their auxiliaries) which need a
+<span class="docutils literal">\write</span>, <span class="docutils literal">\edef</span> or a <span class="docutils literal"><span class="pre">\csname...\endcsname</span></span> context.</p>
+<div class="section" id="poleval-polname-atexpr-numerical-expression">
+<span id="polevalatexpr"></span><h2><a class="toc-backref" href="#id143"><span class="docutils literal"><span class="pre">\PolEval{polname}\AtExpr{numerical</span> expression}</span></a></h2>
+<blockquote>
+<p>It boils down to
+<span class="docutils literal">\xinttheexpr polname(numerical <span class="pre">expression)\relax</span></span>.</p>
+</blockquote>
+</div>
+<div class="section" id="poleval-polname-at-fraction">
+<span id="polevalat"></span><h2><a class="toc-backref" href="#id144"><span class="docutils literal"><span class="pre">\PolEval{polname}\At{fraction}</span></span></a></h2>
+<blockquote>
+<p>Evaluates the polynomial at value <span class="docutils literal">fraction</span> which must be in (or
+expand to) a format acceptable to the <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> macros.</p>
+</blockquote>
+</div>
+<div class="section" id="polevalreduced-polname-atexpr-numerical-expression">
+<span id="polevalreducedatexpr"></span><h2><a class="toc-backref" href="#id145"><span class="docutils literal"><span class="pre">\PolEvalReduced{polname}\AtExpr{numerical</span> expression}</span></a></h2>
+<blockquote>
+<p>Boils down to <span class="docutils literal">\xinttheexpr reduce(polname(numerical <span class="pre">expression))\relax</span></span>.</p>
+</blockquote>
+</div>
+<div class="section" id="polevalreduced-polname-at-fraction">
+<span id="polevalreducedat"></span><h2><a class="toc-backref" href="#id146"><span class="docutils literal"><span class="pre">\PolEvalReduced{polname}\At{fraction}</span></span></a></h2>
+<blockquote>
+<p>Evaluates the polynomial at value <span class="docutils literal">fraction</span> which must be in (or
+expand to) a format acceptable to the <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> macros, and produce
+an irreducible fraction.</p>
+</blockquote>
+</div>
+<div class="section" id="polfloateval-polname-atexpr-numerical-expression">
+<span id="polfloatevalatexpr"></span><h2><a class="toc-backref" href="#id147"><span class="docutils literal"><span class="pre">\PolFloatEval{polname}\AtExpr{numerical</span> expression}</span></a></h2>
+<blockquote>
+<p>Boils down to <span class="docutils literal">\xintthefloatexpr polname(numerical <span class="pre">expression)\relax</span></span>.</p>
+<p>This is done via a Horner Scheme (see <a class="reference internal" href="#poldef">\poldef</a> and
+<a class="reference internal" href="#polgenfloatvariant-polname">\PolGenFloatVariant{polname}</a>), with already rounded
+coefficients. <a class="footnote-reference brackets" href="#id27" id="id25">4</a> To use the <em>exact coefficients</em> with <em>exactly
+executed</em> additions and multiplications, just insert it in the float
+expression as in this example: <a class="footnote-reference brackets" href="#id28" id="id26">5</a></p>
+<pre class="literal-block">\xintthefloatexpr 3.27*\xintexpr f(2.53)\relax^2\relax</pre>
+<p>The <span class="docutils literal">f(2.53)</span> is exactly computed then rounded at the time of
+getting raised to the power <span class="docutils literal">2</span>. Moving the <span class="docutils literal">^2</span> inside, that
+operation would also be treated exactly.</p>
+<dl class="footnote brackets">
+<dt class="label" id="id27"><span class="brackets"><a class="fn-backref" href="#id25">4</a></span></dt>
+<dd><p>Anyway each floating point operation starts by rounding its
+operands to the floating point precision.</p>
+</dd>
+<dt class="label" id="id28"><span class="brackets"><a class="fn-backref" href="#id26">5</a></span></dt>
+<dd><p>The <span class="docutils literal">\xintexpr</span> here could be <span class="docutils literal">\xinttheexpr</span> but that
+would be less efficient. Cf. <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> documentation about
+nested expressions.</p>
+</dd>
+</dl>
+</blockquote>
+</div>
+<div class="section" id="polfloateval-polname-at-fraction">
+<span id="polfloatevalat"></span><h2><a class="toc-backref" href="#id148"><span class="docutils literal"><span class="pre">\PolFloatEval{polname}\At{fraction}</span></span></a></h2>
+<blockquote>
+<p>Evaluates the polynomial at value <span class="docutils literal">fraction</span> which must be in (or
+expand to) a format acceptable to the <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> macros, and produces
+a floating point number.</p>
+</blockquote>
+</div>
+<div class="section" id="polifcoeffisplusorminusone-a-b">
+<span id="polifcoeffisplusorminusone"></span><h2><a class="toc-backref" href="#id149"><span class="docutils literal"><span class="pre">\PolIfCoeffIsPlusOrMinusOne{A}{B}</span></span></a></h2>
+<blockquote>
+<p>This macro is a priori undefined.</p>
+<p>It is defined via the default <a class="reference internal" href="#poltypesetcmd-raw-coeff">\PolTypesetCmd{raw_coeff}</a> to be
+used if needed in the execution of <a class="reference internal" href="#poltypesetmonomialcmd">\PolTypesetMonomialCmd</a>,
+e.g. to insert a <span class="docutils literal">\cdot</span> in front of <span class="docutils literal"><span class="pre">\PolVar^{\PolIndex}</span></span> if
+the coefficient is not plus or minus one.</p>
+<p>The macro will execute <span class="docutils literal">A</span> if the coefficient has been found to be
+plus or minus one, and <span class="docutils literal">B</span> if not.</p>
+</blockquote>
+</div>
+<div class="section" id="polleadingcoeff-polname">
+<span id="polleadingcoeff"></span><h2><a class="toc-backref" href="#id150"><span class="docutils literal">\PolLeadingCoeff{polname}</span></a></h2>
+<blockquote>
+<p>Expands to the leading coefficient.</p>
+</blockquote>
+</div>
+<div class="section" id="polnthcoeff-polname-number">
+<span id="polnthcoeff"></span><h2><a class="toc-backref" href="#id151"><span class="docutils literal"><span class="pre">\PolNthCoeff{polname}{number}</span></span></a></h2>
+<blockquote>
+<p>It expands to the raw <span class="docutils literal">N</span>-th coefficient (<span class="docutils literal">0/1[0]</span> if the index
+number is out of range). With <span class="docutils literal"><span class="pre">N=-1</span></span>, <span class="docutils literal"><span class="pre">-2</span></span>, ... expands to the
+leading coefficients.</p>
+</blockquote>
+</div>
+<div class="section" id="poldegree-polname">
+<span id="poldegree"></span><h2><a class="toc-backref" href="#id152"><span class="docutils literal">\PolDegree{polname}</span></a></h2>
+<blockquote>
+<p>It expands to the degree. This is <span class="docutils literal"><span class="pre">-1</span></span> if zero polynomial but this
+may change in future. Should it then expand to <span class="docutils literal"><span class="pre">-\infty</span></span> ?</p>
+</blockquote>
+</div>
+<div class="section" id="policontent-polname">
+<span id="policontent"></span><h2><a class="toc-backref" href="#id153"><span class="docutils literal">\PolIContent{polname}</span></a></h2>
+<blockquote>
+<p>It expands to the contents of the polynomial, i.e. to the positive
+fraction such that dividing by this fraction produces a polynomial
+with integer coefficients having no common prime divisor.</p>
+<p>See <a class="reference internal" href="#polmakeprimitive">\PolMakePrimitive</a>.</p>
+</blockquote>
+</div>
+<div class="section" id="poltoexpr-pol-expr">
+<span id="poltoexpr"></span><h2><a class="toc-backref" href="#id154"><span class="docutils literal"><span class="pre">\PolToExpr{&lt;pol.</span> <span class="pre">expr.&gt;}</span></span></a></h2>
+<blockquote>
+<p>Produces expandably <a class="footnote-reference brackets" href="#id30" id="id29">6</a> the string <span class="docutils literal"><span class="pre">coeff_N*x^N+...</span></span>, i.e. the
+polynomial is using descending powers.</p>
+<dl class="footnote brackets">
+<dt class="label" id="id30"><span class="brackets"><a class="fn-backref" href="#id29">6</a></span></dt>
+<dd><p>requires exhaustive expansion, for example as triggered by
+<span class="docutils literal">\write</span> or <span class="docutils literal">\edef</span>.</p>
+</dd>
+</dl>
+<p>Since <span class="docutils literal">0.8</span> the input is not restricted to be a polynomial name but
+is allowed to be an arbitrary expression (where by default the
+letter <span class="docutils literal">x</span> is recognized as the indeterminate; see
+<a class="reference internal" href="#poltoexprinvar">\PolToExprInVar</a>).</p>
+<p>The default output (which also by default uses the letter <span class="docutils literal">x</span> and is
+completely configurable, see in particular <a class="reference internal" href="#poltoexprvar">\PolToExprVar</a>) is
+compatible with both</p>
+<ul class="simple">
+<li><p>the Maple's input format,</p></li>
+<li><p>and the PSTricks <span class="docutils literal">\psplot[algebraic]</span> input format.</p></li>
+</ul>
+<p>Attention that it is not compatible with Python, but see
+<a class="reference internal" href="#poltoexprcaret">\PolToExprCaret</a> in this regard.</p>
+<p>It has the following characteristics:</p>
+<ul class="simple">
+<li><p>vanishing coefficients are skipped (issue <span class="docutils literal">\poltoexpralltrue</span> to
+override this and produce output such as <span class="docutils literal">x^3+0*x^2+0*x^1+0</span>),</p></li>
+<li><p>negative coefficients are not prefixed by a <span class="docutils literal">+</span> sign (else,
+Maple would not be happy),</p></li>
+<li><p>coefficients numerically equal to <span class="docutils literal">1</span> (or <span class="docutils literal"><span class="pre">-1</span></span>) are present
+only via their sign,</p></li>
+<li><p>the letter <span class="docutils literal">x</span> is used and the degree one monomial is output as
+<span class="docutils literal">x</span>, not as <span class="docutils literal">x^1</span>.</p></li>
+<li><p>(<span class="docutils literal">0.8</span>) the caret <span class="docutils literal">^</span> is of catcode 12. This means that one
+can for convenience typeset in regular text mode, for example
+using <span class="docutils literal">\texttt</span> (in LaTeX). But TeX will not know how to break
+the expression across end-of-lines anyhow. Formerly <span class="docutils literal">^</span> was
+suitable for math mode but as the exponent is not braced this
+worked only for polynomials of degrees at most 9. Anyhow this
+is not supposed to be a typesetting macro.</p></li>
+</ul>
+<p>Complete customization is possible, see the next macros. Any user
+redefinition must maintain the expandability property.</p>
+</blockquote>
+<div class="section" id="id31">
+<span id="poltoexprvar"></span><h3><a class="toc-backref" href="#id155"><span class="docutils literal">\PolToExprVar</span></a></h3>
+<blockquote>
+<p>Defaults to <span class="docutils literal">x</span>. The letter used in input.</p>
+</blockquote>
+</div>
+<div class="section" id="poltoexprinvar">
+<h3><a class="toc-backref" href="#id156"><span class="docutils literal">\PolToExprInVar</span></a></h3>
+<blockquote>
+<p>Defaults to <span class="docutils literal">x</span>: the letter used as the polynomial indeterminate.</p>
+<p>Recall that declared polynomials are more efficiently used in
+algebraic expressions without the <span class="docutils literal">(x)</span>, i.e. <span class="docutils literal">P*Q</span> is better
+than <span class="docutils literal"><span class="pre">P(x)*Q(x)</span></span>. Thus the input, even if an expression, does not
+have to contain any <span class="docutils literal">x</span>.</p>
+<p>(new with <span class="docutils literal">0.8</span>)</p>
+</blockquote>
+</div>
+<div class="section" id="id32">
+<span id="poltoexprtimes"></span><h3><a class="toc-backref" href="#id157"><span class="docutils literal">\PolToExprTimes</span></a></h3>
+<blockquote>
+<p>Defaults to <span class="docutils literal">*</span>.</p>
+</blockquote>
+</div>
+<div class="section" id="poltoexprcaret">
+<h3><a class="toc-backref" href="#id158"><span class="docutils literal">\PolToExprCaret</span></a></h3>
+<blockquote>
+<p>Defaults to <span class="docutils literal">^</span> of catcode 12. Set it to
+expand to <span class="docutils literal">**</span> for Python compatible output.</p>
+<p>(new with <span class="docutils literal">0.8</span>)</p>
+</blockquote>
+</div>
+<div class="section" id="poltoexprcmd-raw-coeff">
+<span id="poltoexprcmd"></span><h3><a class="toc-backref" href="#id159"><span class="docutils literal">\PolToExprCmd{raw_coeff}</span></a></h3>
+<blockquote>
+<p>Defaults to <span class="docutils literal"><span class="pre">\xintPRaw{\xintRawWithZeros{#1}}</span></span>.</p>
+<p>This means that the coefficient value is printed-out as a fraction
+<span class="docutils literal">a/b</span>, skipping the <span class="docutils literal">/b</span> part if <span class="docutils literal">b</span> turns out to be one.</p>
+<p>Configure it to be <span class="docutils literal"><span class="pre">\xintPRaw{\xintIrr{#1}}</span></span> if the fractions
+must be in irreducible terms.</p>
+<p>An alternative is <span class="docutils literal"><span class="pre">\xintDecToString{\xintREZ{#1}}</span></span> which uses
+integer or decimal fixed point format such as <span class="docutils literal">23.0071</span> if the
+internal representation of the number only has a power of ten as
+denominator (the effect of <span class="docutils literal">\xintREZ</span> here is to remove trailing
+decimal zeros). The behaviour of <span class="docutils literal">\xintDecToString</span> is not yet
+stable for other cases, and for example at time of writing no
+attempt is made to identify inputs having a finite decimal expansion
+so for example <span class="docutils literal">23.007/2</span> or <span class="docutils literal">23.007/25</span> can appear in output
+and not their finite decimal expansion with no denominator.</p>
+</blockquote>
+</div>
+<div class="section" id="poltoexproneterm-raw-coeff-number">
+<span id="poltoexproneterm"></span><h3><a class="toc-backref" href="#id160"><span class="docutils literal"><span class="pre">\PolToExprOneTerm{raw_coeff}{number}</span></span></a></h3>
+<blockquote>
+<p>This is the macro which from the coefficient and the exponent
+produces the corresponding term in output, such as <span class="docutils literal">2/3*x^7</span>.</p>
+<p>For its default definition, see the source code. It uses
+<a class="reference internal" href="#poltoexprcmd">\PolToExprCmd</a>, <a class="reference internal" href="#poltoexprtimes">\PolToExprTimes</a>, <a class="reference internal" href="#poltoexprvar">\PolToExprVar</a> and
+<a class="reference internal" href="#poltoexprcaret">\PolToExprCaret</a>.</p>
+</blockquote>
+</div>
+<div class="section" id="poltoexpronetermstylea-raw-coeff-number">
+<span id="poltoexpronetermstylea"></span><h3><a class="toc-backref" href="#id161"><span class="docutils literal"><span class="pre">\PolToExprOneTermStyleA{raw_coeff}{number}</span></span></a></h3>
+<blockquote>
+<p>This holds the default package meaning of <span class="docutils literal">\PolToExprOneTerm</span>.</p>
+</blockquote>
+</div>
+<div class="section" id="poltoexpronetermstyleb-raw-coeff-number">
+<span id="poltoexpronetermstyleb"></span><h3><a class="toc-backref" href="#id162"><span class="docutils literal"><span class="pre">\PolToExprOneTermStyleB{raw_coeff}{number}</span></span></a></h3>
+<blockquote>
+<p>This holds an alternative meaning, which puts the fractional part of
+a coefficient after the monomial, i.e. like this:</p>
+<pre class="literal-block">2*x^11/3+3*x^8/7-x^5-x^4/4-x^3-x^2/2-2*x+1</pre>
+<p><a class="reference internal" href="#poltoexprcmd">\PolToExprCmd</a> isn't used at all in this style. But
+<a class="reference internal" href="#poltoexprtimes">\PolToExprTimes</a>, <a class="reference internal" href="#poltoexprvar">\PolToExprVar</a> and <a class="reference internal" href="#poltoexprcaret">\PolToExprCaret</a> are obeyed.</p>
+<p>To activate it use <span class="docutils literal">\let\PolToExprOneTerm\PolToExprOneTermStyleB</span>.
+To revert to the package default behaviour, issue
+<span class="docutils literal">\let\PolToExprOneTerm\PolToExprOneTermStyleA</span>.</p>
+</blockquote>
+</div>
+<div class="section" id="poltoexprtermprefix-raw-coeff">
+<span id="poltoexprtermprefix"></span><h3><a class="toc-backref" href="#id163"><span class="docutils literal">\PolToExprTermPrefix{raw_coeff}</span></a></h3>
+<blockquote>
+<p>It receives as argument the coefficient. Its default behaviour is
+to produce a <span class="docutils literal">+</span> if the coefficient is positive, which will thus
+serve to separate the monomials in the output. This is to match
+the default for <a class="reference internal" href="#poltoexprcmd-raw-coeff">\PolToExprCmd{raw_coeff}</a> which in case of a
+positive coefficient does not output an explicit <span class="docutils literal">+</span> prefix.</p>
+</blockquote>
+</div>
+</div>
+<div class="section" id="id34">
+<span id="id33"></span><h2><a class="toc-backref" href="#id164"><span class="docutils literal"><span class="pre">\PolToExpr*{&lt;pol.</span> <span class="pre">expr.&gt;}</span></span></a></h2>
+<blockquote>
+<p>Ascending powers: <span class="docutils literal"><span class="pre">coeff_0+coeff_1*x+coeff_2*x^2+...</span></span>.</p>
+<p>Extended at <span class="docutils literal">0.8</span> to accept general expressions as input.</p>
+<p>Customizable with the same macros as for
+<a class="reference internal" href="#poltoexpr-pol-expr">\PolToExpr{&lt;pol. expr.&gt;}</a>.</p>
+</blockquote>
+</div>
+<div class="section" id="poltofloatexpr-pol-expr">
+<span id="poltofloatexpr"></span><h2><a class="toc-backref" href="#id165"><span class="docutils literal"><span class="pre">\PolToFloatExpr{&lt;pol.</span> <span class="pre">expr.&gt;}</span></span></a></h2>
+<blockquote>
+<p>Similar to <a class="reference internal" href="#poltoexpr-pol-expr">\PolToExpr{&lt;pol. expr.&gt;}</a> but using <a class="reference external" href="\PolToFloatExprCmd{raw_coeff}">\PolToFloatExprCmd</a> which by default rounds and
+converts the coefficients to floating point format.</p>
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p>This is unrelated to <a class="reference internal" href="#polgenfloatvariant-polname">\PolGenFloatVariant{polname}</a>:
+<a class="reference internal" href="#poltofloatexprcmd-raw-coeff">\PolToFloatExprCmd{raw_coeff}</a> operates on the <em>exact</em>
+coefficients anew (and may thus produce something else than
+the coefficients of the polynomial function acting
+in <span class="docutils literal">\xintfloateval</span> if the floating point precision was changed
+in between).</p>
+</div>
+<p>Extended at <span class="docutils literal">0.8</span> to accept general expressions as input.</p>
+</blockquote>
+<div class="section" id="poltofloatexproneterm-raw-coeff-number">
+<span id="poltofloatexproneterm"></span><h3><a class="toc-backref" href="#id166"><span class="docutils literal"><span class="pre">\PolToFloatExprOneTerm{raw_coeff}{number}</span></span></a></h3>
+<blockquote>
+<p>Similar to <a class="reference external" href="\PolToExprOneTerm{raw_coeff}{number}">\PolToExprOneTerm</a>. But does not treat
+especially coefficients equal to plus or minus one.</p>
+</blockquote>
+</div>
+<div class="section" id="poltofloatexprcmd-raw-coeff">
+<span id="id36"></span><h3><a class="toc-backref" href="#id167"><span class="docutils literal">\PolToFloatExprCmd{raw_coeff}</span></a></h3>
+<blockquote>
+<p>The one-argument macro used by <span class="docutils literal">\PolToFloatExprOneTerm</span>.
+It defaults to <span class="docutils literal"><span class="pre">\xintFloat{#1}</span></span>.</p>
+<div class="admonition caution">
+<p class="admonition-title">Caution!</p>
+<p>Currently <span class="docutils literal">\xintFloat{0}</span> outputs <span class="docutils literal">0.e0</span>
+which is perfectly acceptable input for Python, but not for
+Maple. Thus, one should better leave the <span class="docutils literal">\\ifpoltoexprall</span> TeX
+Boolean to its default <a class="reference internal" href="#poltoexprallfalse">\poltoexprallfalse</a>, if one intends to use
+the output in a Maple worksheet.</p>
+<p>But even then the zero polynomial will cause a problem. Workaround:</p>
+<pre class="literal-block">\renewcommand\PolToFloatExprCmd[1]{\xintiiifZero{#1}{0.0}{\xintFloat{#1}}}</pre>
+<p>Usage of <span class="docutils literal">\xintiiifZero</span> and not <span class="docutils literal">\xintifZero</span> is only for
+optimization (I can't help it) because <span class="docutils literal">#1</span> is known to be
+in <span class="docutils literal">xintfrac</span> raw format.</p>
+</div>
+</blockquote>
+</div>
+</div>
+<div class="section" id="id38">
+<span id="id37"></span><h2><a class="toc-backref" href="#id168"><span class="docutils literal"><span class="pre">\PolToFloatExpr*{&lt;pol.</span> <span class="pre">expr.&gt;}</span></span></a></h2>
+<blockquote>
+<p>Ascending powers.</p>
+<p>Extended at <span class="docutils literal">0.8</span> to accept general expressions as input.</p>
+</blockquote>
+</div>
+<div class="section" id="poltolist-polname">
+<span id="poltolist"></span><h2><a class="toc-backref" href="#id169"><span class="docutils literal">\PolToList{polname}</span></a></h2>
+<blockquote>
+<p>Expands to <span class="docutils literal"><span class="pre">{coeff_0}{coeff_1}...{coeff_N}</span></span> with <span class="docutils literal">N</span> = degree, and
+<span class="docutils literal">coeff_N</span> the leading coefficient
+(the zero polynomial does give <span class="docutils literal">{0/1[0]}</span> and not an
+empty output.)</p>
+</blockquote>
+</div>
+<div class="section" id="poltocsv-polname">
+<span id="poltocsv"></span><h2><a class="toc-backref" href="#id170"><span class="docutils literal">\PolToCSV{polname}</span></a></h2>
+<blockquote>
+<p>Expands to <span class="docutils literal">coeff_0, coeff_1, coeff_2, <span class="pre">.....,</span> coeff_N</span>, starting
+with constant term and ending with leading coefficient. Converse
+to <a class="reference internal" href="#polfromcsv-polname-csv">\PolFromCSV</a>.</p>
+</blockquote>
+</div>
+<div class="section" id="expandable-macros-related-to-the-root-localization-routines">
+<h2><a class="toc-backref" href="#id171">Expandable macros related to the root localization routines</a></h2>
+<div class="section" id="polsturmchainlength-sturmname">
+<span id="polsturmchainlength"></span><h3><a class="toc-backref" href="#id172"><span class="docutils literal">\PolSturmChainLength{sturmname}</span></a></h3>
+<blockquote>
+<p>Returns the integer <span class="docutils literal">N</span> such that <span class="docutils literal">sturmname_N</span> is the last one
+in the Sturm chain <span class="docutils literal">sturmname_0</span>, <span class="docutils literal">sturmname_1</span>, ...</p>
+<p>See <a class="reference internal" href="#poltosturm-polname-sturmname">\PolToSturm{polname}{sturmname}</a>.</p>
+</blockquote>
+</div>
+<div class="section" id="polsturmifzeroexactlyknown-sturmname-index-a-b">
+<span id="polsturmifzeroexactlyknown"></span><h3><a class="toc-backref" href="#id173"><span class="docutils literal"><span class="pre">\PolSturmIfZeroExactlyKnown{sturmname}{index}{A}{B}</span></span></a></h3>
+<blockquote>
+<p>Executes <span class="docutils literal">A</span> if the <span class="docutils literal">index</span>-th interval reduces to a singleton,
+i.e. the root is known exactly, else <span class="docutils literal">B</span>.</p>
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p><span class="docutils literal">index</span> is allowed to be something like <span class="docutils literal">1+2*3</span> as it is fed
+to <span class="docutils literal"><span class="pre">\the\numexpr...\relax</span></span>.</p>
+</div>
+</blockquote>
+</div>
+<div class="section" id="polsturmisolatedzeroleft-sturmname-index">
+<span id="polsturmisolatedzeroleft"></span><h3><a class="toc-backref" href="#id174"><span class="docutils literal"><span class="pre">\PolSturmIsolatedZeroLeft{sturmname}{index}</span></span></a></h3>
+<blockquote>
+<p>Expands to the left end-point for the <span class="docutils literal">index</span>-th interval, as
+computed by some earlier <a class="reference internal" href="#polsturmisolatezeros-sturmname">\PolSturmIsolateZeros{sturmname}</a>.</p>
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p>Of course, this is kept updated by macros such as
+<a class="reference internal" href="#polrefineinterval-n">\PolRefineInterval{sturmname}{index}</a>.</p>
+</div>
+<p>The value is pre-formatted using <a class="reference internal" href="#poldectostring">\PolDecTostring</a>.</p>
+</blockquote>
+</div>
+<div class="section" id="polsturmisolatedzeroright-sturmname-index">
+<span id="polsturmisolatedzeroright"></span><h3><a class="toc-backref" href="#id175"><span class="docutils literal"><span class="pre">\PolSturmIsolatedZeroRight{sturmname}{index}</span></span></a></h3>
+<blockquote>
+<p>Expands to the right end-point for the <span class="docutils literal">index</span>-th interval as
+computed by some earlier <a class="reference internal" href="#polsturmisolatezeros-sturmname">\PolSturmIsolateZeros{sturmname}</a> and
+possibly refined afterwards.</p>
+<p>The value is pre-formatted using <a class="reference internal" href="#poldectostring">\PolDecTostring</a>.</p>
+</blockquote>
+</div>
+<div class="section" id="polsturmisolatedzeromultiplicity-sturmname-index">
+<span id="polsturmisolatedzeromultiplicity"></span><h3><a class="toc-backref" href="#id176"><span class="docutils literal"><span class="pre">\PolSturmIsolatedZeroMultiplicity{sturmname}{index}</span></span></a></h3>
+<blockquote>
+<p>Expands to the multiplicity of the unique root contained in the
+<span class="docutils literal">index</span>-th interval.</p>
+<div class="admonition attention">
+<p class="admonition-title">Attention!</p>
+<p>A prior execution of <a class="reference internal" href="#id15">\PolSturmIsolateZeros*{sturmname}</a> is mandatory.</p>
+</div>
+<p>See <a class="reference internal" href="#the-degree-nine-polynomial-with-0-99-0-999-0-9999-as-triple-roots">The degree nine polynomial with 0.99, 0.999, 0.9999 as triple
+roots</a> for an example of use.</p>
+</blockquote>
+</div>
+<div class="section" id="polsturmnbofisolatedzeros-sturmname">
+<span id="polsturmnbofisolatedzeros"></span><h3><a class="toc-backref" href="#id177"><span class="docutils literal">\PolSturmNbOfIsolatedZeros{sturmname}</span></a></h3>
+<blockquote>
+<p>Expands to the number of real roots of the polynomial
+<span class="docutils literal">&lt;sturmname&gt;_0</span>, i.e. the number of distinct real roots of the
+polynomial originally used to create the Sturm chain via
+<a class="reference internal" href="#poltosturm-polname-sturmname">\PolToSturm{polname}{sturmname}</a>.</p>
+</blockquote>
+<div class="admonition warning">
+<p class="admonition-title">Warning</p>
+<p>The next few macros counting roots, with or without multiplicities,
+less than or equal to some value, are under evaluation and may be
+removed from the package if their utility is judged to be not high
+enough. They can be re-coded at user level on the basis of the other
+documented package macros anyway.</p>
+</div>
+</div>
+<div class="section" id="polsturmnbofrootsof-sturmname-lessthanorequalto-value">
+<h3><a class="toc-backref" href="#id178"><span class="docutils literal"><span class="pre">\PolSturmNbOfRootsOf{sturmname}\LessThanOrEqualTo{value}</span></span></a></h3>
+<blockquote>
+<p>Expands to the number of distinct roots (of the polynomial used to
+create the Sturm chain) less than or equal to the <span class="docutils literal">value</span> (i.e. a
+number of fraction recognizable by the <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> macros).</p>
+<div class="admonition attention">
+<p class="admonition-title">Attention!</p>
+<p><a class="reference internal" href="#polsturmisolatezeros-sturmname">\PolSturmIsolateZeros{sturmname}</a> must have been executed
+beforehand.</p>
+<p>And the argument is a <span class="docutils literal">sturmname</span>, not a <span class="docutils literal">polname</span> (this is
+why the macro contains Sturm in its name), simply to be reminded
+of the above constraint.</p>
+</div>
+</blockquote>
+</div>
+<div class="section" id="polsturmnbofrootsof-sturmname-lessthanorequaltoexpr-expression">
+<h3><a class="toc-backref" href="#id179"><span class="docutils literal"><span class="pre">\PolSturmNbOfRootsOf{sturmname}\LessThanOrEqualToExpr{expression}</span></span></a></h3>
+<blockquote>
+<p>Expands to the number of distinct roots (of the polynomial
+used to create the Sturm chain) which are less than or equal to the
+given <span class="docutils literal">expression</span>.</p>
+<div class="admonition attention">
+<p class="admonition-title">Attention!</p>
+<p><a class="reference internal" href="#polsturmisolatezeros-sturmname">\PolSturmIsolateZeros{sturmname}</a> must have been executed
+beforehand.</p>
+</div>
+</blockquote>
+</div>
+<div class="section" id="polsturmnbwithmultofrootsof-sturmname-lessthanorequalto-value">
+<h3><a class="toc-backref" href="#id180"><span class="docutils literal"><span class="pre">\PolSturmNbWithMultOfRootsOf{sturmname}\LessThanOrEqualTo{value}</span></span></a></h3>
+<blockquote>
+<p>Expands to the number counted with multiplicities of the roots (of
+the polynomial used to create the Sturm chain) which are less than
+or equal to the given <span class="docutils literal">value</span>.</p>
+<div class="admonition attention">
+<p class="admonition-title">Attention!</p>
+<p><a class="reference internal" href="#id15">\PolSturmIsolateZeros*{sturmname}</a> (or the double starred
+variant) must have been executed beforehand.</p>
+</div>
+</blockquote>
+</div>
+<div class="section" id="polsturmnbwithmultofrootsof-sturmname-lessthanorequaltoexpr-expression">
+<h3><a class="toc-backref" href="#id181"><span class="docutils literal"><span class="pre">\PolSturmNbWithMultOfRootsOf{sturmname}\LessThanOrEqualToExpr{expression}</span></span></a></h3>
+<blockquote>
+<p>Expands to the total number of roots (counted with multiplicities)
+which are less than or equal to the given <span class="docutils literal">expression</span>.</p>
+<div class="admonition attention">
+<p class="admonition-title">Attention!</p>
+<p><a class="reference internal" href="#id15">\PolSturmIsolateZeros*{sturmname}</a> (or the double starred
+variant) must have been executed beforehand.</p>
+</div>
+</blockquote>
+</div>
+<div class="section" id="polsturmnbofrationalroots-sturmname">
+<h3><a class="toc-backref" href="#id182"><span class="docutils literal">\PolSturmNbOfRationalRoots{sturmname}</span></a></h3>
+<blockquote>
+<p>Expands to the number of rational roots (without multiplicities).</p>
+<div class="admonition attention">
+<p class="admonition-title">Attention!</p>
+<p><a class="reference internal" href="#id17">\PolSturmIsolateZeros**{sturmname}</a> must have been executed
+beforehand.</p>
+</div>
+</blockquote>
+</div>
+<div class="section" id="polsturmnbofrationalrootswithmultiplicities-sturmname">
+<h3><a class="toc-backref" href="#id183"><span class="docutils literal">\PolSturmNbOfRationalRootsWithMultiplicities{sturmname}</span></a></h3>
+<blockquote>
+<p>Expands to the number of rational roots (counted with multiplicities).</p>
+<div class="admonition attention">
+<p class="admonition-title">Attention!</p>
+<p><a class="reference internal" href="#id17">\PolSturmIsolateZeros**{sturmname}</a> must have been executed
+beforehand.</p>
+</div>
+</blockquote>
+</div>
+<div class="section" id="polsturmrationalroot-sturmname-k">
+<h3><a class="toc-backref" href="#id184"><span class="docutils literal"><span class="pre">\PolSturmRationalRoot{sturmname}{k}</span></span></a></h3>
+<blockquote>
+<p>Expands to the <span class="docutils literal">k</span>th rational root (they are ordered and indexed
+starting at 1 for the most negative).</p>
+<div class="admonition attention">
+<p class="admonition-title">Attention!</p>
+<p><a class="reference internal" href="#id17">\PolSturmIsolateZeros**{sturmname}</a> must have been executed
+beforehand.</p>
+</div>
+</blockquote>
+</div>
+<div class="section" id="polsturmrationalrootindex-sturmname-k">
+<h3><a class="toc-backref" href="#id185"><span class="docutils literal"><span class="pre">\PolSturmRationalRootIndex{sturmname}{k}</span></span></a></h3>
+<blockquote>
+<p>Expands to <span class="docutils literal">index</span> of the <span class="docutils literal">k</span>th rational root as part of the
+ordered real roots (without multiplicities). I.e., above macro
+<a class="reference internal" href="#polsturmrationalroot-sturmname-k">\PolSturmRationalRoot{sturmname}{k}</a> is equivalent to this
+nested call:</p>
+<pre class="literal-block">\PolSturmIsolatedZeroLeft{sturmname}{\PolSturmRationalRootIndex{sturmname}{k}}</pre>
+<div class="admonition attention">
+<p class="admonition-title">Attention!</p>
+<p><a class="reference internal" href="#id17">\PolSturmIsolateZeros**{sturmname}</a> must have been executed
+beforehand.</p>
+</div>
+</blockquote>
+</div>
+<div class="section" id="polsturmrationalrootmultiplicity-sturmname-k">
+<h3><a class="toc-backref" href="#id186"><span class="docutils literal"><span class="pre">\PolSturmRationalRootMultiplicity{sturmname}{k}</span></span></a></h3>
+<blockquote>
+<p>Expands to the multiplicity of the <span class="docutils literal">k</span>th rational root.</p>
+<div class="admonition attention">
+<p class="admonition-title">Attention!</p>
+<p><a class="reference internal" href="#id17">\PolSturmIsolateZeros**{sturmname}</a> must have been executed
+beforehand.</p>
+</div>
+</blockquote>
+</div>
+<div class="section" id="polintervalwidth-sturmname-index">
+<span id="polintervalwidth"></span><h3><a class="toc-backref" href="#id187"><span class="docutils literal"><span class="pre">\PolIntervalWidth{sturmname}{index}</span></span></a></h3>
+<blockquote>
+<p>The <span class="docutils literal">10^E</span> width of the current <span class="docutils literal">index</span>-th root localization
+interval. Output is in <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> raw <span class="docutils literal">1/1[E]</span> format (if not zero).</p>
+</blockquote>
+</div>
+</div>
+<div class="section" id="expandable-macros-for-use-within-execution-of-polprintintervals">
+<h2><a class="toc-backref" href="#id188">Expandable macros for use within execution of <span class="docutils literal">\PolPrintIntervals</span></a></h2>
+<p>These macros are for usage within custom user redefinitions of
+<a class="reference internal" href="#polprintintervalsknownroot">\PolPrintIntervalsKnownRoot</a>, <a class="reference internal" href="#polprintintervalsunknownroot">\PolPrintIntervalsUnknownRoot</a>, or
+in redefinitions of <a class="reference internal" href="#polprintintervalsprintexactzero">PolPrintIntervalsPrintExactZero</a> (used in the
+default for the former) and of <a class="reference internal" href="#polprintintervalsprintleftendpoint">\PolPrintIntervalsPrintLeftEndPoint</a>,
+<a class="reference internal" href="#polprintintervalsprintrightendpoint">\PolPrintIntervalsPrintRightEndPoint</a> (used in the default for the
+latter).</p>
+<div class="admonition attention">
+<p class="admonition-title">Attention!</p>
+<p>Some macros formerly mentioned here got removed at 0.7:
+<span class="docutils literal">\PolPrintIntervalsTheEndPoint</span>,
+<span class="docutils literal"><span class="pre">\PolIfEndPointIsPositive{A}{B}</span></span>,
+<span class="docutils literal"><span class="pre">\PolIfEndPointIsNegative{A}{B}</span></span>,
+<span class="docutils literal"><span class="pre">\PolIfEndPointIsZero{A}{B}</span></span>.</p>
+</div>
+<div class="section" id="polprintintervalsthevar">
+<h3><a class="toc-backref" href="#id189"><span class="docutils literal">\PolPrintIntervalsTheVar</span></a></h3>
+<blockquote>
+<p>Expands to the name (default <span class="docutils literal">Z</span>) used for representing the roots,
+which was passed as optional argument <span class="docutils literal">varname</span> to
+<a class="reference internal" href="#polprintintervals-varname-sturmname">\PolPrintIntervals[varname]{sturmname}</a>.</p>
+</blockquote>
+</div>
+<div class="section" id="polprintintervalstheindex">
+<h3><a class="toc-backref" href="#id190"><span class="docutils literal">\PolPrintIntervalsTheIndex</span></a></h3>
+<blockquote>
+<p>Expands to the index of the considered interval (indexing starting
+at 1 for the leftmost interval).</p>
+</blockquote>
+</div>
+<div class="section" id="polprintintervalsthesturmname">
+<h3><a class="toc-backref" href="#id191"><span class="docutils literal">\PolPrintIntervalsTheSturmName</span></a></h3>
+<blockquote>
+<p>Expands to the argument which was passed as <span class="docutils literal">sturmname</span> to
+<a class="reference internal" href="#polprintintervals-varname-sturmname">\PolPrintIntervals[varname]{sturmname}</a>.</p>
+</blockquote>
+</div>
+<div class="section" id="polprintintervalstheleftendpoint">
+<h3><a class="toc-backref" href="#id192"><span class="docutils literal">\PolPrintIntervalsTheLeftEndPoint</span></a></h3>
+<blockquote>
+<p>The left end point of the interval, as would be produced by
+<a class="reference internal" href="#polsturmisolatedzeroleft">\PolSturmIsolatedZeroLeft</a> if it was
+used with arguments the Sturm chain name and interval index returned
+by <a class="reference internal" href="#polprintintervalsthesturmname">\PolPrintIntervalsTheSturmName</a> and
+<a class="reference internal" href="#polprintintervalstheindex">\PolPrintIntervalsTheIndex</a>.</p>
+</blockquote>
+</div>
+<div class="section" id="polprintintervalstherightendpoint">
+<h3><a class="toc-backref" href="#id193"><span class="docutils literal">\PolPrintIntervalsTheRightEndPoint</span></a></h3>
+<blockquote>
+<p>The right end point of the interval, as would be produced by
+<a class="reference internal" href="#polsturmisolatedzeroright">\PolSturmIsolatedZeroRight</a> for
+this Sturm chain name and index.</p>
+</blockquote>
+</div>
+<div class="section" id="polprintintervalsthemultiplicity">
+<h3><a class="toc-backref" href="#id194"><span class="docutils literal">\PolPrintIntervalsTheMultiplicity</span></a></h3>
+<blockquote>
+<p>The multiplicity of the unique root within the interval of index
+<a class="reference internal" href="#polprintintervalstheindex">\PolPrintIntervalsTheIndex</a>. Makes sense only if the starred (or
+double-starred) variant of <a class="reference internal" href="#polsturmisolatezeros">\PolSturmIsolateZeros</a> was used earlier.</p>
+</blockquote>
+</div>
+</div>
+</div>
+<div class="section" id="booleans-with-default-setting-as-indicated">
+<h1><a class="toc-backref" href="#id195">Booleans (with default setting as indicated)</a></h1>
+<div class="section" id="xintverbosefalse">
+<h2><a class="toc-backref" href="#id196"><span class="docutils literal">\xintverbosefalse</span></a></h2>
+<blockquote>
+<p>This is actually an <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> configuration. Setting it to
+<span class="docutils literal">true</span> triggers the writing of information to the log when new
+polynomial or scalar variables are defined.</p>
+<div class="admonition caution">
+<p class="admonition-title">Caution!</p>
+<p>The macro and variable meanings as written to the log are to be
+considered unstable and undocumented internal structures.</p>
+</div>
+</blockquote>
+</div>
+<div class="section" id="polnewpolverbosefalse">
+<h2><a class="toc-backref" href="#id197"><span class="docutils literal">\polnewpolverbosefalse</span></a></h2>
+<blockquote>
+<p>When <span class="docutils literal">\poldef</span> is used, both a variable and a function are
+defined. The default <span class="docutils literal">\polnewpolverbosefalse</span> setting suppresses
+the print-out to the log and terminal of the function macro meaning,
+as it only duplicates the information contained in the variable
+which is already printed out to the log and terminal.</p>
+<p>However <a class="reference internal" href="#polgenfloatvariant-polname">\PolGenFloatVariant{polname}</a> does still print out the
+information relative to the polynomial function it defines for use in
+<span class="docutils literal">\xintfloateval{}</span> as there is no float polynomial variable, only the
+function, and it is the only way to see its rounded coefficients
+(<span class="docutils literal">\xintverbosefalse</span> suppresses also that info).</p>
+<p>If set to <span class="docutils literal">true</span>, it overrides in both cases
+<span class="docutils literal">\xintverbosefalse</span>. The setting only affects polynomial
+declarations. Scalar variables such as those holding information on
+roots obey only the <span class="docutils literal"><span class="pre">\xintverbose...</span></span> setting.</p>
+<p>(new with <span class="docutils literal">0.8</span>)</p>
+</blockquote>
+</div>
+<div class="section" id="poltypesetallfalse">
+<h2><a class="toc-backref" href="#id198"><span class="docutils literal">\poltypesetallfalse</span></a></h2>
+<blockquote>
+<p>If <span class="docutils literal">true</span>, <a class="reference internal" href="#poltypeset">\PolTypeset</a> will also typeset the vanishing
+coefficients.</p>
+</blockquote>
+</div>
+<div class="section" id="poltoexprallfalse">
+<h2><a class="toc-backref" href="#id199"><span class="docutils literal">\poltoexprallfalse</span></a></h2>
+<blockquote>
+<p>If <span class="docutils literal">true</span>, <a class="reference internal" href="#poltoexpr-pol-expr">\PolToExpr{&lt;pol. expr.&gt;}</a> and <a class="reference internal" href="#poltofloatexpr-pol-expr">\PolToFloatExpr{&lt;pol. expr.&gt;}</a> will
+also include the vanishing coefficients in their outputs.</p>
+</blockquote>
+</div>
+</div>
+<div class="section" id="utilies">
+<h1><a class="toc-backref" href="#id200">Utilies</a></h1>
+<div class="section" id="poldectostring-decimal-number">
+<span id="poldectostring"></span><h2><a class="toc-backref" href="#id201"><span class="docutils literal">\PolDecToString{decimal number}</span></a></h2>
+<blockquote>
+<p>This is a utility macro to print decimal numbers. It has been
+backported to <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> (release <span class="docutils literal">1.3</span> of <span class="docutils literal">2018/03/01</span>) under
+the name <span class="docutils literal">\xintDecToString</span>, and the <span class="docutils literal">polexpr</span> macro is simply
+now an alias to it.</p>
+<p>For example
+<span class="docutils literal"><span class="pre">\PolDecToString{123.456e-8}</span></span> will expand to <span class="docutils literal">0.00000123456</span>
+and <span class="docutils literal"><span class="pre">\PolDecToString{123.450e-8}</span></span> to <span class="docutils literal">0.00000123450</span> which
+illustrates that trailing zeros are not trimmed. To trim trailing
+zeroes, one can use <span class="docutils literal"><span class="pre">\PolDecToString{\xintREZ{#1}}</span></span>.</p>
+<p>The precise behaviour of this macro may evolve in future releases of
+<a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a>.</p>
+</blockquote>
+</div>
+<div class="section" id="polexprsetup">
+<h2><a class="toc-backref" href="#id202"><span class="docutils literal">\polexprsetup</span></a></h2>
+<blockquote>
+<p>Serves to customize the package. Currently only two keys are
+recognized:</p>
+<ul class="simple">
+<li><p><span class="docutils literal">norr</span>: the postfix that <a class="reference internal" href="#id17">\PolSturmIsolateZeros**{sturmname}</a>
+should append to <span class="docutils literal">sturmname</span> to declare the primitive polynomial
+obtained from original one after removal of all rational roots.
+The default value is <span class="docutils literal">_norr</span> (standing for “no rational roots”).</p></li>
+<li><p><span class="docutils literal">sqfnorr</span>: the postfix that <a class="reference internal" href="#id17">\PolSturmIsolateZeros**{sturmname}</a>
+should append to <span class="docutils literal">sturmname</span> to declare the primitive polynomial
+obtained from original one after removal of all rational roots and
+suppression of all multiplicities.
+The default value is <span class="docutils literal">_sqf_norr</span> (standing for “square-free with
+no rational roots”).</p></li>
+</ul>
+<p>The package executes <span class="docutils literal">\polexprsetup{norr=_norr, sqfnorr=_sqf_norr}</span> as default.</p>
+</blockquote>
+</div>
+</div>
+<div class="section" id="technicalities">
+<h1><a class="toc-backref" href="#id203">Technicalities</a></h1>
+<ul>
+<li><p>The catcode of the semi-colon is reset temporarily by <a class="reference internal" href="#poldef">\poldef</a> macro in case some other package (for example the French
+babel module) may have made it active. This will fail though if the
+whole thing was already part of a macro argument, in such cases one
+can use <a class="reference internal" href="#id8">\PolDef{f}{P(x)}</a>
+rather. The colon in <span class="docutils literal">:=</span> may be active with no consequences.</p></li>
+<li><p>As a consequence of <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> addition and subtraction always using
+least common multiples for the denominators <a class="footnote-reference brackets" href="#id40" id="id39">7</a>, user-chosen common
+denominators survive additions and multiplications. For example, this:</p>
+<pre class="literal-block">\poldef P(x):= 1/2 + 2/2*x + 3/2*x^3 + 4/2*x^4;
+\poldef Q(x):= 1/3 + (2/3)x + (3/3)x^3 + (4/3)x^4;
+\poldef PQ(x):= P*Q;</pre>
+<p>gives internally the polynomial:</p>
+<pre class="literal-block">1/6+4/6*x^1+4/6*x^2+6/6*x^3+20/6*x^4+16/6*x^5+9/6*x^6+24/6*x^7+16/6*x^8</pre>
+<p>where all coefficients have the same denominator 6. Notice though that
+<span class="docutils literal">\PolToExpr{PQ}</span> outputs the <span class="docutils literal">6/6*x^3</span> as <span class="docutils literal">x^3</span> because (by
+default) it recognizes and filters out coefficients equal to one or
+minus one (since release <span class="docutils literal">0.3</span>). One can use for example
+<span class="docutils literal">\PolToCSV{PQ}</span> to see the internally stored coefficients.</p>
+<dl class="footnote brackets">
+<dt class="label" id="id40"><span class="brackets"><a class="fn-backref" href="#id39">7</a></span></dt>
+<dd><p>prior to <span class="docutils literal">0.4.1</span>, <span class="docutils literal">polexpr</span> used to temporarily patch
+during the parsing of polynomials the <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> macros. This
+patch was backported to <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> at release <span class="docutils literal">1.3</span>.</p>
+</dd>
+</dl>
+</li>
+<li><p><a class="reference internal" href="#poldiff-polname-1-polname-2">\PolDiff{polname_1}{polname_2}</a> always applies <span class="docutils literal">\xintIrr</span> to the
+resulting coefficients, except that the <em>power of ten</em> part <span class="docutils literal">[N]</span>
+(for example an input in scientific notation such as <span class="docutils literal">1.23e5</span> gives
+<span class="docutils literal">123/1[3]</span> internally in xintfrac) is not taken into account in the
+reduction of the fraction. This is tentative and may change.</p>
+<p>Same remark for <a class="reference internal" href="#polantidiff-polname-1-polname-2">\PolAntiDiff{polname_1}{polname_2}</a>.</p>
+</li>
+<li><p>Currently, the package stores all coefficients from index <span class="docutils literal">0</span> to
+index equal to the polynomial degree inside a single macro, as a list.
+This data structure is obviously very inefficient for polynomials of
+high degree and few coefficients (as an example with <span class="docutils literal">\poldef <span class="pre">f(x):=x^1000</span> + x^500;</span> the subsequent definition <span class="docutils literal">\poldef <span class="pre">g(x):=</span> <span class="pre">f(x)^2;</span></span> will do of the order of 1,000,000 multiplications and
+additions involvings only zeroes... which does take time). This
+may change in the future.</p></li>
+<li><p>As is to be expected internal structures of the package are barely
+documented and unstable. Don't use them.</p></li>
+</ul>
+</div>
+<div class="section" id="change-log">
+<h1><a class="toc-backref" href="#id204">CHANGE LOG</a></h1>
+<ul>
+<li><p>v0.1 (2018/01/11): initial release. Features:</p>
+<ul class="simple">
+<li><p>The <a class="reference internal" href="#poldef">\poldef</a> parser itself,</p></li>
+<li><p>Differentiation and anti-differentiation,</p></li>
+<li><p>Euclidean division and GCDs,</p></li>
+<li><p>Various utilities such as <a class="reference internal" href="#polfromcsv">\PolFromCSV</a>,
+<a class="reference internal" href="#polmapcoeffs">\PolMapCoeffs</a>,
+<a class="reference internal" href="#poltocsv">\PolToCSV</a>, <a class="reference internal" href="#poltoexpr">\PolToExpr</a>, ...</p></li>
+</ul>
+<p>Only one-variable polynomials so far.</p>
+</li>
+<li><p>v0.2 (2018/01/14)</p>
+<ul class="simple">
+<li><p>Fix: <span class="docutils literal">&quot;README thinks \numexpr recognizes ^ operator&quot;</span>.</p></li>
+<li><p>Convert README to reStructuredText markup.</p></li>
+<li><p>Move main documentation from README to separate <span class="docutils literal">polexpr.txt</span> file.</p></li>
+<li><p>Provide <span class="docutils literal">polexpr.html</span> as obtained via <a class="reference external" href="http://docutils.sourceforge.net/docs/index.html">DocUtils</a> <span class="docutils literal">rst2html.py</span>.</p></li>
+<li><p>Convert README to (CTAN compatible) Markdown markup.</p></li>
+</ul>
+<p>Due to lack of available time the test suite might not be extensive
+enough. Bug reports are very welcome!</p>
+</li>
+<li><p>v0.3 (2018/01/17)</p>
+<ul>
+<li><p>bug fixes:</p>
+<ul>
+<li><p>the <span class="docutils literal">0.1</span> <a class="reference internal" href="#polevalat">\PolEval</a> accepted expressions for its second
+argument, but this was removed by mistake at <span class="docutils literal">0.2</span>. Restored.</p>
+<p><strong>Attention</strong>: at <span class="docutils literal">0.4</span> this has been reverted again, and
+<a class="reference internal" href="#polevalatexpr">\PolEval{P}\AtExpr{foo}</a> syntax is needed for
+using expressions in the second argument.</p>
+</li>
+</ul>
+</li>
+<li><p>incompatible or breaking changes:</p>
+<ul class="simple">
+<li><p><a class="reference internal" href="#poltoexpr">\PolToExpr</a> now by default uses <em>descending</em>
+powers (it also treats differently coefficients equal to 1 or -1.)
+Use <a class="reference internal" href="#id33">\PolToExpr*</a> for <em>ascending</em> powers.</p></li>
+<li><p><a class="reference internal" href="#polevalat">\PolEval</a> reduced the output to smallest terms,
+but as this is costly with big fractions and not needed if e.g.
+wrapped in an <span class="docutils literal">\xintRound</span> or <span class="docutils literal">\xintFloat</span>, this step has been
+removed; the former meaning is available as <a class="reference internal" href="#polevalreducedat">\PolEvalReduced</a>.</p></li>
+</ul>
+</li>
+<li><p>new (or newly documented) macros:</p>
+<ul class="simple">
+<li><p><a class="reference internal" href="#poltypesetcmd">\PolTypesetCmd</a></p></li>
+<li><p><a class="reference internal" href="#poltypesetcmdprefix">\PolTypesetCmdPrefix</a></p></li>
+<li><p><a class="reference internal" href="#poltypesetmonomialcmd">\PolTypesetMonomialCmd</a></p></li>
+<li><p><a class="reference internal" href="#polevalreducedat">\PolEvalReducedAt</a></p></li>
+<li><p><a class="reference internal" href="#poltofloatexpr">\PolToFloatExpr</a></p></li>
+<li><p><a class="reference internal" href="#poltoexproneterm">\PolToExprOneTerm</a></p></li>
+<li><p><a class="reference internal" href="#poltofloatexproneterm">\PolToFloatExprOneTerm</a></p></li>
+<li><p><a class="reference internal" href="#poltoexprcmd">\PolToExprCmd</a></p></li>
+<li><p><a class="reference internal" href="#id36">\PolToFloatExprCmd</a></p></li>
+<li><p><a class="reference internal" href="#poltoexprtermprefix">\PolToExprTermPrefix</a></p></li>
+<li><p><a class="reference internal" href="#poltoexprvar">\PolToExprVar</a></p></li>
+<li><p><a class="reference internal" href="#poltoexprtimes">\PolToExprTimes</a></p></li>
+</ul>
+</li>
+<li><p>improvements:</p>
+<ul>
+<li><p>documentation has a table of contents, internal hyperlinks,
+standardized signature notations and added explanations.</p></li>
+<li><p>one can do <span class="docutils literal"><span class="pre">\PolLet{g}={f}</span></span> or <span class="docutils literal"><span class="pre">\PolLet{g}{f}</span></span>.</p></li>
+<li><p><span class="docutils literal">\PolToExpr{f}</span> is highly customizable.</p></li>
+<li><p><a class="reference internal" href="#poldef">\poldef</a> and other defining macros prepare the polynomial
+functions for usage within <span class="docutils literal">\xintthefloatexpr</span> (or
+<span class="docutils literal">\xintdeffloatvar</span>). Coefficients are pre-rounded to the
+floating point precision. Indispensible for numerical algorithms,
+as exact fractions, even reduced, quickly become very big. See the
+documentation about how to use the exact polynomials also in
+floating point context.</p>
+<p><strong>Attention</strong>: this has been reverted at <span class="docutils literal">0.4</span>. The macro
+<a class="reference internal" href="#polgenfloatvariant">\PolGenFloatVariant</a> must be used for
+generation floating point polynomial functions.</p>
+</li>
+</ul>
+</li>
+</ul>
+</li>
+<li><p>v0.3.1 (2018/01/18)</p>
+<p>Fixes two typos in example code included in the documentation.</p>
+</li>
+<li><p>v0.4 (2018/02/16)</p>
+<ul>
+<li><p>bug fixes:</p>
+<ul class="simple">
+<li><p>when Euclidean division gave a zero remainder, the internal
+representation of this zero polynomial could be faulty; this
+could cause mysterious bugs in conjunction with other package
+macros such as <a class="reference internal" href="#polmapcoeffs">\PolMapCoeffs</a>.</p></li>
+<li><p><a class="reference internal" href="#polgcd">\PolGCD</a> was buggy in case of first polynomial being
+of lesser degree than the second one.</p></li>
+</ul>
+</li>
+<li><p>breaking changes:</p>
+<ul>
+<li><p>formerly <a class="reference internal" href="#polevalat">\PolEval{P}\At{foo}</a> allowed <span class="docutils literal">foo</span> to
+be an expression, which was transparently handled via
+<span class="docutils literal">\xinttheexpr</span>. Now, <span class="docutils literal">foo</span> must be a fraction (or a macro
+expanding to such) in the format acceptable by <span class="docutils literal">xintfrac.sty</span>
+macros. Use <a class="reference internal" href="#polevalatexpr">\PolEval{P}\AtExpr{foo}</a> for more
+general arguments using expression syntax. E.g., if <span class="docutils literal">foo</span> is the
+name of a variable known to <span class="docutils literal">\xintexpr</span>.</p>
+<p>The same holds for <a class="reference internal" href="#polevalreducedat">\PolEvalReduced</a>
+and <a class="reference internal" href="#polfloatevalat">\PolFloatEval</a>.</p>
+</li>
+<li><p>the <span class="docutils literal">3.0</span> automatic generation of floating point variants has
+been reverted. Not only do <em>not</em> the package macros automatically
+generate floating point variants of newly created polynomials,
+they actually make pre-existing such variant undefined.</p>
+<p>See <a class="reference internal" href="#polgenfloatvariant">\PolGenFloatVariant</a>.</p>
+</li>
+</ul>
+</li>
+<li><p>new non-expandable macros:</p>
+<ul class="simple">
+<li><p><a class="reference internal" href="#polgenfloatvariant">\PolGenFloatVariant</a></p></li>
+<li><p><a class="reference internal" href="#polgloballet">\PolGlobalLet</a></p></li>
+<li><p><a class="reference internal" href="#poltypesetone">\PolTypesetOne</a></p></li>
+<li><p><a class="reference internal" href="#polquo">\PolQuo</a></p></li>
+<li><p><a class="reference internal" href="#polrem">\PolRem</a></p></li>
+<li><p><a class="reference internal" href="#poltosturm">\PolToSturm</a></p></li>
+<li><p><a class="reference internal" href="#id12">\PolToSturm*</a></p></li>
+<li><p><a class="reference internal" href="#polsettosturmchainsignchangesat">\PolSetToSturmChainSignChangesAt</a></p></li>
+<li><p><a class="reference internal" href="#polsettonbofzeroswithin">\PolSetToNbOfZerosWithin</a></p></li>
+<li><p><a class="reference internal" href="#polsturmisolatezeros">\PolSturmIsolateZeros</a></p></li>
+<li><p><a class="reference internal" href="#polrefineinterval">\PolRefineInterval*</a></p></li>
+<li><p><a class="reference internal" href="#polrefineinterval-n">\PolRefineInterval[N]</a></p></li>
+<li><p><a class="reference internal" href="#polensureintervallength">\PolEnsureIntervalLength</a></p></li>
+<li><p><a class="reference internal" href="#polensureintervallengths">\PolEnsureIntervalLengths</a></p></li>
+<li><p><a class="reference internal" href="#polprintintervals">\PolPrintIntervals</a></p></li>
+<li><p><a class="reference internal" href="#polprintintervalsprintexactzero">\PolPrintIntervalsPrintExactZero</a></p></li>
+<li><p><a class="reference internal" href="#polprintintervalsprintleftendpoint">\PolPrintIntervalsPrintLeftEndPoint</a></p></li>
+<li><p><a class="reference internal" href="#polprintintervalsprintrightendpoint">\PolPrintIntervalsPrintRightEndPoint</a></p></li>
+<li><p><a class="reference internal" href="#id23">\PolReduceCoeffs*</a></p></li>
+<li><p><a class="reference internal" href="#polmakemonic">\PolMakeMonic</a></p></li>
+</ul>
+</li>
+<li><p>new expandable macros:</p>
+<ul class="simple">
+<li><p><a class="reference internal" href="#poltoexpronetermstylea">\PolToExprOneTermStyleA</a></p></li>
+<li><p><a class="reference internal" href="#polifcoeffisplusorminusone">\PolIfCoeffIsPlusOrMinusOne</a></p></li>
+<li><p><a class="reference internal" href="#polleadingcoeff">\PolLeadingCoeff</a></p></li>
+<li><p><a class="reference internal" href="#polsturmchainlength">\PolSturmChainLength</a></p></li>
+<li><p><a class="reference internal" href="#polsturmnbofisolatedzeros">\PolSturmNbOfIsolatedZeros</a></p></li>
+<li><p><a class="reference internal" href="#polsturmifzeroexactlyknown">\PolSturmIfZeroExactlyKnown</a></p></li>
+<li><p><a class="reference internal" href="#polsturmisolatedzeroleft">\PolSturmIsolatedZeroLeft</a></p></li>
+<li><p><a class="reference internal" href="#polsturmisolatedzeroright">\PolSturmIsolatedZeroRight</a></p></li>
+<li><p><span class="docutils literal">\PolPrintIntervalsTheEndPoint</span> (removed at 0.7)</p></li>
+<li><p><a class="reference internal" href="#polprintintervalstheindex">\PolPrintIntervalsTheIndex</a></p></li>
+<li><p><span class="docutils literal">\PolIfEndPointIsPositive</span> (removed at 0.7)</p></li>
+<li><p><span class="docutils literal">\PolIfEndPointIsNegative</span> (removed at 0.7)</p></li>
+<li><p><span class="docutils literal">\PolIfEndPointIsZero</span> (removed at 0.7)</p></li>
+<li><p><a class="reference internal" href="#polintervalwidth">\PolIntervalWidth</a></p></li>
+<li><p><a class="reference internal" href="#poldectostring">\PolDecToString</a></p></li>
+</ul>
+</li>
+<li><p>improvements:</p>
+<p>The main new feature is implementation of the <a class="reference external" href="https://en.wikipedia.org/wiki/Sturm%27s_theorem">Sturm algorithm</a>
+for localization of the real roots of polynomials.</p>
+</li>
+</ul>
+</li>
+<li><p>v0.4.1 (2018/03/01)</p>
+<p>Synced with xint 1.3.</p>
+</li>
+<li><p>v0.4.2 (2018/03/03)</p>
+<p>Documentation fix.</p>
+</li>
+<li><p>v0.5 (2018/04/08)</p>
+<ul class="simple">
+<li><p>bug fixes:</p>
+<ul>
+<li><p><a class="reference internal" href="#polget-polname-fromarray-macro">\PolGet{polname}\fromarray\macro</a> crashed when <span class="docutils literal">\macro</span> was
+an <a class="reference external" href="http://www.ctan.org/pkg/xint">xinttools</a> array macro with no items. It now produces the zero
+polynomial.</p></li>
+</ul>
+</li>
+<li><p>breaking changes:</p>
+<ul>
+<li><p><a class="reference internal" href="#poltosturm">\PolToSturm</a> creates primitive integer coefficients polynomials.
+This speeds up localization of roots via
+<a class="reference internal" href="#polsturmisolatezeros">\PolSturmIsolateZeros</a>. In case of user protests the author
+will make available again the code producing the bona fide Sturm
+polynomials as used formerly.</p></li>
+<li><p>polynomials created from <a class="reference internal" href="#polfromcsv">\PolFromCSV</a> or <a class="reference internal" href="#polget">\PolGet</a>
+get their coefficients normalized via <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a>'s <span class="docutils literal">\xintRaw</span>.</p></li>
+</ul>
+</li>
+<li><p>experimental change:</p>
+<ul>
+<li><p>optional argument to <a class="reference internal" href="#polsturmisolatezeros">\PolSturmIsolateZeros</a> (see <a class="reference internal" href="#the-degree-41-polynomial-with-2-1-9-1-8-0-0-1-1-9-2-as-roots">The
+degree 41 polynomial with -2, -1.9, -1.8, ..., 0, 0.1, ..., 1.9, 2
+as roots</a> for usage). It will presumably be replaced in future by
+an interval specification.</p></li>
+</ul>
+</li>
+<li><p>new non-expandable macro:</p>
+<ul>
+<li><p><a class="reference internal" href="#polmakeprimitive">\PolMakePrimitive</a></p></li>
+</ul>
+</li>
+<li><p>new expandable macro:</p>
+<ul>
+<li><p><a class="reference internal" href="#policontent">\PolIContent</a></p></li>
+</ul>
+</li>
+</ul>
+</li>
+<li><p>v0.5.1 (2018/04/22)</p>
+<ul class="simple">
+<li><p>new feature:</p>
+<ul>
+<li><p>the character <span class="docutils literal">'</span> can be used in polynomial names.</p></li>
+</ul>
+</li>
+</ul>
+</li>
+<li><p>v0.6 (2018/11/20)</p>
+<ul class="simple">
+<li><p>bugfix:</p>
+<ul>
+<li><p>the starred variant <a class="reference internal" href="#id13">\PolToSturm*{polname}{sturmname}</a> was
+broken. On the occasion of the fix, its meaning has been modified,
+see its documentation.</p></li>
+<li><p>using <a class="reference internal" href="#poltosturm">\PolToSturm</a> with a constant polynomial
+caused a division by zero error.</p></li>
+</ul>
+</li>
+<li><p>new macro:</p>
+<ul>
+<li><p><a class="reference internal" href="#id14">\PolSturmIsolateZeros*</a>
+acts like the <a class="reference internal" href="#polsturmisolatezeros">non-starred variant</a> then computes all the multiplicities.</p></li>
+</ul>
+</li>
+<li><p>new expandable macros:</p>
+<ul>
+<li><p><a class="reference internal" href="#polsturmisolatedzeromultiplicity-sturmname-index">\PolSturmIsolatedZeroMultiplicity{sturmname}{index}</a></p></li>
+<li><p><a class="reference internal" href="#polsturmnbofrootsof-sturmname-lessthanorequalto-value">\PolSturmNbOfRootsOf{sturmname}\LessThanOrEqualTo{value}</a></p></li>
+<li><p><a class="reference internal" href="#polsturmnbofrootsof-sturmname-lessthanorequaltoexpr-expression">\PolSturmNbOfRootsOf{sturmname}\LessThanOrEqualToExpr{expression}</a></p></li>
+<li><p><a class="reference internal" href="#polsturmnbwithmultofrootsof-sturmname-lessthanorequalto-value">\PolSturmNbWithMultOfRootsOf{sturmname}\LessThanOrEqualTo{value}</a></p></li>
+<li><p><a class="reference internal" href="#polsturmnbwithmultofrootsof-sturmname-lessthanorequaltoexpr-expression">\PolSturmNbWithMultOfRootsOf{sturmname}\LessThanOrEqualToExpr{expression}</a></p></li>
+</ul>
+</li>
+</ul>
+</li>
+<li><p>v0.7 (2018/12/08), v0.7.1 (bugfix), v0.7.2 (2nd bugfix) (2018/12/09)</p>
+<ul class="simple">
+<li><p>breaking changes:</p>
+<ul>
+<li><p>although <a class="reference internal" href="#polprintintervals-varname-sturmname">\PolPrintIntervals[varname]{sturmname}</a> default output
+remains the same, some auxiliary macros for user-customization
+have been removed: <span class="docutils literal">\PolPrintIntervalsTheEndPoint</span>,
+<span class="docutils literal"><span class="pre">\PolIfEndPointIsPositive{A}{B}</span></span>,
+<span class="docutils literal"><span class="pre">\PolIfEndPointIsNegative{A}{B}</span></span>, and
+<span class="docutils literal"><span class="pre">\PolIfEndPointIsZero{A}{B}</span></span>.</p></li>
+</ul>
+</li>
+<li><p>bugfix:</p>
+<ul>
+<li><p>it could happen that, contrarily to documentation, an interval
+computed by <a class="reference internal" href="#polsturmisolatezeros-sturmname">\PolSturmIsolateZeros{sturmname}</a> had zero as an
+endpoint,</p></li>
+<li><p><a class="reference internal" href="#polensureintervallength-sturmname-index-e">\PolEnsureIntervalLength{sturmname}{index}{E}</a> could under
+certain circumstances erroneously replace a non-zero root by
+zero,</p></li>
+<li><p><a class="reference internal" href="#polensureintervallengths-sturmname-e">\PolEnsureIntervalLengths{sturmname}{E}</a> crashed when used with
+a polynomial with no real roots, hence for which no isolation intervals
+existed (thanks to Thomas Söll for report).</p></li>
+</ul>
+</li>
+<li><p>new macros:</p>
+<ul>
+<li><p><a class="reference internal" href="#id17">\PolSturmIsolateZeros**{sturmname}</a></p></li>
+<li><p><a class="reference internal" href="#polsturmisolatezerosgetmultiplicitiesandrationalroots-sturmname">\PolSturmIsolateZerosGetMultiplicitiesAndRationalRoots{sturmname}</a></p></li>
+<li><p><a class="reference internal" href="#polsturmisolatezerosandfindrationalroots-sturmname">\PolSturmIsolateZerosAndFindRationalRoots{sturmname}</a></p></li>
+<li><p><a class="reference internal" href="#polexprsetup">\polexprsetup</a></p></li>
+<li><p><a class="reference internal" href="#id21">\PolPrintIntervals*</a></p></li>
+<li><p><a class="reference internal" href="#polprintintervalsnorealroots">\PolPrintIntervalsNoRealRoots</a></p></li>
+<li><p><a class="reference internal" href="#polprintintervalsbeginenv">\PolPrintIntervalsBeginEnv</a></p></li>
+<li><p><a class="reference internal" href="#polprintintervalsendenv">\PolPrintIntervalsEndEnv</a></p></li>
+<li><p><a class="reference internal" href="#polprintintervalsknownroot">\PolPrintIntervalsKnownRoot</a></p></li>
+<li><p><a class="reference internal" href="#polprintintervalsunknownroot">\PolPrintIntervalsUnknownRoot</a></p></li>
+<li><p><a class="reference internal" href="#polprintintervalsprintmultiplicity">\PolPrintIntervalsPrintMultiplicity</a></p></li>
+</ul>
+</li>
+<li><p>new expandable macros:</p>
+<ul>
+<li><p><a class="reference internal" href="#polsturmnbofrationalroots-sturmname">\PolSturmNbOfRationalRoots{sturmname}</a></p></li>
+<li><p><a class="reference internal" href="#polsturmnbofrationalrootswithmultiplicities-sturmname">\PolSturmNbOfRationalRootsWithMultiplicities{sturmname}</a></p></li>
+<li><p><a class="reference internal" href="#polsturmrationalroot-sturmname-k">\PolSturmRationalRoot{sturmname}{k}</a></p></li>
+<li><p><a class="reference internal" href="#polsturmrationalrootindex-sturmname-k">\PolSturmRationalRootIndex{sturmname}{k}</a></p></li>
+<li><p><a class="reference internal" href="#polsturmrationalrootmultiplicity-sturmname-k">\PolSturmRationalRootMultiplicity{sturmname}{k}</a></p></li>
+<li><p><a class="reference internal" href="#polprintintervalsthevar">\PolPrintIntervalsTheVar</a></p></li>
+<li><p><a class="reference internal" href="#polprintintervalsthesturmname">\PolPrintIntervalsTheSturmName</a></p></li>
+<li><p><a class="reference internal" href="#polprintintervalsthemultiplicity">\PolPrintIntervalsTheMultiplicity</a></p></li>
+</ul>
+</li>
+</ul>
+</li>
+<li><p>v0.7.3 (2019/02/04)</p>
+<ul class="simple">
+<li><p>bugfix:</p>
+<ul>
+<li><p>Debugging information not destined to user showed in log if root
+finding was done under <span class="docutils literal">\xintverbosetrue</span> regime.</p></li>
+<li><p><a class="reference internal" href="#polprintintervalsthevar">\PolPrintIntervalsTheVar</a> remained defined after
+<a class="reference internal" href="#polprintintervals">\PolPrintIntervals</a> but was left undefined after
+<a class="reference internal" href="#id21">\PolPrintIntervals*</a> (reported by Jürgen Gilg). Now remains
+defined in both cases, and <a class="reference internal" href="#polprintintervalsthesturmname">\PolPrintIntervalsTheSturmName</a>
+also.</p></li>
+<li><p>Polynomial names ending in digits caused errors (reported by Thomas
+Söll).</p></li>
+</ul>
+</li>
+</ul>
+</li>
+<li><p>v0.7.4 (2019/02/12)</p>
+<ul class="simple">
+<li><p>bugfix:</p>
+<ul>
+<li><p>20000000000 is too big for <span class="docutils literal">\numexpr</span>, shouldn't I know that?
+Thanks to Jürgen Gilg for report.</p></li>
+</ul>
+</li>
+</ul>
+</li>
+<li><p>v0.7.5 (2020/01/31)</p>
+<p>Synced with xintexpr 1.4. Requires it.</p>
+</li>
+<li><p>v0.8 (2021/03/29)</p>
+<p>Synced with xintexpr 1.4d. Requires it.</p>
+<ul class="simple">
+<li><p>breaking changes:</p>
+<ul>
+<li><p>As the usability of character <span class="docutils literal">'</span> in names has been extended
+from <span class="docutils literal">\poldef</span> to also generally <span class="docutils literal">\xintexpr</span>, <span class="docutils literal">\xintdefvar</span>,
+and <span class="docutils literal">\xintdeffunc</span>, it breaks there the infix operators
+<span class="docutils literal">'and'</span>, <span class="docutils literal">'or'</span>, <span class="docutils literal">'xor'</span> and <span class="docutils literal">'mod'</span>. See the <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a>
+documentation for the <span class="docutils literal">&amp;&amp;</span>, <span class="docutils literal">||</span>, <span class="docutils literal">xor()</span> and <span class="docutils literal">/:</span>
+alternatives.</p></li>
+<li><p><a class="reference internal" href="#poltoexpr">\PolToExpr</a> by default uses a catcode 12
+<span class="docutils literal">^</span>. See its documentation and the new configuration
+<a class="reference internal" href="#poltoexprcaret">\PolToExprCaret</a>.</p></li>
+</ul>
+</li>
+<li><p>deprecated:</p>
+<ul>
+<li><p>Usage of <span class="docutils literal">P/Q</span> for the euclidean quotient of two polynomials is
+deprecated. Start using <span class="docutils literal">quo(P,Q)</span> in its place.</p></li>
+</ul>
+</li>
+<li><p>bugfix:</p>
+<ul>
+<li><p>The <span class="docutils literal">\xintglobaldefstrue</span> setting was obeyed only partially
+by the polexpr macros defining polynomials.</p></li>
+<li><p>The <span class="docutils literal">\xintexpr</span> variables storing the values of the extremities
+of the intervals as found by <a class="reference internal" href="#polsturmisolatezeros">\PolSturmIsolateZeros</a> were not updated at 0.7.5 to the
+xintexpr 1.4 format and thus caused low-level TeX errors if used.</p></li>
+<li><p>Attempting to use in <span class="docutils literal">\poldef</span> a function previously declared
+via <span class="docutils literal">\xintdeffunc</span> which made usage of the indexing or slicing
+&quot;ople&quot; syntax typically caused <span class="docutils literal">TeX capacity exceeded</span> error.
+Indeed 0.7.5 only partially made polexpr able to cope with the
+extended possibilities for xintexpr 1.4 user-declared functions.
+Hopefully <span class="docutils literal">0.8</span> achieves full functionality in this context.</p></li>
+</ul>
+</li>
+<li><p>new macros:</p>
+<ul>
+<li><p><a class="reference internal" href="#polnewpolverbosefalse">\polnewpolverbosefalse</a></p></li>
+<li><p><a class="reference internal" href="#poltoexprcaret">\PolToExprCaret</a></p></li>
+<li><p><a class="reference internal" href="#poltoexprinvar">\PolToExprInVar</a></p></li>
+<li><p>alongside the major new functionalities described in the next item
+<a class="reference internal" href="#poltypeset">\PolTypeset</a> and <a class="reference internal" href="#poltoexpr">\PolToExpr</a> have
+been enhanced to accept as argument a general expression and not
+only a pre-declared polynomial name.</p></li>
+</ul>
+</li>
+<li><p>new features:</p>
+<ul>
+<li><p>The package is usable under Plain and probably most any TeX format,
+and not only under LaTeX.</p></li>
+<li><p>The core of the package has been rewritten entirely in order to
+start letting <span class="docutils literal">\xintexpr</span> recognize a polynomial type as a genuine
+variable. This has allowed:</p>
+<ul>
+<li><p>to solve the reduced inter-operability problems between polexpr
+and <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> which arose as consequences to the deep <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> <span class="docutils literal">1.4</span>
+evolution,</p></li>
+<li><p>to make available most of the functionality associated to
+expandable macros directly in the <span class="docutils literal">\xinteval</span> syntax as
+operators or functions,</p></li>
+<li><p>to provide (expandable) functional interface in <span class="docutils literal">\xinteval</span> to
+features previously available only via (for some, non-expandable)
+macro interface such as gcd computations.</p></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+<p>See the updated <a class="reference internal" href="#quick-syntax-overview">Quick syntax overview</a> and then <a class="reference internal" href="#polexpr08">the extended syntax
+description</a>.</p>
+</li>
+</ul>
+</div>
+<div class="section" id="acknowledgments">
+<h1><a class="toc-backref" href="#id205">Acknowledgments</a></h1>
+<p>Thanks to Jürgen Gilg whose question about <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> usage for
+differentiating polynomials was the initial trigger leading to this
+package, and to Jürgen Gilg and Thomas Söll for testing it on some
+concrete problems.</p>
+<p>Renewed thanks to them on occasion of the <span class="docutils literal">0.6</span>, <span class="docutils literal">0.7</span>, and <span class="docutils literal">0.8</span>
+releases for their continued interest.</p>
+<p>See README.md for the License.</p>
+</div>
+</div>
+</body>
+</html>
diff --git a/macros/generic/polexpr/polexpr.sty b/macros/generic/polexpr/polexpr.sty
new file mode 100644
index 0000000000..c94a4e8d61
--- /dev/null
+++ b/macros/generic/polexpr/polexpr.sty
@@ -0,0 +1,1057 @@
+% author: Jean-François Burnol
+% License: LPPL 1.3c (author-maintained)
+% Usage: \input polexpr.sty (Plain or other macro formats)
+% or \usepackage{polexpr} (LaTeX macro format)
+% polexpr.sty (this file) inputs:
+% polexprcore.tex
+% polexprexpr.tex
+% polexprsturm.tex
+\begingroup\catcode61\catcode48\catcode32=10\relax%
+ \catcode13=5 % ^^M
+ \endlinechar=13 %
+ \catcode123=1 % {
+ \catcode125=2 % }
+ \catcode64=11 % @
+ \catcode35=6 % #
+ \catcode44=12 % ,
+ \catcode45=12 % -
+ \catcode46=12 % .
+ \catcode58=12 % :
+ \def\z {\endgroup}%
+ \expandafter\let\expandafter\x\csname ver@polexpr.sty\endcsname
+ \expandafter\let\expandafter\w\csname ver@xintexpr.sty\endcsname
+ \expandafter
+ \ifx\csname PackageInfo\endcsname\relax
+ \def\y#1#2{\immediate\write-1{Package #1 Info: #2.}}%
+ \else
+ \def\y#1#2{\PackageInfo{#1}{#2}}%
+ \fi
+ \expandafter
+ % I don't think engine exists providing \expanded but not \numexpr
+ \ifx\csname expanded\endcsname\relax
+ \y{polexpr}{\expanded not available, aborting input}%
+ \aftergroup\endinput
+ \else
+ \ifx\x\relax % plain-TeX, first loading of polexpr.sty
+ \ifx\w\relax % but xintexpr.sty not yet loaded.
+ \expandafter\def\expandafter\z\expandafter
+ {\z\input xintexpr.sty\relax}%
+ \fi
+ \else
+ \def\empty {}%
+ \ifx\x\empty % LaTeX, first loading,
+ % variable is initialized, but \ProvidesPackage not yet seen
+ \ifx\w\relax % xintexpr.sty not yet loaded.
+ \expandafter\def\expandafter\z\expandafter
+ {\z\RequirePackage{xintexpr}[2021/02/20]}%
+ \fi
+ \else
+ \aftergroup\endinput % polexpr already loaded.
+ \fi
+ \fi
+ \fi
+\z%
+\XINTsetupcatcodes%
+\XINT_providespackage
+\ProvidesPackage{polexpr}%
+ [2021/03/29 v0.8 Polynomial expressions with rational coefficients (JFB)]%
+\begingroup
+ \def\x#1/#2/#3 #4\xint:{#1#2#3}%
+ \ifnum\expandafter\x\expanded{\csname ver@xintexpr.sty\endcsname}\xint:
+ <20210220 % actually 20200131 (xint 1.4) is presumably ok
+ \immediate\write128{! Package polexpr error: xintexpr too old, aborting input}%
+ \else\expandafter\xint_gobble_i
+ \fi
+\endinput\endgroup
+\let\PolDecToString\xintDecToString
+\long\def\POL@ifstar#1#2%
+{%
+ \begingroup\def\@tempa{#1}\def\@tempb{#2}%
+ \futurelet\@let@token\POL@@ifstar
+}%
+\def\POL@@ifstar
+{%
+ \xint_firstofone{\ifx} \@let@token\def\next{\POL@@again\POL@@ifstar}\else
+ \ifx*\@let@token\def\next##1{\expandafter\endgroup\@tempa}\else
+ \def\next{\expandafter\endgroup\@tempb}\fi\fi\next
+}%
+\xint_firstofone{\def\POL@@again#1} {\futurelet\@let@token#1}%
+\long\def\POL@chkopt#1[#2]%
+{%
+ \begingroup\def\@tempa{#1}\def\@tempb{#1[#2]}%
+ \futurelet\@let@token\POL@@ifopt
+}%
+\def\POL@@ifopt
+{%
+ \xint_firstofone{\ifx} \@let@token\def\next{\POL@@again\POL@@ifopt}\else
+ \ifx[\@let@token\def\next{\expandafter\endgroup\@tempa}\else %]
+ \def\next{\expandafter\endgroup\@tempb}\fi\fi\next
+}%
+% \polexprsetup added at 0.7
+\catcode`! 3
+\def\polexprsetup#1{\POL@setup_parsekeys #1,=!,\xint_bye}%
+\def\POL@setup_parsekeys #1=#2#3,{%
+ \ifx!#2\expandafter\xint_bye\fi
+ \csname POL@setup_setkey_\xint_zapspaces #1 \xint_gobble_i\endcsname
+ \xint_firstoftwo
+ {\PackageWarning{polexpr}{The \detokenize{#1} key is unknown! ignoring}}%
+ {\xintZapLastSpaces{#2#3}}%
+ \POL@setup_parsekeys
+}%
+\def\POL@setup_setkey_norr #1#2{\edef\POL@norr}%
+\def\POL@setup_setkey_sqfnorr #1#2{\edef\POL@sqfnorr}%
+\polexprsetup{norr=_norr, sqfnorr=_sqf_norr}
+\catcode`! 11 % special catcode for ! as used in xintexpr.sty
+%
+\newif\ifxintveryverbose
+\newif\ifpolnewpolverbose
+\newif\ifpoltypesetall
+\newif\ifpoltoexprall
+%%
+%% Main data format for non-expandable manipulations
+%%
+%% The main exchange structure is:
+%% N.\empty{coeff0}{coeff1}....{coeffN}
+%% It is stored in macros \POLuserpol@<name of polynomial>
+%% The \empty is basically there to avoid brace-stripping
+%% in some grabbing contexts (maybe I should revisit this)
+%%
+%% The zero polynomial is stored as -1.\empty{0/1[0]}
+%% Degree zero polynomials are 0.\empty{numeric value}
+%%
+%% Depending on input path the numeric values coeff0, coeff1, ...., coeffN
+%% may have been or not already converted into A/B[n] format.
+%% As a rule, computations are not followed with reducing the fractions
+%% to smallest terms; the innocent may be unaware that computing
+%% with fractions quickly give gigantic numbers. There is \PolReduceCoeffs
+%% to do that.
+%%
+%% This base structure is maintained at 0.8 for legacy reasons but perhaps I
+%% need to revisit this. A characteristic of the package so far is that it
+%% thus stores and manipulate polynomials basically as the complete sequence
+%% of coefficients, (using the xintfrac "zero" for missing coefficients) which
+%% means that it will handle poorly polynomials of high degrees such as X^500.
+%%
+%% Test if zero
+\def\POL@ifZero#1{\expandafter\POL@ifZero@aux#1;}%
+\def\POL@ifZero@aux #1#2;{\if-#1\expandafter\xint_firstoftwo
+ \else\expandafter\xint_secondoftwo
+ \fi}%
+%% Split into degree and coefficients
+% The \expandafter chain removes the \empty token
+\def\POL@split#1.#2;#3#4%
+ {\def#3{#1}\expandafter\def\expandafter#4\expandafter{#2}}%
+%% Define from values stored in a "macros-array"
+\def\POL@resultfromarray #1{%
+ \edef\POL@result{\ifnum\count@>\z@
+ \the\numexpr\count@-\@ne.\noexpand\empty
+ \xintiloop [1+1]%
+ \expandafter\POL@braceit\csname POL@array#1\xintiloopindex\endcsname
+ \ifnum\xintiloopindex<\count@
+ \repeat
+ \else-1.\noexpand\empty{0/1[0]}\fi}%
+}%
+\def\POL@braceit#1{{#1}}% needed as \xintiloopindex can not "see" through braces
+%%
+%% Conversion between legacy data storage and the one used for the
+%% the novel polexpr 0.8 notion of \xintexpr polynomial variables
+%%
+%% The 0.8 expandable implementation of core algebra is also manipulating
+%% the complete list of coefficients. The internal data structure is
+%% (this is the numeric leaf in xintexpr ople terminology) currently:
+%% PN.{coeff0}{coeff1}....{coeffN}
+%% where the P letter identifies the polynomial type.
+%% Here the degree N is *always* at least 1: if some evaluation ends
+%% up in a constant polynomial it will always be output as a genuine
+%% scalar numeric variable, as a rule in in A/B[n] format
+%%
+%% This is not definitive and I need to think about it more (in particular
+%% in the distant perspective of supporting multi-variable polynomials).
+%% However modifying this will be costly labor at this stage.
+%%
+\input polexprcore.tex\relax % load expandable algebra
+\def\POL@vartolegacy #1% \romannumeral\POL@vartolegacy ... \xint:
+{%
+ \if 0#1\xint_dothis\POL@vartolegacy@zero\fi
+ \if P#1\xint_dothis\POL@vartolegacy@pol\fi
+ \xint_orthat\POL@vartolegacy@scalar #1%
+}%
+\def\POL@vartolegacy@zero #1\xint:{\xint_c_ -1.\empty{0/1[0]}}%
+\def\POL@vartolegacy@scalar #1\xint:{\xint_c_ 0.\empty{#1}}%
+\def\POL@vartolegacy@pol P#1.#2\xint:{\xint_c_ #1.\empty#2}%
+%
+\def\POL@tovar#1{\romannumeral\expandafter\expandafter\expandafter
+ \POL@legacytovar\csname POLuserpol@#1\endcsname}%
+\def\POL@legacytovar #1.% \romannumeral\POL@legacytovar N.\empty{c0}...
+{%
+ \ifnum #1<\xint_c_i\xint_dothis\POL@legacytovar@scalar\fi
+ \xint_orthat\POL@legacytovar@pol #1.%
+}%
+\def\POL@legacytovar@scalar #1.\empty#2{\xint_c_ #2}%
+\def\POL@legacytovar@pol #1.\empty{\xint_c_ P#1.}%
+%%
+%% Extend \xintexpr (\xintdefvar, \xintdeffunc) to recognize the new
+%% polynomial type
+%%
+%% **** It does NOT apply to \xintfloatexpr context
+%%
+\input polexprexpr.tex\relax
+%%
+%% \poldef
+%%
+\def\PolDef{\POL@chkopt\POL@oPolDef[x]}%
+\def\POL@oPolDef[#1]#2#3{\poldef #2(#1):=#3;}%
+\def\poldef{\edef\POL@restoresemicolon{\catcode59=\the\catcode59\relax}%
+ \catcode59 12 \POL@defpol}%
+\def\POL@defpol #1(#2)#3=#4;{%
+ \POL@restoresemicolon
+ \edef\POL@polname{\xint_zapspaces #1 \xint_gobble_i}%
+\begingroup
+ \unless\ifxintveryverbose\xintverbosefalse\fi
+ %% RADICAL CHANGE AT 0.8:
+ %% we define a **variable** not a **function**
+ %% ever since polexpr initial version, a function was defined and
+ %% the associated macros was then deconstructed in further analysis
+ %% via non-expandable approach. At 0.8 the polynomial algebra has
+ %% been implemented expandably allowing direct plug-in into \xintexpr
+ \xintdefvar __pol = subs(#4,#2=qraw({{P1.{0/1[0]}{1/1[0]}}}));%
+ \expandafter
+\endgroup
+ \expandafter\def\expandafter\POL@result\expandafter
+ {\romannumeral0\expandafter\xint_stop_atfirstofone
+ \romannumeral0\csname XINT_expr_varvalue___pol\endcsname}%
+ \XINT_global\expandafter\def\csname POLuserpol@\POL@polname\expandafter\endcsname
+ \expandafter{\romannumeral\expandafter\POL@vartolegacy\POL@result\xint:}%
+ \expandafter\POL@newpol\expandafter{\POL@polname}%
+}%
+\def\POL@newpol#1{%
+ % 0.7.5 had some complicated special handling of constant
+ % polynomials, but these are complications of the past
+ % First a variable usable in \poldef but not in \xintexpr for arithmetic
+ % only for special dedicated functions such as coeff(), deg()
+ % (when they will be implemented). In \poldef, composition of polynomials
+ % in P(Q) syntax will be more efficient than P(Q(x)).
+ % This will use \XINT_global and obey \xintverbose... setting
+ \XINT_expr_defvar_one{#1}{{\POL@tovar{#1}}}%
+ % Second a function usable not only in \poldef but also in \xintexpr
+ % Will use \XINT_global
+ \POL@newpolhorner{#1}%
+ \POL@defpolfunc{#1}{expr}%
+ \XINT_global\expandafter\let\csname XINT_flexpr_func_#1\endcsname\@undefined
+ \ifpolnewpolverbose\POL@info{#1}\fi
+}%
+\def\POL@newfloatpol#1{%
+ \POL@newfloatpolhorner{#1}%
+ \POL@defpolfunc{#1}{flexpr}%
+ \ifpolnewpolverbose\POL@floatinfo{#1}%
+ \else
+ \ifxintverbose\POL@floatinfo{#1}\fi
+ \fi
+}%
+\def\POL@info #1{%
+ \xintMessage {polexpr}{Info}%
+ {Function #1 for the \string\xintexpr\space parser is
+ \ifxintglobaldefs(globally) \fi
+ associated to \string\XINT_expr_polfunc_#1\space
+ with meaning:
+ \expandafter\meaning
+ \csname XINT_expr_polfunc_#1\endcsname}%
+}%
+\def\POL@floatinfo #1{%
+ \xintMessage {polexpr}{Info}%
+ {Function #1 for the \string\xintfloatexpr\space parser is
+ \ifxintglobaldefs(globally) \fi
+ associated to \string\XINT_flexpr_polfunc_#1\space
+ with meaning:
+ \expandafter\meaning
+ \csname XINT_flexpr_polfunc_#1\endcsname}%
+}%
+%
+\def\POL@newpolhorner#1{%
+ \expandafter\expandafter\expandafter\POL@split
+ \csname POLuserpol@#1\endcsname;\POL@var@deg\POL@var@coeffs
+ \edef\POL@var@coeffs{\xintRevWithBraces{\POL@var@coeffs}}%
+ \begingroup
+ \expandafter\POL@newpol@horner\POL@var@coeffs\relax
+ \expandafter
+ \endgroup
+ \expandafter\XINT_global
+ \expandafter\def\csname XINT_expr_polfunc_#1\expandafter\endcsname
+ \expandafter##\expandafter1\expandafter{\POL@tmp{##1}}%
+}%
+\def\POL@newfloatpolhorner#1{%
+ %% redefine function to expand by Horner scheme. Is this useful?
+ %% perhaps bad idea for numerical evaluation of thing such as (1+x)^10?
+% note: I added {0/1[0]} item to zero polynomial also to facilitate this
+ \expandafter\expandafter\expandafter\POL@split
+ \csname POLuserpol@#1\endcsname;\POL@var@deg\POL@var@coeffs
+ \edef\POL@var@coeffs{\xintRevWithBraces{\POL@var@coeffs}}%
+ \begingroup
+ \expandafter\POL@newpol@floathorner\POL@var@coeffs\relax
+ \expandafter
+ \endgroup
+ \expandafter\def\csname XINT_flexpr_polfunc_#1\expandafter\endcsname
+ \expandafter##\expandafter1\expandafter{\POL@tmp{##1}}%
+}%
+\def\POL@newpol@horner#1{\let\xintPolAdd\relax\let\xintPolMul\relax
+ \def\POL@tmp##1{#1}\POL@newpol@horner@loop.}%
+\def\POL@newpol@horner@loop.#1{%
+ \if\relax#1\expandafter\xint_gob_til_dot\fi
+ \edef\POL@tmp##1{\xintiiifZero{#1}
+ {\xint_firstofone}{\xintPolAdd{#1}}%
+ {\xintPolMul{##1}{\POL@tmp{##1}}}}%
+ \POL@newpol@horner@loop.%
+}%
+\def\POL@newpol@floathorner#1{\let\XINTinFloatAdd\relax\let\XINTinFloatMul\relax
+ \edef\POL@tmp##1{\XINTinFloatdigits{#1}}%
+ \POL@newpol@floathorner@loop.}%
+\def\POL@newpol@floathorner@loop.#1{%
+ \if\relax#1\expandafter\xint_gob_til_dot\fi
+ \edef\POL@tmp##1{\xintiiifZero{#1}
+ {\xint_firstofone}{\XINTinFloatAdd{\XINTinFloatdigits{#1}}}%
+ {\XINTinFloatMul{##1}{\POL@tmp{##1}}}}%
+ \POL@newpol@floathorner@loop.%
+}%
+%%
+%% Non-expandable polynomial manipulations
+%%
+\def\PolGenFloatVariant#1{\POL@newfloatpol{#1}}%
+%
+\def\PolLet#1#2{\if=\noexpand#2\expandafter\xint_firstoftwo
+ \else\expandafter\xint_secondoftwo\fi
+ \POL@@let\POL@let{#1}{#2}}%
+\def\POL@@let#1#2#3{\POL@let{#1}{#3}}%
+\def\POL@let#1#2{%
+ \XINT_global
+ \expandafter\let\csname POLuserpol@#1\expandafter\endcsname
+ \csname POLuserpol@#2\endcsname
+ \XINT_expr_defvar_one{#1}{{\POL@tovar{#1}}}%
+ \XINT_global
+ \expandafter\let\csname XINT_expr_polfunc_#1\expandafter\endcsname
+ \csname XINT_expr_polfunc_#2\endcsname
+ \POL@defpolfunc{#1}{expr}%
+ \ifpolnewpolverbose\POL@info{#1}\fi
+}%
+\def\PolGlobalLet#1#2{\begingroup\xintglobaldefstrue\PolLet{#1}{#2}\endgroup}
+%
+\def\PolAssign#1{\def\POL@polname{#1}\POL@assign}% zap spaces in #1?
+\def\POL@assign#1\toarray#2{%
+ \expandafter\expandafter\expandafter\POL@split
+ \csname POLuserpol@\POL@polname\endcsname;\POL@var@deg\POL@var@coeffs
+ \xintAssignArray\POL@var@coeffs\to#2%
+ % modify \#200 macro to return 0/1[0] for out of range indices
+ \@namedef{\xint_arrayname00}##1##2##3{%
+ \@namedef{\xint_arrayname00}####1{%
+ \ifnum####1>##1 \xint_dothis{ 0/1[0]}\fi
+ \ifnum####1>\m@ne \xint_dothis
+ {\expandafter\expandafter\expandafter##3%
+ \csname##2####1\endcsname}\fi
+ \unless\ifnum-####1>##1 \xint_dothis
+ {\expandafter\expandafter\expandafter##3%
+ \csname##2\the\numexpr##1+####1+\@ne\endcsname}\fi
+ \xint_orthat{ 0/1[0]}}% space stops a \romannumeral0
+ }%
+ \csname\xint_arrayname00\expandafter\expandafter\expandafter\endcsname
+ \expandafter\expandafter\expandafter
+ {\csname\xint_arrayname0\expandafter\endcsname\expandafter}\expandafter
+ {\xint_arrayname}{ }%
+}%
+\def\PolGet{}%
+\def\PolGet#1#2\fromarray#3{%
+ \begingroup % closed in \POL@getfromarray
+ \POL@getfromarray{#1}{#3}%
+ \POL@newpol{#1}%
+}%
+\def\POL@getfromarray#1#2{%
+ \count@=#2{0} %<- intentional space
+ \ifnum\count@=\z@
+ \def\POL@result{-1.\empty{0/1[0]}}% 0.5 fix for empty array
+ \else
+ \xintloop
+ \edef\POL@tmp{#2{\count@}}%
+ \edef\POL@tmp{\xintRaw{\POL@tmp}}%
+% sadly xinttools (current 1.3a) arrays have no setters for individual items...
+ \expandafter\let\csname POL@tmparray\the\count@\endcsname\POL@tmp
+ \if0\xintiiSgn{\POL@tmp}%
+ \advance\count@\m@ne
+ \repeat
+ \count\tw@\count@
+ \xintloop
+ \ifnum\count@>\@ne
+ \advance\count@\m@ne
+ \edef\POL@tmp{#2{\count@}}%
+ \edef\POL@tmp{\xintRaw{\POL@tmp}}%
+ \expandafter\let\csname POL@tmparray\the\count@\endcsname\POL@tmp
+ \repeat
+ \count@\count\tw@
+ \def\POL@tmp##1.{{\csname POL@tmparray##1\endcsname}}%
+ \edef\POL@result{\the\numexpr\count@-\@ne.\noexpand\empty
+ \xintiloop[1+1]%
+ \expandafter\POL@tmp\xintiloopindex.%
+ \ifnum\xintiloopindex<\count@
+ \repeat}%
+ \fi
+ \expandafter
+ \endgroup
+ \expandafter
+ \XINT_global
+ \expandafter
+ \def\csname POLuserpol@#1\expandafter\endcsname
+ \expandafter{\POL@result}%
+}%
+%
+\def\PolFromCSV#1#2{%
+ \begingroup % closed in \POL@getfromarray
+ \xintAssignArray\xintCSVtoList{#2}\to\POL@arrayA
+ \POL@getfromarray{#1}\POL@arrayA
+ \POL@newpol{#1}%
+}%
+%
+\def\PolMapCoeffs#1#2{% #1 = macro, #2 = name
+ \POL@mapcoeffs{#1}{#2}%
+ \POL@newpol{#2}%
+}%
+\def\POL@mapcoeffs#1#2{%
+ \begingroup
+ \def\POL@mapcoeffs@macro{#1}%
+ \expandafter\expandafter\expandafter\POL@split
+ \csname POLuserpol@#2\endcsname;\POL@mapcoeffs@deg\POL@mapcoeffs@coeffs
+% ATTENTION à ne pas faire un \expandafter ici, car brace removal si 1 item
+ \xintAssignArray\POL@mapcoeffs@coeffs\to\POL@arrayA
+ \def\index{0}%
+ \count@\z@
+ \expandafter\POL@map@loop\expandafter.\POL@mapcoeffs@coeffs\relax
+ \xintloop
+% this abuses that \POL@arrayA0 is never 0.
+ \xintiiifZero{\csname POL@arrayA\the\count@\endcsname}%
+ {\iftrue}%
+ {\iffalse}%
+ \advance\count@\m@ne
+ \repeat
+% donc en sortie \count@ est 0 ssi pol nul.
+ \POL@resultfromarray A%
+ \expandafter
+ \endgroup
+ \expandafter
+ \XINT_global
+ \expandafter
+ \def\csname POLuserpol@#2\expandafter\endcsname\expandafter{\POL@result}%
+}%
+\def\POL@map@loop.#1{\if\relax#1\expandafter\xint_gob_til_dot\fi
+ \advance\count@\@ne
+ \edef\POL@map@coeff{\POL@mapcoeffs@macro{#1}}%
+ \expandafter
+ \let\csname POL@arrayA\the\count@\endcsname\POL@map@coeff
+ \edef\index{\the\numexpr\index+\@ne}%
+ \POL@map@loop.}%
+%
+\def\POL@xintIrr#1{\xintIrr{#1}[0]}%
+\def\PolReduceCoeffs{\POL@ifstar\POL@sreducecoeffs\POL@reducecoeffs}%
+\def\POL@reducecoeffs#1{\PolMapCoeffs{\POL@xintIrr}{#1}}%
+\def\POL@sreducecoeffs#1{\PolMapCoeffs{\xintPIrr}{#1}}%
+%
+\def\PolMakeMonic#1{%
+ \edef\POL@leadingcoeff{\PolLeadingCoeff{#1}}%
+ \edef\POL@leadingcoeff@inverse{\xintDiv{1/1[0]}{\POL@leadingcoeff}}%
+ \PolMapCoeffs{\xintMul{\POL@leadingcoeff@inverse}}{#1}%
+}%
+%
+%% \PolMakePrimitive (0.5)
+% This uses expandable \PolIContent
+% Note: the integer coefficients stored in A/1[n] form with
+% A not having trailing zeroes, due to usage of \xintREZ here.
+\def\POL@makeprim@macro#1%
+ {\xintREZ{\xintNum{\xintDiv{#1}{\POL@makeprim@icontent}}}}%
+\def\PolMakePrimitive#1{%
+ % This does not need a full user declared polynomial on input, only
+ % a \POLuserpol@name macro, but on output it is fully declared
+ \edef\POL@makeprim@icontent{\PolIContent{#1}}%
+ \PolMapCoeffs\POL@makeprim@macro{#1}%
+}%
+\def\POL@makeprimitive#1{%
+ % Avoids declaring the polynomial, internal usage in \PolToSturm
+ \edef\POL@makeprim@icontent{\PolIContent{#1}}%
+ \POL@mapcoeffs\POL@makeprim@macro{#1}%
+}%
+%
+%% Euclidean division
+% now based on the expandable routine from polexprcore.tex
+%
+\def\PolDivide#1#2#3#4{% #3=quotient, #4=remainder of #1 by #2
+ \POL@divide{#1}{#2}%
+ \XINT_global\expandafter\let\csname POLuserpol@#3\endcsname\POL@Q
+ \POL@newpol{#3}%
+ \XINT_global\expandafter\let\csname POLuserpol@#4\endcsname\POL@R
+ \POL@newpol{#4}%
+}%
+\def\PolQuo#1#2#3{% #3=quotient of #1 by #2
+ \POL@divide{#1}{#2}%
+ \XINT_global\expandafter\let\csname POLuserpol@#3\endcsname\POL@Q
+ \POL@newpol{#3}%
+}%
+\def\PolRem#1#2#3{% #3=remainder of #1 by #2
+ \POL@divide{#1}{#2}%
+ \XINT_global\expandafter\let\csname POLuserpol@#3\endcsname\POL@R
+ \POL@newpol{#3}%
+}%
+\def\POL@divide#1#2{%
+ % much simpler at 0.8 thanks to our expandable macros
+ \xintAssign\xintPolQuoRem{\POL@tovar{#1}}{\POL@tovar{#2}}\to\POL@Q\POL@R
+ \odef\POL@Q{\romannumeral\expandafter\POL@vartolegacy\POL@Q\xint:}%
+ \odef\POL@R{\romannumeral\expandafter\POL@vartolegacy\POL@R\xint:}%
+}%
+%% Euclidean special pseudo-remainder
+\def\POL@getprem#1#2{%
+ \let\POL@Q\undefined % trap errors in Sturm code update to use \POL@prem
+ % this was simpler before I converted \xintPolPRem into returning a tuple...
+ \odef\POL@R{\romannumeral\expandafter\POL@vartolegacy
+ \romannumeral0\expandafter\xint_stop_atsecondoftwo
+ \romannumeral`&&@\xintPolPRem{\POL@tovar{#1}}{\POL@tovar{#2}}%
+ \xint:}%
+}%
+%
+%%%%%%%%%%%%
+%%
+%% Things are currenly implemented twice : here the legacy macros
+%% such as GCD or Diff, and in polexprcore.tex the expandable
+%% support macros for the \xinteval interface.
+%%
+%% Soon, I will probably remove all legacy code (like I did already
+%% for division) and make the user macros simple wrappers to the
+%% expandable code.
+%%
+%% But for 0.8 release, I preferred not to yet, as I did not have
+%% really the time to compare speed. Usage of the "special
+%% pseudo euclidean remainder" (expandable) code in Sturm chain
+%% construction proved very beneficial as it divided by 3 the
+%% \PolToSturm execution time on the Wilkinson perturbed type 1
+%% example in the documentation.
+%%
+%%%%%%%%%%%%
+%
+%% GCD
+%
+% It seems I didn't even use here the (now deleted) macros implementing
+% division, and I redid here what was needed: this code, which I leave
+% standing as I have other priorities, does not use the \POL@divide !
+%
+\def\PolGCD#1#2#3{% sets #3 to the (unitary) G.C.D. of #1 and #2
+ \POL@GCD{#1}{#2}{#3}%
+ \POL@newpol{#3}%
+}%
+\def\POL@GCD #1#2#3{%
+ \begingroup
+ \expandafter\let\expandafter\POL@A\csname POLuserpol@#1\endcsname
+ \expandafter\let\expandafter\POL@B\csname POLuserpol@#2\endcsname
+ \expandafter\POL@split\POL@A;\POL@degA\POL@polA
+ \expandafter\POL@split\POL@B;\POL@degB\POL@polB
+ \ifnum\POL@degA<\z@
+ \expandafter\xint_firstoftwo\else\expandafter\xint_secondoftwo
+ \fi
+ {\ifnum\POL@degB<\z@
+ \expandafter\xint_firstoftwo\else\expandafter\xint_secondoftwo
+ \fi
+ {\def\POL@result{-1.\empty{0/1[0]}}}%
+ {\xintAssignArray\POL@polB\to\POL@arrayB
+ \POL@normalize{B}%
+ \POL@gcd@exit BA}}%
+ {\ifnum\POL@degB<\z@
+ \expandafter\xint_firstoftwo\else\expandafter\xint_secondoftwo
+ \fi
+ {\xintAssignArray\POL@polA\to\POL@arrayA
+ \POL@normalize{A}%
+ \POL@gcd@exit AB}%
+ {\ifnum\POL@degA<\POL@degB\space
+ \let\POL@tmp\POL@B\let\POL@B\POL@A\let\POL@A\POL@tmp
+ \let\POL@tmp\POL@degB\let\POL@degB\POL@degA\let\POL@degA\POL@tmp
+ \let\POL@tmp\POL@polB\let\POL@polB\POL@polA\let\POL@polA\POL@tmp
+ \fi
+ \xintAssignArray\POL@polA\to\POL@arrayA
+ \xintAssignArray\POL@polB\to\POL@arrayB
+ \POL@gcd AB%
+ }}%
+ \expandafter
+ \endgroup
+ \expandafter
+ \XINT_global
+ \expandafter\def\csname POLuserpol@#3\expandafter\endcsname
+ \expandafter{\POL@result}%
+}%
+\def\POL@normalize#1{%
+ \expandafter\def\expandafter\POL@tmp\expandafter
+ {\csname POL@array#1\csname POL@array#10\endcsname\endcsname}%
+ \edef\POL@normalize@leading{\POL@tmp}%
+ \expandafter\def\POL@tmp{1/1[0]}%
+ \count@\csname POL@deg#1\endcsname\space
+ \xintloop
+ \ifnum\count@>\z@
+ \expandafter\edef\csname POL@array#1\the\count@\endcsname
+ {\xintIrr{\xintDiv
+ {\csname POL@array#1\the\count@\endcsname}%
+ {\POL@normalize@leading}}[0]}%
+ \advance\count@\m@ne
+ \repeat
+}%
+\def\POL@gcd#1#2{%
+ \POL@normalize{#2}%
+ \edef\POL@degQ{\the\numexpr\csname POL@deg#1\endcsname
+ -\csname POL@deg#2\endcsname}%
+ \count@\numexpr\csname POL@deg#1\endcsname+\@ne\relax
+ \count\tw@\numexpr\POL@degQ+\@ne\relax
+ \xintloop
+ \POL@gcd@getremainder@loopbody#1#2%
+ \ifnum\count\tw@>\z@
+ \repeat
+ \expandafter\def\csname POL@array#10\endcsname{1}%
+ \xintloop
+ \xintiiifZero{\csname POL@array#1\the\count@\endcsname}%
+ {\iftrue}%
+ {\iffalse}%
+ \advance\count@\m@ne
+ \repeat
+ \expandafter\edef\csname POL@deg#1\endcsname{\the\numexpr\count@-\@ne}%
+ \ifnum\count@<\@ne
+ \expandafter\POL@gcd@exit
+ \else
+ \expandafter\edef\csname POL@array#10\endcsname{\the\count@}%
+ \expandafter\POL@gcd
+ \fi{#2}{#1}%
+}%
+\def\POL@gcd@getremainder@loopbody#1#2{%
+ \edef\POL@gcd@ratio{\csname POL@array#1\the\count@\endcsname}%
+ \advance\count@\m@ne
+ \advance\count\tw@\m@ne
+ \count4 \count@
+ \count6 \csname POL@deg#2\endcsname\space
+ \xintloop
+ \ifnum\count6>\z@
+ \expandafter\edef\csname POL@array#1\the\count4\endcsname
+ {\xintSub
+ {\csname POL@array#1\the\count4\endcsname}%
+ {\xintMul
+ {\POL@gcd@ratio}%
+ {\csname POL@array#2\the\count6\endcsname}}}%
+ \advance\count4 \m@ne
+ \advance\count6 \m@ne
+ \repeat
+}%
+\def\POL@gcd@exit#1#2{%
+ \count@\numexpr\csname POL@deg#1\endcsname+\@ne\relax
+ \POL@resultfromarray #1%
+}%
+%
+%% DIFFERENTIATION
+%
+\def\POL@diff@loop@one #1/#2[#3]#4%
+ {\xintIrr{\xintiiMul{#4}{#1}/#2[0]}[#3]}%
+\def\POL@diff#1{\POL@diff@loop1.}%
+\def\POL@diff@loop#1.#2{%
+ \if\relax#2\expandafter\xint_gob_til_dot\fi
+ {\expandafter\POL@diff@loop@one\romannumeral0\xintraw{#2}{#1}}%
+ \expandafter\POL@diff@loop\the\numexpr#1+\@ne.%
+}%
+\def\PolDiff{\POL@chkopt\POL@oPolDiff[1]}%
+\def\POL@oPolDiff[#1]{%
+ % optional parameter is how many times to derivate
+ % first mandatory arg is name of polynomial function to derivate,
+ % same name as in \NewPolExpr
+ % second mandatory arg name of derivative
+ \edef\POL@iterindex{\the\numexpr#1\relax}%
+ \ifnum\POL@iterindex<\z@
+ \expandafter\xint_firstoftwo
+ \else
+ \expandafter\xint_secondoftwo
+ \fi
+ {\PolAntiDiff[-\POL@iterindex]}{\POL@Diff}%
+}%
+\def\POL@Diff{%
+ \ifcase\POL@iterindex\space
+ \expandafter\POL@Diff@no
+ \or\expandafter\POL@Diff@one
+ \else\xint_afterfi{\POL@Iterate\POL@Diff@one}%
+ \fi
+}%
+\def\POL@Diff@no #1#2{\POL@let{#2}{#1}}%
+\def\POL@Diff@one #1#2{\POL@Diff@@one {#1}{#2}\POL@newpol{#2}}%
+\def\POL@Diff@@one#1#2{%
+ \expandafter\expandafter\expandafter\POL@split
+ \csname POLuserpol@#1\endcsname;\POL@var@deg\POL@var@coeffs
+ \ifnum\POL@var@deg<\@ne
+ \XINT_global\@namedef{POLuserpol@#2}{-1.\empty{0/1[0]}}%
+ \else
+ \edef\POL@var@coeffs{\expandafter\POL@diff\POL@var@coeffs\relax}%
+ \XINT_global\expandafter\edef\csname POLuserpol@#2\endcsname
+ {\the\numexpr\POL@var@deg-\@ne.\noexpand\empty\POL@var@coeffs}%
+ \fi
+}%
+% lazy way but allows to share with AntiDiff
+\def\POL@Iterate#1#2#3{%
+ \begingroup
+ \xintverbosefalse
+ #1{#2}{#3}%
+ \xintloop
+ \ifnum\POL@iterindex>\tw@
+ #1{#3}{#3}%
+ \edef\POL@iterindex{\the\numexpr\POL@iterindex-\@ne}%
+ \repeat
+ \expandafter
+ \endgroup\expandafter
+ \XINT_global
+ \expandafter
+ \def\csname POLuserpol@#3\expandafter\endcsname
+ \expandafter{\romannumeral`&&@\csname POLuserpol@#3\endcsname}%
+ #1{#3}{#3}%
+}%
+%
+%% ANTI-DIFFERENTIATION
+%
+\def\POL@antidiff@loop@one #1/#2[#3]#4%
+ {\xintIrr{#1/\xintiiMul{#4}{#2}[0]}[#3]}%
+\def\POL@antidiff{\POL@antidiff@loop1.}%
+\def\POL@antidiff@loop#1.#2{%
+ \if\relax#2\expandafter\xint_gob_til_dot\fi
+ {\expandafter\POL@antidiff@loop@one\romannumeral0\xintraw{#2}{#1}}%
+ \expandafter\POL@antidiff@loop\the\numexpr#1+\@ne.%
+}%
+\def\PolAntiDiff{\POL@chkopt\POL@oPolAntiDiff[1]}%
+\def\POL@oPolAntiDiff[#1]{%
+ % optional parameter is how many times to derivate
+ % first mandatory arg is name of polynomial function to derivate,
+ % same name as in \NewPolExpr
+ % second mandatory arg name of derivative
+ \edef\POL@iterindex{\the\numexpr#1\relax}%
+ \ifnum\POL@iterindex<\z@
+ \expandafter\xint_firstoftwo
+ \else
+ \expandafter\xint_secondoftwo
+ \fi
+ {\PolDiff[-\POL@iterindex]}{\POL@AntiDiff}%
+}%
+\def\POL@AntiDiff{%
+ \ifcase\POL@iterindex\space
+ \expandafter\POL@AntiDiff@no
+ \or\expandafter\POL@AntiDiff@one
+ \else\xint_afterfi{\POL@Iterate\POL@AntiDiff@one}%
+ \fi
+}%
+\let\POL@AntiDiff@no\POL@Diff@no
+\def\POL@AntiDiff@one #1#2{\POL@AntiDiff@@one{#1}{#2}\POL@newpol{#2}}%
+\def\POL@AntiDiff@@one#1#2{%
+ \expandafter\expandafter\expandafter\POL@split
+ \csname POLuserpol@#1\endcsname;\POL@var@deg\POL@var@coeffs
+ \ifnum\POL@var@deg<\z@
+ \XINT_global\@namedef{POLuserpol@#2}{-1.\empty{0/1[0]}}%
+ \else
+ \edef\POL@var@coeffs{\expandafter\POL@antidiff\POL@var@coeffs\relax}%
+ \XINT_global\expandafter\edef\csname POLuserpol@#2\endcsname
+ {\the\numexpr\POL@var@deg+\@ne.\noexpand\empty{0/1[0]}\POL@var@coeffs}%
+ \fi
+}%
+%
+%%
+%% Localization of roots
+%%
+% this is big. It provides also output macros, of both expandable and
+% non-expandable type
+\input polexprsturm.tex\relax
+%
+%
+%% Non-expandable output macros
+%
+\def\PolTypesetCmdPrefix#1{\xintiiifSgn{#1}{}{+}{+}}%
+\def\PolTypesetCmd#1{\xintifOne{\xintiiAbs{#1}}%
+ {\ifnum\PolIndex=\z@\xintiiSgn{#1}\else
+ \xintiiifSgn{#1}{-}{}{}\fi
+ \let\PolIfCoeffIsPlusOrMinusOne\xint_firstoftwo}%
+ {\PolTypesetOne{#1}%
+ \let\PolIfCoeffIsPlusOrMinusOne\xint_secondoftwo}%
+ }%
+\ifdefined\frac
+\def\PolTypesetOne{\xintSignedFrac}%
+\else
+\def\PolTypesetOne{\xintSignedFwOver}%
+\fi
+\catcode`^ 7
+\def\PolTypesetMonomialCmd{%
+ \ifcase\PolIndex\space
+ %
+ \or\PolVar
+ \else\PolVar^{\PolIndex}%
+ \fi
+}%
+\catcode`^ 11 % normal xint catcode
+\def\PolTypeset{\POL@ifstar
+ {\def\POL@ts@ascending{1}\POL@Typeset}%
+ {\def\POL@ts@ascending{0}\POL@Typeset}%
+}%
+%%
+%% \PolTypeset
+%%
+%% extended at 0.8 to handle arbitrary expressions on input
+%%
+\def\POL@Typeset{\POL@chkopt\POL@oPOL@Typeset[x]}%
+\def\POL@oPOL@Typeset[#1]#2{%
+ \ifmmode\let\POL@endtypeset\empty\else$\def\POL@endtypeset{$}\fi
+ \ifcsname POLuserpol@#2\endcsname
+ \expandafter\expandafter\expandafter\POL@split
+ \csname POLuserpol@#2\endcsname;\POL@var@deg\POL@var@coeffs
+ \else
+ \xintAssign\expandafter\xint_firstofone\romannumeral0\xintbareeval
+ subs((deg(x),coeffs(x)),x=subs(#2,\PolToExprInVar=pol([0,1])))\relax
+ \to\POL@var@deg\POL@var@coeffs
+ \fi
+ \if\POL@ts@ascending1%
+ \def\PolIndex{0}%
+ \let\POL@ts@reverse\xint_firstofone
+ \let\POL@@ne@or@m@ne\@ne
+ \else
+ \let\PolIndex\POL@var@deg
+ \ifnum\PolIndex<\z@\def\PolIndex{0}\fi
+ \let\POL@ts@reverse\xintRevWithBraces
+ \let\POL@@ne@or@m@ne\m@ne
+ \fi
+ \def\PolVar{#1}%
+ \ifnum\POL@var@deg<\z@
+ \PolTypesetCmd{0/1[0]}\PolTypesetMonomialCmd
+ \else
+ \ifnum\POL@var@deg=\z@
+ \expandafter\PolTypesetCmd\POL@var@coeffs\PolTypesetMonomialCmd
+ \else
+ \def\POL@ts@prefix##1{\let\POL@ts@prefix\PolTypesetCmdPrefix}%
+ \expandafter\POL@ts@loop
+ \romannumeral-`0\POL@ts@reverse{\POL@var@coeffs}\relax
+ \fi
+ \fi
+ \POL@endtypeset
+}%
+\def\POL@ts@loop{\ifpoltypesetall\expandafter\xint_firstoftwo
+ \else\expandafter\xint_secondoftwo\fi
+ {\POL@ts@nocheck}{\POL@ts@check}.%
+}%
+\def\POL@ts@check.#1{%
+ \if\relax#1\expandafter\xint_gob_til_dot\fi
+ \xintiiifZero{#1}%
+ {}%
+ {\POL@ts@prefix{#1}\PolTypesetCmd{#1}\PolTypesetMonomialCmd}%
+ \edef\PolIndex{\the\numexpr\PolIndex+\POL@@ne@or@m@ne}\POL@ts@check.%
+}%
+\def\POL@ts@nocheck.#1{%
+ \if\relax#1\expandafter\xint_gob_til_dot\fi
+ \POL@ts@prefix{#1}\PolTypesetCmd{#1}\PolTypesetMonomialCmd
+ \edef\PolIndex{\the\numexpr\PolIndex+\POL@@ne@or@m@ne}\POL@ts@nocheck.%
+}%
+%
+%%
+%% Expandable output macros (legacy)
+%%
+\def\POL@eval@fork#1\At#2#3\krof{#2}%
+\def\PolEval#1#2#3{\romannumeral`&&@\POL@eval@fork
+ #2\PolEvalAt
+ \At\PolEvalAtExpr\krof {#1}{#3}%
+}%
+\def\PolEvalAt#1#2{%
+ \xintpraw{\csname XINT_expr_polfunc_#1\endcsname{#2}}%
+}%
+\def\POL@eval#1#2{%
+ \csname XINT_expr_polfunc_#1\endcsname{#2}%
+}%
+\def\PolEvalAtExpr#1#2{\xinttheexpr #1(#2)\relax}%
+%
+\def\PolEvalReduced#1#2#3{\romannumeral`&&@\POL@eval@fork
+ #2\PolEvalReducedAt
+ \At\PolEvalReducedAtExpr\krof {#1}{#3}%
+}%
+\def\PolEvalReducedAt#1#2{%
+ \xintpraw % in order not to print denominator if the latter equals 1
+ {\xintIrr{\csname XINT_expr_polfunc_#1\endcsname{#2}}[0]}%
+}%
+\def\PolEvalReducedAtExpr#1#2{%
+ \xintpraw
+ {\expandafter\xintIrr\romannumeral`&&@\xintthebareeval#1(#2)\relax[0]}%
+}%
+%
+\def\PolFloatEval#1#2#3{\romannumeral`&&@\POL@eval@fork
+ #2\PolFloatEvalAt
+ \At\PolFloatEvalAtExpr\krof {#1}{#3}%
+}%
+\def\PolFloatEvalAt#1#2{%
+ \xintpfloat{\csname XINT_flexpr_polfunc_#1\endcsname{#2}}%
+}%
+\def\PolFloatEvalAtExpr#1#2{\xintthefloatexpr #1(#2)\relax}%
+\def\PolLeadingCoeff#1{%
+ \romannumeral`&&@\expandafter\expandafter\expandafter\xintlastitem
+ \expandafter\expandafter\expandafter
+ {\csname POLuserpol@#1\endcsname}%
+}%
+%
+\def\PolNthCoeff#1#2{\romannumeral`&&@%
+ \expandafter\POL@nthcoeff
+ \romannumeral0\xintnthelt{\ifnum\numexpr#2<\z@#2\else(#2)+1\fi}%
+ {\expandafter\expandafter\expandafter
+ \xint_gob_til_dot\csname POLuserpol@#1\endcsname}@%
+}%
+\def\POL@nthcoeff#1@{\if @#1@\expandafter\xint_firstoftwo
+ \else\expandafter\xint_secondoftwo\fi
+ {0/1[0]}{#1}}%
+%
+% returns -1 for zero polynomial for context of numerical expression
+% should it return -\infty?
+\def\PolDegree#1{\romannumeral`&&@\expandafter\expandafter\expandafter
+ \POL@degree\csname POLuserpol@#1\endcsname;}%
+\def\POL@degree #1.#2;{#1}%
+%
+\def\PolToList#1{\romannumeral`&&@\expandafter\expandafter\expandafter
+ \xint_gob_til_dot\csname POLuserpol@#1\endcsname}%
+%
+\def\PolToCSV#1{\romannumeral0\xintlistwithsep{, }{\PolToList{#1}}}%
+%
+% \PolIContent (0.5)
+% Why did I call this IContent and not Content? Ah, I see Maple terminology
+% But I realize now I misread the Maple doc, its icontent() is the gcd of
+% all coeffs of a multivariate polynomial. Whereas content(,) second argument
+% specifies which variable to consider expression as being univariate in it
+%
+\def\POL@icontent#1{\romannumeral0\expandafter\XINT_fgcd_out
+ \romannumeral0\expandafter\XINT_fgcdof\romannumeral`&&@#1^}%
+% Since xintexpr 1.4d, \xintGCDof always outputs an irreducible fraction A/B.
+% (with B=1 if A/B integer).
+\def\PolIContent#1{\xintGCDof{\PolToList{#1}}}%
+%
+\def\PolToExprCmd#1{\xintPRaw{\xintRawWithZeros{#1}}}%
+\def\PolToFloatExprCmd#1{\xintFloat{#1}}%
+% \def\PolTypesetCmdPrefix#1{\xintiiifSgn{#1}{}{+}{+}}%
+\let\PolToExprTermPrefix\PolTypesetCmdPrefix
+\def\PolToExprOneTermStyleA#1#2{%
+ \ifnum#2=\z@
+ \PolToExprCmd{#1}%
+ \else
+ \xintifOne{\xintiiAbs{#1}}
+ {\xintiiifSgn{#1}{-}{}{}}% + from \PolToExprTermPrefix
+ {\PolToExprCmd{#1}\PolToExprTimes}%
+ \fi
+ \ifcase\xintiiAbs{#2} %<-- space here mandatory
+ \or\PolToExprVar
+ \else\PolToExprVar\PolToExprCaret\xintiiAbs{#2}%
+ \fi
+}%
+\let\PolToExprOneTerm\PolToExprOneTermStyleA
+\def\PolToExprOneTermStyleB#1#2{%
+ \ifnum#2=\z@
+ \xintNumerator{#1}%
+ \else
+ \xintifOne{\xintiiAbs{\xintNumerator{#1}}}
+ {\xintiiifSgn{#1}{-}{}{}}% + from \PolToExprTermPrefix
+ {\xintNumerator{#1}\PolToExprTimes}%
+ \fi
+ \ifcase\xintiiAbs{#2} %<-- space here mandatory
+ \or\PolToExprVar
+ \else\PolToExprVar\PolToExprCaret\xintiiAbs{#2}%
+ \fi
+ \xintiiifOne{\xintDenominator{#1}}{}{/\xintDenominator{#1}}%
+}%
+\def\PolToFloatExprOneTerm#1#2{%
+ \ifnum#2=\z@
+ \PolToFloatExprCmd{#1}%
+ \else
+ \PolToFloatExprCmd{#1}\PolToExprTimes
+ \fi
+ \ifcase\xintiiAbs{#2} %<-- space here mandatory
+ \or\PolToExprVar
+ \else\PolToExprVar\PolToExprCaret\xintiiAbs{#2}%
+ \fi
+}%
+\def\PolToExprTimes{*}%
+\def\PolToExprVar{x}%
+\def\PolToExprInVar{x}%
+\edef\PolToExprCaret{\string ^}%
+%%
+%% \PolToExpr
+%%
+%% extended at 0.8 to handle arbitrary expressions on input
+%%
+\def\PolToExpr#1{%
+ \if*\noexpand#1\expandafter\xint_firstoftwo\else
+ \expandafter\xint_secondoftwo\fi
+ \PolToExprAscending\PolToExprDescending{#1}}%
+\def\PolToFloatExpr#1{%
+ \if*\noexpand#1\expandafter\xint_firstoftwo\else
+ \expandafter\xint_secondoftwo\fi
+ \PolToFloatExprAscending\PolToFloatExprDescending{#1}}%
+\def\PolToExpr@getit#1%
+{%
+ \ifcsname XINT_expr_varvalue_#1\endcsname
+ \csname XINT_expr_varvalue_#1\expandafter\endcsname
+ \else
+ \expandafter\xint_firstofone\romannumeral0%
+ \xintbareeval subs(#1,\PolToExprInVar=pol([0,1]))\expandafter\relax
+ \fi
+}%
+\def\PolToExprAscending#1#2{%
+ \expandafter\POL@toexpr\romannumeral0\PolToExpr@getit{#2}%
+ \PolToExprOneTerm\POL@toexprA
+}%
+\def\PolToFloatExprAscending#1#2{%
+ \expandafter\POL@toexpr\romannumeral0\PolToExpr@getit{#2}%
+ \PolToFloatExprOneTerm\POL@toexprA
+}%
+\def\PolToExprDescending#1{%
+ \expandafter\POL@toexpr\romannumeral0\PolToExpr@getit{#1}%
+ \PolToExprOneTerm\POL@toexprD
+}%
+\def\PolToFloatExprDescending#1{%
+ \expandafter\POL@toexpr\romannumeral0\PolToExpr@getit{#1}%
+ \PolToFloatExprOneTerm\POL@toexprD
+}%
+\def\POL@toexpr#1#2#3{\POL@toexpr@fork#3#2#1\relax}%
+\def\POL@toexpr@fork #1#2#3{%
+ \POL_Pfork
+ #3\POL@toexpr@pol
+ P\POL@toexpr@cst
+ \krof #1#2#3%
+}%
+\def\POL@toexpr@cst#1#2#3\relax{#2{#3}{0}}%
+\def\POL@toexpr@pol#1#2P#3.{#1{#3}#2\empty}%
+% now back to legacy pre 0.8 code
+\def\POL@toexprA #1#2\empty#3{%
+ \ifpoltoexprall\expandafter\POL@toexprall@b
+ \else\expandafter\POL@toexpr@b
+ \fi {#3}#2{0}1.%
+}%
+\def\POL@toexprD #1#2#3\relax{% #3 has \empty to prevent brace removal
+ \expandafter\POL@toexprD@a\expandafter#2%
+ \the\numexpr #1\expandafter.\romannumeral0\xintrevwithbraces{#3}\relax
+}%
+\def\POL@toexprD@a #1#2.#3{%
+ \ifpoltoexprall\expandafter\POL@toexprall@b
+ \else\expandafter\POL@toexpr@b
+ \fi{#3}#1{-#2}\the\numexpr\@ne+-#2.%
+}%
+\def\POL@toexpr@b #1#2#3{%
+ \xintiiifZero{#1}%
+ {\expandafter\POL@toexpr@loop\expandafter\POL@toexpr@b}%
+ {#2{#1}{#3}%
+ \expandafter\POL@toexpr@loop\expandafter\POL@toexpr@c}%
+ \expandafter#2%
+}%
+\def\POL@toexpr@c #1#2#3{%
+ \xintiiifZero{#1}%
+ {}%
+ {\PolToExprTermPrefix{#1}#2{#1}{#3}}%
+ \expandafter\POL@toexpr@loop\expandafter\POL@toexpr@c
+ \expandafter#2%
+}%
+\def\POL@toexprall@b #1#2#3{%
+ #2{#1}{#3}%
+ \expandafter\POL@toexpr@loop\expandafter\POL@toexprall@c
+ \expandafter#2%
+}%
+\def\POL@toexprall@c #1#2#3{%
+ \PolToExprTermPrefix{#1}#2{#1}{#3}%
+ \expandafter\POL@toexpr@loop\expandafter\POL@toexprall@c
+ \expandafter#2%
+}%
+\def\POL@toexpr@loop#1#2#3.#4{%
+ \if\relax#4\expandafter\xint_gob_til_dot\fi
+ #1{#4}#2{#3}\the\numexpr\@ne+#3.%
+}%
+\XINT_restorecatcodes_endinput%
diff --git a/macros/generic/polexpr/polexprcore.tex b/macros/generic/polexpr/polexprcore.tex
new file mode 100644
index 0000000000..e071729e42
--- /dev/null
+++ b/macros/generic/polexpr/polexprcore.tex
@@ -0,0 +1,1366 @@
+%% This file polexprcore.tex is part of the polexpr package (0.8, 2021/03/29)
+%% Core routines to match infix operators +, -, *, //, /:, ^, ** and some
+%% functions
+%% The atoms representing polynomials inside \xintexpr are
+%% - for constants: a numeric value (indistinguishable. from scalars)
+%% - for degree at least 1: P<degree>.{c0}{c1}....{cN} with N = degree
+%% Auxiliaries
+\long\def\POL_Pfork #1P#2#3\krof{#2}%
+\long\def\POL_PPfork #1PP#2#3\krof{#2}%
+\long\def\POL_zeroPfork #10P#2#3\krof{#2}%
+\long\def\POL_secondofthree#1#2#3{#2}%
+% \long\def\POL_Apply:x #1#2%
+% {%
+% \POL_apply:x_loop {#1}#2%
+% \xint_Bye\xint_Bye\xint_Bye\xint_Bye
+% \xint_Bye\xint_Bye\xint_Bye\xint_Bye\xint_bye
+% }%
+\long\def\POL_bBye#1\xint_Bye{}%
+\long\def\POL_apply:x_loop #1#2#3#4#5#6#7#8#9%
+{%
+ \POL_bBye #2\xint_Bye{#1{#2}}%
+ \POL_bBye #3\xint_Bye{#1{#3}}%
+ \POL_bBye #4\xint_Bye{#1{#4}}%
+ \POL_bBye #5\xint_Bye{#1{#5}}%
+ \POL_bBye #6\xint_Bye{#1{#6}}%
+ \POL_bBye #7\xint_Bye{#1{#7}}%
+ \POL_bBye #8\xint_Bye{#1{#8}}%
+ \POL_bBye #9\xint_Bye{#1{#9}}%
+ \POL_apply:x_loop {#1}%
+}%
+\long\def\POL_apply:x_iloop #1#2#3#4#5#6#7#8#9%
+{%
+ \POL_bBye #2\xint_Bye{#10{#2}}%
+ \POL_bBye #3\xint_Bye{#11{#3}}%
+ \POL_bBye #4\xint_Bye{#12{#4}}%
+ \POL_bBye #5\xint_Bye{#13{#5}}%
+ \POL_bBye #6\xint_Bye{#14{#6}}%
+ \POL_bBye #7\xint_Bye{#15{#7}}%
+ \POL_bBye #8\xint_Bye{#16{#8}}%
+ \POL_bBye #9\xint_Bye{#17{#9}}%
+ \POL_apply:x_iloop_a#1%
+}%
+\def\POL_apply:x_iloop_a#1#2.%
+{%
+ \expandafter\POL_apply:x_iloop
+ \expandafter{\expandafter#1\the\numexpr\xint_c_viii+#1.}%
+}%
+\long\def\POL_apply:x_iloop #1#2#3#4#5#6#7#8#9%
+{%
+ \POL_bBye #2\xint_Bye{#10{#2}}%
+ \POL_bBye #3\xint_Bye{#11{#3}}%
+ \POL_bBye #4\xint_Bye{#12{#4}}%
+ \POL_bBye #5\xint_Bye{#13{#5}}%
+ \POL_bBye #6\xint_Bye{#14{#6}}%
+ \POL_bBye #7\xint_Bye{#15{#7}}%
+ \POL_bBye #8\xint_Bye{#16{#8}}%
+ \POL_bBye #9\xint_Bye{#17{#9}}%
+ \POL_apply:x_iloop_a#1%
+}%
+\def\POL_apply:x_iloop_a#1#2.%
+{%
+ \expandafter\POL_apply:x_iloop
+ \expandafter{\expandafter#1\the\numexpr\xint_c_viii+#1.}%
+}%
+%%
+%% ADDITION
+%%
+\def\xintPolAdd #1%
+{%
+ \expanded\expandafter\POL_add_in\romannumeral`&&@#1\xint:
+}%
+\def\POL_add_in #1\xint:#2%
+{%
+ {%
+ \expandafter\POL_add_fork
+% Fragile but this macro is not public anyhow and won't get arbitrary input
+% At odds with systematic \xint: style further down
+ \romannumeral`&&@#2\xint_bye\xint_bye\xint_bye\xint_bye\empty
+ #1\xint_bye\xint_bye\xint_bye\xint_bye\empty
+ \empty
+ }%
+}%
+% Careful that first means "first here" i.e. the original second argument,
+% and vice versa
+\def\POL_add_fork #1#2\empty#3%
+{%
+ \POL_PPfork
+ #1#3{\POL_add_a}%
+ #1P{\POL_add_second_is_scalar}%
+ #3P{\POL_add_first_is_scalar}%
+ PP{\POL_add_both_are_scalar}%
+ \krof #1#2\empty#3%
+}%
+\def\POL_add_first_is_scalar #1\xint_bye#2\empty#3.#4%
+{%
+ #3.{\xintAdd{#1}{#4}}%
+}%
+\def\POL_add_second_is_scalar #1.#2#3\empty#4\xint_bye#5\empty\empty
+{%
+ #1.{\xintAdd{#2}{#4}}#3%
+}%
+\def\POL_add_both_are_scalar #1\xint_bye#2\empty#3\xint_bye#4\empty\empty
+{%
+ \xintAdd{#1}{#3}%
+}%
+\def\POL_add_a P#1.#2#3#4#5\empty P#6.#7#8#9%
+{%
+ \expandafter\POL_add_b
+ \expanded\bgroup\unexpanded{#1.#6.}%
+ \xint_bye #2\POL_add_Eb\xint_bye
+ \xint_bye #7\POL_add_Fb\xint_bye {\xintAdd{#2}{#7}}%
+ \xint_bye #3\POL_add_Ec\xint_bye
+ \xint_bye #8\POL_add_Fc\xint_bye {\xintAdd{#3}{#8}}%
+ \xint_bye #4\POL_add_Ed\xint_bye
+ \xint_bye #9\POL_add_Fd\xint_bye {\xintAdd{#4}{#9}}%
+ \POL_add_A #5\empty
+}%
+\def\POL_add_b #1.#2.%
+{%
+ \ifnum#1=#2 \expandafter\POL_add_c
+ \else
+ \ifnum#1>#2 P#1.\else P#2.\fi
+ \fi
+}%
+% No brace stripping possible, because constant polynomials are really
+% represented by scalars in all those internal contexts, so real
+% polynomials have at least two coefficients
+\def\POL_add_c #1\empty
+{%
+ \expandafter\POL_add_d
+ \romannumeral0\XINT_revwbr_loop {}%
+ #1\xint:\xint:\xint:\xint:%
+ \xint:\xint:\xint:\xint:\xint_bye
+ \xint_bye
+}%
+% Attention, reused in various other locations. It is all f-expandable.
+\def\POL_add_d #1%
+{%
+% abuse of \XINT_Sgn internals compatible to #1 being \xint_bye
+ \if0\XINT_Sgn#1\xint:
+ \xint_dothis\POL_add_d
+ \fi
+ \xint_orthat{\POL_add_e {#1}}%
+}%
+\def\POL_add_e #1%
+{%
+ \xint_bye#1\POL_add_e_zero\xint_bye \POL_add_f\empty{#1}%
+}%
+\def\POL_add_e_zero\xint_bye\POL_add_f\empty #1{0/1[0]}%
+% #1 starts with \empty to avoid brace stripping.
+\def\POL_add_f #1\xint_bye
+{%
+ \expandafter\POL_add_g
+ \the\numexpr
+ \xintLength{#1}-\xint_c_ii\expandafter.%
+ \romannumeral0\expandafter
+ \XINT_revwbr_loop\expandafter {\expandafter}%
+ #1\xint:\xint:\xint:\xint:%
+ \xint:\xint:\xint:\xint:\xint_bye
+}%
+\def\POL_add_g #1.%
+{%
+ \ifnum#1=\xint_c_\expandafter\POL_add_h\fi
+ P#1.%
+}%
+\def\POL_add_h P0.#1{#1}%
+% Attention reused in \POL_mul_d and \POL_quorem_c
+\def\POL_add_A #1#2#3#4#5\empty#6#7#8#9%
+{%
+ \xint_bye #1\POL_add_Ea\xint_bye
+ \xint_bye #6\POL_add_Fa\xint_bye {\xintAdd{#1}{#6}}%
+ \xint_bye #2\POL_add_Eb\xint_bye
+ \xint_bye #7\POL_add_Fb\xint_bye {\xintAdd{#2}{#7}}%
+ \xint_bye #3\POL_add_Ec\xint_bye
+ \xint_bye #8\POL_add_Fc\xint_bye {\xintAdd{#3}{#8}}%
+ \xint_bye #4\POL_add_Ed\xint_bye
+ \xint_bye #9\POL_add_Fd\xint_bye {\xintAdd{#4}{#9}}%
+ \POL_add_A #5\empty
+}%
+\def\POL_add_Ea\xint_bye
+ \xint_bye #1\POL_add_Fa\xint_bye #2\xint_bye\xint_bye
+ \POL_add_Eb\xint_bye\xint_bye#3\POL_add_Fb\xint_bye #4\xint_bye\xint_bye
+ \POL_add_Ec\xint_bye\xint_bye#5\POL_add_Fc\xint_bye #6\xint_bye\xint_bye
+ \POL_add_Ed\xint_bye\xint_bye#7\POL_add_Fd\xint_bye #8%
+ \POL_add_A#9\empty
+{%
+ \xint_bye #1\POL_add_G\xint_bye{#1}%
+ \xint_bye #3\POL_add_G\xint_bye{#3}%
+ \xint_bye #5\POL_add_G\xint_bye{#5}%
+ \xint_bye #7\POL_add_G\xint_bye{#7}%
+ \iffalse{\fi}%
+}%
+\def\POL_add_G#1\empty{\iffalse{\fi}}%
+\def\POL_add_Fa\xint_bye #1%
+ \xint_bye #2\POL_add_Eb \xint_bye
+ \xint_bye\xint_bye\POL_add_Fb\xint_bye #3%
+ \xint_bye #4\POL_add_Ec \xint_bye
+ \xint_bye\xint_bye\POL_add_Fc\xint_bye #5%
+ \xint_bye #6\POL_add_Ed #7\POL_add_A
+ #8\empty#9\empty
+{%
+ \expandafter\xint_bye\POL_secondofthree #1%
+ \POL_add_G\xint_bye{\POL_secondofthree#1}%
+ \xint_bye #2\POL_add_G\xint_bye{#2}%
+ \xint_bye #4\POL_add_G\xint_bye{#4}%
+ \xint_bye #6\POL_add_G\xint_bye{#6}%
+ \iffalse{\fi}#8\empty%
+}%
+\def\POL_add_Eb\xint_bye
+ \xint_bye #1\POL_add_Fb\xint_bye #2\xint_bye\xint_bye
+ \POL_add_Ec\xint_bye\xint_bye#3\POL_add_Fc\xint_bye #4\xint_bye\xint_bye
+ \POL_add_Ed\xint_bye\xint_bye#5\POL_add_Fd\xint_bye #6%
+ \POL_add_A#7\empty
+{%
+ \xint_bye #1\POL_add_G\xint_bye{#1}%
+ \xint_bye #3\POL_add_G\xint_bye{#3}%
+ \xint_bye #5\POL_add_G\xint_bye{#5}%
+ \iffalse{\fi}%
+}%
+\def\POL_add_Fb\xint_bye #1%
+ \xint_bye #2\POL_add_Ec \xint_bye
+ \xint_bye\xint_bye\POL_add_Fc\xint_bye #3%
+ \xint_bye #4\POL_add_Ed #5\POL_add_A
+ #6\empty#7\empty
+{%
+ \expandafter\xint_bye\POL_secondofthree #1%
+ \POL_add_G\xint_bye{\POL_secondofthree#1}%
+ \xint_bye #2\POL_add_G\xint_bye{#2}%
+ \xint_bye #4\POL_add_G\xint_bye{#4}%
+ \iffalse{\fi}#6\empty
+}%
+\def\POL_add_Ec\xint_bye
+ \xint_bye #1\POL_add_Fc\xint_bye #2\xint_bye\xint_bye
+ \POL_add_Ed\xint_bye\xint_bye#3\POL_add_Fd\xint_bye #4%
+ \POL_add_A#5\empty
+{%
+ \xint_bye #1\POL_add_G\xint_bye{#1}%
+ \xint_bye #3\POL_add_G\xint_bye{#3}%
+ \iffalse{\fi}%
+}%
+\def\POL_add_Fc\xint_bye #1\xint_bye #2\POL_add_Ed #3\POL_add_A
+ #4\empty#5\empty
+{%
+ \expandafter\xint_bye\POL_secondofthree #1%
+ \POL_add_G\xint_bye{\POL_secondofthree#1}%
+ \xint_bye #2\POL_add_G\xint_bye{#2}%
+ \iffalse{\fi}#4\empty
+}%
+\def\POL_add_Ed\xint_bye\xint_bye#1\POL_add_Fd\xint_bye#2\POL_add_A#3\empty
+{%
+ \xint_bye #1\POL_add_G\xint_bye{#1}%
+ \iffalse{\fi}%
+}%
+\def\POL_add_Fd\xint_bye#1\POL_add_A #2\empty#3\empty
+{%
+ \expandafter\xint_bye \POL_secondofthree #1%
+ \POL_add_G\xint_bye{\POL_secondofthree#1}%
+ \iffalse{\fi}#2\empty
+}%
+%%
+%% OPPOSITE
+%%
+\def\xintPolOpp #1%
+{%
+ \expanded{%
+ \expandafter\POL_opp_fork\romannumeral`&&@#1%
+ \xint_Bye\xint_Bye\xint_Bye\xint_Bye
+ \xint_Bye\xint_Bye\xint_Bye\xint_Bye\xint_bye
+ }%
+}%
+\def\POL_opp_fork #1%
+{%
+ \if P#1\xint_dothis\POL_opp_a\fi
+ \xint_orthat\POL_opp_scalar #1%
+}%
+\def\POL_opp_scalar #1\xint_Bye#2\xint_bye
+{%
+ \XINT_Opp #1%
+}%
+\def\POL_opp_a #1.%
+{%
+ #1.\POL_apply:x_loop{\XINT_Opp}%
+}%
+%%
+%% SUBTRACTION
+%%
+\def\xintPolSub #1%
+{%
+ \expanded\expandafter\POL@sub\romannumeral`&&@#1\xint:
+}%
+\def\POL@sub #1\xint:#2%
+{%
+ {%
+ \expandafter
+ \POL_add_fork\expanded{%
+ \expandafter\POL_opp_fork \romannumeral`&&@#2%
+ \xint_Bye\xint_Bye\xint_Bye\xint_Bye
+ \xint_Bye\xint_Bye\xint_Bye\xint_Bye\xint_bye
+ }%
+ \xint_bye\xint_bye\xint_bye\xint_bye\empty
+ #1\xint_bye\xint_bye\xint_bye\xint_bye\empty
+ \empty
+ }%
+}%
+%%
+%% MULTIPLICATION
+%%
+\def\xintPolSqr #1%
+{%
+ \expanded\expandafter\POL_sqr_in\romannumeral`&&@#1\xint:
+}%
+\def\POL_sqr_in #1\xint:
+{%
+ {%
+ \expandafter\POL_mul_fork
+ #1\xint_bye
+ #1\xint_Bye\xint_Bye\xint_Bye\xint_Bye
+ \xint_Bye\xint_Bye\xint_Bye\xint_Bye\xint_bye
+ }%
+}%
+%
+\def\xintPolMul #1%
+{%
+ \expanded\expandafter\POL_mul_in\romannumeral`&&@#1\xint:
+}%
+\def\POL_mul_in #1\xint:#2%
+{%
+ {%
+ \expandafter\POL_mul_fork
+ \romannumeral`&&@#2\xint_bye
+ #1\xint_Bye\xint_Bye\xint_Bye\xint_Bye
+ \xint_Bye\xint_Bye\xint_Bye\xint_Bye\xint_bye
+ }%
+}%
+\def\POL_mul_fork #1#2\xint_bye#3%
+{%
+ \POL_PPfork
+ #1#3{\POL_mul_a}%
+ #1P{\POL_mul_second_is_scalar}%
+ #3P{\POL_mul_first_is_scalar}%
+ PP{\POL_mul_both_are_scalar}%
+ \krof #1#2\xint_bye#3%
+}%
+\def\POL_mul_both_are_scalar #1\xint_bye#2\xint_Bye#3\xint_bye
+{%
+ \xintMul{#1}{#2}%
+}%
+\def\POL_mul_second_is_scalar #1\xint_bye#2\xint_Bye
+{%
+ \POL_mul_first_is_scalar #2\xint_bye#1\xint_Bye
+}%
+\def\POL_mul_first_is_scalar #1%
+{%
+ \xint_gob_til_zero#1\POL_mul_zero0\POL_mul_scalar #1%
+}%
+\def\POL_mul_zero0\POL_mul_scalar #1\xint_bye#2\xint_bye{0/1[0]}%
+\def\POL_mul_scalar #1\xint_bye P#2.%
+{%
+ P#2.\POL_apply:x_loop{\xintMul{#1}}%
+}%
+\def\POL_mul_a P#1.#2#3P#4.#5\xint_bye
+{%
+ P\the\numexpr#1+#4.%
+ \expandafter\POL_mul_b
+ \expanded{\POL_apply:x_loop{\xintMul{#2}}#5\xint_bye}%
+ \xint:
+ #3\empty#5\xint_bye
+}%
+\def\POL_mul_b #1{{#1}\POL_mul_c\empty}%
+\def\POL_mul_c #1\xint:#2%
+{%
+ \xint_bye#2\POL_mul_E\xint_bye
+ \expandafter\POL_mul_d\expandafter{#1}{#2}%
+}%
+\def\POL_mul_d #1#2#3\empty#4\xint_bye
+{%
+ \expandafter\POL_mul_b
+ \expanded\bgroup
+ \expandafter\POL_add_A
+ \expanded{\POL_apply:x_loop{\xintMul{#2}}#4\xint_bye}%
+ \xint_bye\xint_bye\xint_bye\xint_bye\empty
+ #1\xint_bye\xint_bye\xint_bye\xint_bye\empty
+ \xint:
+ #3\empty#4\xint_bye
+}%
+\def\POL_mul_E\xint_bye
+ \expandafter\POL_mul_d\expandafter#1#2\xint_bye
+% This #1 starts with \empty
+{%
+ #1%
+}%
+%%
+%% POWERS
+%%
+\def\xintPolPow #1%
+{%
+ \expanded\expandafter\POL_pow_in\romannumeral`&&@#1\xint:
+}%
+\def\POL_pow_in #1\xint:#2%
+{%
+ {%
+ \expandafter\POL_pow_fork\the\numexpr \xintNum{#2}.#1\empty
+ }%
+}%
+\def\POL_pow_fork #1#2.%
+{%
+ \xint_UDzerominusfork
+ #1-\POL_pow_zero
+ 0#1\POL_pow_neg
+ 0-\POL_pow_pos
+ \krof
+ #1#2.%
+}%
+\def\POL_pow_zero #1\empty{1/1[0]}%
+\def\POL_pow_neg #1.#2%
+{%
+ \POL_Pfork #2{\POL_pow_neg_pol}P{\POL_pow_scalar}\krof #1.#2%
+}%
+\def\POL_pow_pos #1.#2%
+{%
+ \POL_Pfork #2{\POL_pow_a}P{\POL_pow_scalar}\krof #1.#2%
+}%
+\def\POL_pow_scalar #1.#2\empty
+{%
+ \xintPow{#2}{#1}%
+}%
+\def\POL_pow_neg_pol #1.#2\empty
+{%
+ \romannumeral0\XINT_signalcondition{InvalidOperation}%
+ {Not supported: polynomial to negative power #1}{}{1/1[0]}%
+}%
+\def\POL_pow_a #1.%
+{%
+% trailing \empty will disappear in expanded context (old comment)
+ \ifnum#1=\xint_c_i\xint_afterfi\xint_gob_til_dot\fi
+ \expandafter\POL_pow_b \the\numexpr#1-\xint_c_i.%
+}%
+\def\POL_pow_b #1.%
+{%
+ \ifodd #1 \xint_dothis{\expandafter\POL_pow_even}\fi
+ \xint_orthat{\expandafter\POL_pow_odd}\the\numexpr#1/\xint_c_ii.%
+}%
+\def\POL_pow_even #1.#2\empty
+{%
+ \expandafter\POL_pow_a
+ \expanded{\unexpanded{#1.}%
+ \POL_mul_a#2\xint_bye
+ #2\xint_Bye\xint_Bye\xint_Bye\xint_Bye
+ \xint_Bye\xint_Bye\xint_Bye\xint_Bye\xint_bye
+ }\empty
+}%
+\def\POL_pow_odd #1.#2\empty
+{%
+ \expanded
+ {\unexpanded{\POL_mul_a #2\xint_bye}%
+ \expandafter\POL_pow_a
+ \expanded{\unexpanded{#1.}%
+ \POL_mul_a#2\xint_bye
+ #2\xint_Bye\xint_Bye\xint_Bye\xint_Bye
+ \xint_Bye\xint_Bye\xint_Bye\xint_Bye\xint_bye
+ }%
+ \empty
+ }%
+ \xint_Bye\xint_Bye\xint_Bye\xint_Bye
+ \xint_Bye\xint_Bye\xint_Bye\xint_Bye\xint_bye
+}%
+%%
+%% DIVISION
+%%
+%
+% / is deprecated for polynomial Euclidean division
+%
+\def\xintPolQuo #1%
+{%
+ \romannumeral0\expandafter\xint_stop_atfirstoftwo
+ \expanded\expandafter\POL_quorem_in\romannumeral`&&@#1\xint:
+}%
+% there is no operator, for lack of obvious best notation
+\def\xintPolRem #1%
+{%
+ \romannumeral0\expandafter\xint_stop_atsecondoftwo
+ \expanded\expandafter\POL_quorem_in\romannumeral`&&@#1\xint:
+}%
+% //
+\def\xintPolDivModQ #1%
+{%
+ \romannumeral0\expandafter\xint_stop_atfirstoftwo
+ \expanded\expandafter\POL_divmod_in\romannumeral`&&@#1\xint:
+}%
+% /:
+\def\xintPolDivModR #1%
+{%
+ \romannumeral0\expandafter\xint_stop_atsecondoftwo
+ \expanded\expandafter\POL_divmod_in\romannumeral`&&@#1\xint:
+}%
+% "divmod" will apply coefficient per coefficient when divisor is scalar
+% I have found it convenient to treat constant polynomials
+% as really being scalars. But I need perhaps to think more about it.
+\def\xintPolDivMod #1%
+{%
+ \expanded\expandafter\POL_divmod_in\romannumeral`&&@#1\xint:
+}%
+% the euclidean division
+\def\xintPolQuoRem #1%
+{%
+ \expanded\expandafter\POL_quorem_in\romannumeral`&&@#1\xint:
+}%
+\def\POL_quorem_in #1\xint:#2%
+{%
+ {%
+ \expandafter\POL_quorem_fork
+ \romannumeral`&&@#2\xint_bye#1\xint_bye
+ }%
+}%
+% the overloading of divmod which does euclidean division if divisor is not a scalar
+\def\POL_divmod_in #1\xint:#2%
+{%
+ {%
+ \expandafter\POL_divmod_fork
+ \romannumeral`&&@#2\xint_bye#1\xint_bye
+ }%
+}%
+% "first" and "second" refer to the actual positions, permuted compared
+% to original arguments
+\def\POL_quorem_fork #1#2\xint_bye#3%
+{%
+ \POL_PPfork
+ #1#3{\POL_quorem_a}% both polynomials -> {eucl. quotient}{remainder}
+ #1P{\POL_quorem_second_is_scalar}% -> {zero quotient}{scalar}
+ #3P{\POL_quorem_first_is_scalar}% -> {polynomial/scalar}{zero}
+ PP{\POL_quorem_both_are_scalar}% -> {scalar/scalar}{zero}
+ \krof #1#2\xint_bye#3%
+}%
+\def\POL_quorem_first_is_scalar #1\xint_bye#2\xint_bye
+{%
+ {\expandafter\POL_quorem_first_is_scalar_i\expandafter
+ {\romannumeral0\xintinv{#1}}%
+ #2\xint_Bye\xint_Bye\xint_Bye\xint_Bye
+ \xint_Bye\xint_Bye\xint_Bye\xint_Bye\xint_bye}{0/1[0]}%
+}%
+\def\POL_quorem_first_is_scalar_i #1#2.%
+{%
+ #2.\POL_apply:x_loop{\xintMul{#1}}%
+}%
+% #2 was initial first argument and is scalar
+\def\POL_quorem_second_is_scalar #1\xint_bye#2\xint_bye
+{%
+ {0/1[0]}{#2}%
+}%
+\def\POL_quorem_both_are_scalar #1\xint_bye#2\xint_bye
+{%
+ {\xintDiv{#2}{#1}}{0/1[0]}%
+}%
+% attention that "first", "second" refer to the actual arguments positions
+\def\POL_divmod_fork #1#2\xint_bye#3%
+{%
+ \POL_PPfork
+ #1#3{\POL_quorem_a}% both polynomials -> {eucl. quotient}{remainder}
+ #1P{\POL_quorem_second_is_scalar}% -> {zero quotient}{scalar}
+ #3P{\POL_divmod_first_is_scalar}% -> {per coeff//scalar}{per coeff/:scalar}
+ PP{\POL_divmod_both_are_scalar}% -> {s1//s2}{s1/:s2}
+ \krof #1#2\xint_bye#3%
+}%
+\def\POL_divmod_both_are_scalar #1\xint_bye#2\xint_bye
+{%
+ \xintDivMod{#2}{#1}%
+}%
+\def\POL_divmod_first_is_scalar #1\xint_bye #2.#3\xint_bye
+{%
+ \expandafter\POL_divmod_first_is_scalar_a
+ \expanded{\unexpanded{{#1}}\expandafter}%
+ \romannumeral0\XINT_revwbr_loop {}%
+ #3\xint:\xint:\xint:\xint:%
+ \xint:\xint:\xint:\xint:\xint_bye
+ \xint_Bye\xint_Bye\xint_Bye\xint_Bye
+ \xint_Bye\xint_Bye\xint_Bye\xint_Bye\xint_bye
+ \iffalse{\fi}%
+ \xint:
+}%
+\long\def\POL_exchange_args#1#2#3{#1{#3}{#2}}%
+\def\POL_divmod_first_is_scalar_a #1%
+{%
+ \expandafter\POL_divmod_first_is_scalar_b
+ \expanded\bgroup
+ \POL_apply:x_loop{\POL_exchange_args\xintDivMod{#1}}%
+}%
+% attention re-use of \POL_add_d
+\def\POL_divmod_first_is_scalar_b #1\xint:
+{%
+ {\expandafter\POL_add_d\expanded{%
+ \POL_apply:x_loop{\expandafter\xint_firstoftwo\xint_firstofone}%
+ #1\xint_Bye\xint_Bye\xint_Bye\xint_Bye
+ \xint_Bye\xint_Bye\xint_Bye\xint_Bye\xint_bye}\xint_bye}%
+ {\expandafter\POL_add_d\expanded{%
+ \POL_apply:x_loop{\expandafter\xint_secondoftwo\xint_firstofone}%
+ #1\xint_Bye\xint_Bye\xint_Bye\xint_Bye
+ \xint_Bye\xint_Bye\xint_Bye\xint_Bye\xint_bye}\xint_bye}%
+}%
+\def\POL_quorem_a P#1.#2\xint_bye P#3.#4\xint_bye
+{%
+ \ifnum#1>#3 \xint_dothis{\POL_quorem_easy #3.}\fi
+ \xint_orthat
+ {\expandafter\POL_quorem_EQuo
+ \expanded\bgroup
+ \expandafter\POL_quorem_b\the\numexpr#3-#1\expandafter.%
+ \expanded\bgroup
+ \xintRevWithBraces
+ }%
+ {#2}%
+ \noexpand\xint_Bye
+ \xint:
+ \expandafter\POL_placemark_loop
+ \the\numexpr#1-\xint_c_vii\expandafter.%
+ \romannumeral0\xintrevwithbraces{#4}%
+% This added {1} is related to termination clean-up (a bit annoying) process
+ {1}%
+ \the\numexpr#3-#1.%
+ \iffalse{\fi}%
+}%
+\def\POL_quorem_easy #1.#2\xintrevwithbraces#3#4.#5#6%
+{%
+ {0/1[0]}{P#1.#3}%
+}%
+\def\POL_placemark_loop #1#2.%
+{%
+ \xint_gob_til_minus#1\POL_placemark_loop_end-%
+ \expandafter\POL_placemark_step\the\numexpr#1#2-\xint_c_viii.%
+}%
+\def\POL_placemark_step #1.#2#3#4#5#6#7#8#9%
+{%
+ {#2}{#3}{#4}{#5}{#6}{#7}{#8}{#9}\POL_placemark_loop#1.%
+}%
+\def\POL_placemark_loop_end-%
+ \expandafter\POL_placemark_step\the\numexpr-#1-\xint_c_viii.%
+{%
+ \csname POL_placemark_end#1\endcsname
+}%
+\expandafter\def\csname POL_placemark_end1\endcsname
+ #1#2#3#4#5#6#7{{#1}{#2}{#3}{#4}{#5}{#6}{#7}\noexpand\xint_bye\xint:}%
+\expandafter\def\csname POL_placemark_end2\endcsname
+ #1#2#3#4#5#6{{#1}{#2}{#3}{#4}{#5}{#6}\noexpand\xint_bye\xint:}%
+\expandafter\def\csname POL_placemark_end3\endcsname
+ #1#2#3#4#5{{#1}{#2}{#3}{#4}{#5}\noexpand\xint_bye\xint:}%
+\expandafter\def\csname POL_placemark_end4\endcsname
+ #1#2#3#4{{#1}{#2}{#3}{#4}\noexpand\xint_bye\xint:}%
+\expandafter\def\csname POL_placemark_end5\endcsname
+ #1#2#3{{#1}{#2}{#3}\noexpand\xint_bye\xint:}%
+\expandafter\def\csname POL_placemark_end6\endcsname
+ #1#2{{#1}{#2}\noexpand\xint_bye\xint:}%
+\expandafter\def\csname POL_placemark_end7\endcsname
+ #1{{#1}\noexpand\xint_bye\xint:}%
+\expandafter\def\csname POL_placemark_end8\endcsname
+ {\noexpand\xint_bye\xint:}%
+\def\POL_quorem_b #1.#2#3\xint:#4#5\xint:#6%
+{%
+% \xintDiv FG computes F/G
+ \expandafter\POL_quorem_c\romannumeral0\xintdiv{\XINT_Opp#4}{#2}.%
+ #1.{#2}#3\xint:
+% there is already \xint_Bye at ends of #3
+ #3\xint_Bye\xint_Bye\xint_Bye
+ \xint_Bye\xint_Bye\xint_Bye\xint_Bye\xint_bye
+% this terminates the \expanded from \POL_apply:x_loop
+ \iffalse{\fi}%
+ \xint_bye\xint_bye\xint_bye\xint_bye\empty
+ #5\xint_bye\xint_bye\xint_bye\empty
+% a \iffalse{\fi} will get inserted by \POL_add_A here
+ {#6}\xint_bye\xint:
+}%
+\def\POL_quorem_c #1.#2.#3\xint:%
+{%
+ {\XINT_Opp#1}%
+ \expandafter\POL_quorem_d\the\numexpr#2-\xint_c_i\expandafter.%
+ \expanded\bgroup
+ \unexpanded{#3}\xint:
+ \expandafter\POL_add_A
+ \expanded\bgroup
+ \POL_apply:x_loop{\xintMul{#1}}%
+}%
+\def\POL_quorem_d #1#2.%
+{%
+ \xint_gob_til_minus#1\POL_quorem_E-%
+ \POL_quorem_b #1#2.%
+}%
+\def\POL_quorem_E-\POL_quorem_b-1.#1\xint:#2\xint_bye\xint:#3.%
+{%
+% this terminates the \POL_quorem_a \expanded
+ \iffalse{\fi}\xint:#3.%
+% recycling some termination code from addition
+ {\expandafter\POL_quorem_ERem_fix\expanded{\POL_add_d#2\xint_bye}}%
+}%
+\def\POL_quorem_ERem_fix #1%
+{%
+ \if P#1\expandafter\POL_quorem_ERem_fix_a\fi 0/1[0]%
+}%
+\def\POL_quorem_ERem_fix_a 0/1[0]#1.#2%
+{%
+ \ifcase #1
+ \or
+ \expandafter\xint_firstofone
+ \else
+ P\the\numexpr#1-\xint_c_i.%
+ \fi
+}%
+\def\POL_quorem_EQuo#1\xint:#2.%
+{%
+ {\ifnum#2=\xint_c_
+ #1%
+ \else
+ P#2.\romannumeral0\XINT_revwbr_loop {}%
+ #1\xint:\xint:\xint:\xint:%
+ \xint:\xint:\xint:\xint:\xint_bye
+ \fi}%
+}%
+\def\xintPolPRem #1%
+{%
+ \expanded\expandafter\POL_prem_in\romannumeral`&&@#1\xint:
+}%
+\def\POL_prem_in #1\xint:#2%
+{%
+ \bgroup
+ \expandafter\POL_prem_fork
+ \romannumeral`&&@#2\xint:#1\xint:
+ \POL_prem_end
+}%
+\def\POL_prem_fork #1#2\xint:#3%
+{%
+ \POL_PPfork
+ #1#3{\POL_prem_a}% both polynomials
+ #1P{\POL_prem_second_is_scalar}% -> scalar
+ #3P{\POL_prem_first_is_scalar}% -> zero
+ PP{\POL_prem_both_are_scalar}% -> zero
+ \krof #1#2\xint:#3%
+}%
+\def\POL_prem_first_is_scalar #1\xint:#2\xint:\POL_prem_end
+{%
+ \iffalse{\fi}{1/1[0]}{0/1[0]}%
+}%
+\def\POL_prem_second_is_scalar #1\xint:#2\xint:\POL_prem_end
+{%
+ \iffalse{\fi}{1/1[0]}{#2}%
+}%
+\def\POL_prem_both_are_scalar #1\xint:#2\xint:\POL_prem_end
+{%
+ \iffalse{\fi}{1/1[0]}{0/1[0]}%
+}%
+\def\POL_prem_a P#1.#2\xint: P#3.#4\xint:
+{%
+ \ifnum#1>#3 \xint_dothis{\POL_prem_easy #3.}\fi
+ \xint_orthat
+ {\expandafter\POL_prem_b\the\numexpr#3-#1\expandafter.%
+ \expanded\bgroup
+ \xintRevWithBraces
+ }%
+ {#2}%
+ \noexpand\xint_Bye
+ \xint:
+ \expandafter\POL_placeBye_loop
+ \the\numexpr#1-\xint_c_vii\expandafter.%
+ \romannumeral0\xintrevwithbraces{#4}%
+ {1/1[0]}%
+ \iffalse{\fi}%
+}%
+\def\POL_prem_easy #1.#2\xintrevwithbraces#3#4\POL_prem_end
+{%
+ \iffalse{\fi}{1/1[0]}{P#1.#3}%
+}%
+\def\POL_placeBye_loop #1#2.%
+{%
+ \xint_gob_til_minus#1\POL_placeBye_loop_end-%
+ \expandafter\POL_placeBye_step\the\numexpr#1#2-\xint_c_viii.%
+}%
+\def\POL_placeBye_step #1.#2#3#4#5#6#7#8#9%
+{%
+ {#2}{#3}{#4}{#5}{#6}{#7}{#8}{#9}\POL_placeBye_loop#1.%
+}%
+\def\POL_placeBye_loop_end-%
+ \expandafter\POL_placeBye_step\the\numexpr-#1-\xint_c_viii.%
+{%
+ \csname POL_placeBye_end#1\endcsname
+}%
+\expandafter\def\csname POL_placeBye_end1\endcsname
+ #1#2#3#4#5#6#7{{#1}{#2}{#3}{#4}{#5}{#6}{#7}\noexpand\xint_Bye\xint:{1}}%
+\expandafter\def\csname POL_placeBye_end2\endcsname
+ #1#2#3#4#5#6{{#1}{#2}{#3}{#4}{#5}{#6}\noexpand\xint_Bye\xint:{1}}%
+\expandafter\def\csname POL_placeBye_end3\endcsname
+ #1#2#3#4#5{{#1}{#2}{#3}{#4}{#5}\noexpand\xint_Bye\xint:{1}}%
+\expandafter\def\csname POL_placeBye_end4\endcsname
+ #1#2#3#4{{#1}{#2}{#3}{#4}\noexpand\xint_Bye\xint:{1}}%
+\expandafter\def\csname POL_placeBye_end5\endcsname
+ #1#2#3{{#1}{#2}{#3}\noexpand\xint_Bye\xint:{1}}%
+\expandafter\def\csname POL_placeBye_end6\endcsname
+ #1#2{{#1}{#2}\noexpand\xint_Bye\xint:{1}}%
+\expandafter\def\csname POL_placeBye_end7\endcsname
+ #1{{#1}\noexpand\xint_Bye\xint:{1}}%
+\expandafter\def\csname POL_placeBye_end8\endcsname
+ {\noexpand\xint_Bye\xint:{1}}%
+\def\POL_prem_b_skip#1#2\unexpanded#3#4#5\xint_Bye#6\xint:#7#8#9%
+{%
+ \iffalse{\fi\expandafter}\xint_gobble_i#5#1%
+}%
+\def\POL_prem_b #1.#2#3\xint:#4#5\xint:#6#7%
+{%
+ \expandafter\POL_prem_c\the\numexpr#1-\xint_c_i\expandafter.%
+ \expanded\bgroup
+ \unexpanded{{#2}#3}\xint:
+ \if0\XINT_Sgn#4\xint:\xint_afterfi
+ {\expandafter\POL_prem_b_skip\expandafter
+ {\expandafter{\romannumeral0\xintmul{#6}{#7}}\xint_Bye\xint:{#6}}%
+ }%
+ \fi
+ \expandafter\POL_add_A
+ \expanded\bgroup
+ \expanded{\noexpand\POL_apply:x_loop{\noexpand\xintMul
+ {\if1\XINT_Sgn#2\xint:\expandafter\XINT_Opp\fi#4}}}%
+% there is already \xint_Bye at ends of #3
+ #3\xint_Bye\xint_Bye\xint_Bye
+ \xint_Bye\xint_Bye\xint_Bye\xint_Bye\xint_bye
+% separator for \POL_add_A
+ \unexpanded{\xint_bye\xint_bye\xint_bye\xint_bye\empty}%
+% there is already \xint_Bye at ends of #5
+ \expanded{\noexpand\POL_apply:x_loop{\noexpand\xintMul{\XINT_Abs#2}}}%
+ #5\xint_Bye\xint_Bye\xint_Bye
+ \xint_Bye\xint_Bye\xint_Bye\xint_Bye\xint_bye
+ \unexpanded{\xint_bye\xint_bye\xint_bye\xint_bye\empty}%
+% a \iffalse{\fi} will get inserted by \POL_add_A exit routine and if will
+% terminate the \expanded triggered here after \POL_prem_c
+% what is next will have already have been expanded
+ {\xintMul{\xintMul{\XINT_Abs#2}{#6}}{#7}}\noexpand\xint_Bye\xint:
+ {\xintMul{\XINT_Abs#2}{#6}}%
+% This terminates the \expanded following \POL_add_A
+ \iffalse{\fi}%
+}%
+\def\POL_prem_c #1%
+{%
+ \xint_gob_til_minus#1\POL_prem_E_-\POL_prem_b#1%
+}%
+% attention that #2 here has a two dummies at end
+% advantage is that \POL_add_a will always think it is non scalar
+\def\POL_prem_E_-\POL_prem_b-1.#1\xint:#2\xint_Bye\xint:#3%
+{%
+ \expandafter\POL_prem_E\expanded{\POL_add_d#2\xint_bye}%
+}%
+\def\POL_prem_E #1%
+{%
+ \if P#1\expandafter\POL_prem_E_i
+ \else\expandafter\POL_prem_E_zero
+ \fi #1%
+}%
+\def\POL_prem_E_zero #1\POL_prem_end{\iffalse{\fi}{#1}{0/1[0]}}%
+\def\POL_prem_E_i P#1.%
+{%
+ \ifnum #1>\xint_c_i\POL_prem_E_ii#1.\fi
+ \POL_prem_E_iii%
+}%
+\def\POL_prem_E_iii#1\POL_prem_end{\iffalse{\fi}#1}%
+\def\POL_prem_E_ii#1.#2\POL_prem_E_iii#3%
+ {#2{#3}{P\the\numexpr#1-\xint_c_i\iffalse}\fi.}%
+\def\POL_prem_end{\iffalse{{\fi}}}%
+%%
+%% SUPPORT FOR FUNCTIONAL INTERFACE
+%%
+% should I do a qpol([]) ?, i.e. without testing for leading zeros, hence
+% would be faster ? but advantage would arise only for very high degree
+% pol([]) this one checks for zeros in the right most coeffs
+\def\xintPolPol#1{\romannumeral`&&@\expandafter\POL_add_d
+ \romannumeral0\expandafter\XINT_revwbr_loop\expandafter
+ {\expandafter}%
+ \romannumeral`&&@#1\xint:\xint:\xint:\xint:
+ \xint:\xint:\xint:\xint:\xint_bye
+ \xint_bye
+}%
+% attention to not overwrite macro names (there is a legacy \PolEvalAt)
+\def\xintPolEvalAt#1#2%
+{%
+% generally, #2 will be scalar, but we allow also a polynomial here
+% should I test for #2 being the monomial, hence handle it very quickly?
+ \romannumeral`&&@\expandafter\POL_evalat_in\romannumeral`&&@#2\xint:
+ #1\xint:\xint:\xint:\xint:
+ \xint:\xint:\xint:\xint:\xint_bye\xint:
+}%
+\def\POL_evalat_in #1\xint:
+{%
+ \expandafter\POL_evalat_fork\expanded{\unexpanded{#1\xint:}\expandafter}%
+ \romannumeral`&&@%
+}%
+\def\POL_evalat_fork #1\xint:#2%
+{%
+ \POL_Pfork
+ #2{\POL_evalat_pol}%
+ P{\POL_evalat_cst}%
+ \krof #1\xint:#2%
+}%
+\def\POL_evalat_cst #1\xint: #2\xint:#3\xint_bye\xint:{#2}%
+\def\POL_evalat_pol #1\xint: P#2.%
+{%
+ \expanded{\unexpanded{\POL_evalat_a#1\xint:}\expandafter}%
+ \romannumeral0\XINT_revwbr_loop{}%
+}%
+\def\POL_evalat_a#1\xint:#2%
+{%
+ \POL_evalat_loop#2\xint:#1\xint:
+}%
+\def\POL_evalat_loop#1\xint:#2\xint:#3%
+{%
+ \xint_gob_til_xint:#3\POL_evalat_E\xint:
+% I have dropped here my old strict \xintFoo = \romannumeral0\xintfoo style
+% ATTENTION! We must allow evaluating at a polynomial expression
+ \expandafter\POL_evalat_loop
+ \romannumeral`&&@\xintPolAdd{#3}{\xintPolMul{#2}{#1}}\xint:#2\xint:
+}%
+\def\POL_evalat_E\xint:\expandafter\POL_evalat_loop
+ \romannumeral`&&@\xintPolAdd #1#2\xint:#3\xint:
+{%
+ \xint_thirdofthree#2%
+}%
+%
+\def\xintPolDeg#1%
+{%
+ \romannumeral`&&@\expandafter\POL_deg_fork\romannumeral`&&@#1\xint:
+}%
+\def\POL_deg_fork #1%
+{%
+ \POL_zeroPfork
+ #1P{\POL_deg_zero}%
+ 0#1{\POL_deg_pol}%
+ 0P{\POL_deg_cst}%
+ \krof #1%
+}%
+% usual hesitations about using or not raw frac format
+\def\POL_deg_zero#1\xint:{-1}%
+\def\POL_deg_cst #1\xint:{0}%
+\def\POL_deg_pol P#1.#2\xint:{#1}%
+%
+\def\xintPolCoeffs#1%
+{%
+ \romannumeral`&&@\expandafter\POL_coeffs_fork\romannumeral`&&@#1\xint:
+}%
+\def\POL_coeffs_fork #1%
+{%
+ \POL_Pfork
+ #1\POL_coeffs_pol
+ P\POL_coeffs_cst
+ \krof #1%
+}%
+% usual hesitations about using or not raw frac format
+\def\POL_coeffs_cst #1\xint:{{#1}}%
+% no brace stripping possible, at least two coefficients
+% annoying that we had to put this delimiter \xint:
+\def\POL_coeffs_pol P#1.#2\xint:{#2}%
+%
+\def\xintPolCoeff#1#2%
+{%
+ \romannumeral`&&@\expandafter\POL_coeff_fork
+ \the\numexpr\xintNum{#2}\expandafter.%
+ \romannumeral`&&@#1\xint:
+}%
+\def\POL_coeff_fork #1.#2%
+{%
+ \POL_Pfork
+ #2\POL_coeff_pol
+ P\POL_coeff_cst
+ \krof #1.#2%
+}%
+\def\POL_coeff_cst#1%
+{%
+ \xint_UDzerofork
+ #1\POL_coeff_itself
+ 0\POL_coeff_zero
+ \krof #1%
+}%
+\def\POL_coeff_itself#1.#2\xint:{#2}%
+\def\POL_coeff_zero#1\xint:{0/1[0]}%
+\def\POL_coeff_pol #1.P#2.%
+{%
+ \ifnum#1<\xint_c_\xint_dothis\POL_coeff_zero\fi
+ \ifnum#1>#2 \xint_dothis\POL_coeff_zero\fi
+ \xint_orthat\POL_coeff_a{#1}%
+}%
+\def\POL_coeff_a#1{\expandafter\POL_coeff_b\romannumeral\xintgobble{#1}}%
+\def\POL_coeff_b#1#2\xint:{#1}%
+%
+\def\xintPolLCoeff#1%
+{%
+ \romannumeral`&&@\expandafter\POL_lcoeff_fork
+ \romannumeral`&&@#1\xint:
+}%
+\def\POL_lcoeff_fork #1%
+{%
+ \POL_Pfork
+ #1\POL_lcoeff_pol
+ P\POL_lcoeff_cst
+ \krof #1%
+}%
+\def\POL_lcoeff_cst#1\xint:{#1}%
+\def\POL_lcoeff_pol P#1.%
+{%
+ \expandafter\POL_lcoeff_a\romannumeral\xintgobble{#1}%
+}%
+\def\POL_lcoeff_a#1\xint:{#1}%
+%
+\def\xintPolMonicPart#1%
+{%
+ \romannumeral`&&@\expandafter\POL_monicpart_fork
+ \romannumeral`&&@#1\xint:
+}%
+\def\POL_monicpart_fork #1%
+{%
+ \POL_Pfork
+ #1\POL_monicpart_pol
+ P\POL_monicpart_cst
+ \krof #1%
+}%
+% monicpart(0) must be 0 to avoid breaking algorithms
+\def\POL_monicpart_cst#1#2\xint:{\if#10\xint_dothis0\fi\xint_orthat1/1[0]}%
+\def\POL_monicpart_pol P#1.#2\xint:%
+{%
+ \expanded{%
+ P#1.%
+ \expandafter\POL_monicpart_a\romannumeral\xintgobble{#1}%
+ #2#2\xint_Bye\xint_Bye\xint_Bye\xint_Bye
+ \xint_Bye\xint_Bye\xint_Bye\xint_Bye\xint_bye
+ }%
+}%
+\def\POL@DivByFirstAndIrrAndREZ#1#2{\xintREZ{\xintIrr{\xintDiv{#2}{#1}}}}%
+\def\POL_monicpart_a#1%
+{%
+ \POL_apply:x_loop{\POL@DivByFirstAndIrrAndREZ{#1}}%
+}%
+%
+\def\xintPolIContent#1%
+{%
+ \romannumeral`&&@\expandafter\POL_icontent_fork
+ \romannumeral`&&@#1^%
+}%
+\def\POL_icontent_fork #1%
+{%
+ \POL_Pfork
+ #1\POL_icontent_pol
+ P\POL_icontent_cst
+ \krof #1%
+}%
+\def\POL_icontent_cst #1^{\xintIrr{\xintAbs{#1}}[0]}%
+\def\POL_icontent_pol P#1.%
+{%
+% 1.4d xintfrac \XINT_fgcdof much saner than 1.4 version !
+% \XINT_fgcd_out does \xintIrr
+ \expandafter\XINT_fgcd_out\romannumeral0\XINT_fgcdof
+}%
+%
+\def\xintPolPrimPart#1%
+{%
+ \romannumeral`&&@\expandafter\POL_primpart_fork
+ \romannumeral`&&@#1\xint:
+}%
+\def\POL_primpart_fork #1%
+{%
+ \POL_Pfork
+ #1\POL_primpart_pol
+ P\POL_primpart_cst
+ \krof #1%
+}%
+\def\POL_primpart_cst#1#2\xint:{\if#10\xint_dothis0\fi\xint_orthat1/1[0]}%
+\def\POL_primpart_pol P#1.#2\xint:%
+{%
+ \expanded{%
+ P#1.\expandafter\POL_primpart_a
+ \romannumeral0\expandafter\XINT_fgcd_out
+ \romannumeral0\XINT_fgcdof#2^\xint:
+ #2\xint_Bye\xint_Bye\xint_Bye\xint_Bye
+ \xint_Bye\xint_Bye\xint_Bye\xint_Bye\xint_bye
+ }%
+}%
+% cf legacy \POL@makeprim@macro
+\def\POL@DivByFirstAndNumAndREZ#1#2{\xintREZ{\xintNum{\xintDiv{#2}{#1}}}}%
+\def\POL_primpart_a#1\xint:{\POL_apply:x_loop{\POL@DivByFirstAndNumAndREZ{#1}}}%
+%
+\def\xintPolRedCoeffs#1%
+{%
+ \romannumeral`&&@\expandafter\POL_redcoeffs_fork
+ \romannumeral`&&@#1\xint:
+}%
+\def\POL_redcoeffs_fork #1%
+{%
+ \POL_Pfork
+ #1\POL_redcoeffs_pol
+ P\POL_redcoeffs_cst
+ \krof #1%
+}%
+\def\POL_redcoeffs_cst#1\xint:{\xintIrr{#1}[0]}%
+\def\POL_redcoeffs_pol P#1.#2\xint:%
+{%
+ \expanded{%
+ P#1.\POL_apply:x_loop\POL@xintIrr
+ #2\xint_Bye\xint_Bye\xint_Bye\xint_Bye
+ \xint_Bye\xint_Bye\xint_Bye\xint_Bye\xint_bye
+ }%
+}%
+%
+\def\xintPolSRedCoeffs#1%
+{%
+ \romannumeral`&&@\expandafter\POL_sredcoeffs_fork
+ \romannumeral`&&@#1\xint:
+}%
+\def\POL_sredcoeffs_fork #1%
+{%
+ \POL_Pfork
+ #1\POL_sredcoeffs_pol
+ P\POL_sredcoeffs_cst
+ \krof #1%
+}%
+\def\POL_sredcoeffs_cst#1\xint:{\xintREZ{\xintIrr{#1}[0]}}%
+\def\POL_sredcoeffs_pol P#1.#2\xint:%
+{%
+ \expanded{%
+ P#1.\POL_apply:x_loop\POL@xintIrrAndREZ
+ #2\xint_Bye\xint_Bye\xint_Bye\xint_Bye
+ \xint_Bye\xint_Bye\xint_Bye\xint_Bye\xint_bye
+ }%
+}%
+\def\POL@xintIrrAndREZ#1{\xintREZ{\xintIrr{#1}[0]}}%
+%
+\def\xintPolDiffOne#1%
+{%
+ \romannumeral`&&@\expandafter\POL_diffone_fork
+ \romannumeral`&&@#1\xint:
+}%
+\def\POL_diffone_fork #1%
+{%
+ \POL_Pfork
+ #1\POL_diffone_pol
+ P\POL_diffone_cst
+ \krof #1%
+}%
+\def\POL_diffone_cst#1\xint:{0/1[0]}%
+\def\POL_diffone_pol P#1.#2#3\xint:%
+{%
+ \expanded{%
+ \ifnum#1=\xint_c_i #3%
+ \else
+ P\the\numexpr#1-\xint_c_i.%
+ \POL_apply:x_iloop{\POL_diffone_diff1.}%
+ #3\xint_Bye\xint_Bye\xint_Bye\xint_Bye
+ \xint_Bye\xint_Bye\xint_Bye\xint_Bye\xint_bye
+ \fi
+ }%
+}%
+\def\POL_diffone_diff#1.#2#3{\xintMul{#1+#2}{#3}}%
+%
+\def\xintPolAntiOne#1%
+{%
+ \romannumeral`&&@\expandafter\POL_antione_fork
+ \romannumeral`&&@#1\xint:
+}%
+\def\POL_antione_fork #1%
+{%
+ \POL_Pfork
+ #1\POL_antione_pol
+ P\POL_antione_cst
+ \krof #1%
+}%
+\def\POL_antione_cst#1%
+{%
+ \xint_gob_til_zero#1\POL_antione_zero0\POL_antione_cst_i#1%
+}%
+\def\POL_antione_cst_i#1\xint:{P1.{0/1[O]}{#1}}%
+\def\POL_antione_zero#1\xint:{0/1[0]}%
+\def\POL_antione_pol P#1.#2\xint:%
+{%
+ \expanded{%
+ P\the\numexpr#1+\xint_c_i.{0/1[0]}%
+ \POL_apply:x_iloop{\POL_antione_anti1.}%
+ #2\xint_Bye\xint_Bye\xint_Bye\xint_Bye
+ \xint_Bye\xint_Bye\xint_Bye\xint_Bye\xint_bye
+ }%
+}%
+\def\POL_antione_anti#1.#2#3{\xintDiv{#3}{#1+#2}}%
+%
+% #2 can be a polynomial
+\def\xintPolIntFrom#1%#2%
+{%
+ \romannumeral`&&@\expandafter\POL_intfrom_a\expandafter
+ {\romannumeral`&&@\xintPolAntiOne{#1}}%
+}%
+\def\POL_intfrom_a #1#2%
+{%
+ \xintPolSub{#1}{\xintPolEvalAt{#1}{#2}}%
+}%
+%
+\def\xintPolIntegral#1#2%
+{%
+ \romannumeral`&&@\expandafter\POL_integral_a\expanded
+ {\xintPolAntiOne{#1}\xint:#2\xint:}%
+}%
+\def\POL_integral_a #1\xint:#2#3\xint:
+{%
+ \xintPolSub{\xintPolEvalAt{#1}{#3}}{\xintPolEvalAt{#1}{#2}}%
+}%
+%
+\def\xintPolDiffTwo#1%
+{%
+ \romannumeral`&&@\expandafter\POL_difftwo_fork
+ \romannumeral`&&@#1\xint:
+}%
+\def\POL_difftwo_fork #1%
+{%
+ \POL_Pfork
+ #1\POL_difftwo_pol
+ P\POL_difftwo_cst
+ \krof #1%
+}%
+\def\POL_difftwo_cst#1\xint:{0/1[0]}%
+\def\POL_difftwo_pol P#1.%
+{%
+ \ifcase #1
+ \or \expandafter\POL_difftwo_zeroout
+ \or \expandafter\POL_difftwo_cstout
+ \else\expandafter\POL_difftwo_polout
+ \fi #1.%
+}%
+\def\POL_difftwo_zeroout#1\xint:{0/1[0]}%
+\def\POL_difftwo_cstout 2.#1#2#3\xint:{\xintMul{2}{#3}}%
+\def\POL_difftwo_polout #1.#2#3#4\xint:%
+{%
+ \expanded{%
+ P\the\numexpr#1-\xint_c_ii.%
+ \POL_apply:x_iloop{\POL_difftwo_diff2.}%
+ #4\xint_Bye\xint_Bye\xint_Bye\xint_Bye
+ \xint_Bye\xint_Bye\xint_Bye\xint_Bye\xint_bye
+ }%
+}%
+\def\POL_difftwo_diff#1.#2#3{\xintMul{\the\numexpr(#1+#2)*(#1+#2-\xint_c_i)\relax}{#3}}%
+%
+\def\POL_diffone_iter_fork #1%
+{%
+ \POL_Pfork
+ #1\POL_diffone_iter_pol
+ P\POL_diffone_iter_cst
+ \krof #1%
+}%
+\def\POL_diffone_iter_cst#1\xint:{0/1[0]\xint:}%
+\def\POL_diffone_iter_pol P#1.#2#3\xint:%
+{%
+ \expanded{%
+ \ifnum#1=\xint_c_i #3%
+ \else
+ P\the\numexpr#1-\xint_c_i.%
+ \POL_apply:x_iloop{\POL_diffone_diff1.}%
+ #3\xint_Bye\xint_Bye\xint_Bye\xint_Bye
+ \xint_Bye\xint_Bye\xint_Bye\xint_Bye\xint_bye
+ \fi
+ }\xint:
+}%
+%
+\def\POL_antione_iter_fork #1%
+{%
+ \POL_Pfork
+ #1\POL_antione_iter_pol
+ P\POL_antione_iter_cst
+ \krof #1%
+}%
+\def\POL_antione_iter_cst#1%
+{%
+ \xint_gob_til_zero#1\POL_antione_iter_zero0\POL_antione_iter_cst_i#1%
+}%
+\def\POL_antione_iter_cst_i#1\xint:{P1.{0/1[O]}{#1}\xint:}%
+\def\POL_antione_iter_zero#1\xint:{0/1[0]\xint:}%
+\def\POL_antione_iter_pol P#1.#2\xint:%
+{%
+ \expanded{%
+ P\the\numexpr#1+\xint_c_i.{0/1[0]}%
+ \POL_apply:x_iloop{\POL_antione_anti1.}%
+ #2\xint_Bye\xint_Bye\xint_Bye\xint_Bye
+ \xint_Bye\xint_Bye\xint_Bye\xint_Bye\xint_bye
+ }\xint:
+}%
+%
+\def\xintPolDiffN#1#2%
+{%
+ \romannumeral`&&@\expandafter\POL_diffn_fork
+ \the\numexpr\xintNum{#2}\expandafter.%
+ \romannumeral`&&@#1\xint:
+}%
+\def\POL_diffn_fork #1%
+{%
+ \xint_UDzerominusfork
+ #1-\POL_diffn_none
+ 0#1\POL_diffn_anti
+ 0-\POL_diffn_diff
+ \krof #1%
+}%
+\def\POL_diffn_none0.#1\xint:{#1}%
+\def\POL_diffn_diff#1.%#2\xint:%
+{%
+ \ifnum#1>\xint_c_i
+ \expandafter\POL_diffn_diff\the\numexpr#1-\xint_c_i\expandafter.%
+ \romannumeral`&&@\expandafter\POL_diffone_iter_fork
+ \else
+ \expandafter\POL_diffone_fork
+ \fi
+}%
+\def\POL_diffn_anti#1.%#2\xint:%
+{%
+ \ifnum#1<-\xint_c_i
+ \expandafter\POL_diffn_anti\the\numexpr#1+\xint_c_i\expandafter.%
+ \romannumeral`&&@\expandafter\POL_antione_iter_fork
+ \else
+ \expandafter\POL_antione_fork
+ \fi
+}%
+%
+% Support for (multi-variable) polgcd
+%
+\def\xintPolGCDof #1%
+{%
+ \romannumeral`&&@\expandafter\POL_polgcdof\romannumeral`&&@#1^%
+}%
+\def\XINT_PolGCDof{\romannumeral`&&@\POL_polgcdof}%
+\def\POL_polgcdof #1%
+{%
+ \romannumeral`&&@\expandafter
+ \POL_polgcdof_chkempty\romannumeral`&&@#1\xint:
+}%
+\def\POL_polgcdof_chkempty #1%
+{%
+ \xint_gob_til_^#1\POL_polgcdof_empty ^\POL_polgcdof_in #1%
+}%
+\def\POL_polgcdof_empty #1\xint:{1/1[0]}% hesitation
+\def\POL_polgcdof_in #1\xint:
+{%
+ \expandafter\POL_polgcdof_loop
+ \romannumeral`&&@\xintPolPrimPart{#1}\xint:
+}%
+\def\POL_polgcdof_loop #1\xint:#2%
+{%
+ \expandafter\POL_polgcdof_chkend\romannumeral`&&@#2\xint:#1\xint:\xint:
+}%
+\def\POL_polgcdof_chkend #1%
+{%
+ \xint_gob_til_^#1\POL_polgcdof_end ^\POL_polgcdof_loop_pair #1%
+}%
+% hesitation with returning a monic polynomial
+%\def\POL_polgcdof_end #1\xint:#2\xint:\xint:{\xintPolMonicPart{#2}}%
+\def\POL_polgcdof_end #1\xint:#2\xint:\xint:{#2}%
+\def\POL_polgcdof_loop_pair #1\xint:
+{%
+ \expandafter\POL_polgcdof_loop
+ \romannumeral`&&@\expandafter\POL_polgcd_pair
+ \romannumeral`&&@\xintPolPrimPart{#1}\xint:
+}%
+% MEMO comme le #2 sera au début le pgcd accumulé il sera souvent de plus
+% petit degré donc il y aura souvent un premier mod "easy" un peu inutile
+% J'hésite à faire une permutation avant de lancer le polgcd_pair
+\def\POL_polgcd_pair#1\xint:#2\xint:
+{%
+ \xintiiifSgn {\xintPolDeg {#1}}%
+ {#2}%
+ {1}%
+ {\expandafter\POL_polgcd_pair
+ \romannumeral`&&@\xintPolPrimPart
+ {\expandafter\xint_secondoftwo
+ \romannumeral`&&@\xintPolPRem {#2}{#1}}\xint:
+ #1\xint:
+ }%
+}%
+%
+\endinput
diff --git a/macros/generic/polexpr/polexprexpr.tex b/macros/generic/polexpr/polexprexpr.tex
new file mode 100644
index 0000000000..9b60e7bab0
--- /dev/null
+++ b/macros/generic/polexpr/polexprexpr.tex
@@ -0,0 +1,179 @@
+%% This file polexprexpr.tex is part of the polexpr package (0.8, 2021/03/29)
+%% Extending \xintexpr syntax:
+%%
+%% 1. Authorize ' in variable and function names
+%% This currently breaks infix operators 'and', 'or', 'xor', 'mod'
+%% hence forces usage everywhere of &&, ||, /: and xor() syntax
+%% (if : is active then use /\string : input syntax!)
+%%
+%% 2. Map infix operators to the polexprcore macros
+%%
+%% Overloading of infix operators must be done even outside of \poldef's
+%% scope else functions declared via \xintdeffunc would not be usable in
+%% \poldef as they would be using the xintfrac macros unaware of polynomials
+%%
+%% The overloading of // and /: is experimental.
+%%
+%% 3. Support for the polynomial functions to work in \xintdeffunc
+%%
+%% 4. Support macros for the new functions acting on polynomial variables
+%
+% 1.
+\def\XINT_expr_scanfunc_b #1%
+{%
+ \ifcat \relax#1\xint_dothis{\iffalse{\fi}(_#1}\fi
+ \if (#1\xint_dothis{\iffalse{\fi}(`}\fi
+ \if 1\ifcat a#10\fi
+ \ifnum\xint_c_ix<1\string#1 0\fi
+ \if @#10\fi
+ \if _#10\fi
+ \if '#10\fi
+ 1%
+ \xint_dothis{\iffalse{\fi}(_#1}\fi
+ \xint_orthat {#1\XINT_expr_scanfunc_a}%
+}%
+% 2.
+% the minus sign as prefix
+\def\POL_tmp #1#2%
+{%
+ \expandafter\def\csname XINT_expr_exec_#1\endcsname##1##2##3% \XINT_expr_exec_<op><level>
+ {%
+ \expandafter ##1\expandafter ##2\expandafter
+ {\romannumeral`&&@\XINT:NEhook:f:one:from:one{\romannumeral`&&@#2##3}}%
+ }%
+}%
+\POL_tmp{-xii} \xintPolOpp
+\POL_tmp{-xiv} \xintPolOpp
+\POL_tmp{-xvi} \xintPolOpp
+\POL_tmp{-xviii}\xintPolOpp
+% infix operators
+\def\POL_tmp #1#2%
+{%
+ \expandafter\def\csname XINT_expr_exec_#1\endcsname##1##2##3##4% \XINT_expr_exec_<op>
+ {%
+ \expandafter##2\expandafter##3\expandafter
+ {\romannumeral`&&@\XINT:NEhook:f:one:from:two{\romannumeral`&&@#2##1##4}}%
+ }%
+}%
+\POL_tmp + \xintPolAdd
+\POL_tmp - \xintPolSub
+\POL_tmp * \xintPolMul
+\POL_tmp / \xintPolQuo
+% there is no infix operator mapped to \xintPolRem
+% for lack of notation: perhaps /; ? advices welcome
+\POL_tmp{//}\xintPolDivModQ
+\POL_tmp{/:}\xintPolDivModR
+\POL_tmp ^ \xintPolPow
+\expandafter\let\csname XINT_expr_op_**\expandafter\endcsname
+ \csname XINT_expr_op_^\endcsname
+% 3.
+% Matches with "mysterious stuff" section of xintexpr source code
+\let\POL:NEhook:polfunc\expandafter
+\toks0\expandafter{\XINT_expr_redefinemacros}%
+\toks2 {\let\POL:NEhook:polfunc\POL:NE:polfunc}%
+\edef\XINT_expr_redefinemacros{\the\toks0 \the\toks2}%
+\catcode`~ 12
+\def\POL@defpolfunc #1#2%
+{%
+ \expandafter\POL@defpolfunc_a
+ \csname XINT_#2_func_#1\expandafter\endcsname
+ \csname XINT_#2_polfunc_#1\endcsname
+}%
+\def\POL@defpolfunc_a #1#2%
+{%
+ \XINT_global
+ \def#1##1##2##3%
+ {%
+ \expandafter##1\expandafter##2\expandafter{%
+ \romannumeral`&&@\POL:NEhook:polfunc{\romannumeral`&&@#2##3}}%
+ }%
+}%
+\def\POL:NE:polfunc #1{%
+\def\POL:NE:polfunc ##1%
+{%
+ \if0\XINT:NE:hastilde ##1~!\relax % this ! of catcode 11
+ \XINT:NE:hashash ##1#1!\relax 0\else
+ \xint_dothis\POL:NE:polfunc_a\fi
+ \xint_orthat\POL:NE:polfunc_b
+ ##1&&A%
+}}\expandafter\POL:NE:polfunc\string#%
+\def\POL:NE:polfunc_a\romannumeral`&&@#1#2&&A%
+{%
+% If we are here #2 was not braced; \string is done with \escapechar126
+ \expandafter{\expanded{~romannumeral~POL:NE:usepolfunc%
+ {\expandafter\xint_gobble_i\string#1}}#2}%
+}%
+\def\POL:NE:polfunc_b#1{%
+\def\POL:NE:polfunc_b\romannumeral`&&@##1##2&&A%
+{%
+ \expandafter{%
+ \romannumeral`&&@%
+ \if0\XINT:NE:hastilde ##2~!\relax
+ \XINT:NE:hashash ##2#1!\relax 0\else
+ \POL:NE:polfunc_c\fi
+ ##1{##2}}%
+}}\expandafter\POL:NE:polfunc_b\string#%
+% In this case the \expandafter inserted by \POL:NE:usepolfunc
+% expansion will be superfluous
+\def\POL:NE:polfunc_c#1#2% #1=\fi
+{%
+ \expanded{#1~romannumeral~POL:NE:usepolfunc%
+ {\expandafter\xint_gobble_i\string#2}}%
+}%
+% This \expandafter is in case there is an \expanded after that due
+% to some slicing constructs
+% Call: \romannumeral\POL:NE:usepolfunc
+\def\POL:NE:usepolfunc#1{`&&@\csname#1\expandafter\endcsname}%
+\catcode`~ 3 % its normal catcode in xint bundle
+% 4.
+\def\POL_tmp #1#2#3%
+{%
+ \expandafter\def\csname XINT_expr_func_#1\endcsname##1##2##3%
+ {%
+ \expandafter ##1\expandafter ##2\expandafter
+ {%
+ \romannumeral`&&@#2{\romannumeral`&&@#3##3}%
+ }%
+ }%
+}%
+\POL_tmp {sqr} \XINT:NEhook:f:one:from:one \xintPolSqr
+\POL_tmp {pol} \XINT:NEhook:f:one:from:one \xintPolPol
+\POL_tmp {deg} \XINT:NEhook:f:one:from:one \xintPolDeg
+\POL_tmp {coeffs} \XINT:NEhook:f:one:from:one \xintPolCoeffs
+\POL_tmp {coeff} \XINT:NEhook:f:one:from:two \xintPolCoeff
+\POL_tmp {lcoeff} \XINT:NEhook:f:one:from:one \xintPolLCoeff
+\POL_tmp {monicpart} \XINT:NEhook:f:one:from:one \xintPolMonicPart
+\POL_tmp {icontent} \XINT:NEhook:f:one:from:one \xintPolIContent
+\POL_tmp {primpart} \XINT:NEhook:f:one:from:one \xintPolPrimPart
+\POL_tmp {rdcoeffs} \XINT:NEhook:f:one:from:one \xintPolRedCoeffs
+\POL_tmp {rdzcoeffs} \XINT:NEhook:f:one:from:one \xintPolSRedCoeffs
+\POL_tmp {diff1} \XINT:NEhook:f:one:from:one \xintPolDiffOne
+\POL_tmp {diff2} \XINT:NEhook:f:one:from:one \xintPolDiffTwo
+\POL_tmp {diffn} \XINT:NEhook:f:one:from:two \xintPolDiffN
+\POL_tmp {antider} \XINT:NEhook:f:one:from:one \xintPolAntiOne
+\POL_tmp {integral} \XINT:NEhook:f:one:from:two \xintPolIntegral
+\POL_tmp {quorem} \XINT:NEhook:f:one:from:two \xintPolQuoRem
+\POL_tmp {quo} \XINT:NEhook:f:one:from:two \xintPolQuo
+\POL_tmp {rem} \XINT:NEhook:f:one:from:two \xintPolRem
+\POL_tmp {prem} \XINT:NEhook:f:one:from:two \xintPolPRem
+\POL_tmp {divmod} \XINT:NEhook:f:one:from:two \xintPolDivMod
+\POL_tmp {mod} \XINT:NEhook:f:one:from:two \xintPolDivModR
+\POL_tmp {evalp} \XINT:NEhook:f:one:from:two \xintPolEvalAt
+\def\XINT_expr_func_polgcd #1#2#3%
+{%
+ \expandafter #1\expandafter #2\expandafter{\expandafter
+ {\romannumeral`&&@\XINT:NEhook:f:from:delim:u\XINT_PolGCDof#3^}}%
+}%
+% this is provisory
+\xintdeffunc polpowmod_(P, m, Q) :=
+ isone(m)?
+ % m=1: return P modulo Q
+ { mod(P,Q) }
+ % m > 1: test if odd or even and do recursive call
+ { odd(m)? { mod(P*sqr(polpowmod_(P, m//2, Q)), Q) }
+ { mod( sqr(polpowmod_(P, m//2, Q)), Q) }
+ }
+ ;%
+\xintdeffunc polpowmod(P, m, Q) := (m)?{polpowmod_(P, m, Q)}{1};%
+%
+\endinput
diff --git a/macros/latex/contrib/polexpr/polexpr.sty b/macros/generic/polexpr/polexprsturm.tex
index 30fef28914..3fa1861558 100644
--- a/macros/latex/contrib/polexpr/polexpr.sty
+++ b/macros/generic/polexpr/polexprsturm.tex
@@ -1,893 +1,4 @@
-% author: Jean-François Burnol
-% License: LPPL 1.3c (author-maintained)
-\ProvidesPackage{polexpr}%
- [2020/01/31 v0.7.5 Polynomial expressions with rational coefficients (JFB)]%
-\RequirePackage{xintexpr}[2020/01/31]% xint 1.4
-\edef\POL@restorecatcodes % TODO: think better about what is reasonable here
- {\catcode`\noexpand\_ \the\catcode`\_ %
- \catcode`\noexpand\! \the\catcode`\! %
- \catcode`\noexpand\* \the\catcode`\* %
- \catcode`\noexpand\~ \the\catcode`\~ %
- \catcode`\noexpand\: \the\catcode`\: %
- \catcode0 \the\catcode0\relax}%
-\catcode`\_ 11 \catcode0 12 \catcode`\* 12
-\long\def\xint_stop_atfirstoftwo #1#2{ #1}% not yet in xint 1.3c
-\long\def\xint_stop_atsecondoftwo #1#2{ #2}%
-
-%% 0.7.5 VERY SERIOUS TROUBLES TO GET polexpr TO WORK WITH xintexpr 1.4
-
-%% I hesitated about incorporating it directly into xint 1.4
-%% Don't do this at home, only xint gurus are allowed.
-\let\POL@originalXINT_expr_redefinemacros\XINT_expr_redefinemacros
-\def\XINT_expr_redefinemacros
-{%
- \POL@originalXINT_expr_redefinemacros
- \POL@activateNEhook
-}%
-%% Using \def's and not \let's to get better readable trace
-%% in case I need to debug but this never happens
-\def\POL@activateNEhook@xint % done in a group
-{%
- \def\POL@NEhook@polfunc{\POL@NE@polfunc}%
-}%
-\def\POL@activateNEhook@pol
-{%
- \def\POL@NEhook@polfunc{\POL@NP@polfunc}%
-}%
-\def\POL@activateNEhook{\POL@activateNEhook@xint}%
-%
-%
-\catcode`~ 12
-\catcode`! 11
-\catcode`: 11
-% We drop consideration of \XINT_global matters
-% because we have other more urgent and arduous problems
-\def\POL@defpolfunc #1#2%
-{%
- \expandafter\POL@defpolfunc_a
- \csname XINT_#2_func_#1\expandafter\endcsname
- \csname XINT_#2_polfunc_#1\endcsname {#1}{#2}%
-}%
-\def\POL@defpolfunc_a #1#2#3#4%
-{%
- \protected % xintexpr 1.4 does things such as \expandafter\xintAdd\expanded
- \expandafter\def\expandafter#2\expandafter##\expandafter1\expandafter
- {%
- #2{##1}%
- }%
- \def#1##1##2##3%
- {%
- % put it directly at the correct level of bracing
- % don't worry for now about minimizing how many times ##3 is grabbed
- \expandafter##1\expandafter##2\expandafter{\expandafter
- {\romannumeral`^^@\POL@NEhook@polfunc{XINT_#4_polfunc_#3}#2{##3}}}%
- }%
-}%
-%
-\def\POL@polfunc@go #1#2#3{#2#3}% brace stripping intentional
-\def\POL@NEhook@polfunc{\POL@polfunc@go}% default for pure numerics
-%
-% Hook for expansion in \poldef
-\def\POL@NP@polfunc #1{%
-\def\POL@NP@polfunc ##1##2##3%
-{%
- \if0\expandafter\XINT:NE:hastilde\detokenize{##3}~!\relax
- \expandafter\XINT:NE:hashash\detokenize{##3}#1!\relax 0%
- \expandafter\POL@polfunc@go
- \else
- \expandafter\POL:NP:polfunc:p
- \fi {##1}{##2}{##3}%
-}}\expandafter\POL@NP@polfunc\string#%
-\def\POL:NP:polfunc:p #1#2#3%
-{%
- ~romannumeral~POL:usepolfunc:pol{#1}{#3}%
-}%
-\def\POL:usepolfunc:pol #1%#2%
-{%
-% Here we are in the core of \poldef and we really
-% need to get rid of some \expanded tokens so
-% we accept being exposed to \expanded but arrange to
-% remain invariant. Then we will try to speed up
-% polynomial composition (at this time the \#1
-% is a nested Horner type macro) by «pre-expanding»
-% the argument, but this means using the \POL@get
-% methods inside an \hbox
-%
-% \POL@applypolfunc will be defined \protected
-%
- \expandafter\xint_c_\expandafter\POL@applypolfunc
-% This will be \protected
- \csname#1\endcsname
-% #2% brace stripping is deliberate
-}%
-%
-% Hook for expansion in \xintexpr
-\def\POL@NE@polfunc #1{%
-\def\POL@NE@polfunc ##1##2##3%
-{%
- \if0\expandafter\XINT:NE:hastilde\detokenize{##3}~!\relax
- \expandafter\XINT:NE:hashash\detokenize{##3}#1!\relax 0%
- \expandafter\POL@polfunc@go
- \else
- \expandafter\POL:NE:polfunc:p
- \fi {##1}{##2}{##3}%
-}}\expandafter\POL@NE@polfunc\string#%
-\def\POL:NE:polfunc:p #1#2#3%
-{%
- ~romannumeral~POL:usepolfunc:xint{#1}{#3}%
-}%
-\def\POL:usepolfunc:xint #1%
-{%
-% This is done to overcome \protected and is useful
-% in case the polynomial function ends up nested
-% in some non-polynomial user declared function
-% as the latter (and other things) tries to pre-expand
-% its arguments (as they may be used multiple time)
-% using \expanded, but \#1 is protected.
-% And this works recursively. We are inside braces.
-% However we have a very big problem with constant
-% polynomial functions. We have to handle them
-% in a special way.
- -`0\csname#1\expandafter\endcsname\expanded
-}%
-\catcode`~ 13
-\catcode`: 12
-
-
-%% Start defining some \protected ones here
-\protected\def\POL@empty{}%
-\newif\ifPOL@pol
-\protected\def\POL@polglobaltrue {\global\let\ifPOL@pol\iftrue}%
-\protected\def\POL@polglobalfalse{\global\let\ifPOL@pol\iffalse}%
-
-
-%% Patch xintexpr to authorize ' in names (0.5.1)
-%% Adapted 0.7.5 to follow-up on xintexpr 1.4 internal changes
-%% (much simpler than previous stuff...)
-%% This allows ' as a character in a polynomial name (not initial one)
-\def\POL@XINT_expr_scanfunc_b #1%
-{%
- \ifcat \relax#1\xint_dothis{\iffalse{\fi}(_#1}\fi
- \if (#1\xint_dothis{\iffalse{\fi}(`}\fi
- \if 1\ifcat a#10\fi
- \ifnum\xint_c_ix<1\string#1 0\fi
- \if @#10\fi
- \if _#10\fi
- \if '#10\fi
- 1%
- \xint_dothis{\iffalse{\fi}(_#1}\fi
- \xint_orthat {#1\XINT_expr_scanfunc_a}%
-}%
-
-
-%% Activate polexp's modified xintexpr (only during definitions
-%% of polynomials)
-\def\POL@hackxintexpr {%
- \let\POL@originalXINT_expr_scanfunc_b\XINT_expr_scanfunc_b
- \let\XINT_expr_scanfunc_b\POL@XINT_expr_scanfunc_b
- \def\POL@activateNEhook{\POL@activateNEhook@pol}%
-}%
-\def\POL@restorexintexpr {%
- \let\XINT_expr_scanfunc_b\POL@originalXINT_expr_scanfunc_b
- \def\POL@activateNEhook{\POL@activateNEhook@xint}%
-}%
-
-
-%% AUXILIARIES
-\catcode`! 3
-%% added at 0.7
-\newcommand\polexprsetup[1]{\POL@setup_parsekeys #1,=!,\xint_bye}%
-\def\POL@setup_parsekeys #1=#2#3,{%
- \ifx!#2\expandafter\xint_bye\fi
- \csname POL@setup_setkey_\xint_zapspaces #1 \xint_gobble_i\endcsname
- \xint_firstoftwo
- {\PackageWarning{polexpr}{The \detokenize{#1} key is unknown! ignoring}}%
- {\xintZapLastSpaces{#2#3}}%
- \POL@setup_parsekeys
-}%
-\catcode`! 11
-\def\POL@setup_setkey_norr #1#2{\edef\POL@norr}%
-\def\POL@setup_setkey_sqfnorr #1#2{\edef\POL@sqfnorr}%
-\polexprsetup{norr=_norr, sqfnorr=_sqf_norr}
-
-\newcount\POL@count
-\newif\ifxintveryverbose
-\newif\ifpoltypesetall
-\newif\ifPOL@tosturm@makefirstprimitive
-\POL@tosturm@makefirstprimitivetrue
-\newif\ifPOL@isolz@nextwillneedrefine
-\newif\ifpoltoexprall
-%% the main exchange structure (stored in macros \POLuserpol@<name>)
-%% is: degree.\POL@empty{coeff0}{coeff1}....{coeffN}
-%% (degree=N except zero polynomial recognized from degree set to -1
-%% but it has always the {0/1[0]} coeff0.)
-\def\POL@ifZero#1{\expandafter\POL@ifZero@aux#1;}%
-\def\POL@ifZero@aux #1#2;{\if-#1\expandafter\xint_firstoftwo
- \else\expandafter\xint_secondoftwo
- \fi}%
-\def\POL@split#1.#2;#3#4% separates degree and list of coefficients
-% The \expandafter chain removes the \empty token
- {\def#3{#1}\expandafter\def\expandafter#4\expandafter{#2}}%
-%
-\def\POL@resultfromarray #1{% ATTENTION, **MUST** be executed with
-% \count@ set to 1 + degree (\count@ = 0 for zero polynomial)
-% Attention to the \protected here at 0.7.5
-% They are many all over the place
- \protected\edef\POL@result{\ifnum\count@>\z@
- \the\numexpr\count@-\@ne.\POL@empty
- \xintiloop [1+1]%
- \expandafter\POL@braceit\csname POL@array#1\xintiloopindex\endcsname
- \ifnum\xintiloopindex<\count@
- \repeat
-% Attention to this \protected\POL@empty
-% They are many all over the place
- \else-1.\POL@empty{0/1[0]}\fi}%
-}%
-\def\POL@braceit#1{{#1}}% needed as \xintiloopindex can not "see" through braces
-
-
-\newcommand\PolDef[3][x]{\poldef #2(#1):=#3;}%
-\def\poldef{\edef\POL@restoresemicolon{\catcode59=\the\catcode59\relax}%
- \catcode59 12 \POL@defpol}%
-\def\POL@defpol #1(#2)#3=#4;{%
- \POL@restoresemicolon
- \edef\POL@tmp{\ifxintverbose1\else0\fi}%
- \unless\ifxintveryverbose\xintverbosefalse\fi
- \POL@hackxintexpr
- \xintdeffunc __pol(#2):=0+(#4);% force conversion to raw if a constant
- \POL@restorexintexpr
- \if1\POL@tmp\xintverbosetrue\fi
- \edef\POL@polname{\xint_zapspaces #1 \xint_gobble_i}%
- \begingroup
- \setbox0\hbox{%
- \let\xintScalarAdd\xintAdd
- \let\xintScalarSub\xintSub
- \let\xintScalarMul\xintMul
- \let\xintScalarDiv\xintDiv
- \let\xintScalarPow\xintPow
- \let\xintScalarOpp\xintOpp
- \let\xintAdd\POL@add
- \let\xintMul\POL@mul
- \let\xintDiv\POL@div
- \let\xintPow\POL@pow
- \let\xintOpp\POL@opp
- \def\xintSub ##1##2{\xintAdd{##1}{\xintOpp{##2}}}%
- % \xintAdd{0} to get \POL@result defined even if numerical only expression
- % I could also test \ifPOL@pol, but this is anyhow small overhead
-% Attention that xintexpr 1.4 has braces all over the place
- \expandafter\xintAdd\expandafter{\expandafter0\expandafter}%
- \romannumeral0\csname XINT_expr_userfunc___pol\endcsname
- {\POL@polglobaltrue\protected\def\POL@result{1.\POL@empty{0/1[0]}{1/1[0]}}}%
- \expandafter}\expandafter
- \endgroup\expandafter
- \def\csname POLuserpol@\POL@polname\expandafter\endcsname
- \expandafter{\POL@result}%
- \expandafter\POL@newpol\expandafter{\POL@polname}%
-}%
-%
-
-
-\def\POL@newpol#1{%
-%% We must handle specially constant polynomials because they must
-%% be made to work expandably in \poldef of other polynomials due
-%% to complicated matters having to do with the \POL@ifpol conditional
- \ifnum\PolDegree{#1}<\@ne
- % non-zero constant
- % I am defining this one only for the Info message, no time now
- \expandafter\edef\csname XINT_expr_polfunc_#1\endcsname
- ##1{\PolNthCoeff{#1}{0}}%
- % No hooks here!
- \expandafter\edef\csname XINT_expr_func_#1\endcsname ##1##2##3%
- {##1##2{{\PolNthCoeff{#1}{0}}}}%
- \else
- % polynomial of degree at least 1. This means that mechanism
- % to get \POL@result will get activated and we must be very careful
- % to never \edef when the Horner macro will be converted to
- % a polynomial
- \POL@newpolhorner{#1}%
- \POL@defpolfunc{#1}{expr}%
- \fi
- \expandafter\let\csname XINT_flexpr_func_#1\endcsname\@undefined
- \ifxintverbose\POL@info{#1}\fi
-}%
-\def\POL@newfloatpol#1{%
-%% We must handle specially constant polynomials because they must
-%% be made to work expandably in \poldef of other polynomials due
-%% to complicated matters having to do with the \POL@ifpol conditional
- \ifnum\PolDegree{#1}<\@ne
- % non-zero constant
- % I am defining this one only for the Info message, no time now
- \expandafter\edef\csname XINT_flexpr_polfunc_#1\endcsname
- ##1{\PolNthCoeff{#1}{0}}%
- % No hooks here!
- \expandafter\edef\csname XINT_flexpr_func_#1\endcsname ##1##2##3%
- {##1##2{{\PolNthCoeff{#1}{0}}}}%
- \else
- % polynomial of degree at least 1. This means that mechanism
- % to get \POL@result will get activated and we must be very careful
- % to never \edef when the Horner macro will be converted to
- % a polynomial
- \POL@newfloatpolhorner{#1}%
- \POL@defpolfunc{#1}{flexpr}%
- \fi
- \ifxintverbose\POL@floatinfo{#1}\fi
-}%
-\def\POL@info #1{%
- \xintMessage {polexpr}{Info}%
- {Function #1 for the \string\xintexpr\space parser is
- associated to \string\XINT_expr_polfunc_#1\space
- whose meaning uses Horner scheme:
- \expandafter\meaning
- \csname XINT_expr_polfunc_#1\endcsname}%
-}%
-\def\POL@floatinfo #1{%
- \xintMessage {polexpr}{Info}%
- {Function #1 for the \string\xintfloatexpr\space parser is
- associated to \string\XINT_flexpr_polfunc_#1\space
- whose meaning uses Horner scheme:
- \expandafter\meaning
- \csname XINT_flexpr_polfunc_#1\endcsname}%
-}%
-%
-\def\POL@newpolhorner#1{%
- %% redefine function to expand by Horner scheme. Is this useful?
- %% perhaps bad idea for numerical evaluation of thing such as (1+x)^10?
-% note: I added {0/1[0]} item to zero polynomial also to facilitate this
- \expandafter\expandafter\expandafter\POL@split
- \csname POLuserpol@#1\endcsname;\POL@var@deg\POL@var@coeffs
- \edef\POL@var@coeffs{\xintRevWithBraces{\POL@var@coeffs}}%
- \begingroup
- \expandafter\POL@newpol@horner\POL@var@coeffs\relax
- \expandafter
- \endgroup
- \expandafter\def\csname XINT_expr_polfunc_#1\expandafter\endcsname
- \expandafter##\expandafter1\expandafter{\POL@tmp{##1}}%
-}%
-\def\POL@newfloatpolhorner#1{%
- %% redefine function to expand by Horner scheme. Is this useful?
- %% perhaps bad idea for numerical evaluation of thing such as (1+x)^10?
-% note: I added {0/1[0]} item to zero polynomial also to facilitate this
- \expandafter\expandafter\expandafter\POL@split
- \csname POLuserpol@#1\endcsname;\POL@var@deg\POL@var@coeffs
- \edef\POL@var@coeffs{\xintRevWithBraces{\POL@var@coeffs}}%
- \begingroup
- \expandafter\POL@newpol@floathorner\POL@var@coeffs\relax
- \expandafter
- \endgroup
- \expandafter\def\csname XINT_flexpr_polfunc_#1\expandafter\endcsname
- \expandafter##\expandafter1\expandafter{\POL@tmp{##1}}%
-}%
-\def\POL@newpol@horner#1{\let\xintAdd\relax\let\xintMul\relax
- \def\POL@tmp##1{#1}\POL@newpol@horner@loop.}%
-\def\POL@newpol@horner@loop.#1{%
- \if\relax#1\expandafter\xint_gob_til_dot\fi
- \edef\POL@tmp##1{\xintiiifZero{#1}
- {\@firstofone}{\xintAdd{#1}}%
- {\xintMul{##1}{\POL@tmp{##1}}}}%
- \POL@newpol@horner@loop.%
-}%
-\def\POL@newpol@floathorner#1{\let\XINTinFloatAdd\relax\let\XINTinFloatMul\relax
- \def\xintAdd{\XINTinFloatAdd}\def\xintMul{\XINTinFloatMul}%
- \edef\POL@tmp##1{\XINTinFloatdigits{#1}}%
- \POL@newpol@floathorner@loop.}%
-\def\POL@newpol@floathorner@loop.#1{%
- \if\relax#1\expandafter\xint_gob_til_dot\fi
- \edef\POL@tmp##1{\xintiiifZero{#1}
- {\@firstofone}{\xintAdd{\XINTinFloatdigits{#1}}}%
- {\xintMul{##1}{\POL@tmp{##1}}}}%
- \POL@newpol@floathorner@loop.%
-}%
-
-
-\newcommand\PolGenFloatVariant[1]{\POL@newfloatpol{#1}}%
-
-
-\newcommand\PolLet[2]{\if=\noexpand#2\expandafter\xint_firstoftwo
- \else\expandafter\xint_secondoftwo\fi
- \POL@@let\POL@let{#1}{#2}}%
-\def\POL@@let#1#2#3{\POL@let{#1}{#3}}%
-\def\POL@let#1#2{%
- \expandafter\let\csname POLuserpol@#1\expandafter\endcsname
- \csname POLuserpol@#2\endcsname
- \expandafter\let\csname XINT_expr_polfunc_#1\expandafter\endcsname
- \csname XINT_expr_polfunc_#2\endcsname
- \POL@defpolfunc{#1}{expr}%
- \ifxintverbose\POL@info{#1}\fi
-}%
-\newcommand\PolGlobalLet[2]{\begingroup
- \globaldefs\@ne
- \if=\noexpand#2\expandafter\xint_firstoftwo
- \else\expandafter\xint_secondoftwo\fi
-% do I need to check something here relative to \xintNewExpr?
- \POL@@globallet\POL@globallet {#1}{#2}}%
-\def\POL@@globallet#1#2#3{\POL@globallet{#1}{#3}}%
-\def\POL@globallet#1#2{\POL@let{#1}{#2}\endgroup}%
-
-\newcommand\PolAssign[1]{\def\POL@polname{#1}\POL@assign}% zap spaces in #1?
-\def\POL@assign#1\toarray#2{%
- \expandafter\expandafter\expandafter\POL@split
- \csname POLuserpol@\POL@polname\endcsname;\POL@var@deg\POL@var@coeffs
- \xintAssignArray\POL@var@coeffs\to#2%
- % modify \#200 macro to return 0/1[0] for out of range indices
- \@namedef{\xint_arrayname00}##1##2##3{%
- \@namedef{\xint_arrayname00}####1{%
- \ifnum####1>##1 \xint_dothis{ 0/1[0]}\fi
- \ifnum####1>\m@ne \xint_dothis
- {\expandafter\expandafter\expandafter##3%
- \csname##2####1\endcsname}\fi
- \unless\ifnum-####1>##1 \xint_dothis
- {\expandafter\expandafter\expandafter##3%
- \csname##2\the\numexpr##1+####1+\@ne\endcsname}\fi
- \xint_orthat{ 0/1[0]}}% space stops a \romannumeral0
- }%
- \csname\xint_arrayname00\expandafter\expandafter\expandafter\endcsname
- \expandafter\expandafter\expandafter
- {\csname\xint_arrayname0\expandafter\endcsname\expandafter}\expandafter
- {\xint_arrayname}{ }%
-}%
-
-
-\newcommand\PolGet{}%
-\def\PolGet#1#2\fromarray#3{%
- \begingroup % closed in \POL@getfromarray
- \POL@getfromarray{#1}{#3}%
- \POL@newpol{#1}%
-}%
-\def\POL@getfromarray#1#2{%
- \count@=#2{0} %<- intentional space
- \ifnum\count@=\z@
- \protected\def\POL@result{-1.\POL@empty{0/1[0]}}% 0.5 fix for empty array
- \else
- \xintloop
- \edef\POL@tmp{#2{\count@}}%
- \edef\POL@tmp{\xintRaw{\POL@tmp}}%
-% sadly xinttools (current 1.3a) arrays have no setters for individual items...
- \expandafter\let\csname POL@tmparray\the\count@\endcsname\POL@tmp
- \if0\xintiiSgn{\POL@tmp}%
- \advance\count@\m@ne
- \repeat
-% dans le cas particulier d'un array avec que des éléments nuls, \count@ est
-% ici devenu 0 et la boucle s'est arrêtée car #2{0} était au moins 1. De plus
-% \POL@tmparray1 est bien 0/1[0] donc ok pour polynôme nul dans \POL@result
- \count\tw@\count@
- \xintloop
-% on mouline tous les coeffs via \xintRaw
- \ifnum\count@>\@ne
- \advance\count@\m@ne
- \edef\POL@tmp{#2{\count@}}%
- \edef\POL@tmp{\xintRaw{\POL@tmp}}%
- \expandafter\let\csname POL@tmparray\the\count@\endcsname\POL@tmp
- \repeat
- \count@\count\tw@
- \def\POL@tmp##1.{{\csname POL@tmparray##1\endcsname}}%
- \protected\edef\POL@result{\the\numexpr\count@-\@ne.\POL@empty
- \xintiloop[1+1]%
- \expandafter\POL@tmp\xintiloopindex.%
- \ifnum\xintiloopindex<\count@
- \repeat}%
- \fi
- \expandafter
- \endgroup
- \expandafter
- \def\csname POLuserpol@#1\expandafter\endcsname
- \expandafter{\POL@result}%
-}%
-
-
-\newcommand\PolFromCSV[2]{%
- \begingroup % closed in \POL@getfromarray
- \xintAssignArray\xintCSVtoList{#2}\to\POL@arrayA
- \POL@getfromarray{#1}\POL@arrayA
- \POL@newpol{#1}%
-% semble un peu indirect et sous-optimal
-% mais je veux élaguer les coefficients nuls. Peut-être à revoir.
-}%
-
-
-\newcommand\PolTypesetCmdPrefix[1]{\xintiiifSgn{#1}{}{+}{+}}%
-\newcommand\PolTypesetCmd[1]{\xintifOne{\xintiiAbs{#1}}%
- {\ifnum\PolIndex=\z@\xintiiSgn{#1}\else
- \xintiiifSgn{#1}{-}{}{}\fi
- \let\PolIfCoeffIsPlusOrMinusOne\@firstoftwo}%
- {\PolTypesetOne{#1}%
- \let\PolIfCoeffIsPlusOrMinusOne\@secondoftwo}%
- }%
-\newcommand\PolTypesetOne{\xintSignedFrac}%
-\newcommand\PolTypesetMonomialCmd{%
- \ifcase\PolIndex\space
- %
- \or\PolVar
- \else\PolVar^{\PolIndex}%
- \fi
-}%
-\newcommand\PolTypeset{\@ifstar
- {\def\POL@ts@ascending{1}\POL@Typeset}%
- {\def\POL@ts@ascending{0}\POL@Typeset}%
-}%
-\newcommand\POL@Typeset[2][x]{% LaTeX \newcommand forces optional argument first
- \ensuremath{%
- \expandafter\expandafter\expandafter\POL@split
- \csname POLuserpol@#2\endcsname;\POL@var@deg\POL@var@coeffs
- \if\POL@ts@ascending1%
- \def\PolIndex{0}%
- \let\POL@ts@reverse\@firstofone
- \let\POL@@ne@or@m@ne\@ne
- \else
- \let\PolIndex\POL@var@deg
- \ifnum\PolIndex<\z@\def\PolIndex{0}\fi
- \let\POL@ts@reverse\xintRevWithBraces
- \let\POL@@ne@or@m@ne\m@ne
- \fi
- \def\PolVar{#1}%
- \ifnum\POL@var@deg<\z@
- \PolTypesetCmd{0/1[0]}\PolTypesetMonomialCmd
- \else
- \ifnum\POL@var@deg=\z@
- \expandafter\PolTypesetCmd\POL@var@coeffs\PolTypesetMonomialCmd
- \else
- \def\POL@ts@prefix##1{\let\POL@ts@prefix\PolTypesetCmdPrefix}%
- \expandafter\POL@ts@loop
- \romannumeral-`0\POL@ts@reverse{\POL@var@coeffs}\relax
- \fi
- \fi
- }%
-}%
-\def\POL@ts@loop{\ifpoltypesetall\expandafter\xint_firstoftwo
- \else\expandafter\xint_secondoftwo\fi
- {\POL@ts@nocheck}{\POL@ts@check}.%
-}%
-\def\POL@ts@check.#1{%
- \if\relax#1\expandafter\xint_gob_til_dot\fi
- \xintiiifZero{#1}%
- {}%
- {\POL@ts@prefix{#1}\PolTypesetCmd{#1}\PolTypesetMonomialCmd}%
- \edef\PolIndex{\the\numexpr\PolIndex+\POL@@ne@or@m@ne}\POL@ts@check.%
-}%
-\def\POL@ts@nocheck.#1{%
- \if\relax#1\expandafter\xint_gob_til_dot\fi
- \POL@ts@prefix{#1}\PolTypesetCmd{#1}\PolTypesetMonomialCmd
- \edef\PolIndex{\the\numexpr\PolIndex+\POL@@ne@or@m@ne}\POL@ts@nocheck.%
-}%
-
-
-\newcommand\PolMapCoeffs[2]{% #1 = macro, #2 = name
- \POL@mapcoeffs{#1}{#2}%
- \POL@newpol{#2}%
-}%
-\def\POL@mapcoeffs#1#2{%
- \begingroup
- \def\POL@mapcoeffs@macro{#1}%
- \expandafter\expandafter\expandafter\POL@split
- \csname POLuserpol@#2\endcsname;\POL@mapcoeffs@deg\POL@mapcoeffs@coeffs
-% ATTENTION à ne pas faire un \expandafter ici, car brace removal si 1 item
- \xintAssignArray\POL@mapcoeffs@coeffs\to\POL@arrayA
- \def\index{0}%
- \count@\z@
- \expandafter\POL@map@loop\expandafter.\POL@mapcoeffs@coeffs\relax
- \xintloop
-% this abuses that \POL@arrayA0 is never 0.
- \xintiiifZero{\csname POL@arrayA\the\count@\endcsname}%
- {\iftrue}%
- {\iffalse}%
- \advance\count@\m@ne
- \repeat
-% donc en sortie \count@ est 0 ssi pol nul.
- \POL@resultfromarray A%
- \expandafter
- \endgroup
- \expandafter
- \def\csname POLuserpol@#2\expandafter\endcsname\expandafter{\POL@result}%
-}%
-\def\POL@map@loop.#1{\if\relax#1\expandafter\xint_gob_til_dot\fi
- \advance\count@\@ne
- \edef\POL@map@coeff{\POL@mapcoeffs@macro{#1}}%
- \expandafter
- \let\csname POL@arrayA\the\count@\endcsname\POL@map@coeff
- \edef\index{\the\numexpr\index+\@ne}%
- \POL@map@loop.}%
-\def\POL@xintIrr#1{\xintIrr{#1}[0]}%
-\newcommand\PolReduceCoeffs{\@ifstar\POL@sreducecoeffs\POL@reducecoeffs}%
-\def\POL@reducecoeffs#1{\PolMapCoeffs{\POL@xintIrr}{#1}}%
-\def\POL@sreducecoeffs#1{\PolMapCoeffs{\xintPIrr}{#1}}%
-
-
-%% EUCLIDEAN DIVISION
-\newcommand\PolDivide[4]{% #3=quotient, #4=remainder of #1 by #2
- \POL@divide{#1}{#2}%
- \expandafter\let\csname POLuserpol@#3\endcsname\POL@Q
- \POL@newpol{#3}%
- \expandafter\let\csname POLuserpol@#4\endcsname\POL@R
- \POL@newpol{#4}%
-}%
-\newcommand\PolQuo[3]{% #3=quotient of #1 by #2
- \POL@divide{#1}{#2}%
- \expandafter\let\csname POLuserpol@#3\endcsname\POL@Q
- \POL@newpol{#3}%
-}%
-\newcommand\PolRem[3]{% #3=remainder of #1 by #2
- \POL@divide{#1}{#2}%
- \expandafter\let\csname POLuserpol@#3\endcsname\POL@R
- \POL@newpol{#3}%
-}%
-\newcommand\POL@divide[2]{%
- \begingroup
- \let\xintScalarSub\xintSub
- \let\xintScalarAdd\xintAdd
- \let\xintScalarMul\xintMul
- \let\xintScalarDiv\xintDiv
- \expandafter\let\expandafter\POL@A\csname POLuserpol@#1\endcsname
- \expandafter\let\expandafter\POL@B\csname POLuserpol@#2\endcsname
- \POL@div@c
- \let\POL@Q\POL@result
- \ifnum\POL@degQ<\z@
- \let\POL@R\POL@A
- \else
- \count@\numexpr\POL@degR+\@ne\relax
- \POL@resultfromarray R%
- \let\POL@R\POL@result
- \fi
- \expandafter
- \endgroup
- \expandafter
- \def\csname POL@Q\expandafter\expandafter\expandafter\endcsname
- \expandafter\expandafter\expandafter{\expandafter\POL@Q\expandafter}%
- \expandafter
- \def\csname POL@R\expandafter\endcsname\expandafter{\POL@R}%
-}%
-
-
-%% GCD
-\newcommand\PolGCD[3]{% sets #3 to the (unitary) G.C.D. of #1 and #2
- \POL@GCD{#1}{#2}{#3}%
- \POL@newpol{#3}%
-}%
-\def\POL@GCD #1#2#3{%
- \begingroup
- \let\xintScalarSub\xintSub
- \let\xintScalarAdd\xintAdd
- \let\xintScalarMul\xintMul
- \let\xintScalarDiv\xintDiv
- \expandafter\let\expandafter\POL@A\csname POLuserpol@#1\endcsname
- \expandafter\let\expandafter\POL@B\csname POLuserpol@#2\endcsname
- \expandafter\POL@split\POL@A;\POL@degA\POL@polA
- \expandafter\POL@split\POL@B;\POL@degB\POL@polB
- \ifnum\POL@degA<\z@
- \expandafter\xint_firstoftwo\else\expandafter\xint_secondoftwo
- \fi
- {\ifnum\POL@degB<\z@
- \expandafter\xint_firstoftwo\else\expandafter\xint_secondoftwo
- \fi
- {\protected\def\POL@result{-1.\POL@empty{0/1[0]}}}%
- {\xintAssignArray\POL@polB\to\POL@arrayB
- \POL@normalize{B}%
- \POL@gcd@exit BA}}%
- {\ifnum\POL@degB<\z@
- \expandafter\xint_firstoftwo\else\expandafter\xint_secondoftwo
- \fi
- {\xintAssignArray\POL@polA\to\POL@arrayA
- \POL@normalize{A}%
- \POL@gcd@exit AB}%
- {\ifnum\POL@degA<\POL@degB\space
- \let\POL@tmp\POL@B\let\POL@B\POL@A\let\POL@A\POL@tmp
- \let\POL@tmp\POL@degB\let\POL@degB\POL@degA\let\POL@degA\POL@tmp
- \let\POL@tmp\POL@polB\let\POL@polB\POL@polA\let\POL@polA\POL@tmp
- \fi
- \xintAssignArray\POL@polA\to\POL@arrayA
- \xintAssignArray\POL@polB\to\POL@arrayB
- \POL@gcd AB%
- }}%
- \expandafter
- \endgroup
- \expandafter\def\csname POLuserpol@#3\expandafter\endcsname
- \expandafter{\POL@result}%
-}%
-\def\POL@normalize#1{%
- \expandafter\def\expandafter\POL@tmp\expandafter
- {\csname POL@array#1\csname POL@array#10\endcsname\endcsname}%
- \edef\POL@normalize@leading{\POL@tmp}%
- \expandafter\def\POL@tmp{1/1[0]}%
- \count@\csname POL@deg#1\endcsname\space
- \xintloop
- \ifnum\count@>\z@
- \expandafter\edef\csname POL@array#1\the\count@\endcsname
- {\xintIrr{\xintScalarDiv
- {\csname POL@array#1\the\count@\endcsname}%
- {\POL@normalize@leading}}[0]}%
- \advance\count@\m@ne
- \repeat
-}%
-\def\POL@gcd#1#2{%
- \POL@normalize{#2}%
- \edef\POL@degQ{\the\numexpr\csname POL@deg#1\endcsname
- -\csname POL@deg#2\endcsname}%
- \count@\numexpr\csname POL@deg#1\endcsname+\@ne\relax
- \count\tw@\numexpr\POL@degQ+\@ne\relax
- \xintloop
- \POL@gcd@getremainder@loopbody#1#2%
- \ifnum\count\tw@>\z@
- \repeat
- \expandafter\def\csname POL@array#10\endcsname{1}%
- \xintloop
- \xintiiifZero{\csname POL@array#1\the\count@\endcsname}%
- {\iftrue}%
- {\iffalse}%
- \advance\count@\m@ne
- \repeat
- \expandafter\edef\csname POL@deg#1\endcsname{\the\numexpr\count@-\@ne}%
- \ifnum\count@<\@ne
- \expandafter\POL@gcd@exit
- \else
- \expandafter\edef\csname POL@array#10\endcsname{\the\count@}%
- \expandafter\POL@gcd
- \fi{#2}{#1}%
-}%
-\def\POL@gcd@getremainder@loopbody#1#2{%
- \edef\POL@gcd@ratio{\csname POL@array#1\the\count@\endcsname}%
- \advance\count@\m@ne
- \advance\count\tw@\m@ne
- \count4 \count@
- \count6 \csname POL@deg#2\endcsname\space
- \xintloop
- \ifnum\count6>\z@
- \expandafter\edef\csname POL@array#1\the\count4\endcsname
- {\xintScalarSub
- {\csname POL@array#1\the\count4\endcsname}%
- {\xintScalarMul
- {\POL@gcd@ratio}%
- {\csname POL@array#2\the\count6\endcsname}}}%
- \advance\count4 \m@ne
- \advance\count6 \m@ne
- \repeat
-}%
-\def\POL@gcd@exit#1#2{%
- \count@\numexpr\csname POL@deg#1\endcsname+\@ne\relax
- \POL@resultfromarray #1%
-}%
-
-
-%% TODO: BEZOUT
-
-
-%% DIFFERENTIATION
-\def\POL@diff@loop@one #1/#2[#3]#4%
- {\xintIrr{\xintiiMul{#4}{#1}/#2[0]}[#3]}%
-\def\POL@diff#1{\POL@diff@loop1.}%
-\def\POL@diff@loop#1.#2{%
- \if\relax#2\expandafter\xint_gob_til_dot\fi
- {\expandafter\POL@diff@loop@one\romannumeral0\xintraw{#2}{#1}}%
- \expandafter\POL@diff@loop\the\numexpr#1+\@ne.%
-}%
-\newcommand\PolDiff[1][1]{%
- % optional parameter is how many times to derivate
- % first mandatory arg is name of polynomial function to derivate,
- % same name as in \NewPolExpr
- % second mandatory arg name of derivative
- \edef\POL@iterindex{\the\numexpr#1\relax}%
- \ifnum\POL@iterindex<\z@
- \expandafter\@firstoftwo
- \else
- \expandafter\@secondoftwo
- \fi
- {\PolAntiDiff[-\POL@iterindex]}{\POL@Diff}%
-}%
-\def\POL@Diff{%
- \ifcase\POL@iterindex\space
- \expandafter\POL@Diff@no
- \or\expandafter\POL@Diff@one
- \else\xint_afterfi{\POL@Iterate\POL@Diff@one}%
- \fi
-}%
-\def\POL@Diff@no #1#2{\POL@let{#2}{#1}}%
-\def\POL@Diff@one #1#2{\POL@Diff@@one {#1}{#2}\POL@newpol{#2}}%
-\def\POL@Diff@@one#1#2{%
- \expandafter\expandafter\expandafter\POL@split
- \csname POLuserpol@#1\endcsname;\POL@var@deg\POL@var@coeffs
- \ifnum\POL@var@deg<\@ne
- \@namedef{POLuserpol@#2}{-1.\POL@empty{0/1[0]}}%
- \else
- \edef\POL@var@coeffs{\expandafter\POL@diff\POL@var@coeffs\relax}%
- \expandafter\edef\csname POLuserpol@#2\endcsname
- {\the\numexpr\POL@var@deg-\@ne.\POL@empty\POL@var@coeffs}%
- \fi
-}%
-% lazy way but allows to share with AntiDiff
-\def\POL@Iterate#1#2#3{%
- \begingroup
- \xintverbosefalse
- #1{#2}{#3}%
- \xintloop
- \ifnum\POL@iterindex>\tw@
- #1{#3}{#3}%
- \edef\POL@iterindex{\the\numexpr\POL@iterindex-\@ne}%
- \repeat
- \expandafter
- \endgroup\expandafter
- \def\csname POLuserpol@#3\expandafter\endcsname
- \expandafter{\romannumeral`^^@\csname POLuserpol@#3\endcsname}%
- #1{#3}{#3}%
-}%
-
-
-%% ANTI-DIFFERENTIATION
-\def\POL@antidiff@loop@one #1/#2[#3]#4%
- {\xintIrr{#1/\xintiiMul{#4}{#2}[0]}[#3]}%
-\def\POL@antidiff{\POL@antidiff@loop1.}%
-\def\POL@antidiff@loop#1.#2{%
- \if\relax#2\expandafter\xint_gob_til_dot\fi
- {\expandafter\POL@antidiff@loop@one\romannumeral0\xintraw{#2}{#1}}%
- \expandafter\POL@antidiff@loop\the\numexpr#1+\@ne.%
-}%
-\newcommand\PolAntiDiff[1][1]{%
- % optional parameter is how many times to derivate
- % first mandatory arg is name of polynomial function to derivate,
- % same name as in \NewPolExpr
- % second mandatory arg name of derivative
- \edef\POL@iterindex{\the\numexpr#1\relax}%
- \ifnum\POL@iterindex<\z@
- \expandafter\@firstoftwo
- \else
- \expandafter\@secondoftwo
- \fi
- {\PolDiff[-\POL@iterindex]}{\POL@AntiDiff}%
-}%
-\def\POL@AntiDiff{%
- \ifcase\POL@iterindex\space
- \expandafter\POL@AntiDiff@no
- \or\expandafter\POL@AntiDiff@one
- \else\xint_afterfi{\POL@Iterate\POL@AntiDiff@one}%
- \fi
-}%
-\let\POL@AntiDiff@no\POL@Diff@no
-\def\POL@AntiDiff@one #1#2{\POL@AntiDiff@@one{#1}{#2}\POL@newpol{#2}}%
-\def\POL@AntiDiff@@one#1#2{%
- \expandafter\expandafter\expandafter\POL@split
- \csname POLuserpol@#1\endcsname;\POL@var@deg\POL@var@coeffs
- \ifnum\POL@var@deg<\z@
- \@namedef{POLuserpol@#2}{-1.\POL@empty{0/1[0]}}%
- \else
- \edef\POL@var@coeffs{\expandafter\POL@antidiff\POL@var@coeffs\relax}%
- \expandafter\edef\csname POLuserpol@#2\endcsname
- {\the\numexpr\POL@var@deg+\@ne.\POL@empty{0/1[0]}\POL@var@coeffs}%
- \fi
-}%
-
-%% IContent and \PolMakePrimitive (0.5)
-\def\POL@aux@mgcd@loop#1#2{%
- \if\relax#2\expandafter\POL@aux@mgcd@exit\fi
- \expandafter
- \POL@aux@mgcd@loop\romannumeral0\POL@aux@gcd#1.#2.%
-}%
-\def\POL@aux@mgcd@exit
- \expandafter
- \POL@aux@mgcd@loop\romannumeral0\POL@aux@gcd#1.\relax.{\xintiiabs{#1}}%
-\def\POL@aux@gcd#1.#2.{%
- \if0\xintiiSgn{#1}\expandafter\POL@aux@gcd@exit\fi
- \expandafter\POL@aux@gcd\romannumeral0\xintmod {#2}{#1}.#1.}%
-\def\POL@aux@gcd@exit
- \expandafter\POL@aux@gcd\romannumeral0\xintmod #1#2.#3.{{#1}}%
-
-\def\POL@icontent #1{\romannumeral0\expandafter
- \POL@aux@mgcd@loop\romannumeral`^^@#1\relax}%
-
-\newcommand\PolIContent[1]{\romannumeral0\expandafter
- \POL@aux@mgcd@loop\romannumeral`^^@\PolToList{#1}\relax}%
-
-
-\def\POL@makeprim@macro#1%
- {\xintREZ{\xintNum{\xintDiv{#1}{\POL@makeprim@icontent}}}}%
-\newcommand\PolMakePrimitive[1]{%
- % This does not need a full user declared polynomial on input, only
- % a \POLuserpol@name macro, but on output it is fully declared
- \edef\POL@makeprim@icontent{\PolIContent{#1}}%
- \PolMapCoeffs\POL@makeprim@macro{#1}%
-}%
-\def\POL@makeprimitive#1{%
- % Avoids declaring the polynomial, internal usage in \PolToSturm
- \edef\POL@makeprim@icontent{\PolIContent{#1}}%
- \POL@mapcoeffs\POL@makeprim@macro{#1}%
-}%
-
-
+%% This file polexprsturm.tex is part of the polexpr package (0.8, 2021/03/29)
%% Sturm Algorithm (polexpr 0.4)
%% 0.5 uses primitive polynomials for faster evaluations afterwards
%% 0.6 corrects misuse of \@ifstar! (mumble). \PolToSturm* was broken.
@@ -898,7 +9,16 @@
%% holding the coefficients in memory
%% 0.6 fixes the case of a constant polynomial P which caused division
%% by zero error from P'.
-\newcommand\PolToSturm{\@ifstar{\PolToSturm@@}{\PolToSturm@}}%
+%% 0.8 - fixes 0.7.5 failure to have updated to xint 1.4 format the defined
+%% \xintexpr variables holding the localization intervals extremities
+%% - also, it uses the prem() in computing the Sturm chain, for a 3X
+%% speed gain in the case of the "perturbed" first Wilkinson example
+%%
+\newcount\POL@count
+\newif\ifPOL@tosturm@makefirstprimitive\POL@tosturm@makefirstprimitivetrue
+\newif\ifPOL@isolz@nextwillneedrefine
+%%
+\def\PolToSturm{\POL@ifstar{\PolToSturm@@}{\PolToSturm@}}%
\def\POL@aux@toint#1{\xintREZ{\xintNum{#1}}}% for polynomials with int. coeffs!
%% Attention that some macros rely upon this one setting \POL@sturmname
%% and \POL@sturm@N as it does
@@ -914,7 +34,7 @@
\POL@count\z@
% if I applied the same as for positive degree, I should make it -1
% if constant is negative. I also don't worry if polynomial is zero.
- \@namedef{POLuserpol@\POL@sturmname _0}{0.\POL@empty{1/1[0]}}%
+ \XINT_global\@namedef{POLuserpol@\POL@sturmname _0}{0.\empty{1/1[0]}}%
\else
\ifPOL@tosturm@makefirstprimitive\POL@makeprimitive{\POL@sturmname _0_}\fi
\POL@tosturm@dosturm
@@ -945,12 +65,13 @@
\POL@makeprimitive{\POL@sturmname _1_}% does not do \POL@newpol
\POL@count\@ne
\xintloop
- \POL@divide{\POL@sturmname _\the\numexpr\POL@count-\@ne\relax _}%
- {\POL@sturmname _\the\POL@count _}%
+ % prior to 0.8, code was using here \POL@divide
+ \POL@getprem{\POL@sturmname _\the\numexpr\POL@count-\@ne\relax _}%
+ {\POL@sturmname _\the\POL@count _}%
\expandafter\POL@split\POL@R;\POL@degR\POL@polR
\unless\ifnum\POL@degR=\m@ne
\advance\POL@count\@ne
- \expandafter\let
+ \XINT_global\expandafter\let
\csname POLuserpol@\POL@sturmname _\the\POL@count _\endcsname\POL@R
\edef\POL@makeprim@icontent{-\POL@icontent\POL@polR}%
% this avoids the \POL@newpol from \PolMapCoeffs
@@ -964,18 +85,18 @@
\advance\POL@count\m@ne
\POL@divide{\POL@sturmname _\the\POL@count _}%
{\POL@sturmname _\POL@sturm@N _}%
- \expandafter
- \let\csname POLuserpol@\POL@sturmname _\the\POL@count\endcsname\POL@Q
+ \XINT_global\expandafter
+ \let\csname POLuserpol@\POL@sturmname _\the\POL@count\endcsname\POL@Q
% quotient actually belongs to Z[X] and is primitive
\POL@mapcoeffs\POL@aux@toint{\POL@sturmname _\the\POL@count}%
\ifnum\POL@count>\z@
\repeat
- \@namedef{POLuserpol@\POL@sturmname _\POL@sturm@N}{0.\POL@empty{1/1[0]}}%
+ \XINT_global\@namedef{POLuserpol@\POL@sturmname _\POL@sturm@N}{0.\empty{1/1[0]}}%
\else % they are already normalized
\advance\POL@count\@ne % attention to include last one also
\xintloop
\advance\POL@count\m@ne
- \expandafter\let
+ \XINT_global\expandafter\let
\csname POLuserpol@\POL@sturmname _\the\POL@count\expandafter\endcsname
\csname POLuserpol@\POL@sturmname _\the\POL@count _\endcsname
\ifnum\POL@count>\z@
@@ -983,10 +104,13 @@
\fi
% Back to \PolToSturm@, \POL@count holds 0
}%
-\newcommand\PolSturmChainLength[1]
- {\romannumeral`^^@\csname PolSturmChainLength_#1\endcsname}%
-
-\newcommand\PolSetToSturmChainSignChangesAt[4][\global]{%
+\def\PolSturmChainLength#1{%
+ \romannumeral`&&@\csname PolSturmChainLength_#1\endcsname
+}%
+\def\PolSetToSturmChainSignChangesAt{%
+ \POL@chkopt\POL@oPolSetToSturmChainSignChangesAt[\global]%
+}%
+\def\POL@oPolSetToSturmChainSignChangesAt[#1]#2#3#4{%
\edef\POL@sturmchain@X{\xintREZ{#4}}%
\edef\POL@sturmname{#3}%
\edef\POL@sturmlength{\PolSturmChainLength{\POL@sturmname}}%
@@ -1014,7 +138,10 @@
\fi
\repeat
}%
-\newcommand\PolSetToNbOfZerosWithin[5][\global]{%
+\def\PolSetToNbOfZerosWithin{%
+ \POL@chkopt\POL@oPolSetToNbOfZerosWithin[\global]%
+}%
+\def\POL@oPolSetToNbOfZerosWithin[#1]#2#3#4#5{%
\edef\POL@tmpA{\xintREZ{#4}}%
\edef\POL@tmpB{\xintREZ{#5}}%
\edef\POL@sturmname{#3}%
@@ -1029,23 +156,25 @@
#1\edef#2{\the\numexpr\POL@SVA-\POL@SVB}%
\fi
}%
-
-
% 0.6 added starred variant to count multiplicities
% 0.7 added double starred variant to locate all rational roots
-\newcommand\PolSturmIsolateZeros{\@ifstar
+\def\PolSturmIsolateZeros{\POL@ifstar
{\PolSturmIsolateZerosAndGetMultiplicities}%
{\PolSturmIsolateZeros@}%
}%
-\newcommand\PolSturmIsolateZerosAndGetMultiplicities{\@ifstar
+\def\PolSturmIsolateZerosAndGetMultiplicities{\POL@ifstar
{\PolSturmIsolateZerosGetMultiplicitiesAndRationalRoots}%
{\PolSturmIsolateZerosAndGetMultiplicities@}%
}%
% on aurait besoin de ça dans xint, mais il aurait un \xintRaw{#1} alors
\def\POL@xintfrac@getNDE #1%
- {\expandafter\POL@xintfrac@getNDE@i\romannumeral`^^@#1}%
+ {\expandafter\POL@xintfrac@getNDE@i\romannumeral`&&@#1}%
\def\POL@xintfrac@getNDE@i #1/#2[#3]#4#5#6{\def#4{#1}\def#5{#2}\def#6{#3}}%
-\newcommand\PolSturmIsolateZerosGetMultiplicitiesAndRationalRoots[2][\empty]{%
+%
+\def\PolSturmIsolateZerosGetMultiplicitiesAndRationalRoots{%
+ \POL@chkopt\POL@oPolSturmIsolateZerosGetMultiplicitiesAndRationalRoots[\empty]%
+}%
+\def\POL@oPolSturmIsolateZerosGetMultiplicitiesAndRationalRoots[#1]#2{%
\PolSturmIsolateZerosAndFindRationalRoots[#1]{#2}%
\ifnum\POL@isolz@NbOfRoots>\z@
% get multiplicities of irrational (real) roots, if any
@@ -1056,7 +185,10 @@
\fi
}%
% added at 0.7
-\newcommand\PolSturmIsolateZerosAndFindRationalRoots[2][\empty]{%
+\def\PolSturmIsolateZerosAndFindRationalRoots{%
+ \POL@chkopt\POL@oPolSturmIsolateZerosAndFindRationalRoots[\empty]%
+}%
+\def\POL@oPolSturmIsolateZerosAndFindRationalRoots[#1]#2{%
% #1 optional E such that roots are searched in -10^E < x < 10^E
% both -10^E and +10^E must not be roots!
% #2 name of Sturm chain (already pre-computed)
@@ -1078,9 +210,11 @@
% on ne va pas utiliser de Horner, mais des divisions par X - x, et ces
% choses vont évoluer, ainsi que le coefficient dominant entier
% (pour \POL@divide entre autres if faut des noms de user pol)
+ \XINT_global
\expandafter\let
\csname POLuserpol@\POL@sturmname\POL@sqfnorr\expandafter\endcsname
\csname POLuserpol@\POL@sturmname _0\endcsname
+ \XINT_global
\expandafter\let
\csname POLuserpol@\POL@sturmname\POL@norr\expandafter\endcsname
\csname POLuserpol@\POL@sturmname _0_\endcsname
@@ -1161,7 +295,7 @@
\POL@findrat@xN\POL@findrat@xD\POl@_
% we can't move this to updatequotients because other branch will
% need to do the division first anyhow
- \edef\POLuserpol@_findrat@oneterm{1.\POL@empty
+ \edef\POLuserpol@_findrat@oneterm{1.\noexpand\empty
{\xintiiOpp\POL@findrat@xN/1[0]}{\POL@findrat@xD/1[0]}}%
\POL@divide{\POL@sturmname\POL@sqfnorr}{_findrat@oneterm}% the one without mult.
%\expandafter\POL@split\POL@R;\POL@degR\POL@polR
@@ -1295,7 +429,7 @@
% zero should never occur here
\POL@findrat@ifnegative{\edef\POL@findrat@x{-\POL@findrat@x}}{}%
\POL@xintfrac@getNDE\POL@findrat@x\POL@findrat@xN\POL@findrat@xD\POL@_
- \edef\POLuserpol@_findrat@oneterm{1.\POL@empty
+ \edef\POLuserpol@_findrat@oneterm{1.\noexpand\empty
{\xintiiOpp{\POL@findrat@xN}/1[0]}{\POL@findrat@xD/1[0]}}%
\POL@divide{\POL@sturmname\POL@sqfnorr}{_findrat@oneterm}% the one without mult.
\expandafter\POL@split\POL@R;\POL@degR\POL@polR
@@ -1362,7 +496,7 @@
% safer to do the edef as \POL@findrat@x used later in storeit
\edef\POL@findrat@x{\xintIrr{\xintDiv\POL@findrat@Num\POL@findrat@D}[0]}%
\POL@xintfrac@getNDE\POL@findrat@x\POL@findrat@xN\POL@findrat@xD\POL@_
- \edef\POLuserpol@_findrat@oneterm{1.\POL@empty
+ \edef\POLuserpol@_findrat@oneterm{1.\noexpand\empty
{\xintiiOpp{\POL@findrat@xN}/1[0]}{\POL@findrat@xD/1[0]}}%
\POL@divide{\POL@sturmname\POL@sqfnorr}{_findrat@oneterm}% the one without mult.
\expandafter\POL@split\POL@R;\POL@degR\POL@polR
@@ -1385,23 +519,24 @@
\let\csname POL_ZK\POL@sturmname*\POL@findrat@index\endcsname
\xint_stop_atfirstoftwo
\begingroup\xintglobaldefstrue
- % skip some overhead of \xintdefvar...
+ % skip some overhead of \xintdefvar...
+ % BUT attention to changes in xint 1.4 internal format !
\XINT_expr_defvar_one{\POL@sturmname L_\POL@findrat@index}%
- {\POL@findrat@x}%
+ {{\POL@findrat@x}}%
\XINT_expr_defvar_one{\POL@sturmname R_\POL@findrat@index}%
- {\POL@findrat@x}%
+ {{\POL@findrat@x}}%
\XINT_expr_defvar_one{\POL@sturmname Z_\POL@findrat@index _isknown}%
- {1}%
+ {{1}}%
\endgroup
}%
\def\POL@findrat@loop@updatequotients{%
% attention last division must have been one testing vanishing of\POL@sqfnorr
- \expandafter\let\csname POLuserpol@\POL@sturmname\POL@sqfnorr\endcsname\POL@Q
+ \XINT_global\expandafter\let\csname POLuserpol@\POL@sturmname\POL@sqfnorr\endcsname\POL@Q
% quotient belongs to Z[X] and is primitive
\POL@mapcoeffs\POL@aux@toint{\POL@sturmname\POL@sqfnorr}%
% update the one with multiplicities
\POL@divide{\POL@sturmname\POL@norr}{_findrat@oneterm}%
- \expandafter\let\csname POLuserpol@\POL@sturmname\POL@norr\endcsname\POL@Q
+ \XINT_global\expandafter\let\csname POLuserpol@\POL@sturmname\POL@norr\endcsname\POL@Q
\POL@mapcoeffs\POL@aux@toint{\POL@sturmname\POL@norr}
% updating of \POL@findrat@D at end of execution of getmultiplicity
}%
@@ -1411,7 +546,7 @@
\POL@divide{\POL@sturmname\POL@norr}{_findrat@oneterm}%
\expandafter\POL@split\POL@R;\POL@degR\POL@polR
\ifnum\POL@degR=\m@ne % yes
- \expandafter\let\csname POLuserpol@\POL@sturmname\POL@norr\endcsname\POL@Q
+ \XINT_global\expandafter\let\csname POLuserpol@\POL@sturmname\POL@norr\endcsname\POL@Q
\POL@mapcoeffs\POL@aux@toint{\POL@sturmname\POL@norr}%
\expandafter
\xdef
@@ -1451,14 +586,19 @@
\let\POL@sturm@N\@gobble% !
\let\POL@isolz@NbOfRoots@with_unknown_mult\POL@findrat@nbofirrroots
\POL@tosturm@makefirstprimitivefalse
+\expanded{\unexpanded{%
+ \unless\ifxintveryverbose\xintverbosefalse\polnewpolverbosefalse\fi
\POL@isolzmult@loop
+}\ifxintverbose\noexpand\xintverbosetrue\fi
+ \ifpolnewpolverbose\noexpand\polnewpolverbosetrue\fi}%
\POL@tosturm@makefirstprimitivetrue
\let\POL@sturmname\POL@originalsturmname
\fi
}%
-
-
-\newcommand\PolSturmIsolateZerosAndGetMultiplicities@[2][\empty]{%
+\def\PolSturmIsolateZerosAndGetMultiplicities@{%
+ \POL@chkopt\POL@oPolSturmIsolateZerosAndGetMultiplicities@[\empty]%
+}%
+\def\POL@oPolSturmIsolateZerosAndGetMultiplicities@[#1]#2{%
% #1 optional E such that roots are searched in -10^E < x < 10^E
% both -10^E and +10^E must not be roots!
% #2 name of Sturm chain (already pre-computed)
@@ -1487,7 +627,11 @@
% store Sturm chain name, it is needed and altered in isolzmult@loop
\let\POL@originalsturmname\POL@sturmname
\POL@tosturm@makefirstprimitivefalse
- \POL@isolzmult@loop
+\expanded{\unexpanded{%
+ \unless\ifxintveryverbose\xintverbosefalse\polnewpolverbosefalse\fi
+ \POL@isolzmult@loop
+}\ifxintverbose\noexpand\xintverbosetrue\fi
+ \ifpolnewpolverbose\noexpand\polnewpolverbosetrue\fi}%
\POL@tosturm@makefirstprimitivetrue
\let\POL@sturmname\POL@originalsturmname
\fi
@@ -1502,8 +646,9 @@
\let\x\POL@isolz@NbOfRoots
\xintloop
% skip some overhead of \xintdefvar...
+ % ATTENTION to xint 1.4 internal changes !
\XINT_expr_defvar_one{\POL@sturmname M_\x}%
- {\csname POL_ZM\POL@sturmname*\x\endcsname}%
+ {{\csname POL_ZM\POL@sturmname*\x\endcsname}}%
\edef\x{\the\numexpr\x-\@ne}%
\ifnum\x>\z@
\repeat
@@ -1586,9 +731,10 @@
{\the\numexpr\POL@isolz@NbOfRoots@with_unknown_mult-\@ne}%
\fi
}%
-
-
-\newcommand\PolSturmIsolateZeros@[2][\empty]{%
+\def\PolSturmIsolateZeros@{%
+ \POL@chkopt\POL@oPolSturmIsolateZeros@[\empty]%
+}%
+\def\POL@oPolSturmIsolateZeros@[#1]#2{%
% #1 optional E such that roots are searched in -10^E < x < 10^E
% both -10^E and +10^E must not be roots!
% #2 name of Sturm chain (already pre-computed from a given polynomial)
@@ -2077,17 +1223,20 @@
\fi
\begingroup\xintglobaldefstrue
% skip some overhead of \xintdefvar...
+ % Let me repeat: ATTENTION to change of internal format at xint 1.4
\XINT_expr_defvar_one{\POL@sturmname L_\POL@isolz@IntervalIndex}%
- {\POL@IsoLeft@rawout}%
+ {{\POL@IsoLeft@rawout}}%
\XINT_expr_defvar_one{\POL@sturmname R_\POL@isolz@IntervalIndex}%
- {\POL@IsoRight@rawout}%
+ {{\POL@IsoRight@rawout}}%
% added at 0.7
\XINT_expr_defvar_one{\POL@sturmname Z_\POL@isolz@IntervalIndex _isknown}%
- {\ifnum\POL@IsoRightSign=\z@ 1\else 0\fi}%
+ {{\ifnum\POL@IsoRightSign=\z@ 1\else 0\fi}}%
\endgroup
}%
%% \PolRefineInterval
-\def\POL@xintexprGetVar#1{\csname XINT_expr_varvalue_#1\endcsname}%
+%% ATTENTION TO xint 1.4 INTERNAL CHANGES
+\def\POL@xintexprGetVar#1{\expandafter\expandafter\expandafter\xint_firstofone
+ \csname XINT_expr_varvalue_#1\endcsname}%
% attention, also used by \POL@findrat@loop@a
\def\POL@get@IsoLeft@rawin{%
\edef\POL@IsoLeft@rawin
@@ -2103,8 +1252,11 @@
\def\POL@get@IsoLeft@Int{%
\expandafter\POL@get@Int@aux\POL@IsoLeft@rawin\POL@IsoLeft@Int\POL@isolz@E
}%
-\newcommand\PolRefineInterval{\@ifstar\POL@srefine@start\POL@refine@start}%
-\newcommand\POL@refine@start[3][1]{%
+\def\PolRefineInterval{\POL@ifstar\POL@srefine@start\POL@refine@start}%
+\def\POL@refine@start{%
+ \POL@chkopt\POL@oPOL@refine@start[1]%
+}%
+\def\POL@oPOL@refine@start[#1]#2#3{%
\edef\POL@isolz@IntervalIndex{\the\numexpr#3}%
\edef\POL@sturmname{#2}%
\expandafter\POL@refine@sharedbody\expandafter
@@ -2138,8 +1290,8 @@
\fi
}%
\def\POL@refine@loop#1{%
- \let\POL@refine@left@next \@empty % no recursion at end sub-intervals
- \let\POL@refine@right@next\@empty
+ \let\POL@refine@left@next \empty % no recursion at end sub-intervals
+ \let\POL@refine@right@next\empty
\xintiloop[1+1]
\POL@refine@main
\ifnum\POL@IsoRightSign=\z@
@@ -2160,11 +1312,11 @@
\ifnum\POL@IsoRightSign=\z@
\let\POL@IsoLeft@Int\POL@IsoRight@Int % root at 1
\def\POL@IsoLeftSign{0}%
- \let\POL@next\@empty
+ \let\POL@next\empty
\else
\ifnum\POL@IsoRightSign=\POL@@IsoRightSign\space
- \let\POL@next\POL@refine@left@next % may be \@empty or \POL@refine@main for recursion
- \let\POL@refine@right@next\@empty
+ \let\POL@next\POL@refine@left@next % may be \empty or \POL@refine@main for recursion
+ \let\POL@refine@right@next\empty
\else
\let\POL@IsoLeft@Int\POL@IsoRight@Int
\edef\POL@IsoRight@Int{\xintDec{\POL@@IsoRight@Int}}%
@@ -2173,7 +1325,7 @@
\ifnum\POL@IsoRightSign=\z@
\let\POL@IsoLeft@Int\POL@IsoRight@Int % root at 9
\def\POL@IsoLeftSign{0}%
- \let\POL@next\@empty
+ \let\POL@next\empty
\else
\ifnum\POL@IsoRightSign=\POL@@IsoRightSign\space
\let\POL@next\POL@refine@doonce
@@ -2182,7 +1334,7 @@
\let\POL@IsoRight@Int\POL@@IsoRight@Int
\let\POL@IsoRightSign\POL@@IsoRightSign
\let\POL@next\POL@refine@right@next
- \let\POL@refine@left@next\@empty
+ \let\POL@refine@left@next\empty
\fi
\fi
\fi\fi
@@ -2190,18 +1342,16 @@
}%
% lacking pre-defined xintfrac macro here (such as an \xintRawExponent)
\def\POL@refine@getE#1[#2]{#2}% \xintREZ already applied, for safety
-
-
-\newcommand\PolIntervalWidth[2]{%
+%
+%
+\def\PolIntervalWidth#1#2{%
% le \xintRez est à cause des E positifs, car trailing zéros explicites
% si je travaillais à partir des variables xintexpr directement ne devrait
% pas être nécessaire, mais trop fragile par rapport à chgt internes possibles
\romannumeral0\xintrez{\xintSub{\@nameuse{POL_ZR#1*}{#2}}%
{\@nameuse{POL_ZL#1*}{#2}}}
}%
-
-
-\newcommand\PolEnsureIntervalLengths[2]{% #1 = Sturm chain name,
+\def\PolEnsureIntervalLengths#1#2{% #1 = Sturm chain name,
% localize roots in intervals of length at most 10^{#2}
\edef\POL@sturmname{#1}%
\edef\POL@ensure@targetE{\the\numexpr#2}%
@@ -2220,7 +1370,7 @@
\ifnum\POL@nbofroots>\POL@count
\repeat
}%
-\newcommand\PolEnsureIntervalLength[3]{% #1 = Sturm chain name,
+\def\PolEnsureIntervalLength#1#2#3{% #1 = Sturm chain name,
% #2 = index of interval
% localize roots in intervals of length at most 10^{#3}
\edef\POL@sturmname{#1}%
@@ -2230,7 +1380,7 @@
\ifnum\POL@isolz@IntervalIndex>\z@
% 0.7, add this safeguard but attention means this structure must be in place
\ifnum\csname POL_ZL\POL@sturmname*0\endcsname>\z@
-% je ne fais pas les \expandafter mais je préfèrerai ne pas être à l'intérieur
+% je ne fais pas les \expandafter mais je préfèrerais ne pas être à l'intérieur
\POL@ensure@one
\fi
\fi
@@ -2282,24 +1432,39 @@
\expandafter\xintbreakloop
\fi
}%
-
-
+%
+%% \PolPrintIntervals
\catcode`_ 8
-\newcommand\PolPrintIntervals
- {\@ifstar{\PolPrintIntervals@@}{\PolPrintIntervals@}}%
-\newcommand\PolPrintIntervals@@{%
+\catcode`& 4
+\def\PolPrintIntervals{\POL@ifstar{\PolPrintIntervals@@}{\PolPrintIntervals@}}%
+% As explained in the docs, this is an example of customization so is not
+% itself customizable, apart from redefining it entirely!
+\def\PolPrintIntervals@@{%
\begingroup
\def\POL@AfterPrintIntervals{\endgroup}%
- \def\arraystretch{2}%
\let\PolPrintIntervalsPrintExactZero\POL@@PrintIntervalsPrintExactZero
\let\PolPrintIntervalsUnknownRoot\POL@@PrintIntervalsUnknownRoot
\let\PolPrintIntervalsKnownRoot\POL@@PrintIntervalsKnownRoot
+\ifdefined\array
+ \def\arraystretch{2}%
\def\PolPrintIntervalsBeginEnv{\[\begin{array}{cl}}%\]
\def\PolPrintIntervalsEndEnv{\end{array}\]}%
+\else
+ \def\PolPrintIntervalsBeginEnv{$$\tabskip0pt plus 1000pt minus 1000pt
+ \halign to\displaywidth\bgroup
+ \hfil\vrule height 2\ht\strutbox
+ depth 2\dp\strutbox
+ width \z@
+ $####$\tabskip6pt&$####$\hfil
+ \tabskip0pt plus 1000pt minus 1000pt\cr}%$$
+ \def\PolPrintIntervalsEndEnv{\crcr\egroup$$}%$$
+\fi
\PolPrintIntervals@
}%
-\newcommand\PolPrintIntervals@[2][Z]{\POL@PrintIntervals{#1}{#2}}%
-\newcommand\POL@PrintIntervals[2]{%
+\def\PolPrintIntervals@{%
+ \POL@chkopt\POL@oPolPrintIntervals@[Z]%
+}%
+\def\POL@oPolPrintIntervals@[#1]#2{%
\def\PolPrintIntervalsTheVar{#1}%
\def\PolPrintIntervalsTheSturmName{#2}%
\ifnum\@nameuse{POL_ZL#2*}{0}=\z@
@@ -2317,34 +1482,60 @@
\def\PolPrintIntervalsTheVar{#1}%
\def\PolPrintIntervalsTheSturmName{#2}%
}%
-\let\POL@AfterPrintIntervals\@empty
-\newcommand\PolPrintIntervalsNoRealRoots{}%
-\newcommand\PolPrintIntervalsBeginEnv{\[\begin{array}{rcccl}}%
-\newcommand\PolPrintIntervalsEndEnv{\end{array}\]}%
-\newcommand\PolPrintIntervalsKnownRoot{%
+\let\POL@AfterPrintIntervals\empty
+\let\PolPrintIntervalsNoRealRoots\empty
+\def\PolPrintIntervalsArrayStretch{1}%
+\ifdefined\array
+ \def\PolPrintIntervalsBeginEnv{\[\begin{array}{rcccl}}%
+ \def\PolPrintIntervalsEndEnv{\end{array}\]}%
+\else
+ \def\PolPrintIntervalsBeginEnv
+ {$$\tabskip 0pt plus 1000pt minus 1000pt
+ \halign to\displaywidth\bgroup
+ \hfil\vrule height\PolPrintIntervalsArrayStretch\ht\strutbox
+ depth \PolPrintIntervalsArrayStretch\dp\strutbox
+ width \z@
+ $##$\tabskip 6pt &\hfil $##$\hfil &\hfil $##$\hfil &\hfil $##$\hfil &$##$\hfil
+ \tabskip 0pt plus 1000pt minus 1000pt \cr
+ }%$$
+ \def\PolPrintIntervalsEndEnv{\crcr\egroup$$}%$$
+\fi
+\def\PolPrintIntervalsKnownRoot{%
&&\PolPrintIntervalsTheVar_{\PolPrintIntervalsTheIndex}%
&=&\PolPrintIntervalsPrintExactZero
}%
-\newcommand\PolPrintIntervalsUnknownRoot{%
+\def\PolPrintIntervalsUnknownRoot{%
\PolPrintIntervalsPrintLeftEndPoint&<&%
\PolPrintIntervalsTheVar_{\PolPrintIntervalsTheIndex}&<&%
\PolPrintIntervalsPrintRightEndPoint
}%
-\newcommand\PolPrintIntervalsPrintExactZero {\PolPrintIntervalsTheLeftEndPoint}%
-\newcommand\PolPrintIntervalsPrintLeftEndPoint {\PolPrintIntervalsTheLeftEndPoint}%
-\newcommand\PolPrintIntervalsPrintRightEndPoint{\PolPrintIntervalsTheRightEndPoint}%
-\newcommand\PolPrintIntervalsPrintMultiplicity{(\mbox{mult. }\PolPrintIntervalsTheMultiplicity)}%
+\def\PolPrintIntervalsPrintExactZero {\PolPrintIntervalsTheLeftEndPoint}%
+\def\PolPrintIntervalsPrintLeftEndPoint {\PolPrintIntervalsTheLeftEndPoint}%
+\def\PolPrintIntervalsPrintRightEndPoint{\PolPrintIntervalsTheRightEndPoint}%
+%
+\ifdefined\mbox
+\def\PolPrintIntervalsPrintMultiplicity{(\mbox{mult. }\PolPrintIntervalsTheMultiplicity)}%
+\else
+\def\PolPrintIntervalsPrintMultiplicity{(\hbox{mult. }\PolPrintIntervalsTheMultiplicity)}%
+\fi
%
-\newcommand\POL@@PrintIntervalsKnownRoot{%
+\def\POL@@PrintIntervalsKnownRoot{%
\PolPrintIntervalsPrintMultiplicity&%
\PolPrintIntervalsTheVar_{\PolPrintIntervalsTheIndex}=%
\PolPrintIntervalsPrintExactZero
}%
-\newcommand\POL@@PrintIntervalsPrintExactZero{%
+\ifdefined\frac
+\def\POL@@PrintIntervalsPrintExactZero{%
\displaystyle
\xintSignedFrac{\PolPrintIntervalsTheLeftEndPoint}%
}%
-\newcommand\POL@@PrintIntervalsUnknownRoot{%
+\else
+\def\POL@@PrintIntervalsPrintExactZero{%
+ \displaystyle
+ \xintSignedFwOver{\PolPrintIntervalsTheLeftEndPoint}%
+}%
+\fi
+\def\POL@@PrintIntervalsUnknownRoot{%
\PolPrintIntervalsPrintMultiplicity&%
\xintifSgn{\PolPrintIntervalsTheLeftEndPoint}%
{\xintifSgn{\PolPrintIntervalsTheRightEndPoint}
@@ -2364,8 +1555,9 @@
{\PolPrintIntervalsTheVar_{\PolPrintIntervalsTheIndex}=%
\PolPrintIntervalsPrintLeftEndPoint\dots}}%
}%
-%
+\catcode`& 7
\catcode`_ 11
+\def\POL@PrintIntervals@Loop#1{%
\def\POL@PrintIntervals@Loop{%
\POL@SturmIfZeroExactlyKnown\PolPrintIntervalsTheSturmName
\PolPrintIntervalsTheIndex
@@ -2375,9 +1567,10 @@
\unless\ifnum\PolPrintIntervalsTheIndex>
\@nameuse{POL_ZL\PolPrintIntervalsTheSturmName*0}
\POL@PrintIntervals@DoDefs
- \xint_afterfi{\\\POL@PrintIntervals@Loop}%
+ \xint_afterfi{#1\POL@PrintIntervals@Loop}%
\fi
-}%
+}}%
+\ifdefined\array\POL@PrintIntervals@Loop{\\}\else\POL@PrintIntervals@Loop{\cr}\fi
\def\POL@PrintIntervals@DoDefs{%
\xdef\PolPrintIntervalsTheLeftEndPoint{%
\csname POL_ZL\PolPrintIntervalsTheSturmName*\PolPrintIntervalsTheIndex
@@ -2397,492 +1590,60 @@
\fi
}%
}%
-
-
-\newcommand\PolSturmIfZeroExactlyKnown[2]{% #1 = sturmname, #2=index
+%
+%% Expandable interface
+%
+\def\PolSturmIfZeroExactlyKnown#1#2{% #1 = sturmname, #2=index
\romannumeral0\csname POL_ZK#1*\endcsname{#2}%
}%
-\newcommand\POL@SturmIfZeroExactlyKnown[2]{% #1 = sturmname, #2=index
+\def\POL@SturmIfZeroExactlyKnown#1#2{% #1 = sturmname, #2=index
\romannumeral0\csname POL_ZK#1*\the\numexpr#2\endcsname
}%
-\newcommand\PolSturmIsolatedZeroMultiplicity[2]{%
- \romannumeral`^^@\csname POL_ZM#1*\endcsname{#2}%
+\def\PolSturmIsolatedZeroMultiplicity#1#2{%
+ \romannumeral`&&@\csname POL_ZM#1*\endcsname{#2}%
}%
-\newcommand\PolSturmIsolatedZeroLeft[2]{%
- \romannumeral`^^@\csname POL_ZL#1*\endcsname{#2}%
+\def\PolSturmIsolatedZeroLeft#1#2{%
+ \romannumeral`&&@\csname POL_ZL#1*\endcsname{#2}%
}%
-\newcommand\PolSturmIsolatedZeroRight[2]{%
- \romannumeral`^^@\csname POL_ZR#1*\endcsname{#2}%
+\def\PolSturmIsolatedZeroRight#1#2{%
+ \romannumeral`&&@\csname POL_ZR#1*\endcsname{#2}%
}%
-\newcommand\PolSturmNbOfIsolatedZeros[1]{%
- \romannumeral`^^@\csname POL_ZL#1*0\endcsname
+\def\PolSturmNbOfIsolatedZeros#1{%
+ \romannumeral`&&@\csname POL_ZL#1*0\endcsname
}%
-\newcommand\PolSturmRationalRoot[2]{%
- \romannumeral`^^@\csname POL_ZL#1*%
+\def\PolSturmRationalRoot#1#2{%
+ \romannumeral`&&@\csname POL_ZL#1*%
\csname POL_RI#1*\endcsname{#2}\endcsname
}%
-\newcommand\PolSturmRationalRootIndex[2]{%
- \romannumeral`^^@\csname POL_RI#1*\endcsname{#2}%
+\def\PolSturmRationalRootIndex#1#2{%
+ \romannumeral`&&@\csname POL_RI#1*\endcsname{#2}%
}%
-\newcommand\PolSturmRationalRootMultiplicity[2]{%
- \romannumeral`^^@\csname POL_ZM#1%
+\def\PolSturmRationalRootMultiplicity#1#2{%
+ \romannumeral`&&@\csname POL_ZM#1%
*\csname POL_RI#1*\endcsname{#2}\endcsname
}%
-\newcommand\PolSturmNbOfRationalRoots[1]{%
- \romannumeral`^^@\csname POL_RI#1*0\endcsname
+\def\PolSturmNbOfRationalRoots#1{%
+ \romannumeral`&&@\csname POL_RI#1*0\endcsname
}%
-\newcommand\PolSturmNbOfRationalRootsWithMultiplicities[1]{%
+\def\PolSturmNbOfRationalRootsWithMultiplicities#1{%
% means the \POL@norr must not have been changed in-between...
\the\numexpr\PolDegree{#1}-\PolDegree{#1\POL@norr}\relax
}%
-
-
-\let\PolDecToString\xintDecToString
-
-
-\newcommand\PolMakeMonic[1]{%
- \edef\POL@leadingcoeff{\PolLeadingCoeff{#1}}%
- \edef\POL@leadingcoeff@inverse{\xintDiv{1/1[0]}{\POL@leadingcoeff}}%
- \PolMapCoeffs{\xintMul{\POL@leadingcoeff@inverse}}{#1}%
-}%
-
-
-%% CORE ALGEBRA MACROS
-%% We do this non-expandably, but in a nestable way... this is the whole
-%% point because \xintdeffunc as used by \poldef creates a big nested macro.
-%% The idea is to execute it with another meaning given to \xintAdd etc..,
-%% so that it operates on "polynomials". This is a mixture of expandable
-%% and non-expandable techniques.
-%%
-%% And it was complicated to let it work with xintexpr 1.4
-%%
-\def\POL@get#1#2#3{%
- \relax %!! part de la tambouille pour fonctionner en xint 1.4
- \POL@polglobalfalse
- \begingroup
- \protected\def\POL@result{#3}%
- #3%
- \expandafter
- \endgroup
- \expandafter\def\expandafter#1\expandafter{\POL@result}%
- \unless\ifPOL@pol
- % avoid expanding more than twice #3
- % #3 must be purely numerical or at least compatible with \edef
- % this is why at 0.7.5 I had to handle especially constant
- % polynomial functions to remove any protection from them
- % (because the protection triggers the COMPOSITION when
- % the polynomial is found as argument of another one and
- % this is not expandable)
- \edef#1{#3}%
- \xintiiifZero{#1}%
- {\def#1{-1.\POL@empty{0/1[0]}}}%
- {\edef#1{0.\POL@empty{#1}}}%
- \fi
- #2%
-}%
-
-%% COMPOSITION
-%% This did not exist before 0.7.5 and is part of its adaptation to xint 1.4
-%% We thus took up this opportunity to speed up substantially composition.
-%% Very serious difficulties with constant polynomials. Had to handle them
-%% especially.
-%% OK, that was really tough, but advantage now is that composition
-%% at 0.7.5 should be more efficient than before. However when polynomials
-%% become big via composition, coefficients also are big and the time
-%% taken by arithmetic dominates. No time to test really, though, relieved
-%% I can release xint 1.4 at last. My basic polexpr test suite passes,
-%% but it goes back already to old releases.
-\protected\def\POL@applypolfunc#1#2%
-{%
-% This #2 may be also invoing \POL@applypolfunc...
- \POL@get\POL@A\POL@applypolfunc@b#2#1%
-}%
-\def\POL@applypolfunc@b #1%
-{%
-% and now the have our Horner scheme nested macro
-% which hopefully will do its job with \POL@add, \POL@mul etc...
- \POL@polglobalfalse
- \expandafter#1\expanded
- {{\POL@polglobaltrue\protected\def\noexpand\POL@result{\POL@A}}}%
- \unless\ifPOL@pol
- \odef\POL@result{#1{0}}%
- \xintiiifZero{\POL@result}%
- {\protected\def\POL@result{-1.\POL@empty{0/1[0]}}}%
- {\protected\edef\POL@result{0.\POL@empty{\POL@result}}}%
- \fi
-}%
-
-%% ADDITION
-\def\POL@add {\POL@get\POL@A\POL@add@b}%
-\def\POL@add@b{\POL@get\POL@B\POL@add@c}%
-\def\POL@add@c{%
- \POL@polglobaltrue
- \POL@ifZero\POL@A
- {\let\POL@result\POL@B}%
- {\POL@ifZero\POL@B
- {\let\POL@result\POL@A}%
- {\POL@@add}}%
-}%
-\def\POL@@add{%
- \expandafter\POL@split\POL@A;\POL@degA\POL@polA
- \expandafter\POL@split\POL@B;\POL@degB\POL@polB
- \ifnum\POL@degA>\POL@degB\relax
- \xintAssignArray\POL@polA\to\POL@arrayA
- \xintAssignArray\POL@polB\to\POL@arrayB
- \else
- \xintAssignArray\POL@polB\to\POL@arrayA
- \xintAssignArray\POL@polA\to\POL@arrayB
- \let\POL@tmp\POL@degB\let\POL@degB\POL@degA\let\POL@degA\POL@tmp
- \fi
- \count@\z@
- \xintloop
- \advance\count@\@ne
- \expandafter\edef\csname POL@arrayA\the\count@\endcsname
- {\xintScalarAdd{\@nameuse{POL@arrayA\the\count@}}%
- {\@nameuse{POL@arrayB\the\count@}}}%
- \unless\ifnum\POL@degB<\count@
- \repeat
- \count@\@nameuse{POL@arrayA0} % 1+\POL@degA
- % trim zero leading coefficients (we could check for equal degrees,
- % but would not bring much as anyhow loop exists immediately if not)
- \xintloop
- % this abuses that \POL@arrayA0 is never zero
- \xintiiifZero{\@nameuse{POL@arrayA\the\count@}}%
- {\iftrue}%
- {\iffalse}%
- \advance\count@\m@ne
- \repeat
- \POL@resultfromarray A% attention that \POL@arrayA0 not updated
-}%
-
-%% MULTIPLICATION
-\def\POL@mul {\POL@get\POL@A\POL@mul@b}%
-\def\POL@mul@b{\POL@get\POL@B\POL@mul@c}%
-\def\POL@mul@c{%
- \POL@polglobaltrue
- \POL@ifZero\POL@A
- {\protected\def\POL@result{-1.\POL@empty{0/1[0]}}}%
- {\POL@ifZero\POL@B
- {\protected\def\POL@result{-1.\POL@empty{0/1[0]}}}%
- {\POL@@mul}}%
-}%
-\def\POL@@mul{%
- \expandafter\POL@split\POL@A;\POL@degA\POL@polA
- \expandafter\POL@split\POL@B;\POL@degB\POL@polB
- \ifnum\POL@degA>\POL@degB\relax
- \xintAssignArray\POL@polA\to\POL@arrayA
- \xintAssignArray\POL@polB\to\POL@arrayB
- \else
- \xintAssignArray\POL@polB\to\POL@arrayA
- \xintAssignArray\POL@polA\to\POL@arrayB
- \let\POL@tmp\POL@degB
- \let\POL@degB\POL@degA
- \let\POL@degA\POL@tmp
- \fi
- \count@\z@
- \xintloop
- \POL@@mul@phaseIloopbody
- \unless\ifnum\POL@degB<\count@
- \repeat
- \xintloop
- \unless\ifnum\POL@degA<\count@ % car attention au cas de mêmes degrés
- \POL@@mul@phaseIIloopbody
- \repeat
- \edef\POL@degC{\the\numexpr\POL@degA+\POL@degB}%
- \xintloop
- \unless\ifnum\POL@degC<\count@
- \POL@@mul@phaseIIIloopbody
- \repeat
- %\count@\the\numexpr\POL@degC+\@ne\relax % never zero polynomial here
- \POL@resultfromarray C%
-}%
-\def\POL@@mul@phaseIloopbody{%
- \advance\count@\@ne
- \def\POL@tmp{0[0]}%
- \count\tw@\z@
- \xintloop
- \advance\count\tw@\@ne
- \edef\POL@tmp{%
- \xintScalarAdd
- {\POL@tmp}%
- {\xintScalarMul
- {\@nameuse{POL@arrayA\the\count\tw@}}%
- {\@nameuse{POL@arrayB\the\numexpr\count@+\@ne-\count\tw@}}%
- }%
- }%
- \ifnum\count\tw@<\count@
- \repeat
- \expandafter\let\csname POL@arrayC\the\count@\endcsname\POL@tmp
-}%
-\def\POL@@mul@phaseIIloopbody{%
- \advance\count@\@ne
- \def\POL@tmp{0[0]}%
- \count\tw@\count@
- \advance\count\tw@-\@nameuse{POL@arrayB0} %
- \xintloop
- \ifnum\count\tw@<\count@
- \advance\count\tw@\@ne
- \edef\POL@tmp{%
- \xintScalarAdd
- {\POL@tmp}%
- {\xintScalarMul
- {\@nameuse{POL@arrayA\the\count\tw@}}%
- {\@nameuse{POL@arrayB\the\numexpr\count@+\@ne-\count\tw@}}%
- }%
- }%
- \repeat
- \expandafter\let\csname POL@arrayC\the\count@\endcsname\POL@tmp
-}%
-\def\POL@@mul@phaseIIIloopbody{%
- \advance\count@\@ne
- \def\POL@tmp{0[0]}%
- \count\tw@\count@
- \advance\count\tw@-\@nameuse{POL@arrayB0} %
- \xintloop
- \advance\count\tw@\@ne
- \edef\POL@tmp{%
- \xintScalarAdd{\POL@tmp}%
- {\xintScalarMul
- {\@nameuse{POL@arrayA\the\count\tw@}}%
- {\@nameuse{POL@arrayB\the\numexpr\count@+\@ne-\count\tw@}}%
- }%
- }%
- \ifnum\@nameuse{POL@arrayA0}>\count\tw@
- \repeat
- \expandafter\let\csname POL@arrayC\the\count@\endcsname\POL@tmp
-}%
-
-%% POWERS (SCALAR EXPONENT...)
-\def\POL@pow #1#2{%
- \POL@polglobalfalse
- \begingroup
- \protected\def\POL@result{#1}%
- #1%
- \expandafter
- \endgroup
- \expandafter\def\expandafter\POL@A\expandafter{\POL@result}%
- \unless\ifPOL@pol
- \edef\POL@A{\xintScalarPow{#1}{#2}}% no error check
- \xintiiifZero{\POL@A}%
- {\protected\def\POL@result{-1.\POL@empty{0/1[0]}}}%
- {\protected\edef\POL@result{0.\POL@empty{\POL@A}}}%
- \else
- \edef\POL@B{\numexpr\xintNum{#2}\relax}% no check on exponent >= 0
- \ifcase\POL@B
- \protected\def\POL@result{0.\POL@empty{1/1[0]}}%
- \or
- \let\POL@result\POL@A
- \else
- \POL@@pow@check
- \fi
- \fi
- \POL@polglobaltrue
-}%
-\def\POL@@pow@check {%
-% no problem here with leftover tokens!
-% should I have used that I-don't-care technique more elsewhere?
- \ifnum\@ne>\POL@A
- % polynomial is a constant, must get rid of dot and \empty (\POL@empty)
- \edef\POL@A{\expandafter\xintScalarPow\romannumeral`^^@%
- \expandafter\xint_gob_til_dot\POL@A{\POL@B}}%
- \xintiiifZero{\POL@A}%
- {\protected\def\POL@result{-1.\POL@empty{0/1[0]}}}%
- {\protected\edef\POL@result{0.\POL@empty{\POL@A}}}%
- \else
- \ifnum\@ne=\POL@A
- % perhaps a constant times X, check constant term
- \xintiiifZero
- {\expandafter\xint_firstoftwo\romannumeral`^^@%
- \expandafter\xint_gob_til_dot\POL@A}
- {\protected\edef\POL@result
- {\the\POL@B.% here at least 2.
- \POL@empty
- \romannumeral\xintreplicate{\POL@B}{{0/1[0]}}%
- {\xintScalarPow
- {\expandafter\xint_secondoftwo\romannumeral`^^@%
- \expandafter\xint_gob_til_dot\POL@A}%
- {\POL@B}}}}%
- {\POL@@pow}% not constant times X, use general recursion
- \else
- \POL@@pow% general recursion
- \fi\fi
-}%
-\def\POL@@pow@recurse#1#2{%
- \begingroup
- #1%
- \expandafter
- \endgroup
- \expandafter\def\expandafter\POL@A\expandafter{\POL@result}%
- \edef\POL@B{\numexpr\xintNum{#2}\relax}%
- \ifcase\POL@B
- \POL@thisshouldneverhappen
- \or
- \let\POL@result\POL@A
- \else
- \expandafter\POL@@pow
- \fi
-}%
-\def\POL@@pow {%
- \let\POL@pow@exp\POL@B
- \let\POL@B\POL@A
- \POL@@mul
- \let\POL@sqA\POL@result
- \ifodd\POL@pow@exp\space
- \expandafter\POL@@pow@odd
- \the\numexpr(\POL@pow@exp+\@ne)/\tw@-\@ne\expandafter.%
- \else
- \expandafter\POL@@pow@even
- \the\numexpr(\POL@pow@exp+\@ne)/\tw@-\@ne\expandafter.%
- \fi
-}%
-\def\POL@@pow@even#1.{%
- \expandafter\POL@@pow@recurse\expandafter
- {\expandafter\def\expandafter\POL@result\expandafter{\POL@sqA}}%
- {#1}%
-}%
-\def\POL@@pow@odd#1.{%
- \expandafter\POL@@pow@odd@i\expandafter{\POL@A}{#1}%
-}%
-\def\POL@@pow@odd@i #1#2{%
- \expandafter\POL@@pow@recurse\expandafter
- {\expandafter\def\expandafter\POL@result\expandafter{\POL@sqA}}%
- {#2}%
- \expandafter\POL@mul\expandafter
- {\expandafter\def\expandafter\POL@result\expandafter
- {\POL@result}\POL@polglobaltrue}%
- {\protected\def\POL@result{#1}\POL@polglobaltrue}%
-}%
-
-%% DIVISION
-%% no check on divisor being non-zero
-\def\POL@div {\POL@get\POL@A\POL@div@b}%
-\def\POL@div@b{\POL@get\POL@B\POL@div@c}%
-\def\POL@div@c{%
- \POL@polglobaltrue
- \expandafter\POL@split\POL@A;\POL@degA\POL@polA
- \expandafter\POL@split\POL@B;\POL@degB\POL@polB
- \ifnum\POL@degA<\POL@degB\space
- \@namedef{POL@arrayQ1}{0/1[0]}%
- \def\POL@degQ{-1}%
- \else
- \xintAssignArray\POL@polA\to\POL@arrayR
- \xintAssignArray\POL@polB\to\POL@arrayB
- \POL@@div
- \fi
- \count@\numexpr\POL@degQ+\@ne\relax
- \POL@resultfromarray Q%
-}%
-\def\POL@@div{%
- \xintAssignArray\POL@polA\to\POL@arrayR
- \xintAssignArray\POL@polB\to\POL@arrayB
- \edef\POL@B@leading{\csname POL@arrayB\the\numexpr\POL@degB+\@ne\endcsname}%
- \edef\POL@degQ{\the\numexpr\POL@degA-\POL@degB}%
- \count@\numexpr\POL@degA+\@ne\relax
- \count\tw@\numexpr\POL@degQ+\@ne\relax
- \xintloop
- \POL@@div@loopbody
- \ifnum\count\tw@>\z@
- \repeat
- %%\expandafter\def\csname POL@arrayR0\endcsname{1}%
- \xintloop
- \xintiiifZero{\csname POL@arrayR\the\count@\endcsname}%
- {\iftrue}%
- {\iffalse}%
- \advance\count@\m@ne
- \repeat
- \edef\POL@degR{\the\numexpr\count@-\@ne}%
-}%
-\def\POL@@div@loopbody{%
- \edef\POL@@div@ratio{%
- \xintScalarDiv{\csname POL@arrayR\the\count@\endcsname}%
- {\POL@B@leading}}%
- \expandafter\let\csname POL@arrayQ\the\count\tw@\endcsname
- \POL@@div@ratio
- \advance\count@\m@ne
- \advance\count\tw@\m@ne
- \count4 \count@
- \count6 \POL@degB\space
- \xintloop
- \ifnum\count6>\z@
- \expandafter\edef\csname POL@arrayR\the\count4\endcsname
- {\xintScalarSub
- {\csname POL@arrayR\the\count4\endcsname}%
- {\xintScalarMul
- {\POL@@div@ratio}%
- {\csname POL@arrayB\the\count6\endcsname}}}%
- \advance\count4 \m@ne
- \advance\count6 \m@ne
- \repeat
-}%
-
-%% MINUS SIGN AS UNARY OPERATOR
-\def\POL@opp #1{%
- \POL@polglobalfalse
- \begingroup
- \protected\def\POL@result{#1}%
- #1%
- \expandafter
- \endgroup
- \expandafter\def\expandafter\POL@A\expandafter{\POL@result}%
- \unless\ifPOL@pol
- \edef\POL@A{\xintScalarOpp{#1}}%
- \xintiiifZero{\POL@A}%
- {\protected\def\POL@result{-1.\POL@empty{0/1[0]}}}%
- {\protected\edef\POL@result{0.\POL@empty{\POL@A}}}%
- \else
- \edef\POL@B{0.\POL@empty{-1/1[0]}}%
- \POL@@mul
- \fi
- \POL@polglobaltrue
-}%
-
-
-%% EXPANDABLE MACROS
-\def\POL@eval@fork#1\At#2#3\krof{#2}%
-\newcommand\PolEval[3]{\romannumeral`^^@\POL@eval@fork
- #2\PolEvalAt
- \At\PolEvalAtExpr\krof {#1}{#3}%
-}%
-\newcommand\PolEvalAt[2]
- {\xintpraw{\csname XINT_expr_polfunc_#1\endcsname{#2}}}%
-\newcommand\POL@eval[2]
- {\csname XINT_expr_polfunc_#1\endcsname{#2}}%
-\newcommand\PolEvalAtExpr[2]{\xinttheexpr #1(#2)\relax}%
-%
-\newcommand\PolEvalReduced[3]{\romannumeral`^^@\POL@eval@fork
- #2\PolEvalReducedAt
- \At\PolEvalReducedAtExpr\krof {#1}{#3}%
-}%
-\newcommand\PolEvalReducedAt[2]{%
- \xintpraw % in order not to print denominator if the latter equals 1
- {\xintIrr{\csname XINT_expr_polfunc_#1\endcsname{#2}}[0]}%
-}%
-\newcommand\PolEvalReducedAtExpr[2]{%
- \xintpraw
- {\expandafter\xintIrr\romannumeral`^^@\xintthebareeval#1(#2)\relax[0]}%
-}%
-%
-\newcommand\PolFloatEval[3]{\romannumeral`^^@\POL@eval@fork
- #2\PolFloatEvalAt
- \At\PolFloatEvalAtExpr\krof {#1}{#3}%
-}%
-\newcommand\PolFloatEvalAt[2]
- {\xintpfloat{\csname XINT_flexpr_polfunc_#1\endcsname{#2}}}%
-\newcommand\PolFloatEvalAtExpr[2]{\xintthefloatexpr #1(#2)\relax}%
-
-
-\newcommand\PolSturmIntervalIndex[3]{\the\numexpr\POL@eval@fork
+\def\PolSturmIntervalIndex#1#2#3{\the\numexpr\POL@eval@fork
#2\PolSturmIntervalIndexAt
\At\PolSturmIntervalIndexAtExpr\krof {#1}{#3}%
}%
-\newcommand\PolSturmIntervalIndexAtExpr[2]
- {\PolSturmIntervalIndexAt{#1}{\xinttheexpr#2\relax}}%
-\newcommand\PolSturmIntervalIndexAt[2]
- {\expandafter\POL@sturm@index@at\romannumeral`^^@#2!{#1}\xint_bye\relax}%
+\def\PolSturmIntervalIndexAtExpr#1#2{%
+ \PolSturmIntervalIndexAt{#1}{\xinttheexpr#2\relax}%
+}%
+% ! is of catcode 11 in all of polexpr
+\def\PolSturmIntervalIndexAt#1#2{%
+ \expandafter\POL@sturm@index@at\romannumeral`&&@#2!{#1}\xint_bye\relax
+}%
\def\POL@sturm@index@at#1!#2%
{%
\expandafter\POL@sturm@index@at@iloop
- \romannumeral`^^@\PolSturmNbOfIsolatedZeros{#2}!{#2}{#1}%
+ \romannumeral`&&@\PolSturmNbOfIsolatedZeros{#2}!{#2}{#1}%
}%
% implementation is sub-optimal as it should use some kind of binary tree
% search rather than comparing to the intervals from right to left as here
@@ -2906,19 +1667,18 @@
}%
{}%
}%
- % catcode of ! is 11 in polexpr.sty
+ % attention that catcode of ! is 11 in polexpr.sty
\expandafter\POL@sturm@index@at@iloop\the\numexpr#1-\@ne !{#2}{#3}%
}%
-
-
+%
\def\POL@leq@fork#1\LessThanOrEqualTo#2#3\krof{#2}%
-\newcommand\PolSturmNbOfRootsOf[3]{\romannumeral`^^@\POL@leq@fork
+\def\PolSturmNbOfRootsOf#1#2#3{\romannumeral`&&@\POL@leq@fork
#2\PolNbOfRootsLessThanOrEqualTo
\LessThanOrEqualTo\PolNbOfRootsLessThanOrEqualToExpr\krof {#1}{#3}%
}%
-\newcommand\PolNbOfRootsLessThanOrEqualToExpr[2]
+\def\PolNbOfRootsLessThanOrEqualToExpr#1#2
{\PolNbOfRootsLessThanOrEqualTo{#1}{\xinttheexpr#2\relax}}%
-\newcommand\PolNbOfRootsLessThanOrEqualTo[1]{%
+\def\PolNbOfRootsLessThanOrEqualTo#1{%
\ifnum\PolSturmNbOfIsolatedZeros{#1}=\z@
\expandafter\xint_firstofthree\expandafter0%
\else
@@ -2927,7 +1687,7 @@
}%
\def\PolNbOfRootsLessThanOrEqualTo@ #1#2%
{%
- \expandafter\POL@nbofrootsleq@prep\romannumeral`^^@#2!{#1}%
+ \expandafter\POL@nbofrootsleq@prep\romannumeral`&&@#2!{#1}%
}%
\def\POL@nbofrootsleq@prep#1!#2%
{%
@@ -2959,16 +1719,16 @@
\def\POL@nbofrootsleq@return #1!#2!#3!#4!#5{\the\numexpr #1\relax}%
\def\POL@nbofrootsleq@rightmost\expandafter\POL@nbofrootsleq@iloop
\the\numexpr\@ne+#1!#2!#3!#4{#1}%
-
-
-\newcommand\PolSturmNbWithMultOfRootsOf[3]
-{\the\numexpr0\POL@leq@fork
+%
+\def\PolSturmNbWithMultOfRootsOf#1#2#3{%
+ \the\numexpr0\POL@leq@fork
#2\PolNbWithMultOfRootsLessThanOrEqualTo
\LessThanOrEqualTo\PolNbWithMultOfRootsLessThanOrEqualToExpr\krof {#1}{#3}%
}%
-\newcommand\PolNbWithMultOfRootsLessThanOrEqualToExpr[2]
- {\PolNbWithMultOfRootsLessThanOrEqualTo{#1}{\xinttheexpr#2\relax}}%
-\newcommand\PolNbWithMultOfRootsLessThanOrEqualTo[1]{%
+\def\PolNbWithMultOfRootsLessThanOrEqualToExpr#1#2{%
+ \PolNbWithMultOfRootsLessThanOrEqualTo{#1}{\xinttheexpr#2\relax}%
+}%
+\def\PolNbWithMultOfRootsLessThanOrEqualTo#1{%
\ifnum\PolSturmNbOfIsolatedZeros{#1}=\z@
\expandafter\POL@nbwmofroots@noroots
\else
@@ -2978,7 +1738,7 @@
\def\POL@nbwmofroots@noroots#1#2{\relax}%
\def\PolNbWithMultOfRootsLessThanOrEqualTo@ #1#2%
{%
- \expandafter\POL@nbwmofrootsleq@prep\romannumeral`^^@#2!{#1}%
+ \expandafter\POL@nbwmofrootsleq@prep\romannumeral`&&@#2!{#1}%
}%
\def\POL@nbwmofrootsleq@prep#1!#2%
{%
@@ -3012,153 +1772,4 @@
#1!#2!#3!{#4}%
}%
\def\POL@nbwmofrootsleq@return #1!#2!#3!#4!#5{#1\relax}%
-
-
-\newcommand\PolLeadingCoeff[1]{%
- \romannumeral`^^@\expandafter\expandafter\expandafter\xintlastitem
- \expandafter\expandafter\expandafter
- {\csname POLuserpol@#1\endcsname}%
-}%
-%
-\newcommand\PolNthCoeff[2]{\romannumeral`^^@%
- \expandafter\POL@nthcoeff
- \romannumeral0\xintnthelt{\ifnum\numexpr#2<\z@#2\else(#2)+1\fi}%
- {\expandafter\expandafter\expandafter
- \xint_gob_til_dot\csname POLuserpol@#1\endcsname}@%
-}%
-\def\POL@nthcoeff#1@{\if @#1@\expandafter\xint_firstoftwo
- \else\expandafter\xint_secondoftwo\fi
- {0/1[0]}{#1}}%
-%
-% returns -1 for zero polynomial for context of numerical expression
-% should it return -\infty?
-\newcommand\PolDegree[1]{\romannumeral`^^@\expandafter\expandafter\expandafter
- \POL@degree\csname POLuserpol@#1\endcsname;}%
-\def\POL@degree #1.#2;{#1}%
-%
-\newcommand\PolToList[1]{\romannumeral`^^@\expandafter\expandafter\expandafter
- \xint_gob_til_dot\csname POLuserpol@#1\endcsname}%
-%
-\newcommand\PolToCSV[1]{\romannumeral0\xintlistwithsep{, }{\PolToList{#1}}}%
-
-
-\newcommand\PolToExprCmd[1]{\xintPRaw{\xintRawWithZeros{#1}}}%
-\newcommand\PolToFloatExprCmd[1]{\xintFloat{#1}}%
-\let\PolToExprTermPrefix\PolTypesetCmdPrefix
-\newcommand\PolToExprOneTermStyleA[2]{%
- \ifnum#2=\z@
- \PolToExprCmd{#1}%
- \else
- \xintifOne{\xintiiAbs{#1}}
- {\xintiiifSgn{#1}{-}{}{}}% + from \PolToExprTermPrefix
- {\PolToExprCmd{#1}\PolToExprTimes}%
- \fi
- \ifcase\xintiiAbs{#2} %<-- space here mandatory
- \or\PolToExprVar
- \else\PolToExprVar^\xintiiAbs{#2}%
- \fi
-}%
-\let\PolToExprOneTerm\PolToExprOneTermStyleA
-\newcommand\PolToExprOneTermStyleB[2]{%
- \ifnum#2=\z@
- \xintNumerator{#1}%
- \else
- \xintifOne{\xintiiAbs{\xintNumerator{#1}}}
- {\xintiiifSgn{#1}{-}{}{}}% + from \PolToExprTermPrefix
- {\xintNumerator{#1}\PolToExprTimes}%
- \fi
- \ifcase\xintiiAbs{#2} %<-- space here mandatory
- \or\PolToExprVar
- \else\PolToExprVar^\xintiiAbs{#2}%
- \fi
- \xintiiifOne{\xintDenominator{#1}}{}{/\xintDenominator{#1}}%
-}%
-\newcommand\PolToFloatExprOneTerm[2]{%
- \ifnum#2=\z@
- \PolToFloatExprCmd{#1}%
- \else
- \PolToFloatExprCmd{#1}\PolToExprTimes
- \fi
- \ifcase\xintiiAbs{#2} %<-- space here mandatory
- \or\PolToExprVar
- \else\PolToExprVar^\xintiiAbs{#2}%
- \fi
-}%
-\newcommand\PolToExprTimes{*}%
-\newcommand\PolToExprVar{x}%
-\newcommand\PolToExpr[1]{%
- \if*\noexpand#1\expandafter\xint_firstoftwo\else
- \expandafter\xint_secondoftwo\fi
- \PolToExprAscending\PolToExprDescending{#1}}%
-\newcommand\PolToFloatExpr[1]{%
- \if*\noexpand#1\expandafter\xint_firstoftwo\else
- \expandafter\xint_secondoftwo\fi
- \PolToFloatExprAscending\PolToFloatExprDescending{#1}}%
-\newcommand\PolToExprAscending[2]{%
- \expandafter\POL@toexpr\csname POLuserpol@#2\endcsname
- \PolToExprOneTerm\POL@toexprA}%
-\newcommand\PolToFloatExprAscending[2]{%
- \expandafter\POL@toexpr\csname POLuserpol@#2\endcsname
- \PolToFloatExprOneTerm\POL@toexprA}%
-\newcommand\PolToExprDescending[1]{%
- \expandafter\POL@toexpr\csname POLuserpol@#1\endcsname
- \PolToExprOneTerm\POL@toexprD}%
-\newcommand\PolToFloatExprDescending[1]{%
- \expandafter\POL@toexpr\csname POLuserpol@#1\endcsname
- \PolToFloatExprOneTerm\POL@toexprD}%
-%
-\def\POL@toexpr#1#2#3{\expandafter\POL@toexpr@
- \expandafter#3\expandafter#2#1\relax}%
-\def\POL@toexpr@#1#2#3.{%
- \ifnum#3<\z@
- #2{0/1[0]}{0}\expandafter\xint_gobble_v
- \else
- \expandafter#1%
- \fi {#3}#2}%
-%
-\def\POL@toexprA #1#2\POL@empty#3{%
- \ifpoltoexprall\expandafter\POL@toexprall@b
- \else\expandafter\POL@toexpr@b
- \fi {#3}#2{0}1.%
-}%
-\def\POL@toexprD #1#2#3\relax{% #3 has \empty (\POL@empty) to prevent brace removal
- \expandafter\POL@toexprD@a\expandafter#2%
- \the\numexpr #1\expandafter.\romannumeral0\xintrevwithbraces{#3}\relax
-}%
-\def\POL@toexprD@a #1#2.#3{%
- \ifpoltoexprall\expandafter\POL@toexprall@b
- \else\expandafter\POL@toexpr@b
- \fi{#3}#1{-#2}\the\numexpr\@ne+-#2.%
-}%
-\def\POL@toexpr@b #1#2#3{%
- \xintiiifZero{#1}%
- {\expandafter\POL@toexpr@loop\expandafter\POL@toexpr@b}%
- {#2{#1}{#3}%
- \expandafter\POL@toexpr@loop\expandafter\POL@toexpr@c}%
- \expandafter#2%
-}%
-\def\POL@toexpr@c #1#2#3{%
- \xintiiifZero{#1}%
- {}%
- {\PolToExprTermPrefix{#1}#2{#1}{#3}}%
- \expandafter\POL@toexpr@loop\expandafter\POL@toexpr@c
- \expandafter#2%
-}%
-\def\POL@toexprall@b #1#2#3{%
- #2{#1}{#3}%
- \expandafter\POL@toexpr@loop\expandafter\POL@toexprall@c
- \expandafter#2%
-}%
-\def\POL@toexprall@c #1#2#3{%
- \PolToExprTermPrefix{#1}#2{#1}{#3}%
- \expandafter\POL@toexpr@loop\expandafter\POL@toexprall@c
- \expandafter#2%
-}%
-\def\POL@toexpr@loop#1#2#3.#4{%
- \if\relax#4\expandafter\xint_gob_til_dot\fi
- #1{#4}#2{#3}\the\numexpr\@ne+#3.%
-}%
-
-
-\POL@restorecatcodes
\endinput
diff --git a/macros/generic/xint/CHANGES.html b/macros/generic/xint/CHANGES.html
index 32fcfbe4ee..20b940dad7 100644
--- a/macros/generic/xint/CHANGES.html
+++ b/macros/generic/xint/CHANGES.html
@@ -4,7 +4,7 @@
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
- <meta name="author" content="xint 1.4c" />
+ <meta name="author" content="xint 1.4d" />
<title>CHANGE LOG</title>
<style type="text/css">
code{white-space: pre-wrap;}
@@ -25,47 +25,51 @@
<body>
<header>
<h1 class="title">CHANGE LOG</h1>
-<p class="author">xint 1.4c</p>
-<p class="date">2021/02/20</p>
+<p class="author">xint 1.4d</p>
+<p class="date">2021/03/29</p>
</header>
<nav id="TOC">
<ul>
-<li><a href="#c-20210220"><code>1.4c (2021/02/20)</code></a><ul>
+<li><a href="#d-20210329"><code>1.4d (2021/03/29)</code></a><ul>
+<li><a href="#breaking-changes">Breaking changes</a></li>
<li><a href="#bug-fixes">Bug fixes</a></li>
</ul></li>
+<li><a href="#c-20210220"><code>1.4c (2021/02/20)</code></a><ul>
+<li><a href="#bug-fixes-1">Bug fixes</a></li>
+</ul></li>
<li><a href="#b-20200225"><code>1.4b (2020/02/25)</code></a><ul>
<li><a href="#future">Future</a></li>
<li><a href="#new-features">New features</a></li>
-<li><a href="#bug-fixes-1">Bug fixes</a></li>
+<li><a href="#bug-fixes-2">Bug fixes</a></li>
</ul></li>
<li><a href="#a-20200219"><code>1.4a (2020/02/19)</code></a><ul>
-<li><a href="#breaking-changes">Breaking changes</a></li>
+<li><a href="#breaking-changes-1">Breaking changes</a></li>
<li><a href="#new-features-1">New features</a></li>
-<li><a href="#bug-fixes-2">Bug fixes</a></li>
+<li><a href="#bug-fixes-3">Bug fixes</a></li>
</ul></li>
<li><a href="#section"><code>1.4 (2020/01/31)</code></a><ul>
-<li><a href="#breaking-changes-1">Breaking changes</a></li>
+<li><a href="#breaking-changes-2">Breaking changes</a></li>
<li><a href="#improvements-and-new-features">Improvements and new features</a></li>
-<li><a href="#bug-fixes-3">Bug fixes</a></li>
+<li><a href="#bug-fixes-4">Bug fixes</a></li>
<li><a href="#todo">TODO</a></li>
</ul></li>
<li><a href="#f-20190910"><code>1.3f (2019/09/10)</code></a><ul>
<li><a href="#improvements-and-new-features-1">Improvements and new features</a></li>
-<li><a href="#bug-fixes-4">Bug fixes</a></li>
+<li><a href="#bug-fixes-5">Bug fixes</a></li>
</ul></li>
<li><a href="#e-20190405"><code>1.3e (2019/04/05)</code></a><ul>
-<li><a href="#breaking-changes-2">Breaking changes</a></li>
+<li><a href="#breaking-changes-3">Breaking changes</a></li>
<li><a href="#improvements-and-new-features-2">Improvements and new features</a></li>
-<li><a href="#bug-fixes-5">Bug fixes</a></li>
+<li><a href="#bug-fixes-6">Bug fixes</a></li>
</ul></li>
<li><a href="#d-20190106"><code>1.3d (2019/01/06)</code></a><ul>
-<li><a href="#breaking-changes-3">Breaking changes</a></li>
+<li><a href="#breaking-changes-4">Breaking changes</a></li>
<li><a href="#improvements-and-new-features-3">Improvements and new features</a></li>
-<li><a href="#bug-fixes-6">Bug fixes</a></li>
+<li><a href="#bug-fixes-7">Bug fixes</a></li>
</ul></li>
<li><a href="#c-20180617"><code>1.3c (2018/06/17)</code></a><ul>
<li><a href="#improvements-and-new-features-4">Improvements and new features</a></li>
-<li><a href="#bug-fixes-7">Bug fixes</a></li>
+<li><a href="#bug-fixes-8">Bug fixes</a></li>
</ul></li>
<li><a href="#b-20180518"><code>1.3b (2018/05/18)</code></a><ul>
<li><a href="#improvements-and-new-features-5">Improvements and new features</a></li>
@@ -73,85 +77,85 @@
<li><a href="#a-20180307"><code>1.3a (2018/03/07)</code></a><ul>
<li><a href="#removed">Removed</a></li>
<li><a href="#improvements-and-new-features-6">Improvements and new features</a></li>
-<li><a href="#bug-fixes-8">Bug fixes</a></li>
+<li><a href="#bug-fixes-9">Bug fixes</a></li>
</ul></li>
<li><a href="#section-1"><code>1.3 (2018/03/01)</code></a><ul>
-<li><a href="#breaking-changes-4">Breaking changes</a></li>
+<li><a href="#breaking-changes-5">Breaking changes</a></li>
<li><a href="#improvements-and-new-features-7">Improvements and new features</a></li>
</ul></li>
<li><a href="#q-20180206"><code>1.2q (2018/02/06)</code></a><ul>
<li><a href="#improvements-and-new-features-8">Improvements and new features</a></li>
-<li><a href="#bug-fixes-9">Bug fixes</a></li>
+<li><a href="#bug-fixes-10">Bug fixes</a></li>
</ul></li>
<li><a href="#p-20171205"><code>1.2p (2017/12/05)</code></a><ul>
-<li><a href="#breaking-changes-5">Breaking changes</a></li>
+<li><a href="#breaking-changes-6">Breaking changes</a></li>
<li><a href="#improvements-and-new-features-9">Improvements and new features</a></li>
-<li><a href="#bug-fixes-10">Bug fixes</a></li>
+<li><a href="#bug-fixes-11">Bug fixes</a></li>
</ul></li>
<li><a href="#o-20170829"><code>1.2o (2017/08/29)</code></a><ul>
-<li><a href="#breaking-changes-6">Breaking changes</a></li>
+<li><a href="#breaking-changes-7">Breaking changes</a></li>
<li><a href="#deprecated">Deprecated</a></li>
</ul></li>
<li><a href="#n-20170806"><code>1.2n (2017/08/06)</code></a><ul>
-<li><a href="#breaking-changes-7">Breaking changes</a></li>
+<li><a href="#breaking-changes-8">Breaking changes</a></li>
<li><a href="#improvements-and-new-features-10">Improvements and new features</a></li>
</ul></li>
<li><a href="#m-20170731"><code>1.2m (2017/07/31)</code></a><ul>
-<li><a href="#breaking-changes-8">Breaking changes</a></li>
+<li><a href="#breaking-changes-9">Breaking changes</a></li>
<li><a href="#improvements-and-new-features-11">Improvements and new features</a></li>
-<li><a href="#bug-fixes-11">Bug fixes</a></li>
+<li><a href="#bug-fixes-12">Bug fixes</a></li>
</ul></li>
<li><a href="#l-20170726"><code>1.2l (2017/07/26)</code></a><ul>
<li><a href="#removed-1">Removed</a></li>
<li><a href="#improvements-and-new-features-12">Improvements and new features</a></li>
-<li><a href="#bug-fixes-12">Bug fixes</a></li>
+<li><a href="#bug-fixes-13">Bug fixes</a></li>
</ul></li>
<li><a href="#k-20170106"><code>1.2k (2017/01/06)</code></a><ul>
-<li><a href="#breaking-changes-9">Breaking changes</a></li>
+<li><a href="#breaking-changes-10">Breaking changes</a></li>
<li><a href="#improvements-and-new-features-13">Improvements and new features</a></li>
-<li><a href="#bug-fixes-13">Bug fixes</a></li>
+<li><a href="#bug-fixes-14">Bug fixes</a></li>
</ul></li>
<li><a href="#j-20161222"><code>1.2j (2016/12/22)</code></a><ul>
<li><a href="#improvements-and-new-features-14">Improvements and new features</a></li>
-<li><a href="#bug-fixes-14">Bug fixes</a></li>
+<li><a href="#bug-fixes-15">Bug fixes</a></li>
</ul></li>
<li><a href="#i-20161213"><code>1.2i (2016/12/13)</code></a><ul>
-<li><a href="#breaking-changes-10">Breaking changes</a></li>
+<li><a href="#breaking-changes-11">Breaking changes</a></li>
<li><a href="#removed-2">Removed</a></li>
<li><a href="#improvements-and-new-features-15">Improvements and new features</a></li>
-<li><a href="#bug-fixes-15">Bug fixes</a></li>
+<li><a href="#bug-fixes-16">Bug fixes</a></li>
</ul></li>
<li><a href="#h-20161120"><code>1.2h (2016/11/20)</code></a><ul>
<li><a href="#improvements-and-new-features-16">Improvements and new features</a></li>
-<li><a href="#bug-fixes-16">Bug fixes</a></li>
+<li><a href="#bug-fixes-17">Bug fixes</a></li>
</ul></li>
<li><a href="#g-20160319"><code>1.2g (2016/03/19)</code></a><ul>
-<li><a href="#breaking-changes-11">Breaking changes</a></li>
+<li><a href="#breaking-changes-12">Breaking changes</a></li>
<li><a href="#improvements-and-new-features-17">Improvements and new features</a></li>
</ul></li>
<li><a href="#f-20160312"><code>1.2f (2016/03/12)</code></a><ul>
-<li><a href="#breaking-changes-12">Breaking changes</a></li>
+<li><a href="#breaking-changes-13">Breaking changes</a></li>
<li><a href="#improvements-and-new-features-18">Improvements and new features</a></li>
-<li><a href="#bug-fixes-17">Bug fixes</a></li>
+<li><a href="#bug-fixes-18">Bug fixes</a></li>
</ul></li>
<li><a href="#e-20151122"><code>1.2e (2015/11/22)</code></a><ul>
<li><a href="#improvements-and-new-features-19">Improvements and new features</a></li>
-<li><a href="#bug-fixes-18">Bug fixes</a></li>
+<li><a href="#bug-fixes-19">Bug fixes</a></li>
</ul></li>
<li><a href="#d-20151118"><code>1.2d (2015/11/18)</code></a><ul>
<li><a href="#improvements-and-new-features-20">Improvements and new features</a></li>
-<li><a href="#bug-fixes-19">Bug fixes</a></li>
+<li><a href="#bug-fixes-20">Bug fixes</a></li>
</ul></li>
<li><a href="#c-20151116"><code>1.2c (2015/11/16)</code></a><ul>
<li><a href="#improvements-and-new-features-21">Improvements and new features</a></li>
-<li><a href="#bug-fixes-20">Bug fixes</a></li>
+<li><a href="#bug-fixes-21">Bug fixes</a></li>
</ul></li>
<li><a href="#b-20151029"><code>1.2b (2015/10/29)</code></a><ul>
-<li><a href="#bug-fixes-21">Bug fixes</a></li>
+<li><a href="#bug-fixes-22">Bug fixes</a></li>
</ul></li>
<li><a href="#a-20151019"><code>1.2a (2015/10/19)</code></a><ul>
<li><a href="#improvements-and-new-features-22">Improvements and new features</a></li>
-<li><a href="#bug-fixes-22">Bug fixes</a></li>
+<li><a href="#bug-fixes-23">Bug fixes</a></li>
</ul></li>
<li><a href="#section-2"><code>1.2 (2015/10/10)</code></a><ul>
<li><a href="#removed-3">Removed</a></li>
@@ -161,11 +165,11 @@
<li><a href="#b-20150831"><code>1.1b (2015/08/31)</code></a></li>
<li><a href="#a-20141107"><code>1.1a (2014/11/07)</code></a></li>
<li><a href="#section-3"><code>1.1 (2014/10/28)</code></a><ul>
-<li><a href="#breaking-changes-13">Breaking changes</a></li>
+<li><a href="#breaking-changes-14">Breaking changes</a></li>
<li><a href="#removed-4">Removed</a></li>
<li><a href="#deprecated-1">Deprecated</a></li>
<li><a href="#improvements-and-new-features-24">Improvements and new features</a></li>
-<li><a href="#bug-fixes-23">Bug fixes</a></li>
+<li><a href="#bug-fixes-24">Bug fixes</a></li>
</ul></li>
<li><a href="#n-20140401"><code>1.09n (2014/04/01)</code></a></li>
<li><a href="#m-20140226"><code>1.09m (2014/02/26)</code></a></li>
@@ -193,13 +197,26 @@
<li><a href="#section-10"><code>1.0 (2013/03/28)</code></a></li>
</ul>
</nav>
-<pre><code>Source: xint.dtx 1.4c 2021/02/20 (doc 2021/02/20)
+<pre><code>Source: xint.dtx 1.4d 2021/03/29 (doc 2021/03/29)
Author: Jean-Francois Burnol
Info: Expandable operations on big integers, decimals, fractions
License: LPPL 1.3c</code></pre>
-<h2 id="c-20210220"><code>1.4c (2021/02/20)</code></h2>
+<h2 id="d-20210329"><code>1.4d (2021/03/29)</code></h2>
+<h3 id="breaking-changes">Breaking changes</h3>
+<ul>
+<li><p><code>quo()</code> and <code>rem()</code> in <code>\xintiiexpr/\xintiieval</code> renamed to <code>iquo()</code> and <code>irem()</code>.</p></li>
+<li><p>the output of <code>gcd()</code> and <code>lcm()</code> as applied to fractions is now always in lowest terms.</p></li>
+</ul>
<h3 id="bug-fixes">Bug fixes</h3>
<ul>
+<li><p>Ever since <code>1.3</code> the <code>quo()</code> and <code>rem()</code> functions in <code>\xintexpr</code> (not the ones in <code>\xintiiexpr</code>) were broken as their (officially deprecated) support macros had been removed! They had somewhat useless definitions anyway. They have now been officially removed from the syntax. Their siblings in <code>\xintiieval</code> were renamed to <code>iquo()</code> and <code>irem()</code>.</p></li>
+<li><p>Sadly, <code>gcd()</code> was broken in <code>\xintexpr</code> since <code>1.4</code>, if the first argument vanished. And <code>gcd()</code> was broken in <code>\xintiiexpr</code> since <code>1.3d</code> if <em>any</em> argument vanished. I did have a unit test! (which obviously was too limited …)</p>
+<p>Further, the <code>\xintGCDof</code> and <code>\xintLCMof</code> <strong>xintfrac</strong> macros were added at <code>1.4</code> but did not behave like other <strong>xintfrac</strong> macros with respect to parsing their arguments: e.g. <code>\xintGCDof{2}{03}</code> gave an unexpected non-numeric result.</p></li>
+<li><p>The <code>first()</code> and <code>last()</code> functions, if used as arguments to numerical functions such as <code>sqr()</code> inside an <code>\xintdeffunc</code> caused the defined function to be broken.</p></li>
+</ul>
+<h2 id="c-20210220"><code>1.4c (2021/02/20)</code></h2>
+<h3 id="bug-fixes-1">Bug fixes</h3>
+<ul>
<li>Fix <code>1.4</code> regression which broke syntax <code>varname(...)</code> which supposedly is allowed and inserts a tacit multiplication.</li>
</ul>
<h2 id="b-20200225"><code>1.4b (2020/02/25)</code></h2>
@@ -217,13 +234,13 @@ License: LPPL 1.3c</code></pre>
<li><p>Chaining of comparison operators (e.g. <code>x&lt;y&lt;z</code>) as in Python (but all comparisons are done even if one is found false) and l3fp.</p></li>
<li><p>It was possible since <code>1.4</code>’s <code>\xintFracToSciE</code> to configure the separator between mantissas and exponents in the output of <code>\xinteval</code> but strangely there was no way to customize the output of <code>\xintfloateval</code>. The added <code>\xintPFloatE</code> fixes this.</p></li>
</ul>
-<h3 id="bug-fixes-1">Bug fixes</h3>
+<h3 id="bug-fixes-2">Bug fixes</h3>
<ul>
<li><code>\xintieval{[D]...}</code> with a negative <code>D</code> (a feature added at <code>1.4a</code>) used erroneously a catcode 12 <code>e</code> in output, which moreover remained immuned to the <code>\xintFracToSciE</code> setting.</li>
</ul>
<h2 id="a-20200219"><code>1.4a (2020/02/19)</code></h2>
<p>All changes regard the <strong>xintexpr</strong> module.</p>
-<h3 id="breaking-changes">Breaking changes</h3>
+<h3 id="breaking-changes-1">Breaking changes</h3>
<ul>
<li>The macros implementing customization of <code>\xintthealign</code> have modified meanings and names.</li>
</ul>
@@ -233,13 +250,13 @@ License: LPPL 1.3c</code></pre>
<li><p>The optional argument <code>[D]</code> to <code>\xintieval/\xintiexpr</code> can be negative, with the same meaning as the non-negative case, i.e. rounding to an integer multiple of <code>10^(-D)</code>.</p>
<p>The same applies to the functions <code>trunc()</code> and <code>round()</code>. And to the <code>\xintTrunc</code>, <code>\xintRound</code>, <code>\xintiTrunc</code>, and <code>\xintiRound</code> macros of <strong>xintfrac</strong>.</p></li>
</ul>
-<h3 id="bug-fixes-2">Bug fixes</h3>
+<h3 id="bug-fixes-3">Bug fixes</h3>
<ul>
<li><p>Usage of <code>round()</code> and <code>trunc()</code> within <code>\xintdeffunc</code> got broken at <code>1.4</code>.</p></li>
<li><p><code>add()</code> and <code>mul()</code> were supposedly accepting the <code>omit</code>, <code>abort</code> and <code>break()</code> keywords since <code>1.4</code> but this was broken.</p></li>
</ul>
<h2 id="section"><code>1.4 (2020/01/31)</code></h2>
-<h3 id="breaking-changes-1">Breaking changes</h3>
+<h3 id="breaking-changes-2">Breaking changes</h3>
<p>Please note that this list may still be incomplete. If not otherly specified all items regard the <strong>xintexpr</strong> module.</p>
<ul>
<li><p>The <code>\expanded</code> primitive (TeXLive 2019) is <strong>required</strong>. This does not affect the macro layer <strong>xintcore</strong>, <strong>xint</strong>, <strong>xintfrac</strong>, <strong>xinttools</strong> (yet).</p></li>
@@ -285,7 +302,7 @@ License: LPPL 1.3c</code></pre>
<li><p>Function declarations are able to parse a much wider part of the syntax, but some severe limitations remain. Refer to the user manual for related information.</p></li>
<li><p>We have made an effort on some error messages, and when working interactively in a shell it may even be sometimes possible to insert for example a correct variable or function name in place of the not recognized one. But don’t expect miracles when trying to intervene in the midst of a purely expandable expansion…</p></li>
</ul>
-<h3 id="bug-fixes-3">Bug fixes</h3>
+<h3 id="bug-fixes-4">Bug fixes</h3>
<p>Bugs? Those identified in <code>1.3f</code> were almost features. As per <code>1.4</code> the code base of <strong>xintexpr</strong> received multiple successive core refactorings and added numerous new features, and our test suite although significantly enlarged is not yet extensive enough. Please report bugs by mail.</p>
<h3 id="todo">TODO</h3>
<ul>
@@ -301,13 +318,13 @@ License: LPPL 1.3c</code></pre>
<li><p><strong>xintexpr</strong>: add starred variants <code>\xintDigits*</code> and <code>\xintSetDigits*</code> which execute <code>\xintreloadxinttrig</code>.</p>
<p>Revert 1.3e ban on usage of <code>\xinteval</code> et al. inside expressions by <code>\xintdeffunc</code>. And make them usable also inside macro definitions via <code>\xintNewExpr</code>.</p></li>
</ul>
-<h3 id="bug-fixes-4">Bug fixes</h3>
+<h3 id="bug-fixes-5">Bug fixes</h3>
<ul>
<li><p><strong>xintexpr</strong>: fix bug preventing usage of <code>\xintdefefunc</code> to define a function without variables.</p>
<p>Fix some issue with <code>\xintfloatexpr[D]..\relax</code> if used inside an expression parsed by <code>\xintdeffunc</code> et al.</p></li>
</ul>
<h2 id="e-20190405"><code>1.3e (2019/04/05)</code></h2>
-<h3 id="breaking-changes-2">Breaking changes</h3>
+<h3 id="breaking-changes-3">Breaking changes</h3>
<ul>
<li>(<em>reverted at 1.3f</em>) When defining functions, sub-expressions can only use the <code>\xint(float)expr...\relax</code> syntax. One can not use there the <code>\xint(float)eval</code> wrappers.</li>
</ul>
@@ -321,12 +338,12 @@ License: LPPL 1.3c</code></pre>
<li><p><strong>xintexpr</strong>: <code>\xintensuredummy</code>, <code>\xintrestorelettervar</code>.</p></li>
<li><p>The optional argument of <code>\xintfloatexpr</code> or <code>\xintfloateval</code> (it must be at start of braced argument) can be negative; it then means to trim (and round) from the output at float precision that many least significant digits.</p></li>
</ul>
-<h3 id="bug-fixes-5">Bug fixes</h3>
+<h3 id="bug-fixes-6">Bug fixes</h3>
<ul>
<li>Some bugfixes related to user functions with no variables at all; they were dysfunctional.</li>
</ul>
<h2 id="d-20190106"><code>1.3d (2019/01/06)</code></h2>
-<h3 id="breaking-changes-3">Breaking changes</h3>
+<h3 id="breaking-changes-4">Breaking changes</h3>
<ul>
<li><p><strong>xintexpr</strong>: the <code>gcd()</code> and <code>lcm()</code> functions formerly converted their arguments to integers via <code>\xintNum</code>. They now handle general input with no such modification.</p></li>
<li><p><strong>xintexpr</strong>: former <code>\xinteval</code>, <code>\xintieval</code>, <code>\xintiieval</code>, and <code>\xintfloateval</code> renamed to <code>\xintexpro</code>, <code>\xintiexpro</code>, <code>\xintiiexpro</code>, and <code>\xintfloatexpro</code>.</p></li>
@@ -340,7 +357,7 @@ License: LPPL 1.3c</code></pre>
<li><p><strong>xintexpr</strong>: functions <code>isone()</code> and <code>isint()</code>.</p></li>
<li><p><strong>xintexpr</strong>: <code>\xinteval</code>, <code>\xintieval</code>, <code>\xintiieval</code>, and <code>\xintfloateval</code> as synonyms to <code>\xinttheexpr...\relax</code> etc…, but with the (comma-separated) expression as a usual braced macro argument.</p></li>
</ul>
-<h3 id="bug-fixes-6">Bug fixes</h3>
+<h3 id="bug-fixes-7">Bug fixes</h3>
<ul>
<li><strong>xintcore</strong>, <strong>xintexpr</strong> : division in <code>\xintiiexpr</code> was broken for a zero dividend and a one-digit divisor (e.g. <code>0//7</code>) since <code>1.2p</code> due to a bug in <code>\xintiiDivMod</code> for such arguments. The bug was signaled (thanks to Kpym for report) and fixed shortly after <code>1.3c</code> release but I then completely forgot to upload a bugfix release to CTAN at that time, apologies for that.</li>
</ul>
@@ -353,7 +370,7 @@ License: LPPL 1.3c</code></pre>
<li><p><strong>xintexpr</strong>: <code>\xintdefvar</code>, <code>\xintdeffunc</code> and their variants try to set the catcode of the semi-colon which delimits their arguments; of course this will not work if that catcode is already frozen.</p></li>
<li><p><code>\xintUniformDeviate</code> is better documented and <code>sourcexint.pdf</code> is better hyperlinked and includes indices for the macros defined by each package.</p></li>
</ul>
-<h3 id="bug-fixes-7">Bug fixes</h3>
+<h3 id="bug-fixes-8">Bug fixes</h3>
<ul>
<li><strong>xintfrac</strong>: since <code>1.3</code> release, it loaded <strong>xintgcd</strong> in contradiction to what the documentation says (hence also <strong>xintexpr</strong> loaded <strong>xintgcd</strong> automatically). There is no actual dependency so the loading is removed for now.</li>
</ul>
@@ -379,12 +396,12 @@ License: LPPL 1.3c</code></pre>
<li><p><strong>xintfrac</strong>: <code>\xintREZ</code> is faster on inputs having one hundred digits or more.</p></li>
<li><p>Added to the user manual mention of macros such as <code>\xintDivFloor</code>, <code>\xintMod</code>, <code>\xintModTrunc</code>, which had been left out so far.</p></li>
</ul>
-<h3 id="bug-fixes-8">Bug fixes</h3>
+<h3 id="bug-fixes-9">Bug fixes</h3>
<ul>
<li><strong>xintexpr</strong>: the mechanism for adjunction to the expression parsers of user defined functions was refactored and improved at previous release <code>1.3</code>: in particular recursive definitions became possible. But an oversight made these recursive functions quite inefficient (to remain polite.) This release fixes the problem.</li>
</ul>
<h2 id="section-1"><code>1.3 (2018/03/01)</code></h2>
-<h3 id="breaking-changes-4">Breaking changes</h3>
+<h3 id="breaking-changes-5">Breaking changes</h3>
<ul>
<li><p><strong>xintcore</strong>, <strong>xint</strong>, <strong>xintfrac</strong>: all macros deprecated at <code>1.2o</code> got removed.</p></li>
<li><p><strong>xintfrac</strong>: addition and subtraction of <code>a/b</code> and <code>c/d</code> now use the l.c.m. of the denominators. Similarly the macro supporting the modulo operator <code>/:</code> uses a l.c.m. for the denominator of the result.</p></li>
@@ -402,12 +419,12 @@ License: LPPL 1.3c</code></pre>
<ul>
<li><strong>xintexpr</strong>: tacit multiplication extended to cases such as <code>3!4!5!</code> or <code>(1+2)3</code>.</li>
</ul>
-<h3 id="bug-fixes-9">Bug fixes</h3>
+<h3 id="bug-fixes-10">Bug fixes</h3>
<ul>
<li><strong>xintcore</strong>: sadly, refactoring at <code>1.2l</code> of subtraction left an extra character in an inner macro causing breakage in some rare circumstances. This should not have escaped our test suite!</li>
</ul>
<h2 id="p-20171205"><code>1.2p (2017/12/05)</code></h2>
-<h3 id="breaking-changes-5">Breaking changes</h3>
+<h3 id="breaking-changes-6">Breaking changes</h3>
<ul>
<li><p><strong>xintgcd</strong>: <code>\xintBezout{a}{b}</code>’s output consists of <code>{u}{v}{d}</code> with <code>u*a+v*b==d</code>, with <code>d</code> the GCD. Formerly it was <code>{a}{b}{u}{v}{d}</code>, and with <code>u*a-v*b==d</code>.</p></li>
<li><p><strong>xintgcd</strong>: <code>\xintBezout{0}{0}</code> expands to <code>{0}{0}{0}</code>. Formerly (since <code>1.2l</code>) it raised <code>InvalidOperation</code>.</p></li>
@@ -421,7 +438,7 @@ License: LPPL 1.3c</code></pre>
<li><p><strong>xintexpr</strong>: <code>\xintdefvar</code>’s syntax is extended to allow simultaneous assignments. Examples: <code>\xintdefvar x1, x2, x3 := 1, 3**10, 3**20;</code> or <code>\xintdefiivar A, B := B, A 'mod' B;</code> for already defined variables <code>A</code> and <code>B</code>.</p></li>
<li><p><strong>xintexpr</strong>: added <code>divmod()</code> to the built-in functions. It is associated with floored division, like the Python language <code>divmod()</code>. Related support macros added to <strong>xintcore</strong>, and <strong>xintfrac</strong>.</p></li>
</ul>
-<h3 id="bug-fixes-10">Bug fixes</h3>
+<h3 id="bug-fixes-11">Bug fixes</h3>
<ul>
<li><p><strong>xintgcd</strong>: <code>\xintBezout{6}{3}</code> (for example) expanded to <code>{6}{3}{-0}{-1}{3}</code>, but the <code>-0</code> should have been <code>0</code>.</p></li>
<li><p><strong>xintgcd</strong>: it still used macro <code>\xintiAbs</code> although the latter had been deprecated from <strong>xintcore</strong>.</p></li>
@@ -429,7 +446,7 @@ License: LPPL 1.3c</code></pre>
<li><p>various documentation fixes; in particular, the partial dependency of <strong>xintcfrac</strong> on <strong>xinttools</strong> had not been mentioned.</p></li>
</ul>
<h2 id="o-20170829"><code>1.2o (2017/08/29)</code></h2>
-<h3 id="breaking-changes-6">Breaking changes</h3>
+<h3 id="breaking-changes-7">Breaking changes</h3>
<ul>
<li><strong>xint</strong>: <code>\xintAND</code>, <code>\xintOR</code>, … and similar Boolean logic macros do not apply anymore <code>\xintNum</code> (or <code>\xintRaw</code> if <strong>xintfrac</strong> is loaded), to their arguments (often, from internal usage of <code>\xintSgn</code>), but only f-expand them (using e.g. <code>\xintiiSgn</code>). This is kept un-modified even if loading <strong>xintfrac</strong>.</li>
</ul>
@@ -445,7 +462,7 @@ License: LPPL 1.3c</code></pre>
<li><p><strong>xint</strong>: <code>\xintNot</code> was renamed to <code>\xintNOT</code>, former denomination is deprecated. See also item about Boolean logic macros in the <em>Incompatible Changes</em> section.</p></li>
</ul>
<h2 id="n-20170806"><code>1.2n (2017/08/06)</code></h2>
-<h3 id="breaking-changes-7">Breaking changes</h3>
+<h3 id="breaking-changes-8">Breaking changes</h3>
<ul>
<li><strong>xintbinhex</strong> does not load package <strong>xintcore</strong> anymore, but only <strong>xintkernel</strong>.</li>
</ul>
@@ -455,7 +472,7 @@ License: LPPL 1.3c</code></pre>
<li><p>Macros of <strong>xintbinhex</strong> have been improved for speed and increased maximal sizes of allowable inputs.</p></li>
</ul>
<h2 id="m-20170731"><code>1.2m (2017/07/31)</code></h2>
-<h3 id="breaking-changes-8">Breaking changes</h3>
+<h3 id="breaking-changes-9">Breaking changes</h3>
<ul>
<li><p><strong>xintbinhex</strong>: the length of the input is now limited. The maximum size depends on the macro and ranges from about <code>4000</code> to about <code>19900</code> digits.</p></li>
<li><p><strong>xintbinhex</strong>: <code>\xintCHexToBin</code> is now the variant of <code>\xintHexToBin</code> which does not remove leading binary zeroes: <code>N</code> hex-digits give on output exactly <code>4N</code> binary digits.</p></li>
@@ -464,7 +481,7 @@ License: LPPL 1.3c</code></pre>
<ul>
<li><strong>xintbinhex</strong>: all macros have been rewritten using techniques from the 1.2 release (they had remained unmodified since <code>1.08</code> of <code>2013/06/07</code>.) The new macros are faster but limited to a few thousand digits. The <code>1.08</code> routines could handle tens of thousands of digits, but not in a reasonable time.</li>
</ul>
-<h3 id="bug-fixes-11">Bug fixes</h3>
+<h3 id="bug-fixes-12">Bug fixes</h3>
<ul>
<li><p>user manual: the <code>Changes</code> section wrongly stated at <code>1.2l</code> that the macros of <strong>xintbinhex</strong> had been made robust against non terminated input such as <code>\number\mathcode`\-</code>. Unfortunately the author fell into the trap of believing his own documentation and he forgot to actually implement the change. Now done.</p></li>
<li><p>user manual: the PDF bookmarks were messed up.</p></li>
@@ -485,14 +502,14 @@ License: LPPL 1.3c</code></pre>
<p>The situation with expressions is unchanged: syntax such as <code>\xintexpr \numexpr1+2\relax</code> is illegal as the ending <code>\relax</code> token will get swallowed by the <code>\numexpr</code>; but it is needed by the <code>xintexpr</code>-ession parser, hence the parser will expand forward and presumably end with in an “illegal token” error, or provoke some low-level TeX error (N.B.: a closing brace <code>}</code> for example can not terminate an <code>xintexpr</code>-ession, the parser must find a <code>\relax</code> token at some point). Thus there must be in this example a second <code>\relax</code>.</p></li>
<li><p>experimental code for error conditions; there is no complete user interface yet, it is done in preparation for next major release and is completely unstable and undocumented.</p></li>
</ul>
-<h3 id="bug-fixes-12">Bug fixes</h3>
+<h3 id="bug-fixes-13">Bug fixes</h3>
<ul>
<li><p><strong>xintbinhex</strong>: since <code>1.2 (2015/10/10)</code>, <code>\xintHexToDec</code> was broken due to an undefined macro (it was in <code>xint.sty</code>, but the module by itself is supposedly dependent only upon <code>xintcore.sty</code>).</p></li>
<li><p><strong>xintgcd</strong>: macro <code>\xintBezout</code> produced partially wrong output if one of its two arguments was zero.</p></li>
<li><p><strong>xintfrac</strong>: the manual said one could use directly <code>\numexpr</code> compatible expressions in arithmetic macros (without even a <code>\numexpr</code> encapsulation) if they were expressed with up to 8 tokens. There was a bug if these 8 tokens evaluated to zero. The bug has been fixed, and up to 9 tokens are now accepted. But it is simpler to use <code>\the\numexpr</code> prefix and not to worry about the token count… The ending <code>\relax</code> is now un-needed.</p></li>
</ul>
<h2 id="k-20170106"><code>1.2k (2017/01/06)</code></h2>
-<h3 id="breaking-changes-9">Breaking changes</h3>
+<h3 id="breaking-changes-10">Breaking changes</h3>
<ul>
<li><p>macro <code>\xintFloat</code> which rounds its input to a floating point number does <em>not</em> print anymore <code>10.0...0eN</code> to signal an upwards rounding to the next power of ten. The mantissa has in all cases except the zero input exactly one digit before the decimal mark.</p></li>
<li><p>some floating point computations may differ in the least significant digits, due to a change in the rounding algorithm applied to macro arguments expressed as fractions and to an improvement in precision regarding half-integer powers in expressions. See next.</p></li>
@@ -504,7 +521,7 @@ License: LPPL 1.3c</code></pre>
<li><p>added <code>\xintiSqrtR</code>, there was only <code>\xintiiSqrtR</code> alongside <code>\xintiSqrt</code> and <code>\xintiiSqrt</code> (<strong>xint</strong>).</p></li>
<li><p>added non public <code>\xintLastItem:f:csv</code> to <strong>xinttools</strong> for faster <code>last()</code> function, and improved <code>\xintNewExpr</code> compatibility. Also <code>\xintFirstItem:f:csv</code>.</p></li>
</ul>
-<h3 id="bug-fixes-13">Bug fixes</h3>
+<h3 id="bug-fixes-14">Bug fixes</h3>
<ul>
<li><p>the <code>1.2f</code> half-integer powers computed within <code>\xintfloatexpr</code> had a silly rounding to the target precision just <em>before</em> the final square-root extraction, thus possibly losing some precision. The <code>1.2k</code> implementation keeps guard digits for this final square root extraction. As for integer exponents, it is guaranteed that the computed value differs from the exact one by less than <code>0.52 ulp</code> (for inputs having at most <code>\xinttheDigits</code> digits.)</p></li>
<li><p>more regressions from <code>1.2i</code> were fixed: <code>\xintLen</code> (<strong>xint</strong>, <strong>xintfrac</strong>) and <code>\xintDouble</code> (<strong>xintcore</strong>) had forgotten that their argument was allowed to be negative. A regression test suite is now in place and is being slowly expanded to cover more macros.</p></li>
@@ -520,12 +537,12 @@ License: LPPL 1.3c</code></pre>
</ol></li>
<li><p>significant documentations tweaks (inclusive of suppressing things!), and among them two beautiful hyperlinked tables with both horizontal and vertical rules which bring the documentation of the <strong>xintexpr</strong> syntax to a kind of awe-inspiring perfection… except that implementation of some math functions is still lacking.</p></li>
</ul>
-<h3 id="bug-fixes-14">Bug fixes</h3>
+<h3 id="bug-fixes-15">Bug fixes</h3>
<ul>
<li>fix two <code>1.2i</code> regressions caused by undefined macros (<code>\xintNthElt</code> in certain branches and <code>[list][N]</code> item extraction in certain cases.) The test files existed but were not executed prior to release. Automation in progress.</li>
</ul>
<h2 id="i-20161213"><code>1.2i (2016/12/13)</code></h2>
-<h3 id="breaking-changes-10">Breaking changes</h3>
+<h3 id="breaking-changes-11">Breaking changes</h3>
<ul>
<li><code>\xintDecSplit</code> second argument must have no sign (former code replaced it with its absolute value, a sign now may cause an error.)</li>
</ul>
@@ -552,7 +569,7 @@ License: LPPL 1.3c</code></pre>
<li><p>the documentation has again been (slightly) re-organized; it has a new sub-section on the Miller-Rabin primality test, to illustrate some use of <code>\xintNewFunction</code> for recursive definitions.</p></li>
<li><p>the documentation has dropped the LaTeX “command” terminology (which had been used initially in 2013 for some forgotten reasons and should have been removed long ago) and uses only the more apt “macro”, as after all, all of <strong>xint</strong> is about expansion of macros (plus the use of <code>\numexpr</code>).</p></li>
</ul>
-<h3 id="bug-fixes-15">Bug fixes</h3>
+<h3 id="bug-fixes-16">Bug fixes</h3>
<ul>
<li><code>\xintDecSplitL</code> and <code>\xintDecSplitR</code> from <strong>xint</strong> produced their output in a spurious brace pair (bug introduced in <code>1.2f</code>).</li>
</ul>
@@ -562,7 +579,7 @@ License: LPPL 1.3c</code></pre>
<li><p>new macro <code>\xintNewFunction</code> in <strong>xintexpr</strong> which allows to extend the parser syntax with functions in situations where <code>\xintdeffunc</code> is not usable (typically, because dummy variables are used over a not yet determined range of values because it depends on the variables).</p></li>
<li><p>after three years of strict obedience to <code>xint</code> prefix, now <code>\thexintexpr</code>, <code>\thexintiexpr</code>, <code>\thexintfloatexpr</code>, and <code>\thexintiiexpr</code> are provided as synonyms to <code>\xinttheexpr</code>, etc…</p></li>
</ul>
-<h3 id="bug-fixes-16">Bug fixes</h3>
+<h3 id="bug-fixes-17">Bug fixes</h3>
<ul>
<li><p>the <code>(cond)?{foo}{bar}</code> operator from <strong>xintexpr</strong> mis-behaved in certain circumstances (such as an empty <code>foo</code>).</p></li>
<li><p>the <strong>xintexpr</strong> <code>1.2f</code> <code>binomial</code> function (which uses <code>\xintiiBinomial</code> from <strong>xint.sty</strong> or <code>\xintFloatBinomial</code> from <strong>xintfrac.sty</strong>) deliberately raised an error for <code>binomial(x,y)</code> with <code>y&lt;0</code> or <code>x&lt;y</code>. This was unfortunate, and it now simply evaluates to zero in such cases.</p></li>
@@ -570,7 +587,7 @@ License: LPPL 1.3c</code></pre>
<li><p>the <code>add</code> and <code>mul</code> from <strong>xintexpr</strong>, which work with dummy variables since <code>1.1</code>, raised an error since <code>1.2c 2015/11/16</code> when the dummy variable was given an empty range (or list) of values, rather than producing respectively <code>0</code> and <code>1</code> as formerly.</p></li>
</ul>
<h2 id="g-20160319"><code>1.2g (2016/03/19)</code></h2>
-<h3 id="breaking-changes-11">Breaking changes</h3>
+<h3 id="breaking-changes-12">Breaking changes</h3>
<ul>
<li><p>inside expressions, list item selector <code>[L][n]</code> counts starting at zero, not at one. This is more coherent with <code>[L][a:b]</code> which was already exactly like in Python since its introduction. A function len(L) replaces earlier <code>[L][0]</code>.</p></li>
<li><p>former <code>iter</code> keyword now called <code>iterr</code>. Indeed it matched with <code>rrseq</code>, the new <code>iter</code> (which was somehow missing from <code>1.1</code>) is the one matching <code>rseq</code>. Allows to iterate more easily with a “list” variable.</p></li>
@@ -584,7 +601,7 @@ License: LPPL 1.3c</code></pre>
<li><p>the syntax of expressions is described in a devoted chapter of the documentation; an example shows how to implement (expandably) the Brent-Salamin algorithm for computation of Pi using <code>iter</code> in a float expression.</p></li>
</ul>
<h2 id="f-20160312"><code>1.2f (2016/03/12)</code></h2>
-<h3 id="breaking-changes-12">Breaking changes</h3>
+<h3 id="breaking-changes-13">Breaking changes</h3>
<ul>
<li>no more <code>\xintFac</code> macro but <code>\xintiFac/\xintiiFac/\xintFloatFac</code>.</li>
</ul>
@@ -602,7 +619,7 @@ License: LPPL 1.3c</code></pre>
<li><p>(TeXperts only) the macros defined (internally) from <code>\xintdeffunc</code> et al. constructs do not incorporate an initial <code>\romannumeral</code> anymore.</p></li>
<li><p>renewed desperate efforts at improving the documentation by random shuffling of sections and well thought additions; cuts were considered and even performed.</p></li>
</ul>
-<h3 id="bug-fixes-17">Bug fixes</h3>
+<h3 id="bug-fixes-18">Bug fixes</h3>
<ul>
<li><p>squaring macro <code>\xintSqr</code> from <strong>xintfrac.sty</strong> was broken due to a misspelled sub-macro name. Dates back to <code>1.1</code> release of <code>2014/10/28</code> <code>:-((</code>.</p></li>
<li><p><code>1.2c</code>’s fix to the subtraction bug from <code>1.2</code> introduced another bug, which in some cases could create leading zeroes in the output, or even worse. This could invalidate other routines using subtractions, like <code>\xintiiSquareRoot</code>.</p></li>
@@ -616,7 +633,7 @@ License: LPPL 1.3c</code></pre>
<li><p>a space in <code>\xintdeffunc f(x)&lt;space&gt;:= expression ;</code> is now accepted.</p></li>
<li><p>documentation enhancements: the <em>Quick Sort</em> section with its included code samples has been entirely re-written; the <em>Commands of the xintexpr package</em> section has been extended and reviewed entirely.</p></li>
</ul>
-<h3 id="bug-fixes-18">Bug fixes</h3>
+<h3 id="bug-fixes-19">Bug fixes</h3>
<ul>
<li><p>in <strong>xintfrac</strong>: the <code>\xintFloatFac</code> from release <code>1.2</code> parsed its argument only through <code>\numexpr</code> but it should have used <code>\xintNum</code>.</p></li>
<li><p>in <strong>xintexpr</strong>: release <code>1.2d</code> had broken the recognition of sub-expressions immediately after variable names (with tacit multiplication).</p></li>
@@ -629,7 +646,7 @@ License: LPPL 1.3c</code></pre>
<li><p>tacit multiplication applies to more cases, for example (x+y)z, and always ties more than standard * infix operator, e.g. x/2y is like x/(2*y).</p></li>
<li><p>some documentation enhancements, particularly in the chapter on xintexpr.sty, and also in the code source comments.</p></li>
</ul>
-<h3 id="bug-fixes-19">Bug fixes</h3>
+<h3 id="bug-fixes-20">Bug fixes</h3>
<ul>
<li>in <strong>xintcore</strong>: release <code>1.2c</code> had inadvertently broken the <code>\xintiiDivRound</code> macro.</li>
</ul>
@@ -639,12 +656,12 @@ License: LPPL 1.3c</code></pre>
<li><p>macros <code>\xintdeffunc</code>, <code>\xintdefiifunc</code>, <code>\xintdeffloatfunc</code> and boolean <code>\ifxintverbose</code>.</p></li>
<li><p>on-going code improvements and documentation enhancements, but stopped in order to issue this bugfix release.</p></li>
</ul>
-<h3 id="bug-fixes-20">Bug fixes</h3>
+<h3 id="bug-fixes-21">Bug fixes</h3>
<ul>
<li>in <strong>xintcore</strong>: recent release <code>1.2</code> introduced a bug in the subtraction (happened when 00000001 was found under certain circumstances at certain mod 8 locations).</li>
</ul>
<h2 id="b-20151029"><code>1.2b (2015/10/29)</code></h2>
-<h3 id="bug-fixes-21">Bug fixes</h3>
+<h3 id="bug-fixes-22">Bug fixes</h3>
<ul>
<li>in <strong>xintcore</strong>: recent release <code>1.2</code> introduced a bug in the division macros, causing a crash when the divisor started with 99999999 (it was attempted to use with 1+99999999 a subroutine expecting only 8-digits numbers).</li>
</ul>
@@ -655,7 +672,7 @@ License: LPPL 1.3c</code></pre>
<li><p>added <code>\xintiiMaxof/\xintiiMinof</code> (<strong>xint</strong>).</p></li>
<li><p>TeX hackers only: replaced all code uses of <code>\romannumeral-`0</code> by the quicker <code>\romannumeral`&amp;&amp;@</code> (<code>^</code> being used as letter, had to find another character usable with catcode 7).</p></li>
</ul>
-<h3 id="bug-fixes-22">Bug fixes</h3>
+<h3 id="bug-fixes-23">Bug fixes</h3>
<ul>
<li>in <strong>xintexpr</strong>: recent release <code>1.2</code> introduced a bad bug in the parsing of decimal numbers and as a result <code>\xinttheexpr 0.01\relax</code> expanded to <code>0</code> ! (sigh…)</li>
</ul>
@@ -698,7 +715,7 @@ License: LPPL 1.3c</code></pre>
<li><p>various typographical fixes throughout the documentation, and a bit of clean up of the code comments. Improved <code>\Factors</code> example of nested <code>subs</code>, <code>rseq</code>, <code>iter</code> in <code>\xintiiexpr</code>.</p></li>
</ul>
<h2 id="section-3"><code>1.1 (2014/10/28)</code></h2>
-<h3 id="breaking-changes-13">Breaking changes</h3>
+<h3 id="breaking-changes-14">Breaking changes</h3>
<ul>
<li><p>in <code>\xintiiexpr</code>, <code>/</code> does <em>rounded</em> division, rather than the Euclidean division (for positive arguments, this is truncated division). The <code>//</code> operator does truncated division,</p></li>
<li><p>the <code>:</code> operator for three-way branching is gone, replaced with <code>??</code>,</p></li>
@@ -756,7 +773,7 @@ License: LPPL 1.3c</code></pre>
<li><p><code>\xintthecoords</code> converts a comma separated list of an even number of items to the format expected by the <code>TikZ</code> <code>coordinates</code> syntax,</p></li>
<li><p>completely new version <code>\xintNewExpr</code>, <code>protect</code> function to handle external macros. The dollar sign <code>$</code> for place holders is not accepted anymore, only the standard macro parameter <code>#</code>. Not all constructs are compatible with <code>\xintNewExpr</code>.</p></li>
</ul>
-<h3 id="bug-fixes-23">Bug fixes</h3>
+<h3 id="bug-fixes-24">Bug fixes</h3>
<ul>
<li><p><code>\xintZapFirstSpaces</code> hence also <code>\xintZapSpaces</code> from package <strong>xinttools</strong> were buggy when used with an argument either empty or containing only space tokens.</p></li>
<li><p><code>\xintiiexpr</code> did not strip leading zeroes, hence <code>\xinttheiiexpr 001+1\relax</code> did not obtain the expected result …</p></li>
diff --git a/macros/generic/xint/README.md b/macros/generic/xint/README.md
index bb01bbb277..a9dcafa44a 100644
--- a/macros/generic/xint/README.md
+++ b/macros/generic/xint/README.md
@@ -1,8 +1,8 @@
% README
-% xint 1.4c
-% 2021/02/20
+% xint 1.4d
+% 2021/03/29
- Source: xint.dtx 1.4c 2021/02/20 (doc 2021/02/20)
+ Source: xint.dtx 1.4d 2021/03/29 (doc 2021/03/29)
Author: Jean-Francois Burnol
Info: Expandable operations on big integers, decimals, fractions
License: LPPL 1.3c
@@ -101,7 +101,7 @@ is a functionality of all major TeX engines since TeXLive 2019.
License
=======
-Copyright (C) 2013-2020 by Jean-Francois Burnol
+Copyright (C) 2013-2021 by Jean-Francois Burnol
This Work may be distributed and/or modified under the
conditions of the LaTeX Project Public License version 1.3c.
diff --git a/macros/generic/xint/sourcexint.pdf b/macros/generic/xint/sourcexint.pdf
index 6c9a354b0b..0e99479d7c 100644
--- a/macros/generic/xint/sourcexint.pdf
+++ b/macros/generic/xint/sourcexint.pdf
Binary files differ
diff --git a/macros/generic/xint/xint.dtx b/macros/generic/xint/xint.dtx
index 8a6a882ba8..6b5ff7588c 100644
--- a/macros/generic/xint/xint.dtx
+++ b/macros/generic/xint/xint.dtx
@@ -3,28 +3,28 @@
% Extract all files via "etex xint.dtx" and do "make help"
% or follow instructions from extracted README.md.
%<*dtx>
-\def\xintdtxtimestamp {Time-stamp: <20-02-2021 at 20:47:06 CET>}
+\def\xintdtxtimestamp {Time-stamp: <29-03-2021 at 11:06:25 CEST>}
%</dtx>
%<*drv>
%% ---------------------------------------------------------------
-\def\xintdocdate {2021/02/20}
-\def\xintbndldate{2021/02/20}
-\def\xintbndlversion {1.4c}
+\def\xintdocdate {2021/03/29}
+\def\xintbndldate{2021/03/29}
+\def\xintbndlversion {1.4d}
%</drv>
%<readme>% README
%<changes>% CHANGE LOG
-%<readme|changes>% xint 1.4c
-%<readme|changes>% 2021/02/20
+%<readme|changes>% xint 1.4d
+%<readme|changes>% 2021/03/29
%<readme|changes>
-%<readme|changes> Source: xint.dtx 1.4c 2021/02/20 (doc 2021/02/20)
+%<readme|changes> Source: xint.dtx 1.4d 2021/03/29 (doc 2021/03/29)
%<readme|changes> Author: Jean-Francois Burnol
%<readme|changes> Info: Expandable operations on big integers, decimals, fractions
%<readme|changes> License: LPPL 1.3c
%<readme|changes>
%<*!readme&!changes&!dohtmlsh&!makefile>
%% ---------------------------------------------------------------
-%% The xint bundle 1.4c 2021/02/20
-%% Copyright (C) 2013-2020 by Jean-Francois Burnol
+%% The xint bundle 1.4d 2021/03/29
+%% Copyright (C) 2013-2021 by Jean-Francois Burnol
%<xintkernel>%% xintkernel: Paraphernalia for the xint packages
%<xinttools>%% xinttools: Expandable and non-expandable utilities
%<xintcore>%% xintcore: Expandable arithmetic on big integers
@@ -137,7 +137,7 @@ is a functionality of all major TeX engines since TeXLive 2019.
License
=======
-Copyright (C) 2013-2020 by Jean-Francois Burnol
+Copyright (C) 2013-2021 by Jean-Francois Burnol
This Work may be distributed and/or modified under the
conditions of the LaTeX Project Public License version 1.3c.
@@ -161,6 +161,40 @@ See `xint.pdf` for contact information.
%</readme>--------------------------------------------------------
%<*changes>-------------------------------------------------------
+`1.4d (2021/03/29)`
+----
+
+### Breaking changes
+
+ - `quo()` and `rem()` in `\xintiiexpr/\xintiieval` renamed to
+ `iquo()` and `irem()`.
+
+ - the output of `gcd()` and `lcm()` as applied to fractions is now
+ always in lowest terms.
+
+### Bug fixes
+
+ - Ever since `1.3` the `quo()` and `rem()` functions in `\xintexpr`
+ (not the ones in `\xintiiexpr`) were broken as their (officially
+ deprecated) support macros had been removed! They had somewhat
+ useless definitions anyway. They have now been officially removed
+ from the syntax. Their siblings in `\xintiieval` were renamed to
+ `iquo()` and `irem()`.
+
+ - Sadly, `gcd()` was broken in `\xintexpr` since `1.4`, if the first
+ argument vanished. And `gcd()` was broken in `\xintiiexpr` since
+ `1.3d` if *any* argument vanished. I did have a unit test! (which
+ obviously was too limited ...)
+
+ Further, the `\xintGCDof` and `\xintLCMof` **xintfrac** macros were
+ added at `1.4` but did not behave like other **xintfrac** macros with
+ respect to parsing their arguments: e.g. `\xintGCDof{2}{03}` gave an
+ unexpected non-numeric result.
+
+ - The `first()` and `last()` functions, if used as arguments to
+ numerical functions such as `sqr()` inside an `\xintdeffunc`
+ caused the defined function to be broken.
+
`1.4c (2021/02/20)`
----
@@ -3577,6 +3611,8 @@ pdfpagemode=UseNone,%
% ===============
% \ttzfamily done at begin document
+\newcommand\ctanpackage[1]{\href{https://ctan.org/pkg/#1}{#1}}
+
\begin{document}\thispagestyle{empty}
\pdfbookmark[1]{Title page}{TOP}
\def\partname{Part}
@@ -3805,16 +3841,16 @@ pdfpagemode=UseNone,%
\node [right of=kernel] (B) {};
\node [block, below right of=B] (core) {\xintcorename};
\node [block, below left of=A] (tools) {\xinttoolsname};
- \node [block, right of=core, xshift=1cm] (bnumexpr) {\href{https://ctan.org/pkg/bnumexpr}{bnumexpr}};
+ \node [block, right of=core, xshift=1cm] (bnumexpr) {\ctanpackage{bnumexpr}};
\node [block, below of=core] (xint) {\xintname};
\node [block, left of=xint, xshift=-1cm] (gcd) {\xintgcdname};
\node [block, left of=gcd] (binhex) {\xintbinhexname};
\node [block, below of=xint] (frac) {\xintfracname};
\node [block, below of=frac, yshift=-.5cm] (expr) {\xintexprname};
- \node [block, below right of=expr, yshift=-.5cm, xshift=2.25cm] (polexpr) {\href{https://ctan.org/pkg/polexpr}{polexpr}};
+ \node [block, below right of=expr, yshift=-.5cm, xshift=2.25cm] (polexpr) {\ctanpackage{polexpr}};
\node [block, below of=expr, yshift=-.5cm] (trig) {\xinttrigname};
\node [block, left of=trig] (log) {\xintlogname};
- \node [block, left of=log, xshift=-1cm] (poormanlog) {\href{https://ctan.org/pkg/poormanlog}{poormanlog}};
+ \node [block, left of=log, xshift=-1cm] (poormanlog) {\ctanpackage{poormanlog}};
\node [block, below right of=frac, xshift=1cm] (series) {\xintseriesname};
\node [block, right of=series] (cfrac) {\xintcfracname};
% Draw edges
@@ -3857,17 +3893,17 @@ pdfpagemode=UseNone,%
functionalities of the lower module it is thus necessary to use
a suitable |\usepackage| (\LaTeX) or |\input| (Plain \TeX.)\par
- \href{https://ctan.org/pkg/bnumexpr}{bnumexpr} is a
+ \ctanpackage{bnumexpr} is a
separate (\LaTeX{} only) package by the author which uses (by default)
\xintcorename as its mathematical engine.
- \href{https://ctan.org/pkg/polexpr}{polexpr} is a
+ \ctanpackage{polexpr} is a
separate (\LaTeX{} only) package by the author which requires \xintexprname.
\xinttrigname and \xintlogname are loaded automatically by \xintexprname; they
will refuse to be loaded directly (but see \csbxint{reloadxinttrig}).
- \href{https://ctan.org/pkg/poormanlog}{poormanlog} is a \TeX{} and
+ \ctanpackage{poormanlog} is a \TeX{} and
\LaTeX{} package by the author which is loaded automatically by \xintlogname.
\par
\end{addmargin}
@@ -3949,6 +3985,49 @@ quality of the document). Reports welcome.%
\footnote{Thanks to Jürgen Gilg for keeping the author motivated and
helping proof-read the documentation.}
+\subsection{Known bugs/features at \texttt{1.4d}}
+
+\begin{description}
+\item[if(100>0,(100,125),(100,128)) breaks my code:]
+%
+ This is a feature. This is a syntax error, as the comma serves to contatenate
+ "oples" (see \autoref{oples}), so it is parsed to behave as
+\begin{everbatim}
+ if(100>0,100,125,100,128)
+\end{everbatim}
+ which is an error as \func{if} requires exactly three arguments, not
+ five. Use:
+\begin{everbatim}
+ if(100>0,[100,125],[100,128])
+\end{everbatim}
+ which will expand to the "tuple" |[100,125]|.
+\item[{\detokenize{\xintdeffunc foo(x):= gcd((x>0)?{[x,125]}{[x,128]});}
+ creates a broken function:}]
+%
+ Bug. Normally \func{gcd} (and other
+ multi-arguments functions) work both with open lists of arguments or
+ bracketed lists ("nutples") and the above syntax would work perfectly fine
+ in numerical context. But the presence of the \oper{?} breaks in
+ \csbxint{deffunc} context the flexibility of \func{gcd}.
+
+ Currently working alternatives:
+\begin{everbatim}
+\xintdeffunc foo(x) := gcd(if(x>0, [x,125], [x,128]));
+\xintdeffunc foo(x) := if(x>0, gcd(x,125), gcd(x,128));
+\xintdeffunc foo(x) := if(x>0, gcd([x,125]), gcd([x,128]));
+\xintdeffunc foo(x) := gcd((x>0)?{x,125}{x,128});
+\xintdeffunc foo(x) := (x>0)?{gcd(x,125)}{gcd(x,128)};
+\xintdeffunc foo(x) := (x>0)?{gcd([x,125])}{gcd([x,128])};
+\end{everbatim}
+ The same problem will arise with an \oper{??} nested inside \func{gcd} or
+ similar functions, in an \csbxint{deffunc}.
+\end{description}
+
+If the list stops here, it is probably only because I have not tested enough
+yet. But it is already mentioned in the \csbxint{deffunc} documentation that
+it can not parse currently the entirety of the available purely numerical
+syntax, some documented limitations apply.
+
\subsection{Features added since the \texttt{1.4} release}
For bugfixes and possibly more details check |CHANGES.html|:
@@ -4095,7 +4174,8 @@ The rendering here uses extra decoration.
\localtableofcontents
-\subsection{Oples and nut-ples: terminology for the \text{1.4} \xintname generation}
+
+\subsection{Oples and nutples: terminology for the \text{1.4} \xintname generation}\label{oples}
\emph{Skip this on first reading, else you will never start using the
package.} \fbox{SKIP THIS!} (understood?)
@@ -4145,7 +4225,7 @@ input syntax, Python |lists|), or \emph{packing} (as a reverse to Python's
unpacking of sequence type objects).
\item
-A braced \emph{ople} is called a \emph{nut-ple}. Among them $\{nil\}$ is a bit
+A braced \emph{ople} is called a \emph{nutple}. Among them $\{nil\}$ is a bit
special. It is called the \emph{not-ple}. It is not |nil|!
\end{itemize}
@@ -4172,7 +4252,7 @@ Each \emph{ople} has a length which is its cardinality. The |oples| of length
1 are called \emph{one-ples}. There are two types of \emph{one-ples}:
\begin{itemize}
\item \emph{numbers},
-\item packed \emph{oples}: the \emph{nut-ples}.
+\item packed \emph{oples}: the \emph{nutples}.
\end{itemize}
As said before the \emph{not-ple} |{{}}| is special. It can be input as
@@ -4186,7 +4266,7 @@ can associate with any \emph{ople} a tree. The root is the ople. In the case
of the |nil|, there is nothing else than the root, which we then consider also
a \emph{leaf}. Else the children at top level are the successive items of the
ople. Among the items some are \emph{atoms} giving \emph{leaves} of the tree,
-others are \emph{nut-ples} which in turn have children. In the special case of
+others are \emph{nutples} which in turn have children. In the special case of
the \emph{not-ple} we consider it has a child, which is the empty set and this
why we consider the empty set |nil| a \emph{leaf}. We then proceed
recursively. We thus obtain from the root \emph{ople} a tree whose vertices
@@ -4223,21 +4303,21 @@ indicate the shape than display it.
subset. This applies also if it is a \emph{number}. Then it can be sliced only
to itself or to the empty set (indeed it has only one element, which is an
atom). Similarly the \emph{not-ple} can only be sliced to give itself or the
-empty set. And more generally a \emph{nut-ple} is a singleton so also can only
+empty set. And more generally a \emph{nutple} is a singleton so also can only
be set-sliced to either the empty set or itself.
\xintexprname extends «Python-like» slicing to act on \emph{oples}:
\begin{itemize}[nosep]
-\item if they are not \emph{nut-ples} set-theoretical slicing applies,
-\item if they are \emph{nut-ples} (only case having a one-to-one
- correspondance in Python) then the slicing happens \emph{within brackets}:
- i.e. the \emph{nut-ple} is unpacked then the set-theoretical slicing is
- applied, then the result is \emph{repacked} to produce a new \emph{nut-ple}.
+\item if they are not \emph{nutples} set-theoretical slicing applies,
+\item if they are \emph{nutples} (only case having a one-to-one
+ correspondence in Python) then the slicing happens \emph{within brackets}:
+ i.e. the \emph{nutple} is unpacked then the set-theoretical slicing is
+ applied, then the result is \emph{repacked} to produce a new \emph{nutple}.
\end{itemize}
With these conventions the \emph{not-ple} for example is invariant under
slicing: unpacking it gives the empty set, which has only the empty set as
subset and repacking gives back the \emph{not-ple}. Slicing a general
-\emph{nut-ple} returns a \emph{nut-ple} but now of course in general distinct
+\emph{nutple} returns a \emph{nutple} but now of course in general distinct
from the first one.
The syntax for Python slicing is to postfix a variable or a parenthesized ople
@@ -4252,16 +4332,16 @@ a set).
\xintexprname extends «Python-like» indexing to act on \emph{oples}:
\begin{itemize}[nosep]
-\item if they are not \emph{nut-ples} set-theoretical item indexing applies,
-\item if they are \emph{nut-ples} (only case having a one-to-one
- correspondance in Python) then the meaning becomes \emph{extracting}: i.e.
- the \emph{nut-ple} is unpacked then the set-theoretical indexing is applied,
+\item if they are not \emph{nutples} set-theoretical item indexing applies,
+\item if they are \emph{nutples} (only case having a one-to-one
+ correspondence in Python) then the meaning becomes \emph{extracting}: i.e.
+ the \emph{nutple} is unpacked then the set-theoretical indexing is applied,
but the result is \emph{not repacked}.
\end{itemize}
For example when applied to the \emph{not-ple} we always obtain
the |nil|. Whereas as we saw slicing the \emph{not-ple} always gives back the
\emph{not-ple}. Indexing is denoted in the syntax by postfixing by |[N]|. Thus
-for \emph{nut-ples} (which are analogous to Python objects), there is genuine
+for \emph{nutples} (which are analogous to Python objects), there is genuine
difference between the |[N]| extractor and the |[N:N+1]| slicer. But for
\emph{oples} which are either |nil|, a \emph{number}, or of length at least 2,
there is no difference.
@@ -4269,8 +4349,8 @@ there is no difference.
Nested slicing is a concept from NumPy, which is extended by \xintexprname to
trees of varying depths. We have a chain of slicers and extractors. I will
-describe only the case of slicers and letting them act on a |nut-ple|. The
-first slicer gives back a new |nut-ple|. The second slicer will be applied to
+describe only the case of slicers and letting them act on a |nutple|. The
+first slicer gives back a new |nutple|. The second slicer will be applied to
each of one of its remaining items. However some of them may be \emph{atoms}
or the empty set. In the NumPy context all leaves are at the same depth thus
this can happen only when we have reached beyond the last dimension
@@ -4278,19 +4358,19 @@ this can happen only when we have reached beyond the last dimension
does not generate an error. But any attempt to slice an \emph{atom} or the
empty set (as element of its container) removes it. Recall we call them
\emph{leaves}. We can not slice leaves. We can only slice non-leaf items: such
-items are necessarily |nut-ples|. The procedure then applies recursively.
+items are necessarily |nutples|. The procedure then applies recursively.
If we handle an extractor rather than a slicer, the procedure is similar: we
can not extract out of an \emph{atom} or the empty set. They are thus
-removed. Else we have a |nut-ple|. It is thus unpacked and replaced by the
+removed. Else we have a |nutple|. It is thus unpacked and replaced by the
selected item. This item may be an atom or the empty set and any further
-slicer or extractor will remove them, or it is a |nut-ple| and the procedure
+slicer or extractor will remove them, or it is a |nutple| and the procedure
applies with the next slicer/extractor.
\xintexprname allows to apply such a |[a:b,c:d,N,e:f,...]| chain of
-slicing/extracting also to an \emph{ople}, which is not a \emph{nut-ple}. We
+slicing/extracting also to an \emph{ople}, which is not a \emph{nutple}. We
simply apply the first step as has been described previously and successive
-steps will only get applied to either \emph{nut-ples} or \emph{leaves}, the
+steps will only get applied to either \emph{nutples} or \emph{leaves}, the
latter getting silently removed by any attempted operation.
One last thing. In the syntax of \xintexprname, variables as well as functions
@@ -4298,11 +4378,11 @@ have a name and a value. The value is an |ople|. We can always use a variable
whose value is an |ople|
in a function call, it will occupy the place of as many arguments as its
length indicates. But in a function declaration, the variables must stand for
-|one-ples|, i.e. either |numbers| or |nut-ples|.
+|one-ples|, i.e. either |numbers| or |nutples|.
The |*| unpacks a
-|nut-ple|. The last positional argument in a function declaration can have a
-special form |*|\meta{name}. This means that \meta{name} is a |nut-ple| which
+|nutple|. The last positional argument in a function declaration can have a
+special form |*|\meta{name}. This means that \meta{name} is a |nutple| which
receives as items all arguments in the function call beyond the first ones
corresponding to the function declaration.
@@ -4934,29 +5014,43 @@ discussion at each level.
\precdesc{14}
\begin{description}
\operdesc{\lowast} multiplication
-\operdesc{/} division: exact in \csbxint{eval}, correctly rounded in
- \csbxint{floateval} (numerator and denominator are rounded before the
- division is done), and rounded to an integer (like |\numexpr| does:
- half-integers are rounded towards infinity of same sign) in
- \csbxint{iieval}. The division is left-associative:
+
+\operdesc{/} division:
+ \begin{itemize}
+ \item in \csbxint{eval}: exact division in the field of rational numbers (not
+ automatically reduced to lowest terms),
+ \item in \csbxint{floateval}: correct rounding of the exact division; the two
+ operands are, if necessary, float-rounded before the fraction is
+ evaluated and rounded (to obtain the correcty rounded |A/B|
+ without prior rounding of |A| and |B| see \func{qfloat}),
+ \item in \csbxint{iieval}: for compatibility with the legacy behaviour of
+ |/| in |\numexpr|, it rounds the exact fraction \emph{with half-integers
+ going towards the infinity of the same sign}.
+ \end{itemize}
+ The division is left-associative. Example:
\begin{everbatim*}
\xintexpr reduce(100/50/2)\relax
\end{everbatim*}
-\operdesc{//} floored division
+\operdesc{//} floored division (and thus produces an integer, see
+ \func{divmod} for details)
-\operdesc{/:} the associated modulo
+\operdesc{/:} the associated modulo (see \func{divmod} and \func{mod})
Left-associativity applies generally to operators of same precedence.
\begin{everbatim*}
\xintexpr 100000/:13, 100000 'mod' 13\relax\newline
\xintexpr 100000/:13/13\relax
\end{everbatim*}
+
+ Nothing special needs to be done in contexts such as \LaTeX3
+ |\ExplSyntaxOn| where |:| is of catcode letter, but if |:| is an active
+ character (for example in \LaTeX\ with babel+french) with an active |:|,
+ one needs to use input such as |/\string :| (or use \func{mod}).
-\operdesc{'mod'} is same as \oper{/:}.
-
-Note: The enclosing (right) ticks are
-mandatory part of all such infix operator «words».
+ \operdesc{'mod'} is same as \oper{/:}. \fbox{Attention:} with
+ \ctanpackage{polexpr} loaded, which allows |'| in variable and function
+ names, |'mod'| syntax is broken. Use the alternatives.
\end{description}
@@ -5013,8 +5107,10 @@ precedence, use parentheses for disambiguation.
\operdesc{\Ampersand\Ampersand} logical conjunction. Evaluates to \dtt{1} if
both sides are non-zero, to \dtt{0} if not.
- \operdesc{'and'} idem. The (right) ticks are mandatory. See also the
- \func{all} multi-arguments function.
+ \operdesc{'and'} same as \verb+&&+. See
+ also the \func{all} multi-arguments function. \fbox{Attention:} with
+ \ctanpackage{polexpr} loaded, which allows |'| in variable and function
+ names, |'and'| syntax is broken. Use the alternatives.
\end{description}
\precdesc{6}
@@ -5022,10 +5118,16 @@ precedence, use parentheses for disambiguation.
\operdesc{\string|\string|} logical (inclusive) disjunction. Evaluates to
\dtt{1} if one or both sides are non-zero, to \dtt{0} if not.
- \operdesc{'or'} idem. See also the \func{any} multi-arguments function.
+ \operdesc{'or'} same as as \verb+||+. See also the \func{any} multi-arguments
+ function. \fbox{Attention:} with \ctanpackage{polexpr} loaded, which allows
+ |'| in variable and function names, |'or'| syntax is broken. Use the
+ alternatives.
- \operdesc{'xor'} logical (exclusive) disjunction. See also the \func{xor}
- multi-arguments function.
+ \operdesc{'xor'} logical (exclusive) disjunction. \fbox{Attention:} with
+ \ctanpackage{polexpr} loaded, which allows |'| in variable and function
+ names, |'xor'| syntax is broken. Use the multi-arguments \func{xor} function
+ (or suggest to the author some credible alternative ascii notation to use as
+ infix operator).
\operdesc{\strut..}
\operdesc{..[}
@@ -5125,13 +5227,13 @@ binomial, bool,
ceil, cos, cosd, cot, cotd, cotg, csc, cscd,
divmod, even, exp,
factorial, first, flat, float, float\string_, floor, frac, gcd,
-if, ifint, ifone, ifsgn, ilog10, isint, isone, iter, iterr, inv,
+if, ifint, ifone, ifsgn, ilog10, iquo, irem, isint, isone, iter, iterr, inv,
last, lcm, len, log, log10, max, min, mod, mul,
ndmap, ndseq, ndfillraw,
not, num, nuple, odd,
pArg, pArgd, pfactorial, pow, pow10, preduce,
-qfloat, qfrac, qint, qrand, qraw, quo,
-random, randrange, rbit, reduce, rem, reversed, round, rrseq, rseq,
+qfloat, qfrac, qint, qrand, qraw,
+random, randrange, rbit, reduce, reversed, round, rrseq, rseq,
sec, secd, seq, sgn, sin, sinc, sind, sqr, sqrt, sqrtr,
subs, subsm, subsn,
tan, tand, tg, togl, trunc, unpack,
@@ -5474,7 +5576,7 @@ $\xintthefloatexpr subs(((x-1)/x, x/x, (x+1)/x), x=2**30)\relax
allow arbitrarily complicated combinations of various |bool(name)|.
\funcdesc[name]{togl}
returns $1$
- if the \LaTeX{} package \href{https://ctan.org/pkg/etoolbox}{etoolbox}%
+ if the \LaTeX{} package \ctanpackage{etoolbox}%
%
%
%
@@ -5483,7 +5585,7 @@ $\xintthefloatexpr subs(((x-1)/x, x/x, (x+1)/x), x=2**30)\relax
has been used to define a toggle named |name|, and this toggle is
currently set to |true|. Using |togl| in an |\xintexpr..\relax|
without having loaded
- \href{https://ctan.org/pkg/etoolbox}{etoolbox} will result in an
+ \ctanpackage{etoolbox} will result in an
error from |\iftoggle| being a non-defined macro. If |etoolbox| is
loaded but |togl| is used on a name not recognized by |etoolbox|
the error message will be of the type ``ERROR: Missing |\endcsname|
@@ -5650,14 +5752,17 @@ $\xintthefloatexpr subs(((x-1)/x, x/x, (x+1)/x), x=2**30)\relax
% labelwidth=-\fontdimen2\font, labelsep=\fontdimen2\font, labelindent=0pt,
% listparindent=\leftmarginiii]
- \funcdesc[f, g]{quo} first truncates the arguments to convert them to integers then
- computes the Euclidean quotient. Hence it computes an integer.
- \funcdesc[f, g]{rem} first truncates the arguments to convert them to integers then
- computes the Euclidean remainder. Hence it computes an integer.
+ \funcdesc[m, n]{iquo} Only available in |\xintiiexpr/\xintiieval|
+ context. Computes the Euclidean quotient. Matches with the remainder
+ defined in next item. See \csbxint{iiQuo}.
+
+ \funcdesc[m, n]{irem} Only available in |\xintiiexpr/\xintiieval|
+ context. Computes the Euclidean remainder. Attention that, following
+ mathematical definition, it is always non-negative. See \csbxint{iiRem}.
\funcdesc[f, g]{mod} computes |f - g*floor(f/g)|. Hence its output is a
general fraction or floating point number or integer depending on the
- used parser.
+ used parser. If non-zero, it has the same sign as |g|.
Prior to |1.2p| it computed |f - g*trunc(f/g)|.
@@ -5833,15 +5938,23 @@ At |1.4| \func{all}, \func{any}, \func{xor},
\func{max}, \func{min}, \func{gcd}, \func{lcm}, \func{first}, \func{last},
\func{reversed} and \func{len} admit:
\begin{itemize}
-\item at least two arguments, and then operate as expected in backward
- compatible way,
-\item or only one argument,\IMPORTANT{} which then \emph{must} be a |nut-ple|, i.e. a
- variable or explicit bracketed list. In the case of \func{reversed} the output
- is a |nut-ple| if the input was one.
+\item at least two arguments, and then they operate as expected in the backwards
+ compatible way (notice that it is possible in \xintexprname to define
+ variables expanding to an |ople|, i.e. (at user level) an unpacked comma
+ separated list, |foo(ople)| thus falls into this category),
+\item or only one argument,\IMPORTANT{} which then \emph{must} be a |nutple|,
+ i.e. a bracketed list (or a variable defined to hold such a
+ bracketed list, or a function producing such a |nutple|). The argument is then
+ automatically unpacked.
+
+ In the specific case of \func{reversed} the output is then repacked so that
+ the output is a |nutple| if and only if the input was one (the reversal does
+ not propagate to deeper nested |nutple|'s, it applies only at depth one).
\end{itemize}
-Notice that this is breaking change as the functions do not work anymore with
-a single argument being a number (or give funny non-documented results
-depending on internal data representation).
+The arguments of the functions doing computations on the arguments (such as
+\func{gcd}) must be numerical, except if there is only one argument, and then
+it must be a |nutple|. Prior to |1.4|, the functions worked also with a single
+scalar argument, but this is now illegal.
\begin{description}
% [parsep=0pt,align=left,
@@ -5894,45 +6007,57 @@ the resulting logical assertion,
\funcdesc[x, y, ...]{gcd} computes the positive generator of the fractional
ideal of rational numbers $x\mathbb Z + y\mathbb Z + ... \subset \mathbb
-Q$. When the inputs are integers it is advantageous to use a sub
-\csbxint{iiexpr}-ession, as the integer-only macro is more efficient (about
-|6X|) than the
-one accepting general fractional inputs. Notice that this may require some
-\func{num} wrapper when using variables, as they may well be in fraction
-format, and \csbxint{iiexpr} accepts only strict integers. Since |1.3d|, this
-function and \func{lcm} are available whether or not package \xintgcdname is
-loaded. Note that like other operations with fractions it does not always
-produce a fraction in irreducible format. This example shows also how to
-reduce an n-uple to its primitive part: (this example should be revisited)
-\begin{everbatim*}
-\xinttheexpr gcd(7/300, 11/150, 13/60)\relax\newline
+Q$. Since |1.4d| the output is always in lowest terms.
+
+This example shows how to reduce an n-uple to its primitive part:
+\begin{everbatim*}
+\xinteval{gcd(7/300, 11/150, 13/60)}\newline
$(7/300, 11/150, 13/60)\to
-(\xinttheexpr subs(seq(reduce(x/D), x = 7/300, 11/150, 13/60), D=gcd(7/300, 11/150, 13/60))\relax)$\newline
+(\xinteval{subsn(seq(reduce(x/D), x = L), D=gcd(L); L=7/300, 11/150, 13/60)})$\newline
\xintexpr gcd([7/300, 11/150, 13/60])\relax\par
\end{everbatim*}
-
+MEMO
Perhaps a future release will provide a |primpart()| function as built-in
functionality.
+In case of strict integers, using a |\xintiiexpr...\relax| wrapper is
+advantageous as the integer-only |gcd()| is more efficient.
+%
+% ceci semble encore à peu près exact à 1.4d :
+% (about |6X|) than the one accepting general fractional inputs.
+%
+As \csbxint{iiexpr} accepts only strict integers, doing this may require
+wrapping the argument in \func{num}.
+
\funcdesc[x, y, ...]{lcm} computes the positive generator of the
fractional ideal of rational numbers $x\mathbb Z \cap y\mathbb Z \cap ...
-\subset \mathbb Q$. When the inputs are integers it is
-advantageous to use a sub \csbxint{iiexpr}-ession, as the integer-only macro
-is more efficient (about |9X|) than the one accepting general fractional inputs.
+\subset \mathbb Q$.
\begin{everbatim*}
\xinttheexpr lcm([7/300, 11/150, 13/60])\relax
\end{everbatim*}
+As for \func{gcd}, since |1.4d| the output is always in lowest terms.
+% Memo 1.4d: This
+% function got (I did not tests extensively) a |4X| speed gain for inputs being
+% only integers
+For strict integers it is slightly advantageous to use a sub
+\csbxint{iiexpr}-ession.
+%
+% je disais à 1.4:
+% (about |9X|) than the one accepting general fractional inputs.
+% mais à 1.4d c'est seulement 2X : le lcm pour les fractions
+% a quadruplé sa vitesse !
+%
-\funcdesc[x, y, ...]{first} first item of the list or nut-ple argument:
+\funcdesc[x, y, ...]{first} first item of the list or nutple argument:
\begin{everbatim*}
\xintiiexpr first([last(-7..3), [58, 97..105]])\relax
\end{everbatim*}
-\funcdesc[x, y, ...]{last} last item of the list or nut-ple argument:
+\funcdesc[x, y, ...]{last} last item of the list or nutple argument:
\begin{everbatim*}
\xintiiexpr last([-7..3, 58, first(97..105)])\relax
\end{everbatim*}
\funcdesc[x, y, ...]{reversed} reverses the order of the comma separated list
-or inside a nut-ple:
+or inside a nutple:
\begin{everbatim*}
\xintiieval{reversed(reversed(1..5), reversed([1..5]))}
\end{everbatim*}
@@ -5940,16 +6065,16 @@ or inside a nut-ple:
The above is correct as \xintexprname functions may produce oples and this is
the case here.
\funcdesc[x, y, ...]{len} computes the number of items in a comma separated
- list or inside a nut-ple (at first level only: it is not a counter of leaves).
+ list or inside a nutple (at first level only: it is not a counter of leaves).
\begin{everbatim*}
\xinttheiiexpr len(1..50, [101..150], 1001..1050), len([1..10])\relax
\end{everbatim*}
\funcdesc[\lowast nutples]{zip} behaves\NewWith{1.4b} similarly to
- the Python function of the same name: i.e. it produces \emph{an ople of nut-ples,
- where the i-th nut-ple contains the i-th element from each of the argument
- nut-ples. The ople ends when the shortest input nut-ple is exhausted.
- With a single nut-ple argument, it returns an ople of 1-nutples.
+ the Python function of the same name: i.e. it produces \emph{an ople of nutples,
+ where the i-th nutple contains the i-th element from each of the argument
+ nutples. The ople ends when the shortest input nutple is exhausted.
+ With a single nutple argument, it returns an ople of 1-nutples.
With no arguments, it returns the empty ople.}
As there is no exact match in \xintexprname of the concept of «iterator» object,%
@@ -6363,7 +6488,7 @@ In the example above the parentheses serve to disambiguate from the raw
on input. And we used a trick to show that |(7)[-2]| returns |nil|.
The behaviour changes for singleton \emph{oples} which are not
-\emph{numbers}. They are thus \emph{nut-ples}, or equivalently they are the
+\emph{numbers}. They are thus \emph{nutples}, or equivalently they are the
bracketing (bracing, packing) of another \emph{ople}. In this case, the meaning
of the syntax for item indexing is, as in Python, item
\emph{extraction}:
@@ -6379,7 +6504,7 @@ of the syntax for item indexing is, as in Python, item
\xintiiexpr (0..10)[:6]\relax\ and \xintiiexpr (0..10)[:-6]\relax
\end{everbatim*}
-As above, the meaning change for \emph{nut-ples} and fits with expectations
+As above, the meaning change for \emph{nutples} and fits with expectations
from Python regarding its sequence types:
\begin{everbatim*}
\xintiiexpr [0..10][:6]\relax\ and \xintiiexpr [0..10][:-6]\relax
@@ -6391,7 +6516,7 @@ from Python regarding its sequence types:
\xintiiexpr (0..10)[6:]\relax\ and \xintiiexpr (0..10)[-6:]\relax
\end{everbatim*}
-As above, the meaning change for \emph{nut-ples} and fit with expectations
+As above, the meaning change for \emph{nutples} and fit with expectations
from Python with \emph{tuple} or \emph{list} types:
\begin{everbatim*}
\xintiiexpr [0..10][6:]\relax\ and \xintiiexpr [0..10][-6:]\relax
@@ -6414,7 +6539,7 @@ from Python with \emph{tuple} or \emph{list} types:
\end{itemize}
-\subsection{NumPy like nested slicing and indexing for arbitrary oples and nut-ples}
+\subsection{NumPy like nested slicing and indexing for arbitrary oples and nutples}
This is entirely new with |1.4|.\NewWith{1.4}
@@ -6467,6 +6592,21 @@ part, or hexadecimal input), or is looking for an infix operator, and:
\end{enumerate}
\begin{framed}
+ \centeredline{\textcolor{Red}{\textbf{!!!!ATTENTION!!!!}}}
+
+ Explicit digits prefixing a variable, or a function, whose name starts with
+ an |e| or |E| will trap the parser into trying to build a number in
+ scientific notation. So the |*| must be explictly inserted.
+
+\begin{everbatim}
+\xintdefiivar e := (2a+4b+6d+N)/:7;%
+\xintdefiivar f := (c+11d+22*e)//451;% 22e would raise errors
+\end{everbatim}
+
+ I don't think I will fix this anytime soon...
+\end{framed}
+
+\begin{framed}
For example, if |x, y, z| are variables all three of |(x+y)z|, |x(y+z)|,
|(x+y)(x+z)| will create a tacit multiplication.
@@ -7109,7 +7249,7 @@ This section\CHANGED{1.4} has changed significantly at |1.4| due to the new exte
types manipulated by the syntax.
Suppose we want to manipulate 3-dimensional vectors, which will be represented
-as |nut-ples| of length 3. And let's add a bit of matrix algebra.
+as |nutples| of length 3. And let's add a bit of matrix algebra.
\begin{everbatim*}
\xintdeffunc dprod(V, W) := V[0]*W[0] + V[1]*W[1] + V[2]*W[2];
\xintdeffunc cprod(V, W) := [V[1]*W[2] - V[2]*W[1],
@@ -7623,9 +7763,9 @@ This package was first included in release |1.3e| (|2019/04/05|) of
Currently, the functions \func{log10}, \func{pow10}, \func{log}, \func{exp},
and \func{pow} use at their core two fast expandable macros handling base 10
logarithms and powers for mantissas of 9 digit tokens. They are
-defined by package \href{https://ctan.org/pkg/poormanlog}{poormanlog} which is
+defined by package \ctanpackage{poormanlog} which is
automatically imported. The error is believed to be at most \dtt{2ulp} (see
-its |README|). The package \href{https://ctan.org/pkg/poormanlog}{poormanlog}
+its |README|). The package \ctanpackage{poormanlog}
has no dependencies and can be imported by any other \TeX\ macro file.
Although the precision is thus limited to about \dtt{8} or \dtt{9} digits this
@@ -7679,7 +7819,7 @@ first 8 or 9 digits of the output are significant...
\end{everbatim*}
Notice that the last digit of |log(2)| is not the correctly rounded one... I
did say 9 \textbf{or} 8 digits or precision... The documentation of
-\href{https://ctan.org/pkg/poormanlog}{poormanlog} mentions an error of up
+\ctanpackage{poormanlog} mentions an error of up
to 2 units in the ninth digit when computing |log10(x)| for |1<x<10| and
|10^x| for |0<x<1|.
@@ -7783,7 +7923,7 @@ using standard infix notations with \TeX{} integers. But \eTeX{} did not
modify the \TeX{} bound on acceptable integers, and did not add floating point
support.
-The \href{https://ctan.org/pkg/bigintcalc}{bigintcalc} package by
+The \ctanpackage{bigintcalc} package by
\textsc{Heiko Oberdiek} provided expandable macros (using some of |\numexpr|
possibilities, when available) on arbitrarily big integers, beyond the \TeX{}
bound. It does not provide an expression parser.%
@@ -7848,7 +7988,7 @@ Even with the superior \liiibigint{} Karatsuba multiplication it takes about
computations in a document. I have long been thinking that without the
expandability constraint much higher speeds could be achieved, but perhaps I
have not given enough thought to sustain that optimistic stance.\footnote{The
- \href{https://ctan.org/pkg/apnum}{apnum} package implements
+ \ctanpackage{apnum} package implements
(non-expandably) arbitrary precision fixed point algebra and (v1.6)
functions exp, log, sqrt, the trigonometrical direct and inverse functions.}
@@ -8076,7 +8216,7 @@ margin annotation next to the description of the arguments.
package provided conditionals such as \csbxint{ifEq}, \csbxint{ifGt},
\csbxint{ifSgn},\dots\ or, for \LaTeX{} users and when dealing
with short integers the
- \href{https://ctan.org/pkg/etoolbox}{etoolbox}%
+ \ctanpackage{etoolbox}%
%
\footnote{\url{https://ctan.org/pkg/etoolbox}}
expandable conditionals (for small integers only) such as \texttt{\char92
@@ -8617,7 +8757,7 @@ unused branches should not be forgotten.
If these tests are to be applied to standard \TeX{} short integers, it is more
efficient to use (under \LaTeX{}) the equivalent conditional tests from the
-\href{https://ctan.org/pkg/etoolbox}{etoolbox}%
+\ctanpackage{etoolbox}%
%
\footnote{\url{https://ctan.org/pkg/etoolbox}}
package.
@@ -8867,7 +9007,7 @@ early 2014.
This |1.2| release also got its impulse from a fast
``reversing'' macro, which I wrote after my interest got awakened again as a
-result of correspondance with Bruno \textsc{Le Floch} during September 2015:
+result of correspondence with Bruno \textsc{Le Floch} during September 2015:
this new reverse uses a \TeX nique which \emph{requires} the tokens to be
digits. I wrote a routine which works (expandably) in quasi-linear time, but a
less fancy |O(N^2)| variant which I developed concurrently proved to be faster
@@ -11334,8 +11474,11 @@ Prior to |1.4| a macro of the same name existed in \xintgcdname. But
it truncated all its arguments to integers via \csbxint{Num} and then
proceeded with integer only computations.
-See \csbxint{iiGCDof} for the integer only variant (which is about |6X| faster
-than this one for integer arguments).
+See \csbxint{iiGCDof} for the integer only variant.
+
+% Semble encore vrai à 1.4d
+% Mais je n'ai testé que sur un exemple...
+% (which is about |6X| faster than this one for integer arguments).
\subsection{\csh{xintLCMof}}\label{xintLCMof}
@@ -11349,8 +11492,13 @@ output.
Prior to |1.4| a macro of the same name existed in \xintgcdname. But
it truncated all its arguments to integers via \csbxint{Num}.
-See \csbxint{iiLCMof} for the integer only variant (which is about |9X| faster
-than this one for integer arguments).
+See \csbxint{iiLCMof} for the integer only variant.
+
+% Avant 1.4d on avait ceci :
+% (which is about |9X| faster han this one for integer arguments).
+% mais à 1.4d le lcm des fractions est environ 4X fois plus efficace,
+% en ce qui concerne son emploi avec des entiers (testé sur un seul exemple)
+% donc le gain de faire \xintiiexpr n'est plus que 2X !
\subsection{\csh{xintDigits}, \csh{xinttheDigits}}
\label{xintDigits}
@@ -18338,7 +18486,7 @@ math shift catcode.
\fi
\XINT_providespackage
\ProvidesPackage {xintkernel}%
- [2021/02/20 v1.4c Paraphernalia for the xint packages (JFB)]%
+ [2021/03/29 v1.4d Paraphernalia for the xint packages (JFB)]%
% \end{macrocode}
% \subsection{Constants}
% \begin{macrocode}
@@ -18431,6 +18579,7 @@ math shift catcode.
\long\def\xint_firstofone #1{#1}%
\long\def\xint_firstoftwo #1#2{#1}%
\long\def\xint_secondoftwo #1#2{#2}%
+\long\def\xint_thirdofthree#1#2#3{#3}% 1.4d
\let\xint_stop_aftergobble\xint_gob_andstop_i
\long\def\xint_stop_atfirstofone #1{ #1}%
\long\def\xint_stop_atfirstoftwo #1#2{ #1}%
@@ -18462,7 +18611,7 @@ math shift catcode.
\long\def\xint_gob_til_xint:#1\xint:{}%
\long\def\xint_gob_til_^#1^{}%
\def\xint_bracedstopper{\xint:}%
-\long\def\xint_gob_til_exclam #1!{}%
+\long\def\xint_gob_til_exclam #1!{}% documenter le catcode de ! ici
\long\def\xint_gob_til_sc #1;{}%
% \end{macrocode}
% \subsection{\csh{xint_afterfi}}
@@ -19124,7 +19273,7 @@ math shift catcode.
% \begin{macrocode}
\XINT_providespackage
\ProvidesPackage{xinttools}%
- [2021/02/20 v1.4c Expandable and non-expandable utilities (JFB)]%
+ [2021/03/29 v1.4d Expandable and non-expandable utilities (JFB)]%
% \end{macrocode}
% \lverb|\XINT_toks is used in macros such as \xintFor. It is not used
% elsewhere in the xint bundle.|
@@ -21468,7 +21617,7 @@ math shift catcode.
% \begin{macrocode}
\XINT_providespackage
\ProvidesPackage{xintcore}%
- [2021/02/20 v1.4c Expandable arithmetic on big integers (JFB)]%
+ [2021/03/29 v1.4d Expandable arithmetic on big integers (JFB)]%
% \end{macrocode}
% \subsection{(WIP!) Error conditions and exceptions}
% \lverb|As per the Mike Cowlishaw/IBM's General Decimal Arithmetic Specification
@@ -21782,6 +21931,13 @@ math shift catcode.
-{ #1}%
\krof
}%
+\def\XINT_Abs #1%
+{%
+ \xint_UDsignfork
+ #1{}%
+ -{#1}%
+ \krof
+}%
% \end{macrocode}
% \subsection{\csh{xintFDg}}
% \lverb|&
@@ -24770,7 +24926,7 @@ math shift catcode.
% \begin{macrocode}
\XINT_providespackage
\ProvidesPackage{xint}%
- [2021/02/20 v1.4c Expandable operations on big integers (JFB)]%
+ [2021/03/29 v1.4d Expandable operations on big integers (JFB)]%
% \end{macrocode}
% \subsection{More token management}
% \begin{macrocode}
@@ -26946,11 +27102,20 @@ math shift catcode.
\def\xintToggle #1{\romannumeral`&&@\iftoggle{#1}{1}{0}}%
% \end{macrocode}
% \subsection{\csh{xintiiGCD}}
-% Copied over |\xintiiGCD| code from \xintgcdnameimp at |1.3d| in order to
+% |1.3d|: |\xintiiGCD| code from \xintgcdnameimp is copied here to
% support |gcd()| function in \csbxint{iiexpr}.
%
-% At |1.4| original code removed from
-% \xintgcdnameimp as the latter now requires \xintnameimp.
+% |1.4|: removed from \xintgcdnameimp the original caode as now
+% \xintgcdnameimp loads \xintnameimp.
+%
+% \changed{1.4d}{2021/03/22} Damn'ed! Since |1.3d| (2019/01/06) the code was
+% broken if one of the arguments vanished due to a typo in macro names:
+% "AisZero" at one location and "Aiszero" at next, and same for B...
+%
+% How could this not be detected by my tests !?!
+%
+% This caused |\xintiiGCDof| hence the |gcd()| function in |\xintiiexpr| to
+% break as soon as one argument was zero.
% \begin{macrocode}
\def\xintiiGCD {\romannumeral0\xintiigcd }%
\def\xintiigcd #1{\expandafter\XINT_iigcd\romannumeral0\xintiiabs#1\xint:}%
@@ -26968,8 +27133,8 @@ math shift catcode.
\krof
#2%
}%
-\def\XINT_gcd_AisZero #1\xint:#2\xint:{ #1}%
-\def\XINT_gcd_BisZero #1\xint:#2\xint:{ #2}%
+\def\XINT_gcd_Aiszero #1\xint:#2\xint:{ #1}%
+\def\XINT_gcd_Biszero #1\xint:#2\xint:{ #2}%
\def\XINT_gcd_loop #1\xint:#2\xint:
{%
\expandafter\expandafter\expandafter\XINT_gcd_CheckRem
@@ -26982,6 +27147,29 @@ math shift catcode.
}%
\def\XINT_gcd_end0\XINT_gcd_loop #1\xint:#2\xint:{ #2}%
% \end{macrocode}
+% \subsection{\csh{xintiiGCDof}}
+% \lverb|New with 1.09a (was located in xintgcd.sty).
+%
+% 1.2l adds protection against items being non-terminated \the\numexpr.
+%
+% 1.4 renames the macro into \xintiiGCDof and moves it here.
+% Terminator modified to ^ for direct call by \xintiiexpr function.
+%
+% 1.4d fixes breakage inherited since 1.3d rom \xintiiGCD, in case
+% any argument vanished.
+%
+% Currently does not support empty list of arguments.
+% |
+% \begin{macrocode}
+\def\xintiiGCDof {\romannumeral0\xintiigcdof }%
+\def\xintiigcdof #1{\expandafter\XINT_iigcdof_a\romannumeral`&&@#1^}%
+\def\XINT_iiGCDof {\romannumeral0\XINT_iigcdof_a}%
+\def\XINT_iigcdof_a #1{\expandafter\XINT_iigcdof_b\romannumeral`&&@#1!}%
+\def\XINT_iigcdof_b #1!#2{\expandafter\XINT_iigcdof_c\romannumeral`&&@#2!{#1}!}%
+\def\XINT_iigcdof_c #1{\xint_gob_til_^ #1\XINT_iigcdof_e ^\XINT_iigcdof_d #1}%
+\def\XINT_iigcdof_d #1!{\expandafter\XINT_iigcdof_b\romannumeral0\xintiigcd {#1}}%
+\def\XINT_iigcdof_e #1!#2!{ #2}%
+% \end{macrocode}
% \subsection{\csh{xintiiLCM}}
% Copied over |\xintiiLCM| code from \xintgcdnameimp at |1.3d| in order to
% support |lcm()| function in \csbxint{iiexpr}.
@@ -27016,26 +27204,6 @@ math shift catcode.
}%
\def\XINT_lcm_end #1\xint:#2\xint:#3\xint:{\xintiimul {#2}{\xintiiQuo{#3}{#1}}}%
% \end{macrocode}
-% \subsection{\csh{xintiiGCDof}}
-% \lverb|New with 1.09a (xintgcd.sty).
-%
-% 1.2l adds protection against items being non-terminated \the\numexpr.
-%
-% 1.4 renames the macro into \xintiiGCDof and moves it here.
-% Terminator modified to ^ for direct call by \xintiiexpr function.
-% See comments
-% in xintfrac.sty about \xintGCDof macro there.|
-%
-% \begin{macrocode}
-\def\xintiiGCDof {\romannumeral0\xintiigcdof }%
-\def\xintiigcdof #1{\expandafter\XINT_iigcdof_a\romannumeral`&&@#1^}%
-\def\XINT_iiGCDof {\romannumeral0\XINT_iigcdof_a}%
-\def\XINT_iigcdof_a #1{\expandafter\XINT_iigcdof_b\romannumeral`&&@#1!}%
-\def\XINT_iigcdof_b #1!#2{\expandafter\XINT_iigcdof_c\romannumeral`&&@#2!{#1}!}%
-\def\XINT_iigcdof_c #1{\xint_gob_til_^ #1\XINT_iigcdof_e ^\XINT_iigcdof_d #1}%
-\def\XINT_iigcdof_d #1!{\expandafter\XINT_iigcdof_b\romannumeral0\xintiigcd {#1}}%
-\def\XINT_iigcdof_e #1!#2!{ #2}%
-% \end{macrocode}
% \subsection{\csh{xintiiLCMof}}
% \lverb|See comments of \xintiiGCDof|.
% \begin{macrocode}
@@ -27336,7 +27504,7 @@ math shift catcode.
% \begin{macrocode}
\XINT_providespackage
\ProvidesPackage{xintbinhex}%
- [2021/02/20 v1.4c Expandable binary and hexadecimal conversions (JFB)]%
+ [2021/03/29 v1.4d Expandable binary and hexadecimal conversions (JFB)]%
% \end{macrocode}
% \subsection{Constants, etc...}
% \lverb|1.2n switches to \csname-governed expansion at various places.|
@@ -28008,7 +28176,7 @@ math shift catcode.
% \begin{macrocode}
\XINT_providespackage
\ProvidesPackage{xintgcd}%
- [2021/02/20 v1.4c Euclide algorithm with xint package (JFB)]%
+ [2021/03/29 v1.4d Euclide algorithm with xint package (JFB)]%
% \end{macrocode}
% \subsection{\csh{xintBezout}}
% \lverb|&
@@ -28608,7 +28776,7 @@ math shift catcode.
% \begin{macrocode}
\XINT_providespackage
\ProvidesPackage{xintfrac}%
- [2021/02/20 v1.4c Expandable operations on fractions (JFB)]%
+ [2021/03/29 v1.4d Expandable operations on fractions (JFB)]%
% \end{macrocode}
% \subsection{\csh{XINT_cntSgnFork}}
% \lverb|1.09i. Used internally, #1 must expand to \m@ne, \z@, or \@ne or
@@ -30692,7 +30860,11 @@ math shift catcode.
% \end{macrocode}
% \subsection{\csh{xintDivFloor}}
% \lverb|1.1. Changed at 1.2p to not append /1[0] ending but rather output a
-% big integer in strict format, like \xintDivTrunc and \xintDivRound.|
+% big integer in strict format, like \xintDivTrunc and \xintDivRound.
+%
+%
+%
+% |
% \begin{macrocode}
\def\xintDivFloor {\romannumeral0\xintdivfloor }%
\def\xintdivfloor #1#2{\xintifloor{\xintDiv {#1}{#2}}}%
@@ -31200,80 +31372,183 @@ math shift catcode.
\def\xintSgn {\romannumeral0\xintsgn }%
\def\xintsgn #1{\expandafter\XINT_sgn\romannumeral0\xintraw {#1}\xint:}%
% \end{macrocode}
-% \subsection{\csh{xintGCD}, \csh{xintLCM}}
+% \subsection{\csh{xintGCD}}
% \changed{1.4}{}
-% They replace the former \xintgcdnameimp macros of the
-% same names which truncated to integers their arguments.
-% Fraction-producing |gcd()| and |lcm()| functions
-% were available since |1.3d| \xintexprnameimp, with non-public
-% support macros handling comma separated
-% values.
+% They replace the former \xintgcdnameimp macros of the same names which
+% truncated to integers their arguments. Fraction-producing |gcd()| and
+% |lcm()| functions were available since |1.3d| \xintexprnameimp, with
+% non-public support macros handling comma separated values.
+%
+% \changed{1.4d}{}
+% Somewhat strangely \csh{xintGCD} was formerly \csh{xintGCDof} used with only two
+% arguments, as the latter directly implemented a fractionl gcd algorithm
+% using \csh{xintMod} repeatedly for two arguments.
+%
+% Now \csh{xintGCD} contains the pairwise gcd routine and \csh{xintGCDof}
+% is only a wrapper. And the pairwise gcd is reduced to integer-only
+% computations to hopefully reduce fraction overhead.
+%
+% Each input is filtered via |\xintPIrr| and |\xintREZ| to reduce size
+% of maniuplate integers in algebra.
+%
+% But hesitation about applying |\xintPIrr| to output, and/or |\xintREZ|.
+% (as it is applied on input).
+%
+% But as the code is now used for frational lcm's we actually need to do
+% some reduction of output else lcm's of integers will not be necessarily
+% printed by |\xinteval| as integers.
+%
+% Well finally I apply |\xintIrr| (but not |\xintREZ| to output).
+% Hesitations here (thinking of inputs with large [n] parts, the output
+% will have many zeros). So I do this only for the user macro but
+% the core routine as used by |\xintGCDof| will not do it.
+%
+% Also at |1.4d| the code uses |\expanded|.
% \begin{macrocode}
\def\xintGCD {\romannumeral0\xintgcd}%
-\def\xintgcd #1#2{\XINT_fgcdof{#1}{#2}^}%
-\def\xintLCM {\romannumeral0\xintlcm}%
-\def\xintlcm #1#2{\XINT_flcmof{#1}{#2}^}%
+\def\xintgcd #1%
+{%
+ \expandafter\XINT_fgcd_in
+ \romannumeral0\xintrez{\xintPIrr{\xintAbs{#1}}}\xint:
+}%
+\def\XINT_fgcd_in #1#2\xint:#3%
+{%
+ \expandafter\XINT_fgcd_out
+ \romannumeral0\expandafter\XINT_fgcd_chkzeros\expandafter#1%
+ \romannumeral0\xintrez{\xintPIrr{\xintAbs{#3}}}\xint:#1#2\xint:
+}%
+\def\XINT_fgcd_out#1[#2]{\xintirr{#1[#2]}[0]}%
+\def\XINT_fgcd_chkzeros #1#2%
+{%
+ \xint_UDzerofork
+ #1\XINT_fgcd_aiszero
+ #2\XINT_fgcd_biszero
+ 0\XINT_fgcd_main
+ \krof #2%
+}%
+\def\XINT_fgcd_aiszero #1\xint:#2\xint:{ #1}%
+\def\XINT_fgcd_biszero #1\xint:#2\xint:{ #2}%
+\def\XINT_fgcd_main #1/#2[#3]\xint:#4/#5[#6]\xint:
+{%
+ \expandafter\XINT_fgcd_a
+ \romannumeral0\XINT_gcd_loop #2\xint:#5\xint:\xint:
+ #2\xint:#5\xint:#1\xint:#4\xint:#3.#6.%
+}%
+\def\XINT_fgcd_a #1\xint:#2\xint:
+{%
+ \expandafter\XINT_fgcd_b
+ \romannumeral0\xintiiquo{#2}{#1}\xint:#1\xint:#2\xint:
+}%
+\def\XINT_fgcd_b #1\xint:#2\xint:#3\xint:#4\xint:#5\xint:#6\xint:#7.#8.%
+{%
+ \expanded{%
+ \xintiigcd{\xintiiE{\xintiiMul{#5}{\xintiiQuo{#4}{#2}}}{#7-#8}}%
+ {\xintiiE{\xintiiMul{#6}{#1}}{#8-#7}}%
+ /\xintiiMul{#1}{#4}%
+ [\ifnum#7>#8 #8\else #7\fi]%
+ }%
+}%
% \end{macrocode}
% \subsection{\csh{xintGCDof}}
% \changed{1.4}{}
-% This inherits from former non public \xintexprnameimp macro called |\xintGCDof:csv|,
-% handling comma separated items, and former \xintgcdnameimp macro called
-% |\xintGCDof| which handled braced items to which it applied |\xintNum|
-% before handling the computations on integers only. The macro keeps the
-% former name \xintgcdnameimp, and handles fractions presented as braced
-% items. It is now the support macro for the |gcd()| function in |\xintexpr|
-% and |\xintfloatexpr|.
+% This inherits from former non public \xintexprnameimp macro called
+% |\xintGCDof:csv|, which handled comma separated items.
%
-% The support macro for the |gcd()| function in |\xintiiexpr| is
-% \csbxint{iiGCDof} which is located in \xintnameimp.
+% It handles fractions presented as braced items and is the support macro
+% for the |gcd()| function in |\xintexpr| and |\xintfloatexpr|. The support
+% macro for the |gcd()| function in |\xintiiexpr| is \csbxint{iiGCDof}, from
+% \xintnameimp.
%
+% An empty input is allowed but I have some hesitations on the return
+% value of 1.
+%
+% \changed{1.4d}{}
+% Sadly the |1.4| version had multiple problems:
+% \begin{itemize}
+% \item broken if first argument vanished,
+% \item broken if some argument was not in strict format, for example
+% had leading chains of signs or zeros (|\xintGCDof{2}{03}|).
+% This bug originates in the fact the original macro
+% was used only in \xintexprnameimp sanitized context.
+% \end{itemize}
%
+% Also, output is now always an irreducible fraction (ending with |[0]|).
% \begin{macrocode}
\def\xintGCDof {\romannumeral0\xintgcdof}%
\def\xintgcdof #1{\expandafter\XINT_fgcdof\romannumeral`&&@#1^}%
\def\XINT_GCDof{\romannumeral0\XINT_fgcdof}%
-% \end{macrocode}
-% \lverb|This abuses the way \xintiiabs works in order to avoid fetching whole
-% argument again: \xintiiabs ^ raises no error.
-% |
-% \begin{macrocode}
\def\XINT_fgcdof #1%
{%
- \xint_gob_til_^ #1\XINT_fgcdof_empty ^%
- \expandafter\XINT_fgcdof_loop\romannumeral0\xintiiabs#1\xint:
+ \expandafter\XINT_fgcdof_chkempty\romannumeral`&&@#1\xint:
+}%
+\def\XINT_fgcdof_chkempty #1%
+{%
+ \xint_gob_til_^#1\XINT_fgcdof_empty ^\XINT_fgcdof_in #1%
+}%
+\def\XINT_fgcdof_empty #1\xint:{ 1/1[0]}% hesitation, should it be infinity? O?
+\def\XINT_fgcdof_in #1\xint:
+{%
+ \expandafter\XINT_fgcd_out
+ \romannumeral0\expandafter\XINT_fgcdof_loop
+ \romannumeral0\xintrez{\xintPIrr{\xintAbs{#1}}}\xint:
}%
-\def\XINT_fgcdof_empty ^#1\xint:{ 1/1[0]}%
\def\XINT_fgcdof_loop #1\xint:#2%
{%
- \expandafter\XINT_fgcdof_loop_a\romannumeral0\xintiiabs#2\xint:#1\xint:
+ \expandafter\XINT_fgcdof_chkend\romannumeral`&&@#2\xint:#1\xint:\xint:
+}%
+\def\XINT_fgcdof_chkend #1%
+{%
+ \xint_gob_til_^#1\XINT_fgcdof_end ^\XINT_fgcdof_loop_pair #1%
+}%
+\def\XINT_fgcdof_end #1\xint:#2\xint:\xint:{ #2}%
+\def\XINT_fgcdof_loop_pair #1\xint:#2%
+{%
+ \expandafter\XINT_fgcdof_loop
+ \romannumeral0\expandafter\XINT_fgcd_chkzeros\expandafter#2%
+ \romannumeral0\xintrez{\xintPIrr{\xintAbs{#1}}}\xint:#2%
}%
% \end{macrocode}
+% \subsection{\csh{xintLCM}}
+% Same comments as for \csh{xintGCD}.
+% Entirely redone for |1.4d|.
+% Well, actually we can express it in terms of fractional gcd.
% \begin{macrocode}
-\def\XINT_fgcdof_loop_a#1#2\xint:#3\xint:
+\def\xintLCM {\romannumeral0\xintlcm}%
+\def\xintlcm #1%
{%
- \xint_gob_til_^ #1\XINT_fgcdof_end ^%
- \xint_gob_til_zero #1\XINT_fgcdof_skip 0%
- \expandafter\XINT_fgcdof_loop_b\romannumeral0\xintmod{#1#2}{#3}\xint:#3\xint:
+ \expandafter\XINT_flcm_in
+ \romannumeral0\xintrez{\xintPIrr{\xintAbs{#1}}}\xint:
}%
-\def\XINT_fgcdof_end ^#1\xint:#2\xint:{ #2}%
-\def\XINT_fgcdof_skip 0%
- \expandafter\XINT_fgcdof_loop_b\romannumeral0\xintmod#1\xint:
+\def\XINT_flcm_in #1#2\xint:#3%
{%
- \XINT_fgcdof_loop
+ \expandafter\XINT_fgcd_out
+ \romannumeral0\expandafter\XINT_flcm_chkzeros\expandafter#1%
+ \romannumeral0\xintrez{\xintPIrr{\xintAbs{#3}}}\xint:#1#2\xint:
}%
-\def\XINT_fgcdof_loop_b#1#2\xint:#3\xint:
+\def\XINT_flcm_chkzeros #1#2%
{%
- \xint_gob_til_zero #1\XINT_fgcdof_next 0%
- \expandafter\XINT_fgcdof_loop_b\romannumeral0\xintmod{#3}{#1#2}\xint:#1#2\xint:
+ \xint_UDzerofork
+ #1\XINT_flcm_zero
+ #2\XINT_flcm_zero
+ 0\XINT_flcm_main
+ \krof #2%
}%
-\def\XINT_fgcdof_next 0%
- \expandafter\XINT_fgcdof_loop_b\romannumeral0\xintmod#1#2\xint:#3\xint:#4%
+\def\XINT_flcm_zero #1\xint:#2\xint:{ 0/1[0]}%
+\def\XINT_flcm_main #1/#2[#3]\xint:#4/#5[#6]\xint:
{%
- \expandafter\XINT_fgcdof_loop_a\romannumeral0\xintiiabs#4\xint:#1\xint:
+ \xintinv
+ {%
+ \romannumeral0\XINT_fgcd_main #2/#1[-#3]\xint:#5/#4[-#6]\xint:
+ }%
}%
% \end{macrocode}
% \subsection{\csh{xintLCMof}}
-% See comments for |\xintGCDof|. \xintnameimp provides integer only \csbxint{iiLCMof}.
+% See comments for |\xintGCDof|. \xintnameimp provides the integer only
+% \csbxint{iiLCMof}.
+%
+% \changes{1.4d}{}
+% Sadly, although a public \xintfracnameimp macro, it did not (since |1.4|)
+% sanitize its arguments like other \xintfracnameimp macros.
%
% \begin{macrocode}
\def\xintLCMof {\romannumeral0\xintlcmof}%
@@ -31281,50 +31556,39 @@ math shift catcode.
\def\XINT_LCMof{\romannumeral0\XINT_flcmof}%
\def\XINT_flcmof #1%
{%
- \xint_gob_til_^ #1\XINT_flcmof_empty ^%
- \expandafter\XINT_flcmof_loop\romannumeral0\xintiiabs\xintRaw{#1}\xint:
+ \expandafter\XINT_flcmof_chkempty\romannumeral`&&@#1\xint:
}%
-\def\XINT_flcmof_empty ^#1\xint:{ 0/1[0]}%
-% \end{macrocode}
-% \lverb|\XINT_inv expects A/B[N] format which is the case here.|
-% \begin{macrocode}
-\def\XINT_flcmof_loop #1%
+\def\XINT_flcmof_chkempty #1%
{%
- \xint_gob_til_zero #1\XINT_flcmof_zero 0%
- \expandafter\XINT_flcmof_d\romannumeral0\XINT_inv #1%
+ \xint_gob_til_^#1\XINT_flcmof_empty ^\XINT_flcmof_in #1%
}%
-\def\XINT_flcmof_zero #1^{ 0/1[0]}%
-% \end{macrocode}
-% \lverb|\xintRaw{^} would raise an error thus we delay application of
-% \xintRaw to new item. As soon as we hit against a zero item, the l.c.m is
-% known to be zero itself. Else we need to inverse new item, but this requires
-% full A/B[N] raw format, hence the \xintraw.|
-% \begin{macrocode}
-\def\XINT_flcmof_d #1\xint:#2%
+\def\XINT_flcmof_empty #1\xint:{ 0/1[0]}% hesitation
+\def\XINT_flcmof_in #1\xint:
{%
- \expandafter\XINT_flcmof_loop_a\romannumeral0\xintiiabs#2\xint:#1\xint:
+ \expandafter\XINT_fgcd_out
+ \romannumeral0\expandafter\XINT_flcmof_loop
+ \romannumeral0\xintrez{\xintPIrr{\xintAbs{#1}}}\xint:
}%
-\def\XINT_flcmof_loop_a #1#2\xint:%
+\def\XINT_flcmof_loop #1\xint:#2%
{%
- \xint_gob_til_^ #1\XINT_flcmof_end ^%
- \xint_gob_til_zero #1\XINT_flcmof_zero 0%
- \expandafter\XINT_flcmof_loop_b\romannumeral0\expandafter\XINT_inv
- \romannumeral0\xintraw{#1#2}\xint:
+ \expandafter\XINT_flcmof_chkend\romannumeral`&&@#2\xint:#1\xint:\xint:
}%
-\def\XINT_flcmof_end ^#1\xint:#2\xint:{\XINT_inv #2}%
-% \end{macrocode}
-% \lverb|This is Euclide algorithm.|
-% \begin{macrocode}
-\def\XINT_flcmof_loop_b #1#2\xint:#3\xint:
+\def\XINT_flcmof_chkend #1%
{%
- \xint_gob_til_zero #1\XINT_flcmof_next 0%
- \expandafter\XINT_flcmof_loop_b\romannumeral0\xintmod{#3}{#1#2}\xint:#1#2\xint:
+ \xint_gob_til_^#1\XINT_flcmof_end ^\XINT_flcmof_loop_pair #1%
}%
-\def\XINT_flcmof_next 0%
- \expandafter\XINT_flcmof_loop_b\romannumeral0\xintmod#1#2\xint:#3\xint:#4%
+\def\XINT_flcmof_end #1\xint:#2\xint:\xint:{ #2}%
+\def\XINT_flcmof_loop_pair #1\xint:#2%
{%
- \expandafter\XINT_flcmof_loop_a\romannumeral0\xintiiabs#4\xint:#1\xint:
+ \expandafter\XINT_flcmof_chkzero
+ \romannumeral0\expandafter\XINT_flcm_chkzeros\expandafter#2%
+ \romannumeral0\xintrez{\xintPIrr{\xintAbs{#1}}}\xint:#2%
}%
+\def\XINT_flcmof_chkzero #1%
+{%
+ \xint_gob_til_zero#1\XINT_flcmof_zero0\XINT_flcmof_loop#1%
+}%
+\def\XINT_flcmof_zero#1^{ 0/1[0]}%
% \end{macrocode}
% \subsection{Floating point macros}
%
@@ -33797,7 +34061,7 @@ math shift catcode.
% \begin{macrocode}
\XINT_providespackage
\ProvidesPackage{xintseries}%
- [2021/02/20 v1.4c Expandable partial sums with xint package (JFB)]%
+ [2021/03/29 v1.4d Expandable partial sums with xint package (JFB)]%
% \end{macrocode}
% \subsection{\csh{xintSeries}}
% \begin{macrocode}
@@ -34298,7 +34562,7 @@ math shift catcode.
% \begin{macrocode}
\XINT_providespackage
\ProvidesPackage{xintcfrac}%
- [2021/02/20 v1.4c Expandable continued fractions with xint package (JFB)]%
+ [2021/03/29 v1.4d Expandable continued fractions with xint package (JFB)]%
% \end{macrocode}
% \subsection{\csh{xintCFrac}}
% \begin{macrocode}
@@ -35690,7 +35954,7 @@ math shift catcode.
% \begin{macrocode}
\XINT_providespackage
\ProvidesPackage{xintexpr}%
- [2021/02/20 v1.4c Expandable expression parser (JFB)]%
+ [2021/03/29 v1.4d Expandable expression parser (JFB)]%
\catcode`! 11
\let\XINT_Cmp \xintiiCmp
\def\XINTfstop{\noexpand\XINTfstop}%
@@ -35713,7 +35977,10 @@ math shift catcode.
% \subsubsection{Bracketed list rendering with prettifying of leaves from nested
% braced contents}
% \lverb|1.4 The braces in \XINT:expr:toblistwith are there because there is
-% an \expanded trigger.|
+% an \expanded trigger.
+%
+% 1.4d: support for polexpr 0.8 polynomial type.
+% |
% \begin{macrocode}
\def\XINT:expr:toblistwith#1#2%
{%
@@ -35729,8 +35996,13 @@ math shift catcode.
\def\XINT:expr:toblist_a #1{#2%
<%
\if{#2\xint_dothis<[\XINT:expr:toblist_a>\fi
+ \if P#2\xint_dothis<\XINT:expr:toblist_pol>\fi
\xint_orthat\XINT:expr:toblist_b #1#2%
>%
+\def\XINT:expr:toblist_pol #1!#2.{#3}}%
+<%
+ pol([\XINT:expr:toblist_b #1!#3}^])\XINT:expr:toblist_c #1!}%
+>%
\def\XINT:expr:toblist_b #1!#2}%
<%
\if\relax#2\relax\xintexprEmptyItem\else#1<#2>\fi\XINT:expr:toblist_c #1!}%
@@ -36235,7 +36507,6 @@ math shift catcode.
\let\XINT:NEhook:f:one:from:two\expandafter
\let\XINT:NEhook:f:one:from:two:direct\empty
\let\XINT:NEhook:x:one:from:two\empty
-\let\XINT:NEhook:x:one:from:twoandone\empty
\let\XINT:NEhook:f:one:and:opt:direct \empty
\let\XINT:NEhook:f:tacitzeroifone:direct \empty
\let\XINT:NEhook:f:iitacitzeroifone:direct \empty
@@ -36969,10 +37240,6 @@ math shift catcode.
% This means cases like (a+b)/(c+d)(e+f) will first multiply the last two
% parenthesized terms.
%
-% The ! starting a sub-expression must be distinguished from the post-fix !
-% for factorial, thus we must not do a too early \string. In versions < 1.2c,
-% the catcode 11 ! had to be identified in all branches of the number or
-% function scans. Here it is simply treated as a special case of a letter.
%
% 1.2q adds tacit multiplication in cases such as (1+1)3 or 5!7!
%
@@ -37396,11 +37663,11 @@ math shift catcode.
\XINT_expr_defbin_b {flexpr}{xor}{vi}{xii} {xintXOR}%
\XINT_expr_defbin_b {iiexpr}{xor}{vi}{xii} {xintXOR}%
\XINT_expr_defbin_b {expr} {//} {xiv}{xiv}{xintDivFloor}%
-\XINT_expr_defbin_b {flexpr}{//} {xiv}{xiv}{XINTinFloatDivFloor}% "
-\XINT_expr_defbin_b {iiexpr}{//} {xiv}{xiv}{xintiiDivFloor}% "
-\XINT_expr_defbin_b {expr} {/:} {xiv}{xiv}{xintMod}% "
-\XINT_expr_defbin_b {flexpr}{/:} {xiv}{xiv}{XINTinFloatMod}% "
-\XINT_expr_defbin_b {iiexpr}{/:} {xiv}{xiv}{xintiiMod}% "
+\XINT_expr_defbin_b {flexpr}{//} {xiv}{xiv}{XINTinFloatDivFloor}%
+\XINT_expr_defbin_b {iiexpr}{//} {xiv}{xiv}{xintiiDivFloor}%
+\XINT_expr_defbin_b {expr} {/:} {xiv}{xiv}{xintMod}%
+\XINT_expr_defbin_b {flexpr}{/:} {xiv}{xiv}{XINTinFloatMod}%
+\XINT_expr_defbin_b {iiexpr}{/:} {xiv}{xiv}{xintiiMod}%
\XINT_expr_defbin_b {expr} + {xii}{xii}{xintAdd}%
\XINT_expr_defbin_b {flexpr} + {xii}{xii}{XINTinFloatAdd}%
\XINT_expr_defbin_b {iiexpr} + {xii}{xii}{xintiiAdd}%
@@ -38414,7 +38681,7 @@ math shift catcode.
*\unexpanded{\expandafter\expandafter}%
\expandafter\noexpand\csname XINT_expr_var_#1\endcsname(}%
\ifxintverbose\xintMessage{xintexpr}{Info}
- {Variable "#1" \ifxintglobaldefs globally \fi
+ {Variable #1 \ifxintglobaldefs globally \fi
defined with value \csname XINT_expr_varvalue_#1\endcsname.}%
\fi
}%
@@ -39801,7 +40068,7 @@ math shift catcode.
% {float}{sfloat}{ilog10}
% {divmod}{mod}{binomial}{pfactorial}
% {randrange}
-% {quo}{rem}{gcd}{lcm}{max}{min}
+% {iquo}{irem}{gcd}{lcm}{max}{min}
% {`+`}{`*`}
% {all}{any}{xor}
% {len}{first}{last}{reversed}
@@ -40268,27 +40535,13 @@ math shift catcode.
{\xintiiRandRange{#1}}%
{\xintiiRandRangeAtoB{#1}{#2}}%
}%
-\def\XINT_expr_func_quo #1#2#3%
-{%
- \expandafter #1\expandafter #2\expandafter{\romannumeral`&&@%
- \XINT:NEhook:f:one:from:two
- {\romannumeral`&&@\xintiQuo #3}}%
-}%
-\let\XINT_flexpr_func_quo\XINT_expr_func_quo
-\def\XINT_iiexpr_func_quo #1#2#3%
+\def\XINT_iiexpr_func_iquo #1#2#3%
{%
\expandafter #1\expandafter #2\expandafter{\romannumeral`&&@%
\XINT:NEhook:f:one:from:two
{\romannumeral`&&@\xintiiQuo #3}}%
}%
-\def\XINT_expr_func_rem #1#2#3%
-{%
- \expandafter #1\expandafter #2\expandafter{\romannumeral`&&@%
- \XINT:NEhook:f:one:from:two
- {\romannumeral`&&@\xintiRem #3}}%
-}%
-\let\XINT_flexpr_func_rem\XINT_expr_func_rem
-\def\XINT_iiexpr_func_rem #1#2#3%
+\def\XINT_iiexpr_func_irem #1#2#3%
{%
\expandafter #1\expandafter #2\expandafter{\romannumeral`&&@%
\XINT:NEhook:f:one:from:two
@@ -41024,7 +41277,7 @@ math shift catcode.
}}\expandafter\XINT:NE:f:iitacitzeroifone:direct\string#%
\def\XINT:NE:f:iitacitzeroifone_a #1#2&&A#3%
{%
- \detokenize{\romannumeral`-0\expandafter#1\expanded{#2}$XINT_expr_exclam#3}%$
+ \detokenize{\romannumeral`$XINT_expr_null\expandafter#1\expanded{#2}$XINT_expr_exclam#3}%
}%
\def\XINT:NE:f:iitacitzeroifone_b\XINT:expr:f:iitacitzeroifone #1#2#3&&A#4%
{%
@@ -41045,16 +41298,6 @@ math shift catcode.
}}\expandafter\XINT:NE:x:one:from:two_fork\string#%
\def\XINT:NE:x:one:from:two:p #1#2#3%
{~expanded{\detokenize{\expandafter#1}~expanded{{#2}{#3}}}}%
-\def\XINT:NE:x:one:from:twoandone #1#2#3{\XINT:NE:x:one:from:twoandone_a #2#3&&A#1{#2}{#3}}%
-\def\XINT:NE:x:one:from:twoandone_a #1#2{\XINT:NE:x:one:from:twoandone_fork #1&&A#2&&A}%
-\def\XINT:NE:x:one:from:twoandone_fork #1{%
-\def\XINT:NE:x:one:from:twoandone_fork ##1##2&&A##3##4&&A##5##6&&A%
-{%
- \if0\XINT:NE:hastilde ##1##3##5~!\relax\XINT:NE:hashash ##1##3##5#1!\relax 0%
- \else
- \expandafter\XINT:NE:x:one:from:two:p
- \fi
-}}\expandafter\XINT:NE:x:one:from:twoandone_fork\string#%
\def\XINT:NE:x:listsel #1{%
\def\XINT:NE:x:listsel ##1##2&%
{%
@@ -41065,13 +41308,12 @@ math shift catcode.
\fi
##1##2&%
}}\expandafter\XINT:NE:x:listsel\string#%
-\def\XINT:NE:x:listsel:p #1#2&(#3%
+\def\XINT:NE:x:listsel:p #1#2_#3&(#4%
{%
- \detokenize
- {%
- \expanded{\expandafter#1\expanded{#2$XINT_expr_tab({#3}}\expandafter\empty\empty}%$
- }%
+ \detokenize{\expanded\XINT:expr:ListSel{{#3}{#4}}}%
}%
+\def\XINT:expr:ListSel{\expandafter\XINT:expr:ListSel_i\expanded}%
+\def\XINT:expr:ListSel_i #1#2{{\XINT_ListSel_top #2_#1&({#2}}}%
\def\XINT:NE:f:reverse #1{%
\def\XINT:NE:f:reverse ##1^%
{%
@@ -41084,13 +41326,14 @@ math shift catcode.
}}\expandafter\XINT:NE:f:reverse\string#%
\def\XINT:NE:f:reverse:p #1^#2\xint_bye
{%
- \detokenize
- {%
- \romannumeral0\expandafter\XINT:expr:f:reverse
- \expandafter{\expanded\expandafter{\xint_gobble_i#1}}%
- }%
+ \expandafter\XINT:NE:f:reverse:p_i\expandafter{\xint_gobble_i#1}%
}%
-\def\XINT:expr:f:reverse #1%
+\def\XINT:NE:f:reverse:p_i #1%
+{%
+ \detokenize{\romannumeral0\XINT:expr:f:reverse{{#1}}}%
+}%
+\def\XINT:expr:f:reverse{\expandafter\XINT:expr:f:reverse_i\expanded}%
+\def\XINT:expr:f:reverse_i #1%
{%
\XINT_expr_reverse #1^^#1\xint:\xint:\xint:\xint:
\xint:\xint:\xint:\xint:\xint_bye
@@ -41118,7 +41361,7 @@ math shift catcode.
##1{##2}%
}}\expandafter\XINT:NE:f:noeval:from:braced:u\string#%
\def\XINT:NE:f:noeval:from:braced:u:p #1#2%
- {\detokenize{\expandafter#1}~expanded{{#2}}}%
+ {\detokenize{\romannumeral`$XINT_expr_null\expandafter#1}~expanded{{#2}}}%
\catcode`- 11
\def\XINT:NE:exec_? #1#2%
{%
@@ -41518,7 +41761,6 @@ math shift catcode.
\let\XINT:NEhook:f:one:from:two \XINT:NE:f:one:from:two
\let\XINT:NEhook:f:one:from:two:direct \XINT:NE:f:one:from:two:direct
\let\XINT:NEhook:x:one:from:two \XINT:NE:x:one:from:two
- \let\XINT:NEhook:x:one:from:twoandone \XINT:NE:x:one:from:twoandone
\let\XINT:NEhook:f:one:and:opt:direct \XINT:NE:f:one:and:opt:direct
\let\XINT:NEhook:f:tacitzeroifone:direct \XINT:NE:f:tacitzeroifone:direct
\let\XINT:NEhook:f:iitacitzeroifone:direct \XINT:NE:f:iitacitzeroifone:direct
@@ -41678,6 +41920,7 @@ math shift catcode.
\def\XINT_expr_tilde{~}\def\XINT_expr_qmark{?}% catcode 3
\def\XINT_expr_caret{^}\def\XINT_expr_exclam{!}% catcode 11
\def\XINT_expr_tab{&}% catcode 7
+\def\XINT_expr_null{&&@}%
\catcode`~ 13 \catcode`@ 14 \catcode`\% 6 \catcode`# 12 \catcode`$ 11 @ $
\def\XINT_NewExpr_a %1%2%3%4%5@
{@
@@ -41869,10 +42112,10 @@ math shift catcode.
\expandafter\xint_secondoftwo
\fi
{\immediate\write-1{Reloading xinttrig library using Digits=\xinttheDigits.}}%
-{\expandafter\gdef\csname xintlibver@trig\endcsname{2021/02/20 v1.4c}%
+{\expandafter\gdef\csname xintlibver@trig\endcsname{2021/03/29 v1.4d}%
\XINT_providespackage
\ProvidesPackage{xinttrig}%
-[2021/02/20 v1.4c Trigonometrical functions for xintexpr (JFB)]%
+[2021/03/29 v1.4d Trigonometrical functions for xintexpr (JFB)]%
}%
% \end{macrocode}
% \subsection{Ensure used letters are dummy letters}
@@ -42868,7 +43111,7 @@ math shift catcode.
\xintexprSafeCatcodes\catcode`_ 11
\XINT_providespackage
\ProvidesPackage{xintlog}%
-[2021/02/20 v1.4c Logarithms and exponentials for xintexpr (JFB)]%
+[2021/03/29 v1.4d Logarithms and exponentials for xintexpr (JFB)]%
% \end{macrocode}
% \subsection{Loading of \cshn{poormanlog} package}
% \lverb|Attention to catcode regime when loading poormanlog. It matters less
@@ -42882,13 +43125,13 @@ math shift catcode.
\fi
% \end{macrocode}
% \lverb|\XINT_setcatcodes switches to the standard catcode regime of
-% xint*.sty files. And we need the xintexpr catcode for ! too (cf
-% \XINT_expr_func_pow)
+% xint*.sty files. Formerly we needed here the ! of catcode 11 as in
+% xintexpr.sty, which is set by \XINT_setcatcodes but does not apply now.
%
% See the remark above about importance of doing \xintexprRestoreCatcodes if
% \xintexprSafeCatcodes has been used...|
% \begin{macrocode}
-\xintexprRestoreCatcodes\csname XINT_setcatcodes\endcsname\catcode`\! 11
+\xintexprRestoreCatcodes\csname XINT_setcatcodes\endcsname
% \end{macrocode}
% \subsection{The \cshn{log10()} and \cshn{pow10()} functions}
% \lverb|The support macros from poormanlog v0.04 \PoorManLogBaseTen,
@@ -42941,9 +43184,6 @@ math shift catcode.
\romannumeral`&&@\XINT:NEhook:f:one:from:one
{\romannumeral`&&@\XINTinFloatExp#3}}%
}%
-% \end{macrocode}
-% \lverb|Attention that the ! is of catcode 11 here.|
-% \begin{macrocode}
\def\XINT_expr_func_pow #1#2#3%
{%
\expandafter #1\expandafter #2\expandafter{%
@@ -42954,7 +43194,11 @@ math shift catcode.
% \end{macrocode}
% \subsection{\csh{poormanloghack}}
% \lverb|With \poormanloghack{**}, the ** operator will use pow10(y*log10(x)).
-% Same for ^. Sync'd with xintexpr 1.4.|
+% Same for ^. Sync'd with xintexpr 1.4.
+%
+% MEMO: the reason why I need to redefine a lot of stuff is that xintexpr.sty
+% does the job only for ^ and then does a \let for exec_** only. So if now
+% ^ and ** possibly act differently all must be duplicated.|
% \begin{macrocode}
\catcode`\* 11
\def\poormanloghack**
@@ -43064,9 +43308,9 @@ math shift catcode.
xint.sty:205
xintbinhex.sty:53
xintcfrac.sty:183
-xintcore.sty:271
-xintexpr.sty:430
-xintfrac.sty:496
+xintcore.sty:272
+xintexpr.sty:428
+xintfrac.sty:507
xintgcd.sty:41
xintkernel.sty:17
xintlog.sty:9
@@ -43075,15 +43319,15 @@ xinttools.sty:157
xinttrig.sty:31
\fi
% grep -o "^{%" xint*sty | wc -l
-\def\totala{ 1941}
+\def\totala{ 1951}
\iffalse
% grep -c -e "^}%" xint*sty
xint.sty:204
xintbinhex.sty:52
xintcfrac.sty:183
-xintcore.sty:268
-xintexpr.sty:413
-xintfrac.sty:499
+xintcore.sty:269
+xintexpr.sty:412
+xintfrac.sty:510
xintgcd.sty:43
xintkernel.sty:18
xintlog.sty:9
@@ -43092,7 +43336,7 @@ xinttools.sty:156
xinttrig.sty:32
\fi
% grep -o "^}%" xint*sty | wc -l
-\def\totalb{ 1925}
+\def\totalb{ 1936}
\cleardoublepage
\section{Cumulative line count}
@@ -43116,8 +43360,8 @@ xinttrig.sty:32
\TeX\strut. Version {\xintbndlversion} of {\xintbndldate}.\par
}
-\CheckSum {35109}% 1.4c
-% 35103 pour 1.4b, 34648 pour 1.4a, 34575 pour 1.4
+\CheckSum {35184}% 1.4d
+% 35109 pour 1.4c, 35103 pour 1.4b, 34648 pour 1.4a, 34575 pour 1.4
% 33497 pour 1.3f, 33274 pour 1.3e, 31601 pour 1.3d, 31122 pour 1.3c
% 31069 pour 1.3b, 30482 pour 1.3a, 30621 pour 1.3, 30988 pour 1.2q,
% 30982 pour 1.2p, 30524 pour 1.2o, 30303 pour 1.2h, 30403 pour 1.2i,
diff --git a/macros/generic/xint/xint.pdf b/macros/generic/xint/xint.pdf
index 5be576e57e..35ac85b1b0 100644
--- a/macros/generic/xint/xint.pdf
+++ b/macros/generic/xint/xint.pdf
Binary files differ
diff --git a/macros/latex/contrib/pkuthss/doc/example.pdf b/macros/latex/contrib/pkuthss/doc/example.pdf
index ea1a631bda..a548fbcc13 100644
--- a/macros/latex/contrib/pkuthss/doc/example.pdf
+++ b/macros/latex/contrib/pkuthss/doc/example.pdf
Binary files differ
diff --git a/macros/latex/contrib/pkuthss/doc/example/chap/abs.tex b/macros/latex/contrib/pkuthss/doc/example/chap/abs.tex
index 305792f836..ea215a83c1 100644
--- a/macros/latex/contrib/pkuthss/doc/example/chap/abs.tex
+++ b/macros/latex/contrib/pkuthss/doc/example/chap/abs.tex
@@ -1,12 +1,12 @@
-% Copyright (c) 2014,2016 Casper Ti. Vector
+% Copyright (c) 2014,2016,2021 Casper Ti. Vector
% Public domain.
\begin{cabstract}
\pkuthssffaq % 中文测试文字。
\end{cabstract}
-\begin{eabstract}
+\ifblind\begin{beabstract}\else\begin{eabstract}\fi
Test of the English abstract.
-\end{eabstract}
+\ifblind\end{beabstract}\else\end{eabstract}\fi
% vim:ts=4:sw=4
diff --git a/macros/latex/contrib/pkuthss/doc/example/chap/origin.tex b/macros/latex/contrib/pkuthss/doc/example/chap/origin.tex
index 49d25b5425..b4103f1bf4 100644
--- a/macros/latex/contrib/pkuthss/doc/example/chap/origin.tex
+++ b/macros/latex/contrib/pkuthss/doc/example/chap/origin.tex
@@ -1,5 +1,6 @@
% Copyright (c) 2008-2009 solvethis
-% Copyright (c) 2010-2017 Casper Ti. Vector
+% Copyright (c) 2010-2017,2021 Casper Ti. Vector
+% Copyright (c) 2021 Kurapica
% All rights reserved.
%
% Redistribution and use in source and binary forms, with or without
@@ -31,10 +32,11 @@
\ctexset{section = {
format+ = {\centering}, beforeskip = {40bp}, afterskip = {15bp}
}}
-
- % 学校书面要求本页面不要页码,但在给出的 Word 模版中又有页码且编入了目录。
- % 此处以 Word 模版为实际标准进行设定。
\specialchap{北京大学学位论文原创性声明和使用授权说明}
+
+ % 学校书面要求本页面不要页码,但在给出的 Word 模版中又有页码。
+ % 此处以学校书面要求为准。
+ \thispagestyle{empty}
\mbox{}\vspace*{-3em}
\section*{原创性声明}
diff --git a/macros/latex/contrib/pkuthss/doc/example/thesis.tex b/macros/latex/contrib/pkuthss/doc/example/thesis.tex
index 9c5f042cb4..30bc89d1aa 100644
--- a/macros/latex/contrib/pkuthss/doc/example/thesis.tex
+++ b/macros/latex/contrib/pkuthss/doc/example/thesis.tex
@@ -1,5 +1,6 @@
% Copyright (c) 2008-2009 solvethis
-% Copyright (c) 2010-2016,2018-2019 Casper Ti. Vector
+% Copyright (c) 2010-2016,2018-2019,2021 Casper Ti. Vector
+% Copyright (c) 2021 Kurapica
% Public domain.
%
% 使用前请先仔细阅读 pkuthss 和 biblatex-caspervector 的文档,
@@ -9,6 +10,7 @@
% texdoc biblatex-caspervector
% 调出。
+% 如果格式审查提示字号不严格符合标准,可以在 [] 中加入“ugly”选项。
\documentclass[UTF8]{pkuthss}
% 如果的确须要使脚注按页编号的话,可以去掉后面 footmisc 包的注释。
%\usepackage[perpage]{footmisc}
@@ -18,6 +20,8 @@
% 若须按照中文文献在前,西文文献在后排序,请设置“sorting = cenyt”;
% 若须按照引用顺序排序,请设置“sorting = none”。
% 若须在排序中实现更复杂的需求,请参考 biblatex-caspervector 的文档。
+% biblatex-caspervector 也有一个“ugly”选项,使其更像国标格式;此外也可考虑
+% 改用 style = gb7714-2015 并去掉之后两选项,详见 biblatex-gb7714-2015 的文档。
\usepackage[backend = biber, style = caspervector, utf8, sorting = ecnyt]{biblatex}
% 对于 linespread 值的计算过程有兴趣的同学可以参考 pkuthss.cls。
@@ -25,19 +29,26 @@
% 按学校要求设定参考文献列表的段间距。
\setlength{\bibitemsep}{3bp}
+% 如是双盲版论文,将 \blindfalse 改为 \blindtrue。后面可用
+% \ifblind 根据是否双盲来条件地启用代码(参见本文件后面部分)。
+\newif\ifblind\blindfalse
% 设定文档的基本信息。
\pkuthssinfo{
- cthesisname = {博士研究生学位论文}, ethesisname = {Doctor Thesis},
- ctitle = {测试文档}, etitle = {Test Document},
- cauthor = {某某},
- eauthor = {Test},
- studentid = {0123456789},
- date = {某年某月},
- school = {某某学院},
+ cthesisname = {博士学位论文}, ethesisname = {Doctor Thesis},
+ thesiscover = {博士研究生学位论文},
+ % 长标题可用 \thssnl 强制换行,不能用“\\”(双盲版会出错)。
+ ctitle = {测试文档},
+ etitle = {Test Document},
+ cauthor = {某某}, eauthor = {Test}, date = {某年某月},
+ studentid = {0123456789}, school = {某某学院},
cmajor = {某某专业}, emajor = {Some Major},
direction = {某某方向},
cmentor = {某某教授}, ementor = {Prof.\ Somebody},
- ckeywords = {其一,其二}, ekeywords = {First, Second}
+ ckeywords = {其一,其二},
+ ekeywords = {First, Second},
+ % 以下两项无双盲评审需求的用户可保持原状。
+ % 注意 discipline/major 分别指一/二级学科。
+ blindid = {9876543210}, discipline = {某某学科}
}
% 载入参考文献数据库(注意不要省略“.bib”)。
\addbibresource{thesis.bib}
@@ -57,7 +68,9 @@
如果编译时不出参考文献,
请参考 \texttt{texdoc pkuthss}“问题及其解决”一章
- “上游宏包可能引起的问题”一节中关于 biber 的说明。%
+ “上游宏包可能引起的问题”一节中关于 biber 的说明。
+
+ 因无法假定用户使用哪种方式排版表格,用户须自行保证表格字号符合学校规定。%
}
\begin{document}
@@ -66,7 +79,7 @@
% 此后到下一 \pagestyle 命令之前不排版页眉或页脚。
\pagestyle{empty}
% 自动生成封面。
- \maketitle
+ \ifblind\makeblind\else\maketitle\fi
% 版权声明。封面要求单面打印,故须新开右页。
\cleardoublepage
\include{chap/copy}
@@ -100,7 +113,7 @@
% 以下为正文之后的部分,默认不进行章节编号。
\backmatter
% 致谢。
- \include{chap/ack}
+ \ifblind\else\include{chap/ack}\fi
% 原创性声明和使用授权说明。
\include{chap/origin}
\end{document}
diff --git a/macros/latex/contrib/pkuthss/doc/pkuthss.pdf b/macros/latex/contrib/pkuthss/doc/pkuthss.pdf
index 837e526455..9d172c6554 100644
--- a/macros/latex/contrib/pkuthss/doc/pkuthss.pdf
+++ b/macros/latex/contrib/pkuthss/doc/pkuthss.pdf
Binary files differ
diff --git a/macros/latex/contrib/pkuthss/doc/readme/ChangeLog.txt b/macros/latex/contrib/pkuthss/doc/readme/ChangeLog.txt
index aaf026bf9f..1d7835cf92 100644
--- a/macros/latex/contrib/pkuthss/doc/readme/ChangeLog.txt
+++ b/macros/latex/contrib/pkuthss/doc/readme/ChangeLog.txt
@@ -1,3 +1,19 @@
+2010-03-29, v1.9.0
+
+ * API changes:
+ - Add support for double-blind review (thank @Kurapikov).
+ - Add `\thesiscover' for possibly different thesis name on the cover.
+
+ * Changes to package code:
+ - Greatly improve format compliance (thank @Kurapikov).
+
+ * Changes to documentation:
+ - More notes about table font and GB/T 7714.
+ - Avoid undefined `\textepsilon'.
+
+ * Misc:
+ - Minor fixes and cosmetics.
+
2020-11-02, v1.8.3
* Changes to example template:
diff --git a/macros/latex/contrib/pkuthss/doc/readme/chap/pkuthss-abs.tex b/macros/latex/contrib/pkuthss/doc/readme/chap/pkuthss-abs.tex
index 453d56bb69..06d2032350 100644
--- a/macros/latex/contrib/pkuthss/doc/readme/chap/pkuthss-abs.tex
+++ b/macros/latex/contrib/pkuthss/doc/readme/chap/pkuthss-abs.tex
@@ -1,7 +1,7 @@
% Documentation for pkuthss.
%
% Copyright (c) 2008-2009 solvethis
-% Copyright (c) 2010-2014 Casper Ti. Vector
+% Copyright (c) 2010-2014,2021 Casper Ti. Vector
%
% This work may be distributed and/or modified under the conditions of the
% LaTeX Project Public License, either version 1.3 of this license or (at
@@ -31,9 +31,9 @@
本文介绍了 pkuthss 文档模版所提供的功能。
\end{cabstract}
-\begin{eabstract}
+\ifblind\begin{beabstract}\else\begin{eabstract}\fi
This document describes the the functions provided by
the pkuthss document template.
-\end{eabstract}
+\ifblind\end{beabstract}\else\end{eabstract}\fi
% vim:ts=4:sw=4
diff --git a/macros/latex/contrib/pkuthss/doc/readme/chap/pkuthss-ack.tex b/macros/latex/contrib/pkuthss/doc/readme/chap/pkuthss-ack.tex
index 2859463747..cd2deb28e9 100644
--- a/macros/latex/contrib/pkuthss/doc/readme/chap/pkuthss-ack.tex
+++ b/macros/latex/contrib/pkuthss/doc/readme/chap/pkuthss-ack.tex
@@ -1,7 +1,7 @@
% Documentation for pkuthss.
%
% Copyright (c) 2008-2009 solvethis
-% Copyright (c) 2010-2012,2015 Casper Ti. Vector
+% Copyright (c) 2010-2012,2015,2021 Casper Ti. Vector
%
% This work may be distributed and/or modified under the conditions of the
% LaTeX Project Public License, either version 1.3 of this license or (at
@@ -31,7 +31,8 @@
感谢北大未名 BBS 上 MathTools 版和 Thesis 版诸位同学的支持。
特别感谢 pkuthss 模版的最初创作者 solvethis 网友,
-以及不断地对 Casper 提出的诸多问题予以解答的 cauchy 网友 :)
+不断地对 Casper 提出的诸多问题予以解答的 cauchy 网友,
+以及在论文格式合规性和双盲版论文格式上有主要贡献的 Kurapica 网友~:)
此外还要感谢 \parencite{pku-thesisstyle} 的作者,
让我校在学位论文格式要求的繁复程度上离隔壁更近了一步,
diff --git a/macros/latex/contrib/pkuthss/doc/readme/chap/pkuthss-chap2.tex b/macros/latex/contrib/pkuthss/doc/readme/chap/pkuthss-chap2.tex
index c7c1c75c18..5d2f91185b 100644
--- a/macros/latex/contrib/pkuthss/doc/readme/chap/pkuthss-chap2.tex
+++ b/macros/latex/contrib/pkuthss/doc/readme/chap/pkuthss-chap2.tex
@@ -1,7 +1,7 @@
% Documentation for pkuthss.
%
% Copyright (c) 2008-2009 solvethis
-% Copyright (c) 2010-2019 Casper Ti. Vector
+% Copyright (c) 2010-2019,2021 Casper Ti. Vector
%
% This work may be distributed and/or modified under the conditions of the
% LaTeX Project Public License, either version 1.3 of this license or (at
@@ -150,7 +150,7 @@
\end{Verbatim}
\section{pkuthss 文档类提供的命令和环境}
-\subsection{设定文档信息的命令}
+\subsection{设定文档信息的命令}\label{ssec:set-cmd}
这一类命令的语法为
\begin{Verbatim}
@@ -159,21 +159,29 @@
这些命令总结如下:
\begin{itemize}
- \item \texttt{\bfseries\string\ctitle}:设定论文中文标题;
+ \item \texttt{\bfseries\string\ctitle}:设定论文中文标题\footnote{%
+ 因为 pkuthss 内部实现机制的缘故,\myemph{双盲版论文的(中文和西文)
+ 标题如须强制换行,必须使用 pkuthss 提供的 \texttt{\string\thssnl}
+ 命令而非 \texttt{\string\\}},否则会出错。%
+ };
\item \texttt{\bfseries\string\etitle}:设定论文西文标题;
\item \texttt{\bfseries\string\cauthor}:设定作者的中文名;
\item \texttt{\bfseries\string\eauthor}:设定作者的西文名;
- \item \texttt{\bfseries\string\studentid}:设定作者的学号;
\item \texttt{\bfseries\string\date}:设定日期;
+ \item \texttt{\bfseries\string\studentid}:设定作者的学号;
\item \texttt{\bfseries\string\school}:设定作者的学院名;
- \item \texttt{\bfseries\string\cmajor}:设定作者专业的中文名;
- \item \texttt{\bfseries\string\emajor}:设定作者专业的西文名;
+ \item \texttt{\bfseries\string\cmajor}:设定作者专业(二级学科)的中文名;
+ \item \texttt{\bfseries\string\emajor}:设定作者专业(二级学科)的西文名;
\item \texttt{\bfseries\string\direction}:设定作者的研究方向;
\item \texttt{\bfseries\string\cmentor}:设定导师的中文名;
\item \texttt{\bfseries\string\ementor}:设定导师的西文名;
\item \texttt{\bfseries\string\ckeywords}:设定中文关键词;
- \item \texttt{\bfseries\string\ekeywords}:设定西文关键词。
+ \item \texttt{\bfseries\string\ekeywords}:设定西文关键词;
+ \item \texttt{\bfseries\string\blindid}:设定论文编号(双盲评审用);
+ \item \texttt{\bfseries\string\discipline}:设定一级学科(双盲评审用)。
\end{itemize}
+排版双盲版论文时除了要去掉致谢等章节、隐去论文中其它可能泄露个人信息的部分外,
+还应注意在排版封面时须使用 \verb|\makeblind| 而非 \verb|\maketitle| 命令。
例如,如果要设定专业为“化学”(“Chemistry”),则可以使用以下命令:
\begin{Verbatim}
@@ -195,16 +203,20 @@
\item \texttt{\bfseries\string\euniversity}:大学的西文名。
\item \texttt{\bfseries\string\cthesisname}:论文类别的中文名。
\item \texttt{\bfseries\string\ethesisname}:论文类别的西文名。
+ \item \texttt{\bfseries\string\thesiscover}:封面显示的论文类别\footnote{%
+ 出于兼容性的考虑,如果 \texttt{\string\thesiscover} 为空,
+ 那么封面将显示 \texttt{\string\cthesisname}。%
+ }。
\item \texttt{\bfseries\string\cabstractname}:摘要的中文标题。
\item \texttt{\bfseries\string\eabstractname}:摘要的西文标题。
\end{itemize}
-例如,
-如果要设定论文的类别为“本科生毕业论文”(“Undergraduate Thesis”),
-则可以使用以下命令:
+例如,如果要设定论文的类别为“博士学位论文”(“Doctor Thesis”),
+但封面要显示“博士研究生学位论文”,则可以使用以下命令:
\begin{Verbatim}
-\renewcommand{\cthesisname}{本科生毕业论文}
-\renewcommand{\ethesisname}{Undergraduate Thesis}
+\renewcommand{\cthesisname}{博士学位论文}
+\renewcommand{\ethesisname}{Doctor Thesis}
+\renewcommand{\thesiscover}{博士研究生学位论文}
\end{Verbatim}
\subsection{以“key = value”格式设置文档信息}
@@ -235,8 +247,8 @@
\subsection{其它命令和环境}\label{ssec:misc}
-\texttt{\bfseries cabstract} 和 \texttt{\bfseries eabstract}
-环境用于编写中西文摘要。
+\texttt{\bfseries cabstract} 和 \texttt{\bfseries eabstract} 环境用于编写
+中西文摘要;\texttt{\bfseries beabstract} 环境用于编写双盲评审版的西文摘要。
用户只须要写摘要的正文;标题、作者、导师、专业等部分会自动生成。
\texttt{\bfseries\string\specialchap} 命令
@@ -258,6 +270,9 @@
此时就须要在设定完文档信息之后调用 \verb|\setpdfproperties|。%
\myemph{注意:须要启用 \texttt{pdfprop} 选项才能使用此命令。}
+\texttt{\bfseries\string\thssnl} 命令用于在双盲版论文的(中文和西文)标题中
+强制换行,见第 \ref{ssec:set-cmd} 小节中关于 \verb|\ctitle| 说明的脚注。
+
\section{从其它文档类和宏包继承的功能}\label{sec:thirdparty}
pkuthss 文档类建立在 ctexbook\cupercite{ctex} 文档类之上,
diff --git a/macros/latex/contrib/pkuthss/doc/readme/chap/pkuthss-chap3.tex b/macros/latex/contrib/pkuthss/doc/readme/chap/pkuthss-chap3.tex
index 0fbd72bd47..b5482a08eb 100644
--- a/macros/latex/contrib/pkuthss/doc/readme/chap/pkuthss-chap3.tex
+++ b/macros/latex/contrib/pkuthss/doc/readme/chap/pkuthss-chap3.tex
@@ -1,7 +1,7 @@
% Documentation for pkuthss.
%
% Copyright (c) 2008-2009 solvethis
-% Copyright (c) 2010-2019 Casper Ti. Vector
+% Copyright (c) 2010-2019,2021 Casper Ti. Vector
%
% This work may be distributed and/or modified under the conditions of the
% LaTeX Project Public License, either version 1.3 of this license or (at
@@ -33,6 +33,9 @@
文档默认情况下是双面模式,章末可能产生空白页,
解决方式见第 \ref{sec:options} 节。
+双盲版论文的(中文和西文)标题只能使用 pkuthss 提供的
+\verb|\thssnl| 命令而非 \verb|\\| 换行,见第 \ref{sec:options} 节。
+
通过一些设置,还可以满足例如被引用的文献按照引用顺序排序,
而未引用的文献按照西文文献在前、中文文献在后排序这样的需求,
见第 \ref{sec:thirdparty} 节。
@@ -97,14 +100,20 @@ data source .../par-xxxxxxxx/cache-xxxxxxxx/
\section{文档格式可能存在的问题}
-学校对学位论文格式的规定\cupercite{pku-thesisstyle}%
-显然没有考虑到非 MS Word 类排版工具的工作方式,
+目前在 \hologo{LaTeX} 中似乎没有一个可以很好地替代其它各类似宏包的
+用于排版表格的宏包,而 pkuthss 文档模版的作者也无意假定用户使用
+某一个宏包,因此模版并未尝试设定表格的默认字号,\myemph{用户
+须自行按学校规定\cupercite{pku-thesisstyle}进行设置}。
+
+学校对学位论文格式的规定显然没有考虑到非 MS Word 类排版工具的工作方式,
因此 pkuthss 文档模版只是对其要求的格式进行模仿,
而在一些小的细节上可能有所出入。
-biblatex-caspervector\cupercite{biblatex-caspervector} 所实现的格式和
-\parencite{pku-thesisstyle} 的规定并不一致,
-但其作者暂时没有精力也不愿意去实现后者所规定的比原格式更丑陋得多的格式。
+biblatex-caspervector\cupercite{biblatex-caspervector}
+所实现的格式和 \parencite{pku-thesisstyle} 的规定并不一致,
+但其作者没有精力也不愿意去实现后者所规定的比原格式更丑陋得多的格式。
+国标 GB/T 7714-2015 现在已经有了 biblatex-gb7714-2015%
+\cupercite{biblatex-gb7714-2015} 这一 biblatex 实现,用户也可以考虑使用。
\section{反馈意见和建议}
diff --git a/macros/latex/contrib/pkuthss/doc/readme/chap/pkuthss-copy.tex b/macros/latex/contrib/pkuthss/doc/readme/chap/pkuthss-copy.tex
index 68d86f34de..e9cecd08d3 100644
--- a/macros/latex/contrib/pkuthss/doc/readme/chap/pkuthss-copy.tex
+++ b/macros/latex/contrib/pkuthss/doc/readme/chap/pkuthss-copy.tex
@@ -32,7 +32,9 @@
版权所有 \copyright\ 2008--2009 solvethis
\par
-版权所有 \copyright\ 2010--2019 Casper Ti. Vector
+版权所有 \copyright\ 2010--2021 Casper Ti. Vector
+\par
+版权所有 \copyright\ 2021 Kurapica
\vskip 1em
pkuthss 文档类及其说明文档均以 \hologo{LaTeX} Project Public License 发布。
diff --git a/macros/latex/contrib/pkuthss/doc/readme/pkuthss-english.patch b/macros/latex/contrib/pkuthss/doc/readme/pkuthss-english.patch
index ee9cadcad2..40b508c77c 100644
--- a/macros/latex/contrib/pkuthss/doc/readme/pkuthss-english.patch
+++ b/macros/latex/contrib/pkuthss/doc/readme/pkuthss-english.patch
@@ -1,5 +1,5 @@
diff --git a/doc/example/chap/abs.tex b/doc/example/chap/abs.tex
-index 305792f..cfa6cd3 100644
+index dcffe0e..8fd046f 100644
--- a/doc/example/chap/abs.tex
+++ b/doc/example/chap/abs.tex
@@ -2,7 +2,7 @@
@@ -10,7 +10,7 @@ index 305792f..cfa6cd3 100644
+ 中文摘要。
\end{cabstract}
- \begin{eabstract}
+ \ifblind\begin{beabstract}\else\begin{eabstract}\fi
diff --git a/doc/example/chap/ack.tex b/doc/example/chap/ack.tex
index 4af4d39..09de33d 100644
--- a/doc/example/chap/ack.tex
@@ -100,10 +100,10 @@ index ac5b0c9..9d2ad60 100644
-
% vim:ts=4:sw=4
diff --git a/doc/example/thesis.tex b/doc/example/thesis.tex
-index 9c5f042..a54d01f 100644
+index 0009fe6..3f2d945 100644
--- a/doc/example/thesis.tex
+++ b/doc/example/thesis.tex
-@@ -12,54 +12,44 @@
+@@ -14,36 +14,42 @@
\documentclass[UTF8]{pkuthss}
% 如果的确须要使脚注按页编号的话,可以去掉后面 footmisc 包的注释。
%\usepackage[perpage]{footmisc}
@@ -113,6 +113,8 @@ index 9c5f042..a54d01f 100644
-% 若须按照中文文献在前,西文文献在后排序,请设置“sorting = cenyt”;
-% 若须按照引用顺序排序,请设置“sorting = none”。
-% 若须在排序中实现更复杂的需求,请参考 biblatex-caspervector 的文档。
+-% biblatex-caspervector 也有一个“ugly”选项,使其更像国标格式;此外也可考虑
+-% 改用 style = gb7714-2015 并去掉之后两选项,详见 biblatex-gb7714-2015 的文档。
-\usepackage[backend = biber, style = caspervector, utf8, sorting = ecnyt]{biblatex}
+% 使用 biblatex 排版参考文献,并规定其格式(详见 biblatex 的文档)。
+\usepackage[backend = biber]{biblatex}
@@ -136,27 +138,32 @@ index 9c5f042..a54d01f 100644
+ chapter/number = {\thechapter},
+}
+
+ % 如是双盲版论文,将 \blindfalse 改为 \blindtrue。后面可用
+ % \ifblind 根据是否双盲来条件地启用代码(参见本文件后面部分)。
+ \newif\ifblind\blindfalse
% 设定文档的基本信息。
\pkuthssinfo{
-- cthesisname = {博士研究生学位论文}, ethesisname = {Doctor Thesis},
-- ctitle = {测试文档}, etitle = {Test Document},
-- cauthor = {某某},
+- cthesisname = {博士学位论文}, ethesisname = {Doctor Thesis},
+- thesiscover = {博士研究生学位论文},
+ ethesisname = {Doctor Thesis},
-+ etitle = {Test Document},
- eauthor = {Test},
- studentid = {0123456789},
-- date = {某年某月},
-- school = {某某学院},
+ % 长标题可用 \thssnl 强制换行,不能用“\\”(双盲版会出错)。
+- ctitle = {测试文档},
+ etitle = {Test Document},
+- cauthor = {某某}, eauthor = {Test}, date = {某年某月},
+- studentid = {0123456789}, school = {某某学院},
- cmajor = {某某专业}, emajor = {Some Major},
- direction = {某某方向},
- cmentor = {某某教授}, ementor = {Prof.\ Somebody},
-+ date = {Some Date},
++ eauthor = {Test},
++ date = {Month Year}, studentid = {0123456789},
+ school = {Some School},
+ emajor = {Some Major},
+ direction = {Some Direction},
+ ementor = {Prof.\ Somebody},
- ckeywords = {其一,其二}, ekeywords = {First, Second}
- }
+ ckeywords = {其一,其二},
+ ekeywords = {First, Second},
+ % 以下两项无双盲评审需求的用户可保持原状。
+@@ -53,26 +59,6 @@
% 载入参考文献数据库(注意不要省略“.bib”)。
\addbibresource{thesis.bib}
@@ -175,18 +182,20 @@ index 9c5f042..a54d01f 100644
-
- 如果编译时不出参考文献,
- 请参考 \texttt{texdoc pkuthss}“问题及其解决”一章
-- “上游宏包可能引起的问题”一节中关于 biber 的说明。%
+- “上游宏包可能引起的问题”一节中关于 biber 的说明。
+-
+- 因无法假定用户使用哪种方式排版表格,用户须自行保证表格字号符合学校规定。%
-}
-
\begin{document}
% 以下为正文之前的部分,默认不进行章节编号。
\frontmatter
diff --git a/tex/pkuthss-utf8.def b/tex/pkuthss-utf8.def
-index 9bc6000..7650e53 100644
+index d968f90..f99a891 100644
--- a/tex/pkuthss-utf8.def
+++ b/tex/pkuthss-utf8.def
-@@ -25,13 +25,13 @@
- [2019/11/17 v1.8.2 Labels and captions in UTF-8 encoding
+@@ -26,13 +26,13 @@
+ [2020/11/02 v1.8.3 Labels and captions in UTF-8 encoding
for the pkuthss document class]
-\def\label@ctitle{题目:}
@@ -207,10 +216,10 @@ index 9bc6000..7650e53 100644
\def\label@ckeywords{关键词:}
\def\label@ekeywords{KEYWORDS:\ }
diff --git a/tex/pkuthss.cls b/tex/pkuthss.cls
-index e34fe2d..477b3f4 100644
+index 4499528..e6311cb 100644
--- a/tex/pkuthss.cls
+++ b/tex/pkuthss.cls
-@@ -304,7 +304,7 @@
+@@ -317,7 +317,7 @@
\fancyhf{}\renewcommand*{\headrulewidth}{0.75bp}
\fancyfoot[C]{\zihao{5}\normalfont{\thepage}}
\if@twoside
@@ -219,23 +228,24 @@ index e34fe2d..477b3f4 100644
\fancyhead[CO]{\zihao{5}\normalfont\thss@int@setcase{\leftmark}}
\else
\fancyhead[C]{\zihao{5}\normalfont\thss@int@setcase{\leftmark}}
-@@ -350,13 +350,13 @@
- \zihao{1}%
- \includegraphics[height = 2.4em]{pkulogo}\hspace{0.4em}%
- \raisebox{0.4em}{\includegraphics[height = 1.6em]{pkuword}}\\[0.8em]
-- {\bfseries{\cthesisname}}%
-+ {\bfseries{\ethesisname}}%
+@@ -367,14 +367,14 @@
+ \zihao{1}\includegraphics[height = 2.4em]{pkulogo}\hspace{0.4em}%
+ \raisebox{0.4em}{\includegraphics[height = 1.6em]{pkuword}}\\[0.8em]
+ \fi%
+- {\bfseries\ifx\thesiscover\empty{\cthesisname}\else{\thesiscover}\fi}%
++ {\bfseries\ethesisname}%
}
\vfill
% Title of the thesis.
{%
- \zihao{2}{\label@ctitle}\linespread{1.6}\selectfont%
+ \ifthss@opt@ugly\zihao{-1}\else\zihao{2}\fi%
+ \linespread{1.6}\selectfont{\label@ctitle}%
- \thss@int@fillinblank{2}{0.64\textwidth}{\textbf{\@ctitle}}%
+ \thss@int@fillinblank{2}{0.64\textwidth}{\textbf{\@etitle}}%
}
\vfill
% Information about the author.
-@@ -364,19 +364,19 @@
+@@ -382,19 +382,19 @@
% Slightly adjust the line skip when using new font size.
\zihao{3}\linespread{1.75}\selectfont
\def\thss@tmp@len{0.56\textwidth}
diff --git a/macros/latex/contrib/pkuthss/doc/readme/pkuthss.bib b/macros/latex/contrib/pkuthss/doc/readme/pkuthss.bib
index 3404e2a59a..3f4adbe05f 100644
--- a/macros/latex/contrib/pkuthss/doc/readme/pkuthss.bib
+++ b/macros/latex/contrib/pkuthss/doc/readme/pkuthss.bib
@@ -1,7 +1,7 @@
% Documentation for pkuthss.
%
% Copyright (c) 2008-2009 solvethis
-% Copyright (c) 2010-2019 Casper Ti. Vector
+% Copyright (c) 2010-2021 Casper Ti. Vector
%
% This work may be distributed and/or modified under the conditions of the
% LaTeX Project Public License, either version 1.3 of this license or (at
@@ -30,7 +30,7 @@
@online{amsthm,
author = {{Publications Technical Group, American Mathematical Society}},
title = {Using the amsthm Package},
- edition = {Ver.\ 2.20.3},
+ edition = {Ver.~2.20.3},
type = {M/OL},
date = {2017-09},
url = {https://ctan.org/pkg/amsthm},
@@ -41,7 +41,7 @@
@online{biber,
author = {Kime, Philip and Charette, Fran\c{c}ois},
title = {Biber: A backend bibliography processor for biblatex},
- edition = {Ver.\ 2.7},
+ edition = {Ver.~2.7},
type = {M/OL},
date = {2016-12-05},
url = {https://ctan.org/pkg/biber},
@@ -52,7 +52,7 @@
@online{biblatex,
author = {Lehman, Philipp},
title = {The biblatex Package: Programmable Bibliographies and Citations},
- edition = {Ver.\ 3.7},
+ edition = {Ver.~3.7},
type = {M/OL},
date = {2016-11-16},
url = {https://ctan.org/pkg/biblatex},
@@ -63,7 +63,7 @@
@online{biblatex-caspervector,
author = {Vector, Casper Ti.},
title = {biblatex 参考文献和引用样式:caspervector},
- edition = {Ver.\ 0.3.3},
+ edition = {Ver.~0.3.3},
type = {M/OL},
date = {2018-06-29},
url = {https://ctan.org/pkg/biblatex-caspervector},
@@ -71,6 +71,17 @@
language = {chinese},
}
+@online{biblatex-gb7714-2015,
+ author = {胡振震},
+ title = {符合 GB/T 7714-2015 标准的 biblatex 参考文献样式},
+ edition = {Ver.~0.1w},
+ type = {M/OL},
+ date = {2021-01-19},
+ url = {https://ctan.org/pkg/biblatex-gb7714-2015},
+ urldate = {2021-03-04},
+ language = {chinese},
+}
+
@online{caption,
author = {Sommerfeldt, Alex},
title = {Customizing captions of floating environments},
@@ -84,7 +95,7 @@
@online{ctex,
author = {{ctex.org}},
title = {\CTeX 宏集手册},
- edition = {Ver.\ 2.4.8},
+ edition = {Ver.~2.4.8},
type = {M/OL},
date = {2017-02-23},
url = {https://ctan.org/pkg/ctex},
@@ -105,7 +116,7 @@
@online{fancyhdr,
author = {van Oostrum, Piet},
title = {Page layout in \hologo{LaTeX}},
- edition = {Ver.\ 3.8},
+ edition = {Ver.~3.8},
type = {M/OL},
date = {2016-09-06},
url = {https://ctan.org/pkg/fancyhdr},
@@ -116,7 +127,7 @@
@online{geometry,
author = {Umeki, Hideo},
title = {The geometry package},
- edition = {Ver.\ 5.6},
+ edition = {Ver.~5.6},
type = {M/OL},
date = {2010-09-12},
url = {https://ctan.org/pkg/geometry},
@@ -137,7 +148,7 @@
@online{hyperref,
author = {Rahtz, Sebastian and Oberdiek, Heiko},
title = {Hypertext marks in \hologo{LaTeX}: a manual for hyperref},
- edition = {Ver.\ 6.82q},
+ edition = {Ver.~6.82q},
type = {M/OL},
date = {2012-11},
url = {https://ctan.org/pkg/hyperref},
@@ -148,7 +159,7 @@
@online{latexsym,
author = {Mittelbach, Frank},
title = {The \hologo{LaTeX} symbol fonts for use with \hologo{LaTeX2e}},
- edition = {Ver.\ 2.2e},
+ edition = {Ver.~2.2e},
type = {M/OL},
date = {1998-08-17},
url = {https://ctan.org/tex-archive/macros/latex/base},
@@ -179,7 +190,7 @@
@online{subcaption,
author = {Sommerfeldt, Alex},
title = {The subcaption package},
- edition = {Ver.\ 1.1-75},
+ edition = {Ver.~1.1-75},
type = {M/OL},
date = {2013-04-16},
url = {https://ctan.org/pkg/subcaption},
@@ -200,7 +211,7 @@
@online{tocloft,
author = {Robertson, Will},
title = {The tocloft package},
- edition = {Ver.\ 2.3f},
+ edition = {Ver.~2.3f},
type = {M/OL},
date = {2013-05-02},
url = {https://ctan.org/pkg/tocloft},
@@ -281,7 +292,7 @@
@online{pku-thesisstyle,
author = {北京大学学位办公室},
title = {北京大学研究生学位论文写作指南},
- edition = {Ver.\ 2.0},
+ edition = {Ver.~2.0},
type = {M/OL},
date = {2015-06-11},
url = {http://grs.pku.edu.cn/document/20150611115317661150.pdf},
diff --git a/macros/latex/contrib/pkuthss/doc/readme/pkuthss.tex b/macros/latex/contrib/pkuthss/doc/readme/pkuthss.tex
index 522ebd9d54..8305720841 100644
--- a/macros/latex/contrib/pkuthss/doc/readme/pkuthss.tex
+++ b/macros/latex/contrib/pkuthss/doc/readme/pkuthss.tex
@@ -1,7 +1,7 @@
% Documentation for pkuthss.
%
% Copyright (c) 2008-2009 solvethis
-% Copyright (c) 2010-2016,2018-2019 Casper Ti. Vector
+% Copyright (c) 2010-2016,2018-2019,2021 Casper Ti. Vector
%
% This work may be distributed and/or modified under the conditions of the
% LaTeX Project Public License, either version 1.3 of this license or (at
@@ -50,31 +50,31 @@
tabsize = 4, formatcom = {\ifXeTeX\xeCJKVerbAddon\fi}
}
-\newcommand*{\docversion}{v1.8.3}
+\newif\ifblind\blindfalse
+\newcommand*{\docversion}{v1.9.0}
\pkuthssinfo{
cthesisname = {本科生毕业论文}, ethesisname = {Undergraduate Thesis},
- ctitle = {北京大学学位论文模版\\pkuthss \docversion},
+ ctitle = {北京大学学位论文模版{\thssnl}pkuthss \docversion},
etitle = {%
- PKU dissertation document class\texorpdfstring{\\}{: }%
- pkuthss \docversion%
+ PKU dissertation document class%
+ \texorpdfstring{\thssnl}{: }pkuthss \docversion%
},
- cauthor = {盖茨波·钛·维克托},
- eauthor = {Casper Ti.\ Vector},
- studentid = {00910???},
- date = {\zhdigits{2020}年\zhnumber{11}月},
- school = {化学与分子工程学院},
- cmajor = {化学(?)}, emajor = {Chemistry ... ?},
+ cauthor = {盖茨波·钛·维克托}, eauthor = {Casper Ti.\ Vector},
+ date = {\zhdigits{2021}年\zhnumber{3}月},
+ studentid = {00910???}, school = {化学与分子工程学院},
+ cmajor = {应用化学}, emajor = {Applied Chemistry},
direction = {据说 Casper 自己也不知道},
cmentor = {XX 教授}, ementor = {Prof.\ XX},
- ckeywords = {\hologo{LaTeX2e},排版,文档类,\CTeX{}},
- ekeywords = {\hologo{LaTeX2e}, Typesetting, Document class, \CTeX{}}
+ ckeywords = {\hologo{LaTeX},排版,文档类,\CTeX{}},
+ ekeywords = {\hologo{LaTeX}, Typesetting, Document class, \CTeX{}},
+ blindid = {???01900}, discipline = {化学}
}
\addbibresource{pkuthss.bib}
\begin{document}
\frontmatter
\pagestyle{empty}
- \maketitle
+ \ifblind\makeblind\else\maketitle\fi
\cleardoublepage
\include{chap/pkuthss-copy}
@@ -97,7 +97,7 @@
\include{chap/pkuthss-encl1}
\backmatter
- \include{chap/pkuthss-ack}
+ \ifblind\else\include{chap/pkuthss-ack}\fi
\include{chap/origin}
\end{document}
diff --git a/macros/latex/contrib/pkuthss/tex/pkulogo.pdf b/macros/latex/contrib/pkuthss/tex/pkulogo.pdf
index 03850ac253..bf9659a692 100644
--- a/macros/latex/contrib/pkuthss/tex/pkulogo.pdf
+++ b/macros/latex/contrib/pkuthss/tex/pkulogo.pdf
Binary files differ
diff --git a/macros/latex/contrib/pkuthss/tex/pkuthss-gbk.def b/macros/latex/contrib/pkuthss/tex/pkuthss-gbk.def
index caf9986940..28eb1ade7e 100644
--- a/macros/latex/contrib/pkuthss/tex/pkuthss-gbk.def
+++ b/macros/latex/contrib/pkuthss/tex/pkuthss-gbk.def
@@ -1,7 +1,8 @@
% Peking University dissertation document class
%
% Copyright (c) 2008-2009 solvethis
-% Copyright (c) 2010-2013,2015 Casper Ti. Vector
+% Copyright (c) 2010-2013,2015,2021 Casper Ti. Vector
+% Copyright (c) 2021 Kurapica
%
% This work may be distributed and/or modified under the conditions of the
% LaTeX Project Public License, either version 1.3 of this license or (at
@@ -22,7 +23,7 @@
% pkuword.eps
\ProvidesFile{pkuthss-gbk.def}
- [2020/11/02 v1.8.3 Labels and captions in GBK encoding
+ [2021/03/29 v1.9.0 Labels and captions in GBK encoding
for the pkuthss document class]
\def\label@ctitle{Ŀ}
@@ -35,12 +36,19 @@
\def\label@ementor{Directed by\ }
\def\label@ckeywords{ؼʣ}
\def\label@ekeywords{KEYWORDS:\ }
+\def\label@blindcover{ķ棩}
+\def\label@blindctitle{Ŀ}
+\def\label@blindetitle{ӢĿ}
+\def\label@blinddiscipline{һѧƣ}
+\def\label@blindmajor{ѧƣ}
+\def\label@blindid{ıţ}
\def\titlepagename{}
\def\cuniversity{ѧ}
\def\euniversity{Peking University}
-\def\cthesisname{ʿоѧλ}
+\def\cthesisname{ʿѧλ}
\def\ethesisname{Doctor Thesis}
+\def\thesiscover{}
\def\cabstractname{ժҪ}
\def\eabstractname{ABSTRACT}
diff --git a/macros/latex/contrib/pkuthss/tex/pkuthss-utf8.def b/macros/latex/contrib/pkuthss/tex/pkuthss-utf8.def
index a5f2722160..6ab9dc0ec8 100644
--- a/macros/latex/contrib/pkuthss/tex/pkuthss-utf8.def
+++ b/macros/latex/contrib/pkuthss/tex/pkuthss-utf8.def
@@ -1,7 +1,8 @@
% Peking University dissertation document class
%
% Copyright (c) 2008-2009 solvethis
-% Copyright (c) 2010-2013,2015 Casper Ti. Vector
+% Copyright (c) 2010-2013,2015,2021 Casper Ti. Vector
+% Copyright (c) 2021 Kurapica
%
% This work may be distributed and/or modified under the conditions of the
% LaTeX Project Public License, either version 1.3 of this license or (at
@@ -22,7 +23,7 @@
% pkuword.eps
\ProvidesFile{pkuthss-utf8.def}
- [2020/11/02 v1.8.3 Labels and captions in UTF-8 encoding
+ [2021/03/29 v1.9.0 Labels and captions in UTF-8 encoding
for the pkuthss document class]
\def\label@ctitle{题目:}
@@ -35,12 +36,19 @@
\def\label@ementor{Directed by\ }
\def\label@ckeywords{关键词:}
\def\label@ekeywords{KEYWORDS:\ }
+\def\label@blindcover{(匿名评阅论文封面)}
+\def\label@blindctitle{中文题目:}
+\def\label@blindetitle{英文题目:}
+\def\label@blinddiscipline{一级学科:}
+\def\label@blindmajor{二级学科:}
+\def\label@blindid{论文编号:}
\def\titlepagename{封面}
\def\cuniversity{北京大学}
\def\euniversity{Peking University}
-\def\cthesisname{博士研究生学位论文}
+\def\cthesisname{博士学位论文}
\def\ethesisname{Doctor Thesis}
+\def\thesiscover{}
\def\cabstractname{摘要}
\def\eabstractname{ABSTRACT}
diff --git a/macros/latex/contrib/pkuthss/tex/pkuthss.cls b/macros/latex/contrib/pkuthss/tex/pkuthss.cls
index 0a021b8bd7..2abf2d72fb 100644
--- a/macros/latex/contrib/pkuthss/tex/pkuthss.cls
+++ b/macros/latex/contrib/pkuthss/tex/pkuthss.cls
@@ -1,7 +1,8 @@
% Peking University dissertation document class
%
% Copyright (c) 2008-2009 solvethis
-% Copyright (c) 2010-2019 Casper Ti. Vector
+% Copyright (c) 2010-2021 Casper Ti. Vector
+% Copyright (c) 2021 Kurapica
%
% This work may be distributed and/or modified under the conditions of the
% LaTeX Project Public License, either version 1.3 of this license or (at
@@ -23,7 +24,7 @@
\NeedsTeXFormat{LaTeX2e}[1995/12/01]
\ProvidesClass{pkuthss}
- [2020/11/02 v1.8.3 Peking University dissertation document class]
+ [2021/03/29 v1.9.0 Peking University dissertation document class]
% eg. `\thss@int@boolopt{spacing}{true}' will expand to:
% \newif\ifthss@opt@spacing \thss@opt@spacingtrue
@@ -113,11 +114,11 @@
\ifthss@opt@pkufoot
% Handle the `Unparsed material' issue with latex/dvipdfmx compilation.
\unless\ifxetex\unless\ifpdf
- \newcommand*\pgfsysdriver{pgfsys-dvipdfm.def}
+ \newcommand*{\pgfsysdriver}{pgfsys-dvipdfm.def}
\fi\fi
% Circled text, cf. <https://tex.stackexchange.com/questions/7032/>.
\RequirePackage{tikz}
- \newcommand*\thss@int@circled[1]{%
+ \newcommand*{\thss@int@circled}[1]{%
\scalebox{0.8}{\tikz[baseline = (char.base)]{
\node[
shape = circle, draw = black, minimum size = 1.25em, inner sep = 0pt
@@ -150,9 +151,14 @@
% `tocloft'; it clashes with `subfigure'/`subfig', but the error message will
% say they cannot be used simultaneously.
\RequirePackage{caption, subcaption}
- \DeclareCaptionFont{cfive}{\zihao{5}}
+ \ifthss@opt@ugly
+ \DeclareCaptionFont{capfsize}{\fontsize{11bp}{13.2bp}}
+ \else
+ \DeclareCaptionFont{capfsize}{\zihao{5}}
+ \fi
\DeclareCaptionLabelSeparator{quad}{\quad}
- \captionsetup{font = cfive, labelsep = quad}
+ \captionsetup{font = capfsize, labelsep = quad}
+ \captionsetup[sub]{font = capfsize}
\fi
\ifthss@opt@spacing
@@ -235,20 +241,27 @@
\thss@int@infoitema{ementor}
\thss@int@infoitema{ckeywords}
\thss@int@infoitema{ekeywords}
+\thss@int@infoitema{blindid}
+\thss@int@infoitema{discipline}
\thss@int@infoitemb{cuniversity}
\thss@int@infoitemb{euniversity}
\thss@int@infoitemb{cthesisname}
\thss@int@infoitemb{ethesisname}
+\thss@int@infoitemb{thesiscover}
\thss@int@infoitemb{cabstractname}
\thss@int@infoitemb{eabstractname}
% Set up document information using the `key = value' grammar.
\newcommand*{\pkuthssinfo}[1]{\setkeys{thss@info}{#1}}
+% Becomes \newline in the \makeblind scope.
+\newcommand{\thssnl}{\\}
% Set up page layout.
-\geometry{
- a4paper, hmargin = 2.6cm, top = 2.92cm, bottom = 3.03cm,
- headheight = 0.45cm, headsep = 0.59cm, footskip = 1.05cm
-}
+\geometry{a4paper, hmargin = 2.6cm, headheight = 0.5cm, headsep = 0.6cm}
+\ifthss@opt@ugly
+ \geometry{top = 3.1cm, bottom = 3.0cm, footskip = 0.8cm}
+\else
+ \geometry{top = 3.0cm, bottom = 3.1cm, footskip = 1.1cm}
+\fi
% Set up chapter/section/... captions.
% The `*skip' values are not supposed to be modified by the `ugly' option:
@@ -258,29 +271,29 @@
\setcounter{secnumdepth}{3}
\setcounter{tocdepth}{2}
\ctexset{
- chapter = {
- beforeskip = {0bp}, afterskip = {18bp plus 0.2ex},
- nameformat = {}, titleformat = {}
- }, section =
+ chapter = {beforeskip = {0bp}, afterskip = {18bp plus 0.2ex}},
+ section =
{beforeskip = {20bp plus 1ex minus 0.2ex}, afterskip = {5bp plus 0.2ex}},
subsection =
{beforeskip = {12bp plus 1ex minus 0.2ex}, afterskip = {5bp plus 0.2ex}},
subsubsection =
{beforeskip = {12bp plus 1ex minus 0.2ex}, afterskip = {5bp plus 0.2ex}}
}
+\ctexset{
+ chapter = {nameformat = {}, titleformat = {}},
+ subsubsection = {format = {\zihao{-4}\bfseries}}
+}
\ifthss@opt@ugly
\ctexset{
chapter = {format = {\zihao{3}\bfseries\centering}},
section = {format = {\zihao{4}\bfseries}},
- subsection = {format = {\fontsize{13bp}{15.6bp}\selectfont\bfseries}},
- subsubsection = {format = {\zihao{-4}\bfseries}}
+ subsection = {format = {\fontsize{13bp}{15.6bp}\selectfont\bfseries}}
}
\else
\ctexset{
chapter = {format = {\zihao{-2}\bfseries\centering}},
section = {format = {\zihao{-3}\bfseries}},
- subsection = {format = {\zihao{4}\bfseries}},
- subsubsection = {format = {\bfseries}}
+ subsection = {format = {\zihao{4}\bfseries}}
}
\fi
@@ -344,18 +357,23 @@
\renewcommand{\maketitle}{%
\thss@int@pdfmark{\titlepagename}{titlepage}
% Make the title page centered.
- \begin{titlepage}\begingroup\centering
+ \begin{titlepage}\centering
% Emblem and inscription of the university, and type of thesis.
{%
- \zihao{1}%
- \includegraphics[height = 2.4em]{pkulogo}\hspace{0.4em}%
- \raisebox{0.4em}{\includegraphics[height = 1.6em]{pkuword}}\\[0.8em]
- {\bfseries{\cthesisname}}%
+ \ifthss@opt@ugly%
+ \zihao{-0}\includegraphics[height = 1.9em]{pkulogo}\hspace{0.3em}%
+ \raisebox{0.32em}{\includegraphics[height = 1.3em]{pkuword}}\\[0.5em]
+ \else%
+ \zihao{1}\includegraphics[height = 2.4em]{pkulogo}\hspace{0.4em}%
+ \raisebox{0.4em}{\includegraphics[height = 1.6em]{pkuword}}\\[0.8em]
+ \fi%
+ {\bfseries\ifx\thesiscover\empty{\cthesisname}\else{\thesiscover}\fi}%
}
\vfill
% Title of the thesis.
{%
- \zihao{2}{\label@ctitle}\linespread{1.6}\selectfont%
+ \ifthss@opt@ugly\zihao{-1}\else\zihao{2}\fi%
+ \linespread{1.6}\selectfont{\label@ctitle}%
\thss@int@fillinblank{2}{0.64\textwidth}{\textbf{\@ctitle}}%
}
\vfill
@@ -382,7 +400,27 @@
\vfill
% Date.
{\ifthss@opt@ugly\zihao{3}\else\zihao{-2}\fi\@date}
- \par\endgroup\end{titlepage}%
+ \par\end{titlepage}%
+}
+
+% Typeset the title page for double-blind review.
+\newcommand{\makeblind}{%
+ \thss@int@pdfmark{\titlepagename}{titlepage}
+ \begin{titlepage}\renewcommand{\thssnl}{\newline}
+ \centering\zihao{3}\selectfont\fangsong\vspace*{0.5cm}
+ {\zihao{-0}\heiti\cuniversity\cthesisname}\\[0.36\baselineskip]
+ {\zihao{-2}\fangsong\label@blindcover}%
+ \par\vspace{4\baselineskip}
+ \renewcommand{\arraystretch}{1.25}
+ \begin{tabular}{lp{0.75\textwidth}}
+ \label@blindctitle & {\@ctitle} \\
+ \label@blindetitle & {\@etitle} \\\\
+ \label@blinddiscipline & {\@discipline} \\
+ \label@blindmajor & {\@cmajor} \\
+ \label@blindid & {\@blindid} \\
+ \end{tabular}\par\vfill
+ {\@date}\par\vspace*{0.5cm}
+ \end{titlepage}%
}
% Typeset the Chinese abstract.
@@ -406,5 +444,14 @@
\vfill\noindent\textbf{\label@ekeywords}{\@ekeywords}%
}
+% Typeset the English abstract for double-blind review.
+\newenvironment{beabstract}{%
+ \thss@int@pdfmark{\eabstractname}{eabstract}
+ \chapter*{\sffamily\@etitle}\markboth{\eabstractname}{}
+ \begin{center}\textbf{\sffamily\eabstractname}\end{center}\par%
+}{% Keywords at the bottom of the page.
+ \vfill\noindent\textbf{\label@ekeywords}{\@ekeywords}%
+}
+
\endinput
% vim:ft=tex:ts=2:sw=2
diff --git a/macros/latex/contrib/pkuthss/tex/pkuword.pdf b/macros/latex/contrib/pkuthss/tex/pkuword.pdf
index 5884b8efd3..58b5193f46 100644
--- a/macros/latex/contrib/pkuthss/tex/pkuword.pdf
+++ b/macros/latex/contrib/pkuthss/tex/pkuword.pdf
Binary files differ
diff --git a/macros/latex/contrib/polexpr/polexpr.html b/macros/latex/contrib/polexpr/polexpr.html
deleted file mode 100644
index 7496332976..0000000000
--- a/macros/latex/contrib/polexpr/polexpr.html
+++ /dev/null
@@ -1,2911 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta name="generator" content="Docutils 0.14: http://docutils.sourceforge.net/" />
-<title>Package polexpr documentation</title>
-<style type="text/css">
-
-/*
-:Author: David Goodger (goodger@python.org)
-:Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $
-:Copyright: This stylesheet has been placed in the public domain.
-
-Default cascading style sheet for the HTML output of Docutils.
-
-See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
-customize this style sheet.
-*/
-
-/* used to remove borders from tables and images */
-.borderless, table.borderless td, table.borderless th {
- border: 0 }
-
-table.borderless td, table.borderless th {
- /* Override padding for "table.docutils td" with "! important".
- The right padding separates the table cells. */
- padding: 0 0.5em 0 0 ! important }
-
-.first {
- /* Override more specific margin styles with "! important". */
- margin-top: 0 ! important }
-
-.last, .with-subtitle {
- margin-bottom: 0 ! important }
-
-.hidden {
- display: none }
-
-.subscript {
- vertical-align: sub;
- font-size: smaller }
-
-.superscript {
- vertical-align: super;
- font-size: smaller }
-
-a.toc-backref {
- text-decoration: none ;
- color: black }
-
-blockquote.epigraph {
- margin: 2em 5em ; }
-
-dl.docutils dd {
- margin-bottom: 0.5em }
-
-object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
- overflow: hidden;
-}
-
-/* Uncomment (and remove this text!) to get bold-faced definition list terms
-dl.docutils dt {
- font-weight: bold }
-*/
-
-div.abstract {
- margin: 2em 5em }
-
-div.abstract p.topic-title {
- font-weight: bold ;
- text-align: center }
-
-div.admonition, div.attention, div.caution, div.danger, div.error,
-div.hint, div.important, div.note, div.tip, div.warning {
- margin: 2em ;
- border: medium outset ;
- padding: 1em }
-
-div.admonition p.admonition-title, div.hint p.admonition-title,
-div.important p.admonition-title, div.note p.admonition-title,
-div.tip p.admonition-title {
- font-weight: bold ;
- font-family: sans-serif }
-
-div.attention p.admonition-title, div.caution p.admonition-title,
-div.danger p.admonition-title, div.error p.admonition-title,
-div.warning p.admonition-title, .code .error {
- color: red ;
- font-weight: bold ;
- font-family: sans-serif }
-
-/* Uncomment (and remove this text!) to get reduced vertical space in
- compound paragraphs.
-div.compound .compound-first, div.compound .compound-middle {
- margin-bottom: 0.5em }
-
-div.compound .compound-last, div.compound .compound-middle {
- margin-top: 0.5em }
-*/
-
-div.dedication {
- margin: 2em 5em ;
- text-align: center ;
- font-style: italic }
-
-div.dedication p.topic-title {
- font-weight: bold ;
- font-style: normal }
-
-div.figure {
- margin-left: 2em ;
- margin-right: 2em }
-
-div.footer, div.header {
- clear: both;
- font-size: smaller }
-
-div.line-block {
- display: block ;
- margin-top: 1em ;
- margin-bottom: 1em }
-
-div.line-block div.line-block {
- margin-top: 0 ;
- margin-bottom: 0 ;
- margin-left: 1.5em }
-
-div.sidebar {
- margin: 0 0 0.5em 1em ;
- border: medium outset ;
- padding: 1em ;
- background-color: #ffffee ;
- width: 40% ;
- float: right ;
- clear: right }
-
-div.sidebar p.rubric {
- font-family: sans-serif ;
- font-size: medium }
-
-div.system-messages {
- margin: 5em }
-
-div.system-messages h1 {
- color: red }
-
-div.system-message {
- border: medium outset ;
- padding: 1em }
-
-div.system-message p.system-message-title {
- color: red ;
- font-weight: bold }
-
-div.topic {
- margin: 2em }
-
-h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
-h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
- margin-top: 0.4em }
-
-h1.title {
- text-align: center }
-
-h2.subtitle {
- text-align: center }
-
-hr.docutils {
- width: 75% }
-
-img.align-left, .figure.align-left, object.align-left, table.align-left {
- clear: left ;
- float: left ;
- margin-right: 1em }
-
-img.align-right, .figure.align-right, object.align-right, table.align-right {
- clear: right ;
- float: right ;
- margin-left: 1em }
-
-img.align-center, .figure.align-center, object.align-center {
- display: block;
- margin-left: auto;
- margin-right: auto;
-}
-
-table.align-center {
- margin-left: auto;
- margin-right: auto;
-}
-
-.align-left {
- text-align: left }
-
-.align-center {
- clear: both ;
- text-align: center }
-
-.align-right {
- text-align: right }
-
-/* reset inner alignment in figures */
-div.align-right {
- text-align: inherit }
-
-/* div.align-center * { */
-/* text-align: left } */
-
-.align-top {
- vertical-align: top }
-
-.align-middle {
- vertical-align: middle }
-
-.align-bottom {
- vertical-align: bottom }
-
-ol.simple, ul.simple {
- margin-bottom: 1em }
-
-ol.arabic {
- list-style: decimal }
-
-ol.loweralpha {
- list-style: lower-alpha }
-
-ol.upperalpha {
- list-style: upper-alpha }
-
-ol.lowerroman {
- list-style: lower-roman }
-
-ol.upperroman {
- list-style: upper-roman }
-
-p.attribution {
- text-align: right ;
- margin-left: 50% }
-
-p.caption {
- font-style: italic }
-
-p.credits {
- font-style: italic ;
- font-size: smaller }
-
-p.label {
- white-space: nowrap }
-
-p.rubric {
- font-weight: bold ;
- font-size: larger ;
- color: maroon ;
- text-align: center }
-
-p.sidebar-title {
- font-family: sans-serif ;
- font-weight: bold ;
- font-size: larger }
-
-p.sidebar-subtitle {
- font-family: sans-serif ;
- font-weight: bold }
-
-p.topic-title {
- font-weight: bold }
-
-pre.address {
- margin-bottom: 0 ;
- margin-top: 0 ;
- font: inherit }
-
-pre.literal-block, pre.doctest-block, pre.math, pre.code {
- margin-left: 2em ;
- margin-right: 2em }
-
-pre.code .ln { color: grey; } /* line numbers */
-pre.code, code { background-color: #eeeeee }
-pre.code .comment, code .comment { color: #5C6576 }
-pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
-pre.code .literal.string, code .literal.string { color: #0C5404 }
-pre.code .name.builtin, code .name.builtin { color: #352B84 }
-pre.code .deleted, code .deleted { background-color: #DEB0A1}
-pre.code .inserted, code .inserted { background-color: #A3D289}
-
-span.classifier {
- font-family: sans-serif ;
- font-style: oblique }
-
-span.classifier-delimiter {
- font-family: sans-serif ;
- font-weight: bold }
-
-span.interpreted {
- font-family: sans-serif }
-
-span.option {
- white-space: nowrap }
-
-span.pre {
- white-space: pre }
-
-span.problematic {
- color: red }
-
-span.section-subtitle {
- /* font-size relative to parent (h1..h6 element) */
- font-size: 80% }
-
-table.citation {
- border-left: solid 1px gray;
- margin-left: 1px }
-
-table.docinfo {
- margin: 2em 4em }
-
-table.docutils {
- margin-top: 0.5em ;
- margin-bottom: 0.5em }
-
-table.footnote {
- border-left: solid 1px black;
- margin-left: 1px }
-
-table.docutils td, table.docutils th,
-table.docinfo td, table.docinfo th {
- padding-left: 0.5em ;
- padding-right: 0.5em ;
- vertical-align: top }
-
-table.docutils th.field-name, table.docinfo th.docinfo-name {
- font-weight: bold ;
- text-align: left ;
- white-space: nowrap ;
- padding-left: 0 }
-
-/* "booktabs" style (no vertical lines) */
-table.docutils.booktabs {
- border: 0px;
- border-top: 2px solid;
- border-bottom: 2px solid;
- border-collapse: collapse;
-}
-table.docutils.booktabs * {
- border: 0px;
-}
-table.docutils.booktabs th {
- border-bottom: thin solid;
- text-align: left;
-}
-
-h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
-h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
- font-size: 100% }
-
-ul.auto-toc {
- list-style-type: none }
-
-</style>
-</head>
-<body>
-<div class="document" id="package-polexpr-documentation">
-<h1 class="title">Package polexpr documentation</h1>
-<h2 class="subtitle" id="id1">0.7.5 (2020/01/31)</h2>
-
-<!-- comment: -*- fill-column: 72; mode: rst; -*- -->
-<div class="contents topic" id="contents">
-<p class="topic-title first">Contents</p>
-<ul class="simple">
-<li><a class="reference internal" href="#basic-syntax" id="id38">Basic syntax</a></li>
-<li><a class="reference internal" href="#examples-of-localization-of-roots" id="id39">Examples of localization of roots</a><ul>
-<li><a class="reference internal" href="#a-typical-example" id="id40">A typical example</a></li>
-<li><a class="reference internal" href="#a-degree-four-polynomial-with-nearby-roots" id="id41">A degree four polynomial with nearby roots</a></li>
-<li><a class="reference internal" href="#the-degree-nine-polynomial-with-0-99-0-999-0-9999-as-triple-roots" id="id42">The degree nine polynomial with 0.99, 0.999, 0.9999 as triple roots</a></li>
-<li><a class="reference internal" href="#a-degree-five-polynomial-with-three-rational-roots" id="id43">A degree five polynomial with three rational roots</a></li>
-<li><a class="reference internal" href="#a-mignotte-type-polynomial" id="id44">A Mignotte type polynomial</a></li>
-<li><a class="reference internal" href="#the-wilkinson-polynomial" id="id45">The Wilkinson polynomial</a></li>
-<li><a class="reference internal" href="#the-second-wilkinson-polynomial" id="id46">The second Wilkinson polynomial</a></li>
-<li><a class="reference internal" href="#the-degree-41-polynomial-with-2-1-9-1-8-0-0-1-1-9-2-as-roots" id="id47">The degree 41 polynomial with -2, -1.9, -1.8, ..., 0, 0.1, ..., 1.9, 2 as roots</a></li>
-<li><a class="reference internal" href="#roots-of-chebyshev-polynomials" id="id48">Roots of Chebyshev polynomials</a></li>
-</ul>
-</li>
-<li><a class="reference internal" href="#non-expandable-macros" id="id49">Non-expandable macros</a><ul>
-<li><a class="reference internal" href="#poldef-polname-letter-expression-in-letter" id="id50"><tt class="docutils literal">\poldef <span class="pre">polname(letter):=</span> expression in letter;</tt></a></li>
-<li><a class="reference internal" href="#poldef-letter-polname-expression-in-letter" id="id51"><tt class="docutils literal"><span class="pre">\PolDef[letter]{polname}{expression</span> in letter}</tt></a></li>
-<li><a class="reference internal" href="#polgenfloatvariant-polname" id="id52"><tt class="docutils literal">\PolGenFloatVariant{polname}</tt></a></li>
-<li><a class="reference internal" href="#pollet-polname-2-polname-1" id="id53"><tt class="docutils literal"><span class="pre">\PolLet{polname_2}={polname_1}</span></tt></a></li>
-<li><a class="reference internal" href="#polgloballet-polname-2-polname-1" id="id54"><tt class="docutils literal"><span class="pre">\PolGlobalLet{polname_2}={polname_1}</span></tt></a></li>
-<li><a class="reference internal" href="#polassign-polname-toarray-macro" id="id55"><tt class="docutils literal"><span class="pre">\PolAssign{polname}\toarray\macro</span></tt></a></li>
-<li><a class="reference internal" href="#polget-polname-fromarray-macro" id="id56"><tt class="docutils literal"><span class="pre">\PolGet{polname}\fromarray\macro</span></tt></a></li>
-<li><a class="reference internal" href="#polfromcsv-polname-csv" id="id57"><tt class="docutils literal"><span class="pre">\PolFromCSV{polname}{&lt;csv&gt;}</span></tt></a></li>
-<li><a class="reference internal" href="#poltypeset-polname" id="id58"><tt class="docutils literal">\PolTypeset{polname}</tt></a><ul>
-<li><a class="reference internal" href="#poltypesetcmd-raw-coeff" id="id59"><tt class="docutils literal">\PolTypesetCmd{raw_coeff}</tt></a></li>
-<li><a class="reference internal" href="#poltypesetone-raw-coeff" id="id60"><tt class="docutils literal">\PolTypesetOne{raw_coeff}</tt></a></li>
-<li><a class="reference internal" href="#id6" id="id61"><tt class="docutils literal">\PolTypesetMonomialCmd</tt></a></li>
-<li><a class="reference internal" href="#poltypesetcmdprefix-raw-coeff" id="id62"><tt class="docutils literal">\PolTypesetCmdPrefix{raw_coeff}</tt></a></li>
-</ul>
-</li>
-<li><a class="reference internal" href="#id8" id="id63"><tt class="docutils literal"><span class="pre">\PolTypeset*{polname}</span></tt></a></li>
-<li><a class="reference internal" href="#poldiff-polname-1-polname-2" id="id64"><tt class="docutils literal"><span class="pre">\PolDiff{polname_1}{polname_2}</span></tt></a></li>
-<li><a class="reference internal" href="#poldiff-n-polname-1-polname-2" id="id65"><tt class="docutils literal"><span class="pre">\PolDiff[N]{polname_1}{polname_2}</span></tt></a></li>
-<li><a class="reference internal" href="#polantidiff-polname-1-polname-2" id="id66"><tt class="docutils literal"><span class="pre">\PolAntiDiff{polname_1}{polname_2}</span></tt></a></li>
-<li><a class="reference internal" href="#polantidiff-n-polname-1-polname-2" id="id67"><tt class="docutils literal"><span class="pre">\PolAntiDiff[N]{polname_1}{polname_2}</span></tt></a></li>
-<li><a class="reference internal" href="#poldivide-polname-1-polname-2-polname-q-polname-r" id="id68"><tt class="docutils literal"><span class="pre">\PolDivide{polname_1}{polname_2}{polname_Q}{polname_R}</span></tt></a></li>
-<li><a class="reference internal" href="#polquo-polname-1-polname-2-polname-q" id="id69"><tt class="docutils literal"><span class="pre">\PolQuo{polname_1}{polname_2}{polname_Q}</span></tt></a></li>
-<li><a class="reference internal" href="#polrem-polname-1-polname-2-polname-r" id="id70"><tt class="docutils literal"><span class="pre">\PolRem{polname_1}{polname_2}{polname_R}</span></tt></a></li>
-<li><a class="reference internal" href="#polgcd-polname-1-polname-2-polname-gcd" id="id71"><tt class="docutils literal"><span class="pre">\PolGCD{polname_1}{polname_2}{polname_GCD}</span></tt></a></li>
-<li><a class="reference internal" href="#poltosturm-polname-sturmname" id="id72"><tt class="docutils literal"><span class="pre">\PolToSturm{polname}{sturmname}</span></tt></a></li>
-<li><a class="reference internal" href="#id10" id="id73"><tt class="docutils literal"><span class="pre">\PolToSturm*{polname}{sturmname}</span></tt></a></li>
-<li><a class="reference internal" href="#polsettosturmchainsignchangesat-macro-sturmname-fraction" id="id74"><tt class="docutils literal"><span class="pre">\PolSetToSturmChainSignChangesAt{\macro}{sturmname}{fraction}</span></tt></a></li>
-<li><a class="reference internal" href="#polsettonbofzeroswithin-macro-sturmname-value-a-value-b" id="id75"><tt class="docutils literal"><span class="pre">\PolSetToNbOfZerosWithin{\macro}{sturmname}{value_a}{value_b}</span></tt></a></li>
-<li><a class="reference internal" href="#polsturmisolatezeros-sturmname" id="id76"><tt class="docutils literal">\PolSturmIsolateZeros{sturmname}</tt></a></li>
-<li><a class="reference internal" href="#id12" id="id77"><tt class="docutils literal"><span class="pre">\PolSturmIsolateZeros*{sturmname}</span></tt></a></li>
-<li><a class="reference internal" href="#id14" id="id78"><tt class="docutils literal"><span class="pre">\PolSturmIsolateZeros**{sturmname}</span></tt></a></li>
-<li><a class="reference internal" href="#polsturmisolatezerosandgetmultiplicities-sturmname" id="id79"><tt class="docutils literal">\PolSturmIsolateZerosAndGetMultiplicities{sturmname}</tt></a></li>
-<li><a class="reference internal" href="#polsturmisolatezerosgetmultiplicitiesandrationalroots-sturmname" id="id80"><tt class="docutils literal">\PolSturmIsolateZerosGetMultiplicitiesAndRationalRoots{sturmname}</tt></a></li>
-<li><a class="reference internal" href="#polsturmisolatezerosandfindrationalroots-sturmname" id="id81"><tt class="docutils literal">\PolSturmIsolateZerosAndFindRationalRoots{sturmname}</tt></a></li>
-<li><a class="reference internal" href="#polrefineinterval-sturmname-index" id="id82"><tt class="docutils literal"><span class="pre">\PolRefineInterval*{sturmname}{index}</span></tt></a></li>
-<li><a class="reference internal" href="#polrefineinterval-n-sturmname-index" id="id83"><tt class="docutils literal"><span class="pre">\PolRefineInterval[N]{sturmname}{index}</span></tt></a></li>
-<li><a class="reference internal" href="#polensureintervallength-sturmname-index-e" id="id84"><tt class="docutils literal"><span class="pre">\PolEnsureIntervalLength{sturmname}{index}{E}</span></tt></a></li>
-<li><a class="reference internal" href="#polensureintervallengths-sturmname-e" id="id85"><tt class="docutils literal"><span class="pre">\PolEnsureIntervalLengths{sturmname}{E}</span></tt></a></li>
-<li><a class="reference internal" href="#polprintintervals-varname-sturmname" id="id86"><tt class="docutils literal"><span class="pre">\PolPrintIntervals[varname]{sturmname}</span></tt></a><ul>
-<li><a class="reference internal" href="#polprintintervalsnorealroots" id="id87"><tt class="docutils literal">\PolPrintIntervalsNoRealRoots</tt></a></li>
-<li><a class="reference internal" href="#polprintintervalsbeginenv" id="id88"><tt class="docutils literal">\PolPrintIntervalsBeginEnv</tt></a></li>
-<li><a class="reference internal" href="#polprintintervalsendenv" id="id89"><tt class="docutils literal">\PolPrintIntervalsEndEnv</tt></a></li>
-<li><a class="reference internal" href="#polprintintervalsknownroot" id="id90"><tt class="docutils literal">\PolPrintIntervalsKnownRoot</tt></a></li>
-<li><a class="reference internal" href="#polprintintervalsunknownroot" id="id91"><tt class="docutils literal">\PolPrintIntervalsUnknownRoot</tt></a></li>
-<li><a class="reference internal" href="#id15" id="id92"><tt class="docutils literal">\PolPrintIntervalsPrintExactZero</tt></a></li>
-<li><a class="reference internal" href="#id16" id="id93"><tt class="docutils literal">\PolPrintIntervalsPrintLeftEndPoint</tt></a></li>
-<li><a class="reference internal" href="#id17" id="id94"><tt class="docutils literal">\PolPrintIntervalsPrintRightEndPoint</tt></a></li>
-</ul>
-</li>
-<li><a class="reference internal" href="#id19" id="id95"><tt class="docutils literal"><span class="pre">\PolPrintIntervals*[varname]{sturmname}</span></tt></a><ul>
-<li><a class="reference internal" href="#polprintintervalsprintmultiplicity" id="id96"><tt class="docutils literal">\PolPrintIntervalsPrintMultiplicity</tt></a></li>
-</ul>
-</li>
-<li><a class="reference internal" href="#polmapcoeffs-macro-polname" id="id97"><tt class="docutils literal"><span class="pre">\PolMapCoeffs{\macro}{polname}</span></tt></a></li>
-<li><a class="reference internal" href="#polreducecoeffs-polname" id="id98"><tt class="docutils literal">\PolReduceCoeffs{polname}</tt></a></li>
-<li><a class="reference internal" href="#id21" id="id99"><tt class="docutils literal"><span class="pre">\PolReduceCoeffs*{polname}</span></tt></a></li>
-<li><a class="reference internal" href="#polmakemonic-polname" id="id100"><tt class="docutils literal">\PolMakeMonic{polname}</tt></a></li>
-<li><a class="reference internal" href="#polmakeprimitive-polname" id="id101"><tt class="docutils literal">\PolMakePrimitive{polname}</tt></a></li>
-</ul>
-</li>
-<li><a class="reference internal" href="#expandable-macros" id="id102">Expandable macros</a><ul>
-<li><a class="reference internal" href="#poleval-polname-atexpr-numerical-expression" id="id103"><tt class="docutils literal"><span class="pre">\PolEval{polname}\AtExpr{numerical</span> expression}</tt></a></li>
-<li><a class="reference internal" href="#poleval-polname-at-fraction" id="id104"><tt class="docutils literal"><span class="pre">\PolEval{polname}\At{fraction}</span></tt></a></li>
-<li><a class="reference internal" href="#polevalreduced-polname-atexpr-numerical-expression" id="id105"><tt class="docutils literal"><span class="pre">\PolEvalReduced{polname}\AtExpr{numerical</span> expression}</tt></a></li>
-<li><a class="reference internal" href="#polevalreduced-polname-at-fraction" id="id106"><tt class="docutils literal"><span class="pre">\PolEvalReduced{polname}\At{fraction}</span></tt></a></li>
-<li><a class="reference internal" href="#polfloateval-polname-atexpr-numerical-expression" id="id107"><tt class="docutils literal"><span class="pre">\PolFloatEval{polname}\AtExpr{numerical</span> expression}</tt></a></li>
-<li><a class="reference internal" href="#polfloateval-polname-at-fraction" id="id108"><tt class="docutils literal"><span class="pre">\PolFloatEval{polname}\At{fraction}</span></tt></a></li>
-<li><a class="reference internal" href="#polifcoeffisplusorminusone-a-b" id="id109"><tt class="docutils literal"><span class="pre">\PolIfCoeffIsPlusOrMinusOne{A}{B}</span></tt></a></li>
-<li><a class="reference internal" href="#polleadingcoeff-polname" id="id110"><tt class="docutils literal">\PolLeadingCoeff{polname}</tt></a></li>
-<li><a class="reference internal" href="#polnthcoeff-polname-number" id="id111"><tt class="docutils literal"><span class="pre">\PolNthCoeff{polname}{number}</span></tt></a></li>
-<li><a class="reference internal" href="#poldegree-polname" id="id112"><tt class="docutils literal">\PolDegree{polname}</tt></a></li>
-<li><a class="reference internal" href="#policontent-polname" id="id113"><tt class="docutils literal">\PolIContent{polname}</tt></a></li>
-<li><a class="reference internal" href="#poltoexpr-polname" id="id114"><tt class="docutils literal">\PolToExpr{polname}</tt></a><ul>
-<li><a class="reference internal" href="#poltoexproneterm-raw-coeff-number" id="id115"><tt class="docutils literal"><span class="pre">\PolToExprOneTerm{raw_coeff}{number}</span></tt></a></li>
-<li><a class="reference internal" href="#poltoexpronetermstylea-raw-coeff-number" id="id116"><tt class="docutils literal"><span class="pre">\PolToExprOneTermStyleA{raw_coeff}{number}</span></tt></a></li>
-<li><a class="reference internal" href="#poltoexpronetermstyleb-raw-coeff-number" id="id117"><tt class="docutils literal"><span class="pre">\PolToExprOneTermStyleB{raw_coeff}{number}</span></tt></a></li>
-<li><a class="reference internal" href="#poltoexprcmd-raw-coeff" id="id118"><tt class="docutils literal">\PolToExprCmd{raw_coeff}</tt></a></li>
-<li><a class="reference internal" href="#poltoexprtermprefix-raw-coeff" id="id119"><tt class="docutils literal">\PolToExprTermPrefix{raw_coeff}</tt></a></li>
-<li><a class="reference internal" href="#id28" id="id120"><tt class="docutils literal">\PolToExprVar</tt></a></li>
-<li><a class="reference internal" href="#id29" id="id121"><tt class="docutils literal">\PolToExprTimes</tt></a></li>
-</ul>
-</li>
-<li><a class="reference internal" href="#id31" id="id122"><tt class="docutils literal"><span class="pre">\PolToExpr*{polname}</span></tt></a></li>
-<li><a class="reference internal" href="#poltofloatexpr-polname" id="id123"><tt class="docutils literal">\PolToFloatExpr{polname}</tt></a><ul>
-<li><a class="reference internal" href="#poltofloatexproneterm-raw-coeff-number" id="id124"><tt class="docutils literal"><span class="pre">\PolToFloatExprOneTerm{raw_coeff}{number}</span></tt></a></li>
-<li><a class="reference internal" href="#poltofloatexprcmd-raw-coeff" id="id125"><tt class="docutils literal">\PolToFloatExprCmd{raw_coeff}</tt></a></li>
-</ul>
-</li>
-<li><a class="reference internal" href="#id35" id="id126"><tt class="docutils literal"><span class="pre">\PolToFloatExpr*{polname}</span></tt></a></li>
-<li><a class="reference internal" href="#poltolist-polname" id="id127"><tt class="docutils literal">\PolToList{polname}</tt></a></li>
-<li><a class="reference internal" href="#poltocsv-polname" id="id128"><tt class="docutils literal">\PolToCSV{polname}</tt></a></li>
-<li><a class="reference internal" href="#polsturmchainlength-sturmname" id="id129"><tt class="docutils literal">\PolSturmChainLength{sturmname}</tt></a></li>
-<li><a class="reference internal" href="#polsturmifzeroexactlyknown-sturmname-index-a-b" id="id130"><tt class="docutils literal"><span class="pre">\PolSturmIfZeroExactlyKnown{sturmname}{index}{A}{B}</span></tt></a></li>
-<li><a class="reference internal" href="#polsturmisolatedzeroleft-sturmname-index" id="id131"><tt class="docutils literal"><span class="pre">\PolSturmIsolatedZeroLeft{sturmname}{index}</span></tt></a></li>
-<li><a class="reference internal" href="#polsturmisolatedzeroright-sturmname-index" id="id132"><tt class="docutils literal"><span class="pre">\PolSturmIsolatedZeroRight{sturmname}{index}</span></tt></a></li>
-<li><a class="reference internal" href="#polsturmisolatedzeromultiplicity-sturmname-index" id="id133"><tt class="docutils literal"><span class="pre">\PolSturmIsolatedZeroMultiplicity{sturmname}{index}</span></tt></a></li>
-<li><a class="reference internal" href="#polsturmnbofisolatedzeros-sturmname" id="id134"><tt class="docutils literal">\PolSturmNbOfIsolatedZeros{sturmname}</tt></a><ul>
-<li><a class="reference internal" href="#polsturmnbofrootsof-sturmname-lessthanorequalto-value" id="id135"><tt class="docutils literal"><span class="pre">\PolSturmNbOfRootsOf{sturmname}\LessThanOrEqualTo{value}</span></tt></a></li>
-<li><a class="reference internal" href="#polsturmnbofrootsof-sturmname-lessthanorequaltoexpr-expression" id="id136"><tt class="docutils literal"><span class="pre">\PolSturmNbOfRootsOf{sturmname}\LessThanOrEqualToExpr{expression}</span></tt></a></li>
-<li><a class="reference internal" href="#polsturmnbwithmultofrootsof-sturmname-lessthanorequalto-value" id="id137"><tt class="docutils literal"><span class="pre">\PolSturmNbWithMultOfRootsOf{sturmname}\LessThanOrEqualTo{value}</span></tt></a></li>
-<li><a class="reference internal" href="#polsturmnbwithmultofrootsof-sturmname-lessthanorequaltoexpr-expression" id="id138"><tt class="docutils literal"><span class="pre">\PolSturmNbWithMultOfRootsOf{sturmname}\LessThanOrEqualToExpr{expression}</span></tt></a></li>
-</ul>
-</li>
-<li><a class="reference internal" href="#polsturmnbofrationalroots-sturmname" id="id139"><tt class="docutils literal">\PolSturmNbOfRationalRoots{sturmname}</tt></a></li>
-<li><a class="reference internal" href="#polsturmnbofrationalrootswithmultiplicities-sturmname" id="id140"><tt class="docutils literal">\PolSturmNbOfRationalRootsWithMultiplicities{sturmname}</tt></a></li>
-<li><a class="reference internal" href="#polsturmrationalroot-sturmname-k" id="id141"><tt class="docutils literal"><span class="pre">\PolSturmRationalRoot{sturmname}{k}</span></tt></a></li>
-<li><a class="reference internal" href="#polsturmrationalrootindex-sturmname-k" id="id142"><tt class="docutils literal"><span class="pre">\PolSturmRationalRootIndex{sturmname}{k}</span></tt></a></li>
-<li><a class="reference internal" href="#polsturmrationalrootmultiplicity-sturmname-k" id="id143"><tt class="docutils literal"><span class="pre">\PolSturmRationalRootMultiplicity{sturmname}{k}</span></tt></a></li>
-<li><a class="reference internal" href="#polintervalwidth-sturmname-index" id="id144"><tt class="docutils literal"><span class="pre">\PolIntervalWidth{sturmname}{index}</span></tt></a></li>
-<li><a class="reference internal" href="#expandable-macros-for-use-within-execution-of-polprintintervals" id="id145">Expandable macros for use within execution of <tt class="docutils literal">\PolPrintIntervals</tt></a><ul>
-<li><a class="reference internal" href="#polprintintervalsthevar" id="id146"><tt class="docutils literal">\PolPrintIntervalsTheVar</tt></a></li>
-<li><a class="reference internal" href="#polprintintervalstheindex" id="id147"><tt class="docutils literal">\PolPrintIntervalsTheIndex</tt></a></li>
-<li><a class="reference internal" href="#polprintintervalsthesturmname" id="id148"><tt class="docutils literal">\PolPrintIntervalsTheSturmName</tt></a></li>
-<li><a class="reference internal" href="#polprintintervalstheleftendpoint" id="id149"><tt class="docutils literal">\PolPrintIntervalsTheLeftEndPoint</tt></a></li>
-<li><a class="reference internal" href="#polprintintervalstherightendpoint" id="id150"><tt class="docutils literal">\PolPrintIntervalsTheRightEndPoint</tt></a></li>
-<li><a class="reference internal" href="#polprintintervalsthemultiplicity" id="id151"><tt class="docutils literal">\PolPrintIntervalsTheMultiplicity</tt></a></li>
-</ul>
-</li>
-<li><a class="reference internal" href="#poldectostring-decimal-number" id="id152"><tt class="docutils literal">\PolDecToString{decimal number}</tt></a></li>
-</ul>
-</li>
-<li><a class="reference internal" href="#booleans-with-default-setting-as-indicated" id="id153">Booleans (with default setting as indicated)</a><ul>
-<li><a class="reference internal" href="#xintverbosefalse" id="id154"><tt class="docutils literal">\xintverbosefalse</tt></a></li>
-<li><a class="reference internal" href="#poltypesetallfalse" id="id155"><tt class="docutils literal">\poltypesetallfalse</tt></a></li>
-<li><a class="reference internal" href="#poltoexprallfalse" id="id156"><tt class="docutils literal">\poltoexprallfalse</tt></a></li>
-</ul>
-</li>
-<li><a class="reference internal" href="#polexprsetup" id="id157"><tt class="docutils literal">\polexprsetup</tt></a></li>
-<li><a class="reference internal" href="#technicalities" id="id158">Technicalities</a></li>
-<li><a class="reference internal" href="#change-log" id="id159">CHANGE LOG</a></li>
-<li><a class="reference internal" href="#acknowledgments" id="id160">Acknowledgments</a></li>
-</ul>
-</div>
-<div class="section" id="basic-syntax">
-<h1><a class="toc-backref" href="#id38">Basic syntax</a></h1>
-<p>The syntax is:</p>
-<pre class="literal-block">
-\poldef polname(x):= expression in variable x;
-</pre>
-<p>where:</p>
-<ul class="simple">
-<li>in place of <tt class="docutils literal">x</tt> an arbitrary <em>dummy variable</em> is authorized,
-i.e. per default any of <tt class="docutils literal"><span class="pre">[a-z|A-Z]</span></tt> (more letters can be declared
-under Unicode engines.)</li>
-<li><tt class="docutils literal">polname</tt> consists of letters, digits, and the <tt class="docutils literal">_</tt> and
-<tt class="docutils literal">'</tt> characters. It must start with a letter.</li>
-</ul>
-<div class="admonition attention">
-<p class="first admonition-title">Attention!</p>
-<p class="last">The <tt class="docutils literal">'</tt> is authorized since <tt class="docutils literal">0.5.1</tt>. As a result some constructs
-recognized by the <tt class="docutils literal">\xintexpr</tt> parser, such as <tt class="docutils literal">var1 'and' var2</tt>
-will get misinterpreted and cause errors. However these constructs
-are unlikely to be frequently needed in polynomial expressions, and
-the <tt class="docutils literal">\xintexpr</tt> syntax offers alternatives, so it was deemed a
-small evil. Of course the <tt class="docutils literal">\xintexpr</tt> parser is modified only
-temporarily during execution of <tt class="docutils literal">\poldef</tt>.</p>
-</div>
-<p>One can also issue:</p>
-<pre class="literal-block">
-\PolDef{polname}{expression in variable x}
-</pre>
-<p>which admits an optional first argument to modify the variable letter
-from its default <tt class="docutils literal">x</tt>.</p>
-<dl class="docutils">
-<dt><tt class="docutils literal">\poldef <span class="pre">f(x):=</span> <span class="pre">1-x+x^2;</span></tt></dt>
-<dd>defines polynomial <tt class="docutils literal">f</tt>. Polynomial names must start with a
-letter and may contain letters, digits, underscores and the right
-tick character. The
-variable must be a single letter. The colon character is optional.
-The semi-colon at end of expression is mandatory.</dd>
-<dt><tt class="docutils literal"><span class="pre">\PolDef{f}{1-x+x^2}</span></tt></dt>
-<dd>does the same as <tt class="docutils literal">\poldef <span class="pre">f(x):=</span> <span class="pre">1-x+x^2;</span></tt> To use another letter
-than <tt class="docutils literal">x</tt> in the expression, one must pass it as an extra optional
-argument to <tt class="docutils literal">\PolDef</tt>. Useful if the semi-colon has been assigned
-some non-standard catcode by some package.</dd>
-<dt><tt class="docutils literal"><span class="pre">\PolLet{g}={f}</span></tt></dt>
-<dd>saves a copy of <tt class="docutils literal">f</tt> under name <tt class="docutils literal">g</tt>. Also usable without <tt class="docutils literal">=</tt>.</dd>
-<dt><tt class="docutils literal">\poldef <span class="pre">f(z):=</span> <span class="pre">f(z)^2;</span></tt></dt>
-<dd>redefines <tt class="docutils literal">f</tt> in terms of itself.</dd>
-<dt><tt class="docutils literal">\poldef <span class="pre">f(T):=</span> <span class="pre">f(f(T));</span></tt></dt>
-<dd>again redefines <tt class="docutils literal">f</tt> in terms of its (new) self.</dd>
-<dt><tt class="docutils literal">\poldef <span class="pre">k(z):=</span> <span class="pre">f(z)-g(g(z)^2)^2;</span></tt></dt>
-<dd>should now define the zero polynomial... Let's check:
-<tt class="docutils literal">\[ k(z) = <span class="pre">\PolTypeset[z]{k}</span> \]</tt></dd>
-<dt><tt class="docutils literal"><span class="pre">\PolDiff{f}{f'}</span></tt></dt>
-<dd>sets <tt class="docutils literal">f'</tt> to the derivative of <tt class="docutils literal">f</tt>. The name doesn't have to be
-<tt class="docutils literal">f'</tt> (in fact the <tt class="docutils literal">'</tt> is licit only since <tt class="docutils literal">0.5.1</tt>).</dd>
-</dl>
-<div class="admonition important">
-<p class="first admonition-title">Important</p>
-<p class="last">This is not done automatically. If some new definition needs to use
-the derivative of some available polynomial, that derivative
-polynomial must have been defined via <tt class="docutils literal">\PolDiff</tt>: something like
-<tt class="docutils literal"><span class="pre">T'(x)^2</span></tt> will not work without a prior <tt class="docutils literal"><span class="pre">\PolDiff{T}{T'}</span></tt>.</p>
-</div>
-<dl class="docutils">
-<dt><tt class="docutils literal"><span class="pre">\PolDiff{f'}{f''}</span></tt></dt>
-<dd>obtains second derivative.</dd>
-<dt><tt class="docutils literal"><span class="pre">\PolDiff[3]{f}{f'''}</span></tt></dt>
-<dd>computes the third derivative.</dd>
-</dl>
-<pre class="literal-block">
-$f(z) = \PolTypeset[z]{f} $\newline
-$f'(z) = \PolTypeset[z]{f'} $\newline
-$f''(z) = \PolTypeset[z]{f''} $\newline
-$f'''(z)= \PolTypeset[z]{f'''} $\par
-</pre>
-<div class="admonition important">
-<p class="first admonition-title">Important</p>
-<p>The package does not currently know rational functions: <tt class="docutils literal">/</tt> in
-a parsed polynomial expression does the Euclidean quotient:</p>
-<pre class="literal-block">
-(1-x^2)/(1-x)
-</pre>
-<p>does give <tt class="docutils literal">1+x</tt> but</p>
-<pre class="literal-block">
-(1/(1-x))*(1-x^2)
-</pre>
-<p>evaluates to zero. This will work as expected:</p>
-<pre class="last literal-block">
-\poldef k(x):= (x-1)(x-2)(x-3)(x-4)/(x^2-5x+4);
-</pre>
-</div>
-<div class="admonition attention" id="warningtacit">
-<p class="first admonition-title">Attention!</p>
-<p><tt class="docutils literal">1/2 x^2</tt> skips the space and is treated like <tt class="docutils literal"><span class="pre">1/(2*x^2)</span></tt> because
-of the tacit multiplication rules of xintexpr. But this means it
-gives zero! Thus one must use <tt class="docutils literal">(1/2)x^2</tt> or <tt class="docutils literal">1/2*x^2</tt> or
-<tt class="docutils literal"><span class="pre">(1/2)*x^2</span></tt> for disambiguation: <tt class="docutils literal">x - 1/2*x^2 + <span class="pre">1/3*x^3...</span></tt>. It is
-even simpler to move the denominator to the right: <tt class="docutils literal">x - x^2/2 +
-x^3/3 - ...</tt>.</p>
-<p class="last">It is worth noting that <tt class="docutils literal"><span class="pre">1/2(x-1)(x-2)</span></tt> suffers the same issue:
-<a class="reference external" href="http://www.ctan.org/pkg/xint">xint</a> tacit multiplication always &quot;ties more&quot;, hence this gets
-interpreted as <tt class="docutils literal"><span class="pre">1/(2*(x-1)*(x-2))</span></tt> which gives zero by polynomial
-division. Thus, use one of <tt class="docutils literal"><span class="pre">(1/2)(x-1)(x-2)</span></tt>, <tt class="docutils literal"><span class="pre">1/2*(x-1)(x-2)</span></tt> or
-<tt class="docutils literal"><span class="pre">(x-1)(x-2)/2</span></tt>.</p>
-</div>
-<p>After:</p>
-<pre class="literal-block">
-\poldef f_1(x):= 25(x-1)(x^2-2)(x-3)(x-4)(x-5);%
-\poldef f_2(x):= 37(x-1)(x^2-2)(x-6)(x-7)(x-8);%
-</pre>
-<p>the macro call <tt class="docutils literal"><span class="pre">\PolGCD{f_1}{f_2}{k}</span></tt> sets <tt class="docutils literal">k</tt> to the (unitary) GCD of
-<tt class="docutils literal">f_1</tt> and <tt class="docutils literal">f_2</tt> (hence to the expansion of <tt class="docutils literal"><span class="pre">(x-1)(x^2-2)</span></tt>.)</p>
-<dl class="docutils">
-<dt><tt class="docutils literal">\PolToExpr{k}</tt></dt>
-<dd>will (expandably) give in this case <tt class="docutils literal"><span class="pre">x^3-x^2-2*x+2</span></tt>. This is
-useful for console or file output (the syntax is Maple- and
-PSTricks-compatible; the letter used in output can be
-(non-expandably) changed via a redefinition of <a class="reference internal" href="#poltoexprvar">\PolToExprVar</a>.)</dd>
-<dt><tt class="docutils literal"><span class="pre">\PolToExpr*{k}</span></tt></dt>
-<dd>gives ascending powers: <tt class="docutils literal"><span class="pre">2-2*x-x^2+x^3</span></tt>.</dd>
-</dl>
-</div>
-<div class="section" id="examples-of-localization-of-roots">
-<h1><a class="toc-backref" href="#id39">Examples of localization of roots</a></h1>
-<ul>
-<li><p class="first">To make printed decimal numbers more enjoyable than via
-<tt class="docutils literal">\xintSignedFrac</tt>:</p>
-<pre class="literal-block">
-\renewcommand\PolTypesetOne[1]{\PolDecToString{\xintREZ{#1}}}%
-</pre>
-<p><tt class="docutils literal">\PolDecToString</tt> will use decimal notation to incorporate the power
-of ten part; and the <tt class="docutils literal">\xintREZ</tt> will have the effect to suppress
-trailing zeros if present in raw numerator (if those digits end up
-after decimal mark.) Notice that the above are expandable macros and
-that one can also do:</p>
-<pre class="literal-block">
-\renewcommand\PolToExprCmd[1]{\PolDecToString{\xintREZ{#1}}}%
-</pre>
-<p>to modify output of <a class="reference internal" href="#poltoexpr-polname">\PolToExpr{polname}</a>.</p>
-</li>
-<li><p class="first">For extra info in log file use <tt class="docutils literal">\xintverbosetrue</tt>.</p>
-</li>
-<li><p class="first">Only for some of these examples is the output included here.</p>
-</li>
-</ul>
-<div class="section" id="a-typical-example">
-<h2><a class="toc-backref" href="#id40">A typical example</a></h2>
-<p>In this example the polynomial is square-free.</p>
-<pre class="literal-block">
-\poldef f(x) := x^7 - x^6 - 2x + 1;
-
-\PolToSturm{f}{f}
-\PolSturmIsolateZeros{f}
-The \PolTypeset{f} polynomial has \PolSturmNbOfIsolatedZeros{f} distinct real
-roots which are located in the following intervals:
-\PolPrintIntervals{f}
-Here is the second root with ten more decimal digits:
-\PolRefineInterval[10]{f}{2}
-\[\PolSturmIsolatedZeroLeft{f}{2}&lt;Z_2&lt;\PolSturmIsolatedZeroRight{f}{2}\]
-And here is the first root with twenty digits after decimal mark:
-\PolEnsureIntervalLength{f}{1}{-20}
-\[\PolSturmIsolatedZeroLeft{f}{1}&lt;Z_1&lt;\PolSturmIsolatedZeroRight{f}{1}\]
-The first element of the Sturm chain has degree $\PolDegree{f_0}$. As
-this is the original degreee $\PolDegree{f}$ we know that $f$ is square free.
-Its derivative is up to a constant \PolTypeset{f_1} (in this example
-it is identical with it).
-\PolToSturm{f_1}{f_1}\PolSturmIsolateZeros{f_1}%
-The derivative has \PolSturmNbOfIsolatedZeros{f_1} distinct real
-roots:
-\PolPrintIntervals[W]{f_1}
-\PolEnsureIntervalLengths{f_1}{-10}%
-Here they are with ten digits after decimal mark:
-\PolPrintIntervals[W]{f_1}
-\PolDiff{f_1}{f''}
-\PolToSturm{f''}{f''}
-\PolSturmIsolateZeros{f''}
-The second derivative is \PolTypeset{f''}.
-It has \PolSturmNbOfIsolatedZeros{f''} distinct real
-roots:
-\PolPrintIntervals[X]{f''}
-Here is the positive one with 20 digits after decimal mark:
-\PolEnsureIntervalLength{f''}{2}{-20}%
-\[X_2 = \PolSturmIsolatedZeroLeft{f''}{2}\dots\]
-The more mathematically advanced among our dear readers will be able
-to give the exact value for $X_2$!
-</pre>
-</div>
-<div class="section" id="a-degree-four-polynomial-with-nearby-roots">
-<h2><a class="toc-backref" href="#id41">A degree four polynomial with nearby roots</a></h2>
-<p>Notice that this example is a bit outdated as <tt class="docutils literal">0.7</tt> release has
-added <tt class="docutils literal"><span class="pre">\PolSturmIsolateZeros**{sturmname}</span></tt> which would find exactly
-the roots. The steps here retain their interest when one is interested
-in finding isolating intervals for example to prepare some demonstration
-of dichotomy method.</p>
-<pre class="literal-block">
-\PolDef{Q}{(x-1.050001)(x-1.105001)(x-1.110501)(x-1.111051)}
-\PolTypeset{Q}
-\PolToSturm{Q}{Q} % it is allowed to use same prefix for Sturm chain
-\PolSturmIsolateZeros{Q}
-\PolPrintIntervals{Q}
-% reports 1.0 &lt; Z_1 &lt; 1.1, 1.10 &lt; Z_2 &lt; 1.11, 1.110 &lt; Z_3 &lt; 1.111, and 1.111 &lt; Z_4 &lt; 1.112
-% but the above bounds do not allow minimizing separation between roots
-% so we refine:
-\PolRefineInterval*{Q}{1}
-\PolRefineInterval*{Q}{2}
-\PolRefineInterval*{Q}{3}
-\PolRefineInterval*{Q}{4}
-\PolPrintIntervals{Q}
-% reports 1.05 &lt; Z_1 &lt; 1.06, 1.105 &lt; Z_2 &lt; 1.106, 1.1105 &lt; Z_3 &lt; 1.1106,
-% and 1.11105 &lt; Z_4 &lt; 1.11106.
-\PolEnsureIntervalLengths{Q}{-6}
-\PolPrintIntervals{Q}
-% of course finds here all roots exactly
-</pre>
-</div>
-<div class="section" id="the-degree-nine-polynomial-with-0-99-0-999-0-9999-as-triple-roots">
-<h2><a class="toc-backref" href="#id42">The degree nine polynomial with 0.99, 0.999, 0.9999 as triple roots</a></h2>
-<pre class="literal-block">
-% define a user command (xinttools is loaded automatically by polexpr)
-\newcommand\showmultiplicities[1]{% #1 = &quot;sturmname&quot;
-\xintFor* ##1 in {\xintSeq{1}{\PolSturmNbOfIsolatedZeros{#1}}}\do{%
- The multiplicity is \PolSturmIsolatedZeroMultiplicity{#1}{##1}
- \PolSturmIfZeroExactlyKnown{#1}{##1}%
- {at the root $x=\PolSturmIsolatedZeroLeft{#1}{##1}$}
- {for the root such that
- $\PolSturmIsolatedZeroLeft{#1}{##1}&lt;x&lt;\PolSturmIsolatedZeroRight{#1}{##1}$}
- \par
-}}%
-\PolDef{f}{(x-0.99)^3(x-0.999)^3(x-0.9999)^3}
-\renewcommand\PolTypesetOne[1]{\PolDecToString{\xintREZ{#1}}}
-\PolTypeset{f}\par
-\PolToSturm{f}{f}% it is allowed to use &quot;polname&quot; as &quot;sturmname&quot; too
-\PolSturmIsolateZerosAndGetMultiplicities{f}% use the &quot;sturmname&quot; here
-% or \PolSturmIsolateZeros*{f} which is exactly the same, but shorter..
-
-\showmultiplicities{f}
-</pre>
-<p>In this example, the output will look like this (but using math mode):</p>
-<pre class="literal-block">
-x^9 - 8.9667x^8 + 35.73400293x^7 - 83.070418400109x^6 + 124.143648875193123x^5
-- 123.683070924326075877x^4 + 82.149260397553075617891x^3
-- 35.07602992699900159127007x^2 + 8.7364078733314648368671733x
-- 0.967100824643585986488103299
-
-The multiplicity is 3 at the root x = 0.99
-The multiplicity is 3 at the root x = 0.999
-The multiplicity is 3 at the root x = 0.9999
-</pre>
-<p>On first pass, these rational roots were found (due to their relative
-magnitudes, using <tt class="docutils literal">\PolSturmIsolateZeros**</tt> was not needed here). But
-multiplicity computation works also with (decimal) roots not yet
-identified or with non-decimal or irrational roots.</p>
-<p>It is fun to modify only a tiny bit the polynomial and see if polexpr
-survives:</p>
-<pre class="literal-block">
-\PolDef{g}{f(x)+1e-27}
-\PolTypeset{g}\par
-\PolToSturm{g}{g}
-\PolSturmIsolateZeros*{g}
-
-\showmultiplicities{g}
-</pre>
-<p>This produces:</p>
-<pre class="literal-block">
-x^9 - 8.9667x^8 + 35.73400293x^7 - 83.070418400109x^6 + 124.143648875193123x^5
-- 123.683070924326075877x^4 + 82.149260397553075617891x^3
-- 35.07602992699900159127007x^2 + 8.7364078733314648368671733x
-- 0.967100824643585986488103298
-
-The multiplicity is 1 for the root such that 0.98 &lt; x &lt; 0.99
-The multiplicity is 1 for the root such that 0.9991 &lt; x &lt; 0.9992
-The multiplicity is 1 for the root such that 0.9997 &lt; x &lt; 0.9998
-</pre>
-<p>Which means that the multiplicity-3 roots each became a real and a pair of
-complex ones. Let's see them better:</p>
-<pre class="literal-block">
-\PolEnsureIntervalLengths{g}{-10}
-
-\showmultiplicities{g}
-</pre>
-<p>which produces:</p>
-<pre class="literal-block">
-The multiplicity is 1 for the root such that 0.9899888032 &lt; x &lt; 0.9899888033
-The multiplicity is 1 for the root such that 0.9991447980 &lt; x &lt; 0.9991447981
-The multiplicity is 1 for the root such that 0.9997663986 &lt; x &lt; 0.9997663987
-</pre>
-</div>
-<div class="section" id="a-degree-five-polynomial-with-three-rational-roots">
-<h2><a class="toc-backref" href="#id43">A degree five polynomial with three rational roots</a></h2>
-<pre class="literal-block">
-\poldef Q(x) := 1581755751184441 x^5
- -14907697165025339 x^4
- +48415668972339336 x^3
- -63952057791306264 x^2
- +46833913221154895 x
- -49044360626280925;
-
-\PolToSturm{Q}{Q}
-%\begin{flushleft}
- \renewcommand\PolTypesetCmdPrefix[1]{\allowbreak\xintiiifSgn{#1}{}{+}{+}}%
- $Q_0(x) = \PolTypeset{Q_0}$
-%\end{flushleft}
-\PolSturmIsolateZeros**{Q}
-\PolPrintIntervals{Q}
-
-$Q_{norr}(x) = \PolTypeset{Q_norr}$
-</pre>
-<p>Here, all real roots are rational:</p>
-<pre class="literal-block">
-Z_1 = 833719/265381
-Z_2 = 165707065/52746197
-Z_3 = 355/113
-
-Q_norr(x) = x^2 + 1
-</pre>
-<p>And let's get their decimal expansion too:</p>
-<pre class="literal-block">
-% print decimal expansion of the found roots
-\renewcommand\PolPrintIntervalsPrintExactZero
- {\xintTrunc{20}{\PolPrintIntervalsTheLeftEndPoint}\dots}
-\PolPrintIntervals{Q}
-
-Z_1 = 3.14159265358107777120...
-Z_2 = 3.14159265358979340254...
-Z_3 = 3.14159292035398230088...
-</pre>
-</div>
-<div class="section" id="a-mignotte-type-polynomial">
-<h2><a class="toc-backref" href="#id44">A Mignotte type polynomial</a></h2>
-<pre class="literal-block">
-\PolDef{P}{x^10 - (10x-1)^2}%
-\PolTypeset{P} % prints it in expanded form
-\PolToSturm{P}{P} % we can use same prefix for Sturm chain
-\PolSturmIsolateZeros{P} % finds 4 real roots
-This polynomial has \PolSturmNbOfIsolatedZeros{P} distinct real roots:
-\PolPrintIntervals{P}%
-% reports -2 &lt; Z_1 &lt; -1, 0.09 &lt; Z_2 &lt; 0.10, 0.1 &lt; Z_3 &lt; 0.2, 1 &lt; Z_4 &lt; 2
-Let us refine the second and third intervals to separate the corresponding
-roots:
-\PolRefineInterval*{P}{2}% will refine to 0.0999990 &lt; Z_2 &lt; 0.0999991
-\PolRefineInterval*{P}{3}% will refine to 0.100001 &lt; Z_3 &lt; 0.100002
-\PolPrintIntervals{P}%
-Let us now get to know all roots with 10 digits after decimal mark:
-\PolEnsureIntervalLengths{P}{-10}%
-\PolPrintIntervals{P}% now all roots are known 10 decimal digits after mark
-Finally, we display 20 digits of the second root:
-\PolEnsureIntervalLength{P}{2}{-20}% makes Z_2 known with 20 digits after mark
-\[\PolSturmIsolatedZeroLeft{P}{2}&lt;Z_2&lt;\PolSturmIsolatedZeroRight{P}{2}\]
-</pre>
-<p>The last line produces:</p>
-<pre class="literal-block">
-0.09999900004999650028 &lt; Z_2 &lt; 0.09999900004999650029
-</pre>
-</div>
-<div class="section" id="the-wilkinson-polynomial">
-<h2><a class="toc-backref" href="#id45">The Wilkinson polynomial</a></h2>
-<p>See <a class="reference external" href="https://en.wikipedia.org/wiki/Wilkinson%27s_polynomial">Wilkinson polynomial</a>.</p>
-<pre class="literal-block">
-\documentclass{article}
-\usepackage{polexpr}
-\begin{document}
-%\xintverbosetrue % for the curious...
-
-\poldef f(x) := mul((x - i), i = 1..20);
-
-\renewcommand\PolTypesetCmdPrefix[1]{\allowbreak\xintiiifSgn{#1}{}{+}{+}}%
-\renewcommand\PolTypesetOne[1]{\xintDecToString{#1}}%
-
-\noindent\PolTypeset{f}
-
-\PolToSturm{f}{f}
-\PolSturmIsolateZeros{f}
-\PolPrintIntervals{f}
-
-\clearpage
-
-\poldef g(x) := f(x) - 2**{-23} x**19;
-
-% be patient!
-\PolToSturm{g}{g}
-\noindent\PolTypeset{g_0}% integer coefficient primitive polynomial
-
-\PolSturmIsolateZeros{g}
-\PolEnsureIntervalLengths{g}{-10}
-
-\renewcommand\PolPrintIntervalsPrintMultiplicity{}
-\PolPrintIntervals*{g}
-
-\end{document}
-</pre>
-<p>The first polynomial:</p>
-<pre class="literal-block">
-f(x) = x**20
-- 210 x**19
-+ 20615 x**18
-- 1256850 x**17
-+ 53327946 x**16
-- 1672280820 x**15
-+ 40171771630 x**14
-- 756111184500 x**13
-+ 11310276995381 x**12
-- 135585182899530 x**11
-+ 1307535010540395 x**10
-- 10142299865511450 x**9
-+ 63030812099294896 x**8
-- 311333643161390640 x**7
-+ 1206647803780373360 x**6
-- 3599979517947607200 x**5
-+ 8037811822645051776 x**4
-- 12870931245150988800 x**3
-+ 13803759753640704000 x**2
-- 8752948036761600000 x
-+ 2432902008176640000
-</pre>
-<p>is handled fast enough (a few seconds), but the modified one <tt class="docutils literal">f(x) -
-<span class="pre">2**-23</span> <span class="pre">x**19</span></tt> takes about 20x longer (the Sturm chain polynomials
-have integer coefficients with up to 321 digits, whereas (surprisingly
-perhaps) those of the Sturm chain polynomials derived from <tt class="docutils literal">f</tt> never
-have more than 21 digits ...).</p>
-<p>Once the Sturm chain is computed and the zeros isolated, obtaining their
-decimal digits is relatively faster. Here is for the ten real roots of
-<tt class="docutils literal">f(x) - <span class="pre">2**-23</span> <span class="pre">x**19</span></tt> as computed by the code above:</p>
-<pre class="literal-block">
-Z_1 = 0.9999999999...
-Z_2 = 2.0000000000...
-Z_3 = 2.9999999999...
-Z_4 = 4.0000000002...
-Z_5 = 4.9999999275...
-Z_6 = 6.0000069439...
-Z_7 = 6.9996972339...
-Z_8 = 8.0072676034...
-Z_9 = 8.9172502485...
-Z_10 = 20.8469081014...
-</pre>
-</div>
-<div class="section" id="the-second-wilkinson-polynomial">
-<h2><a class="toc-backref" href="#id46">The second Wilkinson polynomial</a></h2>
-<pre class="literal-block">
-\documentclass{article}
-\usepackage{polexpr}
-\begin{document}
-\poldef f(x) := mul(x - 2^-i, i = 1..20);
-
-%\PolTypeset{f}
-
-\PolToSturm{f}{f}
-\PolSturmIsolateZeros**{f}
-\PolPrintIntervals{f}
-\end{document}
-</pre>
-<p>This takes more time than the polynomial with 1, 2, .., 20 as roots but
-less than the latter modified by the <tt class="docutils literal"><span class="pre">2**-23</span></tt> change in one
-coefficient.</p>
-<p>Here is the output (with release 0.7.2):</p>
-<pre class="literal-block">
-Z_1 = 0.00000095367431640625
-Z_2 = 0.0000019073486328125
-Z_3 = 0.000003814697265625
-Z_4 = 0.00000762939453125
-Z_5 = 0.0000152587890625
-Z_6 = 0.000030517578125
-Z_7 = 0.00006103515625
-Z_8 = 0.0001220703125
-Z_9 = 1/4096
-Z_10 = 1/2048
-Z_11 = 1/1024
-Z_12 = 1/512
-Z_13 = 1/256
-Z_14 = 1/128
-Z_15 = 0.015625
-Z_16 = 0.03125
-Z_17 = 0.0625
-Z_18 = 0.125
-Z_19 = 0.25
-Z_20 = 0.5
-</pre>
-<p>There is some incoherence in output format which has its source in the
-fact that some roots are found in branches which can only find decimal
-roots, whereas some are found in branches which could find general
-fractions and they use <tt class="docutils literal">\xintIrr</tt> before storage of the found root.
-This may evolve in future.</p>
-</div>
-<div class="section" id="the-degree-41-polynomial-with-2-1-9-1-8-0-0-1-1-9-2-as-roots">
-<h2><a class="toc-backref" href="#id47">The degree 41 polynomial with -2, -1.9, -1.8, ..., 0, 0.1, ..., 1.9, 2 as roots</a></h2>
-<pre class="literal-block">
-\PolDef{P}{mul((x-i*1e-1), i=-20..20)}% i/10 is same but less efficient
-</pre>
-<p>In the defining expression we could have used <tt class="docutils literal">i/10</tt> but this gives
-less efficient internal form for the coefficients (the <tt class="docutils literal">10</tt>'s end up
-in denominators). Using <tt class="docutils literal">\PolToExpr{P}</tt> after having done</p>
-<pre class="literal-block">
-\renewcommand\PolToExprCmd[1]{\PolDecToString{\xintREZ{#1}}}
-</pre>
-<p>we get this expanded form:</p>
-<pre class="literal-block">
-x^41
--28.7*x^39
-+375.7117*x^37
--2975.11006*x^35
-+15935.28150578*x^33
--61167.527674162*x^31
-+173944.259366417394*x^29
--373686.963560544648*x^27
-+613012.0665016658846445*x^25
--771182.31133138163125495*x^23
-+743263.86672885754888959569*x^21
--545609.076599482896371978698*x^19
-+301748.325708943677229642930528*x^17
--123655.8987669450434698869844544*x^15
-+36666.1782054884005855608205864192*x^13
--7607.85821367459445649518380016128*x^11
-+1053.15135918687298508885950223794176*x^9
--90.6380005918141132650786081964032*x^7
-+4.33701563847327366842552218288128*x^5
--0.0944770968420804735498178265088*x^3
-+0.00059190121813899276854174416896*x
-</pre>
-<p>which shows coefficients with up to 36 significant digits...</p>
-<p>Stress test: not a hard challenge to <tt class="docutils literal">xint + polexpr</tt>, but be a bit patient!</p>
-<pre class="literal-block">
-\PolDef{P}{mul((x-i*1e-1), i=-20..20)}%
-\PolToSturm{P}{S} % dutifully computes S_0, ..., S_{41}
-% the [1] optional argument limits the search to interval (-10,10)
-\PolSturmIsolateZeros[1]{S} % finds *exactly* (but a bit slowly) all 41 roots!
-\PolPrintIntervals{S} % nice, isn't it?
-</pre>
-<div class="admonition note">
-<p class="first admonition-title">Note</p>
-<p>Release <tt class="docutils literal">0.5</tt> has <em>experimental</em> addition of optional argument
-<tt class="docutils literal">E</tt> to <tt class="docutils literal">\PolSturmIsolateZeros</tt>. It instructs to search roots only
-in interval <tt class="docutils literal"><span class="pre">(-10^E,</span> 10^E)</tt>. Important: the extremities are
-<em>assumed to not be roots</em>. In this example, the <tt class="docutils literal">[1]</tt> in
-<tt class="docutils literal"><span class="pre">\PolSturmIsolateZeros[1]{S}</span></tt> gives some speed gain; without it, it
-turns out in this case that <tt class="docutils literal">polexpr</tt> would have started with
-<tt class="docutils literal"><span class="pre">(-10^6,</span> 10^6)</tt> interval.</p>
-<p class="last">Please note that this will probably get replaced in future by the
-specification of a general interval. Do not rely on meaning of this
-optional argument keeping the same.</p>
-</div>
-</div>
-<div class="section" id="roots-of-chebyshev-polynomials">
-<h2><a class="toc-backref" href="#id48">Roots of Chebyshev polynomials</a></h2>
-<pre class="literal-block">
-\newcount\mycount
-\poldef T_0(x) := 1;
-\poldef T_1(x) := x;
-\mycount 2
-\xintloop
- \poldef T_\the\mycount(x) :=
- 2x*T_\the\numexpr\mycount-1(x)
- - T_\the\numexpr\mycount-2(x);
-\ifnum\mycount&lt;15
-\advance\mycount 1
-\repeat
-
-\[T_{15} = \PolTypeset[X]{T_15}\]
-\PolToSturm{T_15}{T_15}
-\PolSturmIsolateZeros{T_15}
-\PolEnsureIntervalLengths{T_15}{-10}
-\PolPrintIntervals{T_15}
-</pre>
-</div>
-</div>
-<div class="section" id="non-expandable-macros">
-<h1><a class="toc-backref" href="#id49">Non-expandable macros</a></h1>
-<div class="section" id="poldef-polname-letter-expression-in-letter">
-<span id="poldef"></span><h2><a class="toc-backref" href="#id50"><tt class="docutils literal">\poldef <span class="pre">polname(letter):=</span> expression in letter;</tt></a></h2>
-<blockquote>
-<p>This evaluates the <em>polynomial expression</em> and stores the coefficients
-in a private structure accessible later via other package macros,
-under the user-chosen <tt class="docutils literal">polname</tt>. Of course the <em>expression</em> can
-use other previously defined polynomials. Names must start with a
-letter and are constituted of letters, digits, underscores and
-(since <tt class="docutils literal">0.5.1</tt>) the right tick <tt class="docutils literal">'</tt>.
-The whole <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> syntax is authorized:</p>
-<pre class="literal-block">
-\poldef sin(z) := add((-1)^i z^(2i+1)/(2i+1)!, i = 0..10);
-</pre>
-<p>With fractional coefficients, beware the <a class="reference internal" href="#warningtacit">tacit multiplication issue</a>.</p>
-<p>As a side effect the function <tt class="docutils literal">polname()</tt> is recognized as a
-genuine <tt class="docutils literal"><span class="pre">\xintexpr...\relax</span></tt> function for (exact) numerical
-evaluation (or within an <tt class="docutils literal">\xintdefvar</tt> assignment.) It computes
-values not according to the original expression but via the Horner
-scheme corresponding to the polynomial coefficients.</p>
-<div class="admonition attention">
-<p class="first admonition-title">Attention!</p>
-<p>Release <tt class="docutils literal">0.3</tt> also did the necessary set-up to let the
-polynomial be known to the <tt class="docutils literal">\xintfloatexpr</tt> (or
-<tt class="docutils literal">\xintdeffloatvar</tt>) parser.</p>
-<p>Since <tt class="docutils literal">0.4</tt> this isn't done automatically. Even more, a
-previously existing floating point variant of the same name will
-be let undefined again, to avoid hard to debug mismatches between
-exact and floating point polynomials. This also applies when the
-polynomial is produced not via <tt class="docutils literal">\poldef</tt> or <tt class="docutils literal">\PolDef</tt> but as
-a product of the other package macros.</p>
-<p class="last">See <a class="reference internal" href="#polgenfloatvariant-polname">\PolGenFloatVariant{polname}</a>.</p>
-</div>
-<p>The original expression is lost after parsing, and in particular
-the package provides no way to typeset it. This has to be done
-manually, if needed.</p>
-</blockquote>
-</div>
-<div class="section" id="poldef-letter-polname-expression-in-letter">
-<span id="id2"></span><h2><a class="toc-backref" href="#id51"><tt class="docutils literal"><span class="pre">\PolDef[letter]{polname}{expression</span> in letter}</tt></a></h2>
-<blockquote>
-Does the same as <a class="reference external" href="poldef;">\poldef</a> in an undelimited macro
-format (thus avoiding potential problems with the catcode of the
-semi-colon in presence of some packages.) In absence of the
-<tt class="docutils literal">[letter]</tt> optional argument, the variable is assumed to be <tt class="docutils literal">x</tt>.</blockquote>
-</div>
-<div class="section" id="polgenfloatvariant-polname">
-<span id="polgenfloatvariant"></span><h2><a class="toc-backref" href="#id52"><tt class="docutils literal">\PolGenFloatVariant{polname}</tt></a></h2>
-<blockquote>
-<p>Makes the polynomial also usable in the <tt class="docutils literal">\xintfloatexpr</tt> parser.
-It will therein evaluates via an Horner scheme with coefficients
-already pre-rounded to the float precision.</p>
-<p>See also <a class="reference internal" href="#poltofloatexpr-polname">\PolToFloatExpr{polname}</a>.</p>
-<div class="admonition attention">
-<p class="first admonition-title">Attention!</p>
-<p>Release <tt class="docutils literal">0.3</tt> did this automatically on <tt class="docutils literal">\PolDef</tt> and
-<tt class="docutils literal">\poldef</tt> but this was removed at <tt class="docutils literal">0.4</tt> for optimization.</p>
-<p class="last">Any operation, for example generating the derivative polynomial,
-or dividing two polynomials or using the <tt class="docutils literal">\PolLet</tt>, <strong>must</strong> be
-followed by explicit usage of <tt class="docutils literal">\PolGenFloatVariant{polname}</tt> if
-the new polynomial is to be used in <tt class="docutils literal">\xintfloatexpr</tt> or alike
-context.</p>
-</div>
-</blockquote>
-</div>
-<div class="section" id="pollet-polname-2-polname-1">
-<span id="pollet"></span><h2><a class="toc-backref" href="#id53"><tt class="docutils literal"><span class="pre">\PolLet{polname_2}={polname_1}</span></tt></a></h2>
-<blockquote>
-Makes a copy of the already defined polynomial <tt class="docutils literal">polname_1</tt> to a
-new one <tt class="docutils literal">polname_2</tt>. Same effect as
-<tt class="docutils literal"><span class="pre">\PolDef{polname_2}{polname_1(x)}</span></tt> but with less overhead. The
-<tt class="docutils literal">=</tt> is optional.</blockquote>
-</div>
-<div class="section" id="polgloballet-polname-2-polname-1">
-<span id="polgloballet"></span><h2><a class="toc-backref" href="#id54"><tt class="docutils literal"><span class="pre">\PolGlobalLet{polname_2}={polname_1}</span></tt></a></h2>
-<blockquote>
-Acts globally.</blockquote>
-</div>
-<div class="section" id="polassign-polname-toarray-macro">
-<span id="polassign"></span><h2><a class="toc-backref" href="#id55"><tt class="docutils literal"><span class="pre">\PolAssign{polname}\toarray\macro</span></tt></a></h2>
-<blockquote>
-<p>Defines a one-argument expandable macro <tt class="docutils literal"><span class="pre">\macro{#1}</span></tt> which expands
-to the (raw) #1th polynomial coefficient.</p>
-<ul class="simple">
-<li>Attention, coefficients here are indexed starting at 1.</li>
-<li>With #1=-1, -2, ..., <tt class="docutils literal"><span class="pre">\macro{#1}</span></tt> returns leading coefficients.</li>
-<li>With #1=0, returns the number of coefficients, i.e. <tt class="docutils literal">1 + deg f</tt>
-for non-zero polynomials.</li>
-<li>Out-of-range #1's return <tt class="docutils literal">0/1[0]</tt>.</li>
-</ul>
-<p>See also <a class="reference internal" href="#polnthcoeff-polname-number">\PolNthCoeff{polname}{number}</a>. The main difference is that
-with <tt class="docutils literal">\PolAssign</tt>, <tt class="docutils literal">\macro</tt> is made a prefix to <tt class="docutils literal">1 + deg f</tt>
-already defined (hidden to user) macros holding individually the
-coefficients but <a class="reference internal" href="#polnthcoeff-polname-number">\PolNthCoeff{polname}{number}</a> does each time the job
-to expandably recover the <tt class="docutils literal">Nth</tt> coefficient, and due to
-expandability can not store it in a macro for future usage (of course,
-it can be an argument in an <tt class="docutils literal">\edef</tt>.) The other difference
-is the shift by one in indexing, mentioned above (negative
-indices act the same in both.)</p>
-</blockquote>
-</div>
-<div class="section" id="polget-polname-fromarray-macro">
-<span id="polget"></span><h2><a class="toc-backref" href="#id56"><tt class="docutils literal"><span class="pre">\PolGet{polname}\fromarray\macro</span></tt></a></h2>
-<blockquote>
-<p>Does the converse operation to
-<tt class="docutils literal"><span class="pre">\PolAssign{polname}\toarray\macro</span></tt>. Each individual
-<tt class="docutils literal">\macro{number}</tt> gets expanded in an <tt class="docutils literal">\edef</tt> and then normalized
-via <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a>'s macro <tt class="docutils literal">\xintRaw</tt>.</p>
-<p>The leading zeros are removed from the polynomial.</p>
-<p>(contrived) Example:</p>
-<pre class="literal-block">
-\xintAssignArray{1}{-2}{5}{-3}\to\foo
-\PolGet{f}\fromarray\foo
-</pre>
-<p>This will define <tt class="docutils literal">f</tt> as would have <tt class="docutils literal">\poldef <span class="pre">f(x):=1-2x+5x^2-3x^3;</span></tt>.</p>
-<div class="admonition note">
-<p class="first admonition-title">Note</p>
-<p class="last">Prior to <tt class="docutils literal">0.5</tt>, coefficients were not normalized via
-<tt class="docutils literal">\xintRaw</tt> for internal storage.</p>
-</div>
-</blockquote>
-</div>
-<div class="section" id="polfromcsv-polname-csv">
-<span id="polfromcsv"></span><h2><a class="toc-backref" href="#id57"><tt class="docutils literal"><span class="pre">\PolFromCSV{polname}{&lt;csv&gt;}</span></tt></a></h2>
-<blockquote>
-<p>Defines a polynomial directly from the comma separated list of values
-(or a macro expanding to such a list) of its coefficients, the <em>first
-item</em> gives the constant term, the <em>last item</em> gives the leading
-coefficient, except if zero, then it is dropped (iteratively). List
-items are each expanded in an <tt class="docutils literal">\edef</tt> and then put into normalized
-form via <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a>'s macro <tt class="docutils literal">\xintRaw</tt>.</p>
-<p>As leading zero coefficients are removed:</p>
-<pre class="literal-block">
-\PolFromCSV{f}{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
-</pre>
-<p>defines the zero polynomial, which holds only one coefficient.</p>
-<p>See also expandable macro <a class="reference internal" href="#poltocsv-polname">\PolToCSV</a>.</p>
-<div class="admonition note">
-<p class="first admonition-title">Note</p>
-<p class="last">Prior to <tt class="docutils literal">0.5</tt>, coefficients were not normalized via
-<tt class="docutils literal">\xintRaw</tt> for internal storage.</p>
-</div>
-</blockquote>
-</div>
-<div class="section" id="poltypeset-polname">
-<span id="poltypeset"></span><h2><a class="toc-backref" href="#id58"><tt class="docutils literal">\PolTypeset{polname}</tt></a></h2>
-<blockquote>
-<p>Typesets in descending powers in math mode. It uses letter <tt class="docutils literal">x</tt> but
-this can be changed via an optional argument:</p>
-<pre class="literal-block">
-\PolTypeset[z]{polname}
-</pre>
-<p>By default zero coefficients are skipped (issue <tt class="docutils literal">\poltypesetalltrue</tt>
-to get all of them in output).</p>
-<p>These commands (whose meanings will be found in the package code)
-can be re-defined for customization. Their default definitions are
-expandable, but this is not a requirement.</p>
-</blockquote>
-<div class="section" id="poltypesetcmd-raw-coeff">
-<span id="poltypesetcmd"></span><h3><a class="toc-backref" href="#id59"><tt class="docutils literal">\PolTypesetCmd{raw_coeff}</tt></a></h3>
-<blockquote>
-<p>Checks if the coefficient is <tt class="docutils literal">1</tt> or <tt class="docutils literal"><span class="pre">-1</span></tt> and then skips printing
-the <tt class="docutils literal">1</tt>, except for the constant term. Also it sets conditional
-<a class="reference internal" href="#polifcoeffisplusorminusone-a-b">\PolIfCoeffIsPlusOrMinusOne{A}{B}</a>.</p>
-<p>The actual printing of the coefficients, when not equal to plus or
-minus one is handled by <a class="reference internal" href="#poltypesetone-raw-coeff">\PolTypesetOne{raw_coeff}</a>.</p>
-</blockquote>
-</div>
-<div class="section" id="poltypesetone-raw-coeff">
-<span id="poltypesetone"></span><h3><a class="toc-backref" href="#id60"><tt class="docutils literal">\PolTypesetOne{raw_coeff}</tt></a></h3>
-<blockquote>
-<p>The default is <tt class="docutils literal">\xintSignedFrac</tt> but this macro is annoying as it
-insists to use a power of ten, and not decimal notation.</p>
-<p>One can do things such as for example: <a class="footnote-reference" href="#id5" id="id4">[1]</a></p>
-<pre class="literal-block">
-\renewcommand\PolTypesetOne[1]{\num{\xintPFloat[5]{#1}}}
-\renewcommand\PolTypesetOne[1]{\num{\xintRound{4}{#1}}}
-</pre>
-<p>where e.g. we used the <tt class="docutils literal">\num</tt> macro of <tt class="docutils literal">siunitx</tt> as it
-understands floating point notation.</p>
-<table class="docutils footnote" frame="void" id="id5" rules="none">
-<colgroup><col class="label" /><col /></colgroup>
-<tbody valign="top">
-<tr><td class="label"><a class="fn-backref" href="#id4">[1]</a></td><td>the difference in the syntaxes of <tt class="docutils literal">\xintPFloat</tt> and
-<tt class="docutils literal">\xintRound</tt> is explained from the fact that
-<tt class="docutils literal">\xintPFloat</tt> by default uses the prevailing precision
-hence the extra argument like here <tt class="docutils literal">5</tt> is an optional one.</td></tr>
-</tbody>
-</table>
-<p>One can also give a try to using <a class="reference internal" href="#poldectostring-decimal-number">\PolDecToString{decimal number}</a>
-which uses decimal notation (at least for the numerator part).</p>
-</blockquote>
-</div>
-<div class="section" id="id6">
-<span id="poltypesetmonomialcmd"></span><h3><a class="toc-backref" href="#id61"><tt class="docutils literal">\PolTypesetMonomialCmd</tt></a></h3>
-<blockquote>
-This decides how a monomial (in variable <tt class="docutils literal">\PolVar</tt> and with
-exponent <tt class="docutils literal">\PolIndex</tt>) is to be printed. The default does nothing
-for the constant term, <tt class="docutils literal">\PolVar</tt> for the first degree and
-<tt class="docutils literal"><span class="pre">\PolVar^{\PolIndex}</span></tt> for higher degrees monomials. Beware that
-<tt class="docutils literal">\PolIndex</tt> expands to digit tokens and needs termination in
-<tt class="docutils literal">\ifnum</tt> tests.</blockquote>
-</div>
-<div class="section" id="poltypesetcmdprefix-raw-coeff">
-<span id="poltypesetcmdprefix"></span><h3><a class="toc-backref" href="#id62"><tt class="docutils literal">\PolTypesetCmdPrefix{raw_coeff}</tt></a></h3>
-<blockquote>
-Expands to a <tt class="docutils literal">+</tt> if the <tt class="docutils literal">raw_coeff</tt> is zero or positive, and to
-nothing if <tt class="docutils literal">raw_coeff</tt> is negative, as in latter case the
-<tt class="docutils literal">\xintSignedFrac</tt> used by <a class="reference internal" href="#poltypesetcmd-raw-coeff">\PolTypesetCmd{raw_coeff}</a> will put
-the <tt class="docutils literal">-</tt> sign in front of the fraction (if it is a fraction) and
-this will thus serve as separator in the typeset formula. Not used
-for the first term.</blockquote>
-</div>
-</div>
-<div class="section" id="id8">
-<span id="id7"></span><h2><a class="toc-backref" href="#id63"><tt class="docutils literal"><span class="pre">\PolTypeset*{polname}</span></tt></a></h2>
-<blockquote>
-Typesets in ascending powers. Use e.g. <tt class="docutils literal">[h]</tt> optional argument
-(after the <tt class="docutils literal">*</tt>) to use letter <tt class="docutils literal">h</tt> rather than <tt class="docutils literal">x</tt>.</blockquote>
-</div>
-<div class="section" id="poldiff-polname-1-polname-2">
-<span id="poldiff"></span><h2><a class="toc-backref" href="#id64"><tt class="docutils literal"><span class="pre">\PolDiff{polname_1}{polname_2}</span></tt></a></h2>
-<blockquote>
-<p>This sets <tt class="docutils literal">polname_2</tt> to the first derivative of <tt class="docutils literal">polname_1</tt>. It
-is allowed to issue <tt class="docutils literal"><span class="pre">\PolDiff{f}{f}</span></tt>, effectively replacing <tt class="docutils literal">f</tt>
-by <tt class="docutils literal">f'</tt>.</p>
-<p>Coefficients of the result <tt class="docutils literal">polname_2</tt> are irreducible fractions
-(see <a class="reference internal" href="#technicalities">Technicalities</a> for the whole story.)</p>
-</blockquote>
-</div>
-<div class="section" id="poldiff-n-polname-1-polname-2">
-<span id="poldiff-n"></span><h2><a class="toc-backref" href="#id65"><tt class="docutils literal"><span class="pre">\PolDiff[N]{polname_1}{polname_2}</span></tt></a></h2>
-<blockquote>
-This sets <tt class="docutils literal">polname_2</tt> to the <tt class="docutils literal">N</tt>-th derivative of <tt class="docutils literal">polname_1</tt>.
-Identical arguments is allowed. With <tt class="docutils literal">N=0</tt>, same effect as
-<tt class="docutils literal"><span class="pre">\PolLet{polname_2}={polname_1}</span></tt>. With negative <tt class="docutils literal">N</tt>, switches to
-using <tt class="docutils literal">\PolAntiDiff</tt>.</blockquote>
-</div>
-<div class="section" id="polantidiff-polname-1-polname-2">
-<span id="polantidiff"></span><h2><a class="toc-backref" href="#id66"><tt class="docutils literal"><span class="pre">\PolAntiDiff{polname_1}{polname_2}</span></tt></a></h2>
-<blockquote>
-<p>This sets <tt class="docutils literal">polname_2</tt> to the primitive of <tt class="docutils literal">polname_1</tt> vanishing
-at zero.</p>
-<p>Coefficients of the result <tt class="docutils literal">polname_2</tt> are irreducible fractions
-(see <a class="reference internal" href="#technicalities">Technicalities</a> for the whole story.)</p>
-</blockquote>
-</div>
-<div class="section" id="polantidiff-n-polname-1-polname-2">
-<span id="polantidiff-n"></span><h2><a class="toc-backref" href="#id67"><tt class="docutils literal"><span class="pre">\PolAntiDiff[N]{polname_1}{polname_2}</span></tt></a></h2>
-<blockquote>
-This sets <tt class="docutils literal">polname_2</tt> to the result of <tt class="docutils literal">N</tt> successive integrations on
-<tt class="docutils literal">polname_1</tt>. With negative <tt class="docutils literal">N</tt>, it switches to using <tt class="docutils literal">\PolDiff</tt>.</blockquote>
-</div>
-<div class="section" id="poldivide-polname-1-polname-2-polname-q-polname-r">
-<span id="poldivide"></span><h2><a class="toc-backref" href="#id68"><tt class="docutils literal"><span class="pre">\PolDivide{polname_1}{polname_2}{polname_Q}{polname_R}</span></tt></a></h2>
-<blockquote>
-This sets <tt class="docutils literal">polname_Q</tt> and <tt class="docutils literal">polname_R</tt> to be the quotient and
-remainder in the Euclidean division of <tt class="docutils literal">polname_1</tt> by
-<tt class="docutils literal">polname_2</tt>.</blockquote>
-</div>
-<div class="section" id="polquo-polname-1-polname-2-polname-q">
-<span id="polquo"></span><h2><a class="toc-backref" href="#id69"><tt class="docutils literal"><span class="pre">\PolQuo{polname_1}{polname_2}{polname_Q}</span></tt></a></h2>
-<blockquote>
-This sets <tt class="docutils literal">polname_Q</tt> to be the quotient in the Euclidean division
-of <tt class="docutils literal">polname_1</tt> by <tt class="docutils literal">polname_2</tt>.</blockquote>
-</div>
-<div class="section" id="polrem-polname-1-polname-2-polname-r">
-<span id="polrem"></span><h2><a class="toc-backref" href="#id70"><tt class="docutils literal"><span class="pre">\PolRem{polname_1}{polname_2}{polname_R}</span></tt></a></h2>
-<blockquote>
-This sets <tt class="docutils literal">polname_R</tt> to be the remainder in the Euclidean division
-of <tt class="docutils literal">polname_1</tt> by <tt class="docutils literal">polname_2</tt>.</blockquote>
-</div>
-<div class="section" id="polgcd-polname-1-polname-2-polname-gcd">
-<span id="polgcd"></span><h2><a class="toc-backref" href="#id71"><tt class="docutils literal"><span class="pre">\PolGCD{polname_1}{polname_2}{polname_GCD}</span></tt></a></h2>
-<blockquote>
-This sets <tt class="docutils literal">polname_GCD</tt> to be the (monic) GCD of the two first
-polynomials. It is a unitary polynomial except if both <tt class="docutils literal">polname_1</tt>
-and <tt class="docutils literal">polname_2</tt> vanish, then <tt class="docutils literal">polname_GCD</tt> is the zero
-polynomial.</blockquote>
-<!-- ``\PolIGCD{polname_1}{polname_2}{polname_iGCD}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- **NOT YET**
-
- This **assumes** that the two polynomials have integer coefficients.
- It then computes the greatest common divisor in the integer
- polynomial ring, normalized to have a positive leading coefficient
- (if the inputs are not both zero).
-
-``\PolIContent{polname}``
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
- **NOT YET**
-
- This computes a positive rational number such that dividing the
- polynomial with it returns an integer coefficients polynomial with
- no common factor among the coefficients. -->
-</div>
-<div class="section" id="poltosturm-polname-sturmname">
-<span id="poltosturm"></span><h2><a class="toc-backref" href="#id72"><tt class="docutils literal"><span class="pre">\PolToSturm{polname}{sturmname}</span></tt></a></h2>
-<blockquote>
-<p>With <tt class="docutils literal">polname</tt> being for example <tt class="docutils literal">P</tt>, the macro starts by
-computing polynomials <tt class="docutils literal">P</tt> and <tt class="docutils literal">P'</tt>, then computes the (opposite
-of the) remainder in euclidean division, iteratively.</p>
-<p>The last non-zero remainder <tt class="docutils literal">P_N_</tt> (where <tt class="docutils literal">N</tt> is obtainable as
-<a class="reference internal" href="#polsturmchainlength-sturmname">\PolSturmChainLength{sturmname}</a>) is up to a factor
-the GCD of <tt class="docutils literal">P</tt> and <tt class="docutils literal">P'</tt> hence it is a constant if and only if
-<tt class="docutils literal">P</tt> is square-free.</p>
-<div class="admonition note">
-<p class="first admonition-title">Note</p>
-<ul class="last simple">
-<li>Since <tt class="docutils literal">0.5</tt> all these polynomials are divided by their rational
-content, so they have integer coefficients with no common factor,
-and the last one if a constant is either <tt class="docutils literal">1</tt> or <tt class="docutils literal"><span class="pre">-1</span></tt>.</li>
-<li>After this normalization to primitive polynomials, they are
-stored internally as <tt class="docutils literal">sturmname_k_</tt>, <tt class="docutils literal">k=0,1, ...</tt>.</li>
-<li>These polynomials are used internally only. To keep them as
-genuine declared polynomials also after the macro call, use the
-starred variant <a class="reference internal" href="#id9">PolToSturm*</a>.</li>
-</ul>
-</div>
-<div class="admonition note">
-<p class="first admonition-title">Note</p>
-<p class="last">It is perfectly allowed to use the polynomial name as Sturm chain name:
-<tt class="docutils literal"><span class="pre">\PolToSturm{f}(f}</span></tt>.</p>
-</div>
-<p>The macro then declares <tt class="docutils literal">sturmname_0</tt>, <tt class="docutils literal">sturmname_1</tt>, ..., which are
-the (non-declared) <tt class="docutils literal">sturmname_k_</tt> divided by the last one. Division is
-not done if this last one is the constant <tt class="docutils literal">1</tt> or <tt class="docutils literal"><span class="pre">-1</span></tt>, i.e. if the
-original polynomial was square-free. These polynomials are primitive
-polynomials too, i.e. with integer coefficients having no common factor.</p>
-<p>Thus <tt class="docutils literal">sturmname_0</tt> has exactly the same real and complex roots as
-polynomial <tt class="docutils literal">polname</tt>, but with each root now of multiplicity one:
-i.e. it is the &quot;square-free part&quot; of original polynomial <tt class="docutils literal">polname</tt>.</p>
-<p>Notice that <tt class="docutils literal">sturmname_1</tt> isn't necessarily the derivative of
-<tt class="docutils literal">sturmname_0</tt> due to the various normalizations.</p>
-<p>The polynomials <tt class="docutils literal">sturmname_k</tt> main utility is for the execution of
-<a class="reference internal" href="#polsturmisolatezeros-sturmname">\PolSturmIsolateZeros{sturmname}</a>. Be careful not to use these
-names <tt class="docutils literal">sturmname_0</tt>, <tt class="docutils literal">sturmname_1</tt>, etc... for defining other
-polynomials after having done <tt class="docutils literal"><span class="pre">\PolToSturm{polname}{sturmname}</span></tt> and
-before executing <tt class="docutils literal">\PolSturmIsolateZeros{sturmname}</tt> else the
-latter will behave erroneously.</p>
-<p><a class="reference internal" href="#polsturmchainlength-sturmname">\PolSturmChainLength{sturmname}</a> gives the index of the last
-element of the Sturm chain.</p>
-</blockquote>
-</div>
-<div class="section" id="id10">
-<span id="id9"></span><h2><a class="toc-backref" href="#id73"><tt class="docutils literal"><span class="pre">\PolToSturm*{polname}{sturmname}</span></tt></a></h2>
-<blockquote>
-<p>Does the same as <a class="reference internal" href="#poltosturm">un-starred version</a> and additionally it
-keeps for user usage the memory of the <em>un-normalized</em> Sturm chain
-polynomials <tt class="docutils literal">sturmname_k_</tt>, <tt class="docutils literal">k=0,1, <span class="pre">...,</span> N</tt>, with
-<tt class="docutils literal">N</tt> being <a class="reference internal" href="#polsturmchainlength-sturmname">\PolSturmChainLength{sturmname}</a>.</p>
-<div class="admonition note">
-<p class="first admonition-title">Note</p>
-<p class="last">This behaviour was modified at <tt class="docutils literal">0.6</tt>, anyhow the macro was
-broken at <tt class="docutils literal">0.5</tt>.</p>
-</div>
-<div class="admonition hint">
-<p class="first admonition-title">Hint</p>
-<p class="last">The square-free part of <tt class="docutils literal">polname</tt> is <tt class="docutils literal">sturmname_0</tt>, and their
-quotient is the polynomial with name
-<tt class="docutils literal">sturname_\PolSturmChainLength{sturmname}_</tt>. It thus easy to
-set-up a loop iteratively computing the latter until the last one
-is a constant, thus obtaining the decomposition of an <tt class="docutils literal">f</tt> as
-a product <tt class="docutils literal">c f_1 f_2 f_3 ...</tt> of a constant and square-free (primitive)
-polynomials, where each <tt class="docutils literal">f_i</tt> divides its predecessor.</p>
-</div>
-</blockquote>
-</div>
-<div class="section" id="polsettosturmchainsignchangesat-macro-sturmname-fraction">
-<span id="polsettosturmchainsignchangesat"></span><h2><a class="toc-backref" href="#id74"><tt class="docutils literal"><span class="pre">\PolSetToSturmChainSignChangesAt{\macro}{sturmname}{fraction}</span></tt></a></h2>
-<blockquote>
-<p>Sets macro <tt class="docutils literal">\macro</tt> to the number of sign changes in the Sturm
-chain with name prefix <tt class="docutils literal">sturmname</tt>, at location <tt class="docutils literal">fraction</tt>
-(which must be in format as acceptable by the <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> macros.)</p>
-<div class="admonition note">
-<p class="first admonition-title">Note</p>
-<p>The author was lazy and did not provide rather an expandable
-variant, where one would do <tt class="docutils literal"><span class="pre">\edef\macro{\PolNbOf...}</span></tt>.</p>
-<p>This will presumably get added in a future release.</p>
-<p class="last">After some hesitation it was decided the macro would by default
-act globally. To make the scope of its macro definition local,
-use <tt class="docutils literal">[\empty]</tt> as extra optional argument.</p>
-</div>
-</blockquote>
-</div>
-<div class="section" id="polsettonbofzeroswithin-macro-sturmname-value-a-value-b">
-<span id="polsettonbofzeroswithin"></span><h2><a class="toc-backref" href="#id75"><tt class="docutils literal"><span class="pre">\PolSetToNbOfZerosWithin{\macro}{sturmname}{value_a}{value_b}</span></tt></a></h2>
-<blockquote>
-<p>Applies the <a class="reference external" href="https://en.wikipedia.org/wiki/Sturm%27s_theorem">Sturm Theorem</a> to set <tt class="docutils literal">\macro</tt> to the exact number
-of <strong>distinct</strong> roots of <tt class="docutils literal">sturmname_0</tt> in the interval <tt class="docutils literal">(value_a,
-value_b]</tt> (the macro first re-orders the value for <tt class="docutils literal">value_a &lt;=
-value_b</tt> to hold).</p>
-<div class="admonition note">
-<p class="first admonition-title">Note</p>
-<p>The author was lazy and did not provide rather an expandable
-variant, where one would do <tt class="docutils literal"><span class="pre">\edef\macro{\PolNbOf...}</span></tt>.</p>
-<p>This will presumably get added in future.</p>
-<p class="last">After some hesitation it was decided the macro would by default
-act globally. To make the scope of its macro definition local,
-use <tt class="docutils literal">[\empty]</tt> as extra optional argument.</p>
-</div>
-<p>See also the expandable
-<a class="reference internal" href="#polsturmnbofrootsof-sturmname-lessthanorequalto-value">\PolSturmNbOfRootsOf{sturmname}\LessThanOrEqualTo{value}</a>, from
-which it is immediate (with <tt class="docutils literal">\numexpr</tt>) to create an expandable
-variant of this macro. However the difference is that this macro
-requires only <a class="reference internal" href="#poltosturm">\PolToSturm</a> to have been executed,
-whereas the expandable variant requires prior execution of
-<a class="reference internal" href="#polsturmisolatezeros">\PolSturmIsolateZeros</a>.</p>
-<p>See also the expandable
-<a class="reference internal" href="#polsturmnbwithmultofrootsof-sturmname-lessthanorequalto-value">\PolSturmNbWithMultOfRootsOf{sturmname}\LessThanOrEqualTo{value}</a>
-which requires prior execution of
-<a class="reference internal" href="#id11">\PolSturmIsolateZeros*</a>.</p>
-</blockquote>
-</div>
-<div class="section" id="polsturmisolatezeros-sturmname">
-<span id="polsturmisolatezeros"></span><h2><a class="toc-backref" href="#id76"><tt class="docutils literal">\PolSturmIsolateZeros{sturmname}</tt></a></h2>
-<blockquote>
-<p>The macros locates, using <a class="reference external" href="https://en.wikipedia.org/wiki/Sturm%27s_theorem">Sturm theorem</a>, as many disjoint
-intervals as there are (real) roots.</p>
-<div class="admonition important">
-<p class="first admonition-title">Important</p>
-<p>The Sturm chain must have been produced by an earlier
-<a class="reference internal" href="#poltosturm-polname-sturmname">\PolToSturm{polname}{sturmname}</a>.</p>
-<p>Why does this macro ask for argument the name of Sturm chain,
-rather than the name of a polynomial? well this is mainly for
-legacy reason, and because it is accompanied by other macros for
-which it is simpler to assume the argument will be the name of an
-already computed Sturm chain.</p>
-<p>Notice that <tt class="docutils literal"><span class="pre">\PolToSturm{f}{f}</span></tt> is perfectly legal (the
-<tt class="docutils literal">sturmname</tt> can be same as the <tt class="docutils literal">polname</tt>): it defines
-polynomials <tt class="docutils literal">f_0</tt>, <tt class="docutils literal">f_1</tt>, ... having <tt class="docutils literal">f</tt> has name prefix.</p>
-<p class="last">Such a prior call
-to <tt class="docutils literal">\PolToSturm</tt> must have been made at any rate for
-<tt class="docutils literal">\PolSturmIsolateZeros</tt> to be usable.</p>
-</div>
-<p>After its execution they are two types of such intervals (stored in
-memory and accessible via macros or <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> variables, see below):</p>
-<ul class="simple">
-<li>singleton <tt class="docutils literal">{a}</tt>: then <tt class="docutils literal">a</tt> is a root, (necessarily a decimal
-number, but not all such decimal numbers are exactly identified yet).</li>
-<li>open intervals <tt class="docutils literal">(a,b)</tt>: then there is exactly one root <tt class="docutils literal">z</tt>
-such that <tt class="docutils literal">a &lt; z &lt; b</tt>, and the end points are guaranteed to not
-be roots.</li>
-</ul>
-<p>The interval boundaries are decimal numbers, originating
-in iterated decimal subdivision from initial intervals
-<tt class="docutils literal"><span class="pre">(-10^E,</span> 0)</tt> and <tt class="docutils literal">(0, 10^E)</tt> with <tt class="docutils literal">E</tt> chosen initially large
-enough so that all roots are enclosed; if zero is a root it is always
-identified as such. The non-singleton intervals are of the
-type <tt class="docutils literal">(a/10^f, <span class="pre">(a+1)/10^f)</span></tt> with <tt class="docutils literal">a</tt> an integer, which is
-neither <tt class="docutils literal">0</tt> nor <tt class="docutils literal"><span class="pre">-1</span></tt>. Hence either <tt class="docutils literal">a</tt> and <tt class="docutils literal">a+1</tt> are both positive
-or they are both negative.</p>
-<p>One does not <em>a priori</em> know what will be the lengths of these
-intervals (except that they are always powers of ten), they
-vary depending on how many digits two successive roots have in
-common in their respective decimal expansions.</p>
-<div class="admonition important">
-<p class="first admonition-title">Important</p>
-<p>If some two consecutive intervals share an end-point, no
-information is yet gained about the separation between the two
-roots which could at this stage be arbitrarily small.</p>
-<p class="last">See <a class="reference internal" href="#polrefineinterval-sturmname-index">\PolRefineInterval*{sturmname}{index}</a> which addresses
-this issue.</p>
-</div>
-<!-- This procedure is covariant
-with the independent variable ``x`` becoming ``-x``.
-Hmm, pas sûr et trop fatigué -->
-<p>The interval boundaries (and exactly found roots) are made available
-for future computations in <tt class="docutils literal">\xintexpr</tt>-essions or polynomial
-definitions as variables <tt class="docutils literal">&lt;sturmname&gt;L_1</tt>,
-<tt class="docutils literal">&lt;sturmname&gt;L_2</tt>, etc..., for the left end-points and
-<tt class="docutils literal">&lt;sturmname&gt;R_1</tt>, <tt class="docutils literal">&lt;sturmname&gt;R_2</tt>, ..., for the right
-end-points.</p>
-<p>Thus for example, if <tt class="docutils literal">sturmname</tt> is <tt class="docutils literal">f</tt>, one can use the
-<a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> variables <tt class="docutils literal">fL_1</tt>, <tt class="docutils literal">fL_2</tt>, ... to refer in expressions
-to the left end-points (or to the exact root, if left and right end
-points coincide). Additionally, <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> variable <tt class="docutils literal">fZ_1_isknown</tt>
-will have value <tt class="docutils literal">1</tt> if the root in the first interval is known,
-and <tt class="docutils literal">0</tt> otherwise. And similarly for the other intervals.</p>
-<p>Also, macros <a class="reference internal" href="#polsturmisolatedzeroleft-sturmname-index">\PolSturmIsolatedZeroLeft{sturmname}{index}</a> and
-<a class="reference internal" href="#polsturmisolatedzeroright-sturmname-index">\PolSturmIsolatedZeroRight{sturmname}{index}</a> are provided which
-expand to these same values, written in decimal notation (i.e.
-pre-processed by <a class="reference internal" href="#poldectostring">\PolDecToString</a>.) And there
-is also <a class="reference internal" href="#polsturmifzeroexactlyknown-sturmname-index-a-b">\PolSturmIfZeroExactlyKnown{sturmname}{index}{A}{B}</a>.</p>
-<div class="admonition important">
-<p class="first admonition-title">Important</p>
-<p class="last">Trailing zeroes in the stored decimal numbers accessible via the
-macros are significant: they are also present in the decimal
-expansion of the exact root.</p>
-</div>
-<p>These variables and macros are automatically updated when one next
-uses macros such as <a class="reference internal" href="#polrefineinterval-sturmname-index">\PolRefineInterval*{sturmname}{index}</a>.</p>
-<p>The start of decimal expansion of a positive <tt class="docutils literal">k</tt>-th root is given
-by <a class="reference internal" href="#polsturmisolatedzeroleft">\PolSturmIsolatedZeroLeft{sturmname}{k}</a>, and for a negative root it is given
-by <a class="reference internal" href="#polsturmisolatedzeroright">PolSturmIsolatedZeroRight{sturmname}{k}</a>. These two decimal
-numbers are either both zero or both of the same sign.</p>
-<p>The number of distinct roots is obtainable expandably as
-<a class="reference internal" href="#polsturmnbofisolatedzeros-sturmname">\PolSturmNbOfIsolatedZeros{sturmname}</a>.</p>
-<p>Furthermore
-<a class="reference internal" href="#polsturmnbofrootsof-sturmname-lessthanorequalto-value">\PolSturmNbOfRootsOf{sturmname}\LessThanOrEqualTo{value}</a> and
-<a class="reference internal" href="#polsturmnbofrootsof-sturmname-lessthanorequaltoexpr-expression">\PolSturmNbOfRootsOf{sturmname}\LessThanOrEqualToExpr{expression}</a>.
-will expandably compute respectively the number of real roots at
-most equal to <tt class="docutils literal">value</tt> or <tt class="docutils literal">expression</tt>, and the same but with
-multiplicities.</p>
-<div class="admonition note">
-<p class="first admonition-title">Note</p>
-<p class="last">In the current implementation the <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> variables
-and <a class="reference external" href="http://www.ctan.org/pkg/xint">xinttools</a> arrays are globally defined. On the
-other hand the Sturm sequence polynomials obey the current scope.</p>
-</div>
-<div class="admonition note">
-<p class="first admonition-title">Note</p>
-<p>As all computations are done <em>exactly</em> there can be no errors...
-apart those due to bad coding by author. The results are exact
-bounds for the mathematically exact real roots.</p>
-<p class="last">Future releases will perhaps also provide macros based on Newton
-or Regula Falsi methods. Exact computations with such methods
-lead however quickly to very big fractions, and this forces usage
-of some rounding scheme for the abscissas if computation times
-are to remain reasonable. This raises issues of its own, which
-are studied in numerical mathematics.</p>
-</div>
-</blockquote>
-</div>
-<div class="section" id="id12">
-<span id="id11"></span><h2><a class="toc-backref" href="#id77"><tt class="docutils literal"><span class="pre">\PolSturmIsolateZeros*{sturmname}</span></tt></a></h2>
-<blockquote>
-<p>The macro does the same as <a class="reference internal" href="#polsturmisolatezeros-sturmname">\PolSturmIsolateZeros{sturmname}</a> and
-then in addition it does the extra work to determine all
-multiplicities (of the real roots):
-after executing this macro,
-<a class="reference internal" href="#polsturmisolatedzeromultiplicity-sturmname-index">\PolSturmIsolatedZeroMultiplicity{sturmname}{index}</a> will expand
-to the multiplicity of the root located in the <tt class="docutils literal">index</tt>-th
-interval (intervals are enumerated from left to right, with index
-starting at <tt class="docutils literal">1</tt>).</p>
-<p>Furthermore, if for example the <tt class="docutils literal">sturmname</tt> is <tt class="docutils literal">f</tt>, <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a>
-variables <tt class="docutils literal">fM_1</tt>, <tt class="docutils literal">fM_2</tt>... hold the multiplicities thus
-computed.</p>
-<div class="admonition note">
-<p class="first admonition-title">Note</p>
-<p class="last">It is <strong>not</strong> necessary to have executed the <a class="reference internal" href="#id9">PolToSturm*</a> starred
-variant, as the non-starred variant keeps internally the memory of the
-original GCD (and even of the full non-normalized original Sturm
-chain), even though it does not make the declarations as <em>user-level</em>
-genuine polynomials.</p>
-</div>
-<p>See <a class="reference internal" href="#the-degree-nine-polynomial-with-0-99-0-999-0-9999-as-triple-roots">The degree nine polynomial with 0.99, 0.999, 0.9999 as triple
-roots</a> for an example.</p>
-</blockquote>
-</div>
-<div class="section" id="id14">
-<span id="id13"></span><h2><a class="toc-backref" href="#id78"><tt class="docutils literal"><span class="pre">\PolSturmIsolateZeros**{sturmname}</span></tt></a></h2>
-<blockquote>
-<p>The macro does the same as <a class="reference internal" href="#id12">\PolSturmIsolateZeros*{sturmname}</a> and
-in addition it does the extra work to determine all the <em>rational</em>
-roots.</p>
-<div class="admonition note">
-<p class="first admonition-title">Note</p>
-<p class="last">After execution of this macro, a root is &quot;known&quot; if and only if
-it is rational.</p>
-</div>
-<p>Furthermore, primitive polynomial <tt class="docutils literal">sturmname_sqf_norr</tt> is created
-to match the (square-free) <tt class="docutils literal">sturmname_0</tt> from which all rational
-roots have been removed (see <a class="reference internal" href="#polexprsetup">\polexprsetup</a> for customizing this
-name). The number of distinct rational roots is thus the difference
-between the degrees of these two polynomials (see also
-<a class="reference internal" href="#polsturmnbofrationalroots-sturmname">\PolSturmNbOfRationalRoots{sturmname}</a>).</p>
-<p>And <tt class="docutils literal">sturmname_norr</tt> is <tt class="docutils literal">sturmname_0_</tt> from which all rational
-roots have been removed (see <a class="reference internal" href="#polexprsetup">\polexprsetup</a>), i.e. it contains
-the irrational roots of the original polynomial, with the same
-multiplicities.</p>
-<p>See <a class="reference internal" href="#a-degree-five-polynomial-with-three-rational-roots">A degree five polynomial with three rational
-roots</a> for an example.</p>
-</blockquote>
-</div>
-<div class="section" id="polsturmisolatezerosandgetmultiplicities-sturmname">
-<span id="polsturmisolatezerosandgetmultiplicities"></span><h2><a class="toc-backref" href="#id79"><tt class="docutils literal">\PolSturmIsolateZerosAndGetMultiplicities{sturmname}</tt></a></h2>
-<blockquote>
-This is another name for <a class="reference internal" href="#id12">\PolSturmIsolateZeros*{sturmname}</a>.</blockquote>
-</div>
-<div class="section" id="polsturmisolatezerosgetmultiplicitiesandrationalroots-sturmname">
-<span id="polsturmisolatezerosgetmultiplicitiesandrationalroots"></span><h2><a class="toc-backref" href="#id80"><tt class="docutils literal">\PolSturmIsolateZerosGetMultiplicitiesAndRationalRoots{sturmname}</tt></a></h2>
-<blockquote>
-This is another name for <a class="reference internal" href="#id14">\PolSturmIsolateZeros**{sturmname}</a>.</blockquote>
-</div>
-<div class="section" id="polsturmisolatezerosandfindrationalroots-sturmname">
-<h2><a class="toc-backref" href="#id81"><tt class="docutils literal">\PolSturmIsolateZerosAndFindRationalRoots{sturmname}</tt></a></h2>
-<blockquote>
-<p>This works exactly like <a class="reference internal" href="#id14">\PolSturmIsolateZeros**{sturmname}</a>
-(inclusive of declaring the polynomials <tt class="docutils literal">sturmname_sqf_norr</tt> and
-<tt class="docutils literal">sturmname_norr</tt> with no rational roots) except that it does <em>not</em>
-compute the multiplicities of the <em>non-rational</em> roots.</p>
-<div class="admonition note">
-<p class="first admonition-title">Note</p>
-<p class="last">There is no macro to find the rational roots but not compute
-their multiplicities at the same time.</p>
-</div>
-<div class="admonition attention">
-<p class="first admonition-title">Attention!</p>
-<p>This macro does <em>not</em> define <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> variables
-<tt class="docutils literal">sturmnameM_1</tt>, <tt class="docutils literal">sturmnameM_2</tt>, ... holding the
-multiplicities and it leaves the multiplicity array (whose accessor
-is <a class="reference internal" href="#polsturmisolatedzeromultiplicity-sturmname-index">\PolSturmIsolatedZeroMultiplicity{sturmname}{index}</a>) into
-a broken state, as all non-rational roots will supposedly have
-multiplicity one. This means that the output of
-<a class="reference internal" href="#id18">\PolPrintIntervals*</a> for example will be
-erroneous for the intervals with irrational roots.</p>
-<p class="last">I decided to document it because finding multiplicities of the
-non rational roots is somewhat costly, and one may be interested
-only into finding the rational roots (of course random
-polynomials with integer coefficients will not have <em>any</em>
-rational root anyhow).</p>
-</div>
-</blockquote>
-</div>
-<div class="section" id="polrefineinterval-sturmname-index">
-<span id="polrefineinterval"></span><h2><a class="toc-backref" href="#id82"><tt class="docutils literal"><span class="pre">\PolRefineInterval*{sturmname}{index}</span></tt></a></h2>
-<blockquote>
-The <tt class="docutils literal">index</tt>-th interval (starting indexing at one) is further
-subdivided as many times as is necessary in order for the newer
-interval to have both its end-points distinct from the end-points of
-the original interval. This means that the <tt class="docutils literal">k</tt>th root is then
-strictly separated from the other roots.</blockquote>
-</div>
-<div class="section" id="polrefineinterval-n-sturmname-index">
-<span id="polrefineinterval-n"></span><h2><a class="toc-backref" href="#id83"><tt class="docutils literal"><span class="pre">\PolRefineInterval[N]{sturmname}{index}</span></tt></a></h2>
-<blockquote>
-The <tt class="docutils literal">index</tt>-th interval (starting count at one) is further
-subdivided once, reducing its length by a factor of 10. This is done
-<tt class="docutils literal">N</tt> times if the optional argument <tt class="docutils literal">[N]</tt> is present.</blockquote>
-</div>
-<div class="section" id="polensureintervallength-sturmname-index-e">
-<span id="polensureintervallength"></span><h2><a class="toc-backref" href="#id84"><tt class="docutils literal"><span class="pre">\PolEnsureIntervalLength{sturmname}{index}{E}</span></tt></a></h2>
-<blockquote>
-The <tt class="docutils literal">index</tt>-th interval is subdivided until its length becomes at
-most <tt class="docutils literal">10^E</tt>. This means (for <tt class="docutils literal">E&lt;0</tt>) that the first <tt class="docutils literal"><span class="pre">-E</span></tt> digits
-after decimal mark of the <tt class="docutils literal">k</tt>th root will then be known exactly.</blockquote>
-</div>
-<div class="section" id="polensureintervallengths-sturmname-e">
-<span id="polensureintervallengths"></span><h2><a class="toc-backref" href="#id85"><tt class="docutils literal"><span class="pre">\PolEnsureIntervalLengths{sturmname}{E}</span></tt></a></h2>
-<blockquote>
-<p>The intervals as obtained from <tt class="docutils literal">\PolSturmIsolateZeros</tt> are (if
-necessary) subdivided further by (base 10) dichotomy in order for
-each of them to have length at most <tt class="docutils literal">10^E</tt> (length will be shorter
-than <tt class="docutils literal">10^E</tt> in output only if it did not change or became zero.)</p>
-<p>This means that decimal expansions of all roots will be known with
-<tt class="docutils literal"><span class="pre">-E</span></tt> digits (for <tt class="docutils literal">E&lt;0</tt>) after decimal mark.</p>
-</blockquote>
-</div>
-<div class="section" id="polprintintervals-varname-sturmname">
-<span id="polprintintervals"></span><h2><a class="toc-backref" href="#id86"><tt class="docutils literal"><span class="pre">\PolPrintIntervals[varname]{sturmname}</span></tt></a></h2>
-<blockquote>
-<p>This is a convenience macro which prints the bounds for the roots
-<tt class="docutils literal">Z_1</tt>, <tt class="docutils literal">Z_2</tt>, ... (the optional argument <tt class="docutils literal">varname</tt> allows to
-specify a replacement for the default <tt class="docutils literal">Z</tt>). This will be done (by
-default) in a
-math mode <tt class="docutils literal">array</tt>, one interval per row, and pattern <tt class="docutils literal">rcccl</tt>,
-where the second and fourth column hold the <tt class="docutils literal">&lt;</tt> sign, except when
-the interval reduces to a singleton, which means the root is known
-exactly.</p>
-<div class="admonition attention">
-<p class="first admonition-title">Attention!</p>
-<p class="last">This macro was refactored at 0.7, its default output remained
-identical but the ways to customize it got completely
-modified.</p>
-</div>
-<p>See next macros which govern its output.</p>
-</blockquote>
-<div class="section" id="polprintintervalsnorealroots">
-<h3><a class="toc-backref" href="#id87"><tt class="docutils literal">\PolPrintIntervalsNoRealRoots</tt></a></h3>
-<blockquote>
-<p>Executed in place of an <tt class="docutils literal">array</tt> environment, when there are no
-real roots. Default definition:</p>
-<pre class="literal-block">
-\newcommand\PolPrintIntervalsNoRealRoots{}
-</pre>
-</blockquote>
-</div>
-<div class="section" id="polprintintervalsbeginenv">
-<h3><a class="toc-backref" href="#id88"><tt class="docutils literal">\PolPrintIntervalsBeginEnv</tt></a></h3>
-<blockquote>
-<p>Default definition:</p>
-<pre class="literal-block">
-\newcommand\PolPrintIntervalsBeginEnv{\[\begin{array}{rcccl}}
-</pre>
-</blockquote>
-</div>
-<div class="section" id="polprintintervalsendenv">
-<h3><a class="toc-backref" href="#id89"><tt class="docutils literal">\PolPrintIntervalsEndEnv</tt></a></h3>
-<blockquote>
-<p>Default definition:</p>
-<pre class="literal-block">
-\newcommand\PolPrintIntervalsEndEnv{\end{array}\]}
-</pre>
-</blockquote>
-</div>
-<div class="section" id="polprintintervalsknownroot">
-<h3><a class="toc-backref" href="#id90"><tt class="docutils literal">\PolPrintIntervalsKnownRoot</tt></a></h3>
-<blockquote>
-<p>Default definition:</p>
-<pre class="literal-block">
-\newcommand\PolPrintIntervalsKnownRoot{%
- &amp;&amp;\PolPrintIntervalsTheVar_{\PolPrintIntervalsTheIndex}%
- &amp;=&amp;\PolPrintIntervalsPrintExactZero
-}
-</pre>
-</blockquote>
-</div>
-<div class="section" id="polprintintervalsunknownroot">
-<h3><a class="toc-backref" href="#id91"><tt class="docutils literal">\PolPrintIntervalsUnknownRoot</tt></a></h3>
-<blockquote>
-<p>Default definition:</p>
-<pre class="literal-block">
-\newcommand\PolPrintIntervalsUnknownRoot{%
- \PolPrintIntervalsPrintLeftEndPoint&amp;&lt;&amp;%
- \PolPrintIntervalsTheVar_{\PolPrintIntervalsTheIndex}&amp;&lt;&amp;%
- \PolPrintIntervalsPrintRightEndPoint
-}
-</pre>
-</blockquote>
-</div>
-<div class="section" id="id15">
-<span id="polprintintervalsprintexactzero"></span><h3><a class="toc-backref" href="#id92"><tt class="docutils literal">\PolPrintIntervalsPrintExactZero</tt></a></h3>
-<blockquote>
-<p>Default definition:</p>
-<pre class="literal-block">
-\newcommand\PolPrintIntervalsPrintExactZero{\PolPrintIntervalsTheLeftEndPoint}
-</pre>
-</blockquote>
-</div>
-<div class="section" id="id16">
-<span id="polprintintervalsprintleftendpoint"></span><h3><a class="toc-backref" href="#id93"><tt class="docutils literal">\PolPrintIntervalsPrintLeftEndPoint</tt></a></h3>
-<blockquote>
-<p>Default definition:</p>
-<pre class="literal-block">
-\newcommand\PolPrintIntervalsPrintLeftEndPoint{\PolPrintIntervalsTheLeftEndPoint}
-</pre>
-</blockquote>
-</div>
-<div class="section" id="id17">
-<span id="polprintintervalsprintrightendpoint"></span><h3><a class="toc-backref" href="#id94"><tt class="docutils literal">\PolPrintIntervalsPrintRightEndPoint</tt></a></h3>
-<blockquote>
-<p>Default definition is:</p>
-<pre class="literal-block">
-\newcommand\PolPrintIntervalsPrintRightEndPoint{\PolPrintIntervalsTheRightEndPoint}
-</pre>
-</blockquote>
-</div>
-</div>
-<div class="section" id="id19">
-<span id="id18"></span><h2><a class="toc-backref" href="#id95"><tt class="docutils literal"><span class="pre">\PolPrintIntervals*[varname]{sturmname}</span></tt></a></h2>
-<blockquote>
-<p>This starred variant produces an alternative output (which
-displays the root multiplicity), and is provided as an
-example of customization.</p>
-<p>As replacement for <a class="reference internal" href="#polprintintervalsknownroot">\PolPrintIntervalsKnownRoot</a>,
-<a class="reference internal" href="#polprintintervalsprintexactzero">\PolPrintIntervalsPrintExactZero</a>,
-<a class="reference internal" href="#polprintintervalsunknownroot">\PolPrintIntervalsUnknownRoot</a> it uses its own
-<tt class="docutils literal"><span class="pre">\POL&#64;&#64;PrintIntervals...</span></tt> macros. We only reproduce here one
-definition:</p>
-<pre class="literal-block">
-\newcommand\POL&#64;&#64;PrintIntervalsPrintExactZero{%
- \displaystyle
- \xintSignedFrac{\PolPrintIntervalsTheLeftEndPoint}%
-}%
-</pre>
-<p>Multiplicities are printed using this auxiliary macro:</p>
-</blockquote>
-<div class="section" id="polprintintervalsprintmultiplicity">
-<h3><a class="toc-backref" href="#id96"><tt class="docutils literal">\PolPrintIntervalsPrintMultiplicity</tt></a></h3>
-<blockquote>
-<p>whose default definition is:</p>
-<pre class="literal-block">
-\newcommand\PolPrintIntervalsPrintMultiplicity{(\mbox{mult. }\PolPrintIntervalsTheMultiplicity)}
-</pre>
-</blockquote>
-</div>
-</div>
-<div class="section" id="polmapcoeffs-macro-polname">
-<span id="polmapcoeffs"></span><h2><a class="toc-backref" href="#id97"><tt class="docutils literal"><span class="pre">\PolMapCoeffs{\macro}{polname}</span></tt></a></h2>
-<blockquote>
-<p>It modifies ('in-place': original coefficients get lost) each
-coefficient of the defined polynomial via the <em>expandable</em> macro
-<tt class="docutils literal">\macro</tt>. The degree is adjusted as necessary if some leading
-coefficients vanish after the operation. In replacement text of
-<tt class="docutils literal">\macro</tt>, <tt class="docutils literal">\index</tt> expands to the coefficient index (which is
-defined to be zero for the constant term).</p>
-<p>Notice that <tt class="docutils literal">\macro</tt> will have to handle inputs of the shape
-<tt class="docutils literal">A/B[N]</tt> (<a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> internal notation). This means that it probably
-will have to be expressed in terms of macros from <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> package.</p>
-<p>Example:</p>
-<pre class="literal-block">
-\def\foo#1{\xintMul{#1}{\the\numexpr\index*\index\relax}}
-</pre>
-<p>(or with <tt class="docutils literal"><span class="pre">\xintSqr{\index}</span></tt>) to replace <tt class="docutils literal">n</tt>-th coefficient
-<tt class="docutils literal">f_n</tt> by <tt class="docutils literal">f_n*n^2</tt>.</p>
-</blockquote>
-</div>
-<div class="section" id="polreducecoeffs-polname">
-<span id="polreducecoeffs"></span><h2><a class="toc-backref" href="#id98"><tt class="docutils literal">\PolReduceCoeffs{polname}</tt></a></h2>
-<blockquote>
-About the same as <tt class="docutils literal"><span class="pre">\PolMapCoeffs{\xintIrr}{polname}</span></tt> (but
-maintaining a <tt class="docutils literal">[0]</tt> postfix for speedier <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> parsing when
-polynomial function is used for computations.) This is a
-one-argument macro, working 'in-place'.</blockquote>
-</div>
-<div class="section" id="id21">
-<span id="id20"></span><h2><a class="toc-backref" href="#id99"><tt class="docutils literal"><span class="pre">\PolReduceCoeffs*{polname}</span></tt></a></h2>
-<blockquote>
-<p>This starred variant leaves un-touched the decimal exponent in the
-internal representation of the fractional coefficients, i.e. if a
-coefficient is internally <tt class="docutils literal">A/B[N]</tt>, then <tt class="docutils literal">A/B</tt> is reduced to
-smallest terms, but the <tt class="docutils literal">10^N</tt> part is kept as is. Note: if the
-polynomial is freshly defined directly via <a class="reference internal" href="#polfromcsv">\PolFromCSV</a> its coefficients might still be internally in some
-format like <tt class="docutils literal">1.5e7</tt>; the macro will anyhow always first do the
-needed conversion to strict format <tt class="docutils literal">A/B[N]</tt>.</p>
-<p>Evaluations with polynomials treated by this can be much faster than
-with those handled by the non-starred variant
-<a class="reference internal" href="#polreducecoeffs-polname">\PolReduceCoeffs{polname}</a>: as the numerators and denominators
-remain smaller, this proves very beneficial in favorable cases
-(especially when the coefficients are decimal numbers) to the
-expansion speed of the <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> macros used internally by
-<a class="reference internal" href="#polevalat">\PolEval</a>.</p>
-</blockquote>
-</div>
-<div class="section" id="polmakemonic-polname">
-<span id="polmakemonic"></span><h2><a class="toc-backref" href="#id100"><tt class="docutils literal">\PolMakeMonic{polname}</tt></a></h2>
-<blockquote>
-Divides by the leading coefficient. It is recommended to execute
-<a class="reference internal" href="#id21">\PolReduceCoeffs*{polname}</a> immediately afterwards. This is not
-done automatically, due to the case the original polynomial had integer
-coefficients and we want to keep the leading one as common
-denominator.</blockquote>
-</div>
-<div class="section" id="polmakeprimitive-polname">
-<span id="polmakeprimitive"></span><h2><a class="toc-backref" href="#id101"><tt class="docutils literal">\PolMakePrimitive{polname}</tt></a></h2>
-<blockquote>
-Divides by the integer content see (<a class="reference internal" href="#policontent">\PolIContent</a>). This thus produces a polynomial with integer
-coefficients having no common factor. The sign of the leading
-coefficient is not modified.</blockquote>
-</div>
-</div>
-<div class="section" id="expandable-macros">
-<h1><a class="toc-backref" href="#id102">Expandable macros</a></h1>
-<p>All these macros expand completely in two steps except <tt class="docutils literal">\PolToExpr</tt>
-and <tt class="docutils literal">\PolToFloatExpr</tt> (and their auxiliaries) which need a
-<tt class="docutils literal">\write</tt>, <tt class="docutils literal">\edef</tt> or a <tt class="docutils literal"><span class="pre">\csname...\endcsname</span></tt> context.</p>
-<div class="section" id="poleval-polname-atexpr-numerical-expression">
-<span id="polevalatexpr"></span><h2><a class="toc-backref" href="#id103"><tt class="docutils literal"><span class="pre">\PolEval{polname}\AtExpr{numerical</span> expression}</tt></a></h2>
-<blockquote>
-It boils down to
-<tt class="docutils literal">\xinttheexpr polname(numerical <span class="pre">expression)\relax</span></tt>.</blockquote>
-</div>
-<div class="section" id="poleval-polname-at-fraction">
-<span id="polevalat"></span><h2><a class="toc-backref" href="#id104"><tt class="docutils literal"><span class="pre">\PolEval{polname}\At{fraction}</span></tt></a></h2>
-<blockquote>
-Evaluates the polynomial at value <tt class="docutils literal">fraction</tt> which must be in (or
-expand to) a format acceptable to the <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> macros.</blockquote>
-</div>
-<div class="section" id="polevalreduced-polname-atexpr-numerical-expression">
-<span id="polevalreducedatexpr"></span><h2><a class="toc-backref" href="#id105"><tt class="docutils literal"><span class="pre">\PolEvalReduced{polname}\AtExpr{numerical</span> expression}</tt></a></h2>
-<blockquote>
-Boils down to <tt class="docutils literal">\xinttheexpr reduce(polname(numerical <span class="pre">expression))\relax</span></tt>.</blockquote>
-</div>
-<div class="section" id="polevalreduced-polname-at-fraction">
-<span id="polevalreducedat"></span><h2><a class="toc-backref" href="#id106"><tt class="docutils literal"><span class="pre">\PolEvalReduced{polname}\At{fraction}</span></tt></a></h2>
-<blockquote>
-Evaluates the polynomial at value <tt class="docutils literal">fraction</tt> which must be in (or
-expand to) a format acceptable to the <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> macros, and produce
-an irreducible fraction.</blockquote>
-</div>
-<div class="section" id="polfloateval-polname-atexpr-numerical-expression">
-<span id="polfloatevalatexpr"></span><h2><a class="toc-backref" href="#id107"><tt class="docutils literal"><span class="pre">\PolFloatEval{polname}\AtExpr{numerical</span> expression}</tt></a></h2>
-<blockquote>
-<p>Boils down to <tt class="docutils literal">\xintthefloatexpr polname(numerical <span class="pre">expression)\relax</span></tt>.</p>
-<p>This is done via a Horner Scheme (see <a class="reference internal" href="#poldef">\poldef</a> and
-<a class="reference internal" href="#polgenfloatvariant-polname">\PolGenFloatVariant{polname}</a>), with already rounded
-coefficients. <a class="footnote-reference" href="#id24" id="id22">[2]</a> To use the <em>exact coefficients</em> with <em>exactly
-executed</em> additions and multiplications, just insert it in the float
-expression as in this example: <a class="footnote-reference" href="#id25" id="id23">[3]</a></p>
-<pre class="literal-block">
-\xintthefloatexpr 3.27*\xintexpr f(2.53)\relax^2\relax
-</pre>
-<p>The <tt class="docutils literal">f(2.53)</tt> is exactly computed then rounded at the time of
-getting raised to the power <tt class="docutils literal">2</tt>. Moving the <tt class="docutils literal">^2</tt> inside, that
-operation would also be treated exactly.</p>
-<table class="docutils footnote" frame="void" id="id24" rules="none">
-<colgroup><col class="label" /><col /></colgroup>
-<tbody valign="top">
-<tr><td class="label"><a class="fn-backref" href="#id22">[2]</a></td><td>Anyway each floating point operation starts by rounding its
-operands to the floating point precision.</td></tr>
-</tbody>
-</table>
-<table class="docutils footnote" frame="void" id="id25" rules="none">
-<colgroup><col class="label" /><col /></colgroup>
-<tbody valign="top">
-<tr><td class="label"><a class="fn-backref" href="#id23">[3]</a></td><td>The <tt class="docutils literal">\xintexpr</tt> here could be <tt class="docutils literal">\xinttheexpr</tt> but that
-would be less efficient. Cf. <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> documentation about
-nested expressions.</td></tr>
-</tbody>
-</table>
-</blockquote>
-</div>
-<div class="section" id="polfloateval-polname-at-fraction">
-<span id="polfloatevalat"></span><h2><a class="toc-backref" href="#id108"><tt class="docutils literal"><span class="pre">\PolFloatEval{polname}\At{fraction}</span></tt></a></h2>
-<blockquote>
-Evaluates the polynomial at value <tt class="docutils literal">fraction</tt> which must be in (or
-expand to) a format acceptable to the <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> macros, and produces
-a floating point number.</blockquote>
-</div>
-<div class="section" id="polifcoeffisplusorminusone-a-b">
-<span id="polifcoeffisplusorminusone"></span><h2><a class="toc-backref" href="#id109"><tt class="docutils literal"><span class="pre">\PolIfCoeffIsPlusOrMinusOne{A}{B}</span></tt></a></h2>
-<blockquote>
-<p>This macro is a priori undefined.</p>
-<p>It is defined via the default <a class="reference internal" href="#poltypesetcmd-raw-coeff">\PolTypesetCmd{raw_coeff}</a> to be
-used if needed in the execution of <a class="reference internal" href="#poltypesetmonomialcmd">\PolTypesetMonomialCmd</a>,
-e.g. to insert a <tt class="docutils literal">\cdot</tt> in front of <tt class="docutils literal"><span class="pre">\PolVar^{\PolIndex}</span></tt> if
-the coefficient is not plus or minus one.</p>
-<p>The macro will execute <tt class="docutils literal">A</tt> if the coefficient has been found to be
-plus or minus one, and <tt class="docutils literal">B</tt> if not.</p>
-</blockquote>
-</div>
-<div class="section" id="polleadingcoeff-polname">
-<span id="polleadingcoeff"></span><h2><a class="toc-backref" href="#id110"><tt class="docutils literal">\PolLeadingCoeff{polname}</tt></a></h2>
-<blockquote>
-Expands to the leading coefficient.</blockquote>
-</div>
-<div class="section" id="polnthcoeff-polname-number">
-<span id="polnthcoeff"></span><h2><a class="toc-backref" href="#id111"><tt class="docutils literal"><span class="pre">\PolNthCoeff{polname}{number}</span></tt></a></h2>
-<blockquote>
-It expands to the raw <tt class="docutils literal">N</tt>-th coefficient (<tt class="docutils literal">0/1[0]</tt> if the index
-number is out of range). With <tt class="docutils literal"><span class="pre">N=-1</span></tt>, <tt class="docutils literal"><span class="pre">-2</span></tt>, ... expands to the
-leading coefficients.</blockquote>
-</div>
-<div class="section" id="poldegree-polname">
-<span id="poldegree"></span><h2><a class="toc-backref" href="#id112"><tt class="docutils literal">\PolDegree{polname}</tt></a></h2>
-<blockquote>
-It expands to the degree. This is <tt class="docutils literal"><span class="pre">-1</span></tt> if zero polynomial but this
-may change in future. Should it then expand to <tt class="docutils literal"><span class="pre">-\infty</span></tt> ?</blockquote>
-</div>
-<div class="section" id="policontent-polname">
-<span id="policontent"></span><h2><a class="toc-backref" href="#id113"><tt class="docutils literal">\PolIContent{polname}</tt></a></h2>
-<blockquote>
-<p>It expands to the contents of the polynomial, i.e. to the positive
-fraction such that dividing by this fraction produces a polynomial
-with integer coefficients having no common prime divisor.</p>
-<p>See <a class="reference internal" href="#polmakeprimitive">\PolMakePrimitive</a>.</p>
-</blockquote>
-</div>
-<div class="section" id="poltoexpr-polname">
-<span id="poltoexpr"></span><h2><a class="toc-backref" href="#id114"><tt class="docutils literal">\PolToExpr{polname}</tt></a></h2>
-<blockquote>
-<p>Expands <a class="footnote-reference" href="#id27" id="id26">[4]</a> to <tt class="docutils literal"><span class="pre">coeff_N*x^N+...</span></tt> (descending powers.)</p>
-<table class="docutils footnote" frame="void" id="id27" rules="none">
-<colgroup><col class="label" /><col /></colgroup>
-<tbody valign="top">
-<tr><td class="label"><a class="fn-backref" href="#id26">[4]</a></td><td>in a <tt class="docutils literal">\write</tt>, <tt class="docutils literal">\edef</tt>, or <tt class="docutils literal"><span class="pre">\csname...\endcsname</span></tt>, but
-not under <tt class="docutils literal"><span class="pre">\romannumeral-`0</span></tt>.</td></tr>
-</tbody>
-</table>
-<p>By default zero coefficients are skipped (issue <tt class="docutils literal">\poltoexpralltrue</tt> to
-get all of them in output).</p>
-<p>By default, no <tt class="docutils literal">+</tt> sign before negative coefficients, for
-compliance with Maple input format (but see
-<a class="reference internal" href="#poltoexprtermprefix-raw-coeff">\PolToExprTermPrefix{raw_coeff}</a>.) Also, like the default
-behaviour of <a class="reference internal" href="#poltypeset-polname">\PolTypeset{polname}</a>, does not print (for the non
-constant terms) coefficients equal to plus or minus one. The degree
-one monomial is output as <tt class="docutils literal">x</tt>, not <tt class="docutils literal">x^1</tt>. Complete customization is
-possible, see next macros.</p>
-<p>Of course <tt class="docutils literal">\PolToExpr{f}</tt> can be inserted in a <tt class="docutils literal">\poldef</tt>, as the
-latter expands token by token, hence will force complete expansion
-of <tt class="docutils literal">\PolToExpr{f}</tt>, but a simple <tt class="docutils literal">f(x)</tt> is more efficient for
-the identical result.</p>
-</blockquote>
-<div class="section" id="poltoexproneterm-raw-coeff-number">
-<span id="poltoexproneterm"></span><h3><a class="toc-backref" href="#id115"><tt class="docutils literal"><span class="pre">\PolToExprOneTerm{raw_coeff}{number}</span></tt></a></h3>
-<blockquote>
-<p>This two argument expandable command takes care of the monomial and
-its coefficient. The default definition is done in order for
-coefficients of absolute value <tt class="docutils literal">1</tt> not be printed explicitely
-(except of course for the constant term). Also by default, the
-monomial of degree one is <tt class="docutils literal">x</tt> not <tt class="docutils literal">x^1</tt>, and <tt class="docutils literal">x^0</tt> is skipped.</p>
-<p>For compatibility with Maple input requirements, by default a <tt class="docutils literal">*</tt>
-always precedes the <tt class="docutils literal">x^number</tt>, except if the coefficient is a one
-or a minus one. See <a class="reference internal" href="#poltoexprtimes">\PolToExprTimes</a>.</p>
-</blockquote>
-</div>
-<div class="section" id="poltoexpronetermstylea-raw-coeff-number">
-<span id="poltoexpronetermstylea"></span><h3><a class="toc-backref" href="#id116"><tt class="docutils literal"><span class="pre">\PolToExprOneTermStyleA{raw_coeff}{number}</span></tt></a></h3>
-<blockquote>
-Holds the default package meaning of
-<a class="reference internal" href="#poltoexproneterm-raw-coeff-number">\PolToExprOneTerm{raw_coeff}{number}</a>.</blockquote>
-</div>
-<div class="section" id="poltoexpronetermstyleb-raw-coeff-number">
-<span id="poltoexpronetermstyleb"></span><h3><a class="toc-backref" href="#id117"><tt class="docutils literal"><span class="pre">\PolToExprOneTermStyleB{raw_coeff}{number}</span></tt></a></h3>
-<blockquote>
-<p>For output in this style:</p>
-<pre class="literal-block">
-2*x^11/3+3*x^8/7-x^5-x^4/4-x^3-x^2/2-2*x+1
-</pre>
-<p>issue <tt class="docutils literal">\let\PolToExprOneTerm\PolToExprOneTermStyleB</tt> before usage of
-<tt class="docutils literal">\PolToExpr</tt>. Note that then <tt class="docutils literal">\PolToExprCmd</tt> isn't used at all.
-To revert to package default, issue
-<tt class="docutils literal">\let\PolToExprOneTerm\PolToExprOneTermStyleA</tt>.</p>
-<p>To suppress the <tt class="docutils literal">*</tt>'s, cf. <a class="reference internal" href="#poltoexprtimes">\PolToExprTimes</a>.</p>
-</blockquote>
-</div>
-<div class="section" id="poltoexprcmd-raw-coeff">
-<span id="poltoexprcmd"></span><h3><a class="toc-backref" href="#id118"><tt class="docutils literal">\PolToExprCmd{raw_coeff}</tt></a></h3>
-<blockquote>
-It is the one-argument macro used by the package definition of
-<tt class="docutils literal">\PolToExprOneTerm</tt> for the coefficients themselves (when not
-equal to plus or minus one), and it defaults to
-<tt class="docutils literal"><span class="pre">\xintPRaw{\xintRawWithZeros{#1}}</span></tt>. One will have to redefine it
-to <tt class="docutils literal"><span class="pre">\xintIrr{#1}</span></tt> or to <tt class="docutils literal"><span class="pre">\xintPRaw{\xintIrr{#1}}</span></tt> to obtain in the
-output forcefully reduced coefficients.</blockquote>
-</div>
-<div class="section" id="poltoexprtermprefix-raw-coeff">
-<span id="poltoexprtermprefix"></span><h3><a class="toc-backref" href="#id119"><tt class="docutils literal">\PolToExprTermPrefix{raw_coeff}</tt></a></h3>
-<blockquote>
-Defined identically as <a class="reference internal" href="#poltypesetcmdprefix-raw-coeff">\PolTypesetCmdPrefix{raw_coeff}</a>. It
-prefixes with a plus sign for non-negative coefficients, because
-they don't carry one by themselves.</blockquote>
-</div>
-<div class="section" id="id28">
-<span id="poltoexprvar"></span><h3><a class="toc-backref" href="#id120"><tt class="docutils literal">\PolToExprVar</tt></a></h3>
-<blockquote>
-This expands to the variable to use in output (it does not have to
-be a single letter, may be an expandable macro.) Initial definition
-is <tt class="docutils literal">x</tt>.</blockquote>
-</div>
-<div class="section" id="id29">
-<span id="poltoexprtimes"></span><h3><a class="toc-backref" href="#id121"><tt class="docutils literal">\PolToExprTimes</tt></a></h3>
-<blockquote>
-This expands to the symbol used for multiplication of an
-<tt class="docutils literal"><span class="pre">x^{number}</span></tt> by the corresponding coefficient. The default is
-<tt class="docutils literal">*</tt>. Redefine the macro to expand to nothing to get rid of it (but
-this will give output incompatible with some professional computer
-algebra software).</blockquote>
-</div>
-</div>
-<div class="section" id="id31">
-<span id="id30"></span><h2><a class="toc-backref" href="#id122"><tt class="docutils literal"><span class="pre">\PolToExpr*{polname}</span></tt></a></h2>
-<blockquote>
-Expands to <tt class="docutils literal"><span class="pre">coeff_0+coeff_1*x+coeff_2*x^2+...</span></tt> (ascending powers).
-Customizable like <a class="reference internal" href="#poltoexpr-polname">\PolToExpr{polname}</a> via the same macros.</blockquote>
-</div>
-<div class="section" id="poltofloatexpr-polname">
-<span id="poltofloatexpr"></span><h2><a class="toc-backref" href="#id123"><tt class="docutils literal">\PolToFloatExpr{polname}</tt></a></h2>
-<blockquote>
-<p>Similar to <a class="reference internal" href="#poltoexpr-polname">\PolToExpr{polname}</a> but uses <a class="reference external" href="\PolToFloatExprCmd{raw_coeff}">\PolToFloatExprCmd</a>
-which by default rounds and converts the coefficients to floating
-point format.</p>
-<div class="admonition note">
-<p class="first admonition-title">Note</p>
-<p>It is not necessary to have issued
-<a class="reference internal" href="#polgenfloatvariant-polname">\PolGenFloatVariant{polname}</a>. The rounded coefficients are
-not easily recoverable from the <tt class="docutils literal">\xintfloatexpr</tt> polynomial
-function hence <tt class="docutils literal">\PolToFloatExprCmd</tt> operates from the <em>exact</em>
-coefficients anew.</p>
-<p class="last">Attention that both macros obey the prevailing float precision.
-If it is changed between those macro calls, then a mismatch
-exists between the coefficients as used in <tt class="docutils literal">\xintfloatexpr</tt> and
-those output by <tt class="docutils literal">\PolToFloatExpr{polname}</tt>.</p>
-</div>
-</blockquote>
-<div class="section" id="poltofloatexproneterm-raw-coeff-number">
-<span id="poltofloatexproneterm"></span><h3><a class="toc-backref" href="#id124"><tt class="docutils literal"><span class="pre">\PolToFloatExprOneTerm{raw_coeff}{number}</span></tt></a></h3>
-<blockquote>
-Similar to <a class="reference external" href="\PolToExprOneTerm{raw_coeff}{number}">\PolToExprOneTerm</a>. But does not treat
-especially coefficients equal to plus or minus one.</blockquote>
-</div>
-<div class="section" id="poltofloatexprcmd-raw-coeff">
-<span id="id33"></span><h3><a class="toc-backref" href="#id125"><tt class="docutils literal">\PolToFloatExprCmd{raw_coeff}</tt></a></h3>
-<blockquote>
-<p>It is the one-argument macro used by <tt class="docutils literal">\PolToFloatExprOneTerm</tt>.
-Its package definition is <tt class="docutils literal"><span class="pre">\xintFloat{#1}</span></tt>.</p>
-<div class="admonition caution">
-<p class="first admonition-title">Caution!</p>
-<p>Currently (<a class="reference external" href="http://www.ctan.org/pkg/xint">xint</a> <tt class="docutils literal">1.3c</tt>) <tt class="docutils literal">\xintFloat{0}</tt> outputs <tt class="docutils literal">0.e0</tt>
-which is perfectly acceptable input for Python, but not for
-Maple. Thus, one should better leave the <a class="reference internal" href="#poltoexprallfalse">\poltoexprallfalse</a>
-toggle to its default <tt class="docutils literal">\iffalse</tt> state, if one intends to use
-the output in a Maple worksheet.</p>
-<p>But even then the zero polynomial will cause a problem. Workaround:</p>
-<pre class="literal-block">
-\renewcommand\PolToFloatExprCmd[1]{\xintiiifZero{#1}{0.0}{\xintFloat{#1}}}
-</pre>
-<p class="last">Usage of <tt class="docutils literal">\xintiiifZero</tt> and not <tt class="docutils literal">\xintifZero</tt> is only for
-optimization (I can't help it) because <tt class="docutils literal">#1</tt> is known to be
-in <tt class="docutils literal">xintfrac</tt> raw format.</p>
-</div>
-</blockquote>
-</div>
-</div>
-<div class="section" id="id35">
-<span id="id34"></span><h2><a class="toc-backref" href="#id126"><tt class="docutils literal"><span class="pre">\PolToFloatExpr*{polname}</span></tt></a></h2>
-<blockquote>
-Typesets in ascending powers.</blockquote>
-</div>
-<div class="section" id="poltolist-polname">
-<span id="poltolist"></span><h2><a class="toc-backref" href="#id127"><tt class="docutils literal">\PolToList{polname}</tt></a></h2>
-<blockquote>
-Expands to <tt class="docutils literal"><span class="pre">{coeff_0}{coeff_1}...{coeff_N}</span></tt> with <tt class="docutils literal">N</tt> = degree, and
-<tt class="docutils literal">coeff_N</tt> the leading coefficient
-(the zero polynomial does give <tt class="docutils literal">{0/1[0]}</tt> and not an
-empty output.)</blockquote>
-</div>
-<div class="section" id="poltocsv-polname">
-<span id="poltocsv"></span><h2><a class="toc-backref" href="#id128"><tt class="docutils literal">\PolToCSV{polname}</tt></a></h2>
-<blockquote>
-Expands to <tt class="docutils literal">coeff_0, coeff_1, coeff_2, <span class="pre">.....,</span> coeff_N</tt>, starting
-with constant term and ending with leading coefficient. Converse
-to <a class="reference internal" href="#polfromcsv-polname-csv">\PolFromCSV</a>.</blockquote>
-</div>
-<div class="section" id="polsturmchainlength-sturmname">
-<span id="polsturmchainlength"></span><h2><a class="toc-backref" href="#id129"><tt class="docutils literal">\PolSturmChainLength{sturmname}</tt></a></h2>
-<blockquote>
-<p>Returns the integer <tt class="docutils literal">N</tt> such that <tt class="docutils literal">sturmname_N</tt> is the last one
-in the Sturm chain <tt class="docutils literal">sturmname_0</tt>, <tt class="docutils literal">sturmname_1</tt>, ...</p>
-<p>See <a class="reference internal" href="#poltosturm-polname-sturmname">\PolToSturm{polname}{sturmname}</a>.</p>
-</blockquote>
-</div>
-<div class="section" id="polsturmifzeroexactlyknown-sturmname-index-a-b">
-<span id="polsturmifzeroexactlyknown"></span><h2><a class="toc-backref" href="#id130"><tt class="docutils literal"><span class="pre">\PolSturmIfZeroExactlyKnown{sturmname}{index}{A}{B}</span></tt></a></h2>
-<blockquote>
-<p>Executes <tt class="docutils literal">A</tt> if the <tt class="docutils literal">index</tt>-th interval reduces to a singleton,
-i.e. the root is known exactly, else <tt class="docutils literal">B</tt>.</p>
-<div class="admonition note">
-<p class="first admonition-title">Note</p>
-<p class="last"><tt class="docutils literal">index</tt> is allowed to be something like <tt class="docutils literal">1+2*3</tt> as it is fed
-to <tt class="docutils literal"><span class="pre">\the\numexpr...\relax</span></tt>.</p>
-</div>
-</blockquote>
-</div>
-<div class="section" id="polsturmisolatedzeroleft-sturmname-index">
-<span id="polsturmisolatedzeroleft"></span><h2><a class="toc-backref" href="#id131"><tt class="docutils literal"><span class="pre">\PolSturmIsolatedZeroLeft{sturmname}{index}</span></tt></a></h2>
-<blockquote>
-<p>Expands to the left end-point for the <tt class="docutils literal">index</tt>-th interval, as
-computed by some earlier <a class="reference internal" href="#polsturmisolatezeros-sturmname">\PolSturmIsolateZeros{sturmname}</a>.</p>
-<div class="admonition note">
-<p class="first admonition-title">Note</p>
-<p class="last">Of course, this is kept updated by macros such as
-<a class="reference internal" href="#polrefineinterval-n">\PolRefineInterval{sturmname}{index}</a>.</p>
-</div>
-<p>The value is pre-formatted using <a class="reference internal" href="#poldectostring">\PolDecTostring</a>.</p>
-</blockquote>
-</div>
-<div class="section" id="polsturmisolatedzeroright-sturmname-index">
-<span id="polsturmisolatedzeroright"></span><h2><a class="toc-backref" href="#id132"><tt class="docutils literal"><span class="pre">\PolSturmIsolatedZeroRight{sturmname}{index}</span></tt></a></h2>
-<blockquote>
-<p>Expands to the right end-point for the <tt class="docutils literal">index</tt>-th interval as
-computed by some earlier <a class="reference internal" href="#polsturmisolatezeros-sturmname">\PolSturmIsolateZeros{sturmname}</a> and
-possibly refined afterwards.</p>
-<p>The value is pre-formatted using <a class="reference internal" href="#poldectostring">\PolDecTostring</a>.</p>
-</blockquote>
-</div>
-<div class="section" id="polsturmisolatedzeromultiplicity-sturmname-index">
-<span id="polsturmisolatedzeromultiplicity"></span><h2><a class="toc-backref" href="#id133"><tt class="docutils literal"><span class="pre">\PolSturmIsolatedZeroMultiplicity{sturmname}{index}</span></tt></a></h2>
-<blockquote>
-<p>Expands to the multiplicity of the unique root contained in the
-<tt class="docutils literal">index</tt>-th interval.</p>
-<div class="admonition attention">
-<p class="first admonition-title">Attention!</p>
-<p class="last">A prior execution of <a class="reference internal" href="#id12">\PolSturmIsolateZeros*{sturmname}</a> is mandatory.</p>
-</div>
-<p>See <a class="reference internal" href="#the-degree-nine-polynomial-with-0-99-0-999-0-9999-as-triple-roots">The degree nine polynomial with 0.99, 0.999, 0.9999 as triple
-roots</a> for an example of use.</p>
-</blockquote>
-</div>
-<div class="section" id="polsturmnbofisolatedzeros-sturmname">
-<span id="polsturmnbofisolatedzeros"></span><h2><a class="toc-backref" href="#id134"><tt class="docutils literal">\PolSturmNbOfIsolatedZeros{sturmname}</tt></a></h2>
-<blockquote>
-Expands to the number of real roots of the polynomial
-<tt class="docutils literal">&lt;sturmname&gt;_0</tt>, i.e. the number of distinct real roots of the
-polynomial originally used to create the Sturm chain via
-<a class="reference internal" href="#poltosturm-polname-sturmname">\PolToSturm{polname}{sturmname}</a>.</blockquote>
-<div class="admonition warning">
-<p class="first admonition-title">Warning</p>
-<p class="last">The next few macros counting roots, with or without multiplicities,
-less than or equal to some value, are under evaluation and may be
-removed from the package if their utility is judged to be not high
-enough. They can be re-coded at user level on the basis of the other
-documented package macros anyway.</p>
-</div>
-<div class="section" id="polsturmnbofrootsof-sturmname-lessthanorequalto-value">
-<h3><a class="toc-backref" href="#id135"><tt class="docutils literal"><span class="pre">\PolSturmNbOfRootsOf{sturmname}\LessThanOrEqualTo{value}</span></tt></a></h3>
-<blockquote>
-<p>Expands to the number of distinct roots (of the polynomial used to
-create the Sturm chain) less than or equal to the <tt class="docutils literal">value</tt> (i.e. a
-number of fraction recognizable by the <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> macros).</p>
-<div class="admonition attention">
-<p class="first admonition-title">Attention!</p>
-<p><a class="reference internal" href="#polsturmisolatezeros-sturmname">\PolSturmIsolateZeros{sturmname}</a> must have been executed
-beforehand.</p>
-<p class="last">And the argument is a <tt class="docutils literal">sturmname</tt>, not a <tt class="docutils literal">polname</tt> (this is
-why the macro contains Sturm in its name), simply to be reminded
-of the above constraint.</p>
-</div>
-</blockquote>
-</div>
-<div class="section" id="polsturmnbofrootsof-sturmname-lessthanorequaltoexpr-expression">
-<h3><a class="toc-backref" href="#id136"><tt class="docutils literal"><span class="pre">\PolSturmNbOfRootsOf{sturmname}\LessThanOrEqualToExpr{expression}</span></tt></a></h3>
-<blockquote>
-<p>Expands to the number of distinct roots (of the polynomial
-used to create the Sturm chain) which are less than or equal to the
-given <tt class="docutils literal">expression</tt>.</p>
-<div class="admonition attention">
-<p class="first admonition-title">Attention!</p>
-<p class="last"><a class="reference internal" href="#polsturmisolatezeros-sturmname">\PolSturmIsolateZeros{sturmname}</a> must have been executed
-beforehand.</p>
-</div>
-</blockquote>
-</div>
-<div class="section" id="polsturmnbwithmultofrootsof-sturmname-lessthanorequalto-value">
-<h3><a class="toc-backref" href="#id137"><tt class="docutils literal"><span class="pre">\PolSturmNbWithMultOfRootsOf{sturmname}\LessThanOrEqualTo{value}</span></tt></a></h3>
-<blockquote>
-<p>Expands to the number counted with multiplicities of the roots (of
-the polynomial used to create the Sturm chain) which are less than
-or equal to the given <tt class="docutils literal">value</tt>.</p>
-<div class="admonition attention">
-<p class="first admonition-title">Attention!</p>
-<p class="last"><a class="reference internal" href="#id12">\PolSturmIsolateZeros*{sturmname}</a> (or the double starred
-variant) must have been executed beforehand.</p>
-</div>
-</blockquote>
-</div>
-<div class="section" id="polsturmnbwithmultofrootsof-sturmname-lessthanorequaltoexpr-expression">
-<h3><a class="toc-backref" href="#id138"><tt class="docutils literal"><span class="pre">\PolSturmNbWithMultOfRootsOf{sturmname}\LessThanOrEqualToExpr{expression}</span></tt></a></h3>
-<blockquote>
-<p>Expands to the total number of roots (counted with multiplicities)
-which are less than or equal to the given <tt class="docutils literal">expression</tt>.</p>
-<div class="admonition attention">
-<p class="first admonition-title">Attention!</p>
-<p class="last"><a class="reference internal" href="#id12">\PolSturmIsolateZeros*{sturmname}</a> (or the double starred
-variant) must have been executed beforehand.</p>
-</div>
-</blockquote>
-</div>
-</div>
-<div class="section" id="polsturmnbofrationalroots-sturmname">
-<h2><a class="toc-backref" href="#id139"><tt class="docutils literal">\PolSturmNbOfRationalRoots{sturmname}</tt></a></h2>
-<blockquote>
-<p>Expands to the number of rational roots (without multiplicities).</p>
-<div class="admonition attention">
-<p class="first admonition-title">Attention!</p>
-<p class="last"><a class="reference internal" href="#id14">\PolSturmIsolateZeros**{sturmname}</a> must have been executed
-beforehand.</p>
-</div>
-</blockquote>
-</div>
-<div class="section" id="polsturmnbofrationalrootswithmultiplicities-sturmname">
-<h2><a class="toc-backref" href="#id140"><tt class="docutils literal">\PolSturmNbOfRationalRootsWithMultiplicities{sturmname}</tt></a></h2>
-<blockquote>
-<p>Expands to the number of rational roots (counted with multiplicities).</p>
-<div class="admonition attention">
-<p class="first admonition-title">Attention!</p>
-<p class="last"><a class="reference internal" href="#id14">\PolSturmIsolateZeros**{sturmname}</a> must have been executed
-beforehand.</p>
-</div>
-</blockquote>
-</div>
-<div class="section" id="polsturmrationalroot-sturmname-k">
-<h2><a class="toc-backref" href="#id141"><tt class="docutils literal"><span class="pre">\PolSturmRationalRoot{sturmname}{k}</span></tt></a></h2>
-<blockquote>
-<p>Expands to the <tt class="docutils literal">k</tt>th rational root (they are ordered and indexed
-starting at 1 for the most negative).</p>
-<div class="admonition attention">
-<p class="first admonition-title">Attention!</p>
-<p class="last"><a class="reference internal" href="#id14">\PolSturmIsolateZeros**{sturmname}</a> must have been executed
-beforehand.</p>
-</div>
-</blockquote>
-</div>
-<div class="section" id="polsturmrationalrootindex-sturmname-k">
-<h2><a class="toc-backref" href="#id142"><tt class="docutils literal"><span class="pre">\PolSturmRationalRootIndex{sturmname}{k}</span></tt></a></h2>
-<blockquote>
-<p>Expands to <tt class="docutils literal">index</tt> of the <tt class="docutils literal">k</tt>th rational root as part of the
-ordered real roots (without multiplicities). I.e., above macro
-<a class="reference internal" href="#polsturmrationalroot-sturmname-k">\PolSturmRationalRoot{sturmname}{k}</a> is equivalent to this
-nested call:</p>
-<pre class="literal-block">
-\PolSturmIsolatedZeroLeft{sturmname}{\PolSturmRationalRootIndex{sturmname}{k}}
-</pre>
-<div class="admonition attention">
-<p class="first admonition-title">Attention!</p>
-<p class="last"><a class="reference internal" href="#id14">\PolSturmIsolateZeros**{sturmname}</a> must have been executed
-beforehand.</p>
-</div>
-</blockquote>
-</div>
-<div class="section" id="polsturmrationalrootmultiplicity-sturmname-k">
-<h2><a class="toc-backref" href="#id143"><tt class="docutils literal"><span class="pre">\PolSturmRationalRootMultiplicity{sturmname}{k}</span></tt></a></h2>
-<blockquote>
-<p>Expands to the multiplicity of the <tt class="docutils literal">k</tt>th rational root.</p>
-<div class="admonition attention">
-<p class="first admonition-title">Attention!</p>
-<p class="last"><a class="reference internal" href="#id14">\PolSturmIsolateZeros**{sturmname}</a> must have been executed
-beforehand.</p>
-</div>
-</blockquote>
-</div>
-<div class="section" id="polintervalwidth-sturmname-index">
-<span id="polintervalwidth"></span><h2><a class="toc-backref" href="#id144"><tt class="docutils literal"><span class="pre">\PolIntervalWidth{sturmname}{index}</span></tt></a></h2>
-<blockquote>
-The <tt class="docutils literal">10^E</tt> width of the current <tt class="docutils literal">index</tt>-th root localization
-interval. Output is in <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> raw <tt class="docutils literal">1/1[E]</tt> format (if not zero).</blockquote>
-</div>
-<div class="section" id="expandable-macros-for-use-within-execution-of-polprintintervals">
-<h2><a class="toc-backref" href="#id145">Expandable macros for use within execution of <tt class="docutils literal">\PolPrintIntervals</tt></a></h2>
-<p>These macros are for usage within custom user redefinitions of
-<a class="reference internal" href="#polprintintervalsknownroot">\PolPrintIntervalsKnownRoot</a>, <a class="reference internal" href="#polprintintervalsunknownroot">\PolPrintIntervalsUnknownRoot</a>, or
-in redefinitions of <a class="reference internal" href="#polprintintervalsprintexactzero">PolPrintIntervalsPrintExactZero</a> (used in the
-default for the former) and of <a class="reference internal" href="#polprintintervalsprintleftendpoint">\PolPrintIntervalsPrintLeftEndPoint</a>,
-<a class="reference internal" href="#polprintintervalsprintrightendpoint">\PolPrintIntervalsPrintRightEndPoint</a> (used in the default for the
-latter).</p>
-<div class="admonition attention">
-<p class="first admonition-title">Attention!</p>
-<p class="last">Some macros formerly mentioned here got removed at 0.7:
-<tt class="docutils literal">\PolPrintIntervalsTheEndPoint</tt>,
-<tt class="docutils literal"><span class="pre">\PolIfEndPointIsPositive{A}{B}</span></tt>,
-<tt class="docutils literal"><span class="pre">\PolIfEndPointIsNegative{A}{B}</span></tt>,
-<tt class="docutils literal"><span class="pre">\PolIfEndPointIsZero{A}{B}</span></tt>.</p>
-</div>
-<div class="section" id="polprintintervalsthevar">
-<h3><a class="toc-backref" href="#id146"><tt class="docutils literal">\PolPrintIntervalsTheVar</tt></a></h3>
-<blockquote>
-Expands to the name (default <tt class="docutils literal">Z</tt>) used for representing the roots,
-which was passed as optional argument <tt class="docutils literal">varname</tt> to
-<a class="reference internal" href="#polprintintervals-varname-sturmname">\PolPrintIntervals[varname]{sturmname}</a>.</blockquote>
-</div>
-<div class="section" id="polprintintervalstheindex">
-<h3><a class="toc-backref" href="#id147"><tt class="docutils literal">\PolPrintIntervalsTheIndex</tt></a></h3>
-<blockquote>
-Expands to the index of the considered interval (indexing starting
-at 1 for the leftmost interval).</blockquote>
-</div>
-<div class="section" id="polprintintervalsthesturmname">
-<h3><a class="toc-backref" href="#id148"><tt class="docutils literal">\PolPrintIntervalsTheSturmName</tt></a></h3>
-<blockquote>
-Expands to the argument which was passed as <tt class="docutils literal">sturmname</tt> to
-<a class="reference internal" href="#polprintintervals-varname-sturmname">\PolPrintIntervals[varname]{sturmname}</a>.</blockquote>
-</div>
-<div class="section" id="polprintintervalstheleftendpoint">
-<h3><a class="toc-backref" href="#id149"><tt class="docutils literal">\PolPrintIntervalsTheLeftEndPoint</tt></a></h3>
-<blockquote>
-The left end point of the interval, as would be produced by
-<a class="reference internal" href="#polsturmisolatedzeroleft">\PolSturmIsolatedZeroLeft</a> if it was
-used with arguments the Sturm chain name and interval index returned
-by <a class="reference internal" href="#polprintintervalsthesturmname">\PolPrintIntervalsTheSturmName</a> and
-<a class="reference internal" href="#polprintintervalstheindex">\PolPrintIntervalsTheIndex</a>.</blockquote>
-</div>
-<div class="section" id="polprintintervalstherightendpoint">
-<h3><a class="toc-backref" href="#id150"><tt class="docutils literal">\PolPrintIntervalsTheRightEndPoint</tt></a></h3>
-<blockquote>
-The right end point of the interval, as would be produced by
-<a class="reference internal" href="#polsturmisolatedzeroright">\PolSturmIsolatedZeroRight</a> for
-this Sturm chain name and index.</blockquote>
-</div>
-<div class="section" id="polprintintervalsthemultiplicity">
-<h3><a class="toc-backref" href="#id151"><tt class="docutils literal">\PolPrintIntervalsTheMultiplicity</tt></a></h3>
-<blockquote>
-The multiplicity of the unique root within the interval of index
-<a class="reference internal" href="#polprintintervalstheindex">\PolPrintIntervalsTheIndex</a>. Makes sense only if the starred (or
-double-starred) variant of <a class="reference internal" href="#polsturmisolatezeros">\PolSturmIsolateZeros</a> was used earlier.</blockquote>
-</div>
-</div>
-<div class="section" id="poldectostring-decimal-number">
-<span id="poldectostring"></span><h2><a class="toc-backref" href="#id152"><tt class="docutils literal">\PolDecToString{decimal number}</tt></a></h2>
-<blockquote>
-<p>This is a utility macro to print decimal numbers. It has been
-backported to <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> (release <tt class="docutils literal">1.3</tt> of <tt class="docutils literal">2018/03/01</tt>) under
-the name <tt class="docutils literal">\xintDecToString</tt>, and the <tt class="docutils literal">polexpr</tt> macro is simply
-now an alias to it.</p>
-<p>For example
-<tt class="docutils literal"><span class="pre">\PolDecToString{123.456e-8}</span></tt> will expand to <tt class="docutils literal">0.00000123456</tt>
-and <tt class="docutils literal"><span class="pre">\PolDecToString{123.450e-8}</span></tt> to <tt class="docutils literal">0.00000123450</tt> which
-illustrates that trailing zeros are not trimmed. To trim trailing
-zeroes, one can use <tt class="docutils literal"><span class="pre">\PolDecToString{\xintREZ{#1}}</span></tt>.</p>
-<p>The precise behaviour of this macro may evolve in future releases of
-<a class="reference external" href="http://www.ctan.org/pkg/xint">xint</a>.</p>
-</blockquote>
-</div>
-</div>
-<div class="section" id="booleans-with-default-setting-as-indicated">
-<h1><a class="toc-backref" href="#id153">Booleans (with default setting as indicated)</a></h1>
-<div class="section" id="xintverbosefalse">
-<h2><a class="toc-backref" href="#id154"><tt class="docutils literal">\xintverbosefalse</tt></a></h2>
-<blockquote>
-<p>This is actually an <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> configuration. Setting it to
-<tt class="docutils literal">true</tt> triggers the writing of information to the log when new
-polynomials are defined.</p>
-<div class="admonition caution">
-<p class="first admonition-title">Caution!</p>
-<p class="last">The macro meanings as written to the log are to be considered
-unstable and undocumented internal structures.</p>
-</div>
-</blockquote>
-</div>
-<div class="section" id="poltypesetallfalse">
-<h2><a class="toc-backref" href="#id155"><tt class="docutils literal">\poltypesetallfalse</tt></a></h2>
-<blockquote>
-If <tt class="docutils literal">true</tt>, <a class="reference internal" href="#poltypeset-polname">\PolTypeset{polname}</a> will also typeset the vanishing
-coefficients.</blockquote>
-</div>
-<div class="section" id="poltoexprallfalse">
-<h2><a class="toc-backref" href="#id156"><tt class="docutils literal">\poltoexprallfalse</tt></a></h2>
-<blockquote>
-If <tt class="docutils literal">true</tt>, <a class="reference internal" href="#poltoexpr-polname">\PolToExpr{polname}</a> and <a class="reference internal" href="#poltofloatexpr-polname">\PolToFloatExpr{polname}</a> will
-also include the vanishing coefficients in their outputs.</blockquote>
-</div>
-</div>
-<div class="section" id="polexprsetup">
-<h1><a class="toc-backref" href="#id157"><tt class="docutils literal">\polexprsetup</tt></a></h1>
-<blockquote>
-<p>Serves to customize the package. Currently only two keys are
-recognized:</p>
-<ul class="simple">
-<li><tt class="docutils literal">norr</tt>: the postfix that <a class="reference internal" href="#id14">\PolSturmIsolateZeros**{sturmname}</a>
-should append to <tt class="docutils literal">sturmname</tt> to declare the primitive polynomial
-obtained from original one after removal of all rational roots.
-The default value is <tt class="docutils literal">_norr</tt> (standing for “no rational roots”).</li>
-<li><tt class="docutils literal">sqfnorr</tt>: the postfix that <a class="reference internal" href="#id14">\PolSturmIsolateZeros**{sturmname}</a>
-should append to <tt class="docutils literal">sturmname</tt> to declare the primitive polynomial
-obtained from original one after removal of all rational roots and
-suppression of all multiplicities.
-The default value is <tt class="docutils literal">_sqf_norr</tt> (standing for “square-free with
-no rational roots”).</li>
-</ul>
-<p>The package executes <tt class="docutils literal">\polexprsetup{norr=_norr,
-sqfnorr=_sqf_norr}</tt> as default.</p>
-</blockquote>
-</div>
-<div class="section" id="technicalities">
-<h1><a class="toc-backref" href="#id158">Technicalities</a></h1>
-<ul>
-<li><p class="first">The catcode of the semi-colon is reset temporarily by <a class="reference internal" href="#poldef">\poldef</a> macro in case some other package (for example the French
-babel module) may have made it active. This will fail though if the
-whole thing was already part of a macro argument, in such cases one
-can use <a class="reference internal" href="#id2">\PolDef{f}{P(x)}</a>
-rather. The colon in <tt class="docutils literal">:=</tt> may be active with no consequences.</p>
-</li>
-<li><p class="first">As a consequence of <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> addition and subtraction always using
-least common multiples for the denominators <a class="footnote-reference" href="#id37" id="id36">[5]</a>, user-chosen common
-denominators survive additions and multiplications. For example, this:</p>
-<pre class="literal-block">
-\poldef P(x):= 1/2 + 2/2*x + 3/2*x^3 + 4/2*x^4;
-\poldef Q(x):= 1/3 + (2/3)x + (3/3)x^3 + (4/3)x^4;
-\poldef PQ(x):= P(x)Q(x);
-</pre>
-<p>gives internally the polynomial:</p>
-<pre class="literal-block">
-1/6+4/6*x^1+4/6*x^2+6/6*x^3+20/6*x^4+16/6*x^5+9/6*x^6+24/6*x^7+16/6*x^8
-</pre>
-<p>where all coefficients have the same denominator 6. Notice though that
-<tt class="docutils literal">\PolToExpr{PQ}</tt> outputs the <tt class="docutils literal">6/6*x^3</tt> as <tt class="docutils literal">x^3</tt> because (by
-default) it recognizes and filters out coefficients equal to one or
-minus one (since release <tt class="docutils literal">0.3</tt>). One can use for example
-<tt class="docutils literal">\PolToCSV{PQ}</tt> to see the internally stored coefficients.</p>
-<table class="docutils footnote" frame="void" id="id37" rules="none">
-<colgroup><col class="label" /><col /></colgroup>
-<tbody valign="top">
-<tr><td class="label"><a class="fn-backref" href="#id36">[5]</a></td><td><p class="first last">prior to <tt class="docutils literal">0.4.1</tt>, <tt class="docutils literal">polexpr</tt> used to temporarily patch
-during the parsing of polynomials the <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> macros. This
-patch was backported to <a class="reference external" href="http://www.ctan.org/pkg/xint">xint</a> at release <tt class="docutils literal">1.3</tt>.</p>
-</td></tr>
-</tbody>
-</table>
-</li>
-<li><p class="first"><a class="reference internal" href="#poldiff-polname-1-polname-2">\PolDiff{polname_1}{polname_2}</a> always applies <tt class="docutils literal">\xintIrr</tt> to the
-resulting coefficients, except that the <em>power of ten</em> part <tt class="docutils literal">[N]</tt>
-(for example an input in scientific notation such as <tt class="docutils literal">1.23e5</tt> gives
-<tt class="docutils literal">123/1[3]</tt> internally in xintfrac) is not taken into account in the
-reduction of the fraction. This is tentative and may change.</p>
-<p>Same remark for <a class="reference internal" href="#polantidiff-polname-1-polname-2">\PolAntiDiff{polname_1}{polname_2}</a>.</p>
-</li>
-<li><p class="first">Currently, the package stores all coefficients from index <tt class="docutils literal">0</tt> to
-index equal to the polynomial degree inside a single macro, as a list.
-This data structure is obviously very inefficient for polynomials of
-high degree and few coefficients (as an example with <tt class="docutils literal">\poldef
-<span class="pre">f(x):=x^1000</span> + x^500;</tt> the subsequent definition <tt class="docutils literal">\poldef <span class="pre">g(x):=</span>
-<span class="pre">f(x)^2;</span></tt> will do of the order of 1,000,000 multiplications and
-additions involvings only zeroes... which does take time). This
-may change in the future.</p>
-</li>
-<li><p class="first">As is to be expected internal structures of the package are barely
-documented and unstable. Don't use them.</p>
-</li>
-</ul>
-</div>
-<div class="section" id="change-log">
-<h1><a class="toc-backref" href="#id159">CHANGE LOG</a></h1>
-<ul>
-<li><p class="first">v0.1 (2018/01/11): initial release. Features:</p>
-<ul class="simple">
-<li>The <a class="reference internal" href="#poldef">\poldef</a> parser itself,</li>
-<li>Differentiation and anti-differentiation,</li>
-<li>Euclidean division and GCDs,</li>
-<li>Various utilities such as <a class="reference internal" href="#polfromcsv">\PolFromCSV</a>,
-<a class="reference internal" href="#polmapcoeffs">\PolMapCoeffs</a>,
-<a class="reference internal" href="#poltocsv">\PolToCSV</a>, <a class="reference internal" href="#poltoexpr">\PolToExpr</a>, ...</li>
-</ul>
-<p>Only one-variable polynomials so far.</p>
-</li>
-<li><p class="first">v0.2 (2018/01/14)</p>
-<ul class="simple">
-<li>Fix: <tt class="docutils literal">&quot;README thinks \numexpr recognizes ^ operator&quot;</tt>.</li>
-<li>Convert README to reStructuredText markup.</li>
-<li>Move main documentation from README to separate <tt class="docutils literal">polexpr.txt</tt> file.</li>
-<li>Provide <tt class="docutils literal">polexpr.html</tt> as obtained via <a class="reference external" href="http://docutils.sourceforge.net/docs/index.html">DocUtils</a> <tt class="docutils literal">rst2html.py</tt>.</li>
-<li>Convert README to (CTAN compatible) Markdown markup.</li>
-</ul>
-<p>Due to lack of available time the test suite might not be extensive
-enough. Bug reports are very welcome!</p>
-</li>
-<li><p class="first">v0.3 (2018/01/17)</p>
-<ul>
-<li><p class="first">bug fixes:</p>
-<ul>
-<li><p class="first">the <tt class="docutils literal">0.1</tt> <a class="reference internal" href="#polevalat">\PolEval</a> accepted expressions for its second
-argument, but this was removed by mistake at <tt class="docutils literal">0.2</tt>. Restored.</p>
-<p><strong>Attention</strong>: at <tt class="docutils literal">0.4</tt> this has been reverted again, and
-<a class="reference internal" href="#polevalatexpr">\PolEval{P}\AtExpr{foo}</a> syntax is needed for
-using expressions in the second argument.</p>
-</li>
-</ul>
-</li>
-<li><p class="first">incompatible or breaking changes:</p>
-<ul class="simple">
-<li><a class="reference internal" href="#poltoexpr">\PolToExpr</a> now by default uses <em>descending</em>
-powers (it also treats differently coefficients equal to 1 or -1.)
-Use <a class="reference internal" href="#id30">\PolToExpr*</a> for <em>ascending</em> powers.</li>
-<li><a class="reference internal" href="#polevalat">\PolEval</a> reduced the output to smallest terms,
-but as this is costly with big fractions and not needed if e.g.
-wrapped in an <tt class="docutils literal">\xintRound</tt> or <tt class="docutils literal">\xintFloat</tt>, this step has been
-removed; the former meaning is available as <a class="reference internal" href="#polevalreducedat">\PolEvalReduced</a>.</li>
-</ul>
-</li>
-<li><p class="first">new (or newly documented) macros:</p>
-<ul class="simple">
-<li><a class="reference internal" href="#poltypesetcmd">\PolTypesetCmd</a></li>
-<li><a class="reference internal" href="#poltypesetcmdprefix">\PolTypesetCmdPrefix</a></li>
-<li><a class="reference internal" href="#poltypesetmonomialcmd">\PolTypesetMonomialCmd</a></li>
-<li><a class="reference internal" href="#polevalreducedat">\PolEvalReducedAt</a></li>
-<li><a class="reference internal" href="#poltofloatexpr">\PolToFloatExpr</a></li>
-<li><a class="reference internal" href="#poltoexproneterm">\PolToExprOneTerm</a></li>
-<li><a class="reference internal" href="#poltofloatexproneterm">\PolToFloatExprOneTerm</a></li>
-<li><a class="reference internal" href="#poltoexprcmd">\PolToExprCmd</a></li>
-<li><a class="reference internal" href="#id33">\PolToFloatExprCmd</a></li>
-<li><a class="reference internal" href="#poltoexprtermprefix">\PolToExprTermPrefix</a></li>
-<li><a class="reference internal" href="#poltoexprvar">\PolToExprVar</a></li>
-<li><a class="reference internal" href="#poltoexprtimes">\PolToExprTimes</a></li>
-</ul>
-</li>
-<li><p class="first">improvements:</p>
-<ul>
-<li><p class="first">documentation has a table of contents, internal hyperlinks,
-standardized signature notations and added explanations.</p>
-</li>
-<li><p class="first">one can do <tt class="docutils literal"><span class="pre">\PolLet{g}={f}</span></tt> or <tt class="docutils literal"><span class="pre">\PolLet{g}{f}</span></tt>.</p>
-</li>
-<li><p class="first"><tt class="docutils literal">\PolToExpr{f}</tt> is highly customizable.</p>
-</li>
-<li><p class="first"><a class="reference internal" href="#poldef">\poldef</a> and other defining macros prepare the polynomial
-functions for usage within <tt class="docutils literal">\xintthefloatexpr</tt> (or
-<tt class="docutils literal">\xintdeffloatvar</tt>). Coefficients are pre-rounded to the
-floating point precision. Indispensible for numerical algorithms,
-as exact fractions, even reduced, quickly become very big. See the
-documentation about how to use the exact polynomials also in
-floating point context.</p>
-<p><strong>Attention</strong>: this has been reverted at <tt class="docutils literal">0.4</tt>. The macro
-<a class="reference internal" href="#polgenfloatvariant">\PolGenFloatVariant</a> must be used for
-generation floating point polynomial functions.</p>
-</li>
-</ul>
-</li>
-</ul>
-</li>
-<li><p class="first">v0.3.1 (2018/01/18)</p>
-<p>Fixes two typos in example code included in the documentation.</p>
-</li>
-<li><p class="first">v0.4 (2018/02/16)</p>
-<ul>
-<li><p class="first">bug fixes:</p>
-<ul class="simple">
-<li>when Euclidean division gave a zero remainder, the internal
-representation of this zero polynomial could be faulty; this
-could cause mysterious bugs in conjunction with other package
-macros such as <a class="reference internal" href="#polmapcoeffs">\PolMapCoeffs</a>.</li>
-<li><a class="reference internal" href="#polgcd">\PolGCD</a> was buggy in case of first polynomial being
-of lesser degree than the second one.</li>
-</ul>
-</li>
-<li><p class="first">breaking changes:</p>
-<ul>
-<li><p class="first">formerly <a class="reference internal" href="#polevalat">\PolEval{P}\At{foo}</a> allowed <tt class="docutils literal">foo</tt> to
-be an expression, which was transparently handled via
-<tt class="docutils literal">\xinttheexpr</tt>. Now, <tt class="docutils literal">foo</tt> must be a fraction (or a macro
-expanding to such) in the format acceptable by <tt class="docutils literal">xintfrac.sty</tt>
-macros. Use <a class="reference internal" href="#polevalatexpr">\PolEval{P}\AtExpr{foo}</a> for more
-general arguments using expression syntax. E.g., if <tt class="docutils literal">foo</tt> is the
-name of a variable known to <tt class="docutils literal">\xintexpr</tt>.</p>
-<p>The same holds for <a class="reference internal" href="#polevalreducedat">\PolEvalReduced</a>
-and <a class="reference internal" href="#polfloatevalat">\PolFloatEval</a>.</p>
-</li>
-<li><p class="first">the <tt class="docutils literal">3.0</tt> automatic generation of floating point variants has
-been reverted. Not only do <em>not</em> the package macros automatically
-generate floating point variants of newly created polynomials,
-they actually make pre-existing such variant undefined.</p>
-<p>See <a class="reference internal" href="#polgenfloatvariant">\PolGenFloatVariant</a>.</p>
-</li>
-</ul>
-</li>
-<li><p class="first">new non-expandable macros:</p>
-<ul class="simple">
-<li><a class="reference internal" href="#polgenfloatvariant">\PolGenFloatVariant</a></li>
-<li><a class="reference internal" href="#polgloballet">\PolGlobalLet</a></li>
-<li><a class="reference internal" href="#poltypesetone">\PolTypesetOne</a></li>
-<li><a class="reference internal" href="#polquo">\PolQuo</a></li>
-<li><a class="reference internal" href="#polrem">\PolRem</a></li>
-<li><a class="reference internal" href="#poltosturm">\PolToSturm</a></li>
-<li><a class="reference internal" href="#id9">\PolToSturm*</a></li>
-<li><a class="reference internal" href="#polsettosturmchainsignchangesat">\PolSetToSturmChainSignChangesAt</a></li>
-<li><a class="reference internal" href="#polsettonbofzeroswithin">\PolSetToNbOfZerosWithin</a></li>
-<li><a class="reference internal" href="#polsturmisolatezeros">\PolSturmIsolateZeros</a></li>
-<li><a class="reference internal" href="#polrefineinterval">\PolRefineInterval*</a></li>
-<li><a class="reference internal" href="#polrefineinterval-n">\PolRefineInterval[N]</a></li>
-<li><a class="reference internal" href="#polensureintervallength">\PolEnsureIntervalLength</a></li>
-<li><a class="reference internal" href="#polensureintervallengths">\PolEnsureIntervalLengths</a></li>
-<li><a class="reference internal" href="#polprintintervals">\PolPrintIntervals</a></li>
-<li><a class="reference internal" href="#polprintintervalsprintexactzero">\PolPrintIntervalsPrintExactZero</a></li>
-<li><a class="reference internal" href="#polprintintervalsprintleftendpoint">\PolPrintIntervalsPrintLeftEndPoint</a></li>
-<li><a class="reference internal" href="#polprintintervalsprintrightendpoint">\PolPrintIntervalsPrintRightEndPoint</a></li>
-<li><a class="reference internal" href="#id20">\PolReduceCoeffs*</a></li>
-<li><a class="reference internal" href="#polmakemonic">\PolMakeMonic</a></li>
-</ul>
-</li>
-<li><p class="first">new expandable macros:</p>
-<ul class="simple">
-<li><a class="reference internal" href="#poltoexpronetermstylea">\PolToExprOneTermStyleA</a></li>
-<li><a class="reference internal" href="#polifcoeffisplusorminusone">\PolIfCoeffIsPlusOrMinusOne</a></li>
-<li><a class="reference internal" href="#polleadingcoeff">\PolLeadingCoeff</a></li>
-<li><a class="reference internal" href="#polsturmchainlength">\PolSturmChainLength</a></li>
-<li><a class="reference internal" href="#polsturmnbofisolatedzeros">\PolSturmNbOfIsolatedZeros</a></li>
-<li><a class="reference internal" href="#polsturmifzeroexactlyknown">\PolSturmIfZeroExactlyKnown</a></li>
-<li><a class="reference internal" href="#polsturmisolatedzeroleft">\PolSturmIsolatedZeroLeft</a></li>
-<li><a class="reference internal" href="#polsturmisolatedzeroright">\PolSturmIsolatedZeroRight</a></li>
-<li><tt class="docutils literal">\PolPrintIntervalsTheEndPoint</tt> (removed at 0.7)</li>
-<li><a class="reference internal" href="#polprintintervalstheindex">\PolPrintIntervalsTheIndex</a></li>
-<li><tt class="docutils literal">\PolIfEndPointIsPositive</tt> (removed at 0.7)</li>
-<li><tt class="docutils literal">\PolIfEndPointIsNegative</tt> (removed at 0.7)</li>
-<li><tt class="docutils literal">\PolIfEndPointIsZero</tt> (removed at 0.7)</li>
-<li><a class="reference internal" href="#polintervalwidth">\PolIntervalWidth</a></li>
-<li><a class="reference internal" href="#poldectostring">\PolDecToString</a></li>
-</ul>
-</li>
-<li><p class="first">improvements:</p>
-<p>The main new feature is implementation of the <a class="reference external" href="https://en.wikipedia.org/wiki/Sturm%27s_theorem">Sturm algorithm</a>
-for localization of the real roots of polynomials.</p>
-</li>
-</ul>
-</li>
-<li><p class="first">v0.4.1 (2018/03/01)</p>
-<p>Synced with xint 1.3.</p>
-</li>
-<li><p class="first">v0.4.2 (2018/03/03)</p>
-<p>Documentation fix.</p>
-</li>
-<li><p class="first">v0.5 (2018/04/08)</p>
-<ul class="simple">
-<li>bug fixes:<ul>
-<li><a class="reference internal" href="#polget-polname-fromarray-macro">\PolGet{polname}\fromarray\macro</a> crashed when <tt class="docutils literal">\macro</tt> was
-an <a class="reference external" href="http://www.ctan.org/pkg/xint">xinttools</a> array macro with no items. It now produces the zero
-polynomial.</li>
-</ul>
-</li>
-<li>breaking changes:<ul>
-<li><a class="reference internal" href="#poltosturm">\PolToSturm</a> creates primitive integer coefficients polynomials.
-This speeds up localization of roots via
-<a class="reference internal" href="#polsturmisolatezeros">\PolSturmIsolateZeros</a>. In case of user protests the author
-will make available again the code producing the bona fide Sturm
-polynomials as used formerly.</li>
-<li>polynomials created from <a class="reference internal" href="#polfromcsv">\PolFromCSV</a> or <a class="reference internal" href="#polget">\PolGet</a>
-get their coefficients normalized via <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a>'s <tt class="docutils literal">\xintRaw</tt>.</li>
-</ul>
-</li>
-<li>experimental change:<ul>
-<li>optional argument to <a class="reference internal" href="#polsturmisolatezeros">\PolSturmIsolateZeros</a> (see <a class="reference internal" href="#the-degree-41-polynomial-with-2-1-9-1-8-0-0-1-1-9-2-as-roots">The
-degree 41 polynomial with -2, -1.9, -1.8, ..., 0, 0.1, ..., 1.9, 2
-as roots</a> for usage). It will presumably be replaced in future by
-an interval specification.</li>
-</ul>
-</li>
-<li>new non-expandable macro:<ul>
-<li><a class="reference internal" href="#polmakeprimitive">\PolMakePrimitive</a></li>
-</ul>
-</li>
-<li>new expandable macro:<ul>
-<li><a class="reference internal" href="#policontent">\PolIContent</a></li>
-</ul>
-</li>
-</ul>
-</li>
-<li><p class="first">v0.5.1 (2018/04/22)</p>
-<ul class="simple">
-<li>new feature:<ul>
-<li>the character <tt class="docutils literal">'</tt> can be used in polynomial names.</li>
-</ul>
-</li>
-</ul>
-</li>
-<li><p class="first">v0.6 (2018/11/20)</p>
-<ul class="simple">
-<li>bugfix:<ul>
-<li>the starred variant <a class="reference internal" href="#id10">\PolToSturm*{polname}{sturmname}</a> was
-broken. On the occasion of the fix, its meaning has been modified,
-see its documentation.</li>
-<li>using <a class="reference internal" href="#poltosturm">\PolToSturm</a> with a constant polynomial
-caused a division by zero error.</li>
-</ul>
-</li>
-<li>new macro:<ul>
-<li><a class="reference internal" href="#id11">\PolSturmIsolateZeros*</a>
-acts like the <a class="reference internal" href="#polsturmisolatezeros">non-starred variant</a> then computes all the multiplicities.</li>
-</ul>
-</li>
-<li>new expandable macros:<ul>
-<li><a class="reference internal" href="#polsturmisolatedzeromultiplicity-sturmname-index">\PolSturmIsolatedZeroMultiplicity{sturmname}{index}</a></li>
-<li><a class="reference internal" href="#polsturmnbofrootsof-sturmname-lessthanorequalto-value">\PolSturmNbOfRootsOf{sturmname}\LessThanOrEqualTo{value}</a></li>
-<li><a class="reference internal" href="#polsturmnbofrootsof-sturmname-lessthanorequaltoexpr-expression">\PolSturmNbOfRootsOf{sturmname}\LessThanOrEqualToExpr{expression}</a></li>
-<li><a class="reference internal" href="#polsturmnbwithmultofrootsof-sturmname-lessthanorequalto-value">\PolSturmNbWithMultOfRootsOf{sturmname}\LessThanOrEqualTo{value}</a></li>
-<li><a class="reference internal" href="#polsturmnbwithmultofrootsof-sturmname-lessthanorequaltoexpr-expression">\PolSturmNbWithMultOfRootsOf{sturmname}\LessThanOrEqualToExpr{expression}</a></li>
-</ul>
-</li>
-</ul>
-</li>
-<li><p class="first">v0.7 (2018/12/08), v0.7.1 (bugfix), v0.7.2 (2nd bugfix) (2018/12/09)</p>
-<ul class="simple">
-<li>breaking changes:<ul>
-<li>although <a class="reference internal" href="#polprintintervals-varname-sturmname">\PolPrintIntervals[varname]{sturmname}</a> default output
-remains the same, some auxiliary macros for user-customization
-have been removed: <tt class="docutils literal">\PolPrintIntervalsTheEndPoint</tt>,
-<tt class="docutils literal"><span class="pre">\PolIfEndPointIsPositive{A}{B}</span></tt>,
-<tt class="docutils literal"><span class="pre">\PolIfEndPointIsNegative{A}{B}</span></tt>, and
-<tt class="docutils literal"><span class="pre">\PolIfEndPointIsZero{A}{B}</span></tt>.</li>
-</ul>
-</li>
-<li>bugfix:<ul>
-<li>it could happen that, contrarily to documentation, an interval
-computed by <a class="reference internal" href="#polsturmisolatezeros-sturmname">\PolSturmIsolateZeros{sturmname}</a> had zero as an
-endpoint,</li>
-<li><a class="reference internal" href="#polensureintervallength-sturmname-index-e">\PolEnsureIntervalLength{sturmname}{index}{E}</a> could under
-certain circumstances erroneously replace a non-zero root by
-zero,</li>
-<li><a class="reference internal" href="#polensureintervallengths-sturmname-e">\PolEnsureIntervalLengths{sturmname}{E}</a> crashed when used with
-a polynomial with no real roots, hence for which no isolation intervals
-existed (thanks to Thomas Söll for report).</li>
-</ul>
-</li>
-<li>new macros:<ul>
-<li><a class="reference internal" href="#id14">\PolSturmIsolateZeros**{sturmname}</a></li>
-<li><a class="reference internal" href="#polsturmisolatezerosgetmultiplicitiesandrationalroots-sturmname">\PolSturmIsolateZerosGetMultiplicitiesAndRationalRoots{sturmname}</a></li>
-<li><a class="reference internal" href="#polsturmisolatezerosandfindrationalroots-sturmname">\PolSturmIsolateZerosAndFindRationalRoots{sturmname}</a></li>
-<li><a class="reference internal" href="#polexprsetup">\polexprsetup</a></li>
-<li><a class="reference internal" href="#id18">\PolPrintIntervals*</a></li>
-<li><a class="reference internal" href="#polprintintervalsnorealroots">\PolPrintIntervalsNoRealRoots</a></li>
-<li><a class="reference internal" href="#polprintintervalsbeginenv">\PolPrintIntervalsBeginEnv</a></li>
-<li><a class="reference internal" href="#polprintintervalsendenv">\PolPrintIntervalsEndEnv</a></li>
-<li><a class="reference internal" href="#polprintintervalsknownroot">\PolPrintIntervalsKnownRoot</a></li>
-<li><a class="reference internal" href="#polprintintervalsunknownroot">\PolPrintIntervalsUnknownRoot</a></li>
-<li><a class="reference internal" href="#polprintintervalsprintmultiplicity">\PolPrintIntervalsPrintMultiplicity</a></li>
-</ul>
-</li>
-<li>new expandable macros:<ul>
-<li><a class="reference internal" href="#polsturmnbofrationalroots-sturmname">\PolSturmNbOfRationalRoots{sturmname}</a></li>
-<li><a class="reference internal" href="#polsturmnbofrationalrootswithmultiplicities-sturmname">\PolSturmNbOfRationalRootsWithMultiplicities{sturmname}</a></li>
-<li><a class="reference internal" href="#polsturmrationalroot-sturmname-k">\PolSturmRationalRoot{sturmname}{k}</a></li>
-<li><a class="reference internal" href="#polsturmrationalrootindex-sturmname-k">\PolSturmRationalRootIndex{sturmname}{k}</a></li>
-<li><a class="reference internal" href="#polsturmrationalrootmultiplicity-sturmname-k">\PolSturmRationalRootMultiplicity{sturmname}{k}</a></li>
-<li><a class="reference internal" href="#polprintintervalsthevar">\PolPrintIntervalsTheVar</a></li>
-<li><a class="reference internal" href="#polprintintervalsthesturmname">\PolPrintIntervalsTheSturmName</a></li>
-<li><a class="reference internal" href="#polprintintervalsthemultiplicity">\PolPrintIntervalsTheMultiplicity</a></li>
-</ul>
-</li>
-</ul>
-</li>
-<li><p class="first">v0.7.3 (2019/02/04)</p>
-<ul class="simple">
-<li>bugfix:<ul>
-<li>Debugging information not destined to user showed in log if root
-finding was done under <tt class="docutils literal">\xintverbosetrue</tt> regime.</li>
-<li><a class="reference internal" href="#polprintintervalsthevar">\PolPrintIntervalsTheVar</a> remained defined after
-<a class="reference internal" href="#polprintintervals">\PolPrintIntervals</a> but was left undefined after
-<a class="reference internal" href="#id18">\PolPrintIntervals*</a> (reported by Jürgen Gilg). Now remains
-defined in both cases, and <a class="reference internal" href="#polprintintervalsthesturmname">\PolPrintIntervalsTheSturmName</a>
-also.</li>
-<li>Polynomial names ending in digits caused errors (reported by Thomas
-Söll).</li>
-</ul>
-</li>
-</ul>
-</li>
-<li><p class="first">v0.7.4 (2019/02/12)</p>
-<ul class="simple">
-<li>bugfix:<ul>
-<li>20000000000 is too big for <tt class="docutils literal">\numexpr</tt>, shouldn't I know that?
-Thanks to Jürgen Gilg for report.</li>
-</ul>
-</li>
-</ul>
-</li>
-<li><p class="first">v0.7.5 (2020/01/31)</p>
-<p>Synced with xint 1.4. Requires it.</p>
-</li>
-</ul>
-</div>
-<div class="section" id="acknowledgments">
-<h1><a class="toc-backref" href="#id160">Acknowledgments</a></h1>
-<p>Thanks to Jürgen Gilg whose question about <a class="reference external" href="http://www.ctan.org/pkg/xint">xint</a> usage for
-differentiating polynomials was the initial trigger leading to this
-package, and to Jürgen Gilg and Thomas Söll for testing it on some
-concrete problems.</p>
-<p>Renewed thanks to them on occasion of the <tt class="docutils literal">0.6</tt> and <tt class="docutils literal">0.7</tt> releases for their
-continued interest.</p>
-<p>See README.md for the License.</p>
-</div>
-</div>
-</body>
-</html>
diff --git a/macros/latex/contrib/polexpr/polexpr.txt b/macros/latex/contrib/polexpr/polexpr.txt
deleted file mode 100644
index 898375926b..0000000000
--- a/macros/latex/contrib/polexpr/polexpr.txt
+++ /dev/null
@@ -1,2598 +0,0 @@
-.. comment: -*- fill-column: 72; mode: rst; -*-
-
-===============================
- Package polexpr documentation
-===============================
-
-0.7.5 (2020/01/31)
-==================
-
-.. contents::
-
-Basic syntax
-------------
-
-The syntax is::
-
- \poldef polname(x):= expression in variable x;
-
-where:
-
-- in place of ``x`` an arbitrary *dummy variable* is authorized,
- i.e. per default any of ``[a-z|A-Z]`` (more letters can be declared
- under Unicode engines.)
-
-- ``polname`` consists of letters, digits, and the ``_`` and
- ``'`` characters. It must start with a letter.
-
-.. attention::
-
- The ``'`` is authorized since ``0.5.1``. As a result some constructs
- recognized by the ``\xintexpr`` parser, such as ``var1 'and' var2``
- will get misinterpreted and cause errors. However these constructs
- are unlikely to be frequently needed in polynomial expressions, and
- the ``\xintexpr`` syntax offers alternatives, so it was deemed a
- small evil. Of course the ``\xintexpr`` parser is modified only
- temporarily during execution of ``\poldef``.
-
-One can also issue::
-
- \PolDef{polname}{expression in variable x}
-
-which admits an optional first argument to modify the variable letter
-from its default ``x``.
-
-``\poldef f(x):= 1-x+x^2;``
- defines polynomial ``f``. Polynomial names must start with a
- letter and may contain letters, digits, underscores and the right
- tick character. The
- variable must be a single letter. The colon character is optional.
- The semi-colon at end of expression is mandatory.
-
-``\PolDef{f}{1-x+x^2}``
- does the same as ``\poldef f(x):= 1-x+x^2;`` To use another letter
- than ``x`` in the expression, one must pass it as an extra optional
- argument to ``\PolDef``. Useful if the semi-colon has been assigned
- some non-standard catcode by some package.
-
-``\PolLet{g}={f}``
- saves a copy of ``f`` under name ``g``. Also usable without ``=``.
-
-``\poldef f(z):= f(z)^2;``
- redefines ``f`` in terms of itself.
-
-``\poldef f(T):= f(f(T));``
- again redefines ``f`` in terms of its (new) self.
-
-``\poldef k(z):= f(z)-g(g(z)^2)^2;``
- should now define the zero polynomial... Let's check:
- ``\[ k(z) = \PolTypeset[z]{k} \]``
-
-``\PolDiff{f}{f'}``
- sets ``f'`` to the derivative of ``f``. The name doesn't have to be
- ``f'`` (in fact the ``'`` is licit only since ``0.5.1``).
-
-.. important::
-
- This is not done automatically. If some new definition needs to use
- the derivative of some available polynomial, that derivative
- polynomial must have been defined via ``\PolDiff``: something like
- ``T'(x)^2`` will not work without a prior ``\PolDiff{T}{T'}``.
-
-``\PolDiff{f'}{f''}``
- obtains second derivative.
-
-``\PolDiff[3]{f}{f'''}``
- computes the third derivative.
-
-::
-
- $f(z) = \PolTypeset[z]{f} $\newline
- $f'(z) = \PolTypeset[z]{f'} $\newline
- $f''(z) = \PolTypeset[z]{f''} $\newline
- $f'''(z)= \PolTypeset[z]{f'''} $\par
-
-.. important::
-
- The package does not currently know rational functions: ``/`` in
- a parsed polynomial expression does the Euclidean quotient::
-
- (1-x^2)/(1-x)
-
- does give ``1+x`` but ::
-
- (1/(1-x))*(1-x^2)
-
- evaluates to zero. This will work as expected::
-
- \poldef k(x):= (x-1)(x-2)(x-3)(x-4)/(x^2-5x+4);
-
-.. _warningtacit:
-
-.. attention::
-
- ``1/2 x^2`` skips the space and is treated like ``1/(2*x^2)`` because
- of the tacit multiplication rules of \xintexpr. But this means it
- gives zero! Thus one must use ``(1/2)x^2`` or ``1/2*x^2`` or
- ``(1/2)*x^2`` for disambiguation: ``x - 1/2*x^2 + 1/3*x^3...``. It is
- even simpler to move the denominator to the right: ``x - x^2/2 +
- x^3/3 - ...``.
-
- It is worth noting that ``1/2(x-1)(x-2)`` suffers the same issue:
- xint_ tacit multiplication always "ties more", hence this gets
- interpreted as ``1/(2*(x-1)*(x-2))`` which gives zero by polynomial
- division. Thus, use one of ``(1/2)(x-1)(x-2)``, ``1/2*(x-1)(x-2)`` or
- ``(x-1)(x-2)/2``.
-
-After::
-
- \poldef f_1(x):= 25(x-1)(x^2-2)(x-3)(x-4)(x-5);%
- \poldef f_2(x):= 37(x-1)(x^2-2)(x-6)(x-7)(x-8);%
-
-the macro call ``\PolGCD{f_1}{f_2}{k}`` sets ``k`` to the (unitary) GCD of
-``f_1`` and ``f_2`` (hence to the expansion of ``(x-1)(x^2-2)``.)
-
-``\PolToExpr{k}``
- will (expandably) give in this case ``x^3-x^2-2*x+2``. This is
- useful for console or file output (the syntax is Maple- and
- PSTricks-compatible; the letter used in output can be
- (non-expandably) changed via a redefinition of `\\PolToExprVar`_.)
-
-``\PolToExpr*{k}``
- gives ascending powers: ``2-2*x-x^2+x^3``.
-
-Examples of localization of roots
----------------------------------
-
-- To make printed decimal numbers more enjoyable than via
- ``\xintSignedFrac``::
-
- \renewcommand\PolTypesetOne[1]{\PolDecToString{\xintREZ{#1}}}%
-
- ``\PolDecToString`` will use decimal notation to incorporate the power
- of ten part; and the ``\xintREZ`` will have the effect to suppress
- trailing zeros if present in raw numerator (if those digits end up
- after decimal mark.) Notice that the above are expandable macros and
- that one can also do::
-
- \renewcommand\PolToExprCmd[1]{\PolDecToString{\xintREZ{#1}}}%
-
- to modify output of `\\PolToExpr{polname}`_.
-
-- For extra info in log file use ``\xintverbosetrue``.
-
-- Only for some of these examples is the output included here.
-
-
-A typical example
-~~~~~~~~~~~~~~~~~
-
-In this example the polynomial is square-free.
-
-::
-
- \poldef f(x) := x^7 - x^6 - 2x + 1;
-
- \PolToSturm{f}{f}
- \PolSturmIsolateZeros{f}
- The \PolTypeset{f} polynomial has \PolSturmNbOfIsolatedZeros{f} distinct real
- roots which are located in the following intervals:
- \PolPrintIntervals{f}
- Here is the second root with ten more decimal digits:
- \PolRefineInterval[10]{f}{2}
- \[\PolSturmIsolatedZeroLeft{f}{2}<Z_2<\PolSturmIsolatedZeroRight{f}{2}\]
- And here is the first root with twenty digits after decimal mark:
- \PolEnsureIntervalLength{f}{1}{-20}
- \[\PolSturmIsolatedZeroLeft{f}{1}<Z_1<\PolSturmIsolatedZeroRight{f}{1}\]
- The first element of the Sturm chain has degree $\PolDegree{f_0}$. As
- this is the original degreee $\PolDegree{f}$ we know that $f$ is square free.
- Its derivative is up to a constant \PolTypeset{f_1} (in this example
- it is identical with it).
- \PolToSturm{f_1}{f_1}\PolSturmIsolateZeros{f_1}%
- The derivative has \PolSturmNbOfIsolatedZeros{f_1} distinct real
- roots:
- \PolPrintIntervals[W]{f_1}
- \PolEnsureIntervalLengths{f_1}{-10}%
- Here they are with ten digits after decimal mark:
- \PolPrintIntervals[W]{f_1}
- \PolDiff{f_1}{f''}
- \PolToSturm{f''}{f''}
- \PolSturmIsolateZeros{f''}
- The second derivative is \PolTypeset{f''}.
- It has \PolSturmNbOfIsolatedZeros{f''} distinct real
- roots:
- \PolPrintIntervals[X]{f''}
- Here is the positive one with 20 digits after decimal mark:
- \PolEnsureIntervalLength{f''}{2}{-20}%
- \[X_2 = \PolSturmIsolatedZeroLeft{f''}{2}\dots\]
- The more mathematically advanced among our dear readers will be able
- to give the exact value for $X_2$!
-
-A degree four polynomial with nearby roots
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Notice that this example is a bit outdated as ``0.7`` release has
-added ``\PolSturmIsolateZeros**{sturmname}`` which would find exactly
-the roots. The steps here retain their interest when one is interested
-in finding isolating intervals for example to prepare some demonstration
-of dichotomy method.
-
-
-::
-
- \PolDef{Q}{(x-1.050001)(x-1.105001)(x-1.110501)(x-1.111051)}
- \PolTypeset{Q}
- \PolToSturm{Q}{Q} % it is allowed to use same prefix for Sturm chain
- \PolSturmIsolateZeros{Q}
- \PolPrintIntervals{Q}
- % reports 1.0 < Z_1 < 1.1, 1.10 < Z_2 < 1.11, 1.110 < Z_3 < 1.111, and 1.111 < Z_4 < 1.112
- % but the above bounds do not allow minimizing separation between roots
- % so we refine:
- \PolRefineInterval*{Q}{1}
- \PolRefineInterval*{Q}{2}
- \PolRefineInterval*{Q}{3}
- \PolRefineInterval*{Q}{4}
- \PolPrintIntervals{Q}
- % reports 1.05 < Z_1 < 1.06, 1.105 < Z_2 < 1.106, 1.1105 < Z_3 < 1.1106,
- % and 1.11105 < Z_4 < 1.11106.
- \PolEnsureIntervalLengths{Q}{-6}
- \PolPrintIntervals{Q}
- % of course finds here all roots exactly
-
-
-The degree nine polynomial with 0.99, 0.999, 0.9999 as triple roots
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- % define a user command (xinttools is loaded automatically by polexpr)
- \newcommand\showmultiplicities[1]{% #1 = "sturmname"
- \xintFor* ##1 in {\xintSeq{1}{\PolSturmNbOfIsolatedZeros{#1}}}\do{%
- The multiplicity is \PolSturmIsolatedZeroMultiplicity{#1}{##1}
- \PolSturmIfZeroExactlyKnown{#1}{##1}%
- {at the root $x=\PolSturmIsolatedZeroLeft{#1}{##1}$}
- {for the root such that
- $\PolSturmIsolatedZeroLeft{#1}{##1}<x<\PolSturmIsolatedZeroRight{#1}{##1}$}
- \par
- }}%
- \PolDef{f}{(x-0.99)^3(x-0.999)^3(x-0.9999)^3}
- \renewcommand\PolTypesetOne[1]{\PolDecToString{\xintREZ{#1}}}
- \PolTypeset{f}\par
- \PolToSturm{f}{f}% it is allowed to use "polname" as "sturmname" too
- \PolSturmIsolateZerosAndGetMultiplicities{f}% use the "sturmname" here
- % or \PolSturmIsolateZeros*{f} which is exactly the same, but shorter..
-
- \showmultiplicities{f}
-
-In this example, the output will look like this (but using math mode)::
-
- x^9 - 8.9667x^8 + 35.73400293x^7 - 83.070418400109x^6 + 124.143648875193123x^5
- - 123.683070924326075877x^4 + 82.149260397553075617891x^3
- - 35.07602992699900159127007x^2 + 8.7364078733314648368671733x
- - 0.967100824643585986488103299
-
- The multiplicity is 3 at the root x = 0.99
- The multiplicity is 3 at the root x = 0.999
- The multiplicity is 3 at the root x = 0.9999
-
-On first pass, these rational roots were found (due to their relative
-magnitudes, using ``\PolSturmIsolateZeros**`` was not needed here). But
-multiplicity computation works also with (decimal) roots not yet
-identified or with non-decimal or irrational roots.
-
-It is fun to modify only a tiny bit the polynomial and see if polexpr
-survives::
-
- \PolDef{g}{f(x)+1e-27}
- \PolTypeset{g}\par
- \PolToSturm{g}{g}
- \PolSturmIsolateZeros*{g}
-
- \showmultiplicities{g}
-
-This produces::
-
- x^9 - 8.9667x^8 + 35.73400293x^7 - 83.070418400109x^6 + 124.143648875193123x^5
- - 123.683070924326075877x^4 + 82.149260397553075617891x^3
- - 35.07602992699900159127007x^2 + 8.7364078733314648368671733x
- - 0.967100824643585986488103298
-
- The multiplicity is 1 for the root such that 0.98 < x < 0.99
- The multiplicity is 1 for the root such that 0.9991 < x < 0.9992
- The multiplicity is 1 for the root such that 0.9997 < x < 0.9998
-
-Which means that the multiplicity-3 roots each became a real and a pair of
-complex ones. Let's see them better::
-
- \PolEnsureIntervalLengths{g}{-10}
-
- \showmultiplicities{g}
-
-which produces::
-
- The multiplicity is 1 for the root such that 0.9899888032 < x < 0.9899888033
- The multiplicity is 1 for the root such that 0.9991447980 < x < 0.9991447981
- The multiplicity is 1 for the root such that 0.9997663986 < x < 0.9997663987
-
-A degree five polynomial with three rational roots
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- \poldef Q(x) := 1581755751184441 x^5
- -14907697165025339 x^4
- +48415668972339336 x^3
- -63952057791306264 x^2
- +46833913221154895 x
- -49044360626280925;
-
- \PolToSturm{Q}{Q}
- %\begin{flushleft}
- \renewcommand\PolTypesetCmdPrefix[1]{\allowbreak\xintiiifSgn{#1}{}{+}{+}}%
- $Q_0(x) = \PolTypeset{Q_0}$
- %\end{flushleft}
- \PolSturmIsolateZeros**{Q}
- \PolPrintIntervals{Q}
-
- $Q_{norr}(x) = \PolTypeset{Q_norr}$
-
-Here, all real roots are rational::
-
- Z_1 = 833719/265381
- Z_2 = 165707065/52746197
- Z_3 = 355/113
-
- Q_norr(x) = x^2 + 1
-
-And let's get their decimal expansion too::
-
- % print decimal expansion of the found roots
- \renewcommand\PolPrintIntervalsPrintExactZero
- {\xintTrunc{20}{\PolPrintIntervalsTheLeftEndPoint}\dots}
- \PolPrintIntervals{Q}
-
- Z_1 = 3.14159265358107777120...
- Z_2 = 3.14159265358979340254...
- Z_3 = 3.14159292035398230088...
-
-
-A Mignotte type polynomial
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- \PolDef{P}{x^10 - (10x-1)^2}%
- \PolTypeset{P} % prints it in expanded form
- \PolToSturm{P}{P} % we can use same prefix for Sturm chain
- \PolSturmIsolateZeros{P} % finds 4 real roots
- This polynomial has \PolSturmNbOfIsolatedZeros{P} distinct real roots:
- \PolPrintIntervals{P}%
- % reports -2 < Z_1 < -1, 0.09 < Z_2 < 0.10, 0.1 < Z_3 < 0.2, 1 < Z_4 < 2
- Let us refine the second and third intervals to separate the corresponding
- roots:
- \PolRefineInterval*{P}{2}% will refine to 0.0999990 < Z_2 < 0.0999991
- \PolRefineInterval*{P}{3}% will refine to 0.100001 < Z_3 < 0.100002
- \PolPrintIntervals{P}%
- Let us now get to know all roots with 10 digits after decimal mark:
- \PolEnsureIntervalLengths{P}{-10}%
- \PolPrintIntervals{P}% now all roots are known 10 decimal digits after mark
- Finally, we display 20 digits of the second root:
- \PolEnsureIntervalLength{P}{2}{-20}% makes Z_2 known with 20 digits after mark
- \[\PolSturmIsolatedZeroLeft{P}{2}<Z_2<\PolSturmIsolatedZeroRight{P}{2}\]
-
-The last line produces::
-
- 0.09999900004999650028 < Z_2 < 0.09999900004999650029
-
-
-The Wilkinson polynomial
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-See `Wilkinson polynomial`_.
-
-::
-
- \documentclass{article}
- \usepackage{polexpr}
- \begin{document}
- %\xintverbosetrue % for the curious...
-
- \poldef f(x) := mul((x - i), i = 1..20);
-
- \renewcommand\PolTypesetCmdPrefix[1]{\allowbreak\xintiiifSgn{#1}{}{+}{+}}%
- \renewcommand\PolTypesetOne[1]{\xintDecToString{#1}}%
-
- \noindent\PolTypeset{f}
-
- \PolToSturm{f}{f}
- \PolSturmIsolateZeros{f}
- \PolPrintIntervals{f}
-
- \clearpage
-
- \poldef g(x) := f(x) - 2**{-23} x**19;
-
- % be patient!
- \PolToSturm{g}{g}
- \noindent\PolTypeset{g_0}% integer coefficient primitive polynomial
-
- \PolSturmIsolateZeros{g}
- \PolEnsureIntervalLengths{g}{-10}
-
- \renewcommand\PolPrintIntervalsPrintMultiplicity{}
- \PolPrintIntervals*{g}
-
- \end{document}
-
-
-The first polynomial::
-
- f(x) = x**20
- - 210 x**19
- + 20615 x**18
- - 1256850 x**17
- + 53327946 x**16
- - 1672280820 x**15
- + 40171771630 x**14
- - 756111184500 x**13
- + 11310276995381 x**12
- - 135585182899530 x**11
- + 1307535010540395 x**10
- - 10142299865511450 x**9
- + 63030812099294896 x**8
- - 311333643161390640 x**7
- + 1206647803780373360 x**6
- - 3599979517947607200 x**5
- + 8037811822645051776 x**4
- - 12870931245150988800 x**3
- + 13803759753640704000 x**2
- - 8752948036761600000 x
- + 2432902008176640000
-
-is handled fast enough (a few seconds), but the modified one ``f(x) -
-2**-23 x**19`` takes about 20x longer (the Sturm chain polynomials
-have integer coefficients with up to 321 digits, whereas (surprisingly
-perhaps) those of the Sturm chain polynomials derived from ``f`` never
-have more than 21 digits ...).
-
-Once the Sturm chain is computed and the zeros isolated, obtaining their
-decimal digits is relatively faster. Here is for the ten real roots of
-``f(x) - 2**-23 x**19`` as computed by the code above::
-
- Z_1 = 0.9999999999...
- Z_2 = 2.0000000000...
- Z_3 = 2.9999999999...
- Z_4 = 4.0000000002...
- Z_5 = 4.9999999275...
- Z_6 = 6.0000069439...
- Z_7 = 6.9996972339...
- Z_8 = 8.0072676034...
- Z_9 = 8.9172502485...
- Z_10 = 20.8469081014...
-
-The second Wilkinson polynomial
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- \documentclass{article}
- \usepackage{polexpr}
- \begin{document}
- \poldef f(x) := mul(x - 2^-i, i = 1..20);
-
- %\PolTypeset{f}
-
- \PolToSturm{f}{f}
- \PolSturmIsolateZeros**{f}
- \PolPrintIntervals{f}
- \end{document}
-
-This takes more time than the polynomial with 1, 2, .., 20 as roots but
-less than the latter modified by the ``2**-23`` change in one
-coefficient.
-
-Here is the output (with release 0.7.2)::
-
- Z_1 = 0.00000095367431640625
- Z_2 = 0.0000019073486328125
- Z_3 = 0.000003814697265625
- Z_4 = 0.00000762939453125
- Z_5 = 0.0000152587890625
- Z_6 = 0.000030517578125
- Z_7 = 0.00006103515625
- Z_8 = 0.0001220703125
- Z_9 = 1/4096
- Z_10 = 1/2048
- Z_11 = 1/1024
- Z_12 = 1/512
- Z_13 = 1/256
- Z_14 = 1/128
- Z_15 = 0.015625
- Z_16 = 0.03125
- Z_17 = 0.0625
- Z_18 = 0.125
- Z_19 = 0.25
- Z_20 = 0.5
-
-There is some incoherence in output format which has its source in the
-fact that some roots are found in branches which can only find decimal
-roots, whereas some are found in branches which could find general
-fractions and they use ``\xintIrr`` before storage of the found root.
-This may evolve in future.
-
-
-The degree 41 polynomial with -2, -1.9, -1.8, ..., 0, 0.1, ..., 1.9, 2 as roots
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- \PolDef{P}{mul((x-i*1e-1), i=-20..20)}% i/10 is same but less efficient
-
-In the defining expression we could have used ``i/10`` but this gives
-less efficient internal form for the coefficients (the ``10``'s end up
-in denominators). Using ``\PolToExpr{P}`` after having done
-
-::
-
- \renewcommand\PolToExprCmd[1]{\PolDecToString{\xintREZ{#1}}}
-
-we get this expanded form::
-
- x^41
- -28.7*x^39
- +375.7117*x^37
- -2975.11006*x^35
- +15935.28150578*x^33
- -61167.527674162*x^31
- +173944.259366417394*x^29
- -373686.963560544648*x^27
- +613012.0665016658846445*x^25
- -771182.31133138163125495*x^23
- +743263.86672885754888959569*x^21
- -545609.076599482896371978698*x^19
- +301748.325708943677229642930528*x^17
- -123655.8987669450434698869844544*x^15
- +36666.1782054884005855608205864192*x^13
- -7607.85821367459445649518380016128*x^11
- +1053.15135918687298508885950223794176*x^9
- -90.6380005918141132650786081964032*x^7
- +4.33701563847327366842552218288128*x^5
- -0.0944770968420804735498178265088*x^3
- +0.00059190121813899276854174416896*x
-
-which shows coefficients with up to 36 significant digits...
-
-Stress test: not a hard challenge to ``xint + polexpr``, but be a bit patient!
-
-::
-
- \PolDef{P}{mul((x-i*1e-1), i=-20..20)}%
- \PolToSturm{P}{S} % dutifully computes S_0, ..., S_{41}
- % the [1] optional argument limits the search to interval (-10,10)
- \PolSturmIsolateZeros[1]{S} % finds *exactly* (but a bit slowly) all 41 roots!
- \PolPrintIntervals{S} % nice, isn't it?
-
-.. note::
-
- Release ``0.5`` has *experimental* addition of optional argument
- ``E`` to ``\PolSturmIsolateZeros``. It instructs to search roots only
- in interval ``(-10^E, 10^E)``. Important: the extremities are
- *assumed to not be roots*. In this example, the ``[1]`` in
- ``\PolSturmIsolateZeros[1]{S}`` gives some speed gain; without it, it
- turns out in this case that ``polexpr`` would have started with
- ``(-10^6, 10^6)`` interval.
-
- Please note that this will probably get replaced in future by the
- specification of a general interval. Do not rely on meaning of this
- optional argument keeping the same.
-
-Roots of Chebyshev polynomials
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- \newcount\mycount
- \poldef T_0(x) := 1;
- \poldef T_1(x) := x;
- \mycount 2
- \xintloop
- \poldef T_\the\mycount(x) :=
- 2x*T_\the\numexpr\mycount-1(x)
- - T_\the\numexpr\mycount-2(x);
- \ifnum\mycount<15
- \advance\mycount 1
- \repeat
-
- \[T_{15} = \PolTypeset[X]{T_15}\]
- \PolToSturm{T_15}{T_15}
- \PolSturmIsolateZeros{T_15}
- \PolEnsureIntervalLengths{T_15}{-10}
- \PolPrintIntervals{T_15}
-
-
-Non-expandable macros
----------------------
-
-.. _poldef;:
-
-``\poldef polname(letter):= expression in letter;``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- This evaluates the *polynomial expression* and stores the coefficients
- in a private structure accessible later via other package macros,
- under the user-chosen ``polname``. Of course the *expression* can
- use other previously defined polynomials. Names must start with a
- letter and are constituted of letters, digits, underscores and
- (since ``0.5.1``) the right tick ``'``.
- The whole xintexpr_ syntax is authorized::
-
- \poldef sin(z) := add((-1)^i z^(2i+1)/(2i+1)!, i = 0..10);
-
- With fractional coefficients, beware the `tacit multiplication issue
- <warningtacit_>`_.
-
- As a side effect the function ``polname()`` is recognized as a
- genuine ``\xintexpr...\relax`` function for (exact) numerical
- evaluation (or within an ``\xintdefvar`` assignment.) It computes
- values not according to the original expression but via the Horner
- scheme corresponding to the polynomial coefficients.
-
- .. attention::
-
- Release ``0.3`` also did the necessary set-up to let the
- polynomial be known to the ``\xintfloatexpr`` (or
- ``\xintdeffloatvar``) parser.
-
- Since ``0.4`` this isn't done automatically. Even more, a
- previously existing floating point variant of the same name will
- be let undefined again, to avoid hard to debug mismatches between
- exact and floating point polynomials. This also applies when the
- polynomial is produced not via ``\poldef`` or ``\PolDef`` but as
- a product of the other package macros.
-
- See `\\PolGenFloatVariant{polname}`_.
-
- The original expression is lost after parsing, and in particular
- the package provides no way to typeset it. This has to be done
- manually, if needed.
-
-.. _PolDef:
-
-``\PolDef[letter]{polname}{expression in letter}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Does the same as `\\poldef <poldef;>`_ in an undelimited macro
- format (thus avoiding potential problems with the catcode of the
- semi-colon in presence of some packages.) In absence of the
- ``[letter]`` optional argument, the variable is assumed to be ``x``.
-
-.. _PolGenFloatVariant:
-
-``\PolGenFloatVariant{polname}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Makes the polynomial also usable in the ``\xintfloatexpr`` parser.
- It will therein evaluates via an Horner scheme with coefficients
- already pre-rounded to the float precision.
-
- See also `\\PolToFloatExpr{polname}`_.
-
- .. attention::
-
- Release ``0.3`` did this automatically on ``\PolDef`` and
- ``\poldef`` but this was removed at ``0.4`` for optimization.
-
- Any operation, for example generating the derivative polynomial,
- or dividing two polynomials or using the ``\PolLet``, **must** be
- followed by explicit usage of ``\PolGenFloatVariant{polname}`` if
- the new polynomial is to be used in ``\xintfloatexpr`` or alike
- context.
-
-.. _PolLet:
-
-``\PolLet{polname_2}={polname_1}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Makes a copy of the already defined polynomial ``polname_1`` to a
- new one ``polname_2``. Same effect as
- ``\PolDef{polname_2}{polname_1(x)}`` but with less overhead. The
- ``=`` is optional.
-
-.. _PolGlobalLet:
-
-``\PolGlobalLet{polname_2}={polname_1}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Acts globally.
-
-.. _PolAssign:
-
-``\PolAssign{polname}\toarray\macro``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Defines a one-argument expandable macro ``\macro{#1}`` which expands
- to the (raw) #1th polynomial coefficient.
-
- - Attention, coefficients here are indexed starting at 1.
-
- - With #1=-1, -2, ..., ``\macro{#1}`` returns leading coefficients.
-
- - With #1=0, returns the number of coefficients, i.e. ``1 + deg f``
- for non-zero polynomials.
-
- - Out-of-range #1's return ``0/1[0]``.
-
- See also `\\PolNthCoeff{polname}{number}`_. The main difference is that
- with ``\PolAssign``, ``\macro`` is made a prefix to ``1 + deg f``
- already defined (hidden to user) macros holding individually the
- coefficients but `\\PolNthCoeff{polname}{number}`_ does each time the job
- to expandably recover the ``Nth`` coefficient, and due to
- expandability can not store it in a macro for future usage (of course,
- it can be an argument in an ``\edef``.) The other difference
- is the shift by one in indexing, mentioned above (negative
- indices act the same in both.)
-
-.. _PolGet:
-
-``\PolGet{polname}\fromarray\macro``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Does the converse operation to
- ``\PolAssign{polname}\toarray\macro``. Each individual
- ``\macro{number}`` gets expanded in an ``\edef`` and then normalized
- via xintfrac_\ 's macro ``\xintRaw``.
-
- The leading zeros are removed from the polynomial.
-
- (contrived) Example::
-
- \xintAssignArray{1}{-2}{5}{-3}\to\foo
- \PolGet{f}\fromarray\foo
-
- This will define ``f`` as would have ``\poldef f(x):=1-2x+5x^2-3x^3;``.
-
- .. note::
-
- Prior to ``0.5``, coefficients were not normalized via
- ``\xintRaw`` for internal storage.
-
-.. _PolFromCSV:
-
-``\PolFromCSV{polname}{<csv>}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Defines a polynomial directly from the comma separated list of values
- (or a macro expanding to such a list) of its coefficients, the *first
- item* gives the constant term, the *last item* gives the leading
- coefficient, except if zero, then it is dropped (iteratively). List
- items are each expanded in an ``\edef`` and then put into normalized
- form via xintfrac_\ 's macro ``\xintRaw``.
-
- As leading zero coefficients are removed::
-
- \PolFromCSV{f}{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
-
- defines the zero polynomial, which holds only one coefficient.
-
- See also expandable macro `\\PolToCSV <\\PolToCSV{polname}_>`_.
-
- .. note::
-
- Prior to ``0.5``, coefficients were not normalized via
- ``\xintRaw`` for internal storage.
-
-.. _PolTypeset:
-
-``\PolTypeset{polname}``
-~~~~~~~~~~~~~~~~~~~~~~~~
-
- Typesets in descending powers in math mode. It uses letter ``x`` but
- this can be changed via an optional argument::
-
- \PolTypeset[z]{polname}
-
- By default zero coefficients are skipped (issue ``\poltypesetalltrue``
- to get all of them in output).
-
- These commands (whose meanings will be found in the package code)
- can be re-defined for customization. Their default definitions are
- expandable, but this is not a requirement.
-
-.. _PolTypesetCmd:
-
-``\PolTypesetCmd{raw_coeff}``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- Checks if the coefficient is ``1`` or ``-1`` and then skips printing
- the ``1``, except for the constant term. Also it sets conditional
- `\\PolIfCoeffIsPlusOrMinusOne{A}{B}`_.
-
- The actual printing of the coefficients, when not equal to plus or
- minus one is handled by `\\PolTypesetOne{raw_coeff}`_.
-
-.. _PolTypesetOne:
-
-``\PolTypesetOne{raw_coeff}``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- The default is ``\xintSignedFrac`` but this macro is annoying as it
- insists to use a power of ten, and not decimal notation.
-
- One can do things such as for example: [#]_
-
- ::
-
- \renewcommand\PolTypesetOne[1]{\num{\xintPFloat[5]{#1}}}
- \renewcommand\PolTypesetOne[1]{\num{\xintRound{4}{#1}}}
-
- where e.g. we used the ``\num`` macro of ``siunitx`` as it
- understands floating point notation.
-
- .. [#] the difference in the syntaxes of ``\xintPFloat`` and
- ``\xintRound`` is explained from the fact that
- ``\xintPFloat`` by default uses the prevailing precision
- hence the extra argument like here ``5`` is an optional one.
-
- One can also give a try to using `\\PolDecToString{decimal number}`_
- which uses decimal notation (at least for the numerator part).
-
-.. _PolTypesetMonomialCmd:
-
-``\PolTypesetMonomialCmd``
-^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- This decides how a monomial (in variable ``\PolVar`` and with
- exponent ``\PolIndex``) is to be printed. The default does nothing
- for the constant term, ``\PolVar`` for the first degree and
- ``\PolVar^{\PolIndex}`` for higher degrees monomials. Beware that
- ``\PolIndex`` expands to digit tokens and needs termination in
- ``\ifnum`` tests.
-
-.. _PolTypesetCmdPrefix:
-
-``\PolTypesetCmdPrefix{raw_coeff}``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- Expands to a ``+`` if the ``raw_coeff`` is zero or positive, and to
- nothing if ``raw_coeff`` is negative, as in latter case the
- ``\xintSignedFrac`` used by `\\PolTypesetCmd{raw_coeff}`_ will put
- the ``-`` sign in front of the fraction (if it is a fraction) and
- this will thus serve as separator in the typeset formula. Not used
- for the first term.
-
-.. _PolTypeset*:
-
-``\PolTypeset*{polname}``
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Typesets in ascending powers. Use e.g. ``[h]`` optional argument
- (after the ``*``) to use letter ``h`` rather than ``x``.
-
-.. _PolDiff:
-
-``\PolDiff{polname_1}{polname_2}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- This sets ``polname_2`` to the first derivative of ``polname_1``. It
- is allowed to issue ``\PolDiff{f}{f}``, effectively replacing ``f``
- by ``f'``.
-
- Coefficients of the result ``polname_2`` are irreducible fractions
- (see `Technicalities`_ for the whole story.)
-
-.. _PolDiff[N]:
-
-``\PolDiff[N]{polname_1}{polname_2}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- This sets ``polname_2`` to the ``N``-th derivative of ``polname_1``.
- Identical arguments is allowed. With ``N=0``, same effect as
- ``\PolLet{polname_2}={polname_1}``. With negative ``N``, switches to
- using ``\PolAntiDiff``.
-
-.. _PolAntiDiff:
-
-``\PolAntiDiff{polname_1}{polname_2}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- This sets ``polname_2`` to the primitive of ``polname_1`` vanishing
- at zero.
-
- Coefficients of the result ``polname_2`` are irreducible fractions
- (see `Technicalities`_ for the whole story.)
-
-.. _PolAntiDiff[N]:
-
-``\PolAntiDiff[N]{polname_1}{polname_2}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- This sets ``polname_2`` to the result of ``N`` successive integrations on
- ``polname_1``. With negative ``N``, it switches to using ``\PolDiff``.
-
-.. _PolDivide:
-
-``\PolDivide{polname_1}{polname_2}{polname_Q}{polname_R}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- This sets ``polname_Q`` and ``polname_R`` to be the quotient and
- remainder in the Euclidean division of ``polname_1`` by
- ``polname_2``.
-
-.. _PolQuo:
-
-``\PolQuo{polname_1}{polname_2}{polname_Q}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- This sets ``polname_Q`` to be the quotient in the Euclidean division
- of ``polname_1`` by ``polname_2``.
-
-.. _PolRem:
-
-``\PolRem{polname_1}{polname_2}{polname_R}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- This sets ``polname_R`` to be the remainder in the Euclidean division
- of ``polname_1`` by ``polname_2``.
-
-.. _PolGCD:
-
-``\PolGCD{polname_1}{polname_2}{polname_GCD}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- This sets ``polname_GCD`` to be the (monic) GCD of the two first
- polynomials. It is a unitary polynomial except if both ``polname_1``
- and ``polname_2`` vanish, then ``polname_GCD`` is the zero
- polynomial.
-
-.. ``\PolIGCD{polname_1}{polname_2}{polname_iGCD}``
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- **NOT YET**
-
- This **assumes** that the two polynomials have integer coefficients.
- It then computes the greatest common divisor in the integer
- polynomial ring, normalized to have a positive leading coefficient
- (if the inputs are not both zero).
-
- ``\PolIContent{polname}``
- ~~~~~~~~~~~~~~~~~~~~~~~~~
-
- **NOT YET**
-
- This computes a positive rational number such that dividing the
- polynomial with it returns an integer coefficients polynomial with
- no common factor among the coefficients.
-
-.. _PolToSturm:
-
-``\PolToSturm{polname}{sturmname}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- With ``polname`` being for example ``P``, the macro starts by
- computing polynomials ``P`` and ``P'``, then computes the (opposite
- of the) remainder in euclidean division, iteratively.
-
- The last non-zero remainder ``P_N_`` (where ``N`` is obtainable as
- `\\PolSturmChainLength{sturmname}`_) is up to a factor
- the GCD of ``P`` and ``P'`` hence it is a constant if and only if
- ``P`` is square-free.
-
- .. note::
-
- - Since ``0.5`` all these polynomials are divided by their rational
- content, so they have integer coefficients with no common factor,
- and the last one if a constant is either ``1`` or ``-1``.
-
- - After this normalization to primitive polynomials, they are
- stored internally as ``sturmname_k_``, ``k=0,1, ...``.
-
- - These polynomials are used internally only. To keep them as
- genuine declared polynomials also after the macro call, use the
- starred variant `PolToSturm*`_.
-
- .. note::
-
- It is perfectly allowed to use the polynomial name as Sturm chain name:
- ``\PolToSturm{f}(f}``.
-
- The macro then declares ``sturmname_0``, ``sturmname_1``, ..., which are
- the (non-declared) ``sturmname_k_`` divided by the last one. Division is
- not done if this last one is the constant ``1`` or ``-1``, i.e. if the
- original polynomial was square-free. These polynomials are primitive
- polynomials too, i.e. with integer coefficients having no common factor.
-
- Thus ``sturmname_0`` has exactly the same real and complex roots as
- polynomial ``polname``, but with each root now of multiplicity one:
- i.e. it is the "square-free part" of original polynomial ``polname``.
-
- Notice that ``sturmname_1`` isn't necessarily the derivative of
- ``sturmname_0`` due to the various normalizations.
-
- The polynomials ``sturmname_k`` main utility is for the execution of
- `\\PolSturmIsolateZeros{sturmname}`_. Be careful not to use these
- names ``sturmname_0``, ``sturmname_1``, etc... for defining other
- polynomials after having done ``\PolToSturm{polname}{sturmname}`` and
- before executing ``\PolSturmIsolateZeros{sturmname}`` else the
- latter will behave erroneously.
-
- `\\PolSturmChainLength{sturmname}`_ gives the index of the last
- element of the Sturm chain.
-
-.. _PolToSturm*:
-
-``\PolToSturm*{polname}{sturmname}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Does the same as `un-starred version <PolToSturm_>`_ and additionally it
- keeps for user usage the memory of the *un-normalized* Sturm chain
- polynomials ``sturmname_k_``, ``k=0,1, ..., N``, with
- ``N`` being `\\PolSturmChainLength{sturmname}`_.
-
- .. note::
-
- This behaviour was modified at ``0.6``, anyhow the macro was
- broken at ``0.5``.
-
- .. hint::
-
- The square-free part of ``polname`` is ``sturmname_0``, and their
- quotient is the polynomial with name
- ``sturname_\PolSturmChainLength{sturmname}_``. It thus easy to
- set-up a loop iteratively computing the latter until the last one
- is a constant, thus obtaining the decomposition of an ``f`` as
- a product ``c f_1 f_2 f_3 ...`` of a constant and square-free (primitive)
- polynomials, where each ``f_i`` divides its predecessor.
-
-.. _PolSetToSturmChainSignChangesAt:
-
-``\PolSetToSturmChainSignChangesAt{\macro}{sturmname}{fraction}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Sets macro ``\macro`` to the number of sign changes in the Sturm
- chain with name prefix ``sturmname``, at location ``fraction``
- (which must be in format as acceptable by the xintfrac_ macros.)
-
- .. note::
-
- The author was lazy and did not provide rather an expandable
- variant, where one would do ``\edef\macro{\PolNbOf...}``.
-
- This will presumably get added in a future release.
-
- After some hesitation it was decided the macro would by default
- act globally. To make the scope of its macro definition local,
- use ``[\empty]`` as extra optional argument.
-
-.. _PolSetToNbOfZerosWithin:
-
-``\PolSetToNbOfZerosWithin{\macro}{sturmname}{value_a}{value_b}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Applies the `Sturm Theorem`_ to set ``\macro`` to the exact number
- of **distinct** roots of ``sturmname_0`` in the interval ``(value_a,
- value_b]`` (the macro first re-orders the value for ``value_a <=
- value_b`` to hold).
-
- .. note::
-
- The author was lazy and did not provide rather an expandable
- variant, where one would do ``\edef\macro{\PolNbOf...}``.
-
- This will presumably get added in future.
-
- After some hesitation it was decided the macro would by default
- act globally. To make the scope of its macro definition local,
- use ``[\empty]`` as extra optional argument.
-
- See also the expandable
- `\\PolSturmNbOfRootsOf{sturmname}\\LessThanOrEqualTo{value}`_, from
- which it is immediate (with ``\numexpr``) to create an expandable
- variant of this macro. However the difference is that this macro
- requires only `\\PolToSturm <PolToSturm_>`_ to have been executed,
- whereas the expandable variant requires prior execution of
- `\\PolSturmIsolateZeros <PolSturmIsolateZeros_>`_.
-
- See also the expandable
- `\\PolSturmNbWithMultOfRootsOf{sturmname}\\LessThanOrEqualTo{value}`_
- which requires prior execution of
- `\\PolSturmIsolateZeros* <PolSturmIsolateZeros*_>`_.
-
-
-.. _PolSturmIsolateZeros:
-
-``\PolSturmIsolateZeros{sturmname}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- The macros locates, using `Sturm theorem`_, as many disjoint
- intervals as there are (real) roots.
-
- .. important::
-
- The Sturm chain must have been produced by an earlier
- `\\PolToSturm{polname}{sturmname}`_.
-
- Why does this macro ask for argument the name of Sturm chain,
- rather than the name of a polynomial? well this is mainly for
- legacy reason, and because it is accompanied by other macros for
- which it is simpler to assume the argument will be the name of an
- already computed Sturm chain.
-
- Notice that ``\PolToSturm{f}{f}`` is perfectly legal (the
- ``sturmname`` can be same as the ``polname``): it defines
- polynomials ``f_0``, ``f_1``, ... having ``f`` has name prefix.
-
- Such a prior call
- to ``\PolToSturm`` must have been made at any rate for
- ``\PolSturmIsolateZeros`` to be usable.
-
- After its execution they are two types of such intervals (stored in
- memory and accessible via macros or xintexpr_ variables, see below):
-
- - singleton ``{a}``: then ``a`` is a root, (necessarily a decimal
- number, but not all such decimal numbers are exactly identified yet).
-
- - open intervals ``(a,b)``: then there is exactly one root ``z``
- such that ``a < z < b``, and the end points are guaranteed to not
- be roots.
-
- The interval boundaries are decimal numbers, originating
- in iterated decimal subdivision from initial intervals
- ``(-10^E, 0)`` and ``(0, 10^E)`` with ``E`` chosen initially large
- enough so that all roots are enclosed; if zero is a root it is always
- identified as such. The non-singleton intervals are of the
- type ``(a/10^f, (a+1)/10^f)`` with ``a`` an integer, which is
- neither ``0`` nor ``-1``. Hence either ``a`` and ``a+1`` are both positive
- or they are both negative.
-
- One does not *a priori* know what will be the lengths of these
- intervals (except that they are always powers of ten), they
- vary depending on how many digits two successive roots have in
- common in their respective decimal expansions.
-
- .. important::
-
- If some two consecutive intervals share an end-point, no
- information is yet gained about the separation between the two
- roots which could at this stage be arbitrarily small.
-
- See `\\PolRefineInterval*{sturmname}{index}`_ which addresses
- this issue.
-
- .. This procedure is covariant
- with the independent variable ``x`` becoming ``-x``.
- Hmm, pas sûr et trop fatigué
-
- The interval boundaries (and exactly found roots) are made available
- for future computations in ``\xintexpr``-essions or polynomial
- definitions as variables ``<sturmname>L_1``,
- ``<sturmname>L_2``, etc..., for the left end-points and
- ``<sturmname>R_1``, ``<sturmname>R_2``, ..., for the right
- end-points.
-
- Thus for example, if ``sturmname`` is ``f``, one can use the
- xintexpr_ variables ``fL_1``, ``fL_2``, ... to refer in expressions
- to the left end-points (or to the exact root, if left and right end
- points coincide). Additionally, xintexpr_ variable ``fZ_1_isknown``
- will have value ``1`` if the root in the first interval is known,
- and ``0`` otherwise. And similarly for the other intervals.
-
- Also, macros `\\PolSturmIsolatedZeroLeft{sturmname}{index}`_ and
- `\\PolSturmIsolatedZeroRight{sturmname}{index}`_ are provided which
- expand to these same values, written in decimal notation (i.e.
- pre-processed by `\\PolDecToString <PolDecToString_>`_.) And there
- is also `\\PolSturmIfZeroExactlyKnown{sturmname}{index}{A}{B}`_.
-
- .. important::
-
- Trailing zeroes in the stored decimal numbers accessible via the
- macros are significant: they are also present in the decimal
- expansion of the exact root.
-
- These variables and macros are automatically updated when one next
- uses macros such as `\\PolRefineInterval*{sturmname}{index}`_.
-
- The start of decimal expansion of a positive ``k``-th root is given
- by `\\PolSturmIsolatedZeroLeft{sturmname}{k}
- <PolSturmIsolatedZeroLeft_>`_, and for a negative root it is given
- by `\PolSturmIsolatedZeroRight{sturmname}{k}
- <PolSturmIsolatedZeroRight_>`_. These two decimal
- numbers are either both zero or both of the same sign.
-
- The number of distinct roots is obtainable expandably as
- `\\PolSturmNbOfIsolatedZeros{sturmname}`_.
-
- Furthermore
- `\\PolSturmNbOfRootsOf{sturmname}\\LessThanOrEqualTo{value}`_ and
- `\\PolSturmNbOfRootsOf{sturmname}\\LessThanOrEqualToExpr{expression}`_.
- will expandably compute respectively the number of real roots at
- most equal to ``value`` or ``expression``, and the same but with
- multiplicities.
-
- .. note::
-
- In the current implementation the xintexpr_ variables
- and xinttools_ arrays are globally defined. On the
- other hand the Sturm sequence polynomials obey the current scope.
-
- .. note::
-
- As all computations are done *exactly* there can be no errors...
- apart those due to bad coding by author. The results are exact
- bounds for the mathematically exact real roots.
-
- Future releases will perhaps also provide macros based on Newton
- or Regula Falsi methods. Exact computations with such methods
- lead however quickly to very big fractions, and this forces usage
- of some rounding scheme for the abscissas if computation times
- are to remain reasonable. This raises issues of its own, which
- are studied in numerical mathematics.
-
-.. _PolSturmIsolateZeros*:
-
-``\PolSturmIsolateZeros*{sturmname}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- The macro does the same as `\\PolSturmIsolateZeros{sturmname}`_ and
- then in addition it does the extra work to determine all
- multiplicities (of the real roots):
- after executing this macro,
- `\\PolSturmIsolatedZeroMultiplicity{sturmname}{index}`_ will expand
- to the multiplicity of the root located in the ``index``\ -th
- interval (intervals are enumerated from left to right, with index
- starting at ``1``).
-
- Furthermore, if for example the ``sturmname`` is ``f``, xintexpr_
- variables ``fM_1``, ``fM_2``... hold the multiplicities thus
- computed.
-
- .. note::
-
- It is **not** necessary to have executed the `PolToSturm*`_ starred
- variant, as the non-starred variant keeps internally the memory of the
- original GCD (and even of the full non-normalized original Sturm
- chain), even though it does not make the declarations as *user-level*
- genuine polynomials.
-
- See `The degree nine polynomial with 0.99, 0.999, 0.9999 as triple
- roots`_ for an example.
-
-.. _PolSturmIsolateZeros**:
-
-``\PolSturmIsolateZeros**{sturmname}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- The macro does the same as `\\PolSturmIsolateZeros*{sturmname}`_ and
- in addition it does the extra work to determine all the *rational*
- roots.
-
- .. note::
-
- After execution of this macro, a root is "known" if and only if
- it is rational.
-
- Furthermore, primitive polynomial ``sturmname_sqf_norr`` is created
- to match the (square-free) ``sturmname_0`` from which all rational
- roots have been removed (see `\\polexprsetup`_ for customizing this
- name). The number of distinct rational roots is thus the difference
- between the degrees of these two polynomials (see also
- `\\PolSturmNbOfRationalRoots{sturmname}`_).
-
- And ``sturmname_norr`` is ``sturmname_0_`` from which all rational
- roots have been removed (see `\\polexprsetup`_), i.e. it contains
- the irrational roots of the original polynomial, with the same
- multiplicities.
-
- See `A degree five polynomial with three rational
- roots`_ for an example.
-
-.. _PolSturmIsolateZerosAndGetMultiplicities:
-
-``\PolSturmIsolateZerosAndGetMultiplicities{sturmname}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- This is another name for `\\PolSturmIsolateZeros*{sturmname}`_.
-
-.. _PolSturmIsolateZerosGetMultiplicitiesAndRationalRoots:
-
-``\PolSturmIsolateZerosGetMultiplicitiesAndRationalRoots{sturmname}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- This is another name for `\\PolSturmIsolateZeros**{sturmname}`_.
-
-
-``\PolSturmIsolateZerosAndFindRationalRoots{sturmname}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- This works exactly like `\\PolSturmIsolateZeros**{sturmname}`_
- (inclusive of declaring the polynomials ``sturmname_sqf_norr`` and
- ``sturmname_norr`` with no rational roots) except that it does *not*
- compute the multiplicities of the *non-rational* roots.
-
- .. note::
-
- There is no macro to find the rational roots but not compute
- their multiplicities at the same time.
-
- .. attention::
-
- This macro does *not* define xintexpr_ variables
- ``sturmnameM_1``, ``sturmnameM_2``, ... holding the
- multiplicities and it leaves the multiplicity array (whose accessor
- is `\\PolSturmIsolatedZeroMultiplicity{sturmname}{index}`_) into
- a broken state, as all non-rational roots will supposedly have
- multiplicity one. This means that the output of
- `\\PolPrintIntervals* <PolPrintIntervals*_>`_ for example will be
- erroneous for the intervals with irrational roots.
-
- I decided to document it because finding multiplicities of the
- non rational roots is somewhat costly, and one may be interested
- only into finding the rational roots (of course random
- polynomials with integer coefficients will not have *any*
- rational root anyhow).
-
-
-.. _PolRefineInterval*:
-
-``\PolRefineInterval*{sturmname}{index}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- The ``index``\ -th interval (starting indexing at one) is further
- subdivided as many times as is necessary in order for the newer
- interval to have both its end-points distinct from the end-points of
- the original interval. This means that the ``k``\ th root is then
- strictly separated from the other roots.
-
-.. _PolRefineInterval[N]:
-
-``\PolRefineInterval[N]{sturmname}{index}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- The ``index``\ -th interval (starting count at one) is further
- subdivided once, reducing its length by a factor of 10. This is done
- ``N`` times if the optional argument ``[N]`` is present.
-
-.. _PolEnsureIntervalLength:
-
-``\PolEnsureIntervalLength{sturmname}{index}{E}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- The ``index``\ -th interval is subdivided until its length becomes at
- most ``10^E``. This means (for ``E<0``) that the first ``-E`` digits
- after decimal mark of the ``k``\ th root will then be known exactly.
-
-.. _PolEnsureIntervalLengths:
-
-``\PolEnsureIntervalLengths{sturmname}{E}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- The intervals as obtained from ``\PolSturmIsolateZeros`` are (if
- necessary) subdivided further by (base 10) dichotomy in order for
- each of them to have length at most ``10^E`` (length will be shorter
- than ``10^E`` in output only if it did not change or became zero.)
-
- This means that decimal expansions of all roots will be known with
- ``-E`` digits (for ``E<0``) after decimal mark.
-
-.. _PolPrintIntervals:
-
-``\PolPrintIntervals[varname]{sturmname}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- This is a convenience macro which prints the bounds for the roots
- ``Z_1``, ``Z_2``, ... (the optional argument ``varname`` allows to
- specify a replacement for the default ``Z``). This will be done (by
- default) in a
- math mode ``array``, one interval per row, and pattern ``rcccl``,
- where the second and fourth column hold the ``<`` sign, except when
- the interval reduces to a singleton, which means the root is known
- exactly.
-
- .. attention::
-
- This macro was refactored at 0.7, its default output remained
- identical but the ways to customize it got completely
- modified.
-
- See next macros which govern its output.
-
-``\PolPrintIntervalsNoRealRoots``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- Executed in place of an ``array`` environment, when there are no
- real roots. Default definition::
-
- \newcommand\PolPrintIntervalsNoRealRoots{}
-
-``\PolPrintIntervalsBeginEnv``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- Default definition::
-
- \newcommand\PolPrintIntervalsBeginEnv{\[\begin{array}{rcccl}}
-
-``\PolPrintIntervalsEndEnv``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- Default definition::
-
- \newcommand\PolPrintIntervalsEndEnv{\end{array}\]}
-
-``\PolPrintIntervalsKnownRoot``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- Default definition::
-
- \newcommand\PolPrintIntervalsKnownRoot{%
- &&\PolPrintIntervalsTheVar_{\PolPrintIntervalsTheIndex}%
- &=&\PolPrintIntervalsPrintExactZero
- }
-
-``\PolPrintIntervalsUnknownRoot``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- Default definition::
-
- \newcommand\PolPrintIntervalsUnknownRoot{%
- \PolPrintIntervalsPrintLeftEndPoint&<&%
- \PolPrintIntervalsTheVar_{\PolPrintIntervalsTheIndex}&<&%
- \PolPrintIntervalsPrintRightEndPoint
- }
-
-
-.. _PolPrintIntervalsPrintExactZero:
-
-``\PolPrintIntervalsPrintExactZero``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- Default definition::
-
- \newcommand\PolPrintIntervalsPrintExactZero{\PolPrintIntervalsTheLeftEndPoint}
-
-
-.. _PolPrintIntervalsPrintLeftEndPoint:
-
-``\PolPrintIntervalsPrintLeftEndPoint``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- Default definition::
-
- \newcommand\PolPrintIntervalsPrintLeftEndPoint{\PolPrintIntervalsTheLeftEndPoint}
-
-.. _PolPrintIntervalsPrintRightEndPoint:
-
-``\PolPrintIntervalsPrintRightEndPoint``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- Default definition is::
-
- \newcommand\PolPrintIntervalsPrintRightEndPoint{\PolPrintIntervalsTheRightEndPoint}
-
-.. _PolPrintIntervals*:
-
-``\PolPrintIntervals*[varname]{sturmname}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- This starred variant produces an alternative output (which
- displays the root multiplicity), and is provided as an
- example of customization.
-
- As replacement for `\\PolPrintIntervalsKnownRoot`_,
- `\\PolPrintIntervalsPrintExactZero`_,
- `\\PolPrintIntervalsUnknownRoot`_ it uses its own
- ``\POL@@PrintIntervals...`` macros. We only reproduce here one
- definition::
-
- \newcommand\POL@@PrintIntervalsPrintExactZero{%
- \displaystyle
- \xintSignedFrac{\PolPrintIntervalsTheLeftEndPoint}%
- }%
-
- Multiplicities are printed using this auxiliary macro:
-
-``\PolPrintIntervalsPrintMultiplicity``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- whose default definition is::
-
- \newcommand\PolPrintIntervalsPrintMultiplicity{(\mbox{mult. }\PolPrintIntervalsTheMultiplicity)}
-
-
-.. _PolMapCoeffs:
-
-``\PolMapCoeffs{\macro}{polname}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- It modifies ('in-place': original coefficients get lost) each
- coefficient of the defined polynomial via the *expandable* macro
- ``\macro``. The degree is adjusted as necessary if some leading
- coefficients vanish after the operation. In replacement text of
- ``\macro``, ``\index`` expands to the coefficient index (which is
- defined to be zero for the constant term).
-
- Notice that ``\macro`` will have to handle inputs of the shape
- ``A/B[N]`` (xintfrac_ internal notation). This means that it probably
- will have to be expressed in terms of macros from xintfrac_ package.
-
- Example::
-
- \def\foo#1{\xintMul{#1}{\the\numexpr\index*\index\relax}}
-
- (or with ``\xintSqr{\index}``) to replace ``n``-th coefficient
- ``f_n`` by ``f_n*n^2``.
-
-.. _PolReduceCoeffs:
-
-``\PolReduceCoeffs{polname}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- About the same as ``\PolMapCoeffs{\xintIrr}{polname}`` (but
- maintaining a ``[0]`` postfix for speedier xintfrac_ parsing when
- polynomial function is used for computations.) This is a
- one-argument macro, working 'in-place'.
-
-.. _PolReduceCoeffs*:
-
-``\PolReduceCoeffs*{polname}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- This starred variant leaves un-touched the decimal exponent in the
- internal representation of the fractional coefficients, i.e. if a
- coefficient is internally ``A/B[N]``, then ``A/B`` is reduced to
- smallest terms, but the ``10^N`` part is kept as is. Note: if the
- polynomial is freshly defined directly via `\\PolFromCSV
- <PolFromCSV_>`_ its coefficients might still be internally in some
- format like ``1.5e7``; the macro will anyhow always first do the
- needed conversion to strict format ``A/B[N]``.
-
- Evaluations with polynomials treated by this can be much faster than
- with those handled by the non-starred variant
- `\\PolReduceCoeffs{polname}`_: as the numerators and denominators
- remain smaller, this proves very beneficial in favorable cases
- (especially when the coefficients are decimal numbers) to the
- expansion speed of the xintfrac_ macros used internally by
- `\\PolEval <PolEvalAt_>`_.
-
-.. _PolMakeMonic:
-
-``\PolMakeMonic{polname}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Divides by the leading coefficient. It is recommended to execute
- `\\PolReduceCoeffs*{polname}`_ immediately afterwards. This is not
- done automatically, due to the case the original polynomial had integer
- coefficients and we want to keep the leading one as common
- denominator.
-
-.. _PolMakePrimitive:
-
-``\PolMakePrimitive{polname}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Divides by the integer content see (`\\PolIContent
- <PolIContent_>`_). This thus produces a polynomial with integer
- coefficients having no common factor. The sign of the leading
- coefficient is not modified.
-
-Expandable macros
------------------
-
-All these macros expand completely in two steps except ``\PolToExpr``
-and ``\PolToFloatExpr`` (and their auxiliaries) which need a
-``\write``, ``\edef`` or a ``\csname...\endcsname`` context.
-
-.. _PolEvalAtExpr:
-
-``\PolEval{polname}\AtExpr{numerical expression}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- It boils down to
- ``\xinttheexpr polname(numerical expression)\relax``.
-
-.. _PolEvalAt:
-
-``\PolEval{polname}\At{fraction}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Evaluates the polynomial at value ``fraction`` which must be in (or
- expand to) a format acceptable to the xintfrac_ macros.
-
-.. _PolEvalReducedAtExpr:
-
-``\PolEvalReduced{polname}\AtExpr{numerical expression}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Boils down to ``\xinttheexpr reduce(polname(numerical expression))\relax``.
-
-.. _PolEvalReducedAt:
-
-``\PolEvalReduced{polname}\At{fraction}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Evaluates the polynomial at value ``fraction`` which must be in (or
- expand to) a format acceptable to the xintfrac_ macros, and produce
- an irreducible fraction.
-
-.. _PolFloatEvalAtExpr:
-
-``\PolFloatEval{polname}\AtExpr{numerical expression}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Boils down to ``\xintthefloatexpr polname(numerical expression)\relax``.
-
- This is done via a Horner Scheme (see `\\poldef <poldef;_>`_ and
- `\\PolGenFloatVariant{polname}`_), with already rounded
- coefficients. [#]_ To use the *exact coefficients* with *exactly
- executed* additions and multiplications, just insert it in the float
- expression as in this example: [#]_
-
- ::
-
- \xintthefloatexpr 3.27*\xintexpr f(2.53)\relax^2\relax
-
- The ``f(2.53)`` is exactly computed then rounded at the time of
- getting raised to the power ``2``. Moving the ``^2`` inside, that
- operation would also be treated exactly.
-
-
- .. [#] Anyway each floating point operation starts by rounding its
- operands to the floating point precision.
-
- .. [#] The ``\xintexpr`` here could be ``\xinttheexpr`` but that
- would be less efficient. Cf. xintexpr_ documentation about
- nested expressions.
-
-.. _PolFloatEvalAt:
-
-``\PolFloatEval{polname}\At{fraction}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Evaluates the polynomial at value ``fraction`` which must be in (or
- expand to) a format acceptable to the xintfrac_ macros, and produces
- a floating point number.
-
-.. _PolIfCoeffIsPlusOrMinusOne:
-
-``\PolIfCoeffIsPlusOrMinusOne{A}{B}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- This macro is a priori undefined.
-
- It is defined via the default `\\PolTypesetCmd{raw_coeff}`_ to be
- used if needed in the execution of `\\PolTypesetMonomialCmd`_,
- e.g. to insert a ``\cdot`` in front of ``\PolVar^{\PolIndex}`` if
- the coefficient is not plus or minus one.
-
- The macro will execute ``A`` if the coefficient has been found to be
- plus or minus one, and ``B`` if not.
-
-.. _PolLeadingCoeff:
-
-``\PolLeadingCoeff{polname}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Expands to the leading coefficient.
-
-.. _PolNthCoeff:
-
-``\PolNthCoeff{polname}{number}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- It expands to the raw ``N``-th coefficient (``0/1[0]`` if the index
- number is out of range). With ``N=-1``, ``-2``, ... expands to the
- leading coefficients.
-
-.. _PolDegree:
-
-``\PolDegree{polname}``
-~~~~~~~~~~~~~~~~~~~~~~~
-
- It expands to the degree. This is ``-1`` if zero polynomial but this
- may change in future. Should it then expand to ``-\infty`` ?
-
-.. _PolIContent:
-
-``\PolIContent{polname}``
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
- It expands to the contents of the polynomial, i.e. to the positive
- fraction such that dividing by this fraction produces a polynomial
- with integer coefficients having no common prime divisor.
-
- See `\\PolMakePrimitive <PolMakePrimitive_>`_.
-
-.. _PolToExpr:
-
-``\PolToExpr{polname}``
-~~~~~~~~~~~~~~~~~~~~~~~
-
- Expands [#]_ to ``coeff_N*x^N+...`` (descending powers.)
-
- .. [#] in a ``\write``, ``\edef``, or ``\csname...\endcsname``, but
- not under ``\romannumeral-`0``.
-
- By default zero coefficients are skipped (issue ``\poltoexpralltrue`` to
- get all of them in output).
-
- By default, no ``+`` sign before negative coefficients, for
- compliance with Maple input format (but see
- `\\PolToExprTermPrefix{raw_coeff}`_.) Also, like the default
- behaviour of `\\PolTypeset{polname}`_, does not print (for the non
- constant terms) coefficients equal to plus or minus one. The degree
- one monomial is output as ``x``, not ``x^1``. Complete customization is
- possible, see next macros.
-
- Of course ``\PolToExpr{f}`` can be inserted in a ``\poldef``, as the
- latter expands token by token, hence will force complete expansion
- of ``\PolToExpr{f}``, but a simple ``f(x)`` is more efficient for
- the identical result.
-
-.. _PolToExprOneTerm:
-
-``\PolToExprOneTerm{raw_coeff}{number}``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- This two argument expandable command takes care of the monomial and
- its coefficient. The default definition is done in order for
- coefficients of absolute value ``1`` not be printed explicitely
- (except of course for the constant term). Also by default, the
- monomial of degree one is ``x`` not ``x^1``, and ``x^0`` is skipped.
-
- For compatibility with Maple input requirements, by default a ``*``
- always precedes the ``x^number``, except if the coefficient is a one
- or a minus one. See `\\PolToExprTimes`_.
-
-.. _PolToExprOneTermStyleA:
-
-``\PolToExprOneTermStyleA{raw_coeff}{number}``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- Holds the default package meaning of
- `\\PolToExprOneTerm{raw_coeff}{number}`_.
-
-.. _PolToExprOneTermStyleB:
-
-``\PolToExprOneTermStyleB{raw_coeff}{number}``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- For output in this style::
-
- 2*x^11/3+3*x^8/7-x^5-x^4/4-x^3-x^2/2-2*x+1
-
- issue ``\let\PolToExprOneTerm\PolToExprOneTermStyleB`` before usage of
- ``\PolToExpr``. Note that then ``\PolToExprCmd`` isn't used at all.
- To revert to package default, issue
- ``\let\PolToExprOneTerm\PolToExprOneTermStyleA``.
-
- To suppress the ``*``'s, cf. `\\PolToExprTimes`_.
-
-.. _PolToExprCmd:
-
-``\PolToExprCmd{raw_coeff}``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- It is the one-argument macro used by the package definition of
- ``\PolToExprOneTerm`` for the coefficients themselves (when not
- equal to plus or minus one), and it defaults to
- ``\xintPRaw{\xintRawWithZeros{#1}}``. One will have to redefine it
- to ``\xintIrr{#1}`` or to ``\xintPRaw{\xintIrr{#1}}`` to obtain in the
- output forcefully reduced coefficients.
-
-.. _PolToExprTermPrefix:
-
-``\PolToExprTermPrefix{raw_coeff}``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- Defined identically as `\\PolTypesetCmdPrefix{raw_coeff}`_. It
- prefixes with a plus sign for non-negative coefficients, because
- they don't carry one by themselves.
-
-.. _PolToExprVar:
-
-``\PolToExprVar``
-^^^^^^^^^^^^^^^^^
-
- This expands to the variable to use in output (it does not have to
- be a single letter, may be an expandable macro.) Initial definition
- is ``x``.
-
-.. _PolToExprTimes:
-
-``\PolToExprTimes``
-^^^^^^^^^^^^^^^^^^^
-
- This expands to the symbol used for multiplication of an
- ``x^{number}`` by the corresponding coefficient. The default is
- ``*``. Redefine the macro to expand to nothing to get rid of it (but
- this will give output incompatible with some professional computer
- algebra software).
-
-.. _PolToExpr*:
-
-``\PolToExpr*{polname}``
-~~~~~~~~~~~~~~~~~~~~~~~~
-
- Expands to ``coeff_0+coeff_1*x+coeff_2*x^2+...`` (ascending powers).
- Customizable like `\\PolToExpr{polname}`_ via the same macros.
-
-.. _PolToFloatExpr:
-
-``\PolToFloatExpr{polname}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Similar to `\\PolToExpr{polname}`_ but uses `\\PolToFloatExprCmd
- <\\PolToFloatExprCmd{raw_coeff}>`_
- which by default rounds and converts the coefficients to floating
- point format.
-
- .. note::
-
- It is not necessary to have issued
- `\\PolGenFloatVariant{polname}`_. The rounded coefficients are
- not easily recoverable from the ``\xintfloatexpr`` polynomial
- function hence ``\PolToFloatExprCmd`` operates from the *exact*
- coefficients anew.
-
- Attention that both macros obey the prevailing float precision.
- If it is changed between those macro calls, then a mismatch
- exists between the coefficients as used in ``\xintfloatexpr`` and
- those output by ``\PolToFloatExpr{polname}``.
-
-.. _PolToFloatExprOneTerm:
-
-``\PolToFloatExprOneTerm{raw_coeff}{number}``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- Similar to `\\PolToExprOneTerm
- <\\PolToExprOneTerm{raw_coeff}{number}>`_. But does not treat
- especially coefficients equal to plus or minus one.
-
-.. _PolToFloatExprCmd:
-
-``\PolToFloatExprCmd{raw_coeff}``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- It is the one-argument macro used by ``\PolToFloatExprOneTerm``.
- Its package definition is ``\xintFloat{#1}``.
-
- .. caution::
-
- Currently (xint_ ``1.3c``) ``\xintFloat{0}`` outputs ``0.e0``
- which is perfectly acceptable input for Python, but not for
- Maple. Thus, one should better leave the `\\poltoexprallfalse`_
- toggle to its default ``\iffalse`` state, if one intends to use
- the output in a Maple worksheet.
-
- But even then the zero polynomial will cause a problem. Workaround::
-
- \renewcommand\PolToFloatExprCmd[1]{\xintiiifZero{#1}{0.0}{\xintFloat{#1}}}
-
- Usage of ``\xintiiifZero`` and not ``\xintifZero`` is only for
- optimization (I can't help it) because ``#1`` is known to be
- in ``xintfrac`` raw format.
-
-.. _PolToFloatExpr*:
-
-``\PolToFloatExpr*{polname}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Typesets in ascending powers.
-
-.. _PolToList:
-
-``\PolToList{polname}``
-~~~~~~~~~~~~~~~~~~~~~~~
-
- Expands to ``{coeff_0}{coeff_1}...{coeff_N}`` with ``N`` = degree, and
- ``coeff_N`` the leading coefficient
- (the zero polynomial does give ``{0/1[0]}`` and not an
- empty output.)
-
-.. _PolToCSV:
-
-``\PolToCSV{polname}``
-~~~~~~~~~~~~~~~~~~~~~~
-
- Expands to ``coeff_0, coeff_1, coeff_2, ....., coeff_N``, starting
- with constant term and ending with leading coefficient. Converse
- to `\\PolFromCSV <\\PolFromCSV{polname}{\<csv\>}_>`_.
-
-.. _PolSturmChainLength:
-
-``\PolSturmChainLength{sturmname}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Returns the integer ``N`` such that ``sturmname_N`` is the last one
- in the Sturm chain ``sturmname_0``, ``sturmname_1``, ...
-
- See `\\PolToSturm{polname}{sturmname}`_.
-
-.. _PolSturmIfZeroExactlyKnown:
-
-``\PolSturmIfZeroExactlyKnown{sturmname}{index}{A}{B}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Executes ``A`` if the ``index``\ -th interval reduces to a singleton,
- i.e. the root is known exactly, else ``B``.
-
- .. note::
-
- ``index`` is allowed to be something like ``1+2*3`` as it is fed
- to ``\the\numexpr...\relax``.
-
-.. _PolSturmIsolatedZeroLeft:
-
-``\PolSturmIsolatedZeroLeft{sturmname}{index}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Expands to the left end-point for the ``index``\ -th interval, as
- computed by some earlier `\\PolSturmIsolateZeros{sturmname}`_.
-
- .. note::
-
- Of course, this is kept updated by macros such as
- `\\PolRefineInterval{sturmname}{index} <PolRefineInterval[N]_>`_.
-
- The value is pre-formatted using `\\PolDecTostring
- <PolDecToString_>`_.
-
-.. _PolSturmIsolatedZeroRight:
-
-``\PolSturmIsolatedZeroRight{sturmname}{index}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Expands to the right end-point for the ``index``\ -th interval as
- computed by some earlier `\\PolSturmIsolateZeros{sturmname}`_ and
- possibly refined afterwards.
-
- The value is pre-formatted using `\\PolDecTostring
- <PolDecToString_>`_.
-
-.. _PolSturmIsolatedZeroMultiplicity:
-
-``\PolSturmIsolatedZeroMultiplicity{sturmname}{index}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Expands to the multiplicity of the unique root contained in the
- ``index``\ -th interval.
-
- .. attention::
-
- A prior execution of `\\PolSturmIsolateZeros*{sturmname}`_ is mandatory.
-
- See `The degree nine polynomial with 0.99, 0.999, 0.9999 as triple
- roots`_ for an example of use.
-
-.. _PolSturmNbOfIsolatedZeros:
-
-``\PolSturmNbOfIsolatedZeros{sturmname}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Expands to the number of real roots of the polynomial
- ``<sturmname>_0``, i.e. the number of distinct real roots of the
- polynomial originally used to create the Sturm chain via
- `\\PolToSturm{polname}{sturmname}`_.
-
-.. warning::
-
- The next few macros counting roots, with or without multiplicities,
- less than or equal to some value, are under evaluation and may be
- removed from the package if their utility is judged to be not high
- enough. They can be re-coded at user level on the basis of the other
- documented package macros anyway.
-
-``\PolSturmNbOfRootsOf{sturmname}\LessThanOrEqualTo{value}``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- Expands to the number of distinct roots (of the polynomial used to
- create the Sturm chain) less than or equal to the ``value`` (i.e. a
- number of fraction recognizable by the xintfrac_ macros).
-
- .. attention::
-
- `\\PolSturmIsolateZeros{sturmname}`_ must have been executed
- beforehand.
-
- And the argument is a ``sturmname``, not a ``polname`` (this is
- why the macro contains Sturm in its name), simply to be reminded
- of the above constraint.
-
-``\PolSturmNbOfRootsOf{sturmname}\LessThanOrEqualToExpr{expression}``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- Expands to the number of distinct roots (of the polynomial
- used to create the Sturm chain) which are less than or equal to the
- given ``expression``.
-
- .. attention::
-
- `\\PolSturmIsolateZeros{sturmname}`_ must have been executed
- beforehand.
-
-``\PolSturmNbWithMultOfRootsOf{sturmname}\LessThanOrEqualTo{value}``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- Expands to the number counted with multiplicities of the roots (of
- the polynomial used to create the Sturm chain) which are less than
- or equal to the given ``value``.
-
- .. attention::
-
- `\\PolSturmIsolateZeros*{sturmname}`_ (or the double starred
- variant) must have been executed beforehand.
-
-``\PolSturmNbWithMultOfRootsOf{sturmname}\LessThanOrEqualToExpr{expression}``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- Expands to the total number of roots (counted with multiplicities)
- which are less than or equal to the given ``expression``.
-
- .. attention::
-
- `\\PolSturmIsolateZeros*{sturmname}`_ (or the double starred
- variant) must have been executed beforehand.
-
-``\PolSturmNbOfRationalRoots{sturmname}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Expands to the number of rational roots (without multiplicities).
-
- .. attention::
-
- `\\PolSturmIsolateZeros**{sturmname}`_ must have been executed
- beforehand.
-
-``\PolSturmNbOfRationalRootsWithMultiplicities{sturmname}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Expands to the number of rational roots (counted with multiplicities).
-
- .. attention::
-
- `\\PolSturmIsolateZeros**{sturmname}`_ must have been executed
- beforehand.
-
-``\PolSturmRationalRoot{sturmname}{k}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Expands to the ``k``\ th rational root (they are ordered and indexed
- starting at 1 for the most negative).
-
- .. attention::
-
- `\\PolSturmIsolateZeros**{sturmname}`_ must have been executed
- beforehand.
-
-``\PolSturmRationalRootIndex{sturmname}{k}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Expands to ``index`` of the ``k``\ th rational root as part of the
- ordered real roots (without multiplicities). I.e., above macro
- `\\PolSturmRationalRoot{sturmname}{k}`_ is equivalent to this
- nested call::
-
- \PolSturmIsolatedZeroLeft{sturmname}{\PolSturmRationalRootIndex{sturmname}{k}}
-
- .. attention::
-
- `\\PolSturmIsolateZeros**{sturmname}`_ must have been executed
- beforehand.
-
-``\PolSturmRationalRootMultiplicity{sturmname}{k}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Expands to the multiplicity of the ``k``\ th rational root.
-
- .. attention::
-
- `\\PolSturmIsolateZeros**{sturmname}`_ must have been executed
- beforehand.
-
-.. _PolIntervalWidth:
-
-``\PolIntervalWidth{sturmname}{index}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- The ``10^E`` width of the current ``index``\ -th root localization
- interval. Output is in xintfrac_ raw ``1/1[E]`` format (if not zero).
-
-Expandable macros for use within execution of ``\PolPrintIntervals``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-These macros are for usage within custom user redefinitions of
-`\\PolPrintIntervalsKnownRoot`_, `\\PolPrintIntervalsUnknownRoot`_, or
-in redefinitions of `\PolPrintIntervalsPrintExactZero`_ (used in the
-default for the former) and of `\\PolPrintIntervalsPrintLeftEndPoint`_,
-`\\PolPrintIntervalsPrintRightEndPoint`_ (used in the default for the
-latter).
-
-.. attention::
-
- Some macros formerly mentioned here got removed at 0.7:
- ``\PolPrintIntervalsTheEndPoint``,
- ``\PolIfEndPointIsPositive{A}{B}``,
- ``\PolIfEndPointIsNegative{A}{B}``,
- ``\PolIfEndPointIsZero{A}{B}``.
-
-``\PolPrintIntervalsTheVar``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- Expands to the name (default ``Z``) used for representing the roots,
- which was passed as optional argument ``varname`` to
- `\\PolPrintIntervals[varname]{sturmname}`_.
-
-``\PolPrintIntervalsTheIndex``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- Expands to the index of the considered interval (indexing starting
- at 1 for the leftmost interval).
-
-``\PolPrintIntervalsTheSturmName``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- Expands to the argument which was passed as ``sturmname`` to
- `\\PolPrintIntervals[varname]{sturmname}`_.
-
-``\PolPrintIntervalsTheLeftEndPoint``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- The left end point of the interval, as would be produced by
- `\\PolSturmIsolatedZeroLeft <PolSturmIsolatedZeroLeft_>`_ if it was
- used with arguments the Sturm chain name and interval index returned
- by `\\PolPrintIntervalsTheSturmName`_ and
- `\\PolPrintIntervalsTheIndex`_.
-
-``\PolPrintIntervalsTheRightEndPoint``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- The right end point of the interval, as would be produced by
- `\\\PolSturmIsolatedZeroRight <PolSturmIsolatedZeroRight_>`_ for
- this Sturm chain name and index.
-
-``\PolPrintIntervalsTheMultiplicity``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- The multiplicity of the unique root within the interval of index
- `\\PolPrintIntervalsTheIndex`_. Makes sense only if the starred (or
- double-starred) variant of `\\PolSturmIsolateZeros
- <PolSturmIsolateZeros_>`_ was used earlier.
-
-.. _PolDecToString:
-
-``\PolDecToString{decimal number}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- This is a utility macro to print decimal numbers. It has been
- backported to xintfrac_ (release ``1.3`` of ``2018/03/01``) under
- the name ``\xintDecToString``, and the ``polexpr`` macro is simply
- now an alias to it.
-
- For example
- ``\PolDecToString{123.456e-8}`` will expand to ``0.00000123456``
- and ``\PolDecToString{123.450e-8}`` to ``0.00000123450`` which
- illustrates that trailing zeros are not trimmed. To trim trailing
- zeroes, one can use ``\PolDecToString{\xintREZ{#1}}``.
-
- The precise behaviour of this macro may evolve in future releases of
- xint_.
-
-Booleans (with default setting as indicated)
---------------------------------------------
-
-``\xintverbosefalse``
-~~~~~~~~~~~~~~~~~~~~~
-
- This is actually an xintexpr_ configuration. Setting it to
- ``true`` triggers the writing of information to the log when new
- polynomials are defined.
-
- .. caution::
-
- The macro meanings as written to the log are to be considered
- unstable and undocumented internal structures.
-
-``\poltypesetallfalse``
-~~~~~~~~~~~~~~~~~~~~~~~
-
- If ``true``, `\\PolTypeset{polname}`_ will also typeset the vanishing
- coefficients.
-
-
-``\poltoexprallfalse``
-~~~~~~~~~~~~~~~~~~~~~~
-
- If ``true``, `\\PolToExpr{polname}`_ and `\\PolToFloatExpr{polname}`_ will
- also include the vanishing coefficients in their outputs.
-
-``\polexprsetup``
------------------
-
- Serves to customize the package. Currently only two keys are
- recognized:
-
- - ``norr``: the postfix that `\\PolSturmIsolateZeros**{sturmname}`_
- should append to ``sturmname`` to declare the primitive polynomial
- obtained from original one after removal of all rational roots.
- The default value is ``_norr`` (standing for “no rational roots”).
-
- - ``sqfnorr``: the postfix that `\\PolSturmIsolateZeros**{sturmname}`_
- should append to ``sturmname`` to declare the primitive polynomial
- obtained from original one after removal of all rational roots and
- suppression of all multiplicities.
- The default value is ``_sqf_norr`` (standing for “square-free with
- no rational roots”).
-
- The package executes ``\polexprsetup{norr=_norr,
- sqfnorr=_sqf_norr}`` as default.
-
-Technicalities
---------------
-
-- The catcode of the semi-colon is reset temporarily by `\\poldef
- <poldef;_>`_ macro in case some other package (for example the French
- babel module) may have made it active. This will fail though if the
- whole thing was already part of a macro argument, in such cases one
- can use `\\PolDef{f}{P(x)} <PolDef_>`_
- rather. The colon in ``:=`` may be active with no consequences.
-
-- As a consequence of xintfrac_ addition and subtraction always using
- least common multiples for the denominators [#]_, user-chosen common
- denominators survive additions and multiplications. For example, this::
-
- \poldef P(x):= 1/2 + 2/2*x + 3/2*x^3 + 4/2*x^4;
- \poldef Q(x):= 1/3 + (2/3)x + (3/3)x^3 + (4/3)x^4;
- \poldef PQ(x):= P(x)Q(x);
-
- gives internally the polynomial::
-
- 1/6+4/6*x^1+4/6*x^2+6/6*x^3+20/6*x^4+16/6*x^5+9/6*x^6+24/6*x^7+16/6*x^8
-
- where all coefficients have the same denominator 6. Notice though that
- ``\PolToExpr{PQ}`` outputs the ``6/6*x^3`` as ``x^3`` because (by
- default) it recognizes and filters out coefficients equal to one or
- minus one (since release ``0.3``). One can use for example
- ``\PolToCSV{PQ}`` to see the internally stored coefficients.
-
- .. [#] prior to ``0.4.1``, ``polexpr`` used to temporarily patch
- during the parsing of polynomials the xintfrac_ macros. This
- patch was backported to xint_ at release ``1.3``.
-
-- `\\PolDiff{polname_1}{polname_2}`_ always applies ``\xintIrr`` to the
- resulting coefficients, except that the *power of ten* part ``[N]``
- (for example an input in scientific notation such as ``1.23e5`` gives
- ``123/1[3]`` internally in xintfrac) is not taken into account in the
- reduction of the fraction. This is tentative and may change.
-
- Same remark for `\\PolAntiDiff{polname_1}{polname_2}`_.
-
-- Currently, the package stores all coefficients from index ``0`` to
- index equal to the polynomial degree inside a single macro, as a list.
- This data structure is obviously very inefficient for polynomials of
- high degree and few coefficients (as an example with ``\poldef
- f(x):=x^1000 + x^500;`` the subsequent definition ``\poldef g(x):=
- f(x)^2;`` will do of the order of 1,000,000 multiplications and
- additions involvings only zeroes... which does take time). This
- may change in the future.
-
-- As is to be expected internal structures of the package are barely
- documented and unstable. Don't use them.
-
-
-CHANGE LOG
-----------
-
-- v0.1 (2018/01/11): initial release. Features:
-
- * The `\\poldef <poldef;_>`_ parser itself,
- * Differentiation and anti-differentiation,
- * Euclidean division and GCDs,
- * Various utilities such as `\\PolFromCSV <PolFromCSV_>`_,
- `\\PolMapCoeffs <PolMapCoeffs_>`_,
- `\\PolToCSV <PolToCSV_>`_, `\\PolToExpr <PolToExpr_>`_, ...
-
- Only one-variable polynomials so far.
-
-- v0.2 (2018/01/14)
-
- * Fix: ``"README thinks \numexpr recognizes ^ operator"``.
- * Convert README to reStructuredText markup.
- * Move main documentation from README to separate ``polexpr.txt`` file.
- * Provide ``polexpr.html`` as obtained via DocUtils_ ``rst2html.py``.
- * Convert README to (CTAN compatible) Markdown markup.
-
- Due to lack of available time the test suite might not be extensive
- enough. Bug reports are very welcome!
-
-- v0.3 (2018/01/17)
-
- * bug fixes:
-
- - the ``0.1`` `\\PolEval <PolEvalAt_>`_ accepted expressions for its second
- argument, but this was removed by mistake at ``0.2``. Restored.
-
- **Attention**: at ``0.4`` this has been reverted again, and
- `\\PolEval{P}\\AtExpr{foo} <PolEvalAtExpr_>`_ syntax is needed for
- using expressions in the second argument.
- * incompatible or breaking changes:
-
- - `\\PolToExpr <PolToExpr_>`_ now by default uses *descending*
- powers (it also treats differently coefficients equal to 1 or -1.)
- Use `\\PolToExpr* <PolToExpr*_>`_ for *ascending* powers.
- - `\\PolEval <PolEvalAt_>`_ reduced the output to smallest terms,
- but as this is costly with big fractions and not needed if e.g.
- wrapped in an ``\xintRound`` or ``\xintFloat``, this step has been
- removed; the former meaning is available as `\\PolEvalReduced
- <PolEvalReducedAt_>`_.
- * new (or newly documented) macros:
-
- - `\\PolTypesetCmd <PolTypesetCmd_>`_
- - `\\PolTypesetCmdPrefix <PolTypesetCmdPrefix_>`_
- - `\\PolTypesetMonomialCmd <PolTypesetMonomialCmd_>`_
- - `\\PolEvalReducedAt <PolEvalReducedAt_>`_
- - `\\PolToFloatExpr <PolToFloatExpr_>`_
- - `\\PolToExprOneTerm <PolToExprOneTerm_>`_
- - `\\PolToFloatExprOneTerm <PolToFloatExprOneTerm_>`_
- - `\\PolToExprCmd <PolToExprCmd_>`_
- - `\\PolToFloatExprCmd <PolToFloatExprCmd_>`_
- - `\\PolToExprTermPrefix <PolToExprTermPrefix_>`_
- - `\\PolToExprVar <PolToExprVar_>`_
- - `\\PolToExprTimes <PolToExprTimes_>`_
- * improvements:
-
- - documentation has a table of contents, internal hyperlinks,
- standardized signature notations and added explanations.
- - one can do ``\PolLet{g}={f}`` or ``\PolLet{g}{f}``.
- - ``\PolToExpr{f}`` is highly customizable.
- - `\\poldef <poldef;_>`_ and other defining macros prepare the polynomial
- functions for usage within ``\xintthefloatexpr`` (or
- ``\xintdeffloatvar``). Coefficients are pre-rounded to the
- floating point precision. Indispensible for numerical algorithms,
- as exact fractions, even reduced, quickly become very big. See the
- documentation about how to use the exact polynomials also in
- floating point context.
-
- **Attention**: this has been reverted at ``0.4``. The macro
- `\\PolGenFloatVariant <PolGenFloatVariant_>`_ must be used for
- generation floating point polynomial functions.
-
-- v0.3.1 (2018/01/18)
-
- Fixes two typos in example code included in the documentation.
-
-- v0.4 (2018/02/16)
-
- * bug fixes:
-
- - when Euclidean division gave a zero remainder, the internal
- representation of this zero polynomial could be faulty; this
- could cause mysterious bugs in conjunction with other package
- macros such as `\\PolMapCoeffs <PolMapCoeffs_>`_.
- - `\\PolGCD <PolGCD_>`_ was buggy in case of first polynomial being
- of lesser degree than the second one.
- * breaking changes:
-
- - formerly `\\PolEval{P}\\At{foo} <PolEvalAt_>`_ allowed ``foo`` to
- be an expression, which was transparently handled via
- ``\xinttheexpr``. Now, ``foo`` must be a fraction (or a macro
- expanding to such) in the format acceptable by ``xintfrac.sty``
- macros. Use `\\PolEval{P}\\AtExpr{foo} <PolEvalAtExpr_>`_ for more
- general arguments using expression syntax. E.g., if ``foo`` is the
- name of a variable known to ``\xintexpr``.
-
- The same holds for `\\PolEvalReduced <PolEvalReducedAt_>`_
- and `\\PolFloatEval <PolFloatEvalAt_>`_.
- - the ``3.0`` automatic generation of floating point variants has
- been reverted. Not only do *not* the package macros automatically
- generate floating point variants of newly created polynomials,
- they actually make pre-existing such variant undefined.
-
- See `\\PolGenFloatVariant <PolGenFloatVariant_>`_.
- * new non-expandable macros:
-
- - `\\PolGenFloatVariant <PolGenFloatVariant_>`_
- - `\\PolGlobalLet <PolGlobalLet_>`_
- - `\\PolTypesetOne <PolTypesetOne_>`_
- - `\\PolQuo <PolQuo_>`_
- - `\\PolRem <PolRem_>`_
- - `\\PolToSturm <PolToSturm_>`_
- - `\\PolToSturm\* <PolToSturm*_>`_
- - `\\PolSetToSturmChainSignChangesAt <PolSetToSturmChainSignChangesAt_>`_
- - `\\PolSetToNbOfZerosWithin <PolSetToNbOfZerosWithin_>`_
- - `\\PolSturmIsolateZeros <PolSturmIsolateZeros_>`_
- - `\\PolRefineInterval* <PolRefineInterval*_>`_
- - `\\PolRefineInterval[N] <PolRefineInterval[N]_>`_
- - `\\PolEnsureIntervalLength <PolEnsureIntervalLength_>`_
- - `\\PolEnsureIntervalLengths <PolEnsureIntervalLengths_>`_
- - `\\PolPrintIntervals <PolPrintIntervals_>`_
- - `\\PolPrintIntervalsPrintExactZero <PolPrintIntervalsPrintExactZero_>`_
- - `\\PolPrintIntervalsPrintLeftEndPoint <PolPrintIntervalsPrintLeftEndPoint_>`_
- - `\\PolPrintIntervalsPrintRightEndPoint <PolPrintIntervalsPrintRightEndPoint_>`_
- - `\\PolReduceCoeffs* <PolReduceCoeffs*_>`_
- - `\\PolMakeMonic <PolMakeMonic_>`_
- * new expandable macros:
-
- - `\\PolToExprOneTermStyleA <PolToExprOneTermStyleA_>`_
- - `\\PolIfCoeffIsPlusOrMinusOne <PolIfCoeffIsPlusOrMinusOne_>`_
- - `\\PolLeadingCoeff <PolLeadingCoeff_>`_
- - `\\PolSturmChainLength <PolSturmChainLength_>`_
- - `\\PolSturmNbOfIsolatedZeros <PolSturmNbOfIsolatedZeros_>`_
- - `\\PolSturmIfZeroExactlyKnown <PolSturmIfZeroExactlyKnown_>`_
- - `\\PolSturmIsolatedZeroLeft <PolSturmIsolatedZeroLeft_>`_
- - `\\PolSturmIsolatedZeroRight <PolSturmIsolatedZeroRight_>`_
- - ``\PolPrintIntervalsTheEndPoint`` (removed at 0.7)
- - `\\PolPrintIntervalsTheIndex`_
- - ``\PolIfEndPointIsPositive`` (removed at 0.7)
- - ``\PolIfEndPointIsNegative`` (removed at 0.7)
- - ``\PolIfEndPointIsZero`` (removed at 0.7)
- - `\\PolIntervalWidth <PolIntervalWidth_>`_
- - `\\PolDecToString <PolDecToString_>`_
- * improvements:
-
- The main new feature is implementation of the `Sturm algorithm`_
- for localization of the real roots of polynomials.
-
-- v0.4.1 (2018/03/01)
-
- Synced with xint 1.3.
-
-- v0.4.2 (2018/03/03)
-
- Documentation fix.
-
-- v0.5 (2018/04/08)
-
- * bug fixes:
-
- - `\\PolGet{polname}\\fromarray\\macro`_ crashed when ``\macro`` was
- an xinttools_ array macro with no items. It now produces the zero
- polynomial.
- * breaking changes:
-
- - `\\PolToSturm`_ creates primitive integer coefficients polynomials.
- This speeds up localization of roots via
- `\\PolSturmIsolateZeros`_. In case of user protests the author
- will make available again the code producing the bona fide Sturm
- polynomials as used formerly.
- - polynomials created from `\\PolFromCSV`_ or `\\PolGet <PolGet_>`_
- get their coefficients normalized via xintfrac_\ 's ``\xintRaw``.
- * experimental change:
-
- - optional argument to `\\PolSturmIsolateZeros`_ (see `The
- degree 41 polynomial with -2, -1.9, -1.8, ..., 0, 0.1, ..., 1.9, 2
- as roots`_ for usage). It will presumably be replaced in future by
- an interval specification.
- * new non-expandable macro:
-
- - `\\PolMakePrimitive`_
- * new expandable macro:
-
- - `\\PolIContent`_
-
-- v0.5.1 (2018/04/22)
-
- * new feature:
-
- - the character ``'`` can be used in polynomial names.
-
-- v0.6 (2018/11/20)
-
- * bugfix:
-
- - the starred variant `\\PolToSturm*{polname}{sturmname}`_ was
- broken. On the occasion of the fix, its meaning has been modified,
- see its documentation.
-
- - using `\\PolToSturm <PolToSturm_>`_ with a constant polynomial
- caused a division by zero error.
-
- * new macro:
-
- - `\\PolSturmIsolateZeros* <PolSturmIsolateZeros*_>`_
- acts like the `non-starred variant
- <PolSturmIsolateZeros_>`_ then computes all the multiplicities.
-
- * new expandable macros:
-
- - `\\PolSturmIsolatedZeroMultiplicity{sturmname}{index}`_
- - `\\PolSturmNbOfRootsOf{sturmname}\\LessThanOrEqualTo{value}`_
- - `\\PolSturmNbOfRootsOf{sturmname}\\LessThanOrEqualToExpr{expression}`_
- - `\\PolSturmNbWithMultOfRootsOf{sturmname}\\LessThanOrEqualTo{value}`_
- - `\\PolSturmNbWithMultOfRootsOf{sturmname}\\LessThanOrEqualToExpr{expression}`_
-
-- v0.7 (2018/12/08), v0.7.1 (bugfix), v0.7.2 (2nd bugfix) (2018/12/09)
-
- * breaking changes:
-
- - although `\\PolPrintIntervals[varname]{sturmname}`_ default output
- remains the same, some auxiliary macros for user-customization
- have been removed: ``\PolPrintIntervalsTheEndPoint``,
- ``\PolIfEndPointIsPositive{A}{B}``,
- ``\PolIfEndPointIsNegative{A}{B}``, and
- ``\PolIfEndPointIsZero{A}{B}``.
-
- * bugfix:
-
- - it could happen that, contrarily to documentation, an interval
- computed by `\\PolSturmIsolateZeros{sturmname}`_ had zero as an
- endpoint,
- - `\\PolEnsureIntervalLength{sturmname}{index}{E}`_ could under
- certain circumstances erroneously replace a non-zero root by
- zero,
- - `\\PolEnsureIntervalLengths{sturmname}{E}`_ crashed when used with
- a polynomial with no real roots, hence for which no isolation intervals
- existed (thanks to Thomas Söll for report).
-
- * new macros:
-
- - `\\PolSturmIsolateZeros**{sturmname}`_
- - `\\PolSturmIsolateZerosGetMultiplicitiesAndRationalRoots{sturmname}`_
- - `\\PolSturmIsolateZerosAndFindRationalRoots{sturmname}`_
- - `\\polexprsetup`_
- - `\\PolPrintIntervals* <PolPrintIntervals*_>`_
- - `\\PolPrintIntervalsNoRealRoots`_
- - `\\PolPrintIntervalsBeginEnv`_
- - `\\PolPrintIntervalsEndEnv`_
- - `\\PolPrintIntervalsKnownRoot`_
- - `\\PolPrintIntervalsUnknownRoot`_
- - `\\PolPrintIntervalsPrintMultiplicity`_
-
- * new expandable macros:
-
- - `\\PolSturmNbOfRationalRoots{sturmname}`_
- - `\\PolSturmNbOfRationalRootsWithMultiplicities{sturmname}`_
- - `\\PolSturmRationalRoot{sturmname}{k}`_
- - `\\PolSturmRationalRootIndex{sturmname}{k}`_
- - `\\PolSturmRationalRootMultiplicity{sturmname}{k}`_
- - `\\PolPrintIntervalsTheVar`_
- - `\\PolPrintIntervalsTheSturmName`_
- - `\\PolPrintIntervalsTheMultiplicity`_
-
-- v0.7.3 (2019/02/04)
-
- * bugfix:
-
- - Debugging information not destined to user showed in log if root
- finding was done under ``\xintverbosetrue`` regime.
- - `\\PolPrintIntervalsTheVar`_ remained defined after
- `\\PolPrintIntervals`_ but was left undefined after
- `\\PolPrintIntervals*`_ (reported by Jürgen Gilg). Now remains
- defined in both cases, and `\\PolPrintIntervalsTheSturmName`_
- also.
- - Polynomial names ending in digits caused errors (reported by Thomas
- Söll).
-
-- v0.7.4 (2019/02/12)
-
- * bugfix:
-
- - 20000000000 is too big for ``\numexpr``, shouldn't I know that?
- Thanks to Jürgen Gilg for report.
-
-- v0.7.5 (2020/01/31)
-
- Synced with xint 1.4. Requires it.
-
-
-Acknowledgments
----------------
-
-Thanks to Jürgen Gilg whose question about xint_ usage for
-differentiating polynomials was the initial trigger leading to this
-package, and to Jürgen Gilg and Thomas Söll for testing it on some
-concrete problems.
-
-Renewed thanks to them on occasion of the ``0.6`` and ``0.7`` releases for their
-continued interest.
-
-See README.md for the License.
-
-.. _xinttools:
-.. _xintfrac:
-.. _xintexpr:
-.. _xint: http://www.ctan.org/pkg/xint
-
-.. _Wilkinson polynomial: https://en.wikipedia.org/wiki/Wilkinson%27s_polynomial
-
-.. _Sturm algorithm:
-.. _Sturm Theorem: https://en.wikipedia.org/wiki/Sturm%27s_theorem
-
-.. _DocUtils: http://docutils.sourceforge.net/docs/index.html
diff --git a/macros/latex/contrib/srdp-mathematik/README.txt b/macros/latex/contrib/srdp-mathematik/README.txt
index 98bf90021a..af803dd1eb 100644
--- a/macros/latex/contrib/srdp-mathematik/README.txt
+++ b/macros/latex/contrib/srdp-mathematik/README.txt
@@ -1,28 +1,28 @@
-__________________________________
-
- The
- srdp-mathematik package
- v1.8
-
- 2021/03/18
-___________________________________
-
-Maintainer: Christoph Weberndorfer
-E-mail : c.weberndorfer@gmail.com
- Comments, bug reports and suggestions are welcome.
-Licence : Released under the LaTeX Project Public License 1.3c or
- later, see http://www.latex-project.org/lppl.txt
-
-----------------------------------------------------------------------
-
-This package provides basic commands for the defined formats of the Austrian sRDP in mathematics.
-Furthermore, it includes ways to implement answers in the tex file, which can be voluntarily displayed in the pdf file and
-it offers a way of varying the answers in order to create different groups (e.g. for tests) easily.
-
-----------------------------------------------------------------------
-
-Dieses Paket bietet grundlegende Befehle für die vorgegebenen Formate der österreichischen, standardisierten
-Reife- und Diplomprüfung (sRDP) in Mathematik.
-Es bietet darüber hinaus die Möglichkeit, Antworten in die tex Datei zu implentieren und diese bei Bedarf in der pdf Datei anzuzeigen.
-Außerdem können die eingegeben Antwortmöglichkeiten variiert werden, um mehrere Gruppe für zum Beispiel Schularbeiten einfach zu erstellen.
-
+__________________________________
+
+ The
+ srdp-mathematik package
+ v1.9.0
+
+ 2021/03/29
+___________________________________
+
+Maintainer: Christoph Weberndorfer
+E-mail : c.weberndorfer@gmail.com
+ Comments, bug reports and suggestions are welcome.
+Licence : Released under the LaTeX Project Public License 1.3c or
+ later, see http://www.latex-project.org/lppl.txt
+
+----------------------------------------------------------------------
+
+This package provides basic commands for the defined formats of the Austrian sRDP in mathematics.
+Furthermore, it includes ways to implement answers in the tex file, which can be voluntarily displayed in the pdf file and
+it offers a way of varying the answers in order to create different groups (e.g. for tests) easily.
+
+----------------------------------------------------------------------
+
+Dieses Paket bietet grundlegende Befehle für die vorgegebenen Formate der österreichischen, standardisierten
+Reife- und Diplomprüfung (sRDP) in Mathematik.
+Es bietet darüber hinaus die Möglichkeit, Antworten in die tex Datei zu implentieren und diese bei Bedarf in der pdf Datei anzuzeigen.
+Außerdem können die eingegeben Antwortmöglichkeiten variiert werden, um mehrere Gruppe für zum Beispiel Schularbeiten einfach zu erstellen.
+
diff --git a/macros/latex/contrib/srdp-mathematik/srdp-mathematik.pdf b/macros/latex/contrib/srdp-mathematik/srdp-mathematik.pdf
index 610ae58130..81b5cbc449 100644
--- a/macros/latex/contrib/srdp-mathematik/srdp-mathematik.pdf
+++ b/macros/latex/contrib/srdp-mathematik/srdp-mathematik.pdf
Binary files differ
diff --git a/macros/latex/contrib/srdp-mathematik/srdp-mathematik.sty b/macros/latex/contrib/srdp-mathematik/srdp-mathematik.sty
index 6176e19db1..09bf9fd8ab 100644
--- a/macros/latex/contrib/srdp-mathematik/srdp-mathematik.sty
+++ b/macros/latex/contrib/srdp-mathematik/srdp-mathematik.sty
@@ -10,7 +10,7 @@
%
\NeedsTeXFormat{LaTeX2e}[1996/12/26]
-\ProvidesPackage{srdp-mathematik}[2021/03/18 v1.8 Standard-Schularbeitsformate]
+\ProvidesPackage{srdp-mathematik}[2021/03/29 v1.9.0 Standard-Schularbeitsformate]
\usepackage{color}
@@ -309,54 +309,38 @@
%
%%%%%%%%%%%% NOTENSCHLUESSEL %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
-%
-\newcommand{\notenschluessel}[5][]{
-\vfill
+%
+
+\NewDocumentCommand{\notenschluessel}{ O{} O{} O{} m m m m}{
+\null\vfill
\STautoround{3}\renewcommand{\arraystretch}{0}\tiny
\begin{spreadtab}[\STsavecell\gutgenau{b2} \STsavecell\befriedigendgenau{c2} \STsavecell\genuegendgenau{d2} \STsavecell\nichtgenuegendgenau{e2}
\STsavecell\gut{b3} \STsavecell\befriedigend{c3} \STsavecell\genuegend{d3} \STsavecell\nichtgenuegend{e3}
\STsavecell\gutpluseins{b4} \STsavecell\befriedigendpluseins{c4} \STsavecell\genuegendpluseins{d4} \STsavecell\nichtgenuegendpluseins{e4} \STsavecell\gutminuseins{b5} \STsavecell\befriedigendminuseins{c5} \STsavecell\genuegendminuseins{d5} \STsavecell\nichtgenuegendminuseins{e5}]{{tabular}{ccccc}}
- \SThidecol\thepunkte &\SThidecol 1 &\SThidecol2 &\SThidecol 3 &\SThidecol 4 \\
- & a1*#2 &a1*#3 & a1*#4 & a1*#5 \\
- &trunc(a1*#2,0) & trunc(a1*#3,0) &trunc(a1*#4,0) &trunc(a1*#5,0) \\
- &b3+1 &c3+1 &d3+1 & e3+1\\
- &b3-1 &c3-1 &d3-1 & e3-1\\
+ \SThidecol\thepunkte &\SThidecol 1 &\SThidecol2 &\SThidecol 3 &\SThidecol 4 \\
+ & a1*#4 &a1*#5 & a1*#6 & a1*#7 \\
+ &trunc(a1*#4,0) & trunc(a1*#5,0) &trunc(a1*#6,0) &trunc(a1*#7,0) \\
+ &b3+1 &c3+1 &d3+1 & e3+1\\
+ &b3-1 &c3-1 &d3-1 & e3-1\\
\end{spreadtab}
\footnotesize\renewcommand{\arraystretch}{1}
\begin{center}
\begin{tabular}{|C{3cm}C{3cm}C{3cm}C{3cm}C{3cm}|} \hline
+\ifthenelse{\equal{#2}{prozent}}{%
Erreichte Punkte & Prozent & Gesamt & \multicolumn{2}{c|}{Note} \\
-&& \multirow{2}{*}{\thepunkte} && \\
-&&&& \\ \hline \hline
-\scriptsize{Sehr gut} & \scriptsize{Gut} & \scriptsize{Befriedigend} & \scriptsize{Gen\"ugend} & \scriptsize{Nicht gen\"ugend} \\
-\scriptsize{\thepunkte ~ - \ifdim\gut pt=\gutgenau pt \gut\else\gutpluseins\fi}& \scriptsize{\ifdim\gut pt=\gutgenau pt \gutminuseins\else\gut\fi \ifthenelse{\equal{#1}{1/2}}{,5}{} ~ - \ifdim\befriedigend pt=\befriedigendgenau pt \befriedigend\else\befriedigendpluseins\fi} & \scriptsize{\ifdim\befriedigend pt=\befriedigendgenau pt \befriedigendminuseins\else\befriedigend\fi \ifthenelse{\equal{#1}{1/2}}{,5}{} ~ - \ifdim\genuegend pt=\genuegendgenau pt \genuegend\else\genuegendpluseins\fi} & \scriptsize{\ifdim\genuegend pt=\genuegendgenau pt \genuegendminuseins\else\genuegend\fi \ifthenelse{\equal{#1}{1/2}}{,5}{} ~ - \ifdim\nichtgenuegend pt=\nichtgenuegendgenau pt \nichtgenuegend\else\nichtgenuegendpluseins\fi} & \scriptsize{unter \ifdim\nichtgenuegend pt=\nichtgenuegendgenau pt \nichtgenuegend\else\nichtgenuegendpluseins\fi} \\ \hline
-\end{tabular}
-\end{center}\STautoround{}\normalsize}
-
-\newcommand{\notenschluesselop}[5][]{
-\vfill
-\STautoround{3}\renewcommand{\arraystretch}{0}\tiny
-\begin{spreadtab}[\STsavecell\gutgenau{b2} \STsavecell\befriedigendgenau{c2} \STsavecell\genuegendgenau{d2}
-\STsavecell\gut{b3} \STsavecell\befriedigend{c3} \STsavecell\genuegend{d3} \STsavecell\nichtgenuegend{e3}
-\STsavecell\gutpluseins{b4} \STsavecell\befriedigendpluseins{c4} \STsavecell\genuegendpluseins{d4} \STsavecell\gutminuseins{b5} \STsavecell\befriedigendminuseins{c5} \STsavecell\genuegendminuseins{d5}]{{tabular}{ccccc}}
- \SThidecol \thepunkte &\SThidecol 1 &\SThidecol 2 &\SThidecol 3 &\SThidecol 4 \\
- & a1*#2 &a1*#3 & a1*#4 & a1*#5 \\
- &trunc(a1*#2,0) & trunc(a1*#3,0) &trunc(a1*#4,0) &trunc(a1*#5,0) \\
- &b3+1 &c3+1 &d3+1 & e3+1\\
- &b3-1 &c3-1 &d3-1 & e3-1\\
-\end{spreadtab}
-\footnotesize\renewcommand{\arraystretch}{1}
-\begin{center}
-\begin{tabular}{|C{3cm}C{3cm}C{3cm}C{3cm}C{3cm}|} \hline
+&& \multirow{2}{*}{\thepunkte} && \\%
+}{%
Erreichte Punkte &Gesamt&\multicolumn{2}{c}{Note}& \\
-&\multirow{2}{*}{\thepunkte} &&& \\
+&\multirow{2}{*}{\thepunkte} &&& \\}
&&&& \\ \hline \hline
-\scriptsize{Sehr gut} & \scriptsize{Gut} & \scriptsize{Befriedigend} & \scriptsize{Gen\"ugend} & \scriptsize{Nicht gen\"ugend} \\
-\scriptsize{\thepunkte ~ - \ifdim\gut pt=\gutgenau pt \gut\else\gutpluseins\fi}& \scriptsize{\ifdim\gut pt=\gutgenau pt \gutminuseins\else\gut\fi \ifthenelse{\equal{#1}{1/2}}{,5}{} ~ - \ifdim\befriedigend pt=\befriedigendgenau pt \befriedigend\else\befriedigendpluseins\fi} & \scriptsize{\ifdim\befriedigend pt=\befriedigendgenau pt \befriedigendminuseins\else\befriedigend\fi \ifthenelse{\equal{#1}{1/2}}{,5}{} ~ - \ifdim\genuegend pt=\genuegendgenau pt \genuegend\else\genuegendpluseins\fi} & \scriptsize{\ifdim\genuegend pt=\genuegendgenau pt \genuegendminuseins\else\genuegend\fi \ifthenelse{\equal{#1}{1/2}}{,5}{} ~ - \ifdim\nichtgenuegend pt=\nichtgenuegendgenau pt \nichtgenuegend\else\nichtgenuegendpluseins\fi} & \scriptsize{unter \ifdim\nichtgenuegend pt=\nichtgenuegendgenau pt \nichtgenuegend\else\nichtgenuegendpluseins\fi} \\ \hline
+\ifthenelse{\equal{#3}{ms}}{}{\scriptsize{Sehr gut}} & \ifthenelse{\equal{#3}{ms}}{}{\scriptsize{Gut}} & \scriptsize{Befriedigend} & \scriptsize{Gen\"ugend} & \scriptsize{Nicht gen\"ugend} \\
+\ifthenelse{\equal{#3}{ms}}{}{\scriptsize{\thepunkte ~ - \ifdim\gut pt=\gutgenau pt \gut\else\gutpluseins\fi}}& \ifthenelse{\equal{#3}{ms}}{}{\scriptsize{\ifdim\gut pt=\gutgenau pt \gutminuseins\else\gut\fi \ifthenelse{\equal{#1}{1/2}}{,5}{} ~ - \ifdim\befriedigend pt=\befriedigendgenau pt \befriedigend\else\befriedigendpluseins\fi}} & \scriptsize{\ifdim\befriedigend pt=\befriedigendgenau pt \befriedigendminuseins\else\befriedigend\fi \ifthenelse{\equal{#1}{1/2}}{,5}{} ~ - \ifdim\genuegend pt=\genuegendgenau pt \genuegend\else\genuegendpluseins\fi} & \scriptsize{\ifdim\genuegend pt=\genuegendgenau pt \genuegendminuseins\else\genuegend\fi \ifthenelse{\equal{#1}{1/2}}{,5}{} ~ - \ifdim\nichtgenuegend pt=\nichtgenuegendgenau pt \nichtgenuegend\else\nichtgenuegendpluseins\fi} & \scriptsize{unter \ifdim\nichtgenuegend pt=\nichtgenuegendgenau pt \nichtgenuegend\else\nichtgenuegendpluseins\fi} \\ \hline
\end{tabular}
\end{center}\STautoround{}\normalsize}
-
+% for legacy reason
+\newcommand{\notenschluesselop}[5][1]{\notenschluessel[#1]{#2}{#3}{#4}{#5}}
+%%%%%%%%%%%%%%%%%
%
%%%%%%%%%%%%%%%%%% GAP DEFINITION
diff --git a/macros/latex/contrib/srdp-mathematik/srdp-mathematik.tex b/macros/latex/contrib/srdp-mathematik/srdp-mathematik.tex
index 8dbc5baae6..1df75d3560 100644
--- a/macros/latex/contrib/srdp-mathematik/srdp-mathematik.tex
+++ b/macros/latex/contrib/srdp-mathematik/srdp-mathematik.tex
@@ -55,7 +55,7 @@ hidelinks
\vfill
-\Huge The \textit{srdp-mathematik} package v1.8\\[1cm]
+\Huge The \textit{srdp-mathematik} package v1.9.0\\[1cm]
Documentation \\ [1cm]
@@ -93,7 +93,7 @@ Die \textit{allgemeinen Befehle} erleichtern das Erstellen von Tests, Schularbei
Jedes Beispiel sollte innerhalb einer Beispielumgebung gesetzt werden, welche bei der Formatierung und der Verarbeitung der Punkte unterstützt. Dabei werden zwei Beispiel-Typen unterschieden: \texttt{beispiel} und \texttt{langesbeispiel}.
\vspace{1cm}
-\subsubsection{\texttt{beispiel}-Umbgebung}
+\subsubsection{\texttt{\textbackslash begin\{beispiel\} \ldots\ \textbackslash end\{beispiel\}}}
Die \texttt{beispiel}-Umgebung dient zur Erstellung eines Beispiels einer Schularbeit, einer Prüfung, usw. Dabei sind praktisch alle Funktionen von \LaTeX, wie Text, Formeln oder Grafiken möglich. Diese Umgebung erlaubt jedoch keinen Seitenumbruch! Die Beispiele werden automatisch nummeriert.
@@ -127,7 +127,7 @@ $\frac{x^2+x+5}{\sqrt{x^3}}$
\vspace{1cm}
-\subsubsection{\texttt{langesbeispiel}-Umbgebung}
+\subsubsection{\texttt{\textbackslash begin\{langesbeispiel\} \ldots\ \textbackslash end\{langesbeispiel\}}}
Die \texttt{langesbeispiel}-Umgebung dient ebenso zur Erstellung eines Beispiels, funktioniert analog, erlaubt aber im Gegensatz zur \texttt{beispiel}-Umgebung Seitenumbrüche. Auch lange Beispiele werden weiterführend nummeriert.
@@ -159,48 +159,83 @@ $\frac{x^2+x+5}{\sqrt{x^3}}$.
-\subsubsection{Notenschlüssel}
+\subsubsection{\texttt{\textbackslash notenschluessel}}
Werden für alle Beispiele die \texttt{beispiel}- oder die \texttt{langesbeispiel}-Umgebung verwendet, wird die Gesamtpunktezahl sowie der Notenschlüssel automatisch berechnet. Die Werte in Klammer geben dabei den prozentualen Notenschlüssel vor und können beliebig variiert werden:
\vspace{0.4cm}
+\setcounter{punkte}{48}
+
+
+\vspace{0.3cm}
+
+\textsc{Ausgabe:}
+\notenschluessel{0.91}{0.8}{0.64}{0.5}
+\vfill
+
+Der Befehl \texttt{notenschluessel} bietet auch die Eingabe von drei unterschiedlichen Optionen, die alle einzeln oder gemeinsam verwendet werden können. Wichtig: Wird Option 3 benötigt (jedoch Option 1 \& 2 nicht) müssen die Optionen 1 \& 2 jeweils mit leerer Klammer \texttt{[]} angegeben werden.
+
+\subsubsection*{\texttt{\textbackslash notenschluessel} -- Option 1: Halbe Punkte-Schritte}
+
+Durch die Option 1 \texttt{[1/2]} wird die Anzeige auf halbe Punkte-Schritten geändert.
\textsc{Eingabe:}
\begin{verbatim}
-\notenschluessel{0.91}{0.8}{0.64}{0.5}
+\notenschluessel[1/2]{0.91}{0.8}{0.64}{0.5}
\end{verbatim}
-\vspace{0.3cm}
-
\textsc{Ausgabe:}
-\notenschluessel{0.91}{0.8}{0.64}{0.5}
+\notenschluessel[1/2]{0.91}{0.8}{0.64}{0.5}
+
-\normalsize
+\subsubsection*{\texttt{\textbackslash notenschluessel} -- Option 2: Prozentanzeige}
-\paragraph{Notenschlüssel - Ohne Prozentangabe}
-Analog zum \texttt{notenschluessel} funktioniert auch der Befehl \texttt{notenschluesselop}. Es wird dabei jedoch die Prozentspalte nicht angezeigt.
+Die Option 2 \texttt{[prozent]} ergänzt die erste Zeile des Notenschlüssel mit einer prozentuellen Angabe.
\textsc{Eingabe:}
\begin{verbatim}
-\notenschluesselop{0.91}{0.8}{0.64}{0.5}
+\notenschluessel[][prozent]{0.91}{0.8}{0.64}{0.5}
\end{verbatim}
\textsc{Ausgabe:}
-\notenschluessel{0.91}{0.8}{0.64}{0.5}
+\notenschluessel[][prozent]{0.91}{0.8}{0.64}{0.5}
-\paragraph{Notenschlüssel - Option: [1/2]}
+\subsubsection*{\texttt{\textbackslash notenschluessel} -- Option 3: Standard der Mittelschule}
-Die Option 1/2 ermöglicht die Anzeige des Notenschlüssel (mit oder ohne Prozentspalte) mit halben Punkten.
+Die option 3 \texttt{ms} ermöglicht die Darstellung des Notenschlüssels entsprechend des Standards der Mittelschule.
\textsc{Eingabe:}
\begin{verbatim}
-\notenschluessel[1/2]{0.91}{0.8}{0.64}{0.5}
+\notenschluessel[][][ms]{0.91}{0.8}{0.64}{0.5}
\end{verbatim}
\textsc{Ausgabe:}
-\notenschluessel[1/2]{0.91}{0.8}{0.64}{0.5}
+\notenschluessel[][][ms]{0.91}{0.8}{0.64}{0.5}
+
+%\paragraph{Notenschlüssel - Ohne Prozentangabe}
+%Analog zum \texttt{notenschluessel} funktioniert auch der Befehl \texttt{notenschluesselop}. Es wird dabei jedoch die Prozentspalte nicht angezeigt.
+%
+%\textsc{Eingabe:}
+%\begin{verbatim}
+%\notenschluesselop{0.91}{0.8}{0.64}{0.5}
+%\end{verbatim}
+%
+%\textsc{Ausgabe:}
+%\notenschluessel{0.91}{0.8}{0.64}{0.5}
+
+%\paragraph{Notenschlüssel - Option: [1/2]}
+%
+%Die Option 1/2 ermöglicht die Anzeige des Notenschlüssel (mit oder ohne Prozentspalte) mit halben Punkten.
+%
+%\textsc{Eingabe:}
+%\begin{verbatim}
+%\notenschluessel[1/2]{0.91}{0.8}{0.64}{0.5}
+%\end{verbatim}
+%
+%\textsc{Ausgabe:}
+%\notenschluessel[1/2]{0.91}{0.8}{0.64}{0.5}
-\subsubsection{Beurteilungsraster}
+\subsubsection{\texttt{\textbackslash beurteilungsraster}}
Der Befehl \texttt{beurteilungsraster} entspricht der aktuellen Vorgabe der Beurteilung der standardisierten Reifeprüfung (Stand 2019). Dabei müssen die Punkte für Teil 1, Ausgleichspunkte und Teil 2 angegeben werden. Die in Klammer angegebenen Werte entsprechen der bei der Reifeprüfung verwendeten prozentuellen Notenverteilung, können jedoch jederzeit verändert werden. \leer
@@ -227,7 +262,7 @@ siehe nächste Seite \newpage
\newpage
-\subsection{Lösungseingabe -- Option: \texttt{[solution\_on/off]}}
+\subsection{Paketoption -- Lösungseingabe: \texttt{[solution\_on/off]}}
Es besteht die Möglichkeit, die Lösung in der erstellten \texttt{tex}-Datei zu implementieren und diese bei Bedarf in der \texttt{PDF}-Datei ein- bzw. auszublenden. Um diese Funktion nutzen zu können, muss die \texttt{solution\_on/off} Option im \texttt{srdp-mathematik}-Paket geladen werden. Diese kann durch hinzufügen durch "`\texttt{solution\_on}"' bzw. "`\texttt{solution\_off}"' aktiviert bzw. deaktiviert werden. Also:
@@ -245,11 +280,11 @@ oder
Die korrekte Lösungseingabe der vorformatierten Typ-1-Aufgaben wird bei den entsprechenden Befehlen direkt erklärt. Unabhängig davon, gibt es die Möglichkeit mithilfe des \texttt{antwort}-Befehls, beliebige Abschnitte als \textit{Antwort} zu deklarieren. (verwendeter counter: \texttt{Antworten=0, 1})
-\subsubsection{\texttt{antwort}-Befehl}
+\subsubsection{\texttt{\textbackslash antwort}}
Für offene Antworten kann der \texttt{\textbackslash antwort\{\}}-Befehl verwendet werden. Darin können Textpassagen, mathematische Formeln oder Grafiken angegeben werden, die ausschließlich bei aktivierter Lösung (\texttt{[solution\_on]}) und in \textcolor[rgb]{1,0,0}{rot} angegeben werden. \leer
-\subsubsection{Zusatz: Optionales Argument}
+\subsubsection*{\texttt{\textbackslash antwort} -- Option: Anzeige nur bei \texttt{solution\_off}}
Der \texttt{antwort}-Befehl erlaubt ein optionales Argument. Es können dadurch zusätzliche Textpassagen angegeben werden, die \underline{ausschließlich} angezeigt werden, wenn die Lösungsanzeige deaktiviert (\texttt{[solution\_off])} ist. Das heißt: \leer
@@ -278,7 +313,7 @@ wird.]
\texttt{'solution\_on'} eingestellt ist.}
-\subsection{Erstellung von Gruppen -- Option: \texttt{[random=0,1,2,\ldots]}}
+\subsection{Paketoption -- Erstellung von Gruppen: \texttt{[random=0,1,2,\ldots]}}
Das \texttt{srdp-mathematik}-Paket ermöglicht auch die automatische Erstellung von Gruppen für Schularbeiten, durch Vertauschung der Antwortmöglichkeiten aller Typ-1-Aufgaben. Dazu kann die \texttt{random}-Option im \texttt{srdp-mathematik}-Paket eingebunden geladen werden. Also:
\begin{verbatim}
@@ -299,93 +334,9 @@ Durch das Ersetzen der Zahl "`0"' durch die Zahlen $1, 2, 3, \ldots$ (und anschl
Die Erstellung der Gruppen ist dabei reproduzierbar. Die Reihenfolge der Antwortmöglichkeiten einer Gruppe bleibt daher immer gleich. Mithilfe des Befehls \texttt{\textbackslash Gruppe} kann die Gruppennummer innerhalb der \texttt{PDF}-Datei (z.B. am Deckblatt) angezeigt werden. (verwendeter counter: \texttt{Zufall=0, 1, 2, \ldots})
-%Dieses Prinzip wird exemplarisch am Multiplechoice-Format gezeigt:\leer
-%
-%\textsc{Eingabe:}
-%\begin{verbatim}
-%\multiplechoice[5]{ %Anzahl der Antwortmoeglichkeiten, Standard: 5
- %L1={Antwort 1}, %1. Antwortmoeglichkeit
- %L2={Antwort 2}, %2. Antwortmoeglichkeit
- %L3={Antwort 3}, %3. Antwortmoeglichkeit
- %L4={Antwort 4}, %4. Antwortmoeglichkeit
- %L5={Antwort 5}, %5. Antwortmoeglichkeit
- %L6={}, %6. Antwortmoeglichkeit
- %L7={}, %7. Antwortmoeglichkeit
- %L8={}, %8. Antwortmoeglichkeit
- %L9={}, %9. Antwortmoeglichkeit
- %%% LOESUNG: %%
- %A1=2, % 1. Antwort
- %A2=4, % 2. Antwort
- %A3=0, % 3. Antwort
- %A4=0, % 4. Antwort
- %A5=0, % 5. Antwort
- %}
-%\end{verbatim}
-%
-%\setcounter{Zufall}{0}
-%\textsc{Ausgabe:}, bei \texttt{\textbackslash setcounter\{Zufall\}\{0\}}:
-%
-%\multiplechoice[5]{ %Anzahl der Antwortmoeglichkeiten, Standard: 5
- %L1={Antwort 1}, %1. Antwortmoeglichkeit
- %L2={Antwort 2}, %2. Antwortmoeglichkeit
- %L3={Antwort 3}, %3. Antwortmoeglichkeit
- %L4={Antwort 4}, %4. Antwortmoeglichkeit
- %L5={Antwort 5}, %5. Antwortmoeglichkeit
- %L6={}, %6. Antwortmoeglichkeit
- %L7={}, %7. Antwortmoeglichkeit
- %L8={}, %8. Antwortmoeglichkeit
- %L9={}, %9. Antwortmoeglichkeit
- %%% LOESUNG: %%
- %A1=2, % 1. Antwort
- %A2=4, % 2. Antwort
- %A3=0, % 3. Antwort
- %A4=0, % 4. Antwort
- %A5=0, % 5. Antwort
- %}
- %
-%\setcounter{Zufall}{1}
-%\textsc{Ausgabe:}, bei \texttt{\textbackslash setcounter\{Zufall\}\{1\}}:
-%
-%\multiplechoice[5]{ %Anzahl der Antwortmoeglichkeiten, Standard: 5
- %L1={Antwort 1}, %1. Antwortmoeglichkeit
- %L2={Antwort 2}, %2. Antwortmoeglichkeit
- %L3={Antwort 3}, %3. Antwortmoeglichkeit
- %L4={Antwort 4}, %4. Antwortmoeglichkeit
- %L5={Antwort 5}, %5. Antwortmoeglichkeit
- %L6={}, %6. Antwortmoeglichkeit
- %L7={}, %7. Antwortmoeglichkeit
- %L8={}, %8. Antwortmoeglichkeit
- %L9={}, %9. Antwortmoeglichkeit
- %%% LOESUNG: %%
- %A1=2, % 1. Antwort
- %A2=4, % 2. Antwort
- %A3=0, % 3. Antwort
- %A4=0, % 4. Antwort
- %A5=0, % 5. Antwort
- %}
-%
-%\setcounter{Zufall}{2}
-%\textsc{Ausgabe:}, bei \texttt{\textbackslash setcounter\{Zufall\}\{2\}}:
-%
-%\multiplechoice[5]{ %Anzahl der Antwortmoeglichkeiten, Standard: 5
- %L1={Antwort 1}, %1. Antwortmoeglichkeit
- %L2={Antwort 2}, %2. Antwortmoeglichkeit
- %L3={Antwort 3}, %3. Antwortmoeglichkeit
- %L4={Antwort 4}, %4. Antwortmoeglichkeit
- %L5={Antwort 5}, %5. Antwortmoeglichkeit
- %L6={}, %6. Antwortmoeglichkeit
- %L7={}, %7. Antwortmoeglichkeit
- %L8={}, %8. Antwortmoeglichkeit
- %L9={}, %9. Antwortmoeglichkeit
- %%% LOESUNG: %%
- %A1=2, % 1. Antwort
- %A2=4, % 2. Antwort
- %A3=0, % 3. Antwort
- %A4=0, % 4. Antwort
- %A5=0, % 5. Antwort
- %}
-
-\subsection{Informationseingabe -- Option: \texttt{[info\_on/off]}}
+
+
+\subsection{Paketoption -- Informationseingabe: \texttt{[info\_on/off]}}
Es ist darüber hinaus möglich zusätzliche Informationen (Erläuterungen, Hilfestellungen, \ldots) hinzuzufügen und einzublenden. Dazu kann die Option \texttt{info\_on/off} im \texttt{srdp-mathematik}-Paket eingebunden werden. Die Infos werden in \textcolor[rgb]{0,0,1}{blau} angegeben und nur dann angezeigt, wenn die Option \texttt{info\_on} gewählt wurde (verwendeter counter: \texttt{info=0,1}). Also:
@@ -403,13 +354,13 @@ oder
\subsection{Weitere allgemeine Befehle}
Außerdem gibt es noch weitere Befehle, die die Formatierung erleichtern.
-\subsubsection*{\texttt{\textbackslash leer} - Befehl}
+\subsubsection{\texttt{\textbackslash leer}}
Eine Leerzeile, etwa zwischen zwei Beispielen. \\
(Nach dem Befehl \texttt{\textbackslash leer} muss in der \texttt{.tex}-Datei ein Leerzeile eingefügt werden!)
\leer
-\subsubsection*{\texttt{\textbackslash meinlr} - Befehl}
+\subsubsection{\texttt{\textbackslash meinlr}}
\begin{verbatim}
\meinlr{Dieser Teil steht links. Wenn dieser Text länger sein sollte,
geht er automatisch in der nächsten Zeile weiter ohne auf die andere
@@ -426,7 +377,7 @@ geht er automatisch in der nächsten Zeile weiter ohne auf die andere
Seite über zu gehen.}{Dieser Teil steht rechts.}
-\subsubsection*{Zusatz: Variable Spaltenbreiten bei \texttt{\textbackslash meinlr}}
+\subsubsection*{\texttt{\textbackslash meinlr} -- Option: Variable Spaltenbreiten}
Der Befehl \texttt{\textbackslash meinlr} erlaubt durch die optionale Eingabe eine Abänderung der beiden Spaltenbreiten. Durch die Eingabe zwischen ca. -0.3 und 0.3 kann die Spaltenmitte nach links oder rechts verschoben und somit die Spaltenbreite variiert werden.
@@ -446,7 +397,7 @@ die Spaltenbreiten nach Belieben zu variieren.}
\leer
-\subsubsection*{\texttt{\textbackslash meinlcr} - Befehl}
+\subsubsection{\texttt{\textbackslash meinlcr}}
\begin{verbatim}
\meinlcr{Text ganz links}{Text in der Mitte. Auch hier sind längere Texte
möglich.}{Text auf der rechten Seite.}
@@ -459,15 +410,54 @@ Teilt die Seite in drei gleich große Teile
\meinlcr{Text ganz links. Was passiert hier wenn dieser Teil länger ist?}{Text in der Mitte. Auch hier sind längere Texte möglich.}{Text auf der rechten Seite.}
+
+\subsubsection{\texttt{\textbackslash dint} und \texttt{\textbackslash dx}}
+Die Befehle \texttt{\textbackslash dint} und \texttt{\textbackslash dx} vereinfacht die Eingabe eines Integrals (bestimmt oder unbestimmt).\leer
+
+\textsc{Eingabe:}
+
+\begin{verbatim}
+$\dint_1^3 x^2 \dx$
+\end{verbatim}
+
+\textsc{Ausgabe:}\leer
+
+$\dint_1^3 x^2 \dx$
\leer
+Wird eine Variable ungleich $x$ integriert, kann diese mithilfe der Option \texttt{\textbackslash{dx[Variable]}} dargestellt werden.\leer
+
+\textsc{Eingabe:}
+
+\begin{verbatim}
+$\dint t^2 \dx[t]$
+\end{verbatim}
+
+\textsc{Ausgabe:}\leer
+
+$\dint t^2 \dx[t]$
+
+\subsubsection{\texttt{\textbackslash degre}}
+
+Der \texttt{\textbackslash degre} Befehl stellt das Einheitszeichen für Grad dar. Er kann im Text- und im Mathematik-Modus verwendet werden.
+
+\textsc{Eingabe:}
+
+\begin{verbatim}
+Der Winkel Alpha ist 30\degre. ($\alpha = 30 \degre$)
+\end{verbatim}
+
+\textsc{Ausgabe:}\leer
+
+Der Winkel Alpha ist 30\degre. ($\alpha = 30 \degre$)
+
\section{Typ-1-Aufgaben}
Das \texttt{srdp-mathematik}-Paket ermöglicht die Verwendung vorgefertigter Aufgabenformate, die bei der österreichischen, standardisierten Reifeprüfung Anwendung finden.
-\subsection{\texttt{multiplechoice}-Befehl}
+\subsection{\texttt{\textbackslash multiplechoice}}
Dieser Befehl liefert eine vollständige Formatierung für eine Multiplechoice-Aufgabe. Die Anzahl der Antwortmöglichkeiten kann dabei frei (max. 9) gewählt werden. Als Standard ist dabei das Format mit fünf Antwortmöglichkeiten eingestellt. \leer
@@ -669,7 +659,7 @@ Die Eingabe in eckiger Klammer ist dabei optional. Wird sie nicht angegeben, wir
\leer
\newpage
-\subsubsection{Add-on: \texttt{langmultiplechoice}-Befehl}
+\subsubsection{Add-on: \texttt{\textbackslash langmultiplechoice}}
Der \texttt{langmultiplechoice}-Befehl ist analog zum \texttt{multiplechoice}-Befehl zu verwenden. Der Unterschied besteht darin, dass Antwortmöglichkeiten auf zwei Spalten aufgeteilt werden. Dies ist vor allem dann sinnvoll, wenn Geogebra-Grafiken importiert werden, um eine bessere Lesbarkeit zu ermöglichen.
@@ -790,7 +780,7 @@ Der \texttt{langmultiplechoice}-Befehl ist analog zum \texttt{multiplechoice}-Be
\newpage
-\subsection{\texttt{lueckentext}-Befehl}
+\subsection{\texttt{\textbackslash lueckentext}}
Dieser Befehl dient zur Erstellung eines Lückentexts, basierend auf dem standardisierten Format des BIFIE. Der einleitenden Satz: \textit{"`Ergänze die Textlücken im folgenden Satz durch Ankreuzen der jeweils richtigen Satzteile so, dass eine mathematisch korrekte Aussage entsteht!"'} wird als Standard angenommen und automatisch angegeben. Im Bereich \texttt{\textbackslash text=\{\}} wird der Lückentext angegeben, wobei die Lücken immer mit \texttt{\textbackslash gap} eingefügt werden und automatisch nummeriert werden. Analog zu den Lösungsangaben der Multiplechoice-Aufgabe, werden die korrekten Antworten bei A1, A2 oder A3 mit 1,2 oder 3 angegeben. (hier: Lösung links: 3 und rechts: 2)
\vspace{0.35cm}
@@ -829,7 +819,7 @@ die \gap, die Lücke zwei hat die \gap.}, %Lueckentext Luecke=\gap
}
-\subsubsection{Zusatz: Variable Breiten der Boxen}
+\subsubsection{\texttt{\textbackslash lueckentext} -- Option: Variable Breiten der Boxen}
Der \texttt{lueckentext}-Befehl erlaubt ein optionales Argument, um die Größen der beiden Boxen zu variieren. Dabei werden in den eckigen Klammern $[~]$ die Veränderung der linken Box (Änderung ca. zwischen -0.3 und 0.3) angegeben und die rechte Box wird automatisch angepasst. Will man etwa die linke Box vergrößern, gilt:\leer
@@ -877,7 +867,7 @@ die \gap, die Lücke zwei hat die \gap.}, %Lueckentext Luecke=\gap
Analog funktioniert die Verkleinerung der linken Box. Dazu müssen Werte kleiner 0 angegeben
werden.
-\subsubsection{\texttt{Zusatz}: Englischer Lückentext}
+\subsubsection{\texttt{\textbackslash lueckentext} -- Option: Englischer Lückentext}
Der Befehl \texttt{englueckentext} ist analog zum \texttt{lueckentext}-Befehl zu verwenden. Jedoch wird der als Standard angenommene, einleitende Satz bei Lückentextaufgaben in Englisch angezeigt.
\textsc{Eingabe:}
@@ -911,7 +901,7 @@ Der Befehl \texttt{englueckentext} ist analog zum \texttt{lueckentext}-Befehl zu
A2=3 % Antwort rechts
}
-\subsection{\texttt{zuordnen}-Befehl}
+\subsection{\texttt{\textbackslash zuordnen}}
Dieser Befehl dient zum Erstellen des Zuordnungsformats von vier aus sechs Möglichkeiten.
Die korrekten Antworten können hier frei als Buchstaben eingegeben werden. (hier: F, C, A, D)
@@ -961,7 +951,7 @@ Die korrekten Antworten können hier frei als Buchstaben eingegeben werden. (hie
A4={D}, % 4. richtige Zuordnung
}
-\subsubsection{Zusatz: Variable Breiten der Boxen}
+\subsubsection{\texttt{\textbackslash zuordnen} -- Option: Variable Breiten der Boxen}
Der \texttt{zuordnen}-Befehl erlaubt ein optionales Argument, um die Größen der beiden Boxen zu variieren. Dabei werden in den eckigen Klammern $[~]$ die Veränderung der linken Box (Änderung ca. zwischen -0.3 und 0.3) angegeben und die rechte Box wird automatisch angepasst. Will man etwa die linke Box vergrößern, gilt:
@@ -1019,16 +1009,16 @@ Analog funktioniert die Verkleinerung der linken Box. Dazu müssen Werte kleiner
\section{Typ-2-Aufgaben}
Um die Struktur der Teil-2-Aufgaben ähnlich jener bei der standardisierten Reifeprüfung einhalten zu können, beinhaltet das Paket einige Befehle, die die Erstellung von Typ-2-Aufagben erleichtern.
-\subsection{\texttt{aufgabenstellung}-Umgebung}
+\subsection{\texttt{\textbackslash begin\{aufgabenstellung\} \ldots\ \textbackslash end\{aufgabenstellung\}}}
Typ-2-Aufgaben sollten innerhalb einer Prüfung mithilfe der \texttt{langesbeispiel}-Umgebung eingegeben werden, um die volle Funktionalität (wie \texttt{notenschluessel}) des Pakets zu ermöglichen. Der einleitenden Aufgabentext kann dann eingegeben werden. Für die Eingabe der Aufgabenstellung kann dann die \texttt{aufgabenstellung}-Umgebung verwendet werden.\leer
\subsubsection{\texttt{\textbackslash item} und \texttt{\textbackslash Subitem\{\}}}
Innerhalb dieser Umgebung können dann mithilfe von \texttt{\textbackslash item} (nummeriert mit a), b) ,c), \ldots) und \texttt{\textbackslash Subitem\{\}} (nummeriert mit 1), 2), \ldots) die jeweiligen Items und Subitems der Aufgabe eingegeben werden. \leer
-\subsubsection{Ausgleichspunkte}
+\subsubsection{Ausgleichspunkte -- \texttt{\textbackslash Aitem} und \texttt{\textbackslash ASubitem\{\}}}
Um die notwendigen Ausgleichspunkte in den Typ-2-Aufgaben zu markieren, können die Befehle \texttt{item} und \texttt{Subitem} durch \texttt{\textbackslash Aitem} und \texttt{\textbackslash ASubitem\{\}} ersetzt werden. Dabei wird vor den geschriebenen Text noch ein \fbox{A} eingefügt -- die Nummerierung wird aber wie gewohnt fortgesetzt.
-\subsection{\texttt{loesung}-Umgebung}
+\subsection{\texttt{\textbackslash begin\{loesung\} \ldots\ \textbackslash end\{loesung\}}}
Mithilfe der \texttt{loesung}-Umgebung kann die Lösungserwartung sowie der Lösungsschlüssel eingegeben werden. Analog zur Aufgabenstellung können \texttt{\textbackslash item} und \texttt{\textbackslash Subitem\{\}} verwendet werden. Die Eingabe innerhalb der \texttt{loesung}-Umgebung werden nur dann angezeigt, wenn die Lösungsanzeige aktiviert wurde. Die Nummerierung der Subitems kann man mit folgender Eingabe zurücksetzen: \texttt{\textbackslash setcounter{subitemcounter}{0}}.\leer
Eine vollständige Typ-2-Aufgabe könnte also wie folgt aussehen:
@@ -1063,7 +1053,7 @@ Hier steht der einleitende Text der Typ-2-Aufgabe.
\end{langesbeispiel}
\end{verbatim}
-\newpage
+
\textsc{Ausgabe:}
\setcounter{Antworten}{1}
diff --git a/macros/xetex/latex/xesoul/README b/macros/xetex/latex/xesoul/README
new file mode 100644
index 0000000000..90f09481cf
--- /dev/null
+++ b/macros/xetex/latex/xesoul/README
@@ -0,0 +1,5 @@
+The xesoul package is a little hack that allows users to use
+the soul package with XeLaTeX with no problem.
+
+Apostolos Syropoulos
+2021/03/29
diff --git a/macros/xetex/latex/xesoul/xesoul.dtx b/macros/xetex/latex/xesoul/xesoul.dtx
new file mode 100644
index 0000000000..acf496065b
--- /dev/null
+++ b/macros/xetex/latex/xesoul/xesoul.dtx
@@ -0,0 +1,103 @@
+%% \CharacterTable
+%% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+%% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+%% Digits \0\1\2\3\4\5\6\7\8\9
+%% Exclamation \! Double quote \" Hash (number) \#
+%% Dollar \$ Percent \% Ampersand \&
+%% Acute accent \' Left paren \( Right paren \)
+%% Asterisk \* Plus \+ Comma \,
+%% Minus \- Point \. Solidus \/
+%% Colon \: Semicolon \; Less than \<
+%% Equals \= Greater than \> Question mark \?
+%% Commercial at \@ Left bracket \[ Backslash \\
+%% Right bracket \] Circumflex \^ Underscore \_
+%% Grave accent \` Left brace \{ Vertical bar \|
+%% Right brace \} Tilde \~}
+%\iffalse
+%
+% (c) copyright 2021 A Syropoulos
+%
+% This program can be redistributed and/or modified under the
+% terms of the LaTeX Project Public License Distributed from
+% http://www.latex-project.org/lppl.txt; either
+% version 1.3c of the License, or any later version.
+%
+% This work has the LPPL maintenance status `maintained'.
+%
+% Please report errors or suggestions for improvement to
+%
+% Apostolos Syropoulos (asyropoulos@yahoo.com)
+%
+%\fi
+% \CheckSum{15}
+% \iffalse This is a Metacomment
+%
+%<xesoul, >\ProvidesFile{xesoul.sty}
+%
+%<xesoul, > [2021/02/23 v1.0 Package `xesoul.sty']
+%
+% \begin{macrocode}
+%<*driver>
+\documentclass{ltxdoc}
+\GetFileInfo{xesoul.drv}
+\usepackage{xltxtra}
+\usepackage{hyperref}
+\begin{document}
+\setmainfont[Mapping=tex-text,Script=Greek,
+ SmallCapsFeatures={Contextuals=Alternate}]{Universal Modern}
+\setmonofont{UM Typewriter}
+\setsansfont[Mapping=tex-text]{GFS Neohellenic}
+
+ \DocInput{xesoul.dtx}
+\end{document}
+%</driver>
+% \end{macrocode}
+% \fi
+%\StopEventually{}
+%\MakeShortVerb{\|}
+%\title{\textsf{xesoul}: Using the \textsf{soul} package with \XeLaTeX}
+%\author{Apostolos Syropoulos\\
+% Xanthi, Greece\\
+% \texttt{asyropoulos@yahoo.com}}
+% \date{2021/02/23}
+%\maketitle
+% \begin{abstract}
+% This is a small package that allows users to successfully use the \textsf{soul} package
+% when preparing documents with \XeLaTeX.
+%\end{abstract}
+%
+%\section{Introduction}
+%
+% While I was trying to underline Greek text using the |\ul| command of the \textsf{soul} package with \XeLaTeX,
+% I discovered that this is not possible. I was getting several errors and the output was looking terrible.
+% I did not know what was wrong. I did a Google search and I found that another user had the same problem.
+% He posted his case to the \XeTeX\ mailing list and Ulrike Fischer helped him and gave a solution to the problem.
+% However, since the solution is not part of the \textsf{soul} package, I thought it would be a good idea to create
+% a new package that would solve the problem.
+%
+% \section{The Implementation}
+%
+% The code of the package is very simple. It loads the \textsf{soul} package and then it sets the |\SOUL@tt|
+% font to be a Unicode encoded font. The most natural choice is to use a font that is included in every
+% distribution of \TeX{live}. Thus the package uses the freemono font. If for some reason the font is not available
+% in your installtion, then you can download it from the following URL:
+% \begin{center}
+% \href{https://fontmeme.com/fonts/freemono-font/}{https://fontmeme.com/fonts/freemono-font/}
+% \end{center}
+% Since the \textsf{soul} package uses the |\SOUL@ttwidth| variable, we need to reset it. Now one can use
+% the \textsf{soul} package with no problem.
+% \begin{macrocode}
+%<*xesoul>
+\RequirePackage{iftex}
+\ifXeTeX
+\RequirePackage{soul}
+\font\SOUL@tt="[FreeMono.ttf]"
+\setbox\z@\hbox{\SOUL@tt-}
+\SOUL@ttwidth\wd\z@
+\else
+\typeout{The `xesoul' package can be used only with XeLaTeX.}
+\fi
+%</xesoul>
+% \end{macrocode}
+%
+% \Finale
diff --git a/macros/xetex/latex/xesoul/xesoul.ins b/macros/xetex/latex/xesoul/xesoul.ins
new file mode 100644
index 0000000000..d8bd52e18d
--- /dev/null
+++ b/macros/xetex/latex/xesoul/xesoul.ins
@@ -0,0 +1,53 @@
+%% Copyright 2021 Apostolos Syropoulos
+%%
+%% This file is part of the `xesoul' package.
+%% You are not allowed to modify its contents.
+%%
+\def\filedate{2021/02/23}
+\def\batchfile{xesoul.ins}
+\input docstrip.tex
+
+{\ifx\generate\undefined
+\Msg{**********************************************}
+\Msg{*}
+\Msg{* This installation requires docstrip}
+\Msg{* version 2.3c or later.}
+\Msg{*}
+\Msg{* An older version of docstrip has been input}
+\Msg{*}
+\Msg{**********************************************}
+\errhelp{Move or rename old docstrip.tex.}
+\errmessage{Old docstrip in input path}
+\batchmode
+\csname @@end\endcsname
+\fi}
+
+\preamble
+
+ (c) copyright 2021 Apostolos Syropoulos
+ This program can be redistributed and/or modified under the
+ terms of the LaTeX Project Public License Distributed from
+ http://www.latex-project.org/lppl.txt; either
+ version 1.3c of the License, or any later version.
+
+ This work has the LPPL maintenance status `maintained'.
+
+ Please report errors or suggestions for improvement to
+
+ Apostolos Syropoulos (asyropoulos@yahoo.com)
+
+\endpreamble
+
+
+\keepsilent
+
+\generate{\generateFile{xesoul.sty}{f}{\from{xesoul.dtx}{xesoul}}}
+\postamble
+\endpostamble
+\Msg{**********************************************************}
+\Msg{* To finish installation you have to copy}
+\Msg{* the generated .sty file in the appropriate}
+\Msg{* directory and then to rehash your TeX system}
+\Msg{* Happy XeTeXing!}
+\Msg{**********************************************************}
+\endinput
diff --git a/macros/xetex/latex/xesoul/xesoul.pdf b/macros/xetex/latex/xesoul/xesoul.pdf
new file mode 100644
index 0000000000..af76885c17
--- /dev/null
+++ b/macros/xetex/latex/xesoul/xesoul.pdf
Binary files differ