diff options
author | Karl Berry <karl@freefriends.org> | 2022-05-15 20:41:35 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2022-05-15 20:41:35 +0000 |
commit | 468f3f2d5e21e51d77dc26d0141b245976b34bd8 (patch) | |
tree | ee99548dd8ceef0abe0eed514d0c503aeccdac92 /Master | |
parent | 622b49804740c998dab033ab7dfaca46062d9944 (diff) |
polexpr (15may22)
git-svn-id: svn://tug.org/texlive/trunk@63306 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master')
-rw-r--r-- | Master/texmf-dist/doc/generic/polexpr/README.md | 151 | ||||
-rw-r--r-- | Master/texmf-dist/doc/generic/polexpr/polexpr-changes.html | 629 | ||||
-rw-r--r-- | Master/texmf-dist/doc/generic/polexpr/polexpr-changes.rst.txt | 513 | ||||
-rw-r--r-- | Master/texmf-dist/doc/generic/polexpr/polexpr-examples.pdf | bin | 58706 -> 57444 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/generic/polexpr/polexpr-ref.html | 2898 | ||||
-rw-r--r-- | Master/texmf-dist/doc/generic/polexpr/polexpr-ref.rst.txt | 3184 | ||||
-rw-r--r-- | Master/texmf-dist/doc/generic/polexpr/polexpr.css | 826 | ||||
-rw-r--r-- | Master/texmf-dist/doc/generic/polexpr/polexpr.html | 3988 | ||||
-rw-r--r-- | Master/texmf-dist/doc/generic/polexpr/polexpr.rst.txt | 157 | ||||
-rw-r--r-- | Master/texmf-dist/tex/generic/polexpr/polexpr-examples.tex | 86 | ||||
-rw-r--r-- | Master/texmf-dist/tex/generic/polexpr/polexpr.sty | 19 | ||||
-rw-r--r-- | Master/texmf-dist/tex/generic/polexpr/polexprcore.tex | 2 | ||||
-rw-r--r-- | Master/texmf-dist/tex/generic/polexpr/polexprexpr.tex | 2 | ||||
-rw-r--r-- | Master/texmf-dist/tex/generic/polexpr/polexprsturm.tex | 2 |
14 files changed, 8512 insertions, 3945 deletions
diff --git a/Master/texmf-dist/doc/generic/polexpr/README.md b/Master/texmf-dist/doc/generic/polexpr/README.md index 4a74900100a..0f70c6cb343 100644 --- a/Master/texmf-dist/doc/generic/polexpr/README.md +++ b/Master/texmf-dist/doc/generic/polexpr/README.md @@ -1,88 +1,65 @@ Package polexpr README ====================== +Version ``0.8.7`` of ``2022/05/14``. + +Abstract +-------- + +The package provides a parser `\poldef` of algebraic expressions. +As it is based on [xintexpr](http://www.ctan.org/pkg/xintexpr) the +polynomial coefficients are allowed to be arbitrary rational +numbers. Operations on declared polynomials, such as computing +G.C.D.'s or evaluating definite and indefinite integrals are +available directly inside the parser via a functional syntax, or +also via dedicated package macros. + +Root localization is available via package macros. All real roots +can be obtained with arbitrarily long decimal expansions, and all +rational rounds found exactly. + +In memoriam: Jürgen Gilg +------------------------ + +`polexpr` is dedicated to the memory of Jürgen Gilg (1967-2022). + +His question in January 2018 about using +[xintexpr](http://www.ctan.org/pkg/xintexpr) to compute derivatives +of polynomials was the original motivation for the creation of this +package. Jointly with Thomas Söll, he used it and kept expressing +his interest in it throughout the subsequent years, and provided +motivation and encouragements for time-consuming tasks such as (as +was done finally in 2021) re-enacting full interoperability with +[xintexpr](http://www.ctan.org/pkg/xintexpr) after its `1.4` update +from 2020. + +I will remember with gratitude his generous and unassuming +character, which I witnessed during our numerous exchanges on a wide +range of topics. + Usage ----- -The package can be used with TeX based formats incorporating the -e-TeX primitives. The `\expanded` primitive available generally -since TeXLive 2019 is required. +The package can be used with eTeX based formats via \input polexpr.sty -with Plain or other non-LaTeX macro formats, or: +or with LaTeX via \usepackage{polexpr} -with the LaTeX macro format. +[xintexpr](http://www.ctan.org/pkg/xintexpr) `1.4h` or later is +required. -The package currently requires xintexpr.sty `1.4d` or later. - -Abstract --------- +Recent changes +-------------- -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. - -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. - -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 --------- - -- 0.1 (2018/01/11) - Initial release (files README, polexpr.sty). -- 0.2 (2018/01/14) - Documentation moved to polexpr.{txt,html}. -- 0.3 (2018/01/17) - Make polynomials known to `\xintfloatexpr` and improve - documentation. -- 0.3.1 (2018/01/18) - Fix two typos in documentation. -- 0.4 (2018/02/16) - - Revert 0.3 automatic generation of floating point variants. - - Move CHANGE LOG from README.md to HTML documentation. - - A few bug fixes and breaking changes. Please refer to - `polexpr.html`. - - Main new feature: root localization via [Sturm - Theorem](https://en.wikipedia.org/wiki/Sturm%27s_theorem). -- 0.4.1 (2018/03/01) - Synced with xintexpr 1.3. -- 0.4.2 (2018/03/03) - Documentation fix. -- 0.5 (2018/04/08) - - new macros `\PolMakePrimitive` and `\PolIContent`. - - main (breaking) change: `\PolToSturm` creates a chain of primitive - integer coefficients polynomials. -- 0.5.1 (2018/04/22) - The `'` character can be used in polynomial names. -- 0.6 (2018/11/20) - New feature: multiplicity of roots. -- 0.7 (2018/12/08), 0.7.1 (bugfix), 0.7.2 (bugfix) (2018/12/09) - New feature: finding all rational roots. -- 0.7.3 (2019/02/04) - Bugfix: polynomial names ending in digits caused errors. Thanks to - Thomas Söll for report. -- 0.7.4 (2019/02/12) - 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 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. + Complete refactoring of the package core for better interoperability + with `xintexpr` internal changes at its release `1.4 (2020/01/31)`. + Extension of the functional syntax to cover operations such as + G.C.D.'s, derivatives or indefinite integrals previously available + via macros. - 0.8.1 (2021/04/12) Bugfix: a typo broke the 0.8 ``diff1()`` and related functions. - 0.8.2 (2021/05/05) @@ -96,21 +73,13 @@ Releases Bugfix: `intfrom()` was documented at `0.8` but not declared to parser. Track (belatedly) `xintexpr` 1.4g changes - 0.8.6 (2022/01/09) - Separate `polexpr-examples.{tex,pdf}` from the `polexpr.html` reference - -Files of the 0.8.6 release: -- polexpr.sty, polexprcore.tex, polexprexpr.tex, polexprsturm.tex, -- README.md, -- polexpr.html (reference documentation), -- polexpr-examples.pdf, polexpr-examples.tex (pdf doc and its source). + Separate `polexpr-examples.{tex,pdf}` from the `polexpr.html` reference. +- 0.8.7 (2022/05/14) + CSS styling of the `html` documentation, which is now split over + three files. Catcode protection for `\poldef` now matches + long-standing behaviour of `\xintdefvar`. This fixes issues + with ``babel+french``. -Acknowledgments ---------------- - -Thanks to Jürgen Gilg whose question about -[xintexpr](http://www.ctan.org/pkg/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. License ------- @@ -133,6 +102,14 @@ 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 documentation -polexpr.html, polexpr-examples.tex, polexpr-examples.pdf +This Work consists of: + +- the package files: polexpr.sty, polexprcore.tex, + polexprexpr.tex, polexprsturm.tex, +- this README.md, +- the documentation files: + polexpr.html, polexpr-ref.html, polexpr-changes.html, + polexpr.css, polexpr-examples.pdf, + polexpr.rst.txt, polexpr-ref.rst.txt, polexpr-changes.rst.txt, + polexpr-examples.tex + diff --git a/Master/texmf-dist/doc/generic/polexpr/polexpr-changes.html b/Master/texmf-dist/doc/generic/polexpr/polexpr-changes.html new file mode 100644 index 00000000000..51392f6565c --- /dev/null +++ b/Master/texmf-dist/doc/generic/polexpr/polexpr-changes.html @@ -0,0 +1,629 @@ + +<!DOCTYPE html> + +<html lang="en"> + <head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.18.1: http://docutils.sourceforge.net/" /> + + <title>CHANGES — polexpr 0.8.7 documentation</title> + <link rel="stylesheet" type="text/css" href="polexpr.css" /> + <link rel="prev" title="polexpr reference" href="polexpr-ref.html" /> + </head><body> + <div class="related" role="navigation" aria-label="related navigation"> + <h3>Navigation</h3> + <ul> + <li class="right" style="margin-right: 10px"> + <a href="polexpr-ref.html" title="polexpr reference" + accesskey="P">previous</a></li> + <li class="nav-item nav-item-0"><a href="polexpr.html">polexpr 0.8.7 documentation</a> »</li> + <li class="nav-item nav-item-this"><a href="">CHANGES</a></li> + </ul> + </div> + + <div class="document"> + <div class="documentwrapper"> + <div class="bodywrapper"> + <div class="body" role="main"> + + <section id="changes"> +<h1>CHANGES</h1> +<section id="v0-1-2018-01-11-initial-release-features"> +<span id="firstrelease"></span><h2>v0.1 (2018/01/11): initial release. Features:</h2> +<ul class="simple"> +<li><p>The <a class="reference internal" href="polexpr-ref.html#poldef"><span class="std std-ref">\poldef</span></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="polexpr-ref.html#polfromcsv"><span class="std std-ref">\PolFromCSV</span></a>, +<a class="reference internal" href="polexpr-ref.html#polmapcoeffs"><span class="std std-ref">\PolMapCoeffs</span></a>, +<a class="reference internal" href="polexpr-ref.html#poltocsv"><span class="std std-ref">\PolToCSV</span></a>, <a class="reference internal" href="polexpr-ref.html#poltoexpr"><span class="std std-ref">\PolToExpr</span></a>, …</p></li> +</ul> +<p>Only one-variable polynomials so far.</p> +</section> +<section id="v0-2-2018-01-14"> +<h2>v0.2 (2018/01/14)</h2> +<ul class="simple"> +<li><p>Fix: <code class="docutils literal notranslate"><span class="pre">"README</span> <span class="pre">thinks</span> <span class="pre">\numexpr</span> <span class="pre">recognizes</span> <span class="pre">^</span> <span class="pre">operator"</span></code>.</p></li> +<li><p>Convert README to reStructuredText markup.</p></li> +<li><p>Move main documentation from README to separate <code class="docutils literal notranslate"><span class="pre">polexpr.txt</span></code> file.</p></li> +<li><p>Provide <code class="docutils literal notranslate"><span class="pre">polexpr.html</span></code> as obtained via <a class="reference external" href="http://docutils.sourceforge.net/docs/index.html">DocUtils</a> <code class="docutils literal notranslate"><span class="pre">rst2html.py</span></code>.</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> +</section> +<section id="v0-3-2018-01-17"> +<h2>v0.3 (2018/01/17)</h2> +<ul> +<li><p>bug fixes:</p> +<ul> +<li><p>the <code class="docutils literal notranslate"><span class="pre">0.1</span></code> <a class="reference internal" href="polexpr-ref.html#polevalat"><span class="std std-ref">\PolEval</span></a> accepted expressions for its +second argument, but this was removed by mistake at <code class="docutils literal notranslate"><span class="pre">0.2</span></code>. Restored.</p> +<p><strong>Attention</strong>: at <code class="docutils literal notranslate"><span class="pre">0.4</span></code> this has been reverted again, and +<a class="reference internal" href="polexpr-ref.html#polevalatexpr"><span class="std std-ref">\PolEval{P}\AtExpr{foo}</span></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="polexpr-ref.html#poltoexpr"><span class="std std-ref">\PolToExpr</span></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="polexpr-ref.html#id78"><span class="std std-ref">\PolToExpr*</span></a> for <em>ascending</em> powers.</p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polevalat"><span class="std std-ref">\PolEval</span></a> reduced the output to smallest terms, +but as this is costly with big fractions and not needed if e.g. +wrapped in an <code class="docutils literal notranslate"><span class="pre">\xintRound</span></code> or <code class="docutils literal notranslate"><span class="pre">\xintFloat</span></code>, this step has been +removed; the former meaning is available as +<a class="reference internal" href="polexpr-ref.html#polevalreducedat"><span class="std std-ref">\PolEvalReduced</span></a>.</p></li> +</ul> +</li> +<li><p>new (or newly documented) macros:</p> +<ul class="simple"> +<li><p><a class="reference internal" href="polexpr-ref.html#poltypesetcmd"><span class="std std-ref">\PolTypesetCmd</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#poltypesetcmdprefix"><span class="std std-ref">\PolTypesetCmdPrefix</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#poltypesetmonomialcmd"><span class="std std-ref">\PolTypesetMonomialCmd</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polevalreducedat"><span class="std std-ref">\PolEvalReducedAt</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#poltofloatexpr"><span class="std std-ref">\PolToFloatExpr</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#poltoexproneterm"><span class="std std-ref">\PolToExprOneTerm</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#poltofloatexproneterm"><span class="std std-ref">\PolToFloatExprOneTerm</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#poltoexprcmd"><span class="std std-ref">\PolToExprCmd</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#poltofloatexprcmd"><span class="std std-ref">\PolToFloatExprCmd</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#poltoexprtermprefix"><span class="std std-ref">\PolToExprTermPrefix</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#poltoexprvar"><span class="std std-ref">\PolToExprVar</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#poltoexprtimes"><span class="std std-ref">\PolToExprTimes</span></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 <code class="docutils literal notranslate"><span class="pre">\PolLet{g}={f}</span></code> or <code class="docutils literal notranslate"><span class="pre">\PolLet{g}{f}</span></code>.</p></li> +<li><p><code class="docutils literal notranslate"><span class="pre">\PolToExpr{f}</span></code> is highly customizable.</p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#poldef"><span class="std std-ref">\poldef</span></a> and other defining macros prepare the +polynomial functions for usage within <code class="docutils literal notranslate"><span class="pre">\xintthefloatexpr</span></code> (or +<code class="docutils literal notranslate"><span class="pre">\xintdeffloatvar</span></code>). 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 <code class="docutils literal notranslate"><span class="pre">0.4</span></code>. The macro +<a class="reference internal" href="polexpr-ref.html#polgenfloatvariant"><span class="std std-ref">\PolGenFloatVariant</span></a> must be used for +generation floating point polynomial functions.</p> +</li> +</ul> +</li> +</ul> +</section> +<section id="v0-3-1-2018-01-18"> +<h2>v0.3.1 (2018/01/18)</h2> +<p>Fixes two typos in example code included in the documentation.</p> +</section> +<section id="v0-4-2018-02-16"> +<h2>v0.4 (2018/02/16)</h2> +<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="polexpr-ref.html#polmapcoeffs"><span class="std std-ref">\PolMapCoeffs</span></a>.</p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polgcd"><span class="std std-ref">\PolGCD</span></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="polexpr-ref.html#polevalat"><span class="std std-ref">\PolEval{P}\At{foo}</span></a> allowed <code class="docutils literal notranslate"><span class="pre">foo</span></code> to +be an expression, which was transparently handled via +<code class="docutils literal notranslate"><span class="pre">\xinttheexpr</span></code>. Now, <code class="docutils literal notranslate"><span class="pre">foo</span></code> must be a fraction (or a macro +expanding to such) in the format acceptable by <code class="docutils literal notranslate"><span class="pre">xintfrac.sty</span></code> +macros. Use <a class="reference internal" href="polexpr-ref.html#polevalatexpr"><span class="std std-ref">\PolEval{P}\AtExpr{foo}</span></a> for more +general arguments using expression syntax. E.g., if <code class="docutils literal notranslate"><span class="pre">foo</span></code> is the +name of a variable known to <code class="docutils literal notranslate"><span class="pre">\xintexpr</span></code>.</p> +<p>The same holds for <a class="reference internal" href="polexpr-ref.html#polevalreducedat"><span class="std std-ref">\PolEvalReduced</span></a> +and <a class="reference internal" href="polexpr-ref.html#polfloatevalat"><span class="std std-ref">\PolFloatEval</span></a>.</p> +</li> +<li><p>the <code class="docutils literal notranslate"><span class="pre">3.0</span></code> 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="polexpr-ref.html#polgenfloatvariant"><span class="std std-ref">\PolGenFloatVariant</span></a>.</p> +</li> +</ul> +</li> +<li><p>new non-expandable macros:</p> +<ul class="simple"> +<li><p><a class="reference internal" href="polexpr-ref.html#polgenfloatvariant"><span class="std std-ref">\PolGenFloatVariant</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polgloballet"><span class="std std-ref">\PolGlobalLet</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#poltypesetone"><span class="std std-ref">\PolTypesetOne</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polquo"><span class="std std-ref">\PolQuo</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polrem"><span class="std std-ref">\PolRem</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#poltosturm"><span class="std std-ref">\PolToSturm</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#id35"><span class="std std-ref">\PolToSturm*</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polsettosturmchainsignchangesat"><span class="std std-ref">\PolSetToSturmChainSignChangesAt</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polsettonbofzeroswithin"><span class="std std-ref">\PolSetToNbOfZerosWithin</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polsturmisolatezeros"><span class="std std-ref">\PolSturmIsolateZeros</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polrefineinterval"><span class="std std-ref">\PolRefineInterval*</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#id46"><span class="std std-ref">\PolRefineInterval[N]</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polensureintervallength"><span class="std std-ref">\PolEnsureIntervalLength</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polensureintervallengths"><span class="std std-ref">\PolEnsureIntervalLengths</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polprintintervals"><span class="std std-ref">\PolPrintIntervals</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polprintintervalsprintexactzero"><span class="std std-ref">\PolPrintIntervalsPrintExactZero</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polprintintervalsprintleftendpoint"><span class="std std-ref">\PolPrintIntervalsPrintLeftEndPoint</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polprintintervalsprintrightendpoint"><span class="std std-ref">\PolPrintIntervalsPrintRightEndPoint</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#id20"><span class="std std-ref">\PolReduceCoeffs*</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polmakemonic"><span class="std std-ref">\PolMakeMonic</span></a></p></li> +</ul> +</li> +<li><p>new expandable macros:</p> +<ul class="simple"> +<li><p><a class="reference internal" href="polexpr-ref.html#poltoexpronetermstylea"><span class="std std-ref">\PolToExprOneTermStyleA</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polifcoeffisplusorminusone"><span class="std std-ref">\PolIfCoeffIsPlusOrMinusOne</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polleadingcoeff"><span class="std std-ref">\PolLeadingCoeff</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polsturmchainlength"><span class="std std-ref">\PolSturmChainLength</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polsturmnbofisolatedzeros"><span class="std std-ref">\PolSturmNbOfIsolatedZeros</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polsturmifzeroexactlyknown"><span class="std std-ref">\PolSturmIfZeroExactlyKnown</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polsturmisolatedzeroleft"><span class="std std-ref">\PolSturmIsolatedZeroLeft</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polsturmisolatedzeroright"><span class="std std-ref">\PolSturmIsolatedZeroRight</span></a></p></li> +<li><p><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervalsTheEndPoint</span></code> (removed at 0.7)</p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polprintintervalstheindex"><span class="std std-ref">\PolPrintIntervalsTheIndex</span></a></p></li> +<li><p><code class="docutils literal notranslate"><span class="pre">\PolIfEndPointIsPositive</span></code> (removed at 0.7)</p></li> +<li><p><code class="docutils literal notranslate"><span class="pre">\PolIfEndPointIsNegative</span></code> (removed at 0.7)</p></li> +<li><p><code class="docutils literal notranslate"><span class="pre">\PolIfEndPointIsZero</span></code> (removed at 0.7)</p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polintervalwidth"><span class="std std-ref">\PolIntervalWidth</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#poldectostring"><span class="std std-ref">\PolDecToString</span></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> +</section> +<section id="v0-4-1-2018-03-01"> +<h2>v0.4.1 (2018/03/01)</h2> +<p>Synced with xint 1.3.</p> +</section> +<section id="v0-4-2-2018-03-03"> +<h2>v0.4.2 (2018/03/03)</h2> +<p>Documentation fix.</p> +</section> +<section id="v0-5-2018-04-08"> +<h2>v0.5 (2018/04/08)</h2> +<ul class="simple"> +<li><p>bug fixes:</p> +<ul> +<li><p><a class="reference internal" href="polexpr-ref.html#polget"><span class="std std-ref">\PolGet{polname}\fromarray\macro</span></a> +crashed when <code class="docutils literal notranslate"><span class="pre">\macro</span></code> was +an <a class="reference external" href="https://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="polexpr-ref.html#poltosturm"><span class="std std-ref">\PolToSturm</span></a> creates primitive integer coefficients +polynomials. This speeds up localization of roots via +<a class="reference internal" href="polexpr-ref.html#polsturmisolatezeros"><span class="std std-ref">\PolSturmIsolateZeros</span></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="polexpr-ref.html#polfromcsv"><span class="std std-ref">\PolFromCSV</span></a> or +<a class="reference internal" href="polexpr-ref.html#polget"><span class="std std-ref">\PolGet</span></a> +get their coefficients normalized via <a class="reference external" href="https://www.ctan.org/pkg/xint">xintfrac</a>‘s <code class="docutils literal notranslate"><span class="pre">\xintRaw</span></code>.</p></li> +</ul> +</li> +<li><p>experimental change:</p> +<ul> +<li><p>optional argument to <a class="reference internal" href="polexpr-ref.html#polsturmisolatezeros"><span class="std std-ref">\PolSturmIsolateZeros</span></a> +(see <code class="docutils literal notranslate"><span class="pre">The</span> <span class="pre">degree</span> <span class="pre">41</span> <span class="pre">polynomial</span> <span class="pre">with</span> <span class="pre">-2,</span> <span class="pre">-1.9,</span> <span class="pre">-1.8,</span> <span class="pre">...,</span> <span class="pre">0,</span> <span class="pre">0.1,</span> <span class="pre">...,</span> +<span class="pre">1.9,</span> <span class="pre">2</span> <span class="pre">as</span> <span class="pre">roots</span></code> in <code class="docutils literal notranslate"><span class="pre">polexpr-examples.pdf</span></code>). 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="polexpr-ref.html#polmakeprimitive"><span class="std std-ref">\PolMakePrimitive</span></a></p></li> +</ul> +</li> +<li><p>new expandable macro:</p> +<ul> +<li><p><a class="reference internal" href="polexpr-ref.html#policontent"><span class="std std-ref">\PolIContent</span></a></p></li> +</ul> +</li> +</ul> +</section> +<section id="v0-5-1-2018-04-22"> +<h2>v0.5.1 (2018/04/22)</h2> +<ul class="simple"> +<li><p>new feature:</p> +<ul> +<li><p>the character <code class="docutils literal notranslate"><span class="pre">'</span></code> can be used in polynomial names.</p></li> +</ul> +</li> +</ul> +</section> +<section id="v0-6-2018-11-20"> +<h2>v0.6 (2018/11/20)</h2> +<ul class="simple"> +<li><p>bugfix:</p> +<ul> +<li><p>the starred variant +<a class="reference internal" href="polexpr-ref.html#id35"><span class="std std-ref">\PolToSturm*{<polname>}{<sturmname>}</span></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="polexpr-ref.html#poltosturm"><span class="std std-ref">\PolToSturm</span></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="polexpr-ref.html#id38"><span class="std std-ref">\PolSturmIsolateZeros*</span></a> +acts like the <a class="reference internal" href="polexpr-ref.html#polsturmisolatezeros"><span class="std std-ref">non-starred variant</span></a> then computes all the multiplicities.</p></li> +</ul> +</li> +<li><p>new expandable macros:</p> +<ul> +<li><p><a class="reference internal" href="polexpr-ref.html#polsturmisolatedzeromultiplicity"><span class="std std-ref">\PolSturmIsolatedZeroMultiplicity{<sturmname>}{<index>}</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polsturmnbofrootsoflessthanorequalto"><span class="std std-ref">\PolSturmNbOfRootsOf{<sturmname>}\LessThanOrEqualTo{<value>}</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polsturmnbofrootsoflessthanorequaltoexpr"><span class="std std-ref">\PolSturmNbOfRootsOf{<sturmname>}\LessThanOrEqualToExpr{<num. expr.>}</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polsturmnbwithmultofrootsoflessthanorequalto"><span class="std std-ref">\PolSturmNbWithMultOfRootsOf{<sturmname>}\LessThanOrEqualTo{<value>}</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polsturmnbwithmultofrootsoflessthanorequaltoexpr"><span class="std std-ref">\PolSturmNbWithMultOfRootsOf{<sturmname>}\LessThanOrEqualToExpr{<num. expr.>}</span></a></p></li> +</ul> +</li> +</ul> +</section> +<section id="v0-7-2018-12-08-v0-7-1-bugfix-v0-7-2-2nd-bugfix-2018-12-09"> +<h2>v0.7 (2018/12/08), v0.7.1 (bugfix), v0.7.2 (2nd bugfix) (2018/12/09)</h2> +<ul class="simple"> +<li><p>breaking changes:</p> +<ul> +<li><p>although <a class="reference internal" href="polexpr-ref.html#polprintintervals"><span class="std std-ref">\PolPrintIntervals[<varname>]{<sturmname>}</span></a> default output +remains the same, some auxiliary macros for user-customization +have been removed: <code class="docutils literal notranslate"><span class="pre">\PolPrintIntervalsTheEndPoint</span></code>, +<code class="docutils literal notranslate"><span class="pre">\PolIfEndPointIsPositive{T}{F}</span></code>, +<code class="docutils literal notranslate"><span class="pre">\PolIfEndPointIsNegative{T}{F}</span></code>, and +<code class="docutils literal notranslate"><span class="pre">\PolIfEndPointIsZero{T}{F}</span></code>.</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="polexpr-ref.html#polsturmisolatezeros"><span class="std std-ref">\PolSturmIsolateZeros{<sturmname>}</span></a> had +zero as an endpoint,</p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polensureintervallength"><span class="std std-ref">\PolEnsureIntervalLength{<sturmname>}{<index>}{<exponent>}</span></a> could under certain circumstances erroneously +replace a non-zero root by zero,</p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polensureintervallengths"><span class="std std-ref">\PolEnsureIntervalLengths{<sturmname>}{<exponent>}</span></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="polexpr-ref.html#id41"><span class="std std-ref">\PolSturmIsolateZeros**{<sturmname>}</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polsturmisolatezerosgetmultiplicitiesandrationalroots"><span class="std std-ref">\PolSturmIsolateZerosGetMultiplicitiesAndRationalRoots{<sturmname>}</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polsturmisolatezerosandfindrationalroots"><span class="std std-ref">\PolSturmIsolateZerosAndFindRationalRoots{<sturmname>}</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polexprsetup"><span class="std std-ref">\polexprsetup</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#id61"><span class="std std-ref">\PolPrintIntervals*</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polprintintervalsnorealroots"><span class="std std-ref">\PolPrintIntervalsNoRealRoots</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polprintintervalsbeginenv"><span class="std std-ref">\PolPrintIntervalsBeginEnv</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polprintintervalsendenv"><span class="std std-ref">\PolPrintIntervalsEndEnv</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polprintintervalsknownroot"><span class="std std-ref">\PolPrintIntervalsKnownRoot</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polprintintervalsunknownroot"><span class="std std-ref">\PolPrintIntervalsUnknownRoot</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polprintintervalsprintmultiplicity"><span class="std std-ref">\PolPrintIntervalsPrintMultiplicity</span></a></p></li> +</ul> +</li> +<li><p>new expandable macros:</p> +<ul> +<li><p><a class="reference internal" href="polexpr-ref.html#polsturmnbofrationalroots"><span class="std std-ref">\PolSturmNbOfRationalRoots{<sturmname>}</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polsturmnbofrationalrootswithmultiplicities"><span class="std std-ref">\PolSturmNbOfRationalRootsWithMultiplicities{<sturmname>}</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polsturmrationalroot"><span class="std std-ref">\PolSturmRationalRoot{<sturmname>}{<k>}</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polsturmrationalrootindex"><span class="std std-ref">\PolSturmRationalRootIndex{<sturmname>}{<k>}</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polsturmrationalrootmultiplicity"><span class="std std-ref">\PolSturmRationalRootMultiplicity{<sturmname>}{<k>}</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polprintintervalsthevar"><span class="std std-ref">\PolPrintIntervalsTheVar</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polprintintervalsthesturmname"><span class="std std-ref">\PolPrintIntervalsTheSturmName</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polprintintervalsthemultiplicity"><span class="std std-ref">\PolPrintIntervalsTheMultiplicity</span></a></p></li> +</ul> +</li> +</ul> +</section> +<section id="v0-7-3-2019-02-04"> +<h2>v0.7.3 (2019/02/04)</h2> +<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 <code class="docutils literal notranslate"><span class="pre">\xintverbosetrue</span></code> regime.</p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#polprintintervalsthevar"><span class="std std-ref">\PolPrintIntervalsTheVar</span></a> remained +defined after <a class="reference internal" href="polexpr-ref.html#polprintintervals"><span class="std std-ref">\PolPrintIntervals</span></a> but was +left undefined after <a class="reference internal" href="polexpr-ref.html#id61"><span class="std std-ref">\PolPrintIntervals*</span></a> +(reported by Jürgen Gilg). Now remains defined in both cases, and +<a class="reference internal" href="polexpr-ref.html#polprintintervalsthesturmname"><span class="std std-ref">\PolPrintIntervalsTheSturmName</span></a> +also.</p></li> +<li><p>Polynomial names ending in digits caused errors (reported by Thomas +Söll).</p></li> +</ul> +</li> +</ul> +</section> +<section id="v0-7-4-2019-02-12"> +<h2>v0.7.4 (2019/02/12)</h2> +<ul class="simple"> +<li><p>bugfix:</p> +<ul> +<li><p>20000000000 is too big for <code class="docutils literal notranslate"><span class="pre">\numexpr</span></code>, shouldn’t I know that? +Thanks to Jürgen Gilg for report.</p></li> +</ul> +</li> +</ul> +</section> +<section id="v0-7-5-2020-01-31"> +<h2>v0.7.5 (2020/01/31)</h2> +<p>Synced with xintexpr 1.4. Requires it.</p> +</section> +<section id="v0-8-2021-03-29"> +<span id="polexpr08release"></span><h2>v0.8 (2021/03/29)</h2> +<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 <code class="docutils literal notranslate"><span class="pre">'</span></code> in names has been extended +from <code class="docutils literal notranslate"><span class="pre">\poldef</span></code> to also generally <code class="docutils literal notranslate"><span class="pre">\xintexpr</span></code>, <code class="docutils literal notranslate"><span class="pre">\xintdefvar</span></code>, +and <code class="docutils literal notranslate"><span class="pre">\xintdeffunc</span></code>, it means that the infix operators +<code class="docutils literal notranslate"><span class="pre">'and'</span></code>, <code class="docutils literal notranslate"><span class="pre">'or'</span></code>, and <code class="docutils literal notranslate"><span class="pre">'mod'</span></code> must be replaced +by <code class="docutils literal notranslate"><span class="pre">&&</span></code>, <code class="docutils literal notranslate"><span class="pre">||</span></code>, and <code class="docutils literal notranslate"><span class="pre">/:</span></code> if they +follow immediately a variable name (similarly <code class="docutils literal notranslate"><span class="pre">'xor'</span></code> must +be replaced by the <code class="docutils literal notranslate"><span class="pre">xor()</span></code> function in such case).</p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#poltoexpr"><span class="std std-ref">\PolToExpr</span></a> by default uses a catcode 12 +<code class="docutils literal notranslate"><span class="pre">^</span></code>. See its documentation and the new configuration +<a class="reference internal" href="polexpr-ref.html#poltoexprcaret"><span class="std std-ref">\PolToExprCaret</span></a>.</p></li> +</ul> +</li> +<li><p>deprecated:</p> +<ul> +<li><p>Usage of <code class="docutils literal notranslate"><span class="pre">P/Q</span></code> for the euclidean quotient of two polynomials is +deprecated. Start using <code class="docutils literal notranslate"><span class="pre">quo(P,Q)</span></code> in its place.</p></li> +</ul> +</li> +<li><p>bugfix:</p> +<ul> +<li><p>The <code class="docutils literal notranslate"><span class="pre">\xintglobaldefstrue</span></code> setting was obeyed only partially +by the polexpr macros defining polynomials.</p></li> +<li><p>The <code class="docutils literal notranslate"><span class="pre">\xintexpr</span></code> variables storing the values of the extremities of the +intervals as found by <a class="reference internal" href="polexpr-ref.html#polsturmisolatezeros"><span class="std std-ref">\PolSturmIsolateZeros</span></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 <code class="docutils literal notranslate"><span class="pre">\poldef</span></code> a function previously declared +via <code class="docutils literal notranslate"><span class="pre">\xintdeffunc</span></code> which made usage of the indexing or slicing +“ople” syntax typically caused <code class="docutils literal notranslate"><span class="pre">TeX</span> <span class="pre">capacity</span> <span class="pre">exceeded</span></code> error. +Indeed 0.7.5 only partially made polexpr able to cope with the +extended possibilities for xintexpr 1.4 user-declared functions. +Hopefully <code class="docutils literal notranslate"><span class="pre">0.8</span></code> achieves full functionality in this context.</p></li> +</ul> +</li> +<li><p>new macros:</p> +<ul> +<li><p><a class="reference internal" href="polexpr-ref.html#polnewpolverbosefalse"><span class="std std-ref">\polnewpolverbosefalse</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#poltoexprcaret"><span class="std std-ref">\PolToExprCaret</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#poltoexprinvar"><span class="std std-ref">\PolToExprInVar</span></a></p></li> +<li><p>alongside the major new functionalities described in the next item +<a class="reference internal" href="polexpr-ref.html#poltypeset"><span class="std std-ref">\PolTypeset</span></a> and <a class="reference internal" href="polexpr-ref.html#poltoexpr"><span class="std std-ref">\PolToExpr</span></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 <code class="docutils literal notranslate"><span class="pre">\xintexpr</span></code> 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="https://www.ctan.org/pkg/xintexpr">xintexpr</a> which arose as consequences to the deep <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> <code class="docutils literal notranslate"><span class="pre">1.4</span></code> +evolution,</p></li> +<li><p>to make available most of the functionality associated to +expandable macros directly in the <code class="docutils literal notranslate"><span class="pre">\xinteval</span></code> syntax as +operators or functions,</p></li> +<li><p>to provide (expandable) functional interface in <code class="docutils literal notranslate"><span class="pre">\xinteval</span></code> 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="polexpr-ref.html#quick"><span class="std std-ref">Quick syntax overview</span></a> and then +<a class="reference internal" href="polexpr-ref.html#polexpr08"><span class="std std-ref">the extended syntax description</span></a>.</p> +</section> +<section id="v0-8-1-2021-04-12"> +<h2>v0.8.1 (2021/04/12)</h2> +<ul class="simple"> +<li><p>breaking changes:</p> +<ul> +<li><p>renamed v0.8’s <code class="docutils literal notranslate"><span class="pre">icontent()</span></code> to <a class="reference internal" href="polexpr-ref.html#cont"><span class="std std-ref">cont()</span></a>.</p></li> +<li><p>renamed v0.8’s <code class="docutils literal notranslate"><span class="pre">lcoeff()</span></code> to <a class="reference internal" href="polexpr-ref.html#lc"><span class="std std-ref">lc()</span></a>.</p></li> +</ul> +</li> +<li><p>bugfix:</p> +<ul> +<li><p>Sadly, <code class="docutils literal notranslate"><span class="pre">diff1()</span></code>, <code class="docutils literal notranslate"><span class="pre">diff2()</span></code>, <code class="docutils literal notranslate"><span class="pre">diffn()</span></code> were broken +for polynomials of degrees 8 or more, due to a typo and +insufficient testing.</p></li> +<li><p>The package should have (as documented) required <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> 1.4d +but in practice it accepted to work with <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> 1.4c, whose +<code class="docutils literal notranslate"><span class="pre">\xinteval</span></code> does not know how to “output” a polynomial.</p></li> +<li><p>The definition of one of the two variants of +<a class="reference internal" href="polexpr-ref.html#polsturmnbofrootsoflessthanorequalto"><span class="std std-ref">\PolSturmNbOfRootsOf…</span></a> +was broken by an end-of-line space, left-over +from mass conversion from LaTeX to TeX syntax.</p></li> +</ul> +</li> +<li><p>added:</p> +<ul> +<li><p><a class="reference internal" href="polexpr-ref.html#lpol"><span class="std std-ref">lpol()</span></a></p></li> +<li><p><a class="reference internal" href="polexpr-ref.html#lcoeffs"><span class="std std-ref">lcoeffs()</span></a></p></li> +</ul> +</li> +</ul> +</section> +<section id="v0-8-2-2021-05-05"> +<h2>v0.8.2 (2021/05/05)</h2> +<ul class="simple"> +<li><p>breaking change:</p> +<ul> +<li><p>usage of <code class="docutils literal notranslate"><span class="pre">\xintPFloat</span></code> in place of <code class="docutils literal notranslate"><span class="pre">\xintFloat</span></code> for +<a class="reference internal" href="polexpr-ref.html#poltofloatexprcmd"><span class="std std-ref">\PolToFloatExprCmd</span></a>.</p></li> +</ul> +</li> +<li><p>improved:</p> +<ul> +<li><p>Some <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> functions such as <code class="docutils literal notranslate"><span class="pre">rseq()</span></code> use the semi-colon, +and it was mentioned in the documentation that <a class="reference internal" href="polexpr-ref.html#poldef"><span class="std std-ref">\poldef</span></a> +will be confused by this and that inner semi-colons could be +set within braces <code class="docutils literal notranslate"><span class="pre">{;}</span></code> as a work-around. It was not clear from +this documentation that also <a class="reference internal" href="polexpr-ref.html#id5"><span class="std std-ref">\PolDef</span></a> required +this work-around. With this relase only <a class="reference internal" href="polexpr-ref.html#poldef"><span class="std std-ref">\poldef</span></a> but +not <a class="reference internal" href="polexpr-ref.html#id5"><span class="std std-ref">\PolDef</span></a> needs the work-around.</p></li> +</ul> +</li> +<li><p>track <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> <code class="docutils literal notranslate"><span class="pre">1.4e</span></code> changes relative to powers.</p></li> +</ul> +</section> +<section id="v0-8-3-2021-05-27"> +<h2>v0.8.3 (2021/05/27)</h2> +<ul class="simple"> +<li><p>small internal update to track an <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> <code class="docutils literal notranslate"><span class="pre">1.4h</span></code> change +regarding handling of exceptions. Will require this version at +least on loading.</p></li> +</ul> +</section> +<section id="v0-8-4-2021-11-01"> +<h2>v0.8.4 (2021/11/01)</h2> +<ul class="simple"> +<li><p>bugfix: <a class="reference internal" href="polexpr-ref.html#id41"><span class="std std-ref">\PolSturmIsolateZeros**{<sturmname>}</span></a> did not declare the <code class="docutils literal notranslate"><span class="pre"><sturmname>_norr</span></code> and +<code class="docutils literal notranslate"><span class="pre"><sturmname>_sqf_norr</span></code> polynomials if original polynomial had no real +root!</p></li> +</ul> +</section> +<section id="v0-8-5-2021-11-30"> +<h2>v0.8.5 (2021/11/30)</h2> +<ul class="simple"> +<li><p>bugfix: support for the <code class="docutils literal notranslate"><span class="pre">intfrom()</span></code> function was in the code, +but the declaration to the polynomial parser had not been done.</p></li> +<li><p>track (belatedly) upstream deprecation of <code class="docutils literal notranslate"><span class="pre">\xintSignedFrac</span></code> and +<code class="docutils literal notranslate"><span class="pre">\xintSignedFwOver</span></code> at <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> <code class="docutils literal notranslate"><span class="pre">1.4g</span></code></p></li> +</ul> +</section> +<section id="v0-8-6-2022-01-09"> +<h2>v0.8.6 (2022/01/09)</h2> +<ul class="simple"> +<li><p>provide a separate <code class="docutils literal notranslate"><span class="pre">polexpr-examples.pdf</span></code> with examples formerly +shown as part of the html documentation.</p></li> +<li><p>minor improvement to the computation of a priori bounds on real roots.</p></li> +<li><p>add <a class="reference internal" href="polexpr-ref.html#polprintintervalsrowseparator"><span class="std std-ref">\PolPrintIntervalsRowSeparator</span></a> +and allow usage of <code class="docutils literal notranslate"><span class="pre">amsmath</span></code> environments in custom +<a class="reference internal" href="polexpr-ref.html#polprintintervalsbeginenv"><span class="std std-ref">\PolPrintIntervalsBeginEnv</span></a> and +<a class="reference internal" href="polexpr-ref.html#polprintintervalsendenv"><span class="std std-ref">\PolPrintIntervalsEndEnv</span></a>.</p></li> +</ul> +</section> +<section id="v0-8-7-2022-05-14"> +<h2>v0.8.7 (2022/05/14)</h2> +<ul class="simple"> +<li><p>bugfix: catcode sanitization by <a class="reference internal" href="polexpr-ref.html#poldef"><span class="std std-ref">\poldef</span></a> was minimal +ever since <code class="docutils literal notranslate"><span class="pre">0.1</span></code> and handled only the semi-colon. Thus e.g. the +active <code class="docutils literal notranslate"><span class="pre">!</span></code> from babel-french caused errors and <code class="docutils literal notranslate"><span class="pre">\string!</span></code> was +needed as work-around for factorials. Now the same sanitization as +for <code class="docutils literal notranslate"><span class="pre">\xintdefvar</span></code> and <code class="docutils literal notranslate"><span class="pre">\xintdeffunc</span></code> is applied. This however can +only work at locations where the catcodes are not yet frozen at the +time <code class="docutils literal notranslate"><span class="pre">\poldef</span></code> expands.</p></li> +<li><p>split the html documentation into three files and enhance it via CSS +styling.</p></li> +</ul> +</section> +</section> + + + <div class="clearer"></div> + </div> + </div> + </div> + <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> + <div class="sphinxsidebarwrapper"><h3>Contents of this page</h3> +<ul> +<li><a class="reference internal" href="#">CHANGES</a><ul> +<li><a class="reference internal" href="#v0-1-2018-01-11-initial-release-features">v0.1 (2018/01/11): initial release. Features:</a></li> +<li><a class="reference internal" href="#v0-2-2018-01-14">v0.2 (2018/01/14)</a></li> +<li><a class="reference internal" href="#v0-3-2018-01-17">v0.3 (2018/01/17)</a></li> +<li><a class="reference internal" href="#v0-3-1-2018-01-18">v0.3.1 (2018/01/18)</a></li> +<li><a class="reference internal" href="#v0-4-2018-02-16">v0.4 (2018/02/16)</a></li> +<li><a class="reference internal" href="#v0-4-1-2018-03-01">v0.4.1 (2018/03/01)</a></li> +<li><a class="reference internal" href="#v0-4-2-2018-03-03">v0.4.2 (2018/03/03)</a></li> +<li><a class="reference internal" href="#v0-5-2018-04-08">v0.5 (2018/04/08)</a></li> +<li><a class="reference internal" href="#v0-5-1-2018-04-22">v0.5.1 (2018/04/22)</a></li> +<li><a class="reference internal" href="#v0-6-2018-11-20">v0.6 (2018/11/20)</a></li> +<li><a class="reference internal" href="#v0-7-2018-12-08-v0-7-1-bugfix-v0-7-2-2nd-bugfix-2018-12-09">v0.7 (2018/12/08), v0.7.1 (bugfix), v0.7.2 (2nd bugfix) (2018/12/09)</a></li> +<li><a class="reference internal" href="#v0-7-3-2019-02-04">v0.7.3 (2019/02/04)</a></li> +<li><a class="reference internal" href="#v0-7-4-2019-02-12">v0.7.4 (2019/02/12)</a></li> +<li><a class="reference internal" href="#v0-7-5-2020-01-31">v0.7.5 (2020/01/31)</a></li> +<li><a class="reference internal" href="#v0-8-2021-03-29">v0.8 (2021/03/29)</a></li> +<li><a class="reference internal" href="#v0-8-1-2021-04-12">v0.8.1 (2021/04/12)</a></li> +<li><a class="reference internal" href="#v0-8-2-2021-05-05">v0.8.2 (2021/05/05)</a></li> +<li><a class="reference internal" href="#v0-8-3-2021-05-27">v0.8.3 (2021/05/27)</a></li> +<li><a class="reference internal" href="#v0-8-4-2021-11-01">v0.8.4 (2021/11/01)</a></li> +<li><a class="reference internal" href="#v0-8-5-2021-11-30">v0.8.5 (2021/11/30)</a></li> +<li><a class="reference internal" href="#v0-8-6-2022-01-09">v0.8.6 (2022/01/09)</a></li> +<li><a class="reference internal" href="#v0-8-7-2022-05-14">v0.8.7 (2022/05/14)</a></li> +</ul> +</li> +</ul> + + <div role="note" aria-label="source link"> + <h3>This Page</h3> + <ul class="this-page-menu"> + <li><a href="polexpr-changes.rst.txt" + rel="nofollow">Show Source</a></li> + </ul> + </div> + <div> + <h4>Previous topic</h4> + <p class="topless"><a href="polexpr-ref.html" + title="previous chapter">polexpr reference</a></p> + </div> + </div> + </div> + <div class="clearer"></div> + </div> + <div class="related" role="navigation" aria-label="related navigation"> + <h3>Navigation</h3> + <ul> + <li class="right" style="margin-right: 10px"> + <a href="polexpr-ref.html" title="polexpr reference" + >previous</a></li> + <li class="nav-item nav-item-0"><a href="polexpr.html">polexpr 0.8.7 documentation</a> »</li> + <li class="nav-item nav-item-this"><a href="">CHANGES</a></li> + </ul> + </div> + <div class="footer" role="contentinfo"> + © Copyright 2022, Jean-François Burnol. + Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 5.0.0+/f58771c09. + </div> + </body> +</html>
\ No newline at end of file diff --git a/Master/texmf-dist/doc/generic/polexpr/polexpr-changes.rst.txt b/Master/texmf-dist/doc/generic/polexpr/polexpr-changes.rst.txt new file mode 100644 index 00000000000..c1f2c834ec6 --- /dev/null +++ b/Master/texmf-dist/doc/generic/polexpr/polexpr-changes.rst.txt @@ -0,0 +1,513 @@ +.. comment: -*- fill-column: 72; mode: rst -*- + +========= + CHANGES +========= + +.. _firstrelease: + +v0.1 (2018/01/11): initial release. Features: +--------------------------------------------- + +* The :ref:`\\poldef <poldef;>` parser itself, +* Differentiation and anti-differentiation, +* Euclidean division and GCDs, +* Various utilities such as :ref:`\\PolFromCSV <PolFromCSV>`, + :ref:`\\PolMapCoeffs <PolMapCoeffs>`, + :ref:`\\PolToCSV <PolToCSV>`, :ref:`\\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`` :ref:`\\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 + :ref:`\\PolEval{P}\\AtExpr{foo} <PolEvalAtExpr>` syntax is needed for + using expressions in the second argument. +* incompatible or breaking changes: + + - :ref:`\\PolToExpr <PolToExpr>` now by default uses *descending* + powers (it also treats differently coefficients equal to 1 or -1.) + Use :ref:`\\PolToExpr* <PolToExpr*>` for *ascending* powers. + - :ref:`\\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 + :ref:`\\PolEvalReduced <PolEvalReducedAt>`. +* new (or newly documented) macros: + + - :ref:`\\PolTypesetCmd <PolTypesetCmd>` + - :ref:`\\PolTypesetCmdPrefix <PolTypesetCmdPrefix>` + - :ref:`\\PolTypesetMonomialCmd <PolTypesetMonomialCmd>` + - :ref:`\\PolEvalReducedAt <PolEvalReducedAt>` + - :ref:`\\PolToFloatExpr <PolToFloatExpr>` + - :ref:`\\PolToExprOneTerm <PolToExprOneTerm>` + - :ref:`\\PolToFloatExprOneTerm <PolToFloatExprOneTerm>` + - :ref:`\\PolToExprCmd <PolToExprCmd>` + - :ref:`\\PolToFloatExprCmd <PolToFloatExprCmd>` + - :ref:`\\PolToExprTermPrefix <PolToExprTermPrefix>` + - :ref:`\\PolToExprVar <PolToExprVar>` + - :ref:`\\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. + - :ref:`\\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 + :ref:`\\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 :ref:`\\PolMapCoeffs <PolMapCoeffs>`. + - :ref:`\\PolGCD <PolGCD>` was buggy in case of first polynomial being + of lesser degree than the second one. +* breaking changes: + + - formerly :ref:`\\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 :ref:`\\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 :ref:`\\PolEvalReduced <PolEvalReducedAt>` + and :ref:`\\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 :ref:`\\PolGenFloatVariant <PolGenFloatVariant>`. +* new non-expandable macros: + + - :ref:`\\PolGenFloatVariant <PolGenFloatVariant>` + - :ref:`\\PolGlobalLet <PolGlobalLet>` + - :ref:`\\PolTypesetOne <PolTypesetOne>` + - :ref:`\\PolQuo <PolQuo>` + - :ref:`\\PolRem <PolRem>` + - :ref:`\\PolToSturm <PolToSturm>` + - :ref:`\\PolToSturm\* <PolToSturm*>` + - :ref:`\\PolSetToSturmChainSignChangesAt <PolSetToSturmChainSignChangesAt>` + - :ref:`\\PolSetToNbOfZerosWithin <PolSetToNbOfZerosWithin>` + - :ref:`\\PolSturmIsolateZeros <PolSturmIsolateZeros>` + - :ref:`\\PolRefineInterval* <PolRefineInterval*>` + - :ref:`\\PolRefineInterval[N] <PolRefineInterval[]>` + - :ref:`\\PolEnsureIntervalLength <PolEnsureIntervalLength>` + - :ref:`\\PolEnsureIntervalLengths <PolEnsureIntervalLengths>` + - :ref:`\\PolPrintIntervals <PolPrintIntervals>` + - :ref:`\\PolPrintIntervalsPrintExactZero <PolPrintIntervalsPrintExactZero>` + - :ref:`\\PolPrintIntervalsPrintLeftEndPoint <PolPrintIntervalsPrintLeftEndPoint>` + - :ref:`\\PolPrintIntervalsPrintRightEndPoint <PolPrintIntervalsPrintRightEndPoint>` + - :ref:`\\PolReduceCoeffs* <PolReduceCoeffs*>` + - :ref:`\\PolMakeMonic <PolMakeMonic>` +* new expandable macros: + + - :ref:`\\PolToExprOneTermStyleA <PolToExprOneTermStyleA>` + - :ref:`\\PolIfCoeffIsPlusOrMinusOne <PolIfCoeffIsPlusOrMinusOne>` + - :ref:`\\PolLeadingCoeff <PolLeadingCoeff>` + - :ref:`\\PolSturmChainLength <PolSturmChainLength>` + - :ref:`\\PolSturmNbOfIsolatedZeros <PolSturmNbOfIsolatedZeros>` + - :ref:`\\PolSturmIfZeroExactlyKnown <PolSturmIfZeroExactlyKnown>` + - :ref:`\\PolSturmIsolatedZeroLeft <PolSturmIsolatedZeroLeft>` + - :ref:`\\PolSturmIsolatedZeroRight <PolSturmIsolatedZeroRight>` + - ``\PolPrintIntervalsTheEndPoint`` (removed at 0.7) + - :ref:`\\PolPrintIntervalsTheIndex <PolPrintIntervalsTheIndex>` + - ``\PolIfEndPointIsPositive`` (removed at 0.7) + - ``\PolIfEndPointIsNegative`` (removed at 0.7) + - ``\PolIfEndPointIsZero`` (removed at 0.7) + - :ref:`\\PolIntervalWidth <PolIntervalWidth>` + - :ref:`\\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: + + - :ref:`\\PolGet{polname}\\fromarray\\macro <PolGet>` + crashed when ``\macro`` was + an xinttools_ array macro with no items. It now produces the zero + polynomial. +* breaking changes: + + - :ref:`\\PolToSturm <PolToSturm>` creates primitive integer coefficients + polynomials. This speeds up localization of roots via + :ref:`\\PolSturmIsolateZeros <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 :ref:`\\PolFromCSV <PolFromCSV>` or + :ref:`\\PolGet <PolGet>` + get their coefficients normalized via xintfrac_\ 's ``\xintRaw``. +* experimental change: + + - optional argument to :ref:`\\PolSturmIsolateZeros <PolSturmIsolateZeros>` + (see ``The degree 41 polynomial with -2, -1.9, -1.8, ..., 0, 0.1, ..., + 1.9, 2 as roots`` in ``polexpr-examples.pdf``). It will presumably be + replaced in future by an interval specification. +* new non-expandable macro: + + - :ref:`\\PolMakePrimitive <PolMakePrimitive>` +* new expandable macro: + + - :ref:`\\PolIContent <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 + :ref:`\\PolToSturm*{\<polname\>}{\<sturmname\>} <PolToSturm*>` + was broken. On the occasion of the fix, its meaning has + been modified, see its documentation. + + - using :ref:`\\PolToSturm <PolToSturm>` with a constant polynomial + caused a division by zero error. + +* new macro: + + - :ref:`\\PolSturmIsolateZeros* <PolSturmIsolateZeros*>` + acts like the :ref:`non-starred variant + <PolSturmIsolateZeros>` then computes all the multiplicities. + +* new expandable macros: + + - :ref:`\\PolSturmIsolatedZeroMultiplicity{\<sturmname\>}{\<index\>} <PolSturmIsolatedZeroMultiplicity>` + - :ref:`\\PolSturmNbOfRootsOf{\<sturmname\>}\\LessThanOrEqualTo{\<value\>} <PolSturmNbOfRootsOfLessThanOrEqualTo>` + - :ref:`\\PolSturmNbOfRootsOf{\<sturmname\>}\\LessThanOrEqualToExpr{\<num. expr.\>} <PolSturmNbOfRootsOfLessThanOrEqualToExpr>` + - :ref:`\\PolSturmNbWithMultOfRootsOf{\<sturmname\>}\\LessThanOrEqualTo{\<value\>} <PolSturmNbWithMultOfRootsOfLessThanOrEqualTo>` + - :ref:`\\PolSturmNbWithMultOfRootsOf{\<sturmname\>}\\LessThanOrEqualToExpr{\<num. expr.\>} <PolSturmNbWithMultOfRootsOfLessThanOrEqualToExpr>` + +v0.7 (2018/12/08), v0.7.1 (bugfix), v0.7.2 (2nd bugfix) (2018/12/09) +-------------------------------------------------------------------- + +* breaking changes: + + - although :ref:`\\PolPrintIntervals[\<varname\>]{\<sturmname\>} <PolPrintIntervals>` default output + remains the same, some auxiliary macros for user-customization + have been removed: ``\PolPrintIntervalsTheEndPoint``, + ``\PolIfEndPointIsPositive{T}{F}``, + ``\PolIfEndPointIsNegative{T}{F}``, and + ``\PolIfEndPointIsZero{T}{F}``. + +* bugfix: + + - it could happen that, contrarily to documentation, an interval computed + by :ref:`\\PolSturmIsolateZeros{\<sturmname\>} <PolSturmIsolateZeros>` had + zero as an endpoint, + - :ref:`\\PolEnsureIntervalLength{\<sturmname\>}{\<index\>}{\<exponent\>} + <PolEnsureIntervalLength>` could under certain circumstances erroneously + replace a non-zero root by zero, + - :ref:`\\PolEnsureIntervalLengths{\<sturmname\>}{\<exponent\>} + <PolEnsureIntervalLengths>` 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: + + - :ref:`\\PolSturmIsolateZeros**{\<sturmname\>} <PolSturmIsolateZeros**>` + - :ref:`\\PolSturmIsolateZerosGetMultiplicitiesAndRationalRoots{\<sturmname\>} <PolSturmIsolateZerosGetMultiplicitiesAndRationalRoots>` + - :ref:`\\PolSturmIsolateZerosAndFindRationalRoots{\<sturmname\>} <PolSturmIsolateZerosAndFindRationalRoots>` + - :ref:`\\polexprsetup <polexprsetup>` + - :ref:`\\PolPrintIntervals* <PolPrintIntervals*>` + - :ref:`\\PolPrintIntervalsNoRealRoots <PolPrintIntervalsNoRealRoots>` + - :ref:`\\PolPrintIntervalsBeginEnv <PolPrintIntervalsBeginEnv>` + - :ref:`\\PolPrintIntervalsEndEnv <PolPrintIntervalsEndEnv>` + - :ref:`\\PolPrintIntervalsKnownRoot <PolPrintIntervalsKnownRoot>` + - :ref:`\\PolPrintIntervalsUnknownRoot <PolPrintIntervalsUnknownRoot>` + - :ref:`\\PolPrintIntervalsPrintMultiplicity <PolPrintIntervalsPrintMultiplicity>` + +* new expandable macros: + + - :ref:`\\PolSturmNbOfRationalRoots{\<sturmname\>} <PolSturmNbOfRationalRoots>` + - :ref:`\\PolSturmNbOfRationalRootsWithMultiplicities{\<sturmname\>} <PolSturmNbOfRationalRootsWithMultiplicities>` + - :ref:`\\PolSturmRationalRoot{\<sturmname\>}{\<k\>} <PolSturmRationalRoot>` + - :ref:`\\PolSturmRationalRootIndex{\<sturmname\>}{\<k\>} <PolSturmRationalRootIndex>` + - :ref:`\\PolSturmRationalRootMultiplicity{\<sturmname\>}{\<k\>} <PolSturmRationalRootMultiplicity>` + - :ref:`\\PolPrintIntervalsTheVar <PolPrintIntervalsTheVar>` + - :ref:`\\PolPrintIntervalsTheSturmName <PolPrintIntervalsTheSturmName>` + - :ref:`\\PolPrintIntervalsTheMultiplicity <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. + - :ref:`\\PolPrintIntervalsTheVar <PolPrintIntervalsTheVar>` remained + defined after :ref:`\\PolPrintIntervals <PolPrintIntervals>` but was + left undefined after :ref:`\\PolPrintIntervals* <PolPrintIntervals*>` + (reported by Jürgen Gilg). Now remains defined in both cases, and + :ref:`\\PolPrintIntervalsTheSturmName <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 xintexpr 1.4. Requires it. + +.. _polexpr08release: + +v0.8 (2021/03/29) +----------------- + +Synced with xintexpr 1.4d. Requires it. + +* breaking changes: + + - As the usability of character ``'`` in names has been extended + from ``\poldef`` to also generally ``\xintexpr``, ``\xintdefvar``, + and ``\xintdeffunc``, it means that the infix operators + ``'and'``, ``'or'``, and ``'mod'`` must be replaced + by ``&&``, ``||``, and ``/:`` if they + follow immediately a variable name (similarly ``'xor'`` must + be replaced by the ``xor()`` function in such case). + + - :ref:`\\PolToExpr <PolToExpr>` by default uses a catcode 12 + ``^``. See its documentation and the new configuration + :ref:`\\PolToExprCaret <PolToExprCaret>`. + +* deprecated: + + - Usage of ``P/Q`` for the euclidean quotient of two polynomials is + deprecated. Start using ``quo(P,Q)`` in its place. + +* bugfix: + + - The ``\xintglobaldefstrue`` setting was obeyed only partially + by the polexpr macros defining polynomials. + + - The ``\xintexpr`` variables storing the values of the extremities of the + intervals as found by :ref:`\\PolSturmIsolateZeros + <PolSturmIsolateZeros>` were not updated at 0.7.5 to the xintexpr 1.4 + format and thus caused low-level TeX errors if used. + + - Attempting to use in ``\poldef`` a function previously declared + via ``\xintdeffunc`` which made usage of the indexing or slicing + "ople" syntax typically caused ``TeX capacity exceeded`` error. + Indeed 0.7.5 only partially made polexpr able to cope with the + extended possibilities for xintexpr 1.4 user-declared functions. + Hopefully ``0.8`` achieves full functionality in this context. + +* new macros: + + - :ref:`\\polnewpolverbosefalse <polnewpolverbosefalse>` + - :ref:`\\PolToExprCaret <PolToExprCaret>` + - :ref:`\\PolToExprInVar <PolToExprInVar>` + - alongside the major new functionalities described in the next item + :ref:`\\PolTypeset <PolTypeset>` and :ref:`\\PolToExpr <PolToExpr>` have + been enhanced to accept as argument a general expression and not + only a pre-declared polynomial name. + +* new features: + + - The package is usable under Plain and probably most any TeX format, + and not only under LaTeX. + + - The core of the package has been rewritten entirely in order to + start letting ``\xintexpr`` recognize a polynomial type as a genuine + variable. This has allowed: + + - to solve the reduced inter-operability problems between polexpr + and xintexpr_ which arose as consequences to the deep xintexpr_ ``1.4`` + evolution, + + - to make available most of the functionality associated to + expandable macros directly in the ``\xinteval`` syntax as + operators or functions, + + - to provide (expandable) functional interface in ``\xinteval`` to + features previously available only via (for some, non-expandable) + macro interface such as gcd computations. + +See the updated :ref:`Quick syntax overview <quick>` and then +:ref:`the extended syntax description <polexpr08>`. + +v0.8.1 (2021/04/12) +------------------- + +* breaking changes: + + - renamed v0.8's ``icontent()`` to :ref:`cont() <cont>`. + - renamed v0.8's ``lcoeff()`` to :ref:`lc() <lc>`. + +* bugfix: + + - Sadly, ``diff1()``, ``diff2()``, ``diffn()`` were broken + for polynomials of degrees 8 or more, due to a typo and + insufficient testing. + + - The package should have (as documented) required xintexpr_ 1.4d + but in practice it accepted to work with xintexpr_ 1.4c, whose + ``\xinteval`` does not know how to "output" a polynomial. + + - The definition of one of the two variants of + :ref:`\\PolSturmNbOfRootsOf... <PolSturmNbOfRootsOfLessThanOrEqualTo>` + was broken by an end-of-line space, left-over + from mass conversion from LaTeX to TeX syntax. + +* added: + + - :ref:`lpol() <lpol>` + - :ref:`lcoeffs() <lcoeffs>` + +v0.8.2 (2021/05/05) +------------------- + +* breaking change: + + - usage of ``\xintPFloat`` in place of ``\xintFloat`` for + :ref:`\\PolToFloatExprCmd <PolToFloatExprCmd>`. + +* improved: + + - Some xintexpr_ functions such as ``rseq()`` use the semi-colon, + and it was mentioned in the documentation that :ref:`\\poldef <poldef;>` + will be confused by this and that inner semi-colons could be + set within braces ``{;}`` as a work-around. It was not clear from + this documentation that also :ref:`\\PolDef <PolDef>` required + this work-around. With this relase only :ref:`\\poldef <poldef;>` but + not :ref:`\\PolDef <PolDef>` needs the work-around. + +* track xintexpr_ ``1.4e`` changes relative to powers. + +v0.8.3 (2021/05/27) +------------------- + +* small internal update to track an xintexpr_ ``1.4h`` change + regarding handling of exceptions. Will require this version at + least on loading. + +v0.8.4 (2021/11/01) +------------------- + +* bugfix: :ref:`\\PolSturmIsolateZeros**{\<sturmname\>} + <PolSturmIsolateZeros**>` did not declare the ``<sturmname>_norr`` and + ``<sturmname>_sqf_norr`` polynomials if original polynomial had no real + root! + +v0.8.5 (2021/11/30) +------------------- + +* bugfix: support for the ``intfrom()`` function was in the code, + but the declaration to the polynomial parser had not been done. + +* track (belatedly) upstream deprecation of ``\xintSignedFrac`` and + ``\xintSignedFwOver`` at xintexpr_ ``1.4g`` + +v0.8.6 (2022/01/09) +------------------- + +* provide a separate ``polexpr-examples.pdf`` with examples formerly + shown as part of the html documentation. + +* minor improvement to the computation of a priori bounds on real roots. + +* add :ref:`\\PolPrintIntervalsRowSeparator <PolPrintIntervalsRowSeparator>` + and allow usage of ``amsmath`` environments in custom + :ref:`\\PolPrintIntervalsBeginEnv <PolPrintIntervalsBeginEnv>` and + :ref:`\\PolPrintIntervalsEndEnv <PolPrintIntervalsEndEnv>`. + +v0.8.7 (2022/05/14) +------------------- + +* bugfix: catcode sanitization by :ref:`\\poldef <poldef;>` was minimal + ever since ``0.1`` and handled only the semi-colon. Thus e.g. the + active ``!`` from babel-french caused errors and ``\string!`` was + needed as work-around for factorials. Now the same sanitization as + for ``\xintdefvar`` and ``\xintdeffunc`` is applied. This however can + only work at locations where the catcodes are not yet frozen at the + time ``\poldef`` expands. + +* split the html documentation into three files and enhance it via CSS + styling. + + +.. _xinttools: +.. _xintfrac: +.. _xint: https://www.ctan.org/pkg/xint + +.. _xintexpr: https://www.ctan.org/pkg/xintexpr + +.. _xintsession: https://www.ctan.org/pkg/xintsession + +.. _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 + + +.. Local variables: +.. sentence-end-double-space: t; +.. End: diff --git a/Master/texmf-dist/doc/generic/polexpr/polexpr-examples.pdf b/Master/texmf-dist/doc/generic/polexpr/polexpr-examples.pdf Binary files differindex 1c67b4e533e..5be0a95a42e 100644 --- a/Master/texmf-dist/doc/generic/polexpr/polexpr-examples.pdf +++ b/Master/texmf-dist/doc/generic/polexpr/polexpr-examples.pdf diff --git a/Master/texmf-dist/doc/generic/polexpr/polexpr-ref.html b/Master/texmf-dist/doc/generic/polexpr/polexpr-ref.html new file mode 100644 index 00000000000..9f3767c48de --- /dev/null +++ b/Master/texmf-dist/doc/generic/polexpr/polexpr-ref.html @@ -0,0 +1,2898 @@ + +<!DOCTYPE html> + +<html lang="en"> + <head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.18.1: http://docutils.sourceforge.net/" /> + + <title>polexpr reference — polexpr 0.8.7 documentation</title> + <link rel="stylesheet" type="text/css" href="polexpr.css" /> + <link rel="next" title="CHANGES" href="polexpr-changes.html" /> + <link rel="prev" title="Introduction to polexpr" href="polexpr.html" /> + </head><body> + <div class="related" role="navigation" aria-label="related navigation"> + <h3>Navigation</h3> + <ul> + <li class="right" style="margin-right: 10px"> + <a href="polexpr-changes.html" title="CHANGES" + accesskey="N">next</a></li> + <li class="right" > + <a href="polexpr.html" title="Introduction to polexpr" + accesskey="P">previous</a> |</li> + <li class="nav-item nav-item-0"><a href="polexpr.html">polexpr 0.8.7 documentation</a> »</li> + <li class="nav-item nav-item-this"><a href="">polexpr reference</a></li> + </ul> + </div> + + <div class="document"> + <div class="documentwrapper"> + <div class="bodywrapper"> + <div class="body" role="main"> + + <section id="polexpr-reference"> +<h1>polexpr reference</h1> +<section id="syntax-overview-via-examples"> +<span id="quick"></span><h2>Syntax overview via examples</h2> +<p>The syntax to define a new polynomial is:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\poldef</span> polname(x):= expression in variable x; +</pre></div> +</div> +<p>The expression will be parsed by the services of <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a>, with some +polynomial aware functions added to its syntax; they are described in +detail <a class="reference internal" href="#polexpr08"><span class="std std-ref">below</span></a>. The parser accepts and will handle +exactly arbitrarily big integers or fractions.</p> +<div class="admonition note"> +<p class="admonition-title">Note</p> +<p><a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> does not automatically reduce fractions to lowest terms, +and, so far (but this may change in future) neither does <a class="reference internal" href="#poldef"><span class="std std-ref">\poldef</span></a>. +See <a class="reference internal" href="#rdcoeffs"><span class="std std-ref">rdcoeffs()</span></a> and the macro +<a class="reference internal" href="#polreducecoeffs"><span class="std std-ref">\PolReduceCoeffs</span></a>.</p> +</div> +<ul class="simple"> +<li><p>In place of <code class="docutils literal notranslate"><span class="pre">x</span></code> an arbitrary <em>dummy variable</em> is authorized, +i.e. per default one <code class="docutils literal notranslate"><span class="pre">a,</span> <span class="pre">..,</span> <span class="pre">z,</span> <span class="pre">A,</span> <span class="pre">..,</span> <span class="pre">Z</span></code> (more letters can be declared +under Unicode engines).</p></li> +<li><p><code class="docutils literal notranslate"><span class="pre">polname</span></code> consists of <em>letters</em>, <em>digits</em>, and also the <code class="docutils literal notranslate"><span class="pre">_</span></code> and +<code class="docutils literal notranslate"><span class="pre">'</span></code> characters are allowed. The polynomial name <strong>must</strong> start with +a letter: do not use the underscore <code class="docutils literal notranslate"><span class="pre">_</span></code> as <em>first character</em> of a +polynomial name (even if of catcode letter). No warning is emitted +but dire consequences will ensue. The <code class="docutils literal notranslate"><span class="pre">@</span></code> is also allowed +(independently of its catcode “letter” or “other”, which does not +matter). It is recommended to avoid using it as first character, +except for temporary polynomial variables.</p></li> +<li><p>The colon before the equality sign is optional and its (reasonable) +catcode does not matter.</p></li> +<li><p>The semi-colon at the end of the expression is mandatory. It is not +allowed to arise from expansion (despite the fact that the expression +itself will be parsed using only expansion), it must be “visible” +immediately.</p></li> +</ul> +<p>There are some potential problems (refer to the <a class="reference internal" href="#technicalities">Technicalities</a> section at +bottom of this page) with the semi-colon as expression terminator, so an +alternative syntax is provided, which avoids it altogether:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\PolDef</span><span class="na">[optional letter]</span><span class="nb">{</span><polname><span class="nb">}{</span><expr. using letter as indeterminate><span class="nb">}</span> +</pre></div> +</div> +<p>The <code class="docutils literal notranslate"><span class="pre">\PolDef</span></code> optional first argument defaults to <code class="docutils literal notranslate"><span class="pre">x</span></code> and must be +used as the indeterminate in the expression.</p> +<p>Examples:</p> +<p><code class="docutils literal notranslate"><span class="pre">\poldef</span> <span class="pre">f(x):=</span> <span class="pre">1</span> <span class="pre">-</span> <span class="pre">x</span> <span class="pre">+</span> <span class="pre">quo(x^5,1</span> <span class="pre">-</span> <span class="pre">x</span> <span class="pre">+</span> <span class="pre">x^2);</span></code></p> +<dl> +<dt><code class="docutils literal notranslate"><span class="pre">\PolDef{f}{1</span> <span class="pre">-</span> <span class="pre">x</span> <span class="pre">+</span> <span class="pre">quo(x^5,1</span> <span class="pre">-</span> <span class="pre">x</span> <span class="pre">+</span> <span class="pre">x^2)}</span></code></dt><dd><p>Both parse the polynomial +expression, and they create internally macros serving to +incarnate the polynomial, its coefficients, and the associated +polynomial function.</p> +<p>The polynomial can then be used in further polynomial definitions, +be served as argument to package macros, or appear as a variable in +various functions <a class="reference internal" href="#polexpr08">described later</a>.</p> +<div class="admonition warning"> +<p class="admonition-title">Warning</p> +<p>Both the function <code class="docutils literal notranslate"><span class="pre">quo()</span></code> (as shown in the example above), and +the infix operator <code class="docutils literal notranslate"><span class="pre">/</span></code> are mapped to the Euclidean quotient.</p> +<p>This usage of <code class="docutils literal notranslate"><span class="pre">/</span></code> to stand for the Euclidean quotient is +<strong>deprecated</strong> and reserved for a (somewhat improbable) possible +extension of the package to handle rational functions as well.</p> +</div> +<div class="admonition attention" id="warningtacit"> +<p class="admonition-title">Attention</p> +<p>Tacit multiplication rules let the parser when encountering +<code class="docutils literal notranslate"><span class="pre">1/2</span> <span class="pre">x^2</span></code> skip the space and thus handle it as <code class="docutils literal notranslate"><span class="pre">1/(2*x^2)</span></code>. +But then it gives zero, because <cite>/</cite> stands for the Euclidean +quotient operation here.</p> +<p>Thus one must use <code class="docutils literal notranslate"><span class="pre">(1/2)x^2</span></code> or <code class="docutils literal notranslate"><span class="pre">1/2*x^2</span></code> or +<code class="docutils literal notranslate"><span class="pre">(1/2)*x^2</span></code> for disambiguation: <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">-</span> <span class="pre">1/2*x^2</span> <span class="pre">+</span> <span class="pre">1/3*x^3...</span></code>. It is +simpler to move the denominator to the right: <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">-</span> <span class="pre">x^2/2</span> <span class="pre">+</span> +<span class="pre">x^3/3</span> <span class="pre">-</span> <span class="pre">...</span></code>.</p> +<p>It is worth noting that <code class="docutils literal notranslate"><span class="pre">1/2(x-1)(x-2)</span></code> suffers the same issue: +<a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a>‘s tacit multiplication always “ties more”, hence this +gets interpreted as <code class="docutils literal notranslate"><span class="pre">1/(2*(x-1)*(x-2))</span></code> not as +<code class="docutils literal notranslate"><span class="pre">(1/2)*(x-1)*(x-2)</span></code> and then gives zero by +polynomial division. Thus, in such cases, use one of +<code class="docutils literal notranslate"><span class="pre">(1/2)(x-1)(x-2)</span></code>, <code class="docutils literal notranslate"><span class="pre">1/2*(x-1)(x-2)</span></code> or <code class="docutils literal notranslate"><span class="pre">(x-1)(x-2)/2</span></code>.</p> +</div> +<p><code class="docutils literal notranslate"><span class="pre">\poldef</span> <span class="pre">P(x):=...;</span></code> defines <code class="docutils literal notranslate"><span class="pre">P</span></code> as a <em>polynomial function</em>, +which can be used inside <code class="docutils literal notranslate"><span class="pre">\xinteval</span></code>, as:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\xinteval</span><span class="nb">{</span>P(3 + 7 + 11)<span class="nb">}</span> +</pre></div> +</div> +<p>or even as:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\xinteval</span><span class="nb">{</span>P(Q1 + Q2 + Q3)<span class="nb">}</span> +</pre></div> +</div> +<p>where <code class="docutils literal notranslate"><span class="pre">Q1</span></code>, <code class="docutils literal notranslate"><span class="pre">Q2</span></code>, <code class="docutils literal notranslate"><span class="pre">Q3</span></code> are polynomials. The evaluation result, +if not a scalar, will then be printed as <code class="docutils literal notranslate"><span class="pre">pol([c0,c1,...])</span></code> which +stands for a polynomial variable having the listed coefficients; see +<a class="reference internal" href="#pol"><span class="std std-ref">pol()</span></a>.</p> +<p>Indeed, as seen above with <code class="docutils literal notranslate"><span class="pre">Q1</span></code>, the symbol <code class="docutils literal notranslate"><span class="pre">P</span></code> also stands for +a <em>variable of polynomial type</em>, which serves as argument to +polynomial specific functions such as <a class="reference internal" href="#deg"><span class="std std-ref">deg()</span></a> or +<a class="reference internal" href="#polgcd"><span class="std std-ref">polgcd()</span></a>, or as argument to other polynomials (as +above), or even simply stands for its own in algebraic expressions +such as:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\poldef</span> Q(z):= P<span class="nb">^</span>2 + z<span class="nb">^</span>10; +</pre></div> +</div> +<p>Notice that in the above, the <code class="docutils literal notranslate"><span class="pre">(z)</span></code> part is mandatory, as it informs +<code class="docutils literal notranslate"><span class="pre">\poldef</span></code> of the letter used for the indeterminate. In the above +<code class="docutils literal notranslate"><span class="pre">P(z)^2</span></code> would give the same as <code class="docutils literal notranslate"><span class="pre">P^2</span></code> but the latter is slightly +more efficient.</p> +<p>One needs to acquire a good understanding of when the symbol <code class="docutils literal notranslate"><span class="pre">P</span></code> +will stand for a function and when it will stand for a variable.</p> +<ul> +<li><p>If <code class="docutils literal notranslate"><span class="pre">P</span></code> and +<code class="docutils literal notranslate"><span class="pre">Q</span></code> are both declared polynomials then:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span>(P+Q)(3)<span class="c">% <--- attention, does (P+Q)*3, not P(3)+Q(3)</span> +</pre></div> +</div> +<p>is currently evaluated as <code class="docutils literal notranslate"><span class="pre">(P+Q)*3</span></code>, because <code class="docutils literal notranslate"><span class="pre">P+Q</span></code> is not +known as a <em>function</em>, but <em>only as a variable of polynomial +type</em>. Note that <a class="reference internal" href="#evalp"><span class="std std-ref">evalp(P+Q,3)</span></a> gives as expected +the same as <code class="docutils literal notranslate"><span class="pre">P(3)+Q(3)</span></code>.</p> +</li> +<li><p>Also:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span>(P)(3)<span class="c">% <--- attention, does P*3, not P(3)</span> +</pre></div> +</div> +<p>will compute <code class="docutils literal notranslate"><span class="pre">P*3</span></code>, because one can not in current <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> syntax +enclose a function name in parentheses: consequently it is the variable +which is used here.</p> +</li> +</ul> +<p>There is a <em>meager possibility</em> that in future some internal changes +to <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> would let <code class="docutils literal notranslate"><span class="pre">(P)(3)</span></code> actually compute <code class="docutils literal notranslate"><span class="pre">P(3)</span></code> and +<code class="docutils literal notranslate"><span class="pre">(P+Q)(3)</span></code> compute <code class="docutils literal notranslate"><span class="pre">P(3)</span> <span class="pre">+</span> <span class="pre">Q(3)</span></code>, but note that <code class="docutils literal notranslate"><span class="pre">(P)(P)</span></code> will +then do <code class="docutils literal notranslate"><span class="pre">P(P)</span></code> and not <code class="docutils literal notranslate"><span class="pre">P*P</span></code>, the latter, current +interpretation, looking more intuitive. Anyway, do not rely too +extensively on tacit <code class="docutils literal notranslate"><span class="pre">*</span></code> and use explicit <code class="docutils literal notranslate"><span class="pre">(P+Q)*(1+2)</span></code> if this +is what is intended.</p> +</dd> +<dt><code class="docutils literal notranslate"><span class="pre">\PolLet{g}={f}</span></code></dt><dd><p>saves a copy of <code class="docutils literal notranslate"><span class="pre">f</span></code> under name <code class="docutils literal notranslate"><span class="pre">g</span></code>. Also usable without <code class="docutils literal notranslate"><span class="pre">=</span></code>.</p> +<p>Has exactly the same effect as <code class="docutils literal notranslate"><span class="pre">\poldef</span> <span class="pre">g(x):=f;</span></code> or <code class="docutils literal notranslate"><span class="pre">\poldef</span> +<span class="pre">g(w):=f(w);</span></code>.</p> +</dd> +<dt><code class="docutils literal notranslate"><span class="pre">\poldef</span> <span class="pre">f(z):=</span> <span class="pre">f^2;</span></code></dt><dd><p>redefines <code class="docutils literal notranslate"><span class="pre">f</span></code> in terms of itself. Prior to <code class="docutils literal notranslate"><span class="pre">0.8</span></code> one needed +the right hand side to be <code class="docutils literal notranslate"><span class="pre">f(z)^2</span></code>. Also, now <code class="docutils literal notranslate"><span class="pre">sqr(f)</span></code> is +possible (also <code class="docutils literal notranslate"><span class="pre">sqr(f(x))</span></code> but not <code class="docutils literal notranslate"><span class="pre">sqr(f)(x)</span></code>).</p> +<p>It may look strange that an indeterminate variable is used on +left-hand-side even though it may be absent of right-hand-side, as +it seems to define <code class="docutils literal notranslate"><span class="pre">f</span></code> always as a polynomial function.</p> +<p>This is a legacy of pre-<code class="docutils literal notranslate"><span class="pre">0.8</span></code> context.</p> +<div class="admonition important"> +<p class="admonition-title">Important</p> +<p>Note that <code class="docutils literal notranslate"><span class="pre">f^2(z)</span></code> or <code class="docutils literal notranslate"><span class="pre">sqr(f)(z)</span></code> will give a logical but +perhaps unexpected result: first <code class="docutils literal notranslate"><span class="pre">f^2</span></code> is computed, then the +opening parenthesis is seen which inserts a tacit multiplication +<code class="docutils literal notranslate"><span class="pre">*</span></code>, so in the end it is as if the input had been <code class="docutils literal notranslate"><span class="pre">f^2</span> <span class="pre">*</span> <span class="pre">z</span></code>. +Although <code class="docutils literal notranslate"><span class="pre">f</span></code> is both a variable and a function, <code class="docutils literal notranslate"><span class="pre">f^2</span></code> is +computed as a polynomial <em>variable</em> and ceases being a function.</p> +</div> +</dd> +<dt><code class="docutils literal notranslate"><span class="pre">\poldef</span> <span class="pre">f(T):=</span> <span class="pre">f(f);</span></code></dt><dd><p>again modifies <code class="docutils literal notranslate"><span class="pre">f</span></code>. Here it is used both as variable and as +a function. Prior to <code class="docutils literal notranslate"><span class="pre">0.8</span></code> it needed to be <code class="docutils literal notranslate"><span class="pre">f(f(T))</span></code>.</p> +</dd> +<dt><code class="docutils literal notranslate"><span class="pre">\poldef</span> <span class="pre">k(z):=</span> <span class="pre">f-g(g^2)^2;</span></code></dt><dd><p>if everybody followed, this should now define the zero polynomial… +And <code class="docutils literal notranslate"><span class="pre">f-sqr(g(sqr(g)))</span></code> computes the same thing.</p> +<p>We can check this in a typeset document like this:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\poldef</span> f(x):= 1 - x + quo(x<span class="nb">^</span>5,1 - x + x<span class="nb">^</span>2);<span class="c">%</span> +<span class="k">\PolLet</span><span class="nb">{</span>g<span class="nb">}</span>=<span class="nb">{</span>f<span class="nb">}</span><span class="c">%</span> +<span class="k">\poldef</span> f(z):= f<span class="nb">^</span>2;<span class="c">%</span> +<span class="k">\poldef</span> f(T):= f(f);<span class="c">%</span> +<span class="k">\poldef</span> k(w):= f-sqr(g(sqr(g)));<span class="c">%</span> +<span class="sb">$$</span><span class="nb">f</span><span class="o">(</span><span class="nb">x</span><span class="o">)</span><span class="nb"> </span><span class="o">=</span><span class="nb"> </span><span class="nv">\vcenter</span><span class="nb">{</span><span class="nv">\hsize</span><span class="m">10</span><span class="nb">cm </span><span class="nv">\PolTypeset</span><span class="nb">{f}} </span><span class="s">$$</span> +<span class="sb">$$</span><span class="nb">g</span><span class="o">(</span><span class="nb">z</span><span class="o">)</span><span class="nb"> </span><span class="o">=</span><span class="nb"> </span><span class="nv">\PolTypeset</span><span class="nb">{g} </span><span class="s">$$</span> +<span class="sb">$$</span><span class="nb">k</span><span class="o">(</span><span class="nb">z</span><span class="o">)</span><span class="nb"> </span><span class="o">=</span><span class="nb"> </span><span class="nv">\PolTypeset</span><span class="nb">{k} </span><span class="s">$$</span> +<span class="k">\immediate\write</span>128<span class="nb">{</span>f(x)=<span class="k">\PolToExpr</span><span class="nb">{</span>f<span class="nb">}}</span><span class="c">% ah, here we see it also</span> +</pre></div> +</div> +</dd> +<dt><code class="docutils literal notranslate"><span class="pre">\poldef</span> <span class="pre">f'(x):=</span> <span class="pre">diff1(f);</span></code></dt><dd><p>(new at <code class="docutils literal notranslate"><span class="pre">0.8</span></code>)</p> +</dd> +<dt><code class="docutils literal notranslate"><span class="pre">\PolDiff{f}{f'}</span></code></dt><dd><p>Both set <code class="docutils literal notranslate"><span class="pre">f'</span></code> (or any other chosen name) to the derivative +of <code class="docutils literal notranslate"><span class="pre">f</span></code>.</p> +<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 +<code class="docutils literal notranslate"><span class="pre">f'(3)^2</span></code> will not work without a prior definition of <code class="docutils literal notranslate"><span class="pre">f'</span></code>.</p> +<p>But one can now use <code class="docutils literal notranslate"><span class="pre">diff1(f)</span></code> for on-the-spot construction with no +permanent declaration, so here <code class="docutils literal notranslate"><span class="pre">evalp(diff1(f),3)^2</span></code>. And +<code class="docutils literal notranslate"><span class="pre">diff1(f)^2</span></code> is same as <code class="docutils literal notranslate"><span class="pre">f'^2</span></code>, assuming here <code class="docutils literal notranslate"><span class="pre">f'</span></code> was declared +to be the derived polynomial.</p> +<p>Notice that the name <code class="docutils literal notranslate"><span class="pre">diff1()</span></code> is experimental and may change. Use +<code class="docutils literal notranslate"><span class="pre">\PolDiff{f}{f'}</span></code> as the stable interface.</p> +</div> +</dd> +<dt><code class="docutils literal notranslate"><span class="pre">\PolTypeset{P}</span></code></dt><dd><p>Typesets (switching to math mode if in text mode):</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\poldef</span> f(x):=(3+x)<span class="nb">^</span>5;<span class="c">%</span> +<span class="k">\PolDiff</span><span class="nb">{</span>f<span class="nb">}{</span>f'<span class="nb">}</span><span class="k">\PolDiff</span><span class="nb">{</span>f'<span class="nb">}{</span>f''<span class="nb">}</span><span class="k">\PolDiff</span><span class="nb">{</span>f''<span class="nb">}{</span>f'''<span class="nb">}</span><span class="c">%</span> +<span class="sb">$$</span><span class="nb">f</span><span class="o">(</span><span class="nb">z</span><span class="o">)</span><span class="nb"> </span><span class="o">=</span><span class="nb"> </span><span class="nv">\PolTypeset</span><span class="o">[</span><span class="nb">z</span><span class="o">]</span><span class="nb">{f} </span><span class="s">$$</span> +<span class="sb">$$</span><span class="nb">f'</span><span class="o">(</span><span class="nb">z</span><span class="o">)</span><span class="nb"> </span><span class="o">=</span><span class="nb"> </span><span class="nv">\PolTypeset</span><span class="o">[</span><span class="nb">z</span><span class="o">]</span><span class="nb">{f'} </span><span class="s">$$</span> +<span class="sb">$$</span><span class="nb">f''</span><span class="o">(</span><span class="nb">z</span><span class="o">)</span><span class="nb"> </span><span class="o">=</span><span class="nb"> </span><span class="nv">\PolTypeset</span><span class="o">[</span><span class="nb">z</span><span class="o">]</span><span class="nb">{f''} </span><span class="s">$$</span> +<span class="sb">$$</span><span class="nb">f'''</span><span class="o">(</span><span class="nb">z</span><span class="o">)=</span><span class="nb"> </span><span class="nv">\PolTypeset</span><span class="o">[</span><span class="nb">z</span><span class="o">]</span><span class="nb">{f'''} </span><span class="s">$$</span> +</pre></div> +</div> +<p>See <a class="reference internal" href="#poltypeset">its documentation</a> for the configurability +via macros.</p> +<p>Since <code class="docutils literal notranslate"><span class="pre">0.8</span></code> <a class="reference internal" href="#poltypeset">\PolTypeset</a> accepts directly an +expression, it does not have to be a pre-declared polynomial name:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\PolTypeset</span><span class="nb">{</span>mul(x-i,i=1..5)<span class="nb">}</span> +</pre></div> +</div> +</dd> +<dt><code class="docutils literal notranslate"><span class="pre">\PolToExpr{P}</span></code></dt><dd><p>Expandably (contrarily to <a class="reference internal" href="#poltypeset">\PolTypeset</a>) +produces <code class="docutils literal notranslate"><span class="pre">c_n*x^n</span> <span class="pre">+</span> <span class="pre">...</span> <span class="pre">+</span> <span class="pre">c_0</span></code> starting from the leading +coefficient. The <code class="docutils literal notranslate"><span class="pre">+</span></code> signs are omitted if followed by negative +coefficients.</p> +<p>This is useful for console or file output. This syntax is Maple and +PSTricks <code class="docutils literal notranslate"><span class="pre">\psplot[algebraic]</span></code> compatible; and also it is +compatible with <code class="docutils literal notranslate"><span class="pre">\poldef</span></code> input syntax, of course. See +<a class="reference internal" href="#id69">\PolToExprCaret</a> for configuration of the <code class="docutils literal notranslate"><span class="pre">^</span></code>, for example to +use rather <code class="docutils literal notranslate"><span class="pre">**</span></code> for Python syntax compliance.</p> +<p>Changed at <code class="docutils literal notranslate"><span class="pre">0.8</span></code>: the <code class="docutils literal notranslate"><span class="pre">^</span></code> in output is by default of catcode 12 +so in a draft document one can use <code class="docutils literal notranslate"><span class="pre">\PolToExpr{P}</span></code> inside the +typesetting flow (without requiring math mode, where the <code class="docutils literal notranslate"><span class="pre">*</span></code> would +be funny and <code class="docutils literal notranslate"><span class="pre">^12</span></code> would only put the <code class="docutils literal notranslate"><span class="pre">1</span></code> as exponent anyhow; +but arguably in text mode the <code class="docutils literal notranslate"><span class="pre">+</span></code> and <code class="docutils literal notranslate"><span class="pre">-</span></code> 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"><span class="std std-ref">\PolToExpr{<pol. expr.>}</span></a> and related macros for customization.</p> +<p>Extended at <code class="docutils literal notranslate"><span class="pre">0.8</span></code> to accept as argument not only the name of a +polynomial variable but more generally any polynomial expression.</p> +</dd> +</dl> +</section> +<section id="using-defined-polynomials-in-floating-point-context"> +<h2>Using defined polynomials in floating point context</h2> +<p>Exact manipulations with fractional coefficients may quickly lead to +very large denominators. For numerical evaluations, it is advisable +to a use a floating point context. But for the polynomial to be +usable as a function in floating point context, an extra step beyond +<code class="docutils literal notranslate"><span class="pre">\poldef</span></code> is required: see <a class="reference internal" href="#polgenfloatvariant">\PolGenFloatVariant</a>. Then the +<code class="docutils literal notranslate"><span class="pre">\xintfloateval</span></code> macro from <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> will recognize the polynomial +as a genuine function (with already float-rounded coefficients, and +using a Horner scheme).</p> +<p>But <a class="reference internal" href="#polgenfloatvariant">\PolGenFloatVariant</a> must be used each time the polynomial gets +redefined or a new polynomial is created out of it. Functions such as +for example <a class="reference internal" href="#deg"><span class="std std-ref">deg()</span></a> which handle the polynomial as an entity +are only available within the <code class="docutils literal notranslate"><span class="pre">\poldef</span></code> and <code class="docutils literal notranslate"><span class="pre">\xinteval</span></code> (or +<code class="docutils literal notranslate"><span class="pre">\xintexpr</span></code>) parsers. Inside <code class="docutils literal notranslate"><span class="pre">\xintfloateval</span></code> a polynomial can only +serve as a numerical function (and only after declaration via +<a class="reference internal" href="#polgenfloatvariant">\PolGenFloatVariant</a>), and not as a variable.</p> +<p>In some cases one may wish to replace a polynomial having acquired +very big fractional coefficients with a new one whose coefficients +have been float-rounded. See <a class="reference internal" href="#polmapcoeffs"><span class="std std-ref">\PolMapCoeffs</span></a> +which can be used for example with the <code class="docutils literal notranslate"><span class="pre">\xintFloat</span></code> macro from the +<a class="reference external" href="https://www.ctan.org/pkg/xint">xintfrac</a> package to achieve this.</p> +</section> +<section id="the-polexpr-0-8-extensions-to-the-xintexpr-syntax"> +<span id="polexpr08"></span><h2>The polexpr <code class="docutils literal notranslate"><span class="pre">0.8</span></code> extensions to the <code class="docutils literal notranslate"><span class="pre">\xintexpr</span></code> syntax</h2> +<p>All the syntax elements described in this section can be used in the +<code class="docutils literal notranslate"><span class="pre">\xintexpr/\xinteval</span></code> context (where polynomials can be obtained from +the <code class="docutils literal notranslate"><span class="pre">pol([])</span></code> constructor, once polexpr is loaded): their usage is +not limited to only <code class="docutils literal notranslate"><span class="pre">\poldef</span></code> context.</p> +<div class="admonition note"> +<p class="admonition-title">Note</p> +<p>If a variable <code class="docutils literal notranslate"><span class="pre">myPol</span></code> defined via <code class="docutils literal notranslate"><span class="pre">\xintdefvar</span></code> turns out +to be a polynomial, the difference with those declared via <code class="docutils literal notranslate"><span class="pre">\poldef</span></code> +will be:</p> +<ol class="arabic"> +<li><p><code class="docutils literal notranslate"><span class="pre">myPol</span></code> is not usable as <em>function</em>, but only as a variable. +Attention that <code class="docutils literal notranslate"><span class="pre">f(x)</span></code> if <code class="docutils literal notranslate"><span class="pre">f</span></code> is only a variable (even a +polynomial one) will actually compute <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">*</span> <span class="pre">x</span></code>.</p></li> +<li><p><code class="docutils literal notranslate"><span class="pre">myPol</span></code> 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 +<code class="docutils literal notranslate"><span class="pre">rightmostroot(pol([42,1,34,2,-8,1]))</span></code> but…</p> +</li> +</ol> +</div> +<section id="warning-about-unstability-of-the-new-syntax"> +<h3>Warning about unstability of the new syntax</h3> +<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 <code class="docutils literal notranslate"><span class="pre">+</span></code>, <code class="docutils literal notranslate"><span class="pre">-</span></code> and <code class="docutils literal notranslate"><span class="pre">*</span></code>).</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> +</section> +<section id="infix-operators"> +<h3>Infix operators <code class="docutils literal notranslate"><span class="pre">+,</span> <span class="pre">-,</span> <span class="pre">*,</span> <span class="pre">/,</span> <span class="pre">**,</span> <span class="pre">^</span></code></h3> +<blockquote> +<div><p>As has been explained in the <a class="reference internal" href="#syntax-overview-via-examples">Syntax overview via examples</a> +section these infix operators have been made polynomial aware, not +only in the <code class="docutils literal notranslate"><span class="pre">\poldef</span></code> context, but generally in any +<code class="docutils literal notranslate"><span class="pre">\xintexpr/\xinteval</span></code> context, inclusive of <code class="docutils literal notranslate"><span class="pre">\xintdeffunc</span></code>.</p> +<p>Conversely functions declared via <code class="docutils literal notranslate"><span class="pre">\xintdeffunc</span></code> and making use of +these operators will automatically be able to accept polynomials +declared from <code class="docutils literal notranslate"><span class="pre">\poldef</span></code> as variables.</p> +<p>Usage of <code class="docutils literal notranslate"><span class="pre">/</span></code> 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 <code class="docutils literal notranslate"><span class="pre">quo()</span></code>.</p> +</div></blockquote> +</section> +<section id="experimental-infix-operators"> +<h3>Experimental infix operators <code class="docutils literal notranslate"><span class="pre">//,</span> <span class="pre">/:</span></code></h3> +<blockquote> +<div><p>Here is the tentative behaviour of <code class="docutils literal notranslate"><span class="pre">A//B</span></code> according to types:</p> +<ul class="simple"> +<li><p><code class="docutils literal notranslate"><span class="pre">A</span></code> non scalar and <code class="docutils literal notranslate"><span class="pre">B</span></code> non scalar: euclidean quotient,</p></li> +<li><p><code class="docutils literal notranslate"><span class="pre">A</span></code> scalar and <code class="docutils literal notranslate"><span class="pre">B</span></code> scalar: floored division,</p></li> +<li><p><code class="docutils literal notranslate"><span class="pre">A</span></code> scalar and <code class="docutils literal notranslate"><span class="pre">B</span></code> non scalar: produces zero,</p></li> +<li><p><code class="docutils literal notranslate"><span class="pre">A</span></code> non scalar and <code class="docutils literal notranslate"><span class="pre">B</span></code> scalar: coefficient per +coefficient floored division.</p></li> +</ul> +<p>This is an <strong>experimental</strong> overloading of the <code class="docutils literal notranslate"><span class="pre">//</span></code> and <code class="docutils literal notranslate"><span class="pre">/:</span></code> +from <code class="docutils literal notranslate"><span class="pre">\xintexpr</span></code>.</p> +<p>The behaviour in the last case, but not only, is to be considerd +<strong>unstable</strong>. The alternative would be for <code class="docutils literal notranslate"><span class="pre">A//B</span></code> with <code class="docutils literal notranslate"><span class="pre">B</span></code> +scalar to act as <code class="docutils literal notranslate"><span class="pre">quo(A,B)</span></code>. But, we have currently chosen to let +<code class="docutils literal notranslate"><span class="pre">//B</span></code> for a scalar <code class="docutils literal notranslate"><span class="pre">B</span></code> 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 <code class="docutils literal notranslate"><span class="pre">B</span></code> is non-scalar.</p> +<p>The <code class="docutils literal notranslate"><span class="pre">/:</span></code> operator provides the associated remainder so always +<code class="docutils literal notranslate"><span class="pre">A</span></code> is reconstructed from <code class="docutils literal notranslate"><span class="pre">(A//B)*B</span> <span class="pre">+</span> <span class="pre">A/:B</span></code>.</p> +<p>If <code class="docutils literal notranslate"><span class="pre">:</span></code> is active character use <code class="docutils literal notranslate"><span class="pre">/\string:</span></code> (it is safer to use +<code class="docutils literal notranslate"><span class="pre">/\string</span> <span class="pre">:</span></code> if it is not known if <code class="docutils literal notranslate"><span class="pre">:</span></code> has catcode other, letter, +or is active, but note that <code class="docutils literal notranslate"><span class="pre">/:</span></code> is fine and needs no precaution if +<code class="docutils literal notranslate"><span class="pre">:</span></code> has catcode letter, it is only an active <code class="docutils literal notranslate"><span class="pre">:</span></code> which is +problematic, like for all other characters possibly used in an +expression).</p> +<blockquote> +<div><p><strong>UNSTABLE</strong></p> +<p>As explained above, there are (among other things) hesitations +about behaviour with <code class="docutils literal notranslate"><span class="pre">pol2</span></code> a scalar.</p> +</div></blockquote> +</div></blockquote> +</section> +<section id="comparison-operators"> +<h3>Comparison operators <code class="docutils literal notranslate"><span class="pre"><,</span> <span class="pre">>,</span> <span class="pre"><=,</span> <span class="pre">>=,</span> <span class="pre">==,</span> <span class="pre">!=</span></code></h3> +<blockquote> +<div><p><strong>NOT YET IMPLEMENTED</strong></p> +<p>As the internal representation by <a class="reference external" href="https://www.ctan.org/pkg/xint">xintfrac</a> and <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">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 <code class="docutils literal notranslate"><span class="pre">\pdfstrcmp</span></code> engine primitive. In fact <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">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 <code class="docutils literal notranslate"><span class="pre">deg()</span></code> +function allows comparing degrees. In this context note the +following syntax:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span>(deg(Q)) ?? <span class="nb">{</span> zero <span class="nb">}</span> <span class="nb">{</span> non-zero scalar <span class="nb">}</span> <span class="nb">{</span> non-scalar <span class="nb">}</span> +</pre></div> +</div> +<p>for branching.</p> +</div></blockquote> +</section> +<section id="pol-nutple-expression"> +<span id="pol"></span><h3><code class="docutils literal notranslate"><span class="pre">pol(<nutple</span> <span class="pre">expression>)</span></code></h3> +<blockquote> +<div><p>This converts a nutple <code class="docutils literal notranslate"><span class="pre">[c0,c1,...,cN]</span></code> 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 “nutple”.</p> +<blockquote> +<div><p>Currently, this process will not normalize the coefficients (such +as reducing to lowest terms), it only trims out the leading zero +coefficients.</p> +</div></blockquote> +<p>Inside <code class="docutils literal notranslate"><span class="pre">\xintexpr</span></code>, this is the only (allowed) way to create ex +nihilo a polynomial variable; inside <code class="docutils literal notranslate"><span class="pre">\poldef</span></code> it is an alternative +input syntax which is more efficient than the input <code class="docutils literal notranslate"><span class="pre">c0</span> <span class="pre">+</span> <span class="pre">c1</span> <span class="pre">*</span> <span class="pre">x</span> <span class="pre">+</span> <span class="pre">c2</span> <span class="pre">*</span> +<span class="pre">x^2</span> <span class="pre">+</span> <span class="pre">...</span></code>.</p> +</div></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 <code class="docutils literal notranslate"><span class="pre">\poldef</span></code> +or <code class="docutils literal notranslate"><span class="pre">\xintexpr</span></code> between constant polynomial variables and scalar +variables.</p> +<p>Naturally, <code class="docutils literal notranslate"><span class="pre">\poldef</span></code> can be used to declare a constant polynomial +<code class="docutils literal notranslate"><span class="pre">P</span></code>, then <code class="docutils literal notranslate"><span class="pre">P</span></code> 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 <code class="docutils literal notranslate"><span class="pre">deg()</span></code> tacitly +consider scalars to be constant polynomials).</p> +<p>Notice that we tend to use the vocable “variable” to refer to +arbitrary expressions used as function arguments, without implying +that we are actually referring to pre-declared variables in the sense +of <code class="docutils literal notranslate"><span class="pre">\xintdefvar</span></code>.</p> +</div> +</section> +<section id="lpol-nutple-expression"> +<span id="lpol"></span><h3><code class="docutils literal notranslate"><span class="pre">lpol(<nutple</span> <span class="pre">expression>)</span></code></h3> +<blockquote> +<div><p>This converts a nutple <code class="docutils literal notranslate"><span class="pre">[cN,...,c1,c0]</span></code> into the polynomial +variable having these coefficients, with leading coefficients coming +first in the input. Attention that the square brackets are +<strong>mandatory</strong>, except of course if the argument is actually an +expression producing such a “nutple”.</p> +<blockquote> +<div><p>Currently, this process will not normalize the coefficients (such +as reducing to lowest terms), it only trims out the leading zero +coefficients.</p> +<p><strong>NAME UNSTABLE</strong></p> +</div></blockquote> +<p>It can be used in <code class="docutils literal notranslate"><span class="pre">\poldef</span></code> as an alternative input syntax, which +is more efficient than using the algebraic notation with monomials.</p> +<p>(new with <code class="docutils literal notranslate"><span class="pre">0.8.1</span></code>, an empty nutple will cause breakage)</p> +</div></blockquote> +</section> +<section id="xinteval-pol-expr"> +<span id="xintevalpolexpr"></span><h3><code class="docutils literal notranslate"><span class="pre">\xinteval{<pol.</span> <span class="pre">expr.>}</span></code></h3> +<blockquote> +<div><p>This is documented here for lack of a better place: it evaluates the +polynomial expression then outputs the “string” <code class="docutils literal notranslate"><span class="pre">pol([c0,</span> <span class="pre">c1,</span> <span class="pre">...,</span> <span class="pre">cN])</span></code> +if the degree <code class="docutils literal notranslate"><span class="pre">N</span></code> is at least one (and the usual scalar output else).</p> +<p>The “pol” 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 <code class="docutils literal notranslate"><span class="pre">\poldef</span></code> or <code class="docutils literal notranslate"><span class="pre">\xintexpr</span></code> at it means basically +executing <code class="docutils literal notranslate"><span class="pre">pol(coeffs(..expression..))</span></code> which is but a convoluted +way to obtain the same result as <code class="docutils literal notranslate"><span class="pre">(..expression..)</span></code> (the +parentheses delimiting the polynomial expression).</p> +<p>For example, <code class="docutils literal notranslate"><span class="pre">\xinteval{(1+pol([0,1]))^10}</span></code> expands (in two steps) +to:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span>pol([1, 10, 45, 120, 210, 252, 210, 120, 45, 10, 1]) +</pre></div> +</div> +<p>You do need loading polexpr for this, else of course <code class="docutils literal notranslate"><span class="pre">pol([])</span></code> +remains unknown to <code class="docutils literal notranslate"><span class="pre">\xinteval{}</span></code> as well as the polynomial algebra ! +This example can also be done as +<code class="docutils literal notranslate"><span class="pre">\xinteval{subs((1+x)^10,x=pol([0,1]))}</span></code>.</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> +</div></blockquote> +</section> +<section id="evalp-pol-expr-pol-expr"> +<span id="evalp"></span><h3><code class="docutils literal notranslate"><span class="pre">evalp(<pol.</span> <span class="pre">expr.>,</span> <span class="pre"><pol.</span> <span class="pre">expr>)</span></code></h3> +<blockquote> +<div><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> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\poldef</span> K(x):= evalp(-3x<span class="nb">^</span>3-5x+1,-27x<span class="nb">^</span>4+5x-2); +</pre></div> +</div> +<p>If the first argument is an already declared polynomial <code class="docutils literal notranslate"><span class="pre">P</span></code>, use +rather the functional form <code class="docutils literal notranslate"><span class="pre">P()</span></code> (which can accept a numerical as +well as polynomial argument) as it is more efficient.</p> +<p>One can also use <code class="docutils literal notranslate"><span class="pre">subs()</span></code> syntax <a class="footnote-reference brackets" href="#id2" id="id1" role="doc-noteref"><span class="fn-bracket">[</span>1<span class="fn-bracket">]</span></a> (see <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> documentation):</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\poldef</span> K(x):= subs(-3y<span class="nb">^</span>3-5y+1, y = -27x<span class="nb">^</span>4+5x-2); +</pre></div> +</div> +<p>but the <code class="docutils literal notranslate"><span class="pre">evalp()</span></code> will use a Horner evaluation scheme which is +usually more efficient.</p> +<aside class="footnote brackets" id="id2" role="note"> +<span class="label"><span class="fn-bracket">[</span><a role="doc-backlink" href="#id1">1</a><span class="fn-bracket">]</span></span> +<p>by the way Maple uses the opposite, hence wrong, order +<code class="docutils literal notranslate"><span class="pre">subs(x=...,</span> <span class="pre">P)</span></code> but was written before computer science +reached the <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> heights. However it makes validating +Maple results by polexpr sometimes cumbersome, but perhaps +they will update it at some point.</p> +</aside> +<blockquote> +<div><p><strong>name unstable</strong></p> +<p><code class="docutils literal notranslate"><span class="pre">poleval</span></code>? <code class="docutils literal notranslate"><span class="pre">evalpol</span></code>? <code class="docutils literal notranslate"><span class="pre">peval</span></code>? <code class="docutils literal notranslate"><span class="pre">evalp</span></code>? <code class="docutils literal notranslate"><span class="pre">value</span></code>? +<code class="docutils literal notranslate"><span class="pre">eval</span></code>? <code class="docutils literal notranslate"><span class="pre">evalat</span></code>? <code class="docutils literal notranslate"><span class="pre">eval1at2</span></code>? <code class="docutils literal notranslate"><span class="pre">evalat2nd</span></code>?</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> +</div></blockquote> +</div></blockquote> +</section> +<section id="deg-pol-expr"> +<span id="deg"></span><h3><code class="docutils literal notranslate"><span class="pre">deg(<pol.</span> <span class="pre">expr.>)</span></code></h3> +<blockquote> +<div><p>Computes the degree.</p> +</div></blockquote> +<div class="admonition important"> +<p class="admonition-title">Important</p> +<p>As <code class="docutils literal notranslate"><span class="pre">\xintexpr</span></code> does not yet support infinities, the degree of +the zero polynomial is <code class="docutils literal notranslate"><span class="pre">-1</span></code>. Beware that this breaks additivity +of degrees, but <code class="docutils literal notranslate"><span class="pre">deg(P)<0</span></code> correctly detects the zero polynomial, +and <code class="docutils literal notranslate"><span class="pre">deg(P)<=0</span></code> detects scalars.</p> +</div> +</section> +<section id="coeffs-pol-expr"> +<h3><code class="docutils literal notranslate"><span class="pre">coeffs(<pol.</span> <span class="pre">expr.>)</span></code></h3> +<blockquote> +<div><p>Produces the nutple <code class="docutils literal notranslate"><span class="pre">[c0,c1,...,cN]</span></code> of coefficients. The highest +degree coefficient is always non zero (except for the zero +polynomial…).</p> +<blockquote> +<div><p><strong>name unstable</strong></p> +<p>I am considering in particular using <code class="docutils literal notranslate"><span class="pre">polcoeffs()</span></code> to avoid +having to overload <code class="docutils literal notranslate"><span class="pre">coeffs()</span></code> in future when matrix type +will be added to <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a>.</p> +</div></blockquote> +</div></blockquote> +</section> +<section id="lcoeffs-pol-expr"> +<span id="lcoeffs"></span><h3><code class="docutils literal notranslate"><span class="pre">lcoeffs(<pol.</span> <span class="pre">expr.>)</span></code></h3> +<blockquote> +<div><p>Produces the nutple <code class="docutils literal notranslate"><span class="pre">[cN,....,c1,c0]</span></code> of coefficients, starting +with the highest degree coefficient.</p> +<p>(new with <code class="docutils literal notranslate"><span class="pre">0.8.1</span></code>)</p> +</div></blockquote> +</section> +<section id="coeff-pol-expr-num-expr"> +<h3><code class="docutils literal notranslate"><span class="pre">coeff(<pol.</span> <span class="pre">expr.>,</span> <span class="pre"><num.</span> <span class="pre">expr.>)</span></code></h3> +<blockquote> +<div><p>As expected. Produces zero if the numerical index is negative or +higher than the degree.</p> +<blockquote> +<div><p><strong>name, syntax and output unstable</strong></p> +<p>I am hesitating with <code class="docutils literal notranslate"><span class="pre">coeff(n,pol)</span></code> syntax and also perhaps using +<code class="docutils literal notranslate"><span class="pre">polcoeff()</span></code> in order to avoid having to overload <code class="docutils literal notranslate"><span class="pre">coeff()</span></code> +when matrix type will be added to <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a>.</p> +<p>The current behaviour is at odds with legacy +<a class="reference internal" href="#polnthcoeff"><span class="std std-ref">\PolNthCoeff{<polname>}{<index>}</span></a> regarding negative indices. +Accessing leading or sub-leading coefficients can be done with +other syntax, see <a class="reference internal" href="#lc-pol-expr">lc(<pol. expr.>)</a>, and in some contexts it +is useful to be able to rely on the fact that coefficients with +negative indices do vanish, so I am for time being maintaining this.</p> +</div></blockquote> +</div></blockquote> +</section> +<section id="lc-pol-expr"> +<span id="lc"></span><h3><code class="docutils literal notranslate"><span class="pre">lc(<pol.</span> <span class="pre">expr.>)</span></code></h3> +<blockquote> +<div><p>The leading coefficient. The same result can be obtained from +<code class="docutils literal notranslate"><span class="pre">coeffs(pol)[-1]</span></code>, which shows also how to generalize to access +sub-leading coefficients. See the <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> documentation for +Python-like indexing syntax.</p> +</div></blockquote> +</section> +<section id="monicpart-pol-expr"> +<h3><code class="docutils literal notranslate"><span class="pre">monicpart(<pol.</span> <span class="pre">expr.>)</span></code></h3> +<blockquote> +<div><p>Divides by the leading coefficient, except that <code class="docutils literal notranslate"><span class="pre">monicpart(0)==0</span></code>.</p> +<blockquote> +<div><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="https://www.ctan.org/pkg/xint">xintfrac</a> <code class="docutils literal notranslate"><span class="pre">\xintREZ</span></code> 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> +</div></blockquote> +</div></blockquote> +</section> +<section id="cont-pol-expr"> +<span id="cont"></span><h3><code class="docutils literal notranslate"><span class="pre">cont(<pol.</span> <span class="pre">expr.>)</span></code></h3> +<blockquote> +<div><p>The (fractional) greatest common divisor of the 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> +<div><p><strong>name and syntax unstable</strong></p> +<p>At <code class="docutils literal notranslate"><span class="pre">0.8</span></code> it was created as <code class="docutils literal notranslate"><span class="pre">icontent()</span></code> to match the legacy +macro <a class="reference internal" href="#policontent">\PolIContent</a>, whose name in 2018 was +chosen in relation to Maple’s function <code class="docutils literal notranslate"><span class="pre">icontent()</span></code>, possibly +because at that time I had not seen that Maple also had a +<code class="docutils literal notranslate"><span class="pre">content()</span></code> function. Name changed at <code class="docutils literal notranslate"><span class="pre">0.8.1</span></code>.</p> +<p>It will change syntax if in future multivariate polynomials are +supported, and <code class="docutils literal notranslate"><span class="pre">icontent()</span></code> will then make a come-back.</p> +</div></blockquote> +</div></blockquote> +</section> +<section id="primpart-pol-expr"> +<h3><code class="docutils literal notranslate"><span class="pre">primpart(<pol.</span> <span class="pre">expr.>)</span></code></h3> +<blockquote> +<div><p>The quotient (except for the zero polynomial) by +<code class="docutils literal notranslate"><span class="pre">cont(<pol.</span> <span class="pre">expr.>)</span></code>. This is thus a polynomial with +integer coefficients having <code class="docutils literal notranslate"><span class="pre">1</span></code> as greatest common divisor. The +sign of the leading coefficient is the same as in the original.</p> +<p>And <code class="docutils literal notranslate"><span class="pre">primpart(0)==0</span></code>.</p> +<p>The trailing zeros of the integer coefficients are extracted +into a power of ten exponent part, in the internal representation.</p> +</div></blockquote> +</section> +<section id="quorem-pol-expr-pol-expr"> +<h3><code class="docutils literal notranslate"><span class="pre">quorem(<pol.</span> <span class="pre">expr.>,</span> <span class="pre"><pol.</span> <span class="pre">expr.>)</span></code></h3> +<blockquote> +<div><p>Produces a nutple <code class="docutils literal notranslate"><span class="pre">[Q,R]</span></code> with <code class="docutils literal notranslate"><span class="pre">Q</span></code> the euclidean quotient and +<code class="docutils literal notranslate"><span class="pre">R</span></code> the remainder.</p> +<blockquote> +<div><p><strong>name unstable</strong></p> +<p><code class="docutils literal notranslate"><span class="pre">poldiv()</span></code>?</p> +</div></blockquote> +</div></blockquote> +</section> +<section id="quo-pol-expr-pol-expr"> +<h3><code class="docutils literal notranslate"><span class="pre">quo(<pol.</span> <span class="pre">expr.>,</span> <span class="pre"><pol.</span> <span class="pre">expr.>)</span></code></h3> +<blockquote> +<div><p>The euclidean quotient.</p> +<p>The deprecated <code class="docutils literal notranslate"><span class="pre">pol1/pol2</span></code> syntax computes the same polynomial.</p> +</div></blockquote> +</section> +<section id="rem-pol-expr-pol-expr"> +<h3><code class="docutils literal notranslate"><span class="pre">rem(<pol.</span> <span class="pre">expr.>,</span> <span class="pre"><pol.</span> <span class="pre">expr.>)</span></code></h3> +<blockquote> +<div><p>The euclidean remainder. If <code class="docutils literal notranslate"><span class="pre">pol2</span></code> 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><code class="docutils literal notranslate"><span class="pre">/:</span></code> can be used if one is certain that <code class="docutils literal notranslate"><span class="pre">pol2</span></code> is of +degree at least one. But read the warning about it being unstable +even in that case.</p> +</div></blockquote> +</section> +<section id="prem-pol-expr-1-pol-expr-2"> +<span id="prem"></span><h3><code class="docutils literal notranslate"><span class="pre">prem(<pol.</span> <span class="pre">expr.</span> <span class="pre">1>,</span> <span class="pre"><pol.</span> <span class="pre">expr.</span> <span class="pre">2>)</span></code></h3> +<blockquote> +<div><p>Produces a nutple <code class="docutils literal notranslate"><span class="pre">[m,</span> <span class="pre">spR]</span></code> where <code class="docutils literal notranslate"><span class="pre">spR</span></code> is the (special) pseudo +Euclidean remainder. Its description is:</p> +<ul> +<li><p>the standard euclidean remainder <code class="docutils literal notranslate"><span class="pre">R</span></code> is <code class="docutils literal notranslate"><span class="pre">spR/m</span></code></p></li> +<li><p><code class="docutils literal notranslate"><span class="pre">m</span> <span class="pre">=</span> <span class="pre">b^f</span></code> with <code class="docutils literal notranslate"><span class="pre">b</span></code> equal to the <strong>absolute value</strong> of the +leading coefficient of <code class="docutils literal notranslate"><span class="pre">pol2</span></code>,</p></li> +<li><p><code class="docutils literal notranslate"><span class="pre">f</span></code> is the number of non-zero coefficients in the euclidean +quotient, if <code class="docutils literal notranslate"><span class="pre">deg(pol2)>0</span></code> (even if the remainder vanishes).</p> +<p>If <code class="docutils literal notranslate"><span class="pre">pol2</span></code> is a scalar however, the function outputs <code class="docutils literal notranslate"><span class="pre">[1,0]</span></code>.</p> +</li> +</ul> +<p>With these definitions one can show that if both <code class="docutils literal notranslate"><span class="pre">pol1</span></code> and +<code class="docutils literal notranslate"><span class="pre">pol2</span></code> have integer coefficients, then this is also the case of +<code class="docutils literal notranslate"><span class="pre">spR</span></code>, which makes its interest (and also <code class="docutils literal notranslate"><span class="pre">m*Q</span></code> has integer +coefficients, with <code class="docutils literal notranslate"><span class="pre">Q</span></code> the euclidean quotient, if <code class="docutils literal notranslate"><span class="pre">deg(pol2)>0</span></code>). +Also, <code class="docutils literal notranslate"><span class="pre">prem()</span></code> is computed faster than <code class="docutils literal notranslate"><span class="pre">rem()</span></code> for such integer +coefficients polynomials.</p> +<div class="admonition hint"> +<p class="admonition-title">Hint</p> +<p>If you want the euclidean quotient <code class="docutils literal notranslate"><span class="pre">R</span></code> evaluated via <code class="docutils literal notranslate"><span class="pre">spR/m</span></code> +(which may be faster, even with non integer coefficients) use +<code class="docutils literal notranslate"><span class="pre">subs(last(x)/first(x),x=prem(P,Q))</span></code> syntax as it avoids +computing <code class="docutils literal notranslate"><span class="pre">prem(P,Q)</span></code> twice. This does the trick both in +<code class="docutils literal notranslate"><span class="pre">\poldef</span></code> or in <code class="docutils literal notranslate"><span class="pre">\xintdefvar</span></code>.</p> +<p>However, as is explained in the <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> documentation, using +such syntax in an <code class="docutils literal notranslate"><span class="pre">\xintdeffunc</span></code> is (a.t.t.o.w) illusory, due to +technicalities of how <code class="docutils literal notranslate"><span class="pre">subs()</span></code> gets converted into nested +expandable macros. One needs an auxiliary function like this:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\xintdeffunc</span> lastoverfirst(x):=last(x)/first(x); +<span class="k">\xintdeffunc</span> myR(x)=lastoverfirst(prem(x)); +</pre></div> +</div> +<p>Then, <code class="docutils literal notranslate"><span class="pre">myR(pol1,pol2)</span></code> will evaluate <code class="docutils literal notranslate"><span class="pre">prem(pol1,pol2)</span></code> 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 <code class="docutils literal notranslate"><span class="pre">pol1</span></code> and <code class="docutils literal notranslate"><span class="pre">pol2</span></code> (no automatic reduction to +lowest terms is made prior or after computation).</p> +<p>Pay attention here that <code class="docutils literal notranslate"><span class="pre">b</span></code> is the <strong>absolute value</strong> of the +leading coefficient of <code class="docutils literal notranslate"><span class="pre">pol2</span></code>. 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> +</div></blockquote> +</section> +<section id="divmod-pol-expr-1-pol-expr-2"> +<h3><code class="docutils literal notranslate"><span class="pre">divmod(<pol.</span> <span class="pre">expr.</span> <span class="pre">1>,</span> <span class="pre"><pol.</span> <span class="pre">expr.</span> <span class="pre">2>)</span></code></h3> +<blockquote> +<div><p>Overloads the scalar <code class="docutils literal notranslate"><span class="pre">divmod()</span></code> and associates it with the +experimental <code class="docutils literal notranslate"><span class="pre">//</span></code> and <code class="docutils literal notranslate"><span class="pre">/:</span></code> as extended to the polynomial type.</p> +<p>In particular when both <code class="docutils literal notranslate"><span class="pre">pol1</span></code> and <code class="docutils literal notranslate"><span class="pre">pol2</span></code> are scalars, this is +the usual <code class="docutils literal notranslate"><span class="pre">divmod()</span></code> (as in Python) and for <code class="docutils literal notranslate"><span class="pre">pol1</span></code> and <code class="docutils literal notranslate"><span class="pre">pol2</span></code> +non constant polynomials, this is the same as <code class="docutils literal notranslate"><span class="pre">quorem()</span></code>.</p> +<blockquote> +<div><p><strong>Highly unstable</strong> overloading of <code class="docutils literal notranslate"><span class="pre">\xinteval</span></code>‘s <code class="docutils literal notranslate"><span class="pre">divmod()</span></code>.</p> +</div></blockquote> +</div></blockquote> +</section> +<section id="mod-pol-expr-1-pol-expr-2"> +<h3><code class="docutils literal notranslate"><span class="pre">mod(<pol.</span> <span class="pre">expr.</span> <span class="pre">1>,</span> <span class="pre"><pol.</span> <span class="pre">expr.</span> <span class="pre">2>)</span></code></h3> +<blockquote> +<div><p>The <code class="docutils literal notranslate"><span class="pre">R</span></code> of the <code class="docutils literal notranslate"><span class="pre">divmod()</span></code> output. Same as <code class="docutils literal notranslate"><span class="pre">R</span></code> of <code class="docutils literal notranslate"><span class="pre">quorem()</span></code> +when the second argument <code class="docutils literal notranslate"><span class="pre">pol2</span></code> is of degree at least one.</p> +<blockquote> +<div><p><strong>Highly unstable</strong> overloading of <code class="docutils literal notranslate"><span class="pre">\xinteval</span></code>‘s <code class="docutils literal notranslate"><span class="pre">mod()</span></code>.</p> +</div></blockquote> +</div></blockquote> +</section> +<section id="polgcd-pol-expr-1-pol-expr-2"> +<h3><code class="docutils literal notranslate"><span class="pre">polgcd(<pol.</span> <span class="pre">expr.</span> <span class="pre">1>,</span> <span class="pre"><pol.</span> <span class="pre">expr.</span> <span class="pre">2>,</span> <span class="pre">...)</span></code></h3> +<blockquote> +<div><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 “nutple” whose +items are polynomials (see the documentation of the scalar <code class="docutils literal notranslate"><span class="pre">gcd()</span></code> +in <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a>).</p> +<blockquote> +<div><p>The two variable case could (and was, during development) have been +defined at user level like this:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\xintdeffunc</span> polgcd<span class="nb">_</span>(P,Q):= + (deg(Q))??<span class="nb">{</span>P<span class="nb">}{</span>1<span class="nb">}{</span>polgcd<span class="nb">_</span>(Q,primpart(last(prem(P,Q))))<span class="nb">}</span>; +<span class="k">\xintdeffunc</span> polgcd(P,Q):=polgcd<span class="nb">_</span>(primpart(P),primpart(Q));<span class="c">%</span> +</pre></div> +</div> +<p>This is basically what is done internally for two polynomials, up +to some internal optimizations.</p> +</div></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="#id4" id="id3" role="doc-noteref"><span class="fn-bracket">[</span>2<span class="fn-bracket">]</span></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 <code class="docutils literal notranslate"><span class="pre">monicpart()</span></code> 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> +<aside class="footnote brackets" id="id4" role="note"> +<span class="label"><span class="fn-bracket">[</span><a role="doc-backlink" href="#id3">2</a><span class="fn-bracket">]</span></span> +<p>actually, only two polynomial arguments are allowed by Maple’s +<code class="docutils literal notranslate"><span class="pre">gcd()</span></code> as far as I know.</p> +</aside> +</div></blockquote> +</section> +<section id="resultant-pol-expr-1-pol-expr-2"> +<h3><code class="docutils literal notranslate"><span class="pre">resultant(<pol.</span> <span class="pre">expr.</span> <span class="pre">1>,</span> <span class="pre"><pol.</span> <span class="pre">expr.</span> <span class="pre">2>)</span></code></h3> +<blockquote> +<div><p>The resultant.</p> +<blockquote> +<div><p><strong>NOT YET IMPLEMENTED</strong></p> +</div></blockquote> +</div></blockquote> +</section> +<section id="disc-pol-expr"> +<h3><code class="docutils literal notranslate"><span class="pre">disc(<pol.</span> <span class="pre">expr.>)</span></code></h3> +<blockquote> +<div><p>The discriminant.</p> +<blockquote> +<div><p><strong>NOT YET IMPLEMENTED</strong></p> +</div></blockquote> +</div></blockquote> +</section> +<section id="polpowmod-pol-expr-1-num-expr-pol-expr-2"> +<h3><code class="docutils literal notranslate"><span class="pre">polpowmod(<pol.</span> <span class="pre">expr.</span> <span class="pre">1>,</span> <span class="pre"><num.</span> <span class="pre">expr.>,</span> <span class="pre"><pol.</span> <span class="pre">expr.</span> <span class="pre">2>)</span></code></h3> +<blockquote> +<div><p>Modular exponentiation: <code class="docutils literal notranslate"><span class="pre">mod(pol1^N,</span> <span class="pre">pol2)</span></code> in a more efficient +manner than first computing <code class="docutils literal notranslate"><span class="pre">pol1^N</span></code> then reducing modulo <code class="docutils literal notranslate"><span class="pre">pol2</span></code>.</p> +<p>Attention that this is using the <code class="docutils literal notranslate"><span class="pre">mod()</span></code> operation, whose current +experimental status is as follows:</p> +<ul class="simple"> +<li><p>if <code class="docutils literal notranslate"><span class="pre">deg(pol2)>0</span></code>, the euclidean remainder operation,</p></li> +<li><p>if <code class="docutils literal notranslate"><span class="pre">pol2</span></code> is a scalar, coefficient-wise reduction modulo <code class="docutils literal notranslate"><span class="pre">pol2</span></code>.</p></li> +</ul> +<p><strong>UNSTABLE</strong></p> +<blockquote> +<div><p>This is currently implemented at high level via <code class="docutils literal notranslate"><span class="pre">\xintdeffunc</span></code> and +recursive definitions, which were copied over from a scalar example +in the <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> manual:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\xintdeffunc</span> polpowmod<span class="nb">_</span>(P, m, Q) := + isone(m)? + <span class="c">% m=1: return P modulo Q</span> + <span class="nb">{</span> mod(P,Q) <span class="nb">}</span> + <span class="c">% m > 1: test if odd or even and do recursive call</span> + <span class="nb">{</span> odd(m)? <span class="nb">{</span> mod(P*sqr(polpowmod<span class="nb">_</span>(P, m//2, Q)), Q) <span class="nb">}</span> + <span class="nb">{</span> mod( sqr(polpowmod<span class="nb">_</span>(P, m//2, Q)), Q) <span class="nb">}</span> + <span class="nb">}</span> + ;<span class="c">%</span> +<span class="k">\xintdeffunc</span> polpowmod(P, m, Q) := (m)?<span class="nb">{</span>polpowmod<span class="nb">_</span>(P, m, Q)<span class="nb">}{</span>1<span class="nb">}</span>;<span class="c">%</span> +</pre></div> +</div> +<p>Negative exponents are not currently implemented.</p> +<p>For example:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\xinteval</span><span class="nb">{</span>subs(polpowmod(1+x,100,x<span class="nb">^</span>7),x=pol([0,1]))<span class="nb">}</span> +<span class="k">\xinteval</span><span class="nb">{</span>subs(polpowmod(1+x,20,10), x=pol([0,1]))<span class="nb">}</span> +</pre></div> +</div> +<p>produce respectively:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span>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></div> +</div> +</div></blockquote> +</div></blockquote> +</section> +<section id="rdcoeffs-pol-expr"> +<span id="rdcoeffs"></span><h3><code class="docutils literal notranslate"><span class="pre">rdcoeffs(<pol.</span> <span class="pre">expr.>)</span></code></h3> +<blockquote> +<div><p>This operates on the internal representation of the coefficients, +reducing them to lowest terms.</p> +<blockquote> +<div><p><strong>name HIGHLY undecided</strong></p> +</div></blockquote> +</div></blockquote> +</section> +<section id="rdzcoeffs-pol-expr"> +<h3><code class="docutils literal notranslate"><span class="pre">rdzcoeffs(<pol.</span> <span class="pre">expr.>)</span></code></h3> +<blockquote> +<div><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> +<div><p><strong>name HIGHLY undecided</strong></p> +</div></blockquote> +</div></blockquote> +</section> +<section id="diff1-pol-expr"> +<h3><code class="docutils literal notranslate"><span class="pre">diff1(<pol.</span> <span class="pre">expr.>)</span></code></h3> +<blockquote> +<div><p>The first derivative.</p> +<blockquote> +<div><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> +</div></blockquote> +</div></blockquote> +</section> +<section id="diff2-pol-expr"> +<h3><code class="docutils literal notranslate"><span class="pre">diff2(<pol.</span> <span class="pre">expr.>)</span></code></h3> +<blockquote> +<div><p>The second derivative.</p> +<blockquote> +<div><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> +</div></blockquote> +</div></blockquote> +</section> +<section id="diffn-pol-expr-p-num-expr-n"> +<h3><code class="docutils literal notranslate"><span class="pre">diffn(<pol.</span> <span class="pre">expr.</span> <span class="pre">P>,</span> <span class="pre"><num.</span> <span class="pre">expr.</span> <span class="pre">n>)</span></code></h3> +<blockquote> +<div><p>The <code class="docutils literal notranslate"><span class="pre">n</span></code>th derivative of <code class="docutils literal notranslate"><span class="pre">P</span></code>. For <code class="docutils literal notranslate"><span class="pre">n<0</span></code> computes iterated primitives +vanishing at the origin.</p> +<p>The coefficients are not reduced to lowest terms.</p> +<blockquote> +<div><p><strong>name and syntax UNSTABLE</strong></p> +<p>I am also considering reversing the order of the arguments.</p> +</div></blockquote> +</div></blockquote> +</section> +<section id="antider-pol-expr-p"> +<h3><code class="docutils literal notranslate"><span class="pre">antider(<pol.</span> <span class="pre">expr.</span> <span class="pre">P>)</span></code></h3> +<blockquote> +<div><p>The primitive of <code class="docutils literal notranslate"><span class="pre">P</span></code> with no constant term. Same as <code class="docutils literal notranslate"><span class="pre">diffn(P,-1)</span></code>.</p> +</div></blockquote> +</section> +<section id="intfrom-pol-expr-p-pol-expr-c"> +<h3><code class="docutils literal notranslate"><span class="pre">intfrom(<pol.</span> <span class="pre">expr.</span> <span class="pre">P>,</span> <span class="pre"><pol.</span> <span class="pre">expr.</span> <span class="pre">c>)</span></code></h3> +<blockquote> +<div><p>The primitive of <code class="docutils literal notranslate"><span class="pre">P</span></code> vanishing at <code class="docutils literal notranslate"><span class="pre">c</span></code>, i.e. <code class="docutils literal notranslate"><span class="pre">\int_c^x</span> <span class="pre">P(t)dt</span></code>.</p> +<p>Also <code class="docutils literal notranslate"><span class="pre">c</span></code> can be a polynomial… so if <code class="docutils literal notranslate"><span class="pre">c</span></code> is monomial <code class="docutils literal notranslate"><span class="pre">x</span></code> +this will give zero!</p> +<blockquote> +<div><p><strong>UNSTABLE</strong></p> +<p>Allowing general polynomial variable for <code class="docutils literal notranslate"><span class="pre">c</span></code> adds a bit of +overhead to the case of a pure scalar. So I am hesitating +maintaining this feature whose interest appears dubious.</p> +</div></blockquote> +<div class="admonition attention"> +<p class="admonition-title">Attention</p> +<p>As the two arguments are both allowed to be polynomials, if by +inadvertance one exchanges the two, there is no error but the +meaning of <code class="docutils literal notranslate"><span class="pre">intfrom(c,P)</span></code> is completely otherwise, as it +produces <code class="docutils literal notranslate"><span class="pre">c*(x</span> <span class="pre">-</span> <span class="pre">P)</span></code> if <code class="docutils literal notranslate"><span class="pre">c</span></code> is a scalar:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span>>>> <span class="nb">&</span>pol +pol mode (i.e. function definitions use <span class="k">\poldef</span>) +>>> P(x):=1+x<span class="nb">^</span>2; +P = x<span class="nb">^</span>2+1 + --> <span class="nb">&</span>GenFloat(P) lets P become usable as function in fp mode + --> <span class="nb">&</span>ROOTS(P) (resp. <span class="nb">&</span>ROOTS(P,N)) finds all rational roots exactly and + all irrational roots with at least 10 (resp. N) fractional digits +>>> intfrom(P,1); +@<span class="nb">_</span>1 pol([-4/3, 1, 0, 1/3]) +>>> intfrom(1,P); +@<span class="nb">_</span>2 pol([-1, 1, -1]) +>>> <span class="nb">&</span>bye +</pre></div> +</div> +</div> +</div></blockquote> +</section> +<section id="integral-pol-expr-p-pol-expr-a-pol-expr-b"> +<h3><code class="docutils literal notranslate"><span class="pre">integral(<pol.</span> <span class="pre">expr.</span> <span class="pre">P>,</span> <span class="pre">[<pol.</span> <span class="pre">expr.</span> <span class="pre">a>,</span> <span class="pre"><pol.</span> <span class="pre">expr.</span> <span class="pre">b>])</span></code></h3> +<blockquote> +<div><p><code class="docutils literal notranslate"><span class="pre">\int_a^b</span> <span class="pre">P(t)dt</span></code>.</p> +<div class="admonition warning"> +<p class="admonition-title">Warning</p> +<p>The brackets here are not denoting an optional argument but a +<em>mandatory</em> nutple argument <code class="docutils literal notranslate"><span class="pre">[a,</span> <span class="pre">b]</span></code> with <em>two items</em>. No real +recoverable-from error check is done on the input syntax. The +input can be an <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> variable which happens to be a nutple +with two items, or any expression which evaluates to such a +nutple.</p> +</div> +<p><code class="docutils literal notranslate"><span class="pre">a</span></code> and <code class="docutils literal notranslate"><span class="pre">b</span></code> are not restricted to be scalars, they are allowed to +be themselves polynomial variables or even polynomial expressions.</p> +<blockquote> +<div><p>To compute <code class="docutils literal notranslate"><span class="pre">\int_{x-1}^x</span> <span class="pre">P(t)dt</span></code> it is more efficient to use +<code class="docutils literal notranslate"><span class="pre">intfrom(x-1)</span></code>.</p> +<p>Similary to compute <code class="docutils literal notranslate"><span class="pre">\int_x^{x+1}</span> <span class="pre">P(t)dt</span></code>, use <code class="docutils literal notranslate"><span class="pre">-intfrom(x+1)</span></code>.</p> +<p><strong>UNSTABLE</strong></p> +<p>Am I right to allow general polynomials <code class="docutils literal notranslate"><span class="pre">a</span></code> and <code class="docutils literal notranslate"><span class="pre">b</span></code> hence add +overhead to the pure scalar case ?</p> +</div></blockquote> +</div></blockquote> +</section> +</section> +<section id="non-expandable-macros"> +<h2>Non-expandable macros</h2> +<div class="admonition note"> +<p class="admonition-title">Note</p> +<p>At <code class="docutils literal notranslate"><span class="pre">0.8</span></code> <code class="docutils literal notranslate"><span class="pre">polexpr</span></code> is usable with Plain TeX and not only with +LaTeX. Some examples given in this section may be using LaTeX syntax +such as <code class="docutils literal notranslate"><span class="pre">\renewcommand</span></code>.</p> +</div> +<section id="poldef-polname-letter-expression-using-the-letter-as-indeterminate"> +<span id="poldef"></span><h3><code class="docutils literal notranslate"><span class="pre">\poldef</span> <span class="pre">polname(letter):=</span> <span class="pre">expression</span> <span class="pre">using</span> <span class="pre">the</span> <span class="pre">letter</span> <span class="pre">as</span> <span class="pre">indeterminate;</span></code></h3> +<blockquote> +<div><p>This evaluates the <em>polynomial expression</em> and stores the +coefficients in a private structure accessible later via other +package macros, used with argument <code class="docutils literal notranslate"><span class="pre">polname</span></code>. Of course the +<em>expression</em> can make use of previously defined polynomials.</p> +<p>Polynomial names must start with a letter and are constituted of +letters, digits, underscores and the right tick <code class="docutils literal notranslate"><span class="pre">'</span></code>.</p> +<p>The whole <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> syntax is authorized, as long as the final +result is of polynomial type:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\poldef</span> polname(z) := add((-1)<span class="nb">^</span>i z<span class="nb">^</span>(2i+1)/(2i+1)!, i = 0..10); +</pre></div> +</div> +<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 <code class="docutils literal notranslate"><span class="pre">polname</span></code> is defined which can be used in <code class="docutils literal notranslate"><span class="pre">\poldef</span></code> +as well as in <code class="docutils literal notranslate"><span class="pre">\xinteval</span></code> for algebraic computations or as +argument to polynomial aware functions,</p></li> +<li><p>a function <code class="docutils literal notranslate"><span class="pre">polname()</span></code> is defined which can be used in <code class="docutils literal notranslate"><span class="pre">\poldef</span></code> +as well as in <code class="docutils literal notranslate"><span class="pre">\xinteval</span></code>. 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 <code class="docutils literal notranslate"><span class="pre">\xintdeffunc</span></code> and using +only algebraic operations (and ople indexing or slicing operations) +should work fine in <code class="docutils literal notranslate"><span class="pre">\xintexpr/\xinteval</span></code> with such polynomial +names as argument.</p> +<p>In the case of a constant polynomial, the <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">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 <code class="docutils literal notranslate"><span class="pre">cos()</span></code> function).</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 <code class="docutils literal notranslate"><span class="pre">polname()</span></code> is defined <strong>only</strong> for +<code class="docutils literal notranslate"><span class="pre">\xintexpr/\xinteval</span></code> +context. It will be unknown to <code class="docutils literal notranslate"><span class="pre">\xintfloateval</span></code>.</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 <code class="docutils literal notranslate"><span class="pre">\poldef</span></code> or <code class="docutils literal notranslate"><span class="pre">\PolDef</span></code> but +as result of usage of the other package macros.</p> +<p>See <a class="reference internal" href="#polgenfloatvariant"><span class="std std-ref">\PolGenFloatVariant{<polname>}</span></a> to generate a <strong>function</strong> +usable in <code class="docutils literal notranslate"><span class="pre">\xintfloateval</span></code>.</p> +</div> +<div class="admonition attention"> +<p class="admonition-title">Attention</p> +<p>Using the <strong>variable</strong> <code class="docutils literal notranslate"><span class="pre">mypol</span></code> inside <code class="docutils literal notranslate"><span class="pre">\xintfloateval</span></code> will +generate low-level errors because the infix operators there are +not polynomial-aware, and the polynomial specific functions such +as <code class="docutils literal notranslate"><span class="pre">deg()</span></code> are only defined for usage inside <code class="docutils literal notranslate"><span class="pre">\xintexpr</span></code>.</p> +<p>In short, currently polynomials defined via <code class="docutils literal notranslate"><span class="pre">polexpr</span></code> can +be used in floating point context only for numerical evaluations, +via <strong>functions</strong> obtained from <a class="reference internal" href="#polgenfloatvariant"><span class="std std-ref">\PolGenFloatVariant{<polname>}</span></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> +</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> +</div></blockquote> +</section> +<section id="poldef-letter-polname-expr-using-the-letter-as-indeterminate"> +<span id="id5"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolDef[<letter>]{<polname>}{<expr.</span> <span class="pre">using</span> <span class="pre">the</span> <span class="pre">letter</span> <span class="pre">as</span> <span class="pre">indeterminate>}</span></code></h3> +<blockquote> +<div><p>Does the same as <a class="reference internal" href="#poldef">\poldef</a> in an undelimited macro +format, the main interest is to avoid potential problems with the +catcode of the semi-colon in presence of some packages. In absence +of a <code class="docutils literal notranslate"><span class="pre">[<letter>]</span></code> optional argument, the variable is assumed to be +<code class="docutils literal notranslate"><span class="pre">x</span></code>.</p> +</div></blockquote> +</section> +<section id="polgenfloatvariant"> +<span id="id6"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolGenFloatVariant{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolGenFloatVariant{<polname>}</span></code></p> +<blockquote> +<div><p>Makes the polynomial also usable in the +<code class="docutils literal notranslate"><span class="pre">\xintfloatexpr/\xintfloateval</span></code> parser. It will therein evaluates +via an Horner scheme using polynomial coefficients already +pre-rounded to the float precision.</p> +<p>See also <a class="reference internal" href="#poltofloatexpr"><span class="std std-ref">\PolToFloatExpr{<pol. expr.>}</span></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 <code class="docutils literal notranslate"><span class="pre">\PolLet</span></code>, must be +followed by explicit usage of <code class="docutils literal notranslate"><span class="pre">\PolGenFloatVariant{<polname>}</span></code> if +the new polynomial is to be used in <code class="docutils literal notranslate"><span class="pre">\xintfloateval</span></code>.</p> +</div> +</div></blockquote> +</section> +<section id="poltypeset"> +<span id="id7"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolTypeset{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolTypeset{<pol.</span> <span class="pre">expr.>}</span></code></p> +<blockquote> +<div><p>Typesets in descending powers, switching to math mode if in text +mode, after evaluating the polynomial expression:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\PolTypeset</span><span class="nb">{</span>mul(x-i,i=1..5)<span class="nb">}</span><span class="c">% possible since polexpr 0.8</span> +</pre></div> +</div> +<p>The letter used in the input expression is by default <code class="docutils literal notranslate"><span class="pre">x</span></code>, +but can be modified by a redefinition of <a class="reference internal" href="#id67">\PolToExprInVar</a>.</p> +<p>It uses also by default the letter <code class="docutils literal notranslate"><span class="pre">x</span></code> on output but this one can +be changed via an optional argument:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\PolTypeset</span><span class="na">[z]</span><span class="nb">{</span>polname or polynomial expression<span class="nb">}</span> +</pre></div> +</div> +<p>By default zero coefficients are skipped (use <code class="docutils literal notranslate"><span class="pre">\poltypesetalltrue</span></code> +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> +</div></blockquote> +<section id="poltypesetcmd"> +<span id="id8"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolTypesetCmd{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolTypesetCmd{<raw_coeff>}</span></code></p> +<blockquote> +<div><p>Its package definition checks if the coefficient is <code class="docutils literal notranslate"><span class="pre">1</span></code> or <code class="docutils literal notranslate"><span class="pre">-1</span></code> +and then skips printing the <code class="docutils literal notranslate"><span class="pre">1</span></code>, except for the coefficient of +degree zero. Also it sets the conditional deciding behaviour of +<a class="reference internal" href="#polifcoeffisplusorminusone"><span class="std std-ref">\PolIfCoeffIsPlusOrMinusOne{T}{F}</span></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"><span class="std std-ref">\PolTypesetOne{<raw_coeff>}</span></a>.</p> +</div></blockquote> +<section id="polifcoeffisplusorminusone"> +<span id="id9"></span><h5><code class="docutils literal notranslate"><span class="pre">\PolIfCoeffIsPlusOrMinusOne{}{}</span></code></h5> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolIfCoeffIsPlusOrMinusOne{T}{F}</span></code></p> +<blockquote> +<div><p>This macro is a priori undefined.</p> +<p>It is defined via the default <a class="reference internal" href="#poltypesetcmd"><span class="std std-ref">\PolTypesetCmd{<raw_coeff>}</span></a> to be +used if needed in the execution of <a class="reference internal" href="#id11">\PolTypesetMonomialCmd</a>, +e.g. to insert a <code class="docutils literal notranslate"><span class="pre">\cdot</span></code> in front of <code class="docutils literal notranslate"><span class="pre">\PolVar^{\PolIndex}</span></code> if +the coefficient is not plus or minus one.</p> +<p>The macro will execute <code class="docutils literal notranslate"><span class="pre">T</span></code> if the coefficient has been found to be +plus or minus one, and <code class="docutils literal notranslate"><span class="pre">F</span></code> if not. It chooses expandably between +<code class="docutils literal notranslate"><span class="pre">T</span></code> and <code class="docutils literal notranslate"><span class="pre">F</span></code>.</p> +</div></blockquote> +</section> +</section> +<section id="poltypesetone"> +<span id="id10"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolTypesetOne{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolTypesetOne{<raw_coeff>}</span></code></p> +<blockquote> +<div><p>Defaults to <code class="docutils literal notranslate"><span class="pre">\xintTeXsignedFrac</span></code> (LaTeX) or <code class="docutils literal notranslate"><span class="pre">\xintTeXsignedOver</span></code> +(else). But these <a class="reference external" href="https://www.ctan.org/pkg/xint">xintfrac</a> old legacy macros are a bit +annoying as they insist in exhibiting a power of ten rather than +using simpler decimal notation.</p> +<p>As alternative, one can do definitions such as:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\def\PolTypesetOne</span>#1<span class="nb">{</span><span class="k">\xintDecToString</span><span class="nb">{</span><span class="k">\xintREZ</span><span class="nb">{</span>#1<span class="nb">}}}</span> +<span class="c">% or with LaTeX+siunitx for example</span> +<span class="k">\renewcommand\PolTypesetOne</span><span class="na">[1]</span><span class="nb">{</span><span class="k">\num</span><span class="nb">{</span><span class="k">\xintPFloat</span><span class="na">[5]</span><span class="nb">{</span>#1<span class="nb">}}}</span> +<span class="c">% (as \num of siunitx understands floating point notation)</span> +<span class="k">\renewcommand\PolTypesetOne</span><span class="na">[1]</span><span class="nb">{</span><span class="k">\num</span><span class="nb">{</span><span class="k">\xintRound</span><span class="nb">{</span>4<span class="nb">}{</span>#1<span class="nb">}}}</span> +</pre></div> +</div> +</div></blockquote> +</section> +<section id="poltypesetmonomialcmd"> +<span id="id11"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolTypesetMonomialCmd</span></code></h4> +<blockquote> +<div><p>This decides how a monomial (in variable <code class="docutils literal notranslate"><span class="pre">\PolVar</span></code> and with +exponent <code class="docutils literal notranslate"><span class="pre">\PolIndex</span></code>) is to be printed. The default does nothing +for the constant term, <code class="docutils literal notranslate"><span class="pre">\PolVar</span></code> for the first degree and +<code class="docutils literal notranslate"><span class="pre">\PolVar^{\PolIndex}</span></code> for higher degrees monomials. Beware that +<code class="docutils literal notranslate"><span class="pre">\PolIndex</span></code> expands to digit tokens and needs termination in +<code class="docutils literal notranslate"><span class="pre">\ifnum</span></code> tests.</p> +</div></blockquote> +</section> +<section id="poltypesetcmdprefix"> +<span id="id12"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolTypesetCmdPrefix{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolTypesetCmdPrefix{<raw_coeff>}</span></code></p> +<blockquote> +<div><p>Expands to a <code class="docutils literal notranslate"><span class="pre">+</span></code> if the <code class="docutils literal notranslate"><span class="pre">raw_coeff</span></code> is zero or positive, and to +nothing if <code class="docutils literal notranslate"><span class="pre">raw_coeff</span></code> is negative, as in latter case the +<code class="docutils literal notranslate"><span class="pre">\xintTeXsignedFrac</span></code> (or <code class="docutils literal notranslate"><span class="pre">\xintTeXsignedOver</span></code>) used by +<a class="reference internal" href="#poltypesetcmd"><span class="std std-ref">\PolTypesetCmd{<raw_coeff>}</span></a> will put the <code class="docutils literal notranslate"><span class="pre">-</span></code> 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> +</div></blockquote> +</section> +</section> +<section id="id13"> +<span id="id14"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolTypeset*{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolTypeset*{<pol.</span> <span class="pre">expr.>}</span></code></p> +<blockquote> +<div><p>Typesets in ascending powers. Use <code class="docutils literal notranslate"><span class="pre">[<letter>]</span></code> optional argument +(after the <code class="docutils literal notranslate"><span class="pre">*</span></code>) to use another letter than <code class="docutils literal notranslate"><span class="pre">x</span></code>.</p> +<p>Extended at <code class="docutils literal notranslate"><span class="pre">0.8</span></code> to accept general expressions and not only +polynomial names. Redefine <a class="reference internal" href="#id67">\PolToExprInVar</a> to use in the +expression another letter than default <code class="docutils literal notranslate"><span class="pre">x</span></code>.</p> +</div></blockquote> +</section> +<section id="pollet"> +<span id="id15"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolLet{}={}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolLet{<polname_2>}={<polname_1>}</span></code></p> +<blockquote> +<div><p>Makes a copy of the already defined polynomial <code class="docutils literal notranslate"><span class="pre">polname_1</span></code> to a +new one <code class="docutils literal notranslate"><span class="pre">polname_2</span></code>. This has the same effect as +<code class="docutils literal notranslate"><span class="pre">\PolDef{<polname_2>}{<polname_1>(x)}</span></code> or (better) +<code class="docutils literal notranslate"><span class="pre">\PolDef{<polname_2>}{<polname_1>}</span></code> but with less overhead. The +<code class="docutils literal notranslate"><span class="pre">=</span></code> is optional.</p> +</div></blockquote> +</section> +<section id="polgloballet"> +<span id="id16"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolGlobalLet{}={}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolGlobalLet{<polname_2>}={<polname_1>}</span></code></p> +<blockquote> +<div><p>Acts globally.</p> +</div></blockquote> +</section> +<section id="polassign-toarray"> +<span id="polassign"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolAssign{}\toarray{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolAssign{<polname>}\toarray{<\macro>}</span></code></p> +<blockquote> +<div><p>Defines a one-argument expandable macro <code class="docutils literal notranslate"><span class="pre">\macro{#1}</span></code> which expands +to the (raw) #1th polynomial coefficient.</p> +<ul class="simple"> +<li><p>Attention, coefficients here are indexed starting at 1. This is +an unfortunate legacy situation related to the original indexing +convention in <a class="reference external" href="https://www.ctan.org/pkg/xint">xinttools</a> arrays.</p></li> +<li><p>With #1=-1, -2, …, <code class="docutils literal notranslate"><span class="pre">\macro{#1}</span></code> returns leading coefficients.</p></li> +<li><p>With #1=0, returns the number of coefficients, i.e. <code class="docutils literal notranslate"><span class="pre">1</span> <span class="pre">+</span> <span class="pre">deg</span> <span class="pre">f</span></code> +for non-zero polynomials.</p></li> +<li><p>Out-of-range #1’s return <code class="docutils literal notranslate"><span class="pre">0/1[0]</span></code>.</p></li> +</ul> +<p>See also <a class="reference internal" href="#polnthcoeff"><span class="std std-ref">\PolNthCoeff{<polname>}{<index>}</span></a>.</p> +</div></blockquote> +</section> +<section id="polget-fromarray"> +<span id="polget"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolGet{}\fromarray{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolGet{<polname>}\fromarray{<\macro>}</span></code></p> +<blockquote> +<div><p>Does the converse operation to +<code class="docutils literal notranslate"><span class="pre">\PolAssign{<polname>}\toarray\macro</span></code>. Each individual +<code class="docutils literal notranslate"><span class="pre">\macro{<value>}</span></code> gets expanded in an <code class="docutils literal notranslate"><span class="pre">\edef</span></code> and then normalized +via <a class="reference external" href="https://www.ctan.org/pkg/xint">xintfrac</a>‘s macro <code class="docutils literal notranslate"><span class="pre">\xintRaw</span></code>.</p> +<p>The leading zeros are removed from the polynomial.</p> +<p>(contrived) Example:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\xintAssignArray</span><span class="nb">{</span>1<span class="nb">}{</span>-2<span class="nb">}{</span>5<span class="nb">}{</span>-3<span class="nb">}</span><span class="k">\to\foo</span> +<span class="k">\PolGet</span><span class="nb">{</span>f<span class="nb">}</span><span class="k">\fromarray\foo</span> +</pre></div> +</div> +<p>This will define <code class="docutils literal notranslate"><span class="pre">f</span></code> as would have <code class="docutils literal notranslate"><span class="pre">\poldef</span> <span class="pre">f(x):=1-2x+5x^2-3x^3;</span></code>.</p> +</div></blockquote> +</section> +<section id="polfromcsv"> +<span id="id17"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolFromCSV{}{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolFromCSV{<polname>}{<csv>}</span></code></p> +<blockquote> +<div><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 <code class="docutils literal notranslate"><span class="pre">\edef</span></code> and then put into normalized +form via <a class="reference external" href="https://www.ctan.org/pkg/xint">xintfrac</a>‘s macro <code class="docutils literal notranslate"><span class="pre">\xintRaw</span></code>.</p> +<p>As leading zero coefficients are removed:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\PolFromCSV</span><span class="nb">{</span>f<span class="nb">}{</span>0, 0, 0, 0, 0, 0, 0, 0, 0, 0<span class="nb">}</span> +</pre></div> +</div> +<p>defines the zero polynomial, which holds only one coefficient.</p> +<p>See also expandable macro <a class="reference internal" href="#poltocsv"><span class="std std-ref">\PolToCSV{<polname>}</span></a>.</p> +</div></blockquote> +</section> +<section id="polmapcoeffs"> +<span id="id18"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolMapCoeffs{}{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolMapCoeffs{\macro}{<polname>}</span></code></p> +<blockquote> +<div><p>It modifies (‘in-place’: original coefficients get lost) each +coefficient of the defined polynomial via the <em>expandable</em> macro +<code class="docutils literal notranslate"><span class="pre">\macro</span></code>. The degree is adjusted as necessary if some leading +coefficients vanish after the operation.</p> +<p>In the replacement text of <code class="docutils literal notranslate"><span class="pre">\macro</span></code>, <code class="docutils literal notranslate"><span class="pre">\index</span></code> expands to the +coefficient index (starting at zero for the constant term).</p> +<p>Notice that <code class="docutils literal notranslate"><span class="pre">\macro</span></code> will have to handle inputs in the <a class="reference external" href="https://www.ctan.org/pkg/xint">xintfrac</a> +internal format. This means that it probably will have to be +expressed in terms of macros from the <a class="reference external" href="https://www.ctan.org/pkg/xint">xintfrac</a> package.</p> +<p>Example:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\def\foo</span>#1<span class="nb">{</span><span class="k">\xintMul</span><span class="nb">{</span>#1<span class="nb">}{</span><span class="k">\the\numexpr\index*\index\relax</span><span class="nb">}}</span> +</pre></div> +</div> +<p>(or with <code class="docutils literal notranslate"><span class="pre">\xintSqr{\index}</span></code>) to replace <code class="docutils literal notranslate"><span class="pre">n</span></code>-th coefficient +<code class="docutils literal notranslate"><span class="pre">f_n</span></code> by <code class="docutils literal notranslate"><span class="pre">f_n*n^2</span></code>.</p> +</div></blockquote> +</section> +<section id="polreducecoeffs"> +<span id="id19"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolReduceCoeffs{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolReduceCoeffs{<polname>}</span></code></p> +<blockquote> +<div><p>Reduces the internal representations of the coefficients to +their lowest terms.</p> +</div></blockquote> +</section> +<section id="id20"> +<span id="id21"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolReduceCoeffs*{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolReduceCoeffs*{<polname>}</span></code></p> +<blockquote> +<div><p>Reduces the internal representations of the coefficients to their +lowest terms, but ignoring a possible separated “power of ten part”.</p> +<p>For example, <a class="reference external" href="https://www.ctan.org/pkg/xint">xintfrac</a> stores an <code class="docutils literal notranslate"><span class="pre">30e2/50</span></code> input as <code class="docutils literal notranslate"><span class="pre">30/50</span></code> with +a separate <code class="docutils literal notranslate"><span class="pre">10^2</span></code> part. This will thus get replaced by <code class="docutils literal notranslate"><span class="pre">3e^2/5</span></code> +(or rather whatever <a class="reference external" href="https://www.ctan.org/pkg/xint">xintfrac</a> uses for internal representation), and +not by <code class="docutils literal notranslate"><span class="pre">60</span></code> as would result from complete reduction.</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"><span class="std std-ref">\PolReduceCoeffs{<polname>}</span></a>: as the numerators and denominators +remain generally smaller.</p> +</div></blockquote> +</section> +<section id="polmakemonic"> +<span id="id22"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolMakeMonic{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolMakeMonic{<polname>}</span></code></p> +<blockquote> +<div><p>Divides by the leading coefficient. It is recommended to execute +<a class="reference internal" href="#id20"><span class="std std-ref">\PolReduceCoeffs*{<polname>}</span></a> immediately afterwards. This is not +done automatically, in case the original polynomial had integer +coefficients and the user wants to keep the leading one as common +denominator for typesetting purposes.</p> +</div></blockquote> +</section> +<section id="polmakeprimitive"> +<span id="id23"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolMakePrimitive{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolMakePrimitive{<polname>}</span></code></p> +<blockquote> +<div><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> +</div></blockquote> +</section> +<section id="poldiff"> +<span id="id24"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolDiff{}{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolDiff{<polname_1>}{<polname_2>}</span></code></p> +<blockquote> +<div><p>This sets <code class="docutils literal notranslate"><span class="pre">polname_2</span></code> to the first derivative of <code class="docutils literal notranslate"><span class="pre">polname_1</span></code>. It +is allowed to issue <code class="docutils literal notranslate"><span class="pre">\PolDiff{f}{f}</span></code>, effectively replacing <code class="docutils literal notranslate"><span class="pre">f</span></code> +by <code class="docutils literal notranslate"><span class="pre">f'</span></code>.</p> +<p>Coefficients of the result <code class="docutils literal notranslate"><span class="pre">polname_2</span></code> are irreducible fractions +(see <a class="reference internal" href="#technicalities">Technicalities</a> for the whole story.)</p> +</div></blockquote> +</section> +<section id="id25"> +<span id="id26"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolDiff[]{}{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolDiff[N]{<polname_1>}{<polname_2>}</span></code></p> +<blockquote> +<div><p>This sets <code class="docutils literal notranslate"><span class="pre">polname_2</span></code> to the <code class="docutils literal notranslate"><span class="pre">N</span></code>-th derivative of <code class="docutils literal notranslate"><span class="pre">polname_1</span></code>. +Identical arguments is allowed. With <code class="docutils literal notranslate"><span class="pre">N=0</span></code>, same effect as +<code class="docutils literal notranslate"><span class="pre">\PolLet{<polname_2>}={<polname_1>}</span></code>. With negative <code class="docutils literal notranslate"><span class="pre">N</span></code>, switches to +using <code class="docutils literal notranslate"><span class="pre">\PolAntiDiff</span></code>.</p> +</div></blockquote> +</section> +<section id="polantidiff"> +<span id="id27"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolAntiDiff{}{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolAntiDiff{<polname_1>}{<polname_2>}</span></code></p> +<blockquote> +<div><p>This sets <code class="docutils literal notranslate"><span class="pre">polname_2</span></code> to the primitive of <code class="docutils literal notranslate"><span class="pre">polname_1</span></code> vanishing +at zero.</p> +<p>Coefficients of the result <code class="docutils literal notranslate"><span class="pre">polname_2</span></code> are irreducible fractions +(see <a class="reference internal" href="#technicalities">Technicalities</a> for the whole story.)</p> +</div></blockquote> +</section> +<section id="id28"> +<span id="id29"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolAntiDiff[]{}{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolAntiDiff[N]{<polname_1>}{<polname_2>}</span></code></p> +<blockquote> +<div><p>This sets <code class="docutils literal notranslate"><span class="pre">polname_2</span></code> to the result of <code class="docutils literal notranslate"><span class="pre">N</span></code> successive integrations on +<code class="docutils literal notranslate"><span class="pre">polname_1</span></code>. With negative <code class="docutils literal notranslate"><span class="pre">N</span></code>, it switches to using <code class="docutils literal notranslate"><span class="pre">\PolDiff</span></code>.</p> +</div></blockquote> +</section> +<section id="poldivide"> +<span id="id30"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolDivide{}{}{}{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolDivide{<polname_1>}{<polname_2>}{<polname_Q>}{<polname_R>}</span></code></p> +<blockquote> +<div><p>This sets <code class="docutils literal notranslate"><span class="pre">polname_Q</span></code> and <code class="docutils literal notranslate"><span class="pre">polname_R</span></code> to be the quotient and +remainder in the Euclidean division of <code class="docutils literal notranslate"><span class="pre">polname_1</span></code> by +<code class="docutils literal notranslate"><span class="pre">polname_2</span></code>.</p> +</div></blockquote> +</section> +<section id="polquo"> +<span id="id31"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolQuo{}{}{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolQuo{<polname_1>}{<polname_2>}{<polname_Q>}</span></code></p> +<blockquote> +<div><p>This sets <code class="docutils literal notranslate"><span class="pre">polname_Q</span></code> to be the quotient in the Euclidean division +of <code class="docutils literal notranslate"><span class="pre">polname_1</span></code> by <code class="docutils literal notranslate"><span class="pre">polname_2</span></code>.</p> +</div></blockquote> +</section> +<section id="polrem"> +<span id="id32"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolRem{}{}{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolRem{<polname_1>}{<polname_2>}{<polname_R>}</span></code></p> +<blockquote> +<div><p>This sets <code class="docutils literal notranslate"><span class="pre">polname_R</span></code> to be the remainder in the Euclidean division +of <code class="docutils literal notranslate"><span class="pre">polname_1</span></code> by <code class="docutils literal notranslate"><span class="pre">polname_2</span></code>.</p> +</div></blockquote> +</section> +<section id="polgcd"> +<span id="id33"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolGCD{}{}{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolGCD{<polname_1>}{<polname_2>}{<polname_GCD>}</span></code></p> +<blockquote> +<div><p>This sets <code class="docutils literal notranslate"><span class="pre">polname_GCD</span></code> to be the (monic) GCD of <code class="docutils literal notranslate"><span class="pre">polname_1</span></code> +and <code class="docutils literal notranslate"><span class="pre">polname_2</span></code>. It is a unitary polynomial except if both +<code class="docutils literal notranslate"><span class="pre">polname_1</span></code> and <code class="docutils literal notranslate"><span class="pre">polname_2</span></code> vanish, then <code class="docutils literal notranslate"><span class="pre">polname_GCD</span></code> is the +zero polynomial.</p> +</div></blockquote> +</section> +<section id="root-localization-routines-via-the-sturm-theorem"> +<h3>Root localization routines via the <a class="reference external" href="https://en.wikipedia.org/wiki/Sturm%27s_theorem">Sturm Theorem</a></h3> +<p>As <a class="reference internal" href="#poltosturm"><span class="std std-ref">\PolToSturm{<polname>}{<sturmname>}</span></a> and +<a class="reference internal" href="#polsturmisolatezeros"><span class="std std-ref">\PolSturmIsolateZeros{<sturmname>}</span></a> and variants declare +additional polynomial or scalar variables with names based on <code class="docutils literal notranslate"><span class="pre"><sturmname></span></code> as +prefix, it is advisable to keep the <code class="docutils literal notranslate"><span class="pre"><sturmname></span></code> namespace separate from +the one applying to <code class="docutils literal notranslate"><span class="pre">\xintexpr</span></code> variables generally, or to polynomials.</p> +<section id="poltosturm"> +<span id="id34"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolToSturm{}{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolToSturm{<polname>}{<sturmname>}</span></code></p> +<blockquote> +<div><p>With <code class="docutils literal notranslate"><span class="pre"><polname></span></code> being for example <code class="docutils literal notranslate"><span class="pre">P</span></code>, and <code class="docutils literal notranslate"><span class="pre"><sturmname></span></code> being +for example <code class="docutils literal notranslate"><span class="pre">S</span></code>, the macro starts by computing the derivative +<code class="docutils literal notranslate"><span class="pre">P'</span></code>, then computes the opposite of the remainder in the euclidean +division of <code class="docutils literal notranslate"><span class="pre">P</span></code> by <code class="docutils literal notranslate"><span class="pre">P'</span></code>, then the opposite of the remainder in +the euclidean division of <code class="docutils literal notranslate"><span class="pre">P'</span></code> by the first obtained polynomial, +etc… Up to signs following the <code class="docutils literal notranslate"><span class="pre">--++--++...</span></code> pattern, these are +the same remainders as in the Euclide algorithm applied to the +computation of the GCD of <code class="docutils literal notranslate"><span class="pre">P</span></code> and <code class="docutils literal notranslate"><span class="pre">P'</span></code>.</p> +<p>The precise process differs from the above description: the +algorithm first sets <code class="docutils literal notranslate"><span class="pre">S_0_</span></code> to be the <em>primitive part</em> of <code class="docutils literal notranslate"><span class="pre">P</span></code> +and <code class="docutils literal notranslate"><span class="pre">S_1_</span></code> to be the <em>primitive part</em> of <code class="docutils literal notranslate"><span class="pre">P'</span></code> (see +<a class="reference internal" href="#policontent"><span class="std std-ref">\PolIContent{<polname>}</span></a>), then at each step +the remainder is made primitive and stored for internal reference as +<code class="docutils literal notranslate"><span class="pre">S_k_</span></code>, so only integer-coefficients polynomials are manipulated.</p> +<div class="admonition warning"> +<p class="admonition-title">Warning</p> +<p>This exact procedure will perhaps in future be replaced by a +<em>sub-resultant algorithm</em>, which may bring some speed gain in +obtaining a pseudo-Sturm sequence, but some experimenting is +needed, in the context of realistically realizable computations +by the package; primitive polynomials although a bit costly +have the smallest coefficients hence are the best for the kind of +computations done for root localization, after having computed a +Sturm sequence.</p> +</div> +<p>The last non-zero primitivized remainder <code class="docutils literal notranslate"><span class="pre">S_N_</span></code> is, up to sign, +the primitive part of the GCD of <code class="docutils literal notranslate"><span class="pre">P</span></code> and <code class="docutils literal notranslate"><span class="pre">P'</span></code>. Its roots (real +and complex) are the multiple roots of the original <code class="docutils literal notranslate"><span class="pre">P</span></code>. The +original <code class="docutils literal notranslate"><span class="pre">P</span></code> was “square-free” (i.e. did not have multiple real +or complex roots) if and only if <code class="docutils literal notranslate"><span class="pre">S_N_</span></code> is a constant, which is +then <code class="docutils literal notranslate"><span class="pre">+1</span></code> or <code class="docutils literal notranslate"><span class="pre">-1</span></code> (its value before primitivization is lost).</p> +<p>The macro then divides each <code class="docutils literal notranslate"><span class="pre">S_k_</span></code> by <code class="docutils literal notranslate"><span class="pre">S_N_</span></code> and declares the +quotients <code class="docutils literal notranslate"><span class="pre">S_k</span></code> as user polynomials for future use. By Gauss +theorem about the contents of integer-coefficients polynomials, +these <code class="docutils literal notranslate"><span class="pre">S_k</span></code> also are primitive integer-coefficients polynomials.</p> +<p>This step will be referred to as <em>normalization</em>, and in this +documentation the obtained polynomials are said to constitute the +“Sturm chain” (or “Sturm sequence”), i.e. by convention the “Sturm +chain polynomials” are square-free and primitive. The possibly +non-square-free ones are referred to as <em>non-normalized</em>.</p> +<p>As an exception to the rule, if the original <code class="docutils literal notranslate"><span class="pre">P</span></code> was “square-free” +(i.e. did not have multiple real or complex roots) then +normalization is skipped (in that case <code class="docutils literal notranslate"><span class="pre">S_N_</span></code> is either <code class="docutils literal notranslate"><span class="pre">+1</span></code> or +<code class="docutils literal notranslate"><span class="pre">-1</span></code>), so <code class="docutils literal notranslate"><span class="pre">S_0_</span></code> is exactly the primitive part of starting +polynomial <code class="docutils literal notranslate"><span class="pre">P</span></code>, in the “square-free” case.</p> +<p>The next logical step is to execute <a class="reference internal" href="#polsturmisolatezeros">\PolSturmIsolateZeros{S}</a> or one of its variants. Be careful not to +use the names <code class="docutils literal notranslate"><span class="pre">sturmname_0</span></code>, <code class="docutils literal notranslate"><span class="pre">sturmname_1</span></code>, etc… for defining +other polynomials after having done +<code class="docutils literal notranslate"><span class="pre">\PolToSturm{<polname>}{<sturmname>}</span></code> and before executing +<code class="docutils literal notranslate"><span class="pre">\PolSturmIsolateZeros{<sturmname>}</span></code> or its variants else the +latter will behave erroneously.</p> +<div class="admonition note"> +<p class="admonition-title">Note</p> +<p>The declaration of the <code class="docutils literal notranslate"><span class="pre">S_k</span></code>‘s will overwrite +with no warning previously declared polynomials with identical +names <code class="docutils literal notranslate"><span class="pre">S_k</span></code>. This is original reason why the macro expects two +names: <code class="docutils literal notranslate"><span class="pre"><polname></span></code> and <code class="docutils literal notranslate"><span class="pre"><sturmname></span></code>.</p> +<p>It is allowed to use the polynomial name <code class="docutils literal notranslate"><span class="pre">P</span></code> as Sturm chain +name <code class="docutils literal notranslate"><span class="pre">S</span></code>: <code class="docutils literal notranslate"><span class="pre">\PolToSturm{f}(f}</span></code>, but of course fusing the +namespaces is slightly dangerous. And, also <a class="reference internal" href="#polsturmisolatezeros">\PolSturmIsolateZeros</a> creates variables sharing +the <code class="docutils literal notranslate"><span class="pre"><sturmname></span></code> prefix, which must be taken into account to +avoid name clashes.</p> +</div> +<div class="admonition warning"> +<p class="admonition-title">Warning</p> +<p>The reason why the <code class="docutils literal notranslate"><span class="pre">S_k</span></code>‘s are declared as polynomials is +that the associated polynomial functions are needed to compute +the sign changes in the Sturm sequence evaluated at a given +location, as this is the basis mechanism of <a class="reference internal" href="#polsturmisolatezeros">\PolSturmIsolateZeros</a> (on the basis of the <a class="reference external" href="https://en.wikipedia.org/wiki/Sturm%27s_theorem">Sturm theorem</a>).</p> +<p>It is possible that in future the package will only internally +construct such polynomial functions and only the starred variant +will make the normalized (i.e. square-free) Sturm sequence public.</p> +</div> +<p>The integer <code class="docutils literal notranslate"><span class="pre">N</span></code> giving the length of the Sturm chain <code class="docutils literal notranslate"><span class="pre">S_0</span></code>, +<code class="docutils literal notranslate"><span class="pre">S_1</span></code>, …, <code class="docutils literal notranslate"><span class="pre">S_N</span></code> is available as +<a class="reference internal" href="#polsturmchainlength"><span class="std std-ref">\PolSturmChainLength{<sturmname>}</span></a>. If all roots of original <code class="docutils literal notranslate"><span class="pre">P</span></code> +are real, then <code class="docutils literal notranslate"><span class="pre">N</span></code> is both the number of distinct real roots and +the degree of <code class="docutils literal notranslate"><span class="pre">S_0</span></code>. In the case of existence of complex roots, +the number of distinct real roots is at most <code class="docutils literal notranslate"><span class="pre">N</span></code> and <code class="docutils literal notranslate"><span class="pre">N</span></code> is at +most the degree of <code class="docutils literal notranslate"><span class="pre">S_0</span></code>.</p> +</div></blockquote> +</section> +<section id="id35"> +<span id="id36"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolToSturm*{}{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolToSturm*{<polname>}{<sturmname>}</span></code></p> +<blockquote> +<div><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> (but still +made primitive) Sturm chain +polynomials <code class="docutils literal notranslate"><span class="pre">sturmname_k_</span></code>, <code class="docutils literal notranslate"><span class="pre">k=0,1,</span> <span class="pre">...,</span> <span class="pre">N</span></code>, with +<code class="docutils literal notranslate"><span class="pre">N</span></code> being <a class="reference internal" href="#polsturmchainlength"><span class="std std-ref">\PolSturmChainLength{<sturmname>}</span></a>.</p> +</div></blockquote> +</section> +<section id="polsturmisolatezeros"> +<span id="id37"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolSturmIsolateZeros{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolSturmIsolateZeros{<sturmname>}</span></code></p> +<blockquote> +<div><p>The macro locates, using the <a class="reference external" href="https://en.wikipedia.org/wiki/Sturm%27s_theorem">Sturm Theorem</a>, as many disjoint +intervals as there are distinct 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"><span class="std std-ref">\PolToSturm{<polname>}{<sturmname>}</span></a>.</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="https://www.ctan.org/pkg/xintexpr">xintexpr</a> variables, see below):</p> +<ul class="simple"> +<li><p>singleton <code class="docutils literal notranslate"><span class="pre">{a}</span></code>: then <code class="docutils literal notranslate"><span class="pre">a</span></code> is a root, (necessarily a decimal +number, but not all such decimal numbers are exactly identified yet).</p></li> +<li><p>open intervals <code class="docutils literal notranslate"><span class="pre">(a,b)</span></code>: then there is exactly one root <code class="docutils literal notranslate"><span class="pre">z</span></code> +such that <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre"><</span> <span class="pre">z</span> <span class="pre"><</span> <span class="pre">b</span></code>, 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 +<code class="docutils literal notranslate"><span class="pre">(-10^E,</span> <span class="pre">0)</span></code> and <code class="docutils literal notranslate"><span class="pre">(0,</span> <span class="pre">10^E)</span></code> with <code class="docutils literal notranslate"><span class="pre">E</span></code> 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 <code class="docutils literal notranslate"><span class="pre">(a/10^f,</span> <span class="pre">(a+1)/10^f)</span></code> with <code class="docutils literal notranslate"><span class="pre">a</span></code> an integer, which is +neither <code class="docutils literal notranslate"><span class="pre">0</span></code> nor <code class="docutils literal notranslate"><span class="pre">-1</span></code>. Hence either <code class="docutils literal notranslate"><span class="pre">a</span></code> and <code class="docutils literal notranslate"><span class="pre">a+1</span></code> 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"><span class="std std-ref">\PolRefineInterval*{<sturmname>}{<index>}</span></a> which addresses +this issue.</p> +</div> +<p>Let us suppose <code class="docutils literal notranslate"><span class="pre"><sturmname></span></code> is <code class="docutils literal notranslate"><span class="pre">S</span></code>.</p> +<p>The interval boundaries (and exactly found roots) are made available +for future computations in <code class="docutils literal notranslate"><span class="pre">\xintexpr/xinteval</span></code> or <code class="docutils literal notranslate"><span class="pre">\poldef</span></code> as +variables <code class="docutils literal notranslate"><span class="pre">SL_1</span></code>, <code class="docutils literal notranslate"><span class="pre">SL_2</span></code>, etc…, for the left end-points and +<code class="docutils literal notranslate"><span class="pre">SR_1</span></code>, <code class="docutils literal notranslate"><span class="pre">SR_2</span></code>, …, for the right end-points.</p> +<p>Additionally, <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> variable <code class="docutils literal notranslate"><span class="pre">SZ_1_isknown</span></code> will have value +<code class="docutils literal notranslate"><span class="pre">1</span></code> if the root in the first interval is known, and <code class="docutils literal notranslate"><span class="pre">0</span></code> +otherwise. And similarly for the other intervals.</p> +<div class="admonition important"> +<p class="admonition-title">Important</p> +<p>The variable declarations are done with no check of existence of +previously existing variables with identical names.</p> +</div> +<p>Also, macros <a class="reference internal" href="#polsturmisolatedzeroleft"><span class="std std-ref">\PolSturmIsolatedZeroLeft{<sturmname>}{<index>}</span></a> and +<a class="reference internal" href="#polsturmisolatedzeroright"><span class="std std-ref">\PolSturmIsolatedZeroRight{<sturmname>}{<index>}</span></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"><span class="std std-ref">\PolSturmIfZeroExactlyKnown{<sturmname>}{<index>}{T}{F}</span></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, so as to be able for example to +print out bounds of real roots with as many digits as is +significant, even if the digits are zeros.</p> +</div> +<p>The start of the decimal expansion of the <code class="docutils literal notranslate"><span class="pre"><index></span></code>-th root is given by +<a class="reference internal" href="#polsturmisolatedzeroleft">\PolSturmIsolatedZeroLeft{<sturmname>}{<index>}</a> if the root is positive, and by +<a class="reference internal" href="#polsturmisolatedzeroright">PolSturmIsolatedZeroRight{<sturmname>}{<index>}</a> if the root is neagtive. 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"><span class="std std-ref">\PolSturmNbOfIsolatedZeros{<sturmname>}</span></a>.</p> +<p>Furthermore +<a class="reference internal" href="#polsturmnbofrootsoflessthanorequalto"><span class="std std-ref">\PolSturmNbOfRootsOf{<sturmname>}\LessThanOrEqualTo{<value>}</span></a> and +<a class="reference internal" href="#polsturmnbofrootsoflessthanorequaltoexpr"><span class="std std-ref">\PolSturmNbOfRootsOf{<sturmname>}\LessThanOrEqualToExpr{<num. expr.>}</span></a>. +will expandably compute respectively the number of real roots at +most equal to <code class="docutils literal notranslate"><span class="pre">value</span></code> or <code class="docutils literal notranslate"><span class="pre">expression</span></code>, and the same but with +multiplicities.</p> +<p>These variables and macros are automatically updated in case of +subsequent usage of <a class="reference internal" href="#polrefineinterval"><span class="std std-ref">\PolRefineInterval*{<sturmname>}{<index>}</span></a> or +other localization improving macros.</p> +<div class="admonition note"> +<p class="admonition-title">Note</p> +<p>The current polexpr implementation defines the <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> variables +and <a class="reference external" href="https://www.ctan.org/pkg/xint">xinttools</a> arrays as described above with global scope. On the +other hand the Sturm sequence polynomials obey the current scope.</p> +<p>This is perhaps a bit inconsistent and may change in future.</p> +</div> +<div class="admonition note"> +<p class="admonition-title">Note</p> +<p>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> +</div></blockquote> +</section> +<section id="id38"> +<span id="id39"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolSturmIsolateZeros*{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolSturmIsolateZeros*{<sturmname>}</span></code></p> +<blockquote> +<div><p>The macro does the same as <a class="reference internal" href="#polsturmisolatezeros"><span class="std std-ref">\PolSturmIsolateZeros{<sturmname>}</span></a> and +then in addition it does the extra work to determine all +multiplicities of the real roots.</p> +<p>After execution, +<a class="reference internal" href="#polsturmisolatedzeromultiplicity"><span class="std std-ref">\PolSturmIsolatedZeroMultiplicity{<sturmname>}{<index>}</span></a> expands +to the multiplicity of the root located in the <code class="docutils literal notranslate"><span class="pre">index</span></code>-th +interval (intervals are enumerated from left to right, with index +starting at <code class="docutils literal notranslate"><span class="pre">1</span></code>).</p> +<p>Furthermore, if for example the <code class="docutils literal notranslate"><span class="pre"><sturmname></span></code> is <code class="docutils literal notranslate"><span class="pre">S</span></code>, <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> +variables <code class="docutils literal notranslate"><span class="pre">SM_1</span></code>, <code class="docutils literal notranslate"><span class="pre">SM_2</span></code>… hold the multiplicities thus +computed.</p> +<div class="admonition note"> +<p class="admonition-title">Note</p> +<p>Somewhat counter-intuitively, it is not necessary to have +executed the <a class="reference internal" href="#id35"><span class="std std-ref">\PolToSturm*</span></a> +starred variant: during its +execution, <a class="reference internal" href="#poltosturm"><span class="std std-ref">\PolToSturm</span></a>, +even though it does not declare the +non-square-free Sturm chain polynomials as user-level genuine +polynomials, stores their data in private macros.</p> +</div> +<p>See <code class="docutils literal notranslate"><span class="pre">The</span> <span class="pre">degree</span> <span class="pre">nine</span> <span class="pre">polynomial</span> <span class="pre">with</span> <span class="pre">0.99,</span> <span class="pre">0.999,</span> <span class="pre">0.9999</span> <span class="pre">as</span> <span class="pre">triple</span> +<span class="pre">roots</span></code> example in <code class="docutils literal notranslate"><span class="pre">polexpr-examples.pdf</span></code>.</p> +</div></blockquote> +<section id="polsturmisolatezerosandgetmultiplicities"> +<span id="id40"></span><h5><code class="docutils literal notranslate"><span class="pre">\PolSturmIsolateZerosAndGetMultiplicities{}</span></code></h5> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolSturmIsolateZerosAndGetMultiplicities{<sturmname>}</span></code></p> +<blockquote> +<div><p>This is another name for <a class="reference internal" href="#id38"><span class="std std-ref">\PolSturmIsolateZeros*{<sturmname>}</span></a>.</p> +</div></blockquote> +</section> +</section> +<section id="id41"> +<span id="id42"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolSturmIsolateZeros**{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolSturmIsolateZeros**{<sturmname>}</span></code></p> +<blockquote> +<div><p>The macro does the same as <a class="reference internal" href="#id38"><span class="std std-ref">\PolSturmIsolateZeros*{<sturmname>}</span></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 “known” if and only if +it is rational.</p> +</div> +<p>Furthermore, primitive polynomial <code class="docutils literal notranslate"><span class="pre">sturmname_sqf_norr</span></code> is created +to match the (square-free) <code class="docutils literal notranslate"><span class="pre">sturmname_0</span></code> from which all rational +roots have been removed. 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"><span class="std std-ref">\PolSturmNbOfRationalRoots{<sturmname>}</span></a>).</p> +<p>And <code class="docutils literal notranslate"><span class="pre">sturmname_norr</span></code> is <code class="docutils literal notranslate"><span class="pre">sturmname_0_</span></code> from which all rational +roots have been removed, i.e. it contains the irrational roots of +the original polynomial, with the same multiplicities.</p> +<p>See <code class="docutils literal notranslate"><span class="pre">A</span> <span class="pre">degree</span> <span class="pre">five</span> <span class="pre">polynomial</span> <span class="pre">with</span> <span class="pre">three</span> <span class="pre">rational</span> +<span class="pre">roots</span></code> in <code class="docutils literal notranslate"><span class="pre">polexpr-examples.pdf</span></code>.</p> +</div></blockquote> +<section id="polsturmisolatezerosgetmultiplicitiesandrationalroots"> +<span id="id43"></span><h5><code class="docutils literal notranslate"><span class="pre">\PolSturmIsolateZerosGetMultiplicitiesAndRationalRoots</span></code></h5> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolSturmIsolateZerosGetMultiplicitiesAndRationalRoots</span></code></p> +<blockquote> +<div><p>This is another name for <a class="reference internal" href="#id41"><span class="std std-ref">\PolSturmIsolateZeros**{<sturmname>}</span></a>.</p> +</div></blockquote> +</section> +</section> +<section id="polsturmisolatezerosandfindrationalroots"> +<span id="id44"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolSturmIsolateZerosAndFindRationalRoots{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolSturmIsolateZerosAndFindRationalRoots{<sturmname>}</span></code></p> +<blockquote> +<div><p>This works exactly like <a class="reference internal" href="#id41"><span class="std std-ref">\PolSturmIsolateZeros**{<sturmname>}</span></a> +(inclusive of declaring the polynomials <code class="docutils literal notranslate"><span class="pre">sturmname_sqf_norr</span></code> and +<code class="docutils literal notranslate"><span class="pre">sturmname_norr</span></code> 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="https://www.ctan.org/pkg/xintexpr">xintexpr</a> variables +<code class="docutils literal notranslate"><span class="pre">sturmnameM_1</span></code>, <code class="docutils literal notranslate"><span class="pre">sturmnameM_2</span></code>, … holding the +multiplicities and it leaves the multiplicity array (whose accessor +is <a class="reference internal" href="#polsturmisolatedzeromultiplicity"><span class="std std-ref">\PolSturmIsolatedZeroMultiplicity{<sturmname>}{<index>}</span></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="#id61">\PolPrintIntervals*</a> will be +erroneous regarding the multiplicities of 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> +</div></blockquote> +</section> +<section id="polrefineinterval"> +<span id="id45"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolRefineInterval*{}{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolRefineInterval*{<sturmname>}{<index>}</span></code></p> +<blockquote> +<div><p>The <code class="docutils literal notranslate"><span class="pre">index</span></code>-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. As a consequence, the <code class="docutils literal notranslate"><span class="pre">k</span></code>th root is then +strictly separated from the other roots.</p> +</div></blockquote> +</section> +<section id="id46"> +<span id="id47"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolRefineInterval[]{}{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolRefineInterval[N]{<sturmname>}{<index>}</span></code></p> +<blockquote> +<div><p>The <code class="docutils literal notranslate"><span class="pre">index</span></code>-th interval (starting count at one) is further +subdivided once, reducing its length by a factor of 10. This is done +<code class="docutils literal notranslate"><span class="pre">N</span></code> times if the optional argument <code class="docutils literal notranslate"><span class="pre">[N]</span></code> is present.</p> +</div></blockquote> +</section> +<section id="polensureintervallength"> +<span id="id48"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolEnsureIntervalLength{}{}{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolEnsureIntervalLength{<sturmname>}{<index>}{<exponent>}</span></code></p> +<blockquote> +<div><p>The <code class="docutils literal notranslate"><span class="pre">index</span></code>-th interval is subdivided until its length becomes at +most <code class="docutils literal notranslate"><span class="pre">10^E</span></code>. This means (for <code class="docutils literal notranslate"><span class="pre">E<0</span></code>) that the first <code class="docutils literal notranslate"><span class="pre">-E</span></code> digits +after decimal mark of the <code class="docutils literal notranslate"><span class="pre">k</span></code>th root will then be known exactly.</p> +</div></blockquote> +</section> +<section id="polensureintervallengths"> +<span id="id49"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolEnsureIntervalLengths{}{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolEnsureIntervalLengths{<sturmname>}{<exponent>}</span></code></p> +<blockquote> +<div><p>The intervals as obtained from <code class="docutils literal notranslate"><span class="pre">\PolSturmIsolateZeros</span></code> are (if +necessary) subdivided further by (base 10) dichotomy in order for +each of them to have length at most <code class="docutils literal notranslate"><span class="pre">10^E</span></code>.</p> +<p>This means that decimal expansions of all roots will be known with +<code class="docutils literal notranslate"><span class="pre">-E</span></code> digits (for <code class="docutils literal notranslate"><span class="pre">E<0</span></code>) after decimal mark.</p> +</div></blockquote> +</section> +<section id="polsettosturmchainsignchangesat"> +<span id="id50"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolSetToSturmChainSignChangesAt{}{}{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolSetToSturmChainSignChangesAt{\foo}{<sturmname>}{<value>}</span></code></p> +<blockquote> +<div><p>Sets macro <code class="docutils literal notranslate"><span class="pre">\foo</span></code> to store the number of sign changes in the +already computed normalized Sturm chain with name prefix +<code class="docutils literal notranslate"><span class="pre"><sturmname></span></code>, at location <code class="docutils literal notranslate"><span class="pre"><value></span></code> (which must be in format as +acceptable by the <a class="reference external" href="https://www.ctan.org/pkg/xint">xintfrac</a> macros.)</p> +<p>The definition is made with global scope. For local scope, use +<code class="docutils literal notranslate"><span class="pre">[\empty]</span></code> as extra optional argument.</p> +<p>One can use this immediately after creation of the Sturm chain.</p> +</div></blockquote> +</section> +<section id="polsettonbofzeroswithin"> +<span id="id51"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolSetToNbOfZerosWithin{}{}{}{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolSetToNbOfZerosWithin{\foo}{<sturmname>}{<value_left>}{<value_right>}</span></code></p> +<blockquote> +<div><p>Sets, assuming the normalized Sturm chain has been already computed, +macro <code class="docutils literal notranslate"><span class="pre">\foo</span></code> to store the number of roots of <code class="docutils literal notranslate"><span class="pre">sturmname_0</span></code> in +the interval <code class="docutils literal notranslate"><span class="pre">(value_left,</span> <span class="pre">value_right]</span></code>. The macro first +re-orders end-points if necessary for <code class="docutils literal notranslate"><span class="pre">value_left</span> <span class="pre"><=</span> <span class="pre">value_right</span></code> +to hold.</p> +<p>In accordance to <a class="reference external" href="https://en.wikipedia.org/wiki/Sturm%27s_theorem">Sturm Theorem</a> this is computed as the difference +between the number of sign changes of the Sturm chain at <code class="docutils literal notranslate"><span class="pre">value_right</span></code> +and the one at <code class="docutils literal notranslate"><span class="pre">value_left</span></code>.</p> +<p>The definition is made with global scope. For local scope, use +<code class="docutils literal notranslate"><span class="pre">[\empty]</span></code> as extra optional argument.</p> +<p>One can use this immediately after creation of a Sturm chain.</p> +<p>See also the expandable +<a class="reference internal" href="#polsturmnbofrootsoflessthanorequalto"><span class="std std-ref">\PolSturmNbOfRootsOf{<sturmname>}\LessThanOrEqualTo{value}</span></a>, +which however requires prior execution of <a class="reference internal" href="#polsturmisolatezeros">\PolSturmIsolateZeros</a>.</p> +<p>See also the expandable +<a class="reference internal" href="#polsturmnbwithmultofrootsoflessthanorequalto"><span class="std std-ref">\PolSturmNbWithMultOfRootsOf{<sturmname>}\LessThanOrEqualTo{value}</span></a> +which requires prior execution of +<a class="reference internal" href="#id38">\PolSturmIsolateZeros*</a>.</p> +</div></blockquote> +</section> +</section> +<section id="displaying-the-found-roots-polprintintervals-varname"> +<span id="polprintintervals"></span><h3>Displaying the found roots: <code class="docutils literal notranslate"><span class="pre">\PolPrintIntervals[<varname>]{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolPrintIntervals[<varname>]{<sturmname>}</span></code></p> +<blockquote> +<div><p>This is a convenience macro which prints the bounds for the roots +<code class="docutils literal notranslate"><span class="pre">Z_1</span></code>, <code class="docutils literal notranslate"><span class="pre">Z_2</span></code>, … (the optional argument <code class="docutils literal notranslate"><span class="pre">varname</span></code> allows to +specify a replacement for the default <code class="docutils literal notranslate"><span class="pre">Z</span></code>). This will be done (by +default) in a +math mode <code class="docutils literal notranslate"><span class="pre">array</span></code>, one interval per row, and pattern <code class="docutils literal notranslate"><span class="pre">rcccl</span></code>, +where the second and fourth column hold the <code class="docutils literal notranslate"><span class="pre"><</span></code> 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 +<code class="docutils literal notranslate"><span class="pre">\begin{array}{rcccl}</span></code> which appears in the documentation here +is actually replaced with quasi-equivalent direct use of TeX +primitives.</p> +</div> +<p>The next macros which govern its output.</p> +</div></blockquote> +<section id="polprintintervalsnorealroots"> +<span id="id52"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervalsNoRealRoots</span></code></h4> +<blockquote> +<div><p>Executed in place of an <code class="docutils literal notranslate"><span class="pre">array</span></code> environment, when there are no +real roots. Default definition:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\newcommand\PolPrintIntervalsNoRealRoots</span><span class="nb">{}</span> +</pre></div> +</div> +</div></blockquote> +</section> +<section id="polprintintervalsbeginenv"> +<span id="id53"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervalsBeginEnv</span></code></h4> +<blockquote> +<div><p>Default definition (given here for LaTeX, Plain has a variant):</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\newcommand\PolPrintIntervalsBeginEnv</span><span class="nb">{</span><span class="sb">\[</span><span class="nv">\begin</span><span class="nb">{array}{rcccl}}</span> +</pre></div> +</div> +<p>A simpler <code class="docutils literal notranslate"><span class="pre">center</span></code> environment provides a straightforward way to +obtain a display allowing pagebreaks. Of course redefinitions must +at any rate be kept in sync with <a class="reference internal" href="#id56">\PolPrintIntervalsKnownRoot</a> and +<a class="reference internal" href="#id57">\PolPrintIntervalsUnknownRoot</a>.</p> +<p>Prior to <code class="docutils literal notranslate"><span class="pre">0.8.6</span></code> it was not possible to use here for example +<code class="docutils literal notranslate"><span class="pre">\begin{align}</span></code> due to the latter executing twice in contents.</p> +</div></blockquote> +</section> +<section id="polprintintervalsendenv"> +<span id="id54"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervalsEndEnv</span></code></h4> +<blockquote> +<div><p>Default definition:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\newcommand\PolPrintIntervalsEndEnv</span><span class="nb">{</span><span class="k">\end</span><span class="nb">{</span>array<span class="nb">}</span><span class="k">\]</span><span class="nb">}</span> +</pre></div> +</div> +</div></blockquote> +</section> +<section id="polprintintervalsrowseparator"> +<span id="id55"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervalsRowSeparator</span></code></h4> +<blockquote> +<div><p>Expands by default to <code class="docutils literal notranslate"><span class="pre">\\</span></code> with LaTeX and to <code class="docutils literal notranslate"><span class="pre">\cr</span></code> with Plain</p> +<p>Added at <code class="docutils literal notranslate"><span class="pre">0.8.6</span></code>.</p> +</div></blockquote> +</section> +<section id="polprintintervalsknownroot"> +<span id="id56"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervalsKnownRoot</span></code></h4> +<blockquote> +<div><p>Default definition:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\newcommand\PolPrintIntervalsKnownRoot</span><span class="nb">{</span><span class="c">%</span> + <span class="nb">&&</span><span class="k">\PolPrintIntervalsTheVar</span><span class="nb">_{</span><span class="k">\PolPrintIntervalsTheIndex</span><span class="nb">}</span><span class="c">%</span> + <span class="nb">&</span>=<span class="nb">&</span><span class="k">\PolPrintIntervalsPrintExactZero</span> +<span class="nb">}</span> +</pre></div> +</div> +</div></blockquote> +</section> +<section id="polprintintervalsunknownroot"> +<span id="id57"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervalsUnknownRoot</span></code></h4> +<blockquote> +<div><p>Default definition:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\newcommand\PolPrintIntervalsUnknownRoot</span><span class="nb">{</span><span class="c">%</span> + <span class="k">\PolPrintIntervalsPrintLeftEndPoint</span><span class="nb">&</span><<span class="nb">&</span><span class="c">%</span> + <span class="k">\PolPrintIntervalsTheVar</span><span class="nb">_{</span><span class="k">\PolPrintIntervalsTheIndex</span><span class="nb">}&</span><<span class="nb">&</span><span class="c">%</span> + <span class="k">\PolPrintIntervalsPrintRightEndPoint</span> +<span class="nb">}</span> +</pre></div> +</div> +</div></blockquote> +</section> +<section id="polprintintervalsprintexactzero"> +<span id="id58"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervalsPrintExactZero</span></code></h4> +<blockquote> +<div><p>Default definition:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\newcommand\PolPrintIntervalsPrintExactZero</span><span class="nb">{</span><span class="k">\PolPrintIntervalsTheLeftEndPoint</span><span class="nb">}</span> +</pre></div> +</div> +</div></blockquote> +</section> +<section id="polprintintervalsprintleftendpoint"> +<span id="id59"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervalsPrintLeftEndPoint</span></code></h4> +<blockquote> +<div><p>Default definition:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\newcommand\PolPrintIntervalsPrintLeftEndPoint</span><span class="nb">{</span><span class="k">\PolPrintIntervalsTheLeftEndPoint</span><span class="nb">}</span> +</pre></div> +</div> +</div></blockquote> +</section> +<section id="polprintintervalsprintrightendpoint"> +<span id="id60"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervalsPrintRightEndPoint</span></code></h4> +<blockquote> +<div><p>Default definition is:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\newcommand\PolPrintIntervalsPrintRightEndPoint</span><span class="nb">{</span><span class="k">\PolPrintIntervalsTheRightEndPoint</span><span class="nb">}</span> +</pre></div> +</div> +</div></blockquote> +</section> +<section id="polprintintervals-varname"> +<span id="id61"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervals*[<varname>]{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolPrintIntervals*[<varname>]{<sturmname>}</span></code></p> +<blockquote> +<div><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="#id56">\PolPrintIntervalsKnownRoot</a>, +<a class="reference internal" href="#id58">\PolPrintIntervalsPrintExactZero</a>, +<a class="reference internal" href="#id57">\PolPrintIntervalsUnknownRoot</a> it uses its own +<code class="docutils literal notranslate"><span class="pre">\POL@@PrintIntervals...</span></code> macros. We only reproduce here one +definition:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\newcommand\POL</span>@@PrintIntervalsPrintExactZero<span class="nb">{</span><span class="c">%</span> + <span class="k">\displaystyle</span> + <span class="k">\xintTeXsignedFrac</span><span class="nb">{</span><span class="k">\PolPrintIntervalsTheLeftEndPoint</span><span class="nb">}</span><span class="c">%</span> +<span class="nb">}</span><span class="c">%</span> +</pre></div> +</div> +<p>Multiplicities are printed using this auxiliary macro:</p> +</div></blockquote> +<section id="polprintintervalsprintmultiplicity"> +<span id="id62"></span><h5><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervalsPrintMultiplicity</span></code></h5> +<blockquote> +<div><p>whose default definition is:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\newcommand\PolPrintIntervalsPrintMultiplicity</span><span class="nb">{</span>(<span class="k">\mbox</span><span class="nb">{</span>mult. <span class="nb">}</span><span class="k">\PolPrintIntervalsTheMultiplicity</span>)<span class="nb">}</span> +</pre></div> +</div> +</div></blockquote> +</section> +</section> +</section> +</section> +<section id="expandable-macros"> +<h2>Expandable macros</h2> +<div class="admonition note"> +<p class="admonition-title">Note</p> +<p>At <code class="docutils literal notranslate"><span class="pre">0.8</span></code> <code class="docutils literal notranslate"><span class="pre">polexpr</span></code> is usable with Plain TeX and not only with +LaTeX. Some examples given in this section may be using LaTeX syntax +such as <code class="docutils literal notranslate"><span class="pre">\renewcommand</span></code>. Convert to TeX primitives as appropriate +if testing with a non LaTeX macro format.</p> +</div> +<p>These macros expand completely in two steps except <code class="docutils literal notranslate"><span class="pre">\PolToExpr</span></code> and +<code class="docutils literal notranslate"><span class="pre">\PolToFloatExpr</span></code> which need a <code class="docutils literal notranslate"><span class="pre">\write</span></code>, <code class="docutils literal notranslate"><span class="pre">\edef</span></code> or a +<code class="docutils literal notranslate"><span class="pre">\csname...\endcsname</span></code> context.</p> +<section id="poltoexpr"> +<span id="id63"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolToExpr{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolToExpr{<pol.</span> <span class="pre">expr.>}</span></code></p> +<blockquote> +<div><p>Produces expandably <a class="footnote-reference brackets" href="#id65" id="id64" role="doc-noteref"><span class="fn-bracket">[</span>3<span class="fn-bracket">]</span></a> the string <code class="docutils literal notranslate"><span class="pre">coeff_N*x^N+...</span></code>, i.e. the +polynomial is using descending powers.</p> +<aside class="footnote brackets" id="id65" role="note"> +<span class="label"><span class="fn-bracket">[</span><a role="doc-backlink" href="#id64">3</a><span class="fn-bracket">]</span></span> +<p>requires exhaustive expansion, for example as triggered by +<code class="docutils literal notranslate"><span class="pre">\write</span></code> or <code class="docutils literal notranslate"><span class="pre">\edef</span></code>.</p> +</aside> +<p>Since <code class="docutils literal notranslate"><span class="pre">0.8</span></code> the input is not restricted to be a polynomial name but +is allowed to be an arbitrary expression. Then <code class="docutils literal notranslate"><span class="pre">x</span></code> is expected as +indeterminate but this can be customized via <a class="reference internal" href="#id67">\PolToExprInVar</a>.</p> +<p>The output uses the letter <code class="docutils literal notranslate"><span class="pre">x</span></code> by default, this is customizable +via <a class="reference internal" href="#poltoexprvar">\PolToExprVar</a>. The default output is compatible both with</p> +<ul class="simple"> +<li><p>the Maple’s input format,</p></li> +<li><p>and the PSTricks <code class="docutils literal notranslate"><span class="pre">\psplot[algebraic]</span></code> input format.</p></li> +</ul> +<p>Attention that it is not compatible with Python, see further +<a class="reference internal" href="#id69">\PolToExprCaret</a> in this context.</p> +<p>The following applies:</p> +<ul class="simple"> +<li><p>vanishing coefficients are skipped (issue <code class="docutils literal notranslate"><span class="pre">\poltoexpralltrue</span></code> to +override this and produce output such as <code class="docutils literal notranslate"><span class="pre">x^3+0*x^2+0*x^1+0</span></code>),</p></li> +<li><p>negative coefficients are not prefixed by a <code class="docutils literal notranslate"><span class="pre">+</span></code> sign (else, +Maple would not be happy),</p></li> +<li><p>coefficients numerically equal to <code class="docutils literal notranslate"><span class="pre">1</span></code> (or <code class="docutils literal notranslate"><span class="pre">-1</span></code>) are present +only via their sign,</p></li> +<li><p>the letter <code class="docutils literal notranslate"><span class="pre">x</span></code> is used and the degree one monomial is output as +<code class="docutils literal notranslate"><span class="pre">x</span></code>, not as <code class="docutils literal notranslate"><span class="pre">x^1</span></code>.</p></li> +<li><p>(<code class="docutils literal notranslate"><span class="pre">0.8</span></code>) the caret <code class="docutils literal notranslate"><span class="pre">^</span></code> is of catcode 12. This means that one +can for convenience typeset in regular text mode, for example +using <code class="docutils literal notranslate"><span class="pre">\texttt</span></code> (in LaTeX). But TeX will not know how to break +the expression across end-of-lines anyhow. Formerly <code class="docutils literal notranslate"><span class="pre">^</span></code> 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> +</div></blockquote> +<section id="poltoexprvar"> +<span id="id66"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolToExprVar</span></code></h4> +<blockquote> +<div><p>Defaults to <code class="docutils literal notranslate"><span class="pre">x</span></code>. The letter used in the macro output.</p> +</div></blockquote> +</section> +<section id="poltoexprinvar"> +<span id="id67"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolToExprInVar</span></code></h4> +<blockquote> +<div><p>Defaults to <code class="docutils literal notranslate"><span class="pre">x</span></code>: the letter used as the polynomial indeterminate +in the macro input.</p> +<p>Recall that declared polynomials are more efficiently used in +algebraic expressions without the <code class="docutils literal notranslate"><span class="pre">(x)</span></code>, i.e. <code class="docutils literal notranslate"><span class="pre">P*Q</span></code> is better +than <code class="docutils literal notranslate"><span class="pre">P(x)*Q(x)</span></code>. Thus the input, even if an expression, does not +have to contain any <code class="docutils literal notranslate"><span class="pre">x</span></code>.</p> +<p>(new with <code class="docutils literal notranslate"><span class="pre">0.8</span></code>)</p> +</div></blockquote> +</section> +<section id="poltoexprtimes"> +<span id="id68"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolToExprTimes</span></code></h4> +<blockquote> +<div><p>Defaults to <code class="docutils literal notranslate"><span class="pre">*</span></code>.</p> +</div></blockquote> +</section> +<section id="poltoexprcaret"> +<span id="id69"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolToExprCaret</span></code></h4> +<blockquote> +<div><p>Defaults to <code class="docutils literal notranslate"><span class="pre">^</span></code> of catcode 12. Set it to +expand to <code class="docutils literal notranslate"><span class="pre">**</span></code> for Python compatible output.</p> +<p>(new with <code class="docutils literal notranslate"><span class="pre">0.8</span></code>)</p> +</div></blockquote> +</section> +<section id="poltoexprcmd"> +<span id="id70"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolToExprCmd{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolToExprCmd{<raw_coeff>}</span></code></p> +<blockquote> +<div><p>Defaults to <code class="docutils literal notranslate"><span class="pre">\xintPRaw{\xintRawWithZeros{#1}}</span></code>.</p> +<p>This means that the coefficient value is printed-out as a fraction +<code class="docutils literal notranslate"><span class="pre">a/b</span></code>, skipping the <code class="docutils literal notranslate"><span class="pre">/b</span></code> part if <code class="docutils literal notranslate"><span class="pre">b</span></code> turns out to be one.</p> +<p>Configure it to be <code class="docutils literal notranslate"><span class="pre">\xintPRaw{\xintIrr{#1}}</span></code> if the fractions +must be in irreducible terms.</p> +<p>An alternative is <code class="docutils literal notranslate"><span class="pre">\xintDecToString{\xintREZ{#1}}</span></code> which uses +integer or decimal fixed point format such as <code class="docutils literal notranslate"><span class="pre">23.0071</span></code> if the +internal representation of the number only has a power of ten as +denominator (the effect of <code class="docutils literal notranslate"><span class="pre">\xintREZ</span></code> here is to remove trailing +decimal zeros). The behaviour of <code class="docutils literal notranslate"><span class="pre">\xintDecToString</span></code> 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 <code class="docutils literal notranslate"><span class="pre">23.007/2</span></code> or <code class="docutils literal notranslate"><span class="pre">23.007/25</span></code> can appear in output +and not their finite decimal expansion with no denominator.</p> +</div></blockquote> +</section> +<section id="poltoexproneterm"> +<span id="id71"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolToExprOneTerm{}{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolToExprOneTerm{<raw_coeff>}{<exponent>}</span></code></p> +<blockquote> +<div><p>This is the macro which from the coefficient and the exponent +produces the corresponding term in output, such as <code class="docutils literal notranslate"><span class="pre">2/3*x^7</span></code>.</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="#id69">\PolToExprCaret</a>.</p> +</div></blockquote> +</section> +<section id="poltoexpronetermstylea"> +<span id="id72"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolToExprOneTermStyleA{}{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolToExprOneTermStyleA{<raw_coeff>}{<exponent>}</span></code></p> +<blockquote> +<div><p>This holds the default package meaning of <code class="docutils literal notranslate"><span class="pre">\PolToExprOneTerm</span></code>.</p> +</div></blockquote> +</section> +<section id="poltoexpronetermstyleb"> +<span id="id73"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolToExprOneTermStyleB{}{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolToExprOneTermStyleB{<raw_coeff>}{<exponent>}</span></code></p> +<blockquote> +<div><p>This holds an alternative meaning, which puts the fractional part of +a coefficient after the monomial, i.e. like this:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span>2*x<span class="nb">^</span>11/3+3*x<span class="nb">^</span>8/7-x<span class="nb">^</span>5-x<span class="nb">^</span>4/4-x<span class="nb">^</span>3-x<span class="nb">^</span>2/2-2*x+1 +</pre></div> +</div> +<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="#id69">\PolToExprCaret</a> are obeyed.</p> +<p>To activate it use <code class="docutils literal notranslate"><span class="pre">\let\PolToExprOneTerm\PolToExprOneTermStyleB</span></code>. +To revert to the package default behaviour, issue +<code class="docutils literal notranslate"><span class="pre">\let\PolToExprOneTerm\PolToExprOneTermStyleA</span></code>.</p> +</div></blockquote> +</section> +<section id="poltoexprtermprefix"> +<span id="id74"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolToExprTermPrefix{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolToExprTermPrefix{<raw_coeff>}</span></code></p> +<blockquote> +<div><p>It receives as argument the coefficient. Its default behaviour is +to produce a <code class="docutils literal notranslate"><span class="pre">+</span></code> 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"><span class="std std-ref">\PolToExprCmd{<raw_coeff>}</span></a> which in case of a +positive coefficient does not output an explicit <code class="docutils literal notranslate"><span class="pre">+</span></code> prefix.</p> +</div></blockquote> +</section> +</section> +<section id="poltofloatexpr"> +<span id="id75"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolToFloatExpr{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolToFloatExpr{<pol.</span> <span class="pre">expr.>}</span></code></p> +<blockquote> +<div><p>Similar to <a class="reference internal" href="#poltoexpr"><span class="std std-ref">\PolToExpr{<pol. expr.>}</span></a> but using +<a class="reference internal" href="#poltofloatexprcmd"><span class="std std-ref">\PolToFloatExprCmd{<raw_coeff>}</span></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"><span class="std std-ref">\PolGenFloatVariant{<polname>}</span></a>: +<a class="reference internal" href="#poltofloatexprcmd"><span class="std std-ref">\PolToFloatExprCmd{<raw_coeff>}</span></a> operates on the <em>exact</em> +coefficients anew (and may thus produce something else than +the coefficients of the polynomial function acting +in <code class="docutils literal notranslate"><span class="pre">\xintfloateval</span></code> if the floating point precision was changed +in between).</p> +</div> +<p>Extended at <code class="docutils literal notranslate"><span class="pre">0.8</span></code> to accept general expressions as input.</p> +</div></blockquote> +<section id="poltofloatexproneterm"> +<span id="id76"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolToFloatExprOneTerm{}{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolToFloatExprOneTerm{<raw_coeff>}{<exponent>}</span></code></p> +<blockquote> +<div><p>Similar to <a class="reference internal" href="#poltoexproneterm"><span class="std std-ref">\PolToExprOneTerm{<raw_coeff>}{<exponent>}</span></a>. But does not treat +especially coefficients equal to plus or minus one.</p> +</div></blockquote> +</section> +<section id="poltofloatexprcmd"> +<span id="id77"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolToFloatExprCmd{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolToFloatExprCmd{<raw_coeff>}</span></code></p> +<blockquote> +<div><p>The one-argument macro used by <code class="docutils literal notranslate"><span class="pre">\PolToFloatExprOneTerm</span></code>. +It defaults to <code class="docutils literal notranslate"><span class="pre">\xintPFloat{#1}</span></code>, which trims trailing +zeroes.</p> +<p><em>changed at 0.8.2</em> Formerly it was using <code class="docutils literal notranslate"><span class="pre">\xintFloat</span></code>.</p> +</div></blockquote> +</section> +</section> +<section id="id78"> +<span id="id79"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolToExpr*{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolToExpr*{<pol.</span> <span class="pre">expr.>}</span></code></p> +<blockquote> +<div><p>Ascending powers: <code class="docutils literal notranslate"><span class="pre">coeff_0+coeff_1*x+coeff_2*x^2+...</span></code>.</p> +<p>Extended at <code class="docutils literal notranslate"><span class="pre">0.8</span></code> to accept general expressions as input.</p> +<p>Customizable with the same macros as for +<a class="reference internal" href="#poltoexpr"><span class="std std-ref">\PolToExpr{<pol. expr.>}</span></a>.</p> +</div></blockquote> +</section> +<section id="id80"> +<span id="id81"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolToFloatExpr*{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolToFloatExpr*{<pol.</span> <span class="pre">expr.>}</span></code></p> +<blockquote> +<div><p>Ascending powers.</p> +<p>Extended at <code class="docutils literal notranslate"><span class="pre">0.8</span></code> to accept general expressions as input.</p> +</div></blockquote> +</section> +<section id="polnthcoeff"> +<span id="id82"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolNthCoeff{}{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolNthCoeff{<polname>}{<index>}</span></code></p> +<blockquote> +<div><p>It expands to the raw <code class="docutils literal notranslate"><span class="pre">N</span></code>-th coefficient (<code class="docutils literal notranslate"><span class="pre">N=0</span></code> corresponds to +the constant coefficient). If <code class="docutils literal notranslate"><span class="pre">N</span></code> is out of range, zero (in its +default <a class="reference external" href="https://www.ctan.org/pkg/xint">xintfrac</a> format <code class="docutils literal notranslate"><span class="pre">0/1[0]</span></code>) is returned.</p> +<p>Negative indices <code class="docutils literal notranslate"><span class="pre">N=-1</span></code>, <code class="docutils literal notranslate"><span class="pre">-2</span></code>, … return the leading +coefficient, sub-leading coefficient, …, and finally <code class="docutils literal notranslate"><span class="pre">0/1[0]</span></code> +for <code class="docutils literal notranslate"><span class="pre">N<-1-degree</span></code>.</p> +</div></blockquote> +</section> +<section id="polleadingcoeff"> +<span id="id83"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolLeadingCoeff{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolLeadingCoeff{<polname>}</span></code></p> +<blockquote> +<div><p>Expands to the leading coefficient.</p> +</div></blockquote> +</section> +<section id="poldegree"> +<span id="id84"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolDegree{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolDegree{<polname>}</span></code></p> +<blockquote> +<div><p>It expands to the degree. This is <code class="docutils literal notranslate"><span class="pre">-1</span></code> if zero polynomial but this +may change in future. Should it then expand to <code class="docutils literal notranslate"><span class="pre">-\infty</span></code> ?</p> +</div></blockquote> +</section> +<section id="policontent"> +<span id="id85"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolIContent{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolIContent{<polname>}</span></code></p> +<blockquote> +<div><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> +</div></blockquote> +</section> +<section id="poltolist"> +<span id="id86"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolToList{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolToList{<polname>}</span></code></p> +<blockquote> +<div><p>Expands to <code class="docutils literal notranslate"><span class="pre">{coeff_0}{coeff_1}...{coeff_N}</span></code> with <code class="docutils literal notranslate"><span class="pre">N</span></code> = degree, and +<code class="docutils literal notranslate"><span class="pre">coeff_N</span></code> the leading coefficient +(the zero polynomial does give <code class="docutils literal notranslate"><span class="pre">{0/1[0]}</span></code> and not an +empty output.)</p> +</div></blockquote> +</section> +<section id="poltocsv"> +<span id="id87"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolToCSV{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolToCSV{<polname>}</span></code></p> +<blockquote> +<div><p>Expands to <code class="docutils literal notranslate"><span class="pre">coeff_0,</span> <span class="pre">coeff_1,</span> <span class="pre">coeff_2,</span> <span class="pre">.....,</span> <span class="pre">coeff_N</span></code>, starting +with constant term and ending with leading coefficient. Converse +to <a class="reference internal" href="#polfromcsv"><span class="std std-ref">\PolFromCSV{<polname>}{<csv>}</span></a>.</p> +</div></blockquote> +</section> +<section id="poleval-atexpr"> +<span id="polevalatexpr"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolEval{}\AtExpr{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolEval{<polname>}\AtExpr{<num.</span> <span class="pre">expr.>}</span></code></p> +<blockquote> +<div><p>Same output as +<code class="docutils literal notranslate"><span class="pre">\xinteval{polname(numerical</span> <span class="pre">expression)}</span></code>.</p> +</div></blockquote> +</section> +<section id="poleval-at"> +<span id="polevalat"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolEval{}\At{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolEval{<polname>}\At{<value>}</span></code></p> +<blockquote> +<div><p>Evaluates the polynomial at the given value which must be in (or +expand to) a format acceptable to the <a class="reference external" href="https://www.ctan.org/pkg/xint">xintfrac</a> macros.</p> +</div></blockquote> +</section> +<section id="polevalreduced-atexpr"> +<span id="polevalreducedatexpr"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolEvalReduced{}\AtExpr{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolEvalReduced{<polname>}\AtExpr{<num.</span> <span class="pre">expr.>}</span></code></p> +<blockquote> +<div><p>Same output as <code class="docutils literal notranslate"><span class="pre">\xinteval{reduce(polname(numerical</span> <span class="pre">expression))}</span></code>.</p> +</div></blockquote> +</section> +<section id="polevalreduced-at"> +<span id="polevalreducedat"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolEvalReduced{}\At{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolEvalReduced{<polname>}\At{<value>}</span></code></p> +<blockquote> +<div><p>Evaluates the polynomial at the value which must be in (or expand +to) a format acceptable to the <a class="reference external" href="https://www.ctan.org/pkg/xint">xintfrac</a> macros, and outputs an +irreducible fraction.</p> +</div></blockquote> +</section> +<section id="polfloateval-atexpr"> +<span id="polfloatevalatexpr"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolFloatEval{}\AtExpr{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolFloatEval{<polname>}\AtExpr{<num.</span> <span class="pre">expr.>}</span></code></p> +<blockquote> +<div><p>Same output as <code class="docutils literal notranslate"><span class="pre">\xintfloateval{polname(numerical</span> <span class="pre">expression)}</span></code>.</p> +<div class="admonition attention"> +<p class="admonition-title">Attention</p> +<p><a class="reference internal" href="#polgenfloatvariant">\PolGenFloatVariant</a> must have +been issued before.</p> +</div> +<p>To use the <em>exact coefficients</em> with <em>exactly executed</em> additions +and multiplications and do the rounding only as the final last step, +the following syntax can be used: <a class="footnote-reference brackets" href="#id89" id="id88" role="doc-noteref"><span class="fn-bracket">[</span>4<span class="fn-bracket">]</span></a></p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\xintfloateval</span><span class="nb">{</span>3.27*<span class="k">\xintexpr</span> f(2.53)<span class="k">\relax</span><span class="nb">^</span>2<span class="nb">}</span> +</pre></div> +</div> +<aside class="footnote brackets" id="id89" role="note"> +<span class="label"><span class="fn-bracket">[</span><a role="doc-backlink" href="#id88">4</a><span class="fn-bracket">]</span></span> +<p>Cf. <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> documentation about nested expressions.</p> +</aside> +</div></blockquote> +</section> +<section id="polfloateval-at"> +<span id="polfloatevalat"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolFloatEval{}\At{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolFloatEval{<polname>}\At{<value>}</span></code></p> +<blockquote> +<div><p>Evaluates the polynomial at the value which must be in (or expand +to) a format acceptable to the <a class="reference external" href="https://www.ctan.org/pkg/xint">xintfrac</a> macros.</p> +</div></blockquote> +</section> +<section id="expandable-macros-in-relation-to-root-localization-via-sturm-theorem"> +<h3>Expandable macros in relation to root localization via <a class="reference external" href="https://en.wikipedia.org/wiki/Sturm%27s_theorem">Sturm Theorem</a></h3> +<section id="polsturmchainlength"> +<span id="id90"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolSturmChainLength{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolSturmChainLength{<sturmname>}</span></code></p> +<blockquote> +<div><p>Returns the integer <code class="docutils literal notranslate"><span class="pre">N</span></code> such that <code class="docutils literal notranslate"><span class="pre">sturmname_N</span></code> is the last one +in the Sturm chain <code class="docutils literal notranslate"><span class="pre">sturmname_0</span></code>, <code class="docutils literal notranslate"><span class="pre">sturmname_1</span></code>, …</p> +<p>See <a class="reference internal" href="#poltosturm"><span class="std std-ref">\PolToSturm{<polname>}{<sturmname>}</span></a>.</p> +</div></blockquote> +</section> +<section id="polsturmifzeroexactlyknown"> +<span id="id91"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolSturmIfZeroExactlyKnown{}{}{}{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolSturmIfZeroExactlyKnown{<sturmname>}{<index>}{T}{F}</span></code></p> +<blockquote> +<div><p>Executes <code class="docutils literal notranslate"><span class="pre">T</span></code> if the <code class="docutils literal notranslate"><span class="pre">index</span></code>-th interval reduces to a singleton, +i.e. the root is known exactly, else <code class="docutils literal notranslate"><span class="pre">F</span></code>.</p> +</div></blockquote> +</section> +<section id="polsturmisolatedzeroleft"> +<span id="id92"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolSturmIsolatedZeroLeft{}{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolSturmIsolatedZeroLeft{<sturmname>}{<index>}</span></code></p> +<blockquote> +<div><p>Expands to the left end-point for the <code class="docutils literal notranslate"><span class="pre">index</span></code>-th interval, as +computed by some earlier <a class="reference internal" href="#polsturmisolatezeros"><span class="std std-ref">\PolSturmIsolateZeros{<sturmname>}</span></a>.</p> +<div class="admonition note"> +<p class="admonition-title">Note</p> +<p>Execution of this macro after some +<a class="reference internal" href="#id46">\PolRefineInterval{<sturmname>}{<index>}</a> +will take into account the now known tighter bounds.</p> +</div> +<p>The value is pre-formatted using <a class="reference internal" href="#poldectostring">\PolDecTostring</a>.</p> +</div></blockquote> +</section> +<section id="polsturmisolatedzeroright"> +<span id="id93"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolSturmIsolatedZeroRight{}{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolSturmIsolatedZeroRight{<sturmname>}{<index>}</span></code></p> +<blockquote> +<div><p>Expands to the right end-point for the <code class="docutils literal notranslate"><span class="pre">index</span></code>-th interval as +computed by some earlier <a class="reference internal" href="#polsturmisolatezeros"><span class="std std-ref">\PolSturmIsolateZeros{<sturmname>}</span></a> and +possibly refined afterwards.</p> +<p>The value is pre-formatted using <a class="reference internal" href="#poldectostring">\PolDecTostring</a>.</p> +</div></blockquote> +</section> +<section id="polsturmisolatedzeromultiplicity"> +<span id="id94"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolSturmIsolatedZeroMultiplicity{}{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolSturmIsolatedZeroMultiplicity{<sturmname>}{<index>}</span></code></p> +<blockquote> +<div><p>Expands to the multiplicity of the unique root contained in the +<code class="docutils literal notranslate"><span class="pre">index</span></code>-th interval.</p> +<div class="admonition attention"> +<p class="admonition-title">Attention</p> +<p>A prior execution of <a class="reference internal" href="#id38"><span class="std std-ref">\PolSturmIsolateZeros*{<sturmname>}</span></a> is mandatory.</p> +</div> +<p>See <code class="docutils literal notranslate"><span class="pre">The</span> <span class="pre">degree</span> <span class="pre">nine</span> <span class="pre">polynomial</span> <span class="pre">with</span> <span class="pre">0.99,</span> <span class="pre">0.999,</span> <span class="pre">0.9999</span> <span class="pre">as</span> <span class="pre">triple</span> +<span class="pre">roots</span></code> in <code class="docutils literal notranslate"><span class="pre">polexpr-examples.pdf</span></code>.</p> +</div></blockquote> +</section> +<section id="polsturmnbofisolatedzeros"> +<span id="id95"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolSturmNbOfIsolatedZeros{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolSturmNbOfIsolatedZeros{<sturmname>}</span></code></p> +<blockquote> +<div><p>Expands to the number of real roots of the polynomial +<code class="docutils literal notranslate"><span class="pre"><sturmname>_0</span></code>, 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"><span class="std std-ref">\PolToSturm{<polname>}{<sturmname>}</span></a>.</p> +</div></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> +</section> +<section id="polsturmnbofrootsof-lessthanorequalto"> +<span id="polsturmnbofrootsoflessthanorequalto"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolSturmNbOfRootsOf{}\LessThanOrEqualTo{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolSturmNbOfRootsOf{<sturmname>}\LessThanOrEqualTo{<value>}</span></code></p> +<blockquote> +<div><p>Expands to the number of distinct roots (of the polynomial used to +create the Sturm chain) less than or equal to the <code class="docutils literal notranslate"><span class="pre">value</span></code> (i.e. a +number of fraction recognizable by the <a class="reference external" href="https://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"><span class="std std-ref">\PolSturmIsolateZeros{<sturmname>}</span></a> must have been executed +beforehand.</p> +<p>And the argument is a <code class="docutils literal notranslate"><span class="pre"><sturmname></span></code>, not a <code class="docutils literal notranslate"><span class="pre"><polname></span></code> (this is +why the macro contains Sturm in its name), simply to be reminded +of the above constraint.</p> +</div> +</div></blockquote> +</section> +<section id="polsturmnbofrootsof-lessthanorequaltoexpr"> +<span id="polsturmnbofrootsoflessthanorequaltoexpr"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolSturmNbOfRootsOf{}\LessThanOrEqualToExpr{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolSturmNbOfRootsOf{<sturmname>}\LessThanOrEqualToExpr{<num.</span> <span class="pre">expr.>}</span></code></p> +<blockquote> +<div><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 numerical expression.</p> +<div class="admonition attention"> +<p class="admonition-title">Attention</p> +<p><a class="reference internal" href="#polsturmisolatezeros"><span class="std std-ref">\PolSturmIsolateZeros{<sturmname>}</span></a> must have been executed +beforehand.</p> +</div> +</div></blockquote> +</section> +<section id="polsturmnbwithmultofrootsof-lessthanorequalto"> +<span id="polsturmnbwithmultofrootsoflessthanorequalto"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolSturmNbWithMultOfRootsOf{}\LessThanOrEqualTo{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolSturmNbWithMultOfRootsOf{<sturmname>}\LessThanOrEqualTo{<value>}</span></code></p> +<blockquote> +<div><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 <code class="docutils literal notranslate"><span class="pre">value</span></code>.</p> +<div class="admonition attention"> +<p class="admonition-title">Attention</p> +<p><a class="reference internal" href="#id38"><span class="std std-ref">\PolSturmIsolateZeros*{<sturmname>}</span></a> (or the double starred +variant) must have been executed beforehand.</p> +</div> +</div></blockquote> +</section> +<section id="polsturmnbwithmultofrootsof-lessthanorequaltoexpr"> +<span id="polsturmnbwithmultofrootsoflessthanorequaltoexpr"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolSturmNbWithMultOfRootsOf{}\LessThanOrEqualToExpr{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolSturmNbWithMultOfRootsOf{<sturmname>}\LessThanOrEqualToExpr{<num.</span> <span class="pre">expr.>}</span></code></p> +<blockquote> +<div><p>Expands to the total number of roots (counted with multiplicities) +which are less than or equal to the given <code class="docutils literal notranslate"><span class="pre">expression</span></code>.</p> +<div class="admonition attention"> +<p class="admonition-title">Attention</p> +<p><a class="reference internal" href="#id38"><span class="std std-ref">\PolSturmIsolateZeros*{<sturmname>}</span></a> (or the double starred +variant) must have been executed beforehand.</p> +</div> +</div></blockquote> +</section> +<section id="polsturmnbofrationalroots"> +<span id="id96"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolSturmNbOfRationalRoots{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolSturmNbOfRationalRoots{<sturmname>}</span></code></p> +<blockquote> +<div><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="#id41"><span class="std std-ref">\PolSturmIsolateZeros**{<sturmname>}</span></a> must have been executed +beforehand.</p> +</div> +</div></blockquote> +</section> +<section id="polsturmnbofrationalrootswithmultiplicities"> +<span id="id97"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolSturmNbOfRationalRootsWithMultiplicities{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolSturmNbOfRationalRootsWithMultiplicities{<sturmname>}</span></code></p> +<blockquote> +<div><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="#id41"><span class="std std-ref">\PolSturmIsolateZeros**{<sturmname>}</span></a> must have been executed +beforehand.</p> +</div> +</div></blockquote> +</section> +<section id="polsturmrationalroot"> +<span id="id98"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolSturmRationalRoot{}{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolSturmRationalRoot{<sturmname>}{<k>}</span></code></p> +<blockquote> +<div><p>Expands to the k-th rational root. They are enumerated from left to +right starting at index value <code class="docutils literal notranslate"><span class="pre">1</span></code>.</p> +<div class="admonition attention"> +<p class="admonition-title">Attention</p> +<p><a class="reference internal" href="#id41"><span class="std std-ref">\PolSturmIsolateZeros**{<sturmname>}</span></a> must have been executed +beforehand.</p> +</div> +</div></blockquote> +</section> +<section id="polsturmrationalrootindex"> +<span id="id99"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolSturmRationalRootIndex{}{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolSturmRationalRootIndex{<sturmname>}{<k>}</span></code></p> +<blockquote> +<div><p>Expands to the index of the <code class="docutils literal notranslate"><span class="pre">k</span></code>th rational root as part of the +ordered real roots (counted without multiplicities). So +<a class="reference internal" href="#polsturmrationalroot"><span class="std std-ref">\PolSturmRationalRoot{<sturmname>}{<k>}</span></a> is equivalent to +this nested call:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\PolSturmIsolatedZeroLeft</span><span class="nb">{</span><sturmname><span class="nb">}{</span><span class="k">\PolSturmRationalRootIndex</span><span class="nb">{</span><sturmname><span class="nb">}{</span><k><span class="nb">}}</span> +</pre></div> +</div> +<div class="admonition attention"> +<p class="admonition-title">Attention</p> +<p><a class="reference internal" href="#id41"><span class="std std-ref">\PolSturmIsolateZeros**{<sturmname>}</span></a> must have been executed +beforehand.</p> +</div> +</div></blockquote> +</section> +<section id="polsturmrationalrootmultiplicity"> +<span id="id100"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolSturmRationalRootMultiplicity{}{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolSturmRationalRootMultiplicity{<sturmname>}{<k>}</span></code></p> +<blockquote> +<div><p>Expands to the multiplicity of the <code class="docutils literal notranslate"><span class="pre">k</span></code>th rational root.</p> +<div class="admonition attention"> +<p class="admonition-title">Attention</p> +<p><a class="reference internal" href="#id41"><span class="std std-ref">\PolSturmIsolateZeros**{<sturmname>}</span></a> must have been executed +beforehand.</p> +</div> +</div></blockquote> +</section> +<section id="polintervalwidth"> +<span id="id101"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolIntervalWidth{}{}</span></code></h4> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolIntervalWidth{<sturmname>}{<index>}</span></code></p> +<blockquote> +<div><p>The <code class="docutils literal notranslate"><span class="pre">10^E</span></code> width of the current <code class="docutils literal notranslate"><span class="pre">index</span></code>-th root localization +interval. Output is in <a class="reference external" href="https://www.ctan.org/pkg/xint">xintfrac</a> raw <code class="docutils literal notranslate"><span class="pre">1/1[E]</span></code> format (if not zero).</p> +</div></blockquote> +</section> +</section> +<section id="expandable-macros-for-use-within-execution-of-polprintintervals"> +<h3>Expandable macros for use within execution of <code class="docutils literal notranslate"><span class="pre">\PolPrintIntervals</span></code></h3> +<p>These macros are for usage within custom user redefinitions of +<a class="reference internal" href="#id56">\PolPrintIntervalsKnownRoot</a>, <a class="reference internal" href="#id57">\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="#id59">\PolPrintIntervalsPrintLeftEndPoint</a>, +<a class="reference internal" href="#id60">\PolPrintIntervalsPrintRightEndPoint</a> (used in the default for the +latter).</p> +<section id="polprintintervalsthevar"> +<span id="id102"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervalsTheVar</span></code></h4> +<blockquote> +<div><p>Expands to the name (default <code class="docutils literal notranslate"><span class="pre">Z</span></code>) used for representing the roots, +which was passed as optional argument <code class="docutils literal notranslate"><span class="pre">varname</span></code> to +<a class="reference internal" href="#polprintintervals"><span class="std std-ref">\PolPrintIntervals[varname]{<sturmname>}</span></a>.</p> +</div></blockquote> +</section> +<section id="polprintintervalstheindex"> +<span id="id103"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervalsTheIndex</span></code></h4> +<blockquote> +<div><p>Expands to the index of the considered interval (indexing starting +at 1 for the leftmost interval).</p> +</div></blockquote> +</section> +<section id="polprintintervalsthesturmname"> +<span id="id104"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervalsTheSturmName</span></code></h4> +<blockquote> +<div><p>Expands to the argument which was passed as <code class="docutils literal notranslate"><span class="pre"><sturmname></span></code> to +<a class="reference internal" href="#polprintintervals"><span class="std std-ref">\PolPrintIntervals[varname]{<sturmname>}</span></a>.</p> +</div></blockquote> +</section> +<section id="polprintintervalstheleftendpoint"> +<span id="id105"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervalsTheLeftEndPoint</span></code></h4> +<blockquote> +<div><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="#id104">\PolPrintIntervalsTheSturmName</a> and +<a class="reference internal" href="#id103">\PolPrintIntervalsTheIndex</a>.</p> +</div></blockquote> +</section> +<section id="polprintintervalstherightendpoint"> +<span id="id106"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervalsTheRightEndPoint</span></code></h4> +<blockquote> +<div><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> +</div></blockquote> +</section> +<section id="polprintintervalsthemultiplicity"> +<span id="id107"></span><h4><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervalsTheMultiplicity</span></code></h4> +<blockquote> +<div><p>The multiplicity of the unique root within the interval of index +<a class="reference internal" href="#id103">\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> +</div></blockquote> +</section> +</section> +</section> +<section id="tex-booleans-with-names-enacting-their-defaults"> +<h2>TeX Booleans (with names enacting their defaults)</h2> +<section id="xintverbosefalse"> +<span id="id108"></span><h3><code class="docutils literal notranslate"><span class="pre">\xintverbosefalse</span></code></h3> +<blockquote> +<div><p>This is actually an <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> configuration. Setting it to +<code class="docutils literal notranslate"><span class="pre">true</span></code> 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> +</div></blockquote> +</section> +<section id="polnewpolverbosefalse"> +<span id="id109"></span><h3><code class="docutils literal notranslate"><span class="pre">\polnewpolverbosefalse</span></code></h3> +<blockquote> +<div><p>When <code class="docutils literal notranslate"><span class="pre">\poldef</span></code> is used, both a variable and a function are +defined. The default <code class="docutils literal notranslate"><span class="pre">\polnewpolverbosefalse</span></code> 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"><span class="std std-ref">\PolGenFloatVariant{<polname>}</span></a> +does still print out the information relative to the polynomial +function it defines for use in <code class="docutils literal notranslate"><span class="pre">\xintfloateval{}</span></code> as there is no +float polynomial variable, only the</p> +<p>function, and it is the only way to see its rounded coefficients +(<code class="docutils literal notranslate"><span class="pre">\xintverbosefalse</span></code> suppresses also that info).</p> +<p>If set to <code class="docutils literal notranslate"><span class="pre">true</span></code>, it overrides in both cases +<code class="docutils literal notranslate"><span class="pre">\xintverbosefalse</span></code>. The setting only affects polynomial +declarations. Scalar variables such as those holding information on +roots obey only the <code class="docutils literal notranslate"><span class="pre">\xintverbose...</span></code> setting.</p> +<p>(new with <code class="docutils literal notranslate"><span class="pre">0.8</span></code>)</p> +</div></blockquote> +</section> +<section id="poltypesetallfalse"> +<span id="id110"></span><h3><code class="docutils literal notranslate"><span class="pre">\poltypesetallfalse</span></code></h3> +<blockquote> +<div><p>If <code class="docutils literal notranslate"><span class="pre">true</span></code>, <a class="reference internal" href="#poltypeset">\PolTypeset</a> will also typeset the vanishing +coefficients.</p> +</div></blockquote> +</section> +<section id="poltoexprallfalse"> +<span id="id111"></span><h3><code class="docutils literal notranslate"><span class="pre">\poltoexprallfalse</span></code></h3> +<blockquote> +<div><p>If <code class="docutils literal notranslate"><span class="pre">true</span></code>, <a class="reference internal" href="#poltoexpr"><span class="std std-ref">\PolToExpr{<pol. expr.>}</span></a> and +<a class="reference internal" href="#poltofloatexpr"><span class="std std-ref">\PolToFloatExpr{<pol. expr.>}</span></a> will also +include the vanishing coefficients in their outputs.</p> +</div></blockquote> +</section> +</section> +<section id="utilities"> +<h2>Utilities</h2> +<section id="poldectostring"> +<span id="id112"></span><h3><code class="docutils literal notranslate"><span class="pre">\PolDecToString{}</span></code></h3> +<p>Syntax: <code class="docutils literal notranslate"><span class="pre">\PolDecToString{decimal</span> <span class="pre">number}</span></code></p> +<blockquote> +<div><p>This is a utility macro to print decimal numbers. It is an alias +for <code class="docutils literal notranslate"><span class="pre">\xintDecToString</span></code>.</p> +</div></blockquote> +<blockquote> +<div><p>For example +<code class="docutils literal notranslate"><span class="pre">\PolDecToString{123.456e-8}</span></code> will expand to <code class="docutils literal notranslate"><span class="pre">0.00000123456</span></code> +and <code class="docutils literal notranslate"><span class="pre">\PolDecToString{123.450e-8}</span></code> to <code class="docutils literal notranslate"><span class="pre">0.00000123450</span></code> which +illustrates that trailing zeros are not trimmed.</p> +<p>To trim trailing zeroes, one can use +<code class="docutils literal notranslate"><span class="pre">\PolDecToString{\xintREZ{#1}}</span></code>.</p> +<p>Attention that a.t.t.o.w. if the argument is for example <code class="docutils literal notranslate"><span class="pre">1/5</span></code>, the +macro does not identify that this is in fact a number with a finite +decimal expansion and it outputs <code class="docutils literal notranslate"><span class="pre">1/5</span></code>. See current <a class="reference external" href="https://www.ctan.org/pkg/xint">xintfrac</a> +documentation.</p> +</div></blockquote> +</section> +<section id="polexprsetup-key-val"> +<span id="polexprsetup"></span><h3><code class="docutils literal notranslate"><span class="pre">\polexprsetup{key=val,...}</span></code></h3> +<blockquote> +<div><p>Serves to customize the package. Currently only two keys are +recognized:</p> +<ul class="simple"> +<li><p><code class="docutils literal notranslate"><span class="pre">norr</span></code>: the postfix that <a class="reference internal" href="#id41"><span class="std std-ref">\PolSturmIsolateZeros**{<sturmname>}</span></a> +should append to <code class="docutils literal notranslate"><span class="pre"><sturmname></span></code> to declare the primitive polynomial +obtained from original one after removal of all rational roots. +The default value is <code class="docutils literal notranslate"><span class="pre">_norr</span></code> (standing for “no rational roots”).</p></li> +<li><p><code class="docutils literal notranslate"><span class="pre">sqfnorr</span></code>: the postfix that <a class="reference internal" href="#id41"><span class="std std-ref">\PolSturmIsolateZeros**{<sturmname>}</span></a> +should append to <code class="docutils literal notranslate"><span class="pre"><sturmname></span></code> to declare the primitive polynomial +obtained from original one after removal of all rational roots and +suppression of all multiplicities. +The default value is <code class="docutils literal notranslate"><span class="pre">_sqf_norr</span></code> (standing for “square-free with +no rational roots”).</p></li> +</ul> +<p>The package executes <code class="docutils literal notranslate"><span class="pre">\polexprsetup{norr=_norr,</span> +<span class="pre">sqfnorr=_sqf_norr}</span></code> as default.</p> +</div></blockquote> +</section> +</section> +<section id="technicalities"> +<h2>Technicalities</h2> +<ul> +<li><p>The <code class="docutils literal notranslate"><span class="pre">@</span></code> is allowed in the name of a polynomial (independently of +whether it is of catcode letter or other.) This has always been the +case, but was not documented by polexpr prior to <code class="docutils literal notranslate"><span class="pre">0.8</span></code>, as the +author has never found the time to provide some official guidelines on +how to name temporary variables and the <code class="docutils literal notranslate"><span class="pre">@</span></code> is used already as such +internally; time has still not yet been found to review the situation +but it seems reasonable to recommend at any rate to restrict usage of +<code class="docutils literal notranslate"><span class="pre">@</span></code> to scratch variables of defined macros and to avoid using it to +name document variable.</p></li> +<li><p>Catcodes are set temporarily by <a class="reference internal" href="#poldef">\poldef</a> macro to safe +values prior to grab the polynomial expression up to the terminator +<code class="docutils literal notranslate"><span class="pre">;</span></code>, and also by <a class="reference internal" href="#id5">\PolDef</a> prior to grab the +brace-enclosed polynomial expression. This gives a layer of +protection in case some package (for example the <code class="docutils literal notranslate"><span class="pre">babel-french</span></code> module) +has made some characters active. It will fail though if the whole +thing is located inside some definition of a macro done at a time the +characters are active.</p></li> +<li><div class="admonition attention"> +<p class="admonition-title">Attention</p> +<p>Contrarily to <code class="docutils literal notranslate"><span class="pre">\xintdefvar</span></code> and <code class="docutils literal notranslate"><span class="pre">\xintdeffunc</span></code> from <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a>, +<code class="docutils literal notranslate"><span class="pre">\poldef</span></code> uses a naive delimited macro to fetch up to the +expression terminator <code class="docutils literal notranslate"><span class="pre">";"</span></code>, hence it will be fooled if some +<code class="docutils literal notranslate"><span class="pre">;</span></code> is used inside the expression (which is possible as it +appears in some <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> constructs). Work-around is to use curly +braces around the inner semi-colons, or simpler to use +<code class="docutils literal notranslate"><span class="pre">\PolDef</span></code>.</p> +</div> +</li> +<li><p>As a consequence of <a class="reference external" href="https://www.ctan.org/pkg/xint">xintfrac</a> addition and subtraction always using +least common multiples for the denominators, user-chosen common +denominators (currently) survive additions and multiplications. For +example, this:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\poldef</span> P(x):= 1/2 + 2/2*x + 3/2*x<span class="nb">^</span>3 + 4/2*x<span class="nb">^</span>4; +<span class="k">\poldef</span> Q(x):= 1/3 + (2/3)x + (3/3)x<span class="nb">^</span>3 + (4/3)x<span class="nb">^</span>4; +<span class="k">\poldef</span> PQ(x):= P*Q; +</pre></div> +</div> +<p>gives internally the polynomial:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span>1/6+4/6*x<span class="nb">^</span>1+4/6*x<span class="nb">^</span>2+6/6*x<span class="nb">^</span>3+20/6*x<span class="nb">^</span>4+16/6*x<span class="nb">^</span>5+9/6*x<span class="nb">^</span>6+24/6*x<span class="nb">^</span>7+16/6*x<span class="nb">^</span>8 +</pre></div> +</div> +<p>where all coefficients have the same denominator 6. Notice though that +<code class="docutils literal notranslate"><span class="pre">\PolToExpr{PQ}</span></code> outputs the <code class="docutils literal notranslate"><span class="pre">6/6*x^3</span></code> as <code class="docutils literal notranslate"><span class="pre">x^3</span></code> because (by +default) it recognizes and filters out coefficients equal to one or +minus one. One can use for example +<code class="docutils literal notranslate"><span class="pre">\PolToCSV{PQ}</span></code> to see the internally stored coefficients.</p> +</li> +<li><p><a class="reference internal" href="#poldiff"><span class="std std-ref">\PolDiff{<polname_1>}{<polname_2>}</span></a> always applies <code class="docutils literal notranslate"><span class="pre">\xintPIrr</span></code> to the +resulting coefficients, which means that fractions are reduced to +lowest terms but ignoring an already separated <em>power of ten</em> part <code class="docutils literal notranslate"><span class="pre">[N]</span></code> +present in the internal representation. This is tentative and may change.</p> +<p>Same remark for <a class="reference internal" href="#polantidiff"><span class="std std-ref">\PolAntiDiff{<polname_1>}{<polname_2>}</span></a>.</p> +</li> +<li><p>Currently, the package stores all coefficients from index <code class="docutils literal notranslate"><span class="pre">0</span></code> 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 <code class="docutils literal notranslate"><span class="pre">\poldef</span> +<span class="pre">f(x):=x^1000</span> <span class="pre">+</span> <span class="pre">x^500;</span></code> the subsequent definition <code class="docutils literal notranslate"><span class="pre">\poldef</span> <span class="pre">g(x):=</span> +<span class="pre">f(x)^2;</span></code> 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> +</section> +</section> + + + <div class="clearer"></div> + </div> + </div> + </div> + <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> + <div class="sphinxsidebarwrapper"><h3>Contents of this page</h3> +<ul> +<li><a class="reference internal" href="#">polexpr reference</a><ul> +<li><a class="reference internal" href="#syntax-overview-via-examples">Syntax overview via examples</a></li> +<li><a class="reference internal" href="#using-defined-polynomials-in-floating-point-context">Using defined polynomials in floating point context</a></li> +<li><a class="reference internal" href="#the-polexpr-0-8-extensions-to-the-xintexpr-syntax">The polexpr <code class="docutils literal notranslate"><span class="pre">0.8</span></code> extensions to the <code class="docutils literal notranslate"><span class="pre">\xintexpr</span></code> syntax</a><ul> +<li><a class="reference internal" href="#warning-about-unstability-of-the-new-syntax">Warning about unstability of the new syntax</a></li> +<li><a class="reference internal" href="#infix-operators">Infix operators <code class="docutils literal notranslate"><span class="pre">+,</span> <span class="pre">-,</span> <span class="pre">*,</span> <span class="pre">/,</span> <span class="pre">**,</span> <span class="pre">^</span></code></a></li> +<li><a class="reference internal" href="#experimental-infix-operators">Experimental infix operators <code class="docutils literal notranslate"><span class="pre">//,</span> <span class="pre">/:</span></code></a></li> +<li><a class="reference internal" href="#comparison-operators">Comparison operators <code class="docutils literal notranslate"><span class="pre"><,</span> <span class="pre">>,</span> <span class="pre"><=,</span> <span class="pre">>=,</span> <span class="pre">==,</span> <span class="pre">!=</span></code></a></li> +<li><a class="reference internal" href="#pol-nutple-expression"><code class="docutils literal notranslate"><span class="pre">pol(<nutple</span> <span class="pre">expression>)</span></code></a></li> +<li><a class="reference internal" href="#lpol-nutple-expression"><code class="docutils literal notranslate"><span class="pre">lpol(<nutple</span> <span class="pre">expression>)</span></code></a></li> +<li><a class="reference internal" href="#xinteval-pol-expr"><code class="docutils literal notranslate"><span class="pre">\xinteval{<pol.</span> <span class="pre">expr.>}</span></code></a></li> +<li><a class="reference internal" href="#evalp-pol-expr-pol-expr"><code class="docutils literal notranslate"><span class="pre">evalp(<pol.</span> <span class="pre">expr.>,</span> <span class="pre"><pol.</span> <span class="pre">expr>)</span></code></a></li> +<li><a class="reference internal" href="#deg-pol-expr"><code class="docutils literal notranslate"><span class="pre">deg(<pol.</span> <span class="pre">expr.>)</span></code></a></li> +<li><a class="reference internal" href="#coeffs-pol-expr"><code class="docutils literal notranslate"><span class="pre">coeffs(<pol.</span> <span class="pre">expr.>)</span></code></a></li> +<li><a class="reference internal" href="#lcoeffs-pol-expr"><code class="docutils literal notranslate"><span class="pre">lcoeffs(<pol.</span> <span class="pre">expr.>)</span></code></a></li> +<li><a class="reference internal" href="#coeff-pol-expr-num-expr"><code class="docutils literal notranslate"><span class="pre">coeff(<pol.</span> <span class="pre">expr.>,</span> <span class="pre"><num.</span> <span class="pre">expr.>)</span></code></a></li> +<li><a class="reference internal" href="#lc-pol-expr"><code class="docutils literal notranslate"><span class="pre">lc(<pol.</span> <span class="pre">expr.>)</span></code></a></li> +<li><a class="reference internal" href="#monicpart-pol-expr"><code class="docutils literal notranslate"><span class="pre">monicpart(<pol.</span> <span class="pre">expr.>)</span></code></a></li> +<li><a class="reference internal" href="#cont-pol-expr"><code class="docutils literal notranslate"><span class="pre">cont(<pol.</span> <span class="pre">expr.>)</span></code></a></li> +<li><a class="reference internal" href="#primpart-pol-expr"><code class="docutils literal notranslate"><span class="pre">primpart(<pol.</span> <span class="pre">expr.>)</span></code></a></li> +<li><a class="reference internal" href="#quorem-pol-expr-pol-expr"><code class="docutils literal notranslate"><span class="pre">quorem(<pol.</span> <span class="pre">expr.>,</span> <span class="pre"><pol.</span> <span class="pre">expr.>)</span></code></a></li> +<li><a class="reference internal" href="#quo-pol-expr-pol-expr"><code class="docutils literal notranslate"><span class="pre">quo(<pol.</span> <span class="pre">expr.>,</span> <span class="pre"><pol.</span> <span class="pre">expr.>)</span></code></a></li> +<li><a class="reference internal" href="#rem-pol-expr-pol-expr"><code class="docutils literal notranslate"><span class="pre">rem(<pol.</span> <span class="pre">expr.>,</span> <span class="pre"><pol.</span> <span class="pre">expr.>)</span></code></a></li> +<li><a class="reference internal" href="#prem-pol-expr-1-pol-expr-2"><code class="docutils literal notranslate"><span class="pre">prem(<pol.</span> <span class="pre">expr.</span> <span class="pre">1>,</span> <span class="pre"><pol.</span> <span class="pre">expr.</span> <span class="pre">2>)</span></code></a></li> +<li><a class="reference internal" href="#divmod-pol-expr-1-pol-expr-2"><code class="docutils literal notranslate"><span class="pre">divmod(<pol.</span> <span class="pre">expr.</span> <span class="pre">1>,</span> <span class="pre"><pol.</span> <span class="pre">expr.</span> <span class="pre">2>)</span></code></a></li> +<li><a class="reference internal" href="#mod-pol-expr-1-pol-expr-2"><code class="docutils literal notranslate"><span class="pre">mod(<pol.</span> <span class="pre">expr.</span> <span class="pre">1>,</span> <span class="pre"><pol.</span> <span class="pre">expr.</span> <span class="pre">2>)</span></code></a></li> +<li><a class="reference internal" href="#polgcd-pol-expr-1-pol-expr-2"><code class="docutils literal notranslate"><span class="pre">polgcd(<pol.</span> <span class="pre">expr.</span> <span class="pre">1>,</span> <span class="pre"><pol.</span> <span class="pre">expr.</span> <span class="pre">2>,</span> <span class="pre">...)</span></code></a></li> +<li><a class="reference internal" href="#resultant-pol-expr-1-pol-expr-2"><code class="docutils literal notranslate"><span class="pre">resultant(<pol.</span> <span class="pre">expr.</span> <span class="pre">1>,</span> <span class="pre"><pol.</span> <span class="pre">expr.</span> <span class="pre">2>)</span></code></a></li> +<li><a class="reference internal" href="#disc-pol-expr"><code class="docutils literal notranslate"><span class="pre">disc(<pol.</span> <span class="pre">expr.>)</span></code></a></li> +<li><a class="reference internal" href="#polpowmod-pol-expr-1-num-expr-pol-expr-2"><code class="docutils literal notranslate"><span class="pre">polpowmod(<pol.</span> <span class="pre">expr.</span> <span class="pre">1>,</span> <span class="pre"><num.</span> <span class="pre">expr.>,</span> <span class="pre"><pol.</span> <span class="pre">expr.</span> <span class="pre">2>)</span></code></a></li> +<li><a class="reference internal" href="#rdcoeffs-pol-expr"><code class="docutils literal notranslate"><span class="pre">rdcoeffs(<pol.</span> <span class="pre">expr.>)</span></code></a></li> +<li><a class="reference internal" href="#rdzcoeffs-pol-expr"><code class="docutils literal notranslate"><span class="pre">rdzcoeffs(<pol.</span> <span class="pre">expr.>)</span></code></a></li> +<li><a class="reference internal" href="#diff1-pol-expr"><code class="docutils literal notranslate"><span class="pre">diff1(<pol.</span> <span class="pre">expr.>)</span></code></a></li> +<li><a class="reference internal" href="#diff2-pol-expr"><code class="docutils literal notranslate"><span class="pre">diff2(<pol.</span> <span class="pre">expr.>)</span></code></a></li> +<li><a class="reference internal" href="#diffn-pol-expr-p-num-expr-n"><code class="docutils literal notranslate"><span class="pre">diffn(<pol.</span> <span class="pre">expr.</span> <span class="pre">P>,</span> <span class="pre"><num.</span> <span class="pre">expr.</span> <span class="pre">n>)</span></code></a></li> +<li><a class="reference internal" href="#antider-pol-expr-p"><code class="docutils literal notranslate"><span class="pre">antider(<pol.</span> <span class="pre">expr.</span> <span class="pre">P>)</span></code></a></li> +<li><a class="reference internal" href="#intfrom-pol-expr-p-pol-expr-c"><code class="docutils literal notranslate"><span class="pre">intfrom(<pol.</span> <span class="pre">expr.</span> <span class="pre">P>,</span> <span class="pre"><pol.</span> <span class="pre">expr.</span> <span class="pre">c>)</span></code></a></li> +<li><a class="reference internal" href="#integral-pol-expr-p-pol-expr-a-pol-expr-b"><code class="docutils literal notranslate"><span class="pre">integral(<pol.</span> <span class="pre">expr.</span> <span class="pre">P>,</span> <span class="pre">[<pol.</span> <span class="pre">expr.</span> <span class="pre">a>,</span> <span class="pre"><pol.</span> <span class="pre">expr.</span> <span class="pre">b>])</span></code></a></li> +</ul> +</li> +<li><a class="reference internal" href="#non-expandable-macros">Non-expandable macros</a><ul> +<li><a class="reference internal" href="#poldef-polname-letter-expression-using-the-letter-as-indeterminate"><code class="docutils literal notranslate"><span class="pre">\poldef</span> <span class="pre">polname(letter):=</span> <span class="pre">expression</span> <span class="pre">using</span> <span class="pre">the</span> <span class="pre">letter</span> <span class="pre">as</span> <span class="pre">indeterminate;</span></code></a></li> +<li><a class="reference internal" href="#poldef-letter-polname-expr-using-the-letter-as-indeterminate"><code class="docutils literal notranslate"><span class="pre">\PolDef[<letter>]{<polname>}{<expr.</span> <span class="pre">using</span> <span class="pre">the</span> <span class="pre">letter</span> <span class="pre">as</span> <span class="pre">indeterminate>}</span></code></a></li> +<li><a class="reference internal" href="#polgenfloatvariant"><code class="docutils literal notranslate"><span class="pre">\PolGenFloatVariant{}</span></code></a></li> +<li><a class="reference internal" href="#poltypeset"><code class="docutils literal notranslate"><span class="pre">\PolTypeset{}</span></code></a><ul> +<li><a class="reference internal" href="#poltypesetcmd"><code class="docutils literal notranslate"><span class="pre">\PolTypesetCmd{}</span></code></a><ul> +<li><a class="reference internal" href="#polifcoeffisplusorminusone"><code class="docutils literal notranslate"><span class="pre">\PolIfCoeffIsPlusOrMinusOne{}{}</span></code></a></li> +</ul> +</li> +<li><a class="reference internal" href="#poltypesetone"><code class="docutils literal notranslate"><span class="pre">\PolTypesetOne{}</span></code></a></li> +<li><a class="reference internal" href="#poltypesetmonomialcmd"><code class="docutils literal notranslate"><span class="pre">\PolTypesetMonomialCmd</span></code></a></li> +<li><a class="reference internal" href="#poltypesetcmdprefix"><code class="docutils literal notranslate"><span class="pre">\PolTypesetCmdPrefix{}</span></code></a></li> +</ul> +</li> +<li><a class="reference internal" href="#id13"><code class="docutils literal notranslate"><span class="pre">\PolTypeset*{}</span></code></a></li> +<li><a class="reference internal" href="#pollet"><code class="docutils literal notranslate"><span class="pre">\PolLet{}={}</span></code></a></li> +<li><a class="reference internal" href="#polgloballet"><code class="docutils literal notranslate"><span class="pre">\PolGlobalLet{}={}</span></code></a></li> +<li><a class="reference internal" href="#polassign-toarray"><code class="docutils literal notranslate"><span class="pre">\PolAssign{}\toarray{}</span></code></a></li> +<li><a class="reference internal" href="#polget-fromarray"><code class="docutils literal notranslate"><span class="pre">\PolGet{}\fromarray{}</span></code></a></li> +<li><a class="reference internal" href="#polfromcsv"><code class="docutils literal notranslate"><span class="pre">\PolFromCSV{}{}</span></code></a></li> +<li><a class="reference internal" href="#polmapcoeffs"><code class="docutils literal notranslate"><span class="pre">\PolMapCoeffs{}{}</span></code></a></li> +<li><a class="reference internal" href="#polreducecoeffs"><code class="docutils literal notranslate"><span class="pre">\PolReduceCoeffs{}</span></code></a></li> +<li><a class="reference internal" href="#id20"><code class="docutils literal notranslate"><span class="pre">\PolReduceCoeffs*{}</span></code></a></li> +<li><a class="reference internal" href="#polmakemonic"><code class="docutils literal notranslate"><span class="pre">\PolMakeMonic{}</span></code></a></li> +<li><a class="reference internal" href="#polmakeprimitive"><code class="docutils literal notranslate"><span class="pre">\PolMakePrimitive{}</span></code></a></li> +<li><a class="reference internal" href="#poldiff"><code class="docutils literal notranslate"><span class="pre">\PolDiff{}{}</span></code></a></li> +<li><a class="reference internal" href="#id25"><code class="docutils literal notranslate"><span class="pre">\PolDiff[]{}{}</span></code></a></li> +<li><a class="reference internal" href="#polantidiff"><code class="docutils literal notranslate"><span class="pre">\PolAntiDiff{}{}</span></code></a></li> +<li><a class="reference internal" href="#id28"><code class="docutils literal notranslate"><span class="pre">\PolAntiDiff[]{}{}</span></code></a></li> +<li><a class="reference internal" href="#poldivide"><code class="docutils literal notranslate"><span class="pre">\PolDivide{}{}{}{}</span></code></a></li> +<li><a class="reference internal" href="#polquo"><code class="docutils literal notranslate"><span class="pre">\PolQuo{}{}{}</span></code></a></li> +<li><a class="reference internal" href="#polrem"><code class="docutils literal notranslate"><span class="pre">\PolRem{}{}{}</span></code></a></li> +<li><a class="reference internal" href="#polgcd"><code class="docutils literal notranslate"><span class="pre">\PolGCD{}{}{}</span></code></a></li> +<li><a class="reference internal" href="#root-localization-routines-via-the-sturm-theorem">Root localization routines via the Sturm Theorem</a><ul> +<li><a class="reference internal" href="#poltosturm"><code class="docutils literal notranslate"><span class="pre">\PolToSturm{}{}</span></code></a></li> +<li><a class="reference internal" href="#id35"><code class="docutils literal notranslate"><span class="pre">\PolToSturm*{}{}</span></code></a></li> +<li><a class="reference internal" href="#polsturmisolatezeros"><code class="docutils literal notranslate"><span class="pre">\PolSturmIsolateZeros{}</span></code></a></li> +<li><a class="reference internal" href="#id38"><code class="docutils literal notranslate"><span class="pre">\PolSturmIsolateZeros*{}</span></code></a><ul> +<li><a class="reference internal" href="#polsturmisolatezerosandgetmultiplicities"><code class="docutils literal notranslate"><span class="pre">\PolSturmIsolateZerosAndGetMultiplicities{}</span></code></a></li> +</ul> +</li> +<li><a class="reference internal" href="#id41"><code class="docutils literal notranslate"><span class="pre">\PolSturmIsolateZeros**{}</span></code></a><ul> +<li><a class="reference internal" href="#polsturmisolatezerosgetmultiplicitiesandrationalroots"><code class="docutils literal notranslate"><span class="pre">\PolSturmIsolateZerosGetMultiplicitiesAndRationalRoots</span></code></a></li> +</ul> +</li> +<li><a class="reference internal" href="#polsturmisolatezerosandfindrationalroots"><code class="docutils literal notranslate"><span class="pre">\PolSturmIsolateZerosAndFindRationalRoots{}</span></code></a></li> +<li><a class="reference internal" href="#polrefineinterval"><code class="docutils literal notranslate"><span class="pre">\PolRefineInterval*{}{}</span></code></a></li> +<li><a class="reference internal" href="#id46"><code class="docutils literal notranslate"><span class="pre">\PolRefineInterval[]{}{}</span></code></a></li> +<li><a class="reference internal" href="#polensureintervallength"><code class="docutils literal notranslate"><span class="pre">\PolEnsureIntervalLength{}{}{}</span></code></a></li> +<li><a class="reference internal" href="#polensureintervallengths"><code class="docutils literal notranslate"><span class="pre">\PolEnsureIntervalLengths{}{}</span></code></a></li> +<li><a class="reference internal" href="#polsettosturmchainsignchangesat"><code class="docutils literal notranslate"><span class="pre">\PolSetToSturmChainSignChangesAt{}{}{}</span></code></a></li> +<li><a class="reference internal" href="#polsettonbofzeroswithin"><code class="docutils literal notranslate"><span class="pre">\PolSetToNbOfZerosWithin{}{}{}{}</span></code></a></li> +</ul> +</li> +<li><a class="reference internal" href="#displaying-the-found-roots-polprintintervals-varname">Displaying the found roots: <code class="docutils literal notranslate"><span class="pre">\PolPrintIntervals[<varname>]{}</span></code></a><ul> +<li><a class="reference internal" href="#polprintintervalsnorealroots"><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervalsNoRealRoots</span></code></a></li> +<li><a class="reference internal" href="#polprintintervalsbeginenv"><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervalsBeginEnv</span></code></a></li> +<li><a class="reference internal" href="#polprintintervalsendenv"><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervalsEndEnv</span></code></a></li> +<li><a class="reference internal" href="#polprintintervalsrowseparator"><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervalsRowSeparator</span></code></a></li> +<li><a class="reference internal" href="#polprintintervalsknownroot"><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervalsKnownRoot</span></code></a></li> +<li><a class="reference internal" href="#polprintintervalsunknownroot"><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervalsUnknownRoot</span></code></a></li> +<li><a class="reference internal" href="#polprintintervalsprintexactzero"><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervalsPrintExactZero</span></code></a></li> +<li><a class="reference internal" href="#polprintintervalsprintleftendpoint"><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervalsPrintLeftEndPoint</span></code></a></li> +<li><a class="reference internal" href="#polprintintervalsprintrightendpoint"><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervalsPrintRightEndPoint</span></code></a></li> +<li><a class="reference internal" href="#polprintintervals-varname"><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervals*[<varname>]{}</span></code></a><ul> +<li><a class="reference internal" href="#polprintintervalsprintmultiplicity"><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervalsPrintMultiplicity</span></code></a></li> +</ul> +</li> +</ul> +</li> +</ul> +</li> +<li><a class="reference internal" href="#expandable-macros">Expandable macros</a><ul> +<li><a class="reference internal" href="#poltoexpr"><code class="docutils literal notranslate"><span class="pre">\PolToExpr{}</span></code></a><ul> +<li><a class="reference internal" href="#poltoexprvar"><code class="docutils literal notranslate"><span class="pre">\PolToExprVar</span></code></a></li> +<li><a class="reference internal" href="#poltoexprinvar"><code class="docutils literal notranslate"><span class="pre">\PolToExprInVar</span></code></a></li> +<li><a class="reference internal" href="#poltoexprtimes"><code class="docutils literal notranslate"><span class="pre">\PolToExprTimes</span></code></a></li> +<li><a class="reference internal" href="#poltoexprcaret"><code class="docutils literal notranslate"><span class="pre">\PolToExprCaret</span></code></a></li> +<li><a class="reference internal" href="#poltoexprcmd"><code class="docutils literal notranslate"><span class="pre">\PolToExprCmd{}</span></code></a></li> +<li><a class="reference internal" href="#poltoexproneterm"><code class="docutils literal notranslate"><span class="pre">\PolToExprOneTerm{}{}</span></code></a></li> +<li><a class="reference internal" href="#poltoexpronetermstylea"><code class="docutils literal notranslate"><span class="pre">\PolToExprOneTermStyleA{}{}</span></code></a></li> +<li><a class="reference internal" href="#poltoexpronetermstyleb"><code class="docutils literal notranslate"><span class="pre">\PolToExprOneTermStyleB{}{}</span></code></a></li> +<li><a class="reference internal" href="#poltoexprtermprefix"><code class="docutils literal notranslate"><span class="pre">\PolToExprTermPrefix{}</span></code></a></li> +</ul> +</li> +<li><a class="reference internal" href="#poltofloatexpr"><code class="docutils literal notranslate"><span class="pre">\PolToFloatExpr{}</span></code></a><ul> +<li><a class="reference internal" href="#poltofloatexproneterm"><code class="docutils literal notranslate"><span class="pre">\PolToFloatExprOneTerm{}{}</span></code></a></li> +<li><a class="reference internal" href="#poltofloatexprcmd"><code class="docutils literal notranslate"><span class="pre">\PolToFloatExprCmd{}</span></code></a></li> +</ul> +</li> +<li><a class="reference internal" href="#id78"><code class="docutils literal notranslate"><span class="pre">\PolToExpr*{}</span></code></a></li> +<li><a class="reference internal" href="#id80"><code class="docutils literal notranslate"><span class="pre">\PolToFloatExpr*{}</span></code></a></li> +<li><a class="reference internal" href="#polnthcoeff"><code class="docutils literal notranslate"><span class="pre">\PolNthCoeff{}{}</span></code></a></li> +<li><a class="reference internal" href="#polleadingcoeff"><code class="docutils literal notranslate"><span class="pre">\PolLeadingCoeff{}</span></code></a></li> +<li><a class="reference internal" href="#poldegree"><code class="docutils literal notranslate"><span class="pre">\PolDegree{}</span></code></a></li> +<li><a class="reference internal" href="#policontent"><code class="docutils literal notranslate"><span class="pre">\PolIContent{}</span></code></a></li> +<li><a class="reference internal" href="#poltolist"><code class="docutils literal notranslate"><span class="pre">\PolToList{}</span></code></a></li> +<li><a class="reference internal" href="#poltocsv"><code class="docutils literal notranslate"><span class="pre">\PolToCSV{}</span></code></a></li> +<li><a class="reference internal" href="#poleval-atexpr"><code class="docutils literal notranslate"><span class="pre">\PolEval{}\AtExpr{}</span></code></a></li> +<li><a class="reference internal" href="#poleval-at"><code class="docutils literal notranslate"><span class="pre">\PolEval{}\At{}</span></code></a></li> +<li><a class="reference internal" href="#polevalreduced-atexpr"><code class="docutils literal notranslate"><span class="pre">\PolEvalReduced{}\AtExpr{}</span></code></a></li> +<li><a class="reference internal" href="#polevalreduced-at"><code class="docutils literal notranslate"><span class="pre">\PolEvalReduced{}\At{}</span></code></a></li> +<li><a class="reference internal" href="#polfloateval-atexpr"><code class="docutils literal notranslate"><span class="pre">\PolFloatEval{}\AtExpr{}</span></code></a></li> +<li><a class="reference internal" href="#polfloateval-at"><code class="docutils literal notranslate"><span class="pre">\PolFloatEval{}\At{}</span></code></a></li> +<li><a class="reference internal" href="#expandable-macros-in-relation-to-root-localization-via-sturm-theorem">Expandable macros in relation to root localization via Sturm Theorem</a><ul> +<li><a class="reference internal" href="#polsturmchainlength"><code class="docutils literal notranslate"><span class="pre">\PolSturmChainLength{}</span></code></a></li> +<li><a class="reference internal" href="#polsturmifzeroexactlyknown"><code class="docutils literal notranslate"><span class="pre">\PolSturmIfZeroExactlyKnown{}{}{}{}</span></code></a></li> +<li><a class="reference internal" href="#polsturmisolatedzeroleft"><code class="docutils literal notranslate"><span class="pre">\PolSturmIsolatedZeroLeft{}{}</span></code></a></li> +<li><a class="reference internal" href="#polsturmisolatedzeroright"><code class="docutils literal notranslate"><span class="pre">\PolSturmIsolatedZeroRight{}{}</span></code></a></li> +<li><a class="reference internal" href="#polsturmisolatedzeromultiplicity"><code class="docutils literal notranslate"><span class="pre">\PolSturmIsolatedZeroMultiplicity{}{}</span></code></a></li> +<li><a class="reference internal" href="#polsturmnbofisolatedzeros"><code class="docutils literal notranslate"><span class="pre">\PolSturmNbOfIsolatedZeros{}</span></code></a></li> +<li><a class="reference internal" href="#polsturmnbofrootsof-lessthanorequalto"><code class="docutils literal notranslate"><span class="pre">\PolSturmNbOfRootsOf{}\LessThanOrEqualTo{}</span></code></a></li> +<li><a class="reference internal" href="#polsturmnbofrootsof-lessthanorequaltoexpr"><code class="docutils literal notranslate"><span class="pre">\PolSturmNbOfRootsOf{}\LessThanOrEqualToExpr{}</span></code></a></li> +<li><a class="reference internal" href="#polsturmnbwithmultofrootsof-lessthanorequalto"><code class="docutils literal notranslate"><span class="pre">\PolSturmNbWithMultOfRootsOf{}\LessThanOrEqualTo{}</span></code></a></li> +<li><a class="reference internal" href="#polsturmnbwithmultofrootsof-lessthanorequaltoexpr"><code class="docutils literal notranslate"><span class="pre">\PolSturmNbWithMultOfRootsOf{}\LessThanOrEqualToExpr{}</span></code></a></li> +<li><a class="reference internal" href="#polsturmnbofrationalroots"><code class="docutils literal notranslate"><span class="pre">\PolSturmNbOfRationalRoots{}</span></code></a></li> +<li><a class="reference internal" href="#polsturmnbofrationalrootswithmultiplicities"><code class="docutils literal notranslate"><span class="pre">\PolSturmNbOfRationalRootsWithMultiplicities{}</span></code></a></li> +<li><a class="reference internal" href="#polsturmrationalroot"><code class="docutils literal notranslate"><span class="pre">\PolSturmRationalRoot{}{}</span></code></a></li> +<li><a class="reference internal" href="#polsturmrationalrootindex"><code class="docutils literal notranslate"><span class="pre">\PolSturmRationalRootIndex{}{}</span></code></a></li> +<li><a class="reference internal" href="#polsturmrationalrootmultiplicity"><code class="docutils literal notranslate"><span class="pre">\PolSturmRationalRootMultiplicity{}{}</span></code></a></li> +<li><a class="reference internal" href="#polintervalwidth"><code class="docutils literal notranslate"><span class="pre">\PolIntervalWidth{}{}</span></code></a></li> +</ul> +</li> +<li><a class="reference internal" href="#expandable-macros-for-use-within-execution-of-polprintintervals">Expandable macros for use within execution of <code class="docutils literal notranslate"><span class="pre">\PolPrintIntervals</span></code></a><ul> +<li><a class="reference internal" href="#polprintintervalsthevar"><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervalsTheVar</span></code></a></li> +<li><a class="reference internal" href="#polprintintervalstheindex"><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervalsTheIndex</span></code></a></li> +<li><a class="reference internal" href="#polprintintervalsthesturmname"><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervalsTheSturmName</span></code></a></li> +<li><a class="reference internal" href="#polprintintervalstheleftendpoint"><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervalsTheLeftEndPoint</span></code></a></li> +<li><a class="reference internal" href="#polprintintervalstherightendpoint"><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervalsTheRightEndPoint</span></code></a></li> +<li><a class="reference internal" href="#polprintintervalsthemultiplicity"><code class="docutils literal notranslate"><span class="pre">\PolPrintIntervalsTheMultiplicity</span></code></a></li> +</ul> +</li> +</ul> +</li> +<li><a class="reference internal" href="#tex-booleans-with-names-enacting-their-defaults">TeX Booleans (with names enacting their defaults)</a><ul> +<li><a class="reference internal" href="#xintverbosefalse"><code class="docutils literal notranslate"><span class="pre">\xintverbosefalse</span></code></a></li> +<li><a class="reference internal" href="#polnewpolverbosefalse"><code class="docutils literal notranslate"><span class="pre">\polnewpolverbosefalse</span></code></a></li> +<li><a class="reference internal" href="#poltypesetallfalse"><code class="docutils literal notranslate"><span class="pre">\poltypesetallfalse</span></code></a></li> +<li><a class="reference internal" href="#poltoexprallfalse"><code class="docutils literal notranslate"><span class="pre">\poltoexprallfalse</span></code></a></li> +</ul> +</li> +<li><a class="reference internal" href="#utilities">Utilities</a><ul> +<li><a class="reference internal" href="#poldectostring"><code class="docutils literal notranslate"><span class="pre">\PolDecToString{}</span></code></a></li> +<li><a class="reference internal" href="#polexprsetup-key-val"><code class="docutils literal notranslate"><span class="pre">\polexprsetup{key=val,...}</span></code></a></li> +</ul> +</li> +<li><a class="reference internal" href="#technicalities">Technicalities</a></li> +</ul> +</li> +</ul> + + <div role="note" aria-label="source link"> + <h3>This Page</h3> + <ul class="this-page-menu"> + <li><a href="polexpr-ref.rst.txt" + rel="nofollow">Show Source</a></li> + </ul> + </div> + <div> + <h4>Previous topic</h4> + <p class="topless"><a href="polexpr.html" + title="previous chapter">Introduction to polexpr</a></p> + </div> + <div> + <h4>Next topic</h4> + <p class="topless"><a href="polexpr-changes.html" + title="next chapter">CHANGES</a></p> + </div> + </div> + </div> + <div class="clearer"></div> + </div> + <div class="related" role="navigation" aria-label="related navigation"> + <h3>Navigation</h3> + <ul> + <li class="right" style="margin-right: 10px"> + <a href="polexpr-changes.html" title="CHANGES" + >next</a></li> + <li class="right" > + <a href="polexpr.html" title="Introduction to polexpr" + >previous</a> |</li> + <li class="nav-item nav-item-0"><a href="polexpr.html">polexpr 0.8.7 documentation</a> »</li> + <li class="nav-item nav-item-this"><a href="">polexpr reference</a></li> + </ul> + </div> + <div class="footer" role="contentinfo"> + © Copyright 2022, Jean-François Burnol. + Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 5.0.0+/f58771c09. + </div> + </body> +</html>
\ No newline at end of file diff --git a/Master/texmf-dist/doc/generic/polexpr/polexpr-ref.rst.txt b/Master/texmf-dist/doc/generic/polexpr/polexpr-ref.rst.txt new file mode 100644 index 00000000000..028e68626f6 --- /dev/null +++ b/Master/texmf-dist/doc/generic/polexpr/polexpr-ref.rst.txt @@ -0,0 +1,3184 @@ +.. comment: -*- fill-column: 72; mode: rst -*- + +=================== + polexpr reference +=================== + +.. _quick: + +Syntax overview via examples +---------------------------- + +The syntax to define a new polynomial is:: + + \poldef polname(x):= expression in variable x; + +.. + +The expression will be parsed by the services of xintexpr_, with some +polynomial aware functions added to its syntax; they are described in +detail :ref:`below <polexpr08>`. The parser accepts and will handle +exactly arbitrarily big integers or fractions. + +.. note:: + + xintexpr_ does not automatically reduce fractions to lowest terms, + and, so far (but this may change in future) neither does :ref:`\\poldef + <poldef;>`. + See :ref:`rdcoeffs() <rdcoeffs>` and the macro + :ref:`\\PolReduceCoeffs <PolReduceCoeffs>`. + + +- In place of ``x`` an arbitrary *dummy variable* is authorized, + i.e. per default one ``a, .., z, A, .., Z`` (more letters can be declared + under Unicode engines). + +- ``polname`` consists of *letters*, *digits*, and also the ``_`` and + ``'`` characters are allowed. The polynomial name **must** start with + a letter: do not use the underscore ``_`` as *first character* of a + polynomial name (even if of catcode letter). No warning is emitted + but dire consequences will ensue. The ``@`` is also allowed + (independently of its catcode "letter" or "other", which does not + matter). It is recommended to avoid using it as first character, + except for temporary polynomial variables. + +- The colon before the equality sign is optional and its (reasonable) + catcode does not matter. + +- The semi-colon at the end of the expression is mandatory. It is not + allowed to arise from expansion (despite the fact that the expression + itself will be parsed using only expansion), it must be "visible" + immediately. + +There are some potential problems (refer to the Technicalities_ section at +bottom of this page) with the semi-colon as expression terminator, so an +alternative syntax is provided, which avoids it altogether:: + + \PolDef[optional letter]{<polname>}{<expr. using letter as indeterminate>} + +The ``\PolDef`` optional first argument defaults to ``x`` and must be +used as the indeterminate in the expression. + +Examples: + +``\poldef f(x):= 1 - x + quo(x^5,1 - x + x^2);`` + +``\PolDef{f}{1 - x + quo(x^5,1 - x + x^2)}`` + Both parse the polynomial + expression, and they create internally macros serving to + incarnate the polynomial, its coefficients, and the associated + polynomial function. + + The polynomial can then be used in further polynomial definitions, + be served as argument to package macros, or appear as a variable in + various functions `described later <polexpr08_>`_. + + .. warning:: + + Both the function ``quo()`` (as shown in the example above), and + the infix operator ``/`` are mapped to the Euclidean quotient. + + This usage of ``/`` to stand for the Euclidean quotient is + **deprecated** and reserved for a (somewhat improbable) possible + extension of the package to handle rational functions as well. + + .. _warningtacit: + + .. attention:: + + Tacit multiplication rules let the parser when encountering + ``1/2 x^2`` skip the space and thus handle it as ``1/(2*x^2)``. + But then it gives zero, because `/` stands for the Euclidean + quotient operation here. + + 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 + 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: + xintexpr_\ 's tacit multiplication always "ties more", hence this + gets interpreted as ``1/(2*(x-1)*(x-2))`` not as + ``(1/2)*(x-1)*(x-2)`` and then gives zero by + polynomial division. Thus, in such cases, use one of + ``(1/2)(x-1)(x-2)``, ``1/2*(x-1)(x-2)`` or ``(x-1)(x-2)/2``. + + ``\poldef P(x):=...;`` defines ``P`` as a *polynomial function*, + which can be used inside ``\xinteval``, as:: + + \xinteval{P(3 + 7 + 11)} + + or even as:: + + \xinteval{P(Q1 + Q2 + Q3)} + + where ``Q1``, ``Q2``, ``Q3`` are polynomials. The evaluation result, + if not a scalar, will then be printed as ``pol([c0,c1,...])`` which + stands for a polynomial variable having the listed coefficients; see + :ref:`pol() <pol>`. + + Indeed, as seen above with ``Q1``, the symbol ``P`` also stands for + a *variable of polynomial type*, which serves as argument to + polynomial specific functions such as :ref:`deg() <deg>` or + :ref:`polgcd() <polgcd>`, or as argument to other polynomials (as + above), or even simply stands for its own in algebraic expressions + such as:: + + \poldef Q(z):= P^2 + z^10; + + Notice that in the above, the ``(z)`` part is mandatory, as it informs + ``\poldef`` of the letter used for the indeterminate. In the above + ``P(z)^2`` would give the same as ``P^2`` but the latter is slightly + more efficient. + + One needs to acquire a good understanding of when the symbol ``P`` + will stand for a function and when it will stand for a variable. + + - If ``P`` and + ``Q`` are both declared polynomials then:: + + (P+Q)(3)% <--- attention, does (P+Q)*3, not P(3)+Q(3) + + is currently evaluated as ``(P+Q)*3``, because ``P+Q`` is not + known as a *function*, but *only as a variable of polynomial + type*. Note that :ref:`evalp(P+Q,3) <evalp>` gives as expected + the same as ``P(3)+Q(3)``. + + - Also:: + + (P)(3)% <--- attention, does P*3, not P(3) + + will compute ``P*3``, because one can not in current xintexpr_ syntax + enclose a function name in parentheses: consequently it is the variable + which is used here. + + There is a *meager possibility* that in future some internal changes + to xintexpr_ would let ``(P)(3)`` actually compute ``P(3)`` and + ``(P+Q)(3)`` compute ``P(3) + Q(3)``, but note that ``(P)(P)`` will + then do ``P(P)`` and not ``P*P``, the latter, current + interpretation, looking more intuitive. Anyway, do not rely too + extensively on tacit ``*`` and use explicit ``(P+Q)*(1+2)`` if this + is what is intended. + + +``\PolLet{g}={f}`` + saves a copy of ``f`` under name ``g``. Also usable without ``=``. + + Has exactly the same effect as ``\poldef g(x):=f;`` or ``\poldef + g(w):=f(w);``\ . + +``\poldef f(z):= f^2;`` + redefines ``f`` in terms of itself. Prior to ``0.8`` one needed + the right hand side to be ``f(z)^2``. Also, now ``sqr(f)`` is + possible (also ``sqr(f(x))`` but not ``sqr(f)(x)``). + + It may look strange that an indeterminate variable is used on + left-hand-side even though it may be absent of right-hand-side, as + it seems to define ``f`` always as a polynomial function. + + This is a legacy of pre-``0.8`` context. + + .. important:: + + Note that ``f^2(z)`` or ``sqr(f)(z)`` will give a logical but + perhaps unexpected result: first ``f^2`` is computed, then the + opening parenthesis is seen which inserts a tacit multiplication + ``*``, so in the end it is as if the input had been ``f^2 * z``. + Although ``f`` is both a variable and a function, ``f^2`` is + computed as a polynomial *variable* and ceases being a function. + +``\poldef f(T):= f(f);`` + again modifies ``f``. Here it is used both as variable and as + a function. Prior to ``0.8`` it needed to be ``f(f(T))``. + +``\poldef k(z):= f-g(g^2)^2;`` + if everybody followed, this should now define the zero polynomial... + And ``f-sqr(g(sqr(g)))`` computes the same thing. + + We can check this in a typeset document like this:: + + \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 + +``\poldef f'(x):= diff1(f);`` + (new at ``0.8``) + +``\PolDiff{f}{f'}`` + Both set ``f'`` (or any other chosen name) to the derivative + of ``f``. + + .. 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 previously defined: something such as + ``f'(3)^2`` will not work without a prior definition of ``f'``. + + But one can now use ``diff1(f)`` for on-the-spot construction with no + permanent declaration, so here ``evalp(diff1(f),3)^2``. And + ``diff1(f)^2`` is same as ``f'^2``, assuming here ``f'`` was declared + to be the derived polynomial. + + Notice that the name ``diff1()`` is experimental and may change. Use + ``\PolDiff{f}{f'}`` as the stable interface. + +``\PolTypeset{P}`` + Typesets (switching to math mode if in text mode):: + + \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'''} $$ + + See `its documentation <PolTypeset_>`_ for the configurability + via macros. + + Since ``0.8`` `\\PolTypeset <PolTypeset_>`_ accepts directly an + expression, it does not have to be a pre-declared polynomial name:: + + \PolTypeset{mul(x-i,i=1..5)} + +``\PolToExpr{P}`` + Expandably (contrarily to `\\PolTypeset <PolTypeset_>`_) + produces ``c_n*x^n + ... + c_0`` starting from the leading + coefficient. The ``+`` signs are omitted if followed by negative + coefficients. + + This is useful for console or file output. This syntax is Maple and + PSTricks ``\psplot[algebraic]`` compatible; and also it is + compatible with ``\poldef`` input syntax, of course. See + `\\PolToExprCaret`_ for configuration of the ``^``, for example to + use rather ``**`` for Python syntax compliance. + + Changed at ``0.8``: the ``^`` in output is by default of catcode 12 + so in a draft document one can use ``\PolToExpr{P}`` inside the + typesetting flow (without requiring math mode, where the ``*`` would + be funny and ``^12`` would only put the ``1`` as exponent anyhow; + but arguably in text mode the ``+`` and ``-`` are not satisfactory + for math, except sometimes in monospace typeface, and anyhow TeX is + unable to break the expression across lines, barring special help). + + See :ref:`\\PolToExpr{\<pol. expr.\>} <PolToExpr>` and related macros for customization. + + Extended at ``0.8`` to accept as argument not only the name of a + polynomial variable but more generally any polynomial expression. + + +Using defined polynomials in floating point context +--------------------------------------------------- + +Exact manipulations with fractional coefficients may quickly lead to +very large denominators. For numerical evaluations, it is advisable +to a use a floating point context. But for the polynomial to be +usable as a function in floating point context, an extra step beyond +``\poldef`` is required: see `\\PolGenFloatVariant`_. Then the +``\xintfloateval`` macro from xintexpr_ will recognize the polynomial +as a genuine function (with already float-rounded coefficients, and +using a Horner scheme). + +But `\\PolGenFloatVariant`_ must be used each time the polynomial gets +redefined or a new polynomial is created out of it. Functions such as +for example :ref:`deg() <deg>` which handle the polynomial as an entity +are only available within the ``\poldef`` and ``\xinteval`` (or +``\xintexpr``) parsers. Inside ``\xintfloateval`` a polynomial can only +serve as a numerical function (and only after declaration via +`\\PolGenFloatVariant`_), and not as a variable. + +In some cases one may wish to replace a polynomial having acquired +very big fractional coefficients with a new one whose coefficients +have been float-rounded. See :ref:`\\PolMapCoeffs <PolMapCoeffs>` +which can be used for example with the ``\xintFloat`` macro from the +xintfrac_ package to achieve this. + + +.. _polexpr08: + +The polexpr ``0.8`` extensions to the ``\xintexpr`` syntax +---------------------------------------------------------- + +All the syntax elements described in this section can be used in the +``\xintexpr/\xinteval`` context (where polynomials can be obtained from +the ``pol([])`` constructor, once polexpr is loaded): their usage is +not limited to only ``\poldef`` context. + +.. note:: + + If a variable ``myPol`` defined via ``\xintdefvar`` turns out + to be a polynomial, the difference with those declared via ``\poldef`` + will be: + + 1. ``myPol`` is not usable as *function*, but only as a variable. + Attention that ``f(x)`` if ``f`` is only a variable (even a + polynomial one) will actually compute ``f * x``. + + 2. ``myPol`` is not known to the polexpr package, hence for example the + macros to achieve localization of its roots are unavailable. + + In a parallel universe I perhaps have implemented this expandably + which means it could then be accessible with syntax such as + ``rightmostroot(pol([42,1,34,2,-8,1]))`` but... + + +Warning about unstability of the new syntax +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. warning:: + + Consider the entirety of this section as **UNSTABLE** and + **EXPERIMENTAL** (except perhaps regarding ``+``, ``-`` and ``*``). + + And this applies even to items not explicitly flagged with one of + **unstable**, **Unstable**, or **UNSTABLE** which only reflect that + documentation was written over a period of time exceeding one minute, + enough for the author mood changes to kick in. + + 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. + + +Infix operators ``+, -, *, /, **, ^`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + As has been explained in the `Syntax overview via examples`_ + section these infix operators have been made polynomial aware, not + only in the ``\poldef`` context, but generally in any + ``\xintexpr/\xinteval`` context, inclusive of ``\xintdeffunc``. + + Conversely functions declared via ``\xintdeffunc`` and making use of + these operators will automatically be able to accept polynomials + declared from ``\poldef`` as variables. + + Usage of ``/`` for euclidean division of polynomials is **deprecated**. + Only in case of a scalar denominator is it to be considered stable. + Please use rather ``quo()``. + +Experimental infix operators ``//, /:`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Here is the tentative behaviour of ``A//B`` according to types: + + - ``A`` non scalar and ``B`` non scalar: euclidean quotient, + + - ``A`` scalar and ``B`` scalar: floored division, + + - ``A`` scalar and ``B`` non scalar: produces zero, + + - ``A`` non scalar and ``B`` scalar: coefficient per + coefficient floored division. + + This is an **experimental** overloading of the ``//`` and ``/:`` + from ``\xintexpr``. + + The behaviour in the last case, but not only, is to be considerd + **unstable**. The alternative would be for ``A//B`` with ``B`` + scalar to act as ``quo(A,B)``. But, we have currently chosen to let + ``//B`` for a scalar ``B`` 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 ``B`` is non-scalar. + + The ``/:`` operator provides the associated remainder so always + ``A`` is reconstructed from ``(A//B)*B + A/:B``. + + If ``:`` is active character use ``/\string:`` (it is safer to use + ``/\string :`` if it is not known if ``:`` has catcode other, letter, + or is active, but note that ``/:`` is fine and needs no precaution if + ``:`` has catcode letter, it is only an active ``:`` which is + problematic, like for all other characters possibly used in an + expression). + + **UNSTABLE** + + As explained above, there are (among other things) hesitations + about behaviour with ``pol2`` a scalar. + +Comparison operators ``<, >, <=, >=, ==, !=`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + **NOT YET IMPLEMENTED** + + As the internal representation by xintfrac_ and xintexpr_ 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 ``\pdfstrcmp`` engine primitive. In fact xintexpr_ does not use + it yet anywhere, even for normalized pure integers, although it could + speed up signifcantly certain aspects of core arithmetic. + + Equality of polynomials can currently be tested by computing the + difference, which is a bit costly. And of course the ``deg()`` + function allows comparing degrees. In this context note the + following syntax:: + + (deg(Q)) ?? { zero } { non-zero scalar } { non-scalar } + + for branching. + + +.. _pol: + +``pol(<nutple expression>)`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + This converts a nutple ``[c0,c1,...,cN]`` into the polynomial + variable having these coefficients. Attention that the square + brackets are **mandatory**, except of course if the argument is + actually an expression producing such a "nutple". + + Currently, this process will not normalize the coefficients (such + as reducing to lowest terms), it only trims out the leading zero + coefficients. + + Inside ``\xintexpr``, this is the only (allowed) way to create ex + nihilo a polynomial variable; inside ``\poldef`` it is an alternative + input syntax which is more efficient than the input ``c0 + c1 * x + c2 * + x^2 + ...``. + +.. important:: + + Whenever an expression with polynomials collapses to a constant, it + becomes a scalar. There is currently no distinction during the + parsing of expressions by ``\poldef`` + or ``\xintexpr`` between constant polynomial variables and scalar + variables. + + Naturally, ``\poldef`` can be used to declare a constant polynomial + ``P``, then ``P`` 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 ``deg()`` tacitly + consider scalars to be constant polynomials). + + Notice that we tend to use the vocable "variable" to refer to + arbitrary expressions used as function arguments, without implying + that we are actually referring to pre-declared variables in the sense + of ``\xintdefvar``. + +.. _lpol: + +``lpol(<nutple expression>)`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + This converts a nutple ``[cN,...,c1,c0]`` into the polynomial + variable having these coefficients, with leading coefficients coming + first in the input. Attention that the square brackets are + **mandatory**, except of course if the argument is actually an + expression producing such a "nutple". + + Currently, this process will not normalize the coefficients (such + as reducing to lowest terms), it only trims out the leading zero + coefficients. + + **NAME UNSTABLE** + + It can be used in ``\poldef`` as an alternative input syntax, which + is more efficient than using the algebraic notation with monomials. + + (new with ``0.8.1``, an empty nutple will cause breakage) + +.. _xintevalpolexpr: + +``\xinteval{<pol. expr.>}`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + This is documented here for lack of a better place: it evaluates the + polynomial expression then outputs the "string" ``pol([c0, c1, ..., cN])`` + if the degree ``N`` is at least one (and the usual scalar output else). + + The "pol" 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 ``\poldef`` or ``\xintexpr`` at it means basically + executing ``pol(coeffs(..expression..))`` which is but a convoluted + way to obtain the same result as ``(..expression..)`` (the + parentheses delimiting the polynomial expression). + + For example, ``\xinteval{(1+pol([0,1]))^10}`` expands (in two steps) + to:: + + pol([1, 10, 45, 120, 210, 252, 210, 120, 45, 10, 1]) + + You do need loading polexpr for this, else of course ``pol([])`` + remains unknown to ``\xinteval{}`` as well as the polynomial algebra ! + This example can also be done as + ``\xinteval{subs((1+x)^10,x=pol([0,1]))}``. + + I hesitated using as output the polynomial notation as produced by + `\\PolToExpr{} <poltoexpr_>`_, but finally opted for this. + +.. _evalp: + +``evalp(<pol. expr.>, <pol. expr>)`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Evaluates the first argument as a polynomial function of the + second. Usually the second argument will be scalar, but this is not + required:: + + \poldef K(x):= evalp(-3x^3-5x+1,-27x^4+5x-2); + + If the first argument is an already declared polynomial ``P``, use + rather the functional form ``P()`` (which can accept a numerical as + well as polynomial argument) as it is more efficient. + + One can also use ``subs()`` syntax [#]_ (see xintexpr_ documentation):: + + \poldef K(x):= subs(-3y^3-5y+1, y = -27x^4+5x-2); + + but the ``evalp()`` will use a Horner evaluation scheme which is + usually more efficient. + + .. [#] by the way Maple uses the opposite, hence wrong, order + ``subs(x=..., P)`` but was written before computer science + reached the xintexpr_ heights. However it makes validating + Maple results by polexpr sometimes cumbersome, but perhaps + they will update it at some point. + + .. + + **name unstable** + + ``poleval``? ``evalpol``? ``peval``? ``evalp``? ``value``? + ``eval``? ``evalat``? ``eval1at2``? ``evalat2nd``? + + Life is so complicated when one asks questions. Not everybody does, + though, as is amply demonstrated these days. + + **syntax unstable** + + I am hesitating about permuting the order of the arguments. + +.. _deg: + +``deg(<pol. expr.>)`` +~~~~~~~~~~~~~~~~~~~~~ + + Computes the degree. + +.. important:: + + As ``\xintexpr`` does not yet support infinities, the degree of + the zero polynomial is ``-1``. Beware that this breaks additivity + of degrees, but ``deg(P)<0`` correctly detects the zero polynomial, + and ``deg(P)<=0`` detects scalars. + +``coeffs(<pol. expr.>)`` +~~~~~~~~~~~~~~~~~~~~~~~~ + + Produces the nutple ``[c0,c1,...,cN]`` of coefficients. The highest + degree coefficient is always non zero (except for the zero + polynomial...). + + **name unstable** + + I am considering in particular using ``polcoeffs()`` to avoid + having to overload ``coeffs()`` in future when matrix type + will be added to xintexpr_. + +.. _lcoeffs: + +``lcoeffs(<pol. expr.>)`` +~~~~~~~~~~~~~~~~~~~~~~~~~ + + Produces the nutple ``[cN,....,c1,c0]`` of coefficients, starting + with the highest degree coefficient. + + (new with ``0.8.1``) + +``coeff(<pol. expr.>, <num. expr.>)`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + As expected. Produces zero if the numerical index is negative or + higher than the degree. + + **name, syntax and output unstable** + + I am hesitating with ``coeff(n,pol)`` syntax and also perhaps using + ``polcoeff()`` in order to avoid having to overload ``coeff()`` + when matrix type will be added to xintexpr_. + + The current behaviour is at odds with legacy + :ref:`\\PolNthCoeff{\<polname\>}{\<index\>} <PolNthCoeff>` regarding negative indices. + Accessing leading or sub-leading coefficients can be done with + other syntax, see `lc(<pol. expr.>)`_, and in some contexts it + is useful to be able to rely on the fact that coefficients with + negative indices do vanish, so I am for time being maintaining this. + +.. _lc: + +``lc(<pol. expr.>)`` +~~~~~~~~~~~~~~~~~~~~ + + The leading coefficient. The same result can be obtained from + ``coeffs(pol)[-1]``, which shows also how to generalize to access + sub-leading coefficients. See the xintexpr_ documentation for + Python-like indexing syntax. + +``monicpart(<pol. expr.>)`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Divides by the leading coefficient, except that ``monicpart(0)==0``. + + **unstable** + + Currently the coefficients are reduced to lowest terms (contrarily + to legacy behaviour of `\\PolMakeMonic <polmakemonic_>`_), and + additionally the xintfrac_ ``\xintREZ`` 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. + +.. _cont: + +``cont(<pol. expr.>)`` +~~~~~~~~~~~~~~~~~~~~~~ + + The (fractional) greatest common divisor of the 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. + + .. commentaire 8 avril 2021 + + surprenamment après avoir utilisé `\\PolIContent <PolIContent_>`_ + une fois on peut utiliser `\\PolIContent`_ directement. + + avec docutils 0.16 + + .. + + **name and syntax unstable** + + At ``0.8`` it was created as ``icontent()`` to match the legacy + macro `\\PolIContent <PolIContent_>`_, whose name in 2018 was + chosen in relation to Maple's function ``icontent()``, possibly + because at that time I had not seen that Maple also had a + ``content()`` function. Name changed at ``0.8.1``. + + It will change syntax if in future multivariate polynomials are + supported, and ``icontent()`` will then make a come-back. + +``primpart(<pol. expr.>)`` +~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The quotient (except for the zero polynomial) by + ``cont(<pol. expr.>)``. This is thus a polynomial with + integer coefficients having ``1`` as greatest common divisor. The + sign of the leading coefficient is the same as in the original. + + And ``primpart(0)==0``. + + The trailing zeros of the integer coefficients are extracted + into a power of ten exponent part, in the internal representation. + +``quorem(<pol. expr.>, <pol. expr.>)`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Produces a nutple ``[Q,R]`` with ``Q`` the euclidean quotient and + ``R`` the remainder. + + **name unstable** + + ``poldiv()``? + +``quo(<pol. expr.>, <pol. expr.>)`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The euclidean quotient. + + The deprecated ``pol1/pol2`` syntax computes the same polynomial. + +``rem(<pol. expr.>, <pol. expr.>)`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The euclidean remainder. If ``pol2`` is a (non-zero) scalar, this is + zero. + + There is no infix operator associated to this, for lack of evident + notation. Please advise. + + ``/:`` can be used if one is certain that ``pol2`` is of + degree at least one. But read the warning about it being unstable + even in that case. + +.. not implemented + + ``spquorem(pol1,pol2)`` + ~~~~~~~~~~~~~~~~~~~~~~~ + + Produces a tuple ``[Q,R]`` with the pseudo-quotient and + pseudo-remainder. See `prem(pol1, pol2) <prem_>`_ for + their definitions. + + **NOT IMPLEMENTED** + + I am hesitating returning rather the nutple ``[b^f, Q, R]`` or + ``[f, Q, R]``. Note that the number of non-zero coefficients of + a polynomial ``P`` can be computed as ``add(?(c),c=coeffs(P))``, + and in this context I am hesitating abstracting a function to + provide this [#]_. The usual problem is that I don't know how to + name the function. + + I am also hesitating providing rather a function returning only + ``f`` and ``R``, not ``Q``, which for modular computations we don't + need to carry along. + + .. [#] one can embed ``\xintiiexpr add(?(c),c=coeffs(P))\relax`` + inside ``\xintexpr`` and it will be more efficient for long + polynomials, but naturally a core implementation using a + single ``\numexpr`` would be quite more efficient still. + +.. _prem: + +``prem(<pol. expr. 1>, <pol. expr. 2>)`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Produces a nutple ``[m, spR]`` where ``spR`` is the (special) pseudo + Euclidean remainder. Its description is: + + - the standard euclidean remainder ``R`` is ``spR/m`` + + - ``m = b^f`` with ``b`` equal to the **absolute value** of the + leading coefficient of ``pol2``, + + - ``f`` is the number of non-zero coefficients in the euclidean + quotient, if ``deg(pol2)>0`` (even if the remainder vanishes). + + If ``pol2`` is a scalar however, the function outputs ``[1,0]``. + + With these definitions one can show that if both ``pol1`` and + ``pol2`` have integer coefficients, then this is also the case of + ``spR``, which makes its interest (and also ``m*Q`` has integer + coefficients, with ``Q`` the euclidean quotient, if ``deg(pol2)>0``). + Also, ``prem()`` is computed faster than ``rem()`` for such integer + coefficients polynomials. + + .. hint:: + + If you want the euclidean quotient ``R`` evaluated via ``spR/m`` + (which may be faster, even with non integer coefficients) use + ``subs(last(x)/first(x),x=prem(P,Q))`` syntax as it avoids + computing ``prem(P,Q)`` twice. This does the trick both in + ``\poldef`` or in ``\xintdefvar``. + + However, as is explained in the xintexpr_ documentation, using + such syntax in an ``\xintdeffunc`` is (a.t.t.o.w) illusory, due to + technicalities of how ``subs()`` gets converted into nested + expandable macros. One needs an auxiliary function like this:: + + \xintdeffunc lastoverfirst(x):=last(x)/first(x); + \xintdeffunc myR(x)=lastoverfirst(prem(x)); + + Then, ``myR(pol1,pol2)`` will evaluate ``prem(pol1,pol2)`` only + once and compute a polynomial identical to the euclidean + remainder (internal representations of coefficients may differ). + + 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 ``pol1`` and ``pol2`` (no automatic reduction to + lowest terms is made prior or after computation). + + Pay attention here that ``b`` is the **absolute value** of the + leading coefficient of ``pol2``. 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. + + +``divmod(<pol. expr. 1>, <pol. expr. 2>)`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Overloads the scalar ``divmod()`` and associates it with the + experimental ``//`` and ``/:`` as extended to the polynomial type. + + In particular when both ``pol1`` and ``pol2`` are scalars, this is + the usual ``divmod()`` (as in Python) and for ``pol1`` and ``pol2`` + non constant polynomials, this is the same as ``quorem()``. + + **Highly unstable** overloading of ``\xinteval``\ 's ``divmod()``. + +``mod(<pol. expr. 1>, <pol. expr. 2>)`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The ``R`` of the ``divmod()`` output. Same as ``R`` of ``quorem()`` + when the second argument ``pol2`` is of degree at least one. + + **Highly unstable** overloading of ``\xinteval``\ 's ``mod()``. + +``polgcd(<pol. expr. 1>, <pol. expr. 2>, ...)`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Evaluates to the greatest common polynomial divisor of all the + polynomial inputs. The output is a **primitive** (in particular, + with integer coefficients) polynomial. It is zero if and only if all + inputs vanish. + + 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 "nutple" whose + items are polynomials (see the documentation of the scalar ``gcd()`` + in xintexpr_). + + The two variable case could (and was, during development) have been + defined at user level like this:: + + \xintdeffunc polgcd_(P,Q):= + (deg(Q))??{P}{1}{polgcd_(Q,primpart(last(prem(P,Q))))}; + \xintdeffunc polgcd(P,Q):=polgcd_(primpart(P),primpart(Q));% + + This is basically what is done internally for two polynomials, up + to some internal optimizations. + + **UNSTABLE** + + I hesitate between returning a *primitive* or a *monic* polynomial. + Maple returns a primitive polynomial if all inputs [#]_ 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. + + 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 ``monicpart()`` to it. + + Attention that this is at odds with behaviour of the legacy + `\\PolGCD <PolGCD_>`_ (non expandable) macro. + + .. [#] actually, only two polynomial arguments are allowed by Maple's + ``gcd()`` as far as I know. + +``resultant(<pol. expr. 1>, <pol. expr. 2>)`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The resultant. + + **NOT YET IMPLEMENTED** + +``disc(<pol. expr.>)`` +~~~~~~~~~~~~~~~~~~~~~~ + + The discriminant. + + **NOT YET IMPLEMENTED** + +``polpowmod(<pol. expr. 1>, <num. expr.>, <pol. expr. 2>)`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Modular exponentiation: ``mod(pol1^N, pol2)`` in a more efficient + manner than first computing ``pol1^N`` then reducing modulo ``pol2``. + + Attention that this is using the ``mod()`` operation, whose current + experimental status is as follows: + + - if ``deg(pol2)>0``, the euclidean remainder operation, + - if ``pol2`` is a scalar, coefficient-wise reduction modulo ``pol2``. + + + **UNSTABLE** + + This is currently implemented at high level via ``\xintdeffunc`` and + recursive definitions, which were copied over from a scalar example + in the xintexpr_ manual:: + + \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};% + + Negative exponents are not currently implemented. + + For example:: + + \xinteval{subs(polpowmod(1+x,100,x^7),x=pol([0,1]))} + \xinteval{subs(polpowmod(1+x,20,10), x=pol([0,1]))} + + produce respectively:: + + 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]) + +.. perte de temps terrible pourquoi j'écris cela + When ``pol2`` is as scalar then the degrees of the modular powers + ``mod(pol1^N, pol2)`` will in general increase linearly in ``N`` + hence become big. But one can play with modifying the above + template and nesting two ``mod()``, one with an integer modulus, + say ``7``, and the other the a monic integer coefficients + polynomial such as ``Q = x^2+1``. Then an integer coefficients + polynomial ``P`` will have an integer coefficient remainder modulo + ``Q``, and + +.. _rdcoeffs: + +``rdcoeffs(<pol. expr.>)`` +~~~~~~~~~~~~~~~~~~~~~~~~~~ + + This operates on the internal representation of the coefficients, + reducing them to lowest terms. + + **name HIGHLY undecided** + +``rdzcoeffs(<pol. expr.>)`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + 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. + + This is sometimes favourable to more efficient polynomial algebra + computations. + + **name HIGHLY undecided** + +``diff1(<pol. expr.>)`` +~~~~~~~~~~~~~~~~~~~~~~~ + + The first derivative. + + **name UNSTABLE** + + This name may be used in future to be the partial derivative with + respect to a first variable. + +``diff2(<pol. expr.>)`` +~~~~~~~~~~~~~~~~~~~~~~~ + + The second derivative. + + **name UNSTABLE** + + This name may be used in future to be the partial derivative with + respect to a second variable. + + +``diffn(<pol. expr. P>, <num. expr. n>)`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The ``n``\ th derivative of ``P``. For ``n<0`` computes iterated primitives + vanishing at the origin. + + The coefficients are not reduced to lowest terms. + + **name and syntax UNSTABLE** + + I am also considering reversing the order of the arguments. + +``antider(<pol. expr. P>)`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The primitive of ``P`` with no constant term. Same as ``diffn(P,-1)``. + +``intfrom(<pol. expr. P>, <pol. expr. c>)`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The primitive of ``P`` vanishing at ``c``, i.e. ``\int_c^x P(t)dt``. + + Also ``c`` can be a polynomial... so if ``c`` is monomial ``x`` + this will give zero! + + **UNSTABLE** + + Allowing general polynomial variable for ``c`` adds a bit of + overhead to the case of a pure scalar. So I am hesitating + maintaining this feature whose interest appears dubious. + + .. attention:: + + As the two arguments are both allowed to be polynomials, if by + inadvertance one exchanges the two, there is no error but the + meaning of ``intfrom(c,P)`` is completely otherwise, as it + produces ``c*(x - P)`` if ``c`` is a scalar:: + + >>> &pol + pol mode (i.e. function definitions use \poldef) + >>> P(x):=1+x^2; + P = x^2+1 + --> &GenFloat(P) lets P become usable as function in fp mode + --> &ROOTS(P) (resp. &ROOTS(P,N)) finds all rational roots exactly and + all irrational roots with at least 10 (resp. N) fractional digits + >>> intfrom(P,1); + @_1 pol([-4/3, 1, 0, 1/3]) + >>> intfrom(1,P); + @_2 pol([-1, 1, -1]) + >>> &bye + + + +.. grosse hésitation ici + + ``intto(<pol. expr. P>, <pol. expr. c>)`` + ----------------------------------------- + + ``\int_x^c P(t)dt``. + + c'est l'opposé du précédent + + mais le nom pourrait faire penser à \int_0^x plutôt + +``integral(<pol. expr. P>, [<pol. expr. a>, <pol. expr. b>])`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + ``\int_a^b P(t)dt``. + + .. warning:: + + The brackets here are not denoting an optional argument but a + *mandatory* nutple argument ``[a, b]`` with *two items*. No real + recoverable-from error check is done on the input syntax. The + input can be an xintexpr_ variable which happens to be a nutple + with two items, or any expression which evaluates to such a + nutple. + + ``a`` and ``b`` are not restricted to be scalars, they are allowed to + be themselves polynomial variables or even polynomial expressions. + + To compute ``\int_{x-1}^x P(t)dt`` it is more efficient to use + ``intfrom(x-1)``. + + Similary to compute ``\int_x^{x+1} P(t)dt``, use ``-intfrom(x+1)``. + + **UNSTABLE** + + Am I right to allow general polynomials ``a`` and ``b`` hence add + overhead to the pure scalar case ? + + + +Non-expandable macros +--------------------- + +.. note:: + + At ``0.8`` ``polexpr`` is usable with Plain TeX and not only with + LaTeX. Some examples given in this section may be using LaTeX syntax + such as ``\renewcommand``. + +.. _poldef;: + +``\poldef polname(letter):= expression using the letter as indeterminate;`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + This evaluates the *polynomial expression* and stores the + coefficients in a private structure accessible later via other + package macros, used with argument ``polname``. Of course the + *expression* can make use of previously defined polynomials. + + Polynomial names must start with a letter and are constituted of + letters, digits, underscores and the right tick ``'``. + + The whole xintexpr_ syntax is authorized, as long as the final + result is of polynomial type:: + + \poldef polname(z) := add((-1)^i z^(2i+1)/(2i+1)!, i = 0..10); + + With fractional coefficients, beware the `tacit multiplication issue + <warningtacit_>`_. + + Furthermore: + + - a variable ``polname`` is defined which can be used in ``\poldef`` + as well as in ``\xinteval`` for algebraic computations or as + argument to polynomial aware functions, + + - a function ``polname()`` is defined which can be used in ``\poldef`` + as well as in ``\xinteval``. It accepts there as argument scalars + and also other polynomials (via their names, thanks to previous + item). + + Notice that any function defined via ``\xintdeffunc`` and using + only algebraic operations (and ople indexing or slicing operations) + should work fine in ``\xintexpr/\xinteval`` with such polynomial + names as argument. + + In the case of a constant polynomial, the xintexpr_ 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 ``cos()`` function). + + The *function* on the other hand remains a one-argument function, + which simply has a constant value. + + .. attention:: + + The function ``polname()`` is defined **only** for + ``\xintexpr/\xinteval`` + context. It will be unknown to ``\xintfloateval``. + + 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 ``\poldef`` or ``\PolDef`` but + as result of usage of the other package macros. + + See :ref:`\\PolGenFloatVariant{\<polname\>} <PolGenFloatVariant>` to generate a **function** + usable in ``\xintfloateval``. + + .. attention:: + + Using the **variable** ``mypol`` inside ``\xintfloateval`` will + generate low-level errors because the infix operators there are + not polynomial-aware, and the polynomial specific functions such + as ``deg()`` are only defined for usage inside ``\xintexpr``. + + In short, currently polynomials defined via ``polexpr`` can + be used in floating point context only for numerical evaluations, + via **functions** obtained from :ref:`\\PolGenFloatVariant{\<polname\>} <PolGenFloatVariant>` + usage. + + 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. + + 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. + +.. _PolDef: + +``\PolDef[<letter>]{<polname>}{<expr. using the letter as indeterminate>}`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Does the same as `\\poldef <poldef;_>`_ in an undelimited macro + format, the main interest is to avoid potential problems with the + catcode of the semi-colon in presence of some packages. In absence + of a ``[<letter>]`` optional argument, the variable is assumed to be + ``x``. + + +.. _PolGenFloatVariant: + +``\PolGenFloatVariant{}`` +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Syntax: ``\PolGenFloatVariant{<polname>}`` + + Makes the polynomial also usable in the + ``\xintfloatexpr/\xintfloateval`` parser. It will therein evaluates + via an Horner scheme using polynomial coefficients already + pre-rounded to the float precision. + + See also :ref:`\\PolToFloatExpr{\<pol. expr.\>} <PolToFloatExpr>`. + + .. attention:: + + 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 ``\xintfloateval``. + +.. _PolTypeset: + +``\PolTypeset{}`` +~~~~~~~~~~~~~~~~~ + +Syntax: ``\PolTypeset{<pol. expr.>}`` + + Typesets in descending powers, switching to math mode if in text + mode, after evaluating the polynomial expression:: + + \PolTypeset{mul(x-i,i=1..5)}% possible since polexpr 0.8 + + The letter used in the input expression is by default ``x``, + but can be modified by a redefinition of `\\PolToExprInVar`_. + + It uses also by default the letter ``x`` on output but this one can + be changed via an optional argument:: + + \PolTypeset[z]{polname or polynomial expression} + + By default zero coefficients are skipped (use ``\poltypesetalltrue`` + to get all of them in output). + + 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. + +.. _PolTypesetCmd: + +``\PolTypesetCmd{}`` +^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\PolTypesetCmd{<raw_coeff>}`` + + Its package definition checks if the coefficient is ``1`` or ``-1`` + and then skips printing the ``1``, except for the coefficient of + degree zero. Also it sets the conditional deciding behaviour of + :ref:`\\PolIfCoeffIsPlusOrMinusOne{T}{F} <PolIfCoeffIsPlusOrMinusOne>`. + + The actual printing of the coefficients, when not equal to plus or + minus one, is handled by :ref:`\\PolTypesetOne{\<raw_coeff\>} <PolTypesetOne>`. + +.. _PolIfCoeffIsPlusOrMinusOne: + +``\PolIfCoeffIsPlusOrMinusOne{}{}`` +*********************************** + +Syntax: ``\PolIfCoeffIsPlusOrMinusOne{T}{F}`` + + This macro is a priori undefined. + + It is defined via the default :ref:`\\PolTypesetCmd{\<raw_coeff\>} <PolTypesetCmd>` 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 ``T`` if the coefficient has been found to be + plus or minus one, and ``F`` if not. It chooses expandably between + ``T`` and ``F``. + +.. _PolTypesetOne: + +``\PolTypesetOne{}`` +^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\PolTypesetOne{<raw_coeff>}`` + + Defaults to ``\xintTeXsignedFrac`` (LaTeX) or ``\xintTeXsignedOver`` + (else). But these xintfrac_ old legacy macros are a bit + annoying as they insist in exhibiting a power of ten rather than + using simpler decimal notation. + + As alternative, one can do definitions such as:: + + \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}}} + +.. _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{}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\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 + ``\xintTeXsignedFrac`` (or ``\xintTeXsignedOver``) used by + :ref:`\\PolTypesetCmd{\<raw_coeff\>} <PolTypesetCmd>` 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*{}`` +~~~~~~~~~~~~~~~~~~ + +Syntax: ``\PolTypeset*{<pol. expr.>}`` + + Typesets in ascending powers. Use ``[<letter>]`` optional argument + (after the ``*``) to use another letter than ``x``. + + Extended at ``0.8`` to accept general expressions and not only + polynomial names. Redefine `\\PolToExprInVar`_ to use in the + expression another letter than default ``x``. + + +.. _PolLet: + +``\PolLet{}={}`` +~~~~~~~~~~~~~~~~ + +Syntax: ``\PolLet{<polname_2>}={<polname_1>}`` + + Makes a copy of the already defined polynomial ``polname_1`` to a + new one ``polname_2``. This has the same effect as + ``\PolDef{<polname_2>}{<polname_1>(x)}`` or (better) + ``\PolDef{<polname_2>}{<polname_1>}`` but with less overhead. The + ``=`` is optional. + +.. _PolGlobalLet: + +``\PolGlobalLet{}={}`` +~~~~~~~~~~~~~~~~~~~~~~ + +Syntax: ``\PolGlobalLet{<polname_2>}={<polname_1>}`` + + Acts globally. + +.. _PolAssign: + +``\PolAssign{}\toarray{}`` +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Syntax: ``\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. This is + an unfortunate legacy situation related to the original indexing + convention in xinttools_ arrays. + + - 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 :ref:`\\PolNthCoeff{\<polname\>}{\<index\>} <PolNthCoeff>`. + +.. _PolGet: + +``\PolGet{}\fromarray{}`` +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Syntax: ``\PolGet{<polname>}\fromarray{<\macro>}`` + + Does the converse operation to + ``\PolAssign{<polname>}\toarray\macro``. Each individual + ``\macro{<value>}`` 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;``. + + .. vieux commentaire + + Prior to ``0.5``, coefficients were not normalized via + ``\xintRaw`` for internal storage. + +.. _PolFromCSV: + +``\PolFromCSV{}{}`` +~~~~~~~~~~~~~~~~~~~ + +Syntax: ``\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 :ref:`\\PolToCSV{\<polname\>} <PolToCSV>`. + + .. vieux commentaire + + Prior to ``0.5``, coefficients were not normalized via + ``\xintRaw`` for internal storage. + + +.. _PolMapCoeffs: + +``\PolMapCoeffs{}{}`` +~~~~~~~~~~~~~~~~~~~~~ + +Syntax: ``\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 the replacement text of ``\macro``, ``\index`` expands to the + coefficient index (starting at zero for the constant term). + + Notice that ``\macro`` will have to handle inputs in the xintfrac_ + internal format. This means that it probably will have to be + expressed in terms of macros from the 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{}`` +~~~~~~~~~~~~~~~~~~~~~~ + +Syntax: ``\PolReduceCoeffs{<polname>}`` + + Reduces the internal representations of the coefficients to + their lowest terms. + +.. _PolReduceCoeffs*: + +``\PolReduceCoeffs*{}`` +~~~~~~~~~~~~~~~~~~~~~~~ + +Syntax: ``\PolReduceCoeffs*{<polname>}`` + + Reduces the internal representations of the coefficients to their + lowest terms, but ignoring a possible separated "power of ten part". + + For example, xintfrac_ stores an ``30e2/50`` input as ``30/50`` with + a separate ``10^2`` part. This will thus get replaced by ``3e^2/5`` + (or rather whatever xintfrac_ uses for internal representation), and + not by ``60`` as would result from complete reduction. + + Evaluations with polynomials treated by this can be much faster than + with those handled by the non-starred variant + :ref:`\\PolReduceCoeffs{\<polname\>} <PolReduceCoeffs>`: as the numerators and denominators + remain generally smaller. + +.. _PolMakeMonic: + +``\PolMakeMonic{}`` +~~~~~~~~~~~~~~~~~~~ + +Syntax: ``\PolMakeMonic{<polname>}`` + + Divides by the leading coefficient. It is recommended to execute + :ref:`\\PolReduceCoeffs*{\<polname\>} <PolReduceCoeffs*>` immediately afterwards. This is not + done automatically, in case the original polynomial had integer + coefficients and the user wants to keep the leading one as common + denominator for typesetting purposes. + +.. _PolMakePrimitive: + +``\PolMakePrimitive{}`` +~~~~~~~~~~~~~~~~~~~~~~~ + +Syntax: ``\PolMakePrimitive{<polname>}`` + + Divides by the integer content see (`\\PolIContent`_). + This thus produces a polynomial with integer + coefficients having no common factor. The sign of the leading + coefficient is not modified. + +.. _PolDiff: + +``\PolDiff{}{}`` +~~~~~~~~~~~~~~~~ + +Syntax: ``\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[]: + +``\PolDiff[]{}{}`` +~~~~~~~~~~~~~~~~~~ + +Syntax: ``\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{}{}`` +~~~~~~~~~~~~~~~~~~~~ + +Syntax: ``\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[]: + +``\PolAntiDiff[]{}{}`` +~~~~~~~~~~~~~~~~~~~~~~~ + +Syntax: ``\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{}{}{}{}`` +~~~~~~~~~~~~~~~~~~~~~~ + +Syntax: ``\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{}{}{}`` +~~~~~~~~~~~~~~~~~ + +Syntax: ``\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{}{}{}`` +~~~~~~~~~~~~~~~~~ + +Syntax: ``\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{}{}{}`` +~~~~~~~~~~~~~~~~~ + +Syntax: ``\PolGCD{<polname_1>}{<polname_2>}{<polname_GCD>}`` + + This sets ``polname_GCD`` to be the (monic) GCD of ``polname_1`` + and ``polname_2``. 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). + + +Root localization routines via the `Sturm Theorem`_ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As :ref:`\\PolToSturm{\<polname\>}{\<sturmname\>} <PolToSturm>` and +:ref:`\\PolSturmIsolateZeros{\<sturmname\>} <PolSturmIsolateZeros>` and variants declare +additional polynomial or scalar variables with names based on ``<sturmname>`` as +prefix, it is advisable to keep the ``<sturmname>`` namespace separate from +the one applying to ``\xintexpr`` variables generally, or to polynomials. + +.. _PolToSturm: + +``\PolToSturm{}{}`` +^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\PolToSturm{<polname>}{<sturmname>}`` + + With ``<polname>`` being for example ``P``, and ``<sturmname>`` being + for example ``S``, the macro starts by computing the derivative + ``P'``, then computes the opposite of the remainder in the euclidean + division of ``P`` by ``P'``, then the opposite of the remainder in + the euclidean division of ``P'`` by the first obtained polynomial, + etc... Up to signs following the ``--++--++...`` pattern, these are + the same remainders as in the Euclide algorithm applied to the + computation of the GCD of ``P`` and ``P'``. + + The precise process differs from the above description: the + algorithm first sets ``S_0_`` to be the *primitive part* of ``P`` + and ``S_1_`` to be the *primitive part* of ``P'`` (see + :ref:`\\PolIContent{\<polname\>} <PolIContent>`), then at each step + the remainder is made primitive and stored for internal reference as + ``S_k_``, so only integer-coefficients polynomials are manipulated. + + .. warning:: + + This exact procedure will perhaps in future be replaced by a + *sub-resultant algorithm*, which may bring some speed gain in + obtaining a pseudo-Sturm sequence, but some experimenting is + needed, in the context of realistically realizable computations + by the package; primitive polynomials although a bit costly + have the smallest coefficients hence are the best for the kind of + computations done for root localization, after having computed a + Sturm sequence. + + The last non-zero primitivized remainder ``S_N_`` is, up to sign, + the primitive part of the GCD of ``P`` and ``P'``. Its roots (real + and complex) are the multiple roots of the original ``P``. The + original ``P`` was "square-free" (i\.e\. did not have multiple real + or complex roots) if and only if ``S_N_`` is a constant, which is + then ``+1`` or ``-1`` (its value before primitivization is lost). + + The macro then divides each ``S_k_`` by ``S_N_`` and declares the + quotients ``S_k`` as user polynomials for future use. By Gauss + theorem about the contents of integer-coefficients polynomials, + these ``S_k`` also are primitive integer-coefficients polynomials. + + This step will be referred to as *normalization*, and in this + documentation the obtained polynomials are said to constitute the + "Sturm chain" (or "Sturm sequence"), i.e. by convention the "Sturm + chain polynomials" are square-free and primitive. The possibly + non-square-free ones are referred to as *non-normalized*. + + As an exception to the rule, if the original ``P`` was "square-free" + (i\.e\. did not have multiple real or complex roots) then + normalization is skipped (in that case ``S_N_`` is either ``+1`` or + ``-1``), so ``S_0_`` is exactly the primitive part of starting + polynomial ``P``, in the "square-free" case. + + The next logical step is to execute `\\PolSturmIsolateZeros{S} + <PolSturmIsolateZeros_>`_ or one of its variants. Be careful not to + use the names ``sturmname_0``, ``sturmname_1``, etc... for defining + other polynomials after having done + ``\PolToSturm{<polname>}{<sturmname>}`` and before executing + ``\PolSturmIsolateZeros{<sturmname>}`` or its variants else the + latter will behave erroneously. + + .. note:: + + The declaration of the ``S_k``\ 's will overwrite + with no warning previously declared polynomials with identical + names ``S_k``. This is original reason why the macro expects two + names: ``<polname>`` and ``<sturmname>``. + + It is allowed to use the polynomial name ``P`` as Sturm chain + name ``S``: ``\PolToSturm{f}(f}``, but of course fusing the + namespaces is slightly dangerous. And, also `\\PolSturmIsolateZeros + <PolSturmIsolateZeros_>`_ creates variables sharing + the ``<sturmname>`` prefix, which must be taken into account to + avoid name clashes. + + .. warning:: + + The reason why the ``S_k``\ 's are declared as polynomials is + that the associated polynomial functions are needed to compute + the sign changes in the Sturm sequence evaluated at a given + location, as this is the basis mechanism of `\\PolSturmIsolateZeros + <PolSturmIsolateZeros_>`_ (on the basis of the `Sturm theorem`_). + + It is possible that in future the package will only internally + construct such polynomial functions and only the starred variant + will make the normalized (i.e. square-free) Sturm sequence public. + + The integer ``N`` giving the length of the Sturm chain ``S_0``, + ``S_1``, ..., ``S_N`` is available as + :ref:`\\PolSturmChainLength{\<sturmname\>} <PolSturmChainLength>`. If all roots of original ``P`` + are real, then ``N`` is both the number of distinct real roots and + the degree of ``S_0``. In the case of existence of complex roots, + the number of distinct real roots is at most ``N`` and ``N`` is at + most the degree of ``S_0``. + +.. _PolToSturm*: + +``\PolToSturm*{}{}`` +^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\PolToSturm*{<polname>}{<sturmname>}`` + + Does the same as `un-starred version <PolToSturm_>`_ and additionally it + keeps for user usage the memory of the *un-normalized* (but still + made primitive) Sturm chain + polynomials ``sturmname_k_``, ``k=0,1, ..., N``, with + ``N`` being :ref:`\\PolSturmChainLength{\<sturmname\>} <PolSturmChainLength>`. + + .. comment + + The square-free part of ``<polname>`` is ``sturmname_0``, and their + quotient is the polynomial with name + ``sturmname_\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. + +.. _PolSturmIsolateZeros: + +``\PolSturmIsolateZeros{}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\PolSturmIsolateZeros{<sturmname>}`` + + The macro locates, using the `Sturm Theorem`_, as many disjoint + intervals as there are distinct real roots. + + .. important:: + + The Sturm chain must have been produced by an earlier + :ref:`\\PolToSturm{\<polname\>}{\<sturmname\>} <PolToSturm>`. + + 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 :ref:`\\PolRefineInterval*{\<sturmname\>}{\<index\>} <PolRefineInterval*>` which addresses + this issue. + + .. This procedure is covariant + with the independent variable ``x`` becoming ``-x``. + Hmm, pas sûr et trop fatigué + + Let us suppose ``<sturmname>`` is ``S``. + + The interval boundaries (and exactly found roots) are made available + for future computations in ``\xintexpr/xinteval`` or ``\poldef`` as + variables ``SL_1``, ``SL_2``, etc..., for the left end-points and + ``SR_1``, ``SR_2``, ..., for the right end-points. + + Additionally, xintexpr_ variable ``SZ_1_isknown`` will have value + ``1`` if the root in the first interval is known, and ``0`` + otherwise. And similarly for the other intervals. + + .. important:: + + The variable declarations are done with no check of existence of + previously existing variables with identical names. + + Also, macros :ref:`\\PolSturmIsolatedZeroLeft{\<sturmname\>}{\<index\>} <PolSturmIsolatedZeroLeft>` and + :ref:`\\PolSturmIsolatedZeroRight{\<sturmname\>}{\<index\>} <PolSturmIsolatedZeroRight>` are provided which + expand to these same values, written in decimal notation (i.e. + pre-processed by `\\PolDecToString <PolDecToString_>`_.) And there + is also :ref:`\\PolSturmIfZeroExactlyKnown{\<sturmname\>}{\<index\>}{T}{F} <PolSturmIfZeroExactlyKnown>`. + + .. 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, so as to be able for example to + print out bounds of real roots with as many digits as is + significant, even if the digits are zeros. + + The start of the decimal expansion of the ``<index>``-th root is given by + `\\PolSturmIsolatedZeroLeft{<sturmname>}{<index>} + <PolSturmIsolatedZeroLeft_>`_ if the root is positive, and by + `\PolSturmIsolatedZeroRight{<sturmname>}{<index>} + <PolSturmIsolatedZeroRight_>`_ if the root is neagtive. These two + decimal numbers are either both zero or both of the same sign. + + The number of distinct roots is obtainable expandably as + :ref:`\\PolSturmNbOfIsolatedZeros{\<sturmname\>} <PolSturmNbOfIsolatedZeros>`. + + Furthermore + :ref:`\\PolSturmNbOfRootsOf{\<sturmname\>}\\LessThanOrEqualTo{\<value\>} <PolSturmNbOfRootsOfLessThanOrEqualTo>` and + :ref:`\\PolSturmNbOfRootsOf{\<sturmname\>}\\LessThanOrEqualToExpr{\<num. expr.\>} <PolSturmNbOfRootsOfLessThanOrEqualToExpr>`. + will expandably compute respectively the number of real roots at + most equal to ``value`` or ``expression``, and the same but with + multiplicities. + + These variables and macros are automatically updated in case of + subsequent usage of :ref:`\\PolRefineInterval*{\<sturmname\>}{\<index\>} <PolRefineInterval*>` or + other localization improving macros. + + .. note:: + + The current polexpr implementation defines the xintexpr_ variables + and xinttools_ arrays as described above with global scope. On the + other hand the Sturm sequence polynomials obey the current scope. + + This is perhaps a bit inconsistent and may change in future. + + .. note:: + + 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*{}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\PolSturmIsolateZeros*{<sturmname>}`` + + The macro does the same as :ref:`\\PolSturmIsolateZeros{\<sturmname\>} <PolSturmIsolateZeros>` and + then in addition it does the extra work to determine all + multiplicities of the real roots. + + After execution, + :ref:`\\PolSturmIsolatedZeroMultiplicity{\<sturmname\>}{\<index\>} <PolSturmIsolatedZeroMultiplicity>` expands + 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 ``S``, xintexpr_ + variables ``SM_1``, ``SM_2``... hold the multiplicities thus + computed. + + .. note:: + + Somewhat counter-intuitively, it is not necessary to have + executed the :ref:`\\PolToSturm* <PolToSturm*>` + starred variant: during its + execution, :ref:`\\PolToSturm <PolToSturm>`, + even though it does not declare the + non-square-free Sturm chain polynomials as user-level genuine + polynomials, stores their data in private macros. + + See ``The degree nine polynomial with 0.99, 0.999, 0.9999 as triple + roots`` example in ``polexpr-examples.pdf``. + +.. _PolSturmIsolateZerosAndGetMultiplicities: + +``\PolSturmIsolateZerosAndGetMultiplicities{}`` +*********************************************** + +Syntax: ``\PolSturmIsolateZerosAndGetMultiplicities{<sturmname>}`` + + This is another name for :ref:`\\PolSturmIsolateZeros*{\<sturmname\>} <PolSturmIsolateZeros*>`. + +.. _PolSturmIsolateZeros**: + +``\PolSturmIsolateZeros**{}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\PolSturmIsolateZeros**{<sturmname>}`` + + The macro does the same as :ref:`\\PolSturmIsolateZeros*{\<sturmname\>} <PolSturmIsolateZeros*>` 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. The number of distinct rational roots is + thus the difference between the degrees of these two polynomials + (see also :ref:`\\PolSturmNbOfRationalRoots{\<sturmname\>} + <PolSturmNbOfRationalRoots>`). + + And ``sturmname_norr`` is ``sturmname_0_`` from which all rational + roots have been removed, i.e. it contains the irrational roots of + the original polynomial, with the same multiplicities. + + See ``A degree five polynomial with three rational + roots`` in ``polexpr-examples.pdf``. + +.. _PolSturmIsolateZerosGetMultiplicitiesAndRationalRoots: + +``\PolSturmIsolateZerosGetMultiplicitiesAndRationalRoots`` +********************************************************** + +Syntax: ``\PolSturmIsolateZerosGetMultiplicitiesAndRationalRoots`` + + This is another name for :ref:`\\PolSturmIsolateZeros**{\<sturmname\>} <PolSturmIsolateZeros**>`. + +.. _PolSturmIsolateZerosAndFindRationalRoots: + +``\PolSturmIsolateZerosAndFindRationalRoots{}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\PolSturmIsolateZerosAndFindRationalRoots{<sturmname>}`` + + This works exactly like :ref:`\\PolSturmIsolateZeros**{\<sturmname\>} <PolSturmIsolateZeros**>` + (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 :ref:`\\PolSturmIsolatedZeroMultiplicity{\<sturmname\>}{\<index\>} <PolSturmIsolatedZeroMultiplicity>`) into + a broken state, as all non-rational roots will supposedly have + multiplicity one. This means that the output of + `\\PolPrintIntervals* <PolPrintIntervals*_>`_ will be + erroneous regarding the multiplicities of 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*{}{}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\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. As a consequence, the ``k``\ th root is then + strictly separated from the other roots. + +.. _PolRefineInterval[]: + +``\PolRefineInterval[]{}{}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\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{}{}{}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\PolEnsureIntervalLength{<sturmname>}{<index>}{<exponent>}`` + + 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{}{}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\PolEnsureIntervalLengths{<sturmname>}{<exponent>}`` + + 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``. + + This means that decimal expansions of all roots will be known with + ``-E`` digits (for ``E<0``) after decimal mark. + +.. _PolSetToSturmChainSignChangesAt: + +``\PolSetToSturmChainSignChangesAt{}{}{}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\PolSetToSturmChainSignChangesAt{\foo}{<sturmname>}{<value>}`` + + Sets macro ``\foo`` to store the number of sign changes in the + already computed normalized Sturm chain with name prefix + ``<sturmname>``, at location ``<value>`` (which must be in format as + acceptable by the xintfrac_ macros.) + + The definition is made with global scope. For local scope, use + ``[\empty]`` as extra optional argument. + + One can use this immediately after creation of the Sturm chain. + +.. _PolSetToNbOfZerosWithin: + +``\PolSetToNbOfZerosWithin{}{}{}{}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\PolSetToNbOfZerosWithin{\foo}{<sturmname>}{<value_left>}{<value_right>}`` + + Sets, assuming the normalized Sturm chain has been already computed, + macro ``\foo`` to store the number of roots of ``sturmname_0`` in + the interval ``(value_left, value_right]``. The macro first + re-orders end-points if necessary for ``value_left <= value_right`` + to hold. + + In accordance to `Sturm Theorem`_ this is computed as the difference + between the number of sign changes of the Sturm chain at ``value_right`` + and the one at ``value_left``. + + The definition is made with global scope. For local scope, use + ``[\empty]`` as extra optional argument. + + One can use this immediately after creation of a Sturm chain. + + See also the expandable + :ref:`\\PolSturmNbOfRootsOf{\<sturmname\>}\\LessThanOrEqualTo{value} <PolSturmNbOfRootsOfLessThanOrEqualTo>`, + which however requires prior execution of `\\PolSturmIsolateZeros + <PolSturmIsolateZeros_>`_. + + See also the expandable + :ref:`\\PolSturmNbWithMultOfRootsOf{\<sturmname\>}\\LessThanOrEqualTo{value} <PolSturmNbWithMultOfRootsOfLessThanOrEqualTo>` + which requires prior execution of + `\\PolSturmIsolateZeros* <PolSturmIsolateZeros*_>`_. + +.. _PolPrintIntervals: + +Displaying the found roots: ``\PolPrintIntervals[<varname>]{}`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Syntax: ``\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. + + .. note:: + + The explanations here and in this section are for LaTeX. With + other TeX macro formats, the LaTeX syntax such as for example + ``\begin{array}{rcccl}`` which appears in the documentation here + is actually replaced with quasi-equivalent direct use of TeX + primitives. + + The next macros which govern its output. + +.. _PolPrintIntervalsNoRealRoots: + +``\PolPrintIntervalsNoRealRoots`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + Executed in place of an ``array`` environment, when there are no + real roots. Default definition:: + + \newcommand\PolPrintIntervalsNoRealRoots{} + +.. _PolPrintIntervalsBeginEnv: + +``\PolPrintIntervalsBeginEnv`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + Default definition (given here for LaTeX, Plain has a variant):: + + \newcommand\PolPrintIntervalsBeginEnv{\[\begin{array}{rcccl}} + + A simpler ``center`` environment provides a straightforward way to + obtain a display allowing pagebreaks. Of course redefinitions must + at any rate be kept in sync with `\\PolPrintIntervalsKnownRoot`_ and + `\\PolPrintIntervalsUnknownRoot`_. + + Prior to ``0.8.6`` it was not possible to use here for example + ``\begin{align}`` due to the latter executing twice in contents. + + +.. _PolPrintIntervalsEndEnv: + +``\PolPrintIntervalsEndEnv`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + Default definition:: + + \newcommand\PolPrintIntervalsEndEnv{\end{array}\]} + +.. _PolPrintIntervalsRowSeparator: + +``\PolPrintIntervalsRowSeparator`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + Expands by default to ``\\`` with LaTeX and to ``\cr`` with Plain + + Added at ``0.8.6``. + +.. _PolPrintIntervalsKnownRoot: + +``\PolPrintIntervalsKnownRoot`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + Default definition:: + + \newcommand\PolPrintIntervalsKnownRoot{% + &&\PolPrintIntervalsTheVar_{\PolPrintIntervalsTheIndex}% + &=&\PolPrintIntervalsPrintExactZero + } + +.. _PolPrintIntervalsUnknownRoot: + +``\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>]{}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\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 + \xintTeXsignedFrac{\PolPrintIntervalsTheLeftEndPoint}% + }% + + Multiplicities are printed using this auxiliary macro: + +.. _PolPrintIntervalsPrintMultiplicity: + +``\PolPrintIntervalsPrintMultiplicity`` +*************************************** + + whose default definition is:: + + \newcommand\PolPrintIntervalsPrintMultiplicity{(\mbox{mult. }\PolPrintIntervalsTheMultiplicity)} + + +Expandable macros +----------------- + +.. note:: + + At ``0.8`` ``polexpr`` is usable with Plain TeX and not only with + LaTeX. Some examples given in this section may be using LaTeX syntax + such as ``\renewcommand``. Convert to TeX primitives as appropriate + if testing with a non LaTeX macro format. + +These macros expand completely in two steps except ``\PolToExpr`` and +``\PolToFloatExpr`` which need a ``\write``, ``\edef`` or a +``\csname...\endcsname`` context. + +.. _PolToExpr: + +``\PolToExpr{}`` +~~~~~~~~~~~~~~~~ + +Syntax: ``\PolToExpr{<pol. expr.>}`` + + Produces expandably [#]_ the string ``coeff_N*x^N+...``, i.e. the + polynomial is using descending powers. + + .. [#] requires exhaustive expansion, for example as triggered by + ``\write`` or ``\edef``. + + Since ``0.8`` the input is not restricted to be a polynomial name but + is allowed to be an arbitrary expression. Then ``x`` is expected as + indeterminate but this can be customized via `\\PolToExprInVar`_. + + The output uses the letter ``x`` by default, this is customizable + via `\\PolToExprVar`_. The default output is compatible both with + + - the Maple's input format, + + - and the PSTricks ``\psplot[algebraic]`` input format. + + Attention that it is not compatible with Python, see further + `\\PolToExprCaret`_ in this context. + + The following applies: + + - vanishing coefficients are skipped (issue ``\poltoexpralltrue`` to + override this and produce output such as ``x^3+0*x^2+0*x^1+0``), + + - negative coefficients are not prefixed by a ``+`` sign (else, + Maple would not be happy), + + - coefficients numerically equal to ``1`` (or ``-1``) are present + only via their sign, + + - the letter ``x`` is used and the degree one monomial is output as + ``x``, not as ``x^1``. + + - (``0.8``) the caret ``^`` is of catcode 12. This means that one + can for convenience typeset in regular text mode, for example + using ``\texttt`` (in LaTeX). But TeX will not know how to break + the expression across end-of-lines anyhow. Formerly ``^`` 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. + + Complete customization is possible, see the next macros. Any user + redefinition must maintain the expandability property. + +.. _PolToExprVar: + +``\PolToExprVar`` +^^^^^^^^^^^^^^^^^ + + Defaults to ``x``. The letter used in the macro output. + + +.. _PolToExprInVar: + +``\PolToExprInVar`` +^^^^^^^^^^^^^^^^^^^ + + Defaults to ``x``: the letter used as the polynomial indeterminate + in the macro input. + + Recall that declared polynomials are more efficiently used in + algebraic expressions without the ``(x)``, i.e. ``P*Q`` is better + than ``P(x)*Q(x)``. Thus the input, even if an expression, does not + have to contain any ``x``. + + (new with ``0.8``) + +.. _PolToExprTimes: + +``\PolToExprTimes`` +^^^^^^^^^^^^^^^^^^^ + + Defaults to ``*``. + +.. _PolToExprCaret: + +``\PolToExprCaret`` +^^^^^^^^^^^^^^^^^^^ + + Defaults to ``^`` of catcode 12. Set it to + expand to ``**`` for Python compatible output. + + (new with ``0.8``) + +.. _PolToExprCmd: + +``\PolToExprCmd{}`` +^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\PolToExprCmd{<raw_coeff>}`` + + Defaults to ``\xintPRaw{\xintRawWithZeros{#1}}``. + + This means that the coefficient value is printed-out as a fraction + ``a/b``, skipping the ``/b`` part if ``b`` turns out to be one. + + Configure it to be ``\xintPRaw{\xintIrr{#1}}`` if the fractions + must be in irreducible terms. + + An alternative is ``\xintDecToString{\xintREZ{#1}}`` which uses + integer or decimal fixed point format such as ``23.0071`` if the + internal representation of the number only has a power of ten as + denominator (the effect of ``\xintREZ`` here is to remove trailing + decimal zeros). The behaviour of ``\xintDecToString`` 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 ``23.007/2`` or ``23.007/25`` can appear in output + and not their finite decimal expansion with no denominator. + +.. _PolToExprOneTerm: + +``\PolToExprOneTerm{}{}`` +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\PolToExprOneTerm{<raw_coeff>}{<exponent>}`` + + This is the macro which from the coefficient and the exponent + produces the corresponding term in output, such as ``2/3*x^7``. + + For its default definition, see the source code. It uses + `\\PolToExprCmd <PolToExprCmd_>`_, `\\PolToExprTimes + <PolToExprTimes_>`_, `\\PolToExprVar <PolToExprVar_>`_ and + `\\PolToExprCaret`_. + +.. _PolToExprOneTermStyleA: + +``\PolToExprOneTermStyleA{}{}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\PolToExprOneTermStyleA{<raw_coeff>}{<exponent>}`` + + This holds the default package meaning of ``\PolToExprOneTerm``. + +.. _PolToExprOneTermStyleB: + +``\PolToExprOneTermStyleB{}{}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\PolToExprOneTermStyleB{<raw_coeff>}{<exponent>}`` + + This holds an alternative meaning, which puts the fractional part of + a coefficient after the monomial, i.e. like this:: + + 2*x^11/3+3*x^8/7-x^5-x^4/4-x^3-x^2/2-2*x+1 + + `\\PolToExprCmd <PolToExprCmd_>`_ isn't used at all in this style. But + `\\PolToExprTimes <PolToExprTimes_>`_, `\\PolToExprVar + <PolToExprVar_>`_ and `\\PolToExprCaret`_ are obeyed. + + To activate it use ``\let\PolToExprOneTerm\PolToExprOneTermStyleB``. + To revert to the package default behaviour, issue + ``\let\PolToExprOneTerm\PolToExprOneTermStyleA``. + +.. _PolToExprTermPrefix: + +``\PolToExprTermPrefix{}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\PolToExprTermPrefix{<raw_coeff>}`` + + It receives as argument the coefficient. Its default behaviour is + to produce a ``+`` if the coefficient is positive, which will thus + serve to separate the monomials in the output. This is to match + the default for :ref:`\\PolToExprCmd{\<raw_coeff\>} <PolToExprCmd>` which in case of a + positive coefficient does not output an explicit ``+`` prefix. + +.. _PolToFloatExpr: + +``\PolToFloatExpr{}`` +~~~~~~~~~~~~~~~~~~~~~ + +Syntax: ``\PolToFloatExpr{<pol. expr.>}`` + + Similar to :ref:`\\PolToExpr{\<pol. expr.\>} <PolToExpr>` but using + :ref:`\\PolToFloatExprCmd{\<raw_coeff\>} <PolToFloatExprCmd>` which by default rounds and + converts the coefficients to floating point format. + + .. note:: + + This is unrelated to :ref:`\\PolGenFloatVariant{\<polname\>} <PolGenFloatVariant>`: + :ref:`\\PolToFloatExprCmd{\<raw_coeff\>} <PolToFloatExprCmd>` operates on the *exact* + coefficients anew (and may thus produce something else than + the coefficients of the polynomial function acting + in ``\xintfloateval`` if the floating point precision was changed + in between). + + Extended at ``0.8`` to accept general expressions as input. + +.. _PolToFloatExprOneTerm: + +``\PolToFloatExprOneTerm{}{}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\PolToFloatExprOneTerm{<raw_coeff>}{<exponent>}`` + + Similar to :ref:`\\PolToExprOneTerm{\<raw_coeff\>}{\<exponent\>} <PolToExprOneTerm>`. But does not treat + especially coefficients equal to plus or minus one. + +.. _PolToFloatExprCmd: + +``\PolToFloatExprCmd{}`` +^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\PolToFloatExprCmd{<raw_coeff>}`` + + The one-argument macro used by ``\PolToFloatExprOneTerm``. + It defaults to ``\xintPFloat{#1}``, which trims trailing + zeroes. + + *changed at 0.8.2* Formerly it was using ``\xintFloat``. + +.. _PolToExpr*: + +``\PolToExpr*{}`` +~~~~~~~~~~~~~~~~~ + +Syntax: ``\PolToExpr*{<pol. expr.>}`` + + Ascending powers: ``coeff_0+coeff_1*x+coeff_2*x^2+...``. + + Extended at ``0.8`` to accept general expressions as input. + + Customizable with the same macros as for + :ref:`\\PolToExpr{\<pol. expr.\>} <PolToExpr>`. + +.. _PolToFloatExpr*: + +``\PolToFloatExpr*{}`` +~~~~~~~~~~~~~~~~~~~~~~ + +Syntax: ``\PolToFloatExpr*{<pol. expr.>}`` + + Ascending powers. + + Extended at ``0.8`` to accept general expressions as input. + +.. _PolNthCoeff: + +``\PolNthCoeff{}{}`` +~~~~~~~~~~~~~~~~~~~~ + +Syntax: ``\PolNthCoeff{<polname>}{<index>}`` + + It expands to the raw ``N``-th coefficient (``N=0`` corresponds to + the constant coefficient). If ``N`` is out of range, zero (in its + default xintfrac_ format ``0/1[0]``) is returned. + + Negative indices ``N=-1``, ``-2``, ... return the leading + coefficient, sub-leading coefficient, ..., and finally ``0/1[0]`` + for ``N<-1-degree``. + +.. _PolLeadingCoeff: + +``\PolLeadingCoeff{}`` +~~~~~~~~~~~~~~~~~~~~~~ + +Syntax: ``\PolLeadingCoeff{<polname>}`` + + Expands to the leading coefficient. + +.. _PolDegree: + +``\PolDegree{}`` +~~~~~~~~~~~~~~~~ + +Syntax: ``\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{}`` +~~~~~~~~~~~~~~~~~~ + +Syntax: ``\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_>`_. + +.. _PolToList: + +``\PolToList{}`` +~~~~~~~~~~~~~~~~ + +Syntax: ``\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{}`` +~~~~~~~~~~~~~~~ + +Syntax: ``\PolToCSV{<polname>}`` + + Expands to ``coeff_0, coeff_1, coeff_2, ....., coeff_N``, starting + with constant term and ending with leading coefficient. Converse + to :ref:`\\PolFromCSV{\<polname\>}{\<csv\>} <PolFromCSV>`. + + +.. _PolEvalAtExpr: + +``\PolEval{}\AtExpr{}`` +~~~~~~~~~~~~~~~~~~~~~~~ + +Syntax: ``\PolEval{<polname>}\AtExpr{<num. expr.>}`` + + Same output as + ``\xinteval{polname(numerical expression)}``. + +.. _PolEvalAt: + +``\PolEval{}\At{}`` +~~~~~~~~~~~~~~~~~~~ + +Syntax: ``\PolEval{<polname>}\At{<value>}`` + + Evaluates the polynomial at the given value which must be in (or + expand to) a format acceptable to the xintfrac_ macros. + +.. _PolEvalReducedAtExpr: + +``\PolEvalReduced{}\AtExpr{}`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Syntax: ``\PolEvalReduced{<polname>}\AtExpr{<num. expr.>}`` + + Same output as ``\xinteval{reduce(polname(numerical expression))}``. + +.. _PolEvalReducedAt: + +``\PolEvalReduced{}\At{}`` +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Syntax: ``\PolEvalReduced{<polname>}\At{<value>}`` + + Evaluates the polynomial at the value which must be in (or expand + to) a format acceptable to the xintfrac_ macros, and outputs an + irreducible fraction. + +.. _PolFloatEvalAtExpr: + +``\PolFloatEval{}\AtExpr{}`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Syntax: ``\PolFloatEval{<polname>}\AtExpr{<num. expr.>}`` + + Same output as ``\xintfloateval{polname(numerical expression)}``. + + .. attention:: + + `\\PolGenFloatVariant <PolGenFloatVariant_>`_ must have + been issued before. + + To use the *exact coefficients* with *exactly executed* additions + and multiplications and do the rounding only as the final last step, + the following syntax can be used: [#]_ + + :: + + \xintfloateval{3.27*\xintexpr f(2.53)\relax^2} + + + .. [#] Cf. xintexpr_ documentation about nested expressions. + +.. _PolFloatEvalAt: + +``\PolFloatEval{}\At{}`` +~~~~~~~~~~~~~~~~~~~~~~~~ + +Syntax: ``\PolFloatEval{<polname>}\At{<value>}`` + + Evaluates the polynomial at the value which must be in (or expand + to) a format acceptable to the xintfrac_ macros. + + +Expandable macros in relation to root localization via `Sturm Theorem`_ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. _PolSturmChainLength: + +``\PolSturmChainLength{}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\PolSturmChainLength{<sturmname>}`` + + Returns the integer ``N`` such that ``sturmname_N`` is the last one + in the Sturm chain ``sturmname_0``, ``sturmname_1``, ... + + See :ref:`\\PolToSturm{\<polname\>}{\<sturmname\>} <PolToSturm>`. + +.. _PolSturmIfZeroExactlyKnown: + +``\PolSturmIfZeroExactlyKnown{}{}{}{}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\PolSturmIfZeroExactlyKnown{<sturmname>}{<index>}{T}{F}`` + + Executes ``T`` if the ``index``\ -th interval reduces to a singleton, + i.e. the root is known exactly, else ``F``. + + .. vieux commentaire + + ``index`` is allowed to be something like ``1+2*3`` as it is fed + to ``\the\numexpr...\relax``. + +.. _PolSturmIsolatedZeroLeft: + +``\PolSturmIsolatedZeroLeft{}{}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\PolSturmIsolatedZeroLeft{<sturmname>}{<index>}`` + + Expands to the left end-point for the ``index``\ -th interval, as + computed by some earlier :ref:`\\PolSturmIsolateZeros{\<sturmname\>} <PolSturmIsolateZeros>`. + + .. note:: + + Execution of this macro after some + `\\PolRefineInterval{<sturmname>}{<index>} <PolRefineInterval[]_>`_ + will take into account the now known tighter bounds. + + The value is pre-formatted using `\\PolDecTostring + <PolDecToString_>`_. + +.. _PolSturmIsolatedZeroRight: + +``\PolSturmIsolatedZeroRight{}{}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\PolSturmIsolatedZeroRight{<sturmname>}{<index>}`` + + Expands to the right end-point for the ``index``\ -th interval as + computed by some earlier :ref:`\\PolSturmIsolateZeros{\<sturmname\>} <PolSturmIsolateZeros>` and + possibly refined afterwards. + + The value is pre-formatted using `\\PolDecTostring + <PolDecToString_>`_. + +.. _PolSturmIsolatedZeroMultiplicity: + +``\PolSturmIsolatedZeroMultiplicity{}{}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\PolSturmIsolatedZeroMultiplicity{<sturmname>}{<index>}`` + + Expands to the multiplicity of the unique root contained in the + ``index``\ -th interval. + + .. attention:: + + A prior execution of :ref:`\\PolSturmIsolateZeros*{\<sturmname\>} <PolSturmIsolateZeros*>` is mandatory. + + See ``The degree nine polynomial with 0.99, 0.999, 0.9999 as triple + roots`` in ``polexpr-examples.pdf``. + +.. _PolSturmNbOfIsolatedZeros: + +``\PolSturmNbOfIsolatedZeros{}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\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 + :ref:`\\PolToSturm{\<polname\>}{\<sturmname\>} <PolToSturm>`. + +.. 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. + +.. _PolSturmNbOfRootsOfLessThanOrEqualTo: + +``\PolSturmNbOfRootsOf{}\LessThanOrEqualTo{}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\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:: + + :ref:`\\PolSturmIsolateZeros{\<sturmname\>} <PolSturmIsolateZeros>` 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. + +.. _PolSturmNbOfRootsOfLessThanOrEqualToExpr: + +``\PolSturmNbOfRootsOf{}\LessThanOrEqualToExpr{}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\PolSturmNbOfRootsOf{<sturmname>}\LessThanOrEqualToExpr{<num. expr.>}`` + + 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 numerical expression. + + .. attention:: + + :ref:`\\PolSturmIsolateZeros{\<sturmname\>} <PolSturmIsolateZeros>` must have been executed + beforehand. + +.. _PolSturmNbWithMultOfRootsOfLessThanOrEqualTo: + +``\PolSturmNbWithMultOfRootsOf{}\LessThanOrEqualTo{}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\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:: + + :ref:`\\PolSturmIsolateZeros*{\<sturmname\>} <PolSturmIsolateZeros*>` (or the double starred + variant) must have been executed beforehand. + +.. _PolSturmNbWithMultOfRootsOfLessThanOrEqualToExpr: + +``\PolSturmNbWithMultOfRootsOf{}\LessThanOrEqualToExpr{}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\PolSturmNbWithMultOfRootsOf{<sturmname>}\LessThanOrEqualToExpr{<num. expr.>}`` + + Expands to the total number of roots (counted with multiplicities) + which are less than or equal to the given ``expression``. + + .. attention:: + + :ref:`\\PolSturmIsolateZeros*{\<sturmname\>} <PolSturmIsolateZeros*>` (or the double starred + variant) must have been executed beforehand. + +.. _PolSturmNbOfRationalRoots: + +``\PolSturmNbOfRationalRoots{}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\PolSturmNbOfRationalRoots{<sturmname>}`` + + Expands to the number of rational roots (without multiplicities). + + .. attention:: + + :ref:`\\PolSturmIsolateZeros**{\<sturmname\>} <PolSturmIsolateZeros**>` must have been executed + beforehand. + +.. _PolSturmNbOfRationalRootsWithMultiplicities: + +``\PolSturmNbOfRationalRootsWithMultiplicities{}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\PolSturmNbOfRationalRootsWithMultiplicities{<sturmname>}`` + + Expands to the number of rational roots (counted with multiplicities). + + .. attention:: + + :ref:`\\PolSturmIsolateZeros**{\<sturmname\>} <PolSturmIsolateZeros**>` must have been executed + beforehand. + +.. _PolSturmRationalRoot: + +``\PolSturmRationalRoot{}{}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\PolSturmRationalRoot{<sturmname>}{<k>}`` + + Expands to the k-th rational root. They are enumerated from left to + right starting at index value ``1``. + + .. attention:: + + :ref:`\\PolSturmIsolateZeros**{\<sturmname\>} <PolSturmIsolateZeros**>` must have been executed + beforehand. + +.. _PolSturmRationalRootIndex: + +``\PolSturmRationalRootIndex{}{}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\PolSturmRationalRootIndex{<sturmname>}{<k>}`` + + Expands to the index of the ``k``\ th rational root as part of the + ordered real roots (counted without multiplicities). So + :ref:`\\PolSturmRationalRoot{\<sturmname\>}{\<k\>} <PolSturmRationalRoot>` is equivalent to + this nested call:: + + \PolSturmIsolatedZeroLeft{<sturmname>}{\PolSturmRationalRootIndex{<sturmname>}{<k>}} + + .. attention:: + + :ref:`\\PolSturmIsolateZeros**{\<sturmname\>} <PolSturmIsolateZeros**>` must have been executed + beforehand. + +.. _PolSturmRationalRootMultiplicity: + +``\PolSturmRationalRootMultiplicity{}{}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\PolSturmRationalRootMultiplicity{<sturmname>}{<k>}`` + + Expands to the multiplicity of the ``k``\ th rational root. + + .. attention:: + + :ref:`\\PolSturmIsolateZeros**{\<sturmname\>} <PolSturmIsolateZeros**>` must have been executed + beforehand. + +.. _PolIntervalWidth: + +``\PolIntervalWidth{}{}`` +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: ``\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). + + .. renommer cela en \PolSturmIntervalWidth ? + +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). + +.. vieux commentaire + + Some macros formerly mentioned here got removed at 0.7: + ``\PolPrintIntervalsTheEndPoint``, + ``\PolIfEndPointIsPositive{T}{F}``, + ``\PolIfEndPointIsNegative{T}{F}``, + ``\PolIfEndPointIsZero{T}{F}``. + +.. _PolPrintIntervalsTheVar: + +``\PolPrintIntervalsTheVar`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + Expands to the name (default ``Z``) used for representing the roots, + which was passed as optional argument ``varname`` to + :ref:`\\PolPrintIntervals[varname]{\<sturmname\>} <PolPrintIntervals>`. + +.. _PolPrintIntervalsTheIndex: + +``\PolPrintIntervalsTheIndex`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + Expands to the index of the considered interval (indexing starting + at 1 for the leftmost interval). + +.. _PolPrintIntervalsTheSturmName: + +``\PolPrintIntervalsTheSturmName`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + Expands to the argument which was passed as ``<sturmname>`` to + :ref:`\\PolPrintIntervals[varname]{\<sturmname\>} <PolPrintIntervals>`. + +.. _PolPrintIntervalsTheLeftEndPoint: + +``\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: + +``\PolPrintIntervalsTheRightEndPoint`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + The right end point of the interval, as would be produced by + `\\\PolSturmIsolatedZeroRight <PolSturmIsolatedZeroRight_>`_ for + this Sturm chain name and index. + +.. _PolPrintIntervalsTheMultiplicity: + +``\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. + + +TeX Booleans (with names enacting their defaults) +------------------------------------------------- + +.. _xintverbosefalse: + +``\xintverbosefalse`` +~~~~~~~~~~~~~~~~~~~~~ + + This is actually an xintexpr_ configuration. Setting it to + ``true`` triggers the writing of information to the log when new + polynomial or scalar variables are defined. + + .. caution:: + + The macro and variable meanings as written to the log are to be + considered unstable and undocumented internal structures. + +.. _polnewpolverbosefalse: + +``\polnewpolverbosefalse`` +~~~~~~~~~~~~~~~~~~~~~~~~~~ + + When ``\poldef`` is used, both a variable and a function are + defined. The default ``\polnewpolverbosefalse`` 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. + + However :ref:`\\PolGenFloatVariant{\<polname\>} <PolGenFloatVariant>` + does still print out the information relative to the polynomial + function it defines for use in ``\xintfloateval{}`` as there is no + float polynomial variable, only the + + function, and it is the only way to see its rounded coefficients + (``\xintverbosefalse`` suppresses also that info). + + If set to ``true``, it overrides in both cases + ``\xintverbosefalse``. The setting only affects polynomial + declarations. Scalar variables such as those holding information on + roots obey only the ``\xintverbose...`` setting. + + (new with ``0.8``) + +.. _poltypesetallfalse: + +``\poltypesetallfalse`` +~~~~~~~~~~~~~~~~~~~~~~~ + + If ``true``, `\\PolTypeset <PolTypeset_>`_ will also typeset the vanishing + coefficients. + + +.. _poltoexprallfalse: + +``\poltoexprallfalse`` +~~~~~~~~~~~~~~~~~~~~~~ + + If ``true``, :ref:`\\PolToExpr{\<pol. expr.\>} <PolToExpr>` and + :ref:`\\PolToFloatExpr{\<pol. expr.\>} <PolToFloatExpr>` will also + include the vanishing coefficients in their outputs. + + +Utilities +--------- + +.. _PolDecToString: + +``\PolDecToString{}`` +~~~~~~~~~~~~~~~~~~~~~ + +Syntax: ``\PolDecToString{decimal number}`` + + This is a utility macro to print decimal numbers. It is an alias + for ``\xintDecToString``. + +.. vieux commentaire + + 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}}``. + + Attention that a.t.t.o.w. if the argument is for example ``1/5``, the + macro does not identify that this is in fact a number with a finite + decimal expansion and it outputs ``1/5``. See current xintfrac_ + documentation. + +.. vieux commentaire + + The precise behaviour of this macro may evolve in future releases of + xintexpr_. + +.. + + +.. _polexprsetup: + +``\polexprsetup{key=val,...}`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Serves to customize the package. Currently only two keys are + recognized: + + - ``norr``: the postfix that :ref:`\\PolSturmIsolateZeros**{\<sturmname\>} <PolSturmIsolateZeros**>` + 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 :ref:`\\PolSturmIsolateZeros**{\<sturmname\>} <PolSturmIsolateZeros**>` + 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 ``@`` is allowed in the name of a polynomial (independently of + whether it is of catcode letter or other.) This has always been the + case, but was not documented by polexpr prior to ``0.8``, as the + author has never found the time to provide some official guidelines on + how to name temporary variables and the ``@`` is used already as such + internally; time has still not yet been found to review the situation + but it seems reasonable to recommend at any rate to restrict usage of + ``@`` to scratch variables of defined macros and to avoid using it to + name document variable. + +- Catcodes are set temporarily by `\\poldef <poldef;_>`_ macro to safe + values prior to grab the polynomial expression up to the terminator + ``;``, and also by `\\PolDef <PolDef_>`_ prior to grab the + brace-enclosed polynomial expression. This gives a layer of + protection in case some package (for example the ``babel-french`` module) + has made some characters active. It will fail though if the whole + thing is located inside some definition of a macro done at a time the + characters are active. + +- .. + + .. attention:: + + Contrarily to ``\xintdefvar`` and ``\xintdeffunc`` from xintexpr_, + ``\poldef`` uses a naive delimited macro to fetch up to the + expression terminator ``";"``, hence it will be fooled if some + ``;`` is used inside the expression (which is possible as it + appears in some xintexpr_ constructs). Work-around is to use curly + braces around the inner semi-colons, or simpler to use + ``\PolDef``. + +- As a consequence of xintfrac_ addition and subtraction always using + least common multiples for the denominators, user-chosen common + denominators (currently) 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*Q; + + 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. One can use for example + ``\PolToCSV{PQ}`` to see the internally stored coefficients. + + .. vieux commentaire + + prior to ``0.4.1``, ``polexpr`` used to temporarily patch + during the parsing of polynomials the xintfrac_ macros. This + patch was backported to xintexpr_ at release ``1.3``. + +- :ref:`\\PolDiff{\<polname_1\>}{\<polname_2\>} <PolDiff>` always applies ``\xintPIrr`` to the + resulting coefficients, which means that fractions are reduced to + lowest terms but ignoring an already separated *power of ten* part ``[N]`` + present in the internal representation. This is tentative and may change. + + Same remark for :ref:`\\PolAntiDiff{\<polname_1\>}{\<polname_2\>} <PolAntiDiff>`. + +- 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. + + +.. _xinttools: +.. _xintfrac: +.. _xint: https://www.ctan.org/pkg/xint + +.. _xintexpr: https://www.ctan.org/pkg/xintexpr + +.. _xintsession: https://www.ctan.org/pkg/xintsession + +.. _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 + + +.. Local variables: +.. sentence-end-double-space: t; +.. End: diff --git a/Master/texmf-dist/doc/generic/polexpr/polexpr.css b/Master/texmf-dist/doc/generic/polexpr/polexpr.css new file mode 100644 index 00000000000..b95962ac845 --- /dev/null +++ b/Master/texmf-dist/doc/generic/polexpr/polexpr.css @@ -0,0 +1,826 @@ +/* + * polexpr.css + * ~~~~~~~~~~~ + * + * stylesheet for polexpr html documentation + * Copyright (c) 2022 by Jean-François Burnol + * + * It has been obtained on May 13, 2022 by Jean-François Burnol via + * copying selected extracts from the css files as found in the output + * of a sphinx-build with "bizstyle" theme, enough for the styling the + * html elements used in polexpr html documentation, and with a few + * changes here and there. + * + * It also incorporate (essentially) the output of `pygmentize -S + * friendly -f html` which specifies the behaviour of the highlighting, + * and is produced by default by Sphinx on all sphinx-build runs. + * + */ + + +/* -- start of extracts from basic.css -------------------------------------- */ + +/* -- main layout ----------------------------------------------------------- */ + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 35%; /* polexpr */ + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a.brackets:before, +span.brackets > a:before{ + content: "["; +} + +a.brackets:after, +span.brackets > a:after { + content: "]"; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +.footnote:target { + background-color: #ffa; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} + +/* -- end of extracts from basic.css ---------------------------------------- */ + +/* -- start of extracts from bizstyle.css ----------------------------------- */ + +/* -- page layout ----------------------------------------------------------- */ + +body { + font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva', + 'Verdana', sans-serif; + /* font-size: 14px; not for polexpr.css */ + letter-spacing: -0.01em; + line-height: 150%; + text-align: center; + background-color: white; + background-image: url(background_b01.png); + color: black; + padding: 0; + border-right: 1px solid #336699; + border-left: 1px solid #336699; + + margin: 0px 40px 0px 40px; +} + +div.document { + background-color: white; + text-align: left; + background-repeat: repeat-x; + + -moz-box-shadow: 2px 2px 5px #000; + -webkit-box-shadow: 2px 2px 5px #000; +} + +div.documentwrapper { + float: left; + width: 100%; +} + +div.bodywrapper { + margin: 0 0 0 240px; + border-left: 1px solid #ccc; +} + +div.body { + margin: 0; + padding: 0.5em 20px 20px 20px; +} +div.bodywrapper { + margin: 0 calc(35% + 30px) 0 0; /* polexpr */ + border-right: 1px solid #ccc; +} + +div.related { + font-size: 1em; + + -moz-box-shadow: 2px 2px 5px #000; + -webkit-box-shadow: 2px 2px 5px #000; +} + +div.related ul { + background-color: #336699; + height: 100%; + overflow: hidden; + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; +} + +div.related ul li { + color: white; + margin: 0; + padding: 0; + height: 2em; + float: left; +} + +div.related ul li.right { + float: right; + margin-right: 5px; +} + +div.related ul li a { + margin: 0; + padding: 0 5px 0 5px; + line-height: 1.75em; + color: #fff; +} + +div.related ul li a:hover { + color: #fff; + text-decoration: underline; +} + +div.sphinxsidebarwrapper { + padding: 0; +} + +div.sphinxsidebar { + padding: 0.5em 12px 12px 12px; + width: 35%; /* polexpr */ + float: right; + font-size: 1em; + text-align: left; +} + +div.sphinxsidebar h3, div.sphinxsidebar h4 { + margin: 1em 0 0.5em 0; + font-size: 1em; + padding: 0.1em 0 0.1em 0.5em; + color: white; + border: 1px solid #336699; + background-color: #336699; +} + +div.sphinxsidebar h3 a { + color: white; +} + +div.sphinxsidebar ul { + padding-left: 1.5em; + margin-top: 7px; + padding: 0; + line-height: 130%; +} + +div.sphinxsidebar ul ul { + margin-left: 20px; +} + +div.sphinxsidebar input { + border: 1px solid #336699; +} + +div.footer { + background-color: white; + color: #336699; + padding: 3px 8px 3px 0; + clear: both; + font-size: 0.8em; + text-align: right; + border-bottom: 1px solid #336699; + + -moz-box-shadow: 2px 2px 5px #000; + -webkit-box-shadow: 2px 2px 5px #000; +} + +div.footer a { + color: #336699; + text-decoration: underline; +} + +/* -- body styles ----------------------------------------------------------- */ + +p { + margin: 0.8em 0 0.5em 0; +} + +a { + color: #336699; + text-decoration: none; +} + +a:hover { + color: #336699; + text-decoration: underline; +} + +div.body a { + text-decoration: underline; +} + +h1, h2, h3 { + color: #336699; +} + +h1 { + margin: 0; + padding: 0.7em 0 0.3em 0; + font-size: 1.5em; +} + +h2 { + margin: 1.3em 0 0.2em 0; + font-size: 1.35em; + padding-bottom: .5em; + border-bottom: 1px solid #336699; +} + +h3 { + margin: 1em 0 -0.3em 0; + font-size: 1.2em; + padding-bottom: .3em; + border-bottom: 1px solid #CCCCCC; +} + +div.body h1 a, div.body h2 a, div.body h3 a, +div.body h4 a, div.body h5 a, div.body h6 a { + color: black!important; +} + +h1 a.anchor, h2 a.anchor, h3 a.anchor, +h4 a.anchor, h5 a.anchor, h6 a.anchor { + display: none; + margin: 0 0 0 0.3em; + padding: 0 0.2em 0 0.2em; + color: #aaa!important; +} + +h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, +h5:hover a.anchor, h6:hover a.anchor { + display: inline; +} + +h1 a.anchor:hover, h2 a.anchor:hover, h3 a.anchor:hover, h4 a.anchor:hover, +h5 a.anchor:hover, h6 a.anchor:hover { + color: #777; + background-color: #eee; +} + +a.headerlink { + color: #c60f0f!important; + font-size: 1em; + margin-left: 6px; + padding: 0 4px 0 4px; + text-decoration: none!important; +} + +a.headerlink:hover { + background-color: #ccc; + color: white!important; +} + +cite, code, tt { + font-family: 'Consolas', 'Deja Vu Sans Mono', + 'Bitstream Vera Sans Mono', monospace; + /* font-size: 0.95em; not for polexpr */ + letter-spacing: 0.01em; +} + +code { + background-color: #F2F2F2; + border-bottom: 1px solid #ddd; + color: #333; +} + +code.descname, code.descclassname, code.xref { + border: 0; +} + +hr { + border: 1px solid #abc; + margin: 2em; +} + +a code { + border: 0; + color: #CA7900; +} + +a code:hover { + color: #2491CF; +} + +pre { + background-color: transparent !important; + font-family: 'Consolas', 'Deja Vu Sans Mono', + 'Bitstream Vera Sans Mono', monospace; + /* font-size: 0.95em; not for polexpr */ + letter-spacing: 0.015em; + line-height: 120%; + padding: 0.5em; + border-right: 5px solid #ccc; + border-left: 5px solid #ccc; +} + +pre a { + color: inherit; + text-decoration: underline; +} + +td.linenos pre { + padding: 0.5em 0; +} + +div.quotebar { + background-color: #f8f8f8; + max-width: 250px; + float: right; + padding: 2px 7px; + border: 1px solid #ccc; +} + +div.topic { + background-color: #f8f8f8; +} + +div.admonition { + /* font-size: 0.9em; not for polexpr */ + margin: 1em 0 1em 0; + border: 3px solid #cccccc; + background-color: #f7f7f7; + padding: 0; +} + +div.admonition p { + margin: 0.5em 1em 0.5em 1em; + padding: 0; +} + +div.admonition li p { + margin-left: 0; +} + +div.admonition pre, div.warning pre { + margin: 0; +} + +div.highlight { + margin: 0.4em 1em; +} + +div.admonition p.admonition-title { + margin: 0; + padding: 0.1em 0 0.1em 0.5em; + color: white; + border-bottom: 3px solid #cccccc; + font-weight: bold; + background-color: #165e83; +} + +div.danger { border: 3px solid #f0908d; background-color: #f0cfa0; } +div.error { border: 3px solid #f0908d; background-color: #ede4cd; } +div.warning { border: 3px solid #f8b862; background-color: #f0cfa0; } +div.caution { border: 3px solid #f8b862; background-color: #ede4cd; } +div.attention { border: 3px solid #f8b862; background-color: #f3f3f3; } +div.important { border: 3px solid #f0cfa0; background-color: #ede4cd; } +div.note { border: 3px solid #f0cfa0; background-color: #f3f3f3; } +div.hint { border: 3px solid #bed2c3; background-color: #f3f3f3; } +div.tip { border: 3px solid #bed2c3; background-color: #f3f3f3; } + +div.danger p.admonition-title, div.error p.admonition-title { + background-color: #b7282e; + border-bottom: 3px solid #f0908d; +} + +div.caution p.admonition-title, +div.warning p.admonition-title, +div.attention p.admonition-title { + background-color: #f19072; + border-bottom: 3px solid #f8b862; +} + +div.note p.admonition-title, div.important p.admonition-title { + background-color: #f8b862; + border-bottom: 3px solid #f0cfa0; +} + +div.hint p.admonition-title, div.tip p.admonition-title { + background-color: #7ebea5; + border-bottom: 3px solid #bed2c3; +} + +div.admonition ul, div.admonition ol, +div.warning ul, div.warning ol { + margin: 0.1em 0.5em 0.5em 3em; + padding: 0; +} + +div.versioninfo { + margin: 1em 0 0 0; + border: 1px solid #ccc; + background-color: #DDEAF0; + padding: 8px; + line-height: 1.3em; + font-size: 0.9em; +} + +div.literal-block-wrapper div.code-block-caption { + background-color: #EEE; + border-style: solid; + border-color: #CCC; + border-width: 1px 5px; +} + +/* WIDE DESKTOP STYLE */ +@media only screen and (min-width: 1176px) { +body { + margin: 0 40px 0 40px; +} +} + +/* TABLET STYLE */ +@media only screen and (min-width: 768px) and (max-width: 991px) { +body { + margin: 0 40px 0 40px; +} +} + +/* MOBILE LAYOUT (PORTRAIT/320px) */ +@media only screen and (max-width: 767px) { +body { + margin: 0; +} +div.bodywrapper { + margin: 0; + width: 100%; + border: none; +} +div.sphinxsidebar { + display: none; +} +} + +/* MOBILE LAYOUT (LANDSCAPE/480px) */ +@media only screen and (min-width: 480px) and (max-width: 767px) { +body { + margin: 0 20px 0 20px; +} +} + +/* RETINA OVERRIDES */ +@media +only screen and (-webkit-min-device-pixel-ratio: 2), +only screen and (min-device-pixel-ratio: 2) { +} + +/* -- end ------------------------------------------------------------------- */ + +/* -- pygments styling from `pygmentize -S friendly -f html` ---------------- */ + +pre { line-height: 125%; } +td.linenos .normal { color: #666666; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: #666666; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight .hll { background-color: #ffffcc } +.highlight { background: #f0f0f0; } +.highlight .c { color: #60a0b0; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #007020; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .ch { color: #60a0b0; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #60a0b0; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #007020 } /* Comment.Preproc */ +.highlight .cpf { color: #60a0b0; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #60a0b0; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #60a0b0; background-color: #fff0f0 } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #888888 } /* Generic.Output */ +.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #007020 } /* Keyword.Pseudo */ +.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #902000 } /* Keyword.Type */ +.highlight .m { color: #40a070 } /* Literal.Number */ +.highlight .s { color: #4070a0 } /* Literal.String */ +.highlight .na { color: #4070a0 } /* Name.Attribute */ +.highlight .nb { color: #007020 } /* Name.Builtin */ +.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ +.highlight .no { color: #60add5 } /* Name.Constant */ +.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ +.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #007020 } /* Name.Exception */ +.highlight .nf { color: #06287e } /* Name.Function */ +.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ +.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #bb60d5 } /* Name.Variable */ +.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mb { color: #40a070 } /* Literal.Number.Bin */ +.highlight .mf { color: #40a070 } /* Literal.Number.Float */ +.highlight .mh { color: #40a070 } /* Literal.Number.Hex */ +.highlight .mi { color: #40a070 } /* Literal.Number.Integer */ +.highlight .mo { color: #40a070 } /* Literal.Number.Oct */ +.highlight .sa { color: #4070a0 } /* Literal.String.Affix */ +.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ +.highlight .sc { color: #4070a0 } /* Literal.String.Char */ +.highlight .dl { color: #4070a0 } /* Literal.String.Delimiter */ +.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #4070a0 } /* Literal.String.Double */ +.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ +.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ +.highlight .sx { color: #c65d09 } /* Literal.String.Other */ +.highlight .sr { color: #235388 } /* Literal.String.Regex */ +.highlight .s1 { color: #4070a0 } /* Literal.String.Single */ +.highlight .ss { color: #517918 } /* Literal.String.Symbol */ +.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #06287e } /* Name.Function.Magic */ +.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ +.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ +.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ +.highlight .vm { color: #bb60d5 } /* Name.Variable.Magic */ +.highlight .il { color: #40a070 } /* Literal.Number.Integer.Long */ diff --git a/Master/texmf-dist/doc/generic/polexpr/polexpr.html b/Master/texmf-dist/doc/generic/polexpr/polexpr.html index 5f695deb4b7..23dafab2c2d 100644 --- a/Master/texmf-dist/doc/generic/polexpr/polexpr.html +++ b/Master/texmf-dist/doc/generic/polexpr/polexpr.html @@ -1,3822 +1,190 @@ -<!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>polexpr reference 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="polexpr-reference-documentation"> -<h1 class="title">polexpr reference documentation</h1> -<p class="subtitle" id="id1">0.8.6 (2022/01/09)</p> +<!DOCTYPE html> -<div class="section" id="introduction"> -<h1><a class="toc-backref" href="#id35">Introduction</a></h1> -<p>This is a TeX and LaTeX macro package.</p> +<html lang="en"> + <head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.18.1: http://docutils.sourceforge.net/" /> + + <title>Introduction to polexpr — polexpr 0.8.7 documentation</title> + <link rel="stylesheet" type="text/css" href="polexpr.css" /> + <link rel="next" title="polexpr reference" href="polexpr-ref.html" /> + </head><body> + <div class="related" role="navigation" aria-label="related navigation"> + <h3>Navigation</h3> + <ul> + <li class="right" style="margin-right: 10px"> + <a href="polexpr-ref.html" title="polexpr reference" + accesskey="N">next</a></li> + <li class="nav-item nav-item-0"><a href="#">polexpr 0.8.7 documentation</a> »</li> + <li class="nav-item nav-item-this"><a href="">Introduction to polexpr</a></li> + </ul> + </div> + + <div class="document"> + <div class="documentwrapper"> + <div class="bodywrapper"> + <div class="body" role="main"> + + <section id="introduction-to-polexpr"> +<h1>Introduction to polexpr</h1> +<p><a class="reference external" href="https://www.ctan.org/pkg/polexpr">polexpr</a> is a TeX and LaTeX macro package.</p> <p>To use it with Plain or formats other than LaTeX:</p> -<pre class="literal-block">\input polexpr.sty</pre> -<p>To use it with LaTeX:</p> -<pre class="literal-block">\usepackage{polexpr}</pre> -<p>The capabilities of the package are implemented via:</p> -<ul class="simple"> -<li><p>a parser <span class="docutils literal">\poldef</span> allowing to define polynomials via the usual -algebraic notations,</p></li> -<li><p>many functions available for use directly in the powerful <span class="docutils literal">\poldef</span> or -<span class="docutils literal"><span class="pre">\xintexpr/\xinteval</span></span> expandable functional syntax,</p></li> -<li><p>and macros acting on named polynomials which may serve either as -alternative to the functional interface or to provide further -capabilities, such as root localization to arbitrary precision.</p></li> -</ul> -</div> -<div class="section" id="examples-of-root-localization"> -<h1><a class="toc-backref" href="#id36">Examples of root localization</a></h1> -<p>This legacy section has been moved to the -<a class="reference external" href="polexpr-examples.pdf">polexpr-examples.pdf</a> document. -To access it (if previous link does not work):</p> -<pre class="literal-block">texdoc polexpr-examples</pre> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\input</span> polexpr.sty +</pre></div> </div> -<div class="section" id="usage-via-xintsession"> -<h1>Usage via <a class="reference external" href="https://www.ctan.org/pkg/xintsession">xintsession</a></h1> +<p>To use it with LaTeX:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="k">\usepackage</span><span class="nb">{</span>polexpr<span class="nb">}</span> +</pre></div> +</div> +<p><a class="reference external" href="https://www.ctan.org/pkg/polexpr">polexpr</a> loads <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> and extends its syntax with a polynomial type.</p> +<p>Polynomials are defined via the <a class="reference internal" href="polexpr-ref.html#quick"><span class="std std-ref">\poldef</span></a> parser and +can then be manipulated via TeX macros for various operations such +as obtaining G.C.D.s, computing derivatives, or indefinite +integrals… many of these functionalities are available directly +via functions in the syntax recognized by the <code class="docutils literal notranslate"><span class="pre">\poldef</span></code> parser.</p> +<p>Apart from the final step of internally creating some TeX macros +associated with the polynomial name, this is all done completely +expandably, and a polynomial expression can be fetched directly to +<code class="docutils literal notranslate"><span class="pre">\xinteval</span></code> for a completely expandable operation from start to +finish.</p> +<p>For polynomials fully declared via <code class="docutils literal notranslate"><span class="pre">\poldef</span></code>, root localization +implementing the <a class="reference external" href="https://en.wikipedia.org/wiki/Sturm%27s_theorem">Sturm algorithm</a> is available via macros. +Arbitrarily long decimal expansion of all real roots can be +obtained, and all rational roots can be found exactly.</p> +<p>The legacy documentation section which showed examples of root +localization has been moved to the <a class="reference external" href="polexpr-examples.pdf">polexpr-examples.pdf</a> document, where both the TeX code and its +output are displayed.</p> +<p>To access this document (if the previous link for some reason does not +work):</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span>texdoc polexpr-examples +</pre></div> +</div> +<section id="usage-via-xintsession"> +<h2>Usage via <a class="reference external" href="https://www.ctan.org/pkg/xintsession">xintsession</a></h2> <p>The simplest manner to get a feeling for the package abilities regarding -root localization is to use it on the command line via the <a class="reference external" href="https://www.ctan.org/pkg/xintsession">xintsession</a> -interface. Here is an example:</p> -<pre class="literal-block">$ rlwrap etex xintsession -[...xintsession welcome message...] -Starting in exact mode (floating point evaluations use 16 digits) ->>> &pol -pol mode (i.e. function definitions use \poldef) ->>> f(x) := x^7 - x^6 - 2x + 1; -f = x^7-x^6-2*x+1 - --> &GenFloat(f) lets f become usable as function in fp mode - --> &ROOTS(f) (resp. &ROOTS(f,N)) finds all rational roots exactly and - all irrational roots with at least 10 (resp. N) fractional digits ->>> &ROOTS(f) -Solving for real roots of f and assigning them (please wait...) -(mult. 1) Rootf_1 = -1.0719678841... -(mult. 1) Rootf_2 = 0.4962386948... -(mult. 1) Rootf_3 = 1.3151140860... -Square-free irrational part: x^7-x^6-2*x+1 - --> &REFINEROOTS(f,N) to extend real irr. roots to N fractional digits ->>> &REFINEROOTS(f,40) -Refining real roots of f to 40 digits (please wait...) -(mult. 1) Rootf_1 = -1.0719678841080266034109100331975342338141... -(mult. 1) Rootf_2 = 0.4962386948771497344730618510143671567979... -(mult. 1) Rootf_3 = 1.3151140860165192656960005018679846354234...</pre> +in particularl root localization is to use it on the command line +via the <a class="reference external" href="https://www.ctan.org/pkg/xintsession">xintsession</a> interface. Here is an example:</p> +<div class="highlight-latex notranslate"><div class="highlight"><pre><span></span><span class="s">$</span><span class="nb"> rlwrap etex xintsession</span> +<span class="o">[</span><span class="nb">...xintsession welcome message...</span><span class="o">]</span><span class="nb"></span> +<span class="nb">Starting in exact mode </span><span class="o">(</span><span class="nb">floating point evaluations use </span><span class="m">16</span><span class="nb"> digits</span><span class="o">)</span><span class="nb"></span> +<span class="nb">>>> &pol</span> +<span class="nb">pol mode </span><span class="o">(</span><span class="nb">i.e. function definitions use </span><span class="nv">\poldef</span><span class="o">)</span><span class="nb"></span> +<span class="nb">>>> f</span><span class="o">(</span><span class="nb">x</span><span class="o">)</span><span class="nb"> :</span><span class="o">=</span><span class="nb"> x^</span><span class="m">7</span><span class="nb"> </span><span class="o">-</span><span class="nb"> x^</span><span class="m">6</span><span class="nb"> </span><span class="o">-</span><span class="nb"> </span><span class="m">2</span><span class="nb">x </span><span class="o">+</span><span class="nb"> </span><span class="m">1</span><span class="nb">;</span> +<span class="nb">f </span><span class="o">=</span><span class="nb"> x^</span><span class="m">7</span><span class="o">-</span><span class="nb">x^</span><span class="m">6</span><span class="o">-</span><span class="m">2</span><span class="o">*</span><span class="nb">x</span><span class="o">+</span><span class="m">1</span><span class="nb"></span> +<span class="nb"> </span><span class="o">--</span><span class="nb">> &GenFloat</span><span class="o">(</span><span class="nb">f</span><span class="o">)</span><span class="nb"> lets f become usable as function in fp mode</span> +<span class="nb"> </span><span class="o">--</span><span class="nb">> &ROOTS</span><span class="o">(</span><span class="nb">f</span><span class="o">)</span><span class="nb"> </span><span class="o">(</span><span class="nb">resp. &ROOTS</span><span class="o">(</span><span class="nb">f,N</span><span class="o">))</span><span class="nb"> finds all rational roots exactly and</span> +<span class="nb"> all irrational roots with at least </span><span class="m">10</span><span class="nb"> </span><span class="o">(</span><span class="nb">resp. N</span><span class="o">)</span><span class="nb"> fractional digits</span> +<span class="nb">>>> &ROOTS</span><span class="o">(</span><span class="nb">f</span><span class="o">)</span><span class="nb"></span> +<span class="nb">Solving for real roots of f and assigning them </span><span class="o">(</span><span class="nb">please wait...</span><span class="o">)</span><span class="nb"></span> +<span class="o">(</span><span class="nb">mult. </span><span class="m">1</span><span class="o">)</span><span class="nb"> Rootf_</span><span class="m">1</span><span class="nb"> </span><span class="o">=</span><span class="nb"> </span><span class="o">-</span><span class="m">1</span><span class="nb">.</span><span class="m">0719678841</span><span class="nb">...</span> +<span class="o">(</span><span class="nb">mult. </span><span class="m">1</span><span class="o">)</span><span class="nb"> Rootf_</span><span class="m">2</span><span class="nb"> </span><span class="o">=</span><span class="nb"> </span><span class="m">0</span><span class="nb">.</span><span class="m">4962386948</span><span class="nb">...</span> +<span class="o">(</span><span class="nb">mult. </span><span class="m">1</span><span class="o">)</span><span class="nb"> Rootf_</span><span class="m">3</span><span class="nb"> </span><span class="o">=</span><span class="nb"> </span><span class="m">1</span><span class="nb">.</span><span class="m">3151140860</span><span class="nb">...</span> +<span class="nb">Square</span><span class="o">-</span><span class="nb">free irrational part: x^</span><span class="m">7</span><span class="o">-</span><span class="nb">x^</span><span class="m">6</span><span class="o">-</span><span class="m">2</span><span class="o">*</span><span class="nb">x</span><span class="o">+</span><span class="m">1</span><span class="nb"></span> +<span class="nb"> </span><span class="o">--</span><span class="nb">> &REFINEROOTS</span><span class="o">(</span><span class="nb">f,N</span><span class="o">)</span><span class="nb"> to extend real irr. roots to N fractional digits</span> +<span class="nb">>>> &REFINEROOTS</span><span class="o">(</span><span class="nb">f,</span><span class="m">40</span><span class="o">)</span><span class="nb"></span> +<span class="nb">Refining real roots of f to </span><span class="m">40</span><span class="nb"> digits </span><span class="o">(</span><span class="nb">please wait...</span><span class="o">)</span><span class="nb"></span> +<span class="o">(</span><span class="nb">mult. </span><span class="m">1</span><span class="o">)</span><span class="nb"> Rootf_</span><span class="m">1</span><span class="nb"> </span><span class="o">=</span><span class="nb"> </span><span class="o">-</span><span class="m">1</span><span class="nb">.</span><span class="m">0719678841080266034109100331975342338141</span><span class="nb">...</span> +<span class="o">(</span><span class="nb">mult. </span><span class="m">1</span><span class="o">)</span><span class="nb"> Rootf_</span><span class="m">2</span><span class="nb"> </span><span class="o">=</span><span class="nb"> </span><span class="m">0</span><span class="nb">.</span><span class="m">4962386948771497344730618510143671567979</span><span class="nb">...</span> +<span class="o">(</span><span class="nb">mult. </span><span class="m">1</span><span class="o">)</span><span class="nb"> Rootf_</span><span class="m">3</span><span class="nb"> </span><span class="o">=</span><span class="nb"> </span><span class="m">1</span><span class="nb">.</span><span class="m">3151140860165192656960005018679846354234</span><span class="nb">...</span> +</pre></div> +</div> <p>The <a class="reference external" href="https://www.ctan.org/pkg/xintsession">xintsession</a> interface allows to define polynomial variables via its -<span class="docutils literal">&pol</span> mode. It also exposes <a class="reference internal" href="#polexpr08">all polynomial functions added to the -xintexpr syntax</a> by <span class="docutils literal">polexpr</span>. Further, as seen in the -example above it also covers some of the <span class="docutils literal">polexpr</span> capabilities +<code class="docutils literal notranslate"><span class="pre">&pol</span></code> mode. It also exposes <a class="reference internal" href="polexpr-ref.html#polexpr08"><span class="std std-ref">all polynomial functions added to the +xintexpr syntax</span></a> by <code class="docutils literal notranslate"><span class="pre">polexpr</span></code>. Further, as seen in the +example above it also covers some of the <code class="docutils literal notranslate"><span class="pre">polexpr</span></code> capabilities currently implemented via user macros. This is to be considered a work -in progress, the above <span class="docutils literal">&ROOTS</span> and <span class="docutils literal">&REFINEROOTS</span> may be renamed +in progress, the above <code class="docutils literal notranslate"><span class="pre">&ROOTS</span></code> and <code class="docutils literal notranslate"><span class="pre">&REFINEROOTS</span></code> may be renamed into something else, and may have been so already since this documentation was written.</p> -<p>Any input on the command line at the <a class="reference external" href="https://www.ctan.org/pkg/xintsession">xintsession</a> <span class="docutils literal">>>></span> prompt which +<p>Any input on the command line at the <a class="reference external" href="https://www.ctan.org/pkg/xintsession">xintsession</a> <code class="docutils literal notranslate"><span class="pre">>>></span></code> prompt which starts with a backslash is executed as TeX macros, so all macros of -<span class="docutils literal">polexpr</span> are in fact already available, including those typesetting +<code class="docutils literal notranslate"><span class="pre">polexpr</span></code> are in fact already available, including those typesetting material in background of the interactive session on command line. The -<span class="docutils literal">&ROOTS</span> and <span class="docutils literal">&REFINEROOTS</span> direct their outputs to the +<code class="docutils literal notranslate"><span class="pre">&ROOTS</span></code> and <code class="docutils literal notranslate"><span class="pre">&REFINEROOTS</span></code> direct their outputs to the terminal rather than to the TeX page as would the typesetting macros -defined by <span class="docutils literal">polexpr</span> itself.</p> -<div class="contents topic" id="contents"> -<p class="topic-title">Contents</p> -<ul class="simple"> -<li><p><a class="reference internal" href="#introduction" id="id35">Introduction</a></p></li> -<li><p><a class="reference internal" href="#examples-of-root-localization" id="id36">Examples of root localization</a></p></li> -<li><p><a class="reference internal" href="#usage-via-xintsession" id="id37">Usage via xintsession</a></p></li> -<li><p><a class="reference internal" href="#quick-syntax-overview" id="id38">Quick syntax overview</a></p></li> -<li><p><a class="reference internal" href="#the-polexpr-0-8-extensions-to-the-xintexpr-syntax" id="id39">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="id40">Warning about unstability of the new syntax</a></p></li> -<li><p><a class="reference internal" href="#infix-operators" id="id41">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="id42">Experimental infix operators <span class="docutils literal">//, /:</span></a></p></li> -<li><p><a class="reference internal" href="#comparison-operators" id="id43">Comparison operators <span class="docutils literal"><, >, <=, >=, ==, !=</span></a></p></li> -<li><p><a class="reference internal" href="#pol-nutple-expression" id="id44"><span class="docutils literal"><span class="pre">pol(<nutple</span> expression>)</span></a></p></li> -<li><p><a class="reference internal" href="#lpol-nutple-expression" id="id45"><span class="docutils literal"><span class="pre">lpol(<nutple</span> expression>)</span></a></p></li> -<li><p><a class="reference internal" href="#xinteval-pol-expr" id="id46"><span class="docutils literal"><span class="pre">\xinteval{<pol.</span> <span class="pre">expr.>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#evalp-pol-expr-pol-expr" id="id47"><span class="docutils literal"><span class="pre">evalp(<pol.</span> <span class="pre">expr.>,</span> <pol. expr>)</span></a></p></li> -<li><p><a class="reference internal" href="#deg-pol-expr" id="id48"><span class="docutils literal"><span class="pre">deg(<pol.</span> <span class="pre">expr.>)</span></span></a></p></li> -<li><p><a class="reference internal" href="#coeffs-pol-expr" id="id49"><span class="docutils literal"><span class="pre">coeffs(<pol.</span> <span class="pre">expr.>)</span></span></a></p></li> -<li><p><a class="reference internal" href="#lcoeffs-pol-expr" id="id50"><span class="docutils literal"><span class="pre">lcoeffs(<pol.</span> <span class="pre">expr.>)</span></span></a></p></li> -<li><p><a class="reference internal" href="#coeff-pol-expr-num-expr" id="id51"><span class="docutils literal"><span class="pre">coeff(<pol.</span> <span class="pre">expr.>,</span> <num. <span class="pre">expr.>)</span></span></a></p></li> -<li><p><a class="reference internal" href="#lc-pol-expr" id="id52"><span class="docutils literal"><span class="pre">lc(<pol.</span> <span class="pre">expr.>)</span></span></a></p></li> -<li><p><a class="reference internal" href="#monicpart-pol-expr" id="id53"><span class="docutils literal"><span class="pre">monicpart(<pol.</span> <span class="pre">expr.>)</span></span></a></p></li> -<li><p><a class="reference internal" href="#cont-pol-expr" id="id54"><span class="docutils literal"><span class="pre">cont(<pol.</span> <span class="pre">expr.>)</span></span></a></p></li> -<li><p><a class="reference internal" href="#primpart-pol-expr" id="id55"><span class="docutils literal"><span class="pre">primpart(<pol.</span> <span class="pre">expr.>)</span></span></a></p></li> -<li><p><a class="reference internal" href="#quorem-pol-expr-pol-expr" id="id56"><span class="docutils literal"><span class="pre">quorem(<pol.</span> <span class="pre">expr.>,</span> <pol. <span class="pre">expr.>)</span></span></a></p></li> -<li><p><a class="reference internal" href="#quo-pol-expr-pol-expr" id="id57"><span class="docutils literal"><span class="pre">quo(<pol.</span> <span class="pre">expr.>,</span> <pol. <span class="pre">expr.>)</span></span></a></p></li> -<li><p><a class="reference internal" href="#rem-pol-expr-pol-expr" id="id58"><span class="docutils literal"><span class="pre">rem(<pol.</span> <span class="pre">expr.>,</span> <pol. <span class="pre">expr.>)</span></span></a></p></li> -<li><p><a class="reference internal" href="#prem-pol-expr-1-pol-expr-2" id="id59"><span class="docutils literal"><span class="pre">prem(<pol.</span> expr. 1>, <pol. expr. 2>)</span></a></p></li> -<li><p><a class="reference internal" href="#divmod-pol-expr-1-pol-expr-2" id="id60"><span class="docutils literal"><span class="pre">divmod(<pol.</span> expr. 1>, <pol. expr. 2>)</span></a></p></li> -<li><p><a class="reference internal" href="#mod-pol-expr-1-pol-expr-2" id="id61"><span class="docutils literal"><span class="pre">mod(<pol.</span> expr. 1>, <pol. expr. 2>)</span></a></p></li> -<li><p><a class="reference internal" href="#polgcd-pol-expr-1-pol-expr-2" id="id62"><span class="docutils literal"><span class="pre">polgcd(<pol.</span> expr. 1>, <pol. expr. 2>, <span class="pre">...)</span></span></a></p></li> -<li><p><a class="reference internal" href="#resultant-pol-expr-1-pol-expr-2" id="id63"><span class="docutils literal"><span class="pre">resultant(<pol.</span> expr. 1>, <pol. expr. 2>)</span></a></p></li> -<li><p><a class="reference internal" href="#disc-pol-expr" id="id64"><span class="docutils literal"><span class="pre">disc(<pol.</span> <span class="pre">expr.>)</span></span></a></p></li> -<li><p><a class="reference internal" href="#polpowmod-pol-expr-1-num-expr-pol-expr-2" id="id65"><span class="docutils literal"><span class="pre">polpowmod(<pol.</span> expr. 1>, <num. <span class="pre">expr.>,</span> <pol. expr. 2>)</span></a></p></li> -<li><p><a class="reference internal" href="#rdcoeffs-pol-expr" id="id66"><span class="docutils literal"><span class="pre">rdcoeffs(<pol.</span> <span class="pre">expr.>)</span></span></a></p></li> -<li><p><a class="reference internal" href="#rdzcoeffs-pol-expr" id="id67"><span class="docutils literal"><span class="pre">rdzcoeffs(<pol.</span> <span class="pre">expr.>)</span></span></a></p></li> -<li><p><a class="reference internal" href="#diff1-pol-expr" id="id68"><span class="docutils literal"><span class="pre">diff1(<pol.</span> <span class="pre">expr.>)</span></span></a></p></li> -<li><p><a class="reference internal" href="#diff2-pol-expr" id="id69"><span class="docutils literal"><span class="pre">diff2(<pol.</span> <span class="pre">expr.>)</span></span></a></p></li> -<li><p><a class="reference internal" href="#diffn-pol-expr-p-num-expr-n" id="id70"><span class="docutils literal"><span class="pre">diffn(<pol.</span> expr. P>, <num. expr. n>)</span></a></p></li> -<li><p><a class="reference internal" href="#antider-pol-expr-p" id="id71"><span class="docutils literal"><span class="pre">antider(<pol.</span> expr. P>)</span></a></p></li> -<li><p><a class="reference internal" href="#intfrom-pol-expr-p-pol-expr-c" id="id72"><span class="docutils literal"><span class="pre">intfrom(<pol.</span> expr. P>, <pol. expr. c>)</span></a></p></li> -<li><p><a class="reference internal" href="#integral-pol-expr-p-pol-expr-a-pol-expr-b" id="id73"><span class="docutils literal"><span class="pre">integral(<pol.</span> expr. P>, [<pol. expr. a>, <pol. expr. <span class="pre">b>])</span></span></a></p></li> -</ul> -</li> -<li><p><a class="reference internal" href="#non-expandable-macros" id="id74">Non-expandable macros</a></p> -<ul> -<li><p><a class="reference internal" href="#poldef-polname-letter-expression-using-the-letter-as-indeterminate" id="id75"><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-expr-using-the-letter-as-indeterminate" id="id76"><span class="docutils literal"><span class="pre">\PolDef[<letter>]{<polname>}{<expr.</span> using the letter as indeterminate>}</span></a></p></li> -<li><p><a class="reference internal" href="#polgenfloatvariant-polname" id="id77"><span class="docutils literal"><span class="pre">\PolGenFloatVariant{<polname>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#poltypeset-pol-expr" id="id78"><span class="docutils literal"><span class="pre">\PolTypeset{<pol.</span> <span class="pre">expr.>}</span></span></a></p> -<ul> -<li><p><a class="reference internal" href="#poltypesetcmd-raw-coeff" id="id79"><span class="docutils literal"><span class="pre">\PolTypesetCmd{<raw_coeff>}</span></span></a></p> -<ul> -<li><p><a class="reference internal" href="#polifcoeffisplusorminusone-t-f" id="id80"><span class="docutils literal"><span class="pre">\PolIfCoeffIsPlusOrMinusOne{T}{F}</span></span></a></p></li> -</ul> -</li> -<li><p><a class="reference internal" href="#poltypesetone-raw-coeff" id="id81"><span class="docutils literal"><span class="pre">\PolTypesetOne{<raw_coeff>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#id9" id="id82"><span class="docutils literal">\PolTypesetMonomialCmd</span></a></p></li> -<li><p><a class="reference internal" href="#poltypesetcmdprefix-raw-coeff" id="id83"><span class="docutils literal"><span class="pre">\PolTypesetCmdPrefix{<raw_coeff>}</span></span></a></p></li> -</ul> -</li> -<li><p><a class="reference internal" href="#id11" id="id84"><span class="docutils literal"><span class="pre">\PolTypeset*{<pol.</span> <span class="pre">expr.>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#non-expandable-macros-related-to-the-root-localization-routines" id="id85">Non-expandable macros related to the root localization routines</a></p> -<ul> -<li><p><a class="reference internal" href="#poltosturm-polname-sturmname" id="id86"><span class="docutils literal"><span class="pre">\PolToSturm{<polname>}{<sturmname>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#id13" id="id87"><span class="docutils literal"><span class="pre">\PolToSturm*{<polname>}{<sturmname>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#polsturmisolatezeros-sturmname" id="id88"><span class="docutils literal"><span class="pre">\PolSturmIsolateZeros{<sturmname>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#id15" id="id89"><span class="docutils literal"><span class="pre">\PolSturmIsolateZeros*{<sturmname>}</span></span></a></p> -<ul> -<li><p><a class="reference internal" href="#polsturmisolatezerosandgetmultiplicities-sturmname" id="id90"><span class="docutils literal"><span class="pre">\PolSturmIsolateZerosAndGetMultiplicities{<sturmname>}</span></span></a></p></li> -</ul> -</li> -<li><p><a class="reference internal" href="#id17" id="id91"><span class="docutils literal"><span class="pre">\PolSturmIsolateZeros**{<sturmname>}</span></span></a></p> -<ul> -<li><p><a class="reference internal" href="#polsturmisolatezerosgetmultiplicitiesandrationalroots-sturmname" id="id92"><span class="docutils literal"><span class="pre">\PolSturmIsolateZerosGetMultiplicitiesAndRationalRoots{<sturmname>}</span></span></a></p></li> -</ul> -</li> -<li><p><a class="reference internal" href="#polsturmisolatezerosandfindrationalroots-sturmname" id="id93"><span class="docutils literal"><span class="pre">\PolSturmIsolateZerosAndFindRationalRoots{<sturmname>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#polrefineinterval-sturmname-index" id="id94"><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="id95"><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-exponent" id="id96"><span class="docutils literal"><span class="pre">\PolEnsureIntervalLength{<sturmname>}{<index>}{<exponent>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#polensureintervallengths-sturmname-exponent" id="id97"><span class="docutils literal"><span class="pre">\PolEnsureIntervalLengths{<sturmname>}{<exponent>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#polprintintervals-varname-sturmname" id="id98"><span class="docutils literal"><span class="pre">\PolPrintIntervals[<varname>]{<sturmname>}</span></span></a></p> -<ul> -<li><p><a class="reference internal" href="#polprintintervalsnorealroots" id="id99"><span class="docutils literal">\PolPrintIntervalsNoRealRoots</span></a></p></li> -<li><p><a class="reference internal" href="#polprintintervalsbeginenv" id="id100"><span class="docutils literal">\PolPrintIntervalsBeginEnv</span></a></p></li> -<li><p><a class="reference internal" href="#polprintintervalsendenv" id="id101"><span class="docutils literal">\PolPrintIntervalsEndEnv</span></a></p></li> -<li><p><a class="reference internal" href="#polprintintervalsrowseparator" id="id102"><span class="docutils literal">\PolPrintIntervalsRowSeparator</span></a></p></li> -<li><p><a class="reference internal" href="#polprintintervalsknownroot" id="id103"><span class="docutils literal">\PolPrintIntervalsKnownRoot</span></a></p></li> -<li><p><a class="reference internal" href="#polprintintervalsunknownroot" id="id104"><span class="docutils literal">\PolPrintIntervalsUnknownRoot</span></a></p></li> -<li><p><a class="reference internal" href="#id18" id="id105"><span class="docutils literal">\PolPrintIntervalsPrintExactZero</span></a></p></li> -<li><p><a class="reference internal" href="#id19" id="id106"><span class="docutils literal">\PolPrintIntervalsPrintLeftEndPoint</span></a></p></li> -<li><p><a class="reference internal" href="#id20" id="id107"><span class="docutils literal">\PolPrintIntervalsPrintRightEndPoint</span></a></p></li> -</ul> -</li> -<li><p><a class="reference internal" href="#id22" id="id108"><span class="docutils literal"><span class="pre">\PolPrintIntervals*[<varname>]{<sturmname>}</span></span></a></p> -<ul> -<li><p><a class="reference internal" href="#polprintintervalsprintmultiplicity" id="id109"><span class="docutils literal">\PolPrintIntervalsPrintMultiplicity</span></a></p></li> -</ul> -</li> -<li><p><a class="reference internal" href="#polsettosturmchainsignchangesat-foo-sturmname-value" id="id110"><span class="docutils literal"><span class="pre">\PolSetToSturmChainSignChangesAt{\foo}{<sturmname>}{<value>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#polsettonbofzeroswithin-foo-sturmname-value-left-value-right" id="id111"><span class="docutils literal"><span class="pre">\PolSetToNbOfZerosWithin{\foo}{<sturmname>}{<value_left>}{<value_right>}</span></span></a></p></li> -</ul> -</li> -<li><p><a class="reference internal" href="#pollet-polname-2-polname-1" id="id112"><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="id113"><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="id114"><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="id115"><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="id116"><span class="docutils literal"><span class="pre">\PolFromCSV{<polname>}{<csv>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#polmapcoeffs-macro-polname" id="id117"><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="id118"><span class="docutils literal"><span class="pre">\PolReduceCoeffs{<polname>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#id24" id="id119"><span class="docutils literal"><span class="pre">\PolReduceCoeffs*{<polname>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#polmakemonic-polname" id="id120"><span class="docutils literal"><span class="pre">\PolMakeMonic{<polname>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#polmakeprimitive-polname" id="id121"><span class="docutils literal"><span class="pre">\PolMakePrimitive{<polname>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#poldiff-polname-1-polname-2" id="id122"><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="id123"><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="id124"><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="id125"><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="id126"><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="id127"><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="id128"><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="id129"><span class="docutils literal"><span class="pre">\PolGCD{<polname_1>}{<polname_2>}{<polname_GCD>}</span></span></a></p></li> -</ul> -</li> -<li><p><a class="reference internal" href="#expandable-macros" id="id130">Expandable macros</a></p> -<ul> -<li><p><a class="reference internal" href="#poltoexpr-pol-expr" id="id131"><span class="docutils literal"><span class="pre">\PolToExpr{<pol.</span> <span class="pre">expr.>}</span></span></a></p> -<ul> -<li><p><a class="reference internal" href="#id27" id="id132"><span class="docutils literal">\PolToExprVar</span></a></p></li> -<li><p><a class="reference internal" href="#poltoexprinvar" id="id133"><span class="docutils literal">\PolToExprInVar</span></a></p></li> -<li><p><a class="reference internal" href="#id28" id="id134"><span class="docutils literal">\PolToExprTimes</span></a></p></li> -<li><p><a class="reference internal" href="#poltoexprcaret" id="id135"><span class="docutils literal">\PolToExprCaret</span></a></p></li> -<li><p><a class="reference internal" href="#poltoexprcmd-raw-coeff" id="id136"><span class="docutils literal"><span class="pre">\PolToExprCmd{<raw_coeff>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#poltoexproneterm-raw-coeff-exponent" id="id137"><span class="docutils literal"><span class="pre">\PolToExprOneTerm{<raw_coeff>}{<exponent>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#poltoexpronetermstylea-raw-coeff-exponent" id="id138"><span class="docutils literal"><span class="pre">\PolToExprOneTermStyleA{<raw_coeff>}{<exponent>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#poltoexpronetermstyleb-raw-coeff-exponent" id="id139"><span class="docutils literal"><span class="pre">\PolToExprOneTermStyleB{<raw_coeff>}{<exponent>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#poltoexprtermprefix-raw-coeff" id="id140"><span class="docutils literal"><span class="pre">\PolToExprTermPrefix{<raw_coeff>}</span></span></a></p></li> -</ul> -</li> -<li><p><a class="reference internal" href="#poltofloatexpr-pol-expr" id="id141"><span class="docutils literal"><span class="pre">\PolToFloatExpr{<pol.</span> <span class="pre">expr.>}</span></span></a></p> -<ul> -<li><p><a class="reference internal" href="#poltofloatexproneterm-raw-coeff-exponent" id="id142"><span class="docutils literal"><span class="pre">\PolToFloatExprOneTerm{<raw_coeff>}{<exponent>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#poltofloatexprcmd-raw-coeff" id="id143"><span class="docutils literal"><span class="pre">\PolToFloatExprCmd{<raw_coeff>}</span></span></a></p></li> -</ul> -</li> -<li><p><a class="reference internal" href="#id30" id="id144"><span class="docutils literal"><span class="pre">\PolToExpr*{<pol.</span> <span class="pre">expr.>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#id32" id="id145"><span class="docutils literal"><span class="pre">\PolToFloatExpr*{<pol.</span> <span class="pre">expr.>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#polnthcoeff-polname-index" id="id146"><span class="docutils literal"><span class="pre">\PolNthCoeff{<polname>}{<index>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#polleadingcoeff-polname" id="id147"><span class="docutils literal"><span class="pre">\PolLeadingCoeff{<polname>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#poldegree-polname" id="id148"><span class="docutils literal"><span class="pre">\PolDegree{<polname>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#policontent-polname" id="id149"><span class="docutils literal"><span class="pre">\PolIContent{<polname>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#poltolist-polname" id="id150"><span class="docutils literal"><span class="pre">\PolToList{<polname>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#poltocsv-polname" id="id151"><span class="docutils literal"><span class="pre">\PolToCSV{<polname>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#poleval-polname-atexpr-num-expr" id="id152"><span class="docutils literal"><span class="pre">\PolEval{<polname>}\AtExpr{<num.</span> <span class="pre">expr.>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#poleval-polname-at-value" id="id153"><span class="docutils literal"><span class="pre">\PolEval{<polname>}\At{<value>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#polevalreduced-polname-atexpr-num-expr" id="id154"><span class="docutils literal"><span class="pre">\PolEvalReduced{<polname>}\AtExpr{<num.</span> <span class="pre">expr.>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#polevalreduced-polname-at-value" id="id155"><span class="docutils literal"><span class="pre">\PolEvalReduced{<polname>}\At{<value>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#polfloateval-polname-atexpr-num-expr" id="id156"><span class="docutils literal"><span class="pre">\PolFloatEval{<polname>}\AtExpr{<num.</span> <span class="pre">expr.>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#polfloateval-polname-at-value" id="id157"><span class="docutils literal"><span class="pre">\PolFloatEval{<polname>}\At{<value>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#expandable-macros-related-to-the-root-localization-routines" id="id158">Expandable macros related to the root localization routines</a></p> -<ul> -<li><p><a class="reference internal" href="#polsturmchainlength-sturmname" id="id159"><span class="docutils literal"><span class="pre">\PolSturmChainLength{<sturmname>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#polsturmifzeroexactlyknown-sturmname-index-t-f" id="id160"><span class="docutils literal"><span class="pre">\PolSturmIfZeroExactlyKnown{<sturmname>}{<index>}{T}{F}</span></span></a></p></li> -<li><p><a class="reference internal" href="#polsturmisolatedzeroleft-sturmname-index" id="id161"><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="id162"><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="id163"><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="id164"><span class="docutils literal"><span class="pre">\PolSturmNbOfIsolatedZeros{<sturmname>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#polsturmnbofrootsof-sturmname-lessthanorequalto-value" id="id165"><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-num-expr" id="id166"><span class="docutils literal"><span class="pre">\PolSturmNbOfRootsOf{<sturmname>}\LessThanOrEqualToExpr{<num.</span> <span class="pre">expr.>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#polsturmnbwithmultofrootsof-sturmname-lessthanorequalto-value" id="id167"><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-num-expr" id="id168"><span class="docutils literal"><span class="pre">\PolSturmNbWithMultOfRootsOf{<sturmname>}\LessThanOrEqualToExpr{<num.</span> <span class="pre">expr.>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#polsturmnbofrationalroots-sturmname" id="id169"><span class="docutils literal"><span class="pre">\PolSturmNbOfRationalRoots{<sturmname>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#polsturmnbofrationalrootswithmultiplicities-sturmname" id="id170"><span class="docutils literal"><span class="pre">\PolSturmNbOfRationalRootsWithMultiplicities{<sturmname>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#polsturmrationalroot-sturmname-k" id="id171"><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="id172"><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="id173"><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="id174"><span class="docutils literal"><span class="pre">\PolIntervalWidth{<sturmname>}{<index>}</span></span></a></p></li> -<li><p><a class="reference internal" href="#expandable-macros-for-use-within-execution-of-polprintintervals" id="id175">Expandable macros for use within execution of <span class="docutils literal">\PolPrintIntervals</span></a></p></li> -<li><p><a class="reference internal" href="#polprintintervalsthevar" id="id176"><span class="docutils literal">\PolPrintIntervalsTheVar</span></a></p></li> -<li><p><a class="reference internal" href="#polprintintervalstheindex" id="id177"><span class="docutils literal">\PolPrintIntervalsTheIndex</span></a></p></li> -<li><p><a class="reference internal" href="#polprintintervalsthesturmname" id="id178"><span class="docutils literal">\PolPrintIntervalsTheSturmName</span></a></p></li> -<li><p><a class="reference internal" href="#polprintintervalstheleftendpoint" id="id179"><span class="docutils literal">\PolPrintIntervalsTheLeftEndPoint</span></a></p></li> -<li><p><a class="reference internal" href="#polprintintervalstherightendpoint" id="id180"><span class="docutils literal">\PolPrintIntervalsTheRightEndPoint</span></a></p></li> -<li><p><a class="reference internal" href="#polprintintervalsthemultiplicity" id="id181"><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="id182">Booleans (with default setting as indicated)</a></p> -<ul> -<li><p><a class="reference internal" href="#xintverbosefalse" id="id183"><span class="docutils literal">\xintverbosefalse</span></a></p></li> -<li><p><a class="reference internal" href="#polnewpolverbosefalse" id="id184"><span class="docutils literal">\polnewpolverbosefalse</span></a></p></li> -<li><p><a class="reference internal" href="#poltypesetallfalse" id="id185"><span class="docutils literal">\poltypesetallfalse</span></a></p></li> -<li><p><a class="reference internal" href="#poltoexprallfalse" id="id186"><span class="docutils literal">\poltoexprallfalse</span></a></p></li> -</ul> -</li> -<li><p><a class="reference internal" href="#utilies" id="id187">Utilies</a></p> -<ul> -<li><p><a class="reference internal" href="#poldectostring-decimal-number" id="id188"><span class="docutils literal">\PolDecToString{decimal number}</span></a></p></li> -<li><p><a class="reference internal" href="#polexprsetup" id="id189"><span class="docutils literal">\polexprsetup</span></a></p></li> -</ul> -</li> -<li><p><a class="reference internal" href="#technicalities" id="id190">Technicalities</a></p></li> -<li><p><a class="reference internal" href="#change-log" id="id191">CHANGE LOG</a></p></li> -<li><p><a class="reference internal" href="#acknowledgments" id="id192">Acknowledgments</a></p></li> -</ul> -</div> -</div> -<div class="section" id="quick-syntax-overview"> -<h1><a class="toc-backref" href="#id38">Quick syntax overview</a></h1> -<p>The syntax to define a new polynomial is:</p> -<pre class="literal-block">\poldef polname(x):= expression in variable x;</pre> -<p>The package is focused on exact computations, so this expression will be -parsed by the services of <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> and accept arbitrarily big integers -or fractions.</p> -<p>If you are interested into numerical evaluations, for example for -plotting, it is advisable to use the <span class="docutils literal"><span class="pre">\xintfloatexpr/\xintfloateval</span></span> -context, as exact evaluations will quickly lead to manipulating numbers -with dozens of digits (when the number of digits exceeds five hundreds, -computation with <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> will become noticeably too slow, if many -evaluations need to be done). For the polynomial to be usable as a function in -floating point context, an extra step beyond <span class="docutils literal">\poldef</span> is required: -see <a class="reference internal" href="#polgenfloatvariant">\PolGenFloatVariant</a>.</p> -<p>As a rule, the functionalities such as getting the degree, or getting -one coefficient, or taking derivatives, etc..., i.e. anything which -handles the polynomial as an entity and not only as a numerical -function, are only available in the <span class="docutils literal"><span class="pre">\poldef/\xintexpr/\xinteval</span></span> -context. The <a class="reference internal" href="#polgenfloatvariant">\PolGenFloatVariant</a> must be used each time the -polynomial gets modified or a new polynomial created out of it, if -continuing computations in <span class="docutils literal">\xintfloatexpr</span> are to follow. But (see -<a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> documentation) one can always use a sub-expression such as -<span class="docutils literal">\xintexpr <span class="pre">deg(P)\relax</span></span> as sub-component inside a -<span class="docutils literal"><span class="pre">\xintfloatexpr/\xintfloateval</span></span>.</p> -<p>Conversely if perhaps the coefficients of your polynomial have become -too gigantic and you would like to replace them with some approximation -to keep on working in <span class="docutils literal">\xinteval</span>, not necessarily <span class="docutils literal">\xintfloateval</span>, -see <a class="reference internal" href="#polmapcoeffs">\PolMapCoeffs</a> which can be used for example with <span class="docutils literal">\xintFloat</span> -macro to make the float-rounding applied to the exact coefficients.</p> -<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">@</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">@</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">@</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 (reasonable) -catcode does not matter.</p></li> -<li><p>The semi-colon at the end of the expression is mandatory. Some -contexts (such as (pdf)LaTeX with babel+frenchb) modify its catcode. -If at top level, <span class="docutils literal">\poldef</span> resets temporarily the semi-colon catcode -before fetching the expression, so is immune to this. There is also -naturally no problem either if <span class="docutils literal">\poldef</span> is used in the replacement -text of some other macro which is defined at a time the <span class="docutils literal">;</span> has its -standard catcode, as is the case in LaTeX in the document preamble, -even with babel+french loaded.</p> -<p>The semi-colon intervenes in certain <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> syntax elements, within -parentheses. This (except if the inner semi-colons are hidden within -braces: <span class="docutils literal">{;}</span>) will break <span class="docutils literal">\poldef</span> which, contrarily to -<a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a>'s <span class="docutils literal">\xintdefvar</span>, does not balance parentheses when -fetching the semi-colon delimited polynomial expression.</p> -</li> -</ul> -<p>Problems with the semi-colon are avoided via an alternative syntax:</p> -<pre class="literal-block">\PolDef[optional letter]{<polname>}{<expr. using letter as indeterminate>}</pre> -<p>The <span class="docutils literal">\PolDef</span> optional first argument defaults to <span class="docutils literal">x</span> and must be -used as the indeterminate in the expression.</p> -<p><span class="docutils literal">\poldef <span class="pre">f(x):=</span> 1 - x + quo(x^5,1 - x + x^2);</span></p> -<dl> -<dt><span class="docutils literal"><span class="pre">\PolDef{f}{1</span> - x + quo(x^5,1 - x + x^2)}</span></dt> -<dd><p>Both parse the polynomial -expression, and convert it internally (currently) to the list -of its coefficients from the constant term to the highest degree -term.</p> -<p>The polynomial can then be used in further polynomial definitions or -serve as argument to package macros, or as a variable in various -functions which will be <a class="reference internal" href="#polexpr08">described later</a>.</p> -</dd> -</dl> -<div class="admonition important"> -<p class="admonition-title">Important</p> -<p>Euclidean quotient is mapped to the function <span class="docutils literal">quo()</span> (as shown -in the example above), but -for backwards compatibility one can currently still use the <span class="docutils literal">/</span> -infix operator:</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="https://www.ctan.org/pkg/xintexpr">xintexpr</a>'s tacit multiplication always "ties more", 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 release <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)% <--- 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)% <--- attention!</pre> -<p>will compute <span class="docutils literal">P*3</span>, because one can not in current <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">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="https://www.ctan.org/pkg/xintexpr">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> -<p>It may look strange that an indeterminate variable is used on -left-hand-side even though it may be absent of right-hand-side, as -it seems to define <span class="docutils literal">f</span> always as a polynomial function.</p> -<p>This is a legacy of pre-<span class="docutils literal">0.8</span> context.</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{<pol. expr.>}</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="#id39">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="#id40">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="#id41">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> -<div class="section" id="experimental-infix-operators"> -<h2><a class="toc-backref" href="#id42">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="#id43">Comparison operators <span class="docutils literal"><, >, <=, >=, ==, !=</span></a></h2> -<blockquote> -<p><strong>NOT YET IMPLEMENTED</strong></p> -<p>As the internal representation by <a class="reference external" href="https://www.ctan.org/pkg/xint">xintfrac</a> and <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">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="https://www.ctan.org/pkg/xintexpr">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="#id44"><span class="docutils literal"><span class="pre">pol(<nutple</span> expression>)</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 "nutple".</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 "variable" 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="lpol-nutple-expression"> -<span id="lpol"></span><h2><a class="toc-backref" href="#id45"><span class="docutils literal"><span class="pre">lpol(<nutple</span> expression>)</span></a></h2> -<blockquote> -<p>This converts a nutple <span class="docutils literal"><span class="pre">[cN,...,c1,c0]</span></span> into the polynomial -variable having these coefficients, with leading coefficients coming -first in the input. Attention that the square brackets are -<strong>mandatory</strong>, except of course if the argument is actually an -expression producing such a "nutple".</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> -<p><strong>NAME UNSTABLE</strong></p> -</blockquote> -<p>It can be used in <span class="docutils literal">\poldef</span> as an alternative input syntax, which -is more efficient than using the algebraic notation with monomials.</p> -<p>(new with <span class="docutils literal">0.8.1</span>, an empty nutple will cause breakage)</p> -</blockquote> -</div> -<div class="section" id="xinteval-pol-expr"> -<h2><a class="toc-backref" href="#id46"><span class="docutils literal"><span class="pre">\xinteval{<pol.</span> <span class="pre">expr.>}</span></span></a></h2> -<blockquote> -<p>This is documented here for lack of a better place: it evaluates the -polynomial expression then outputs the "string" <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 "pol" 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="#id47"><span class="docutils literal"><span class="pre">evalp(<pol.</span> <span class="pre">expr.>,</span> <pol. expr>)</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="https://www.ctan.org/pkg/xintexpr">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="https://www.ctan.org/pkg/xintexpr">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="#id48"><span class="docutils literal"><span class="pre">deg(<pol.</span> <span class="pre">expr.>)</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)<0</span></span> correctly detects the zero polynomial, -and <span class="docutils literal"><span class="pre">deg(P)<=0</span></span> detects scalars.</p> -</div> -</div> -<div class="section" id="coeffs-pol-expr"> -<h2><a class="toc-backref" href="#id49"><span class="docutils literal"><span class="pre">coeffs(<pol.</span> <span class="pre">expr.>)</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="https://www.ctan.org/pkg/xintexpr">xintexpr</a>.</p> -</blockquote> -</blockquote> -</div> -<div class="section" id="lcoeffs-pol-expr"> -<span id="lcoeffs"></span><h2><a class="toc-backref" href="#id50"><span class="docutils literal"><span class="pre">lcoeffs(<pol.</span> <span class="pre">expr.>)</span></span></a></h2> -<blockquote> -<p>Produces the nutple <span class="docutils literal"><span class="pre">[cN,....,c1,c0]</span></span> of coefficients, starting -with the highest degree coefficient.</p> -<p>(new with <span class="docutils literal">0.8.1</span>)</p> -</blockquote> -</div> -<div class="section" id="coeff-pol-expr-num-expr"> -<h2><a class="toc-backref" href="#id51"><span class="docutils literal"><span class="pre">coeff(<pol.</span> <span class="pre">expr.>,</span> <num. <span class="pre">expr.>)</span></span></a></h2> -<blockquote> -<p>As expected. Produces zero if the numerical index is negative or -higher than the degree.</p> -<blockquote> -<p><strong>name, syntax and output 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="https://www.ctan.org/pkg/xintexpr">xintexpr</a>.</p> -<p>The current behaviour is at odds with legacy -<a class="reference internal" href="#polnthcoeff-polname-index">\PolNthCoeff{<polname>}{<index>}</a> regarding negative indices. -Accessing leading or sub-leading coefficients can be done with -other syntax, see <a class="reference internal" href="#lc-pol-expr">lc(<pol. expr.>)</a>, and in some contexts it -is useful to be able to rely on the fact that coefficients with -negative indices do vanish, so I am for time being maintaining this.</p> -</blockquote> -</blockquote> -</div> -<div class="section" id="lc-pol-expr"> -<span id="lc"></span><h2><a class="toc-backref" href="#id52"><span class="docutils literal"><span class="pre">lc(<pol.</span> <span class="pre">expr.>)</span></span></a></h2> -<blockquote> -<p>The leading coefficient. The same result can be obtained from -<span class="docutils literal"><span class="pre">coeffs(pol)[-1]</span></span>, which shows also how to generalize to access -sub-leading coefficients. See the <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> documentation for -Python-like indexing syntax.</p> -</blockquote> -</div> -<div class="section" id="monicpart-pol-expr"> -<h2><a class="toc-backref" href="#id53"><span class="docutils literal"><span class="pre">monicpart(<pol.</span> <span class="pre">expr.>)</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="https://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="cont-pol-expr"> -<span id="cont"></span><h2><a class="toc-backref" href="#id54"><span class="docutils literal"><span class="pre">cont(<pol.</span> <span class="pre">expr.>)</span></span></a></h2> -<blockquote> -<p>The (fractional) greatest common divisor of the 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 and syntax unstable</strong></p> -<p>At <span class="docutils literal">0.8</span> it was created as <span class="docutils literal">icontent()</span> to match the legacy -macro <a class="reference internal" href="#policontent">\PolIContent</a>, whose name in 2018 was -chosen in relation to Maple's function <span class="docutils literal">icontent()</span>, possibly -because at that time I had not seen that Maple also had a -<span class="docutils literal">content()</span> function. Name changed at <span class="docutils literal">0.8.1</span>.</p> -<p>It will change syntax if in future multivariate polynomials are -supported, and <span class="docutils literal">icontent()</span> will then make a come-back.</p> -</blockquote> -</blockquote> -</div> -<div class="section" id="primpart-pol-expr"> -<h2><a class="toc-backref" href="#id55"><span class="docutils literal"><span class="pre">primpart(<pol.</span> <span class="pre">expr.>)</span></span></a></h2> -<blockquote> -<p>The quotient (except for the zero polynomial) by -<span class="docutils literal"><span class="pre">cont(<pol.</span> <span class="pre">expr.>)</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="#id56"><span class="docutils literal"><span class="pre">quorem(<pol.</span> <span class="pre">expr.>,</span> <pol. <span class="pre">expr.>)</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="#id57"><span class="docutils literal"><span class="pre">quo(<pol.</span> <span class="pre">expr.>,</span> <pol. <span class="pre">expr.>)</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="#id58"><span class="docutils literal"><span class="pre">rem(<pol.</span> <span class="pre">expr.>,</span> <pol. <span class="pre">expr.>)</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="#id59"><span class="docutils literal"><span class="pre">prem(<pol.</span> expr. 1>, <pol. expr. 2>)</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)>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)>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="https://www.ctan.org/pkg/xintexpr">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="#id60"><span class="docutils literal"><span class="pre">divmod(<pol.</span> expr. 1>, <pol. expr. 2>)</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="#id61"><span class="docutils literal"><span class="pre">mod(<pol.</span> expr. 1>, <pol. expr. 2>)</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="#id62"><span class="docutils literal"><span class="pre">polgcd(<pol.</span> expr. 1>, <pol. expr. 2>, <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 "nutple" whose -items are polynomials (see the documentation of the scalar <span class="docutils literal">gcd()</span> -in <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">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="#id63"><span class="docutils literal"><span class="pre">resultant(<pol.</span> expr. 1>, <pol. expr. 2>)</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="#id64"><span class="docutils literal"><span class="pre">disc(<pol.</span> <span class="pre">expr.>)</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="#id65"><span class="docutils literal"><span class="pre">polpowmod(<pol.</span> expr. 1>, <num. <span class="pre">expr.>,</span> <pol. expr. 2>)</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)>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="https://www.ctan.org/pkg/xintexpr">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 > 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="#id66"><span class="docutils literal"><span class="pre">rdcoeffs(<pol.</span> <span class="pre">expr.>)</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="#id67"><span class="docutils literal"><span class="pre">rdzcoeffs(<pol.</span> <span class="pre">expr.>)</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="#id68"><span class="docutils literal"><span class="pre">diff1(<pol.</span> <span class="pre">expr.>)</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="#id69"><span class="docutils literal"><span class="pre">diff2(<pol.</span> <span class="pre">expr.>)</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="#id70"><span class="docutils literal"><span class="pre">diffn(<pol.</span> expr. P>, <num. expr. n>)</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<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="#id71"><span class="docutils literal"><span class="pre">antider(<pol.</span> expr. P>)</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="#id72"><span class="docutils literal"><span class="pre">intfrom(<pol.</span> expr. P>, <pol. expr. c>)</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="#id73"><span class="docutils literal"><span class="pre">integral(<pol.</span> expr. P>, [<pol. expr. a>, <pol. expr. <span class="pre">b>])</span></span></a></h2> -<blockquote> -<p><span class="docutils literal">\int_a^b P(t)dt</span>.</p> -<div class="admonition warning"> -<p class="admonition-title">Warning</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> -</div> -<p><span class="docutils literal">a</span> and <span class="docutils literal">b</span> are not restricted to be scalars, they are allowed to -be themselves polynomial variables or even polynomial expressions.</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="non-expandable-macros"> -<h1><a class="toc-backref" href="#id74">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>.</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="#id75"><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, used with argument <span class="docutils literal">polname</span>. Of course the -<em>expression</em> can make use of 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="https://www.ctan.org/pkg/xintexpr">xintexpr</a> syntax is authorized, as long as the final -result is of polynomial type:</p> -<pre class="literal-block">\poldef polname(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">polname</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">polname()</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="https://www.ctan.org/pkg/xintexpr">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).</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">polname()</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>.</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> -</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-expr-using-the-letter-as-indeterminate"> -<span id="id8"></span><h2><a class="toc-backref" href="#id76"><span class="docutils literal"><span class="pre">\PolDef[<letter>]{<polname>}{<expr.</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, the main interest is to avoid potential problems with the -catcode of the semi-colon in presence of some packages. In absence -of a <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="#id77"><span class="docutils literal"><span class="pre">\PolGenFloatVariant{<polname>}</span></span></a></h2> -<blockquote> -<p>Makes the polynomial also usable in the -<span class="docutils literal"><span class="pre">\xintfloatexpr/\xintfloateval</span></span> parser. It will therein evaluates -via an Horner scheme using polynomial coefficients already -pre-rounded to the float precision.</p> -<p>See also <a class="reference internal" href="#poltofloatexpr-pol-expr">\PolToFloatExpr{<pol. expr.>}</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>, must be -followed by explicit usage of <span class="docutils literal"><span class="pre">\PolGenFloatVariant{<polname>}</span></span> if -the new polynomial is to be used in <span class="docutils literal">\xintfloateval</span>.</p> -</div> -</blockquote> -</div> -<div class="section" id="poltypeset-pol-expr"> -<span id="poltypeset"></span><h2><a class="toc-backref" href="#id78"><span class="docutils literal"><span class="pre">\PolTypeset{<pol.</span> <span class="pre">expr.>}</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="#id79"><span class="docutils literal"><span class="pre">\PolTypesetCmd{<raw_coeff>}</span></span></a></h3> -<blockquote> -<p>Its package definition 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 coefficient of -degree zero. Also it sets the conditional deciding behaviour of -<a class="reference internal" href="#polifcoeffisplusorminusone-t-f">\PolIfCoeffIsPlusOrMinusOne{T}{F}</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 class="section" id="polifcoeffisplusorminusone-t-f"> -<span id="polifcoeffisplusorminusone"></span><h4><a class="toc-backref" href="#id80"><span class="docutils literal"><span class="pre">\PolIfCoeffIsPlusOrMinusOne{T}{F}</span></span></a></h4> -<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">T</span> if the coefficient has been found to be -plus or minus one, and <span class="docutils literal">F</span> if not. It chooses expandably between -<span class="docutils literal">T</span> and <span class="docutils literal">F</span>.</p> -</blockquote> -</div> -</div> -<div class="section" id="poltypesetone-raw-coeff"> -<span id="poltypesetone"></span><h3><a class="toc-backref" href="#id81"><span class="docutils literal"><span class="pre">\PolTypesetOne{<raw_coeff>}</span></span></a></h3> -<blockquote> -<p>Defaults to <span class="docutils literal">\xintTeXsignedFrac</span> (LaTeX) or <span class="docutils literal">\xintTeXsignedOver</span> -(else). But these <a class="reference external" href="https://www.ctan.org/pkg/xint">xintfrac</a> old legacy macros are a bit -annoying as they insist in exhibiting a power of ten rather than -using simpler decimal notation.</p> -<p>As alternative, one can do definitions 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="#id82"><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="#id83"><span class="docutils literal"><span class="pre">\PolTypesetCmdPrefix{<raw_coeff>}</span></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">\xintTeXsignedFrac</span> (or <span class="docutils literal">\xintTeXsignedOver</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="#id84"><span class="docutils literal"><span class="pre">\PolTypeset*{<pol.</span> <span class="pre">expr.>}</span></span></a></h2> -<blockquote> -<p>Typesets in ascending powers. Use <span class="docutils literal">[<letter>]</span> optional argument -(after the <span class="docutils literal">*</span>) to use another letter 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="non-expandable-macros-related-to-the-root-localization-routines"> -<h2><a class="toc-backref" href="#id85">Non-expandable macros related to the root localization routines</a></h2> -<p>As <a class="reference internal" href="#poltosturm-polname-sturmname">\PolToSturm{<polname>}{<sturmname>}</a> and -<a class="reference internal" href="#polsturmisolatezeros-sturmname">\PolSturmIsolateZeros{<sturmname>}</a> and variants declare -additional polynomial or scalar variables with names based on <span class="docutils literal"><sturmname></span> as -prefix, it is advisable to keep the <span class="docutils literal"><sturmname></span> namespace separate from -the one applying to <span class="docutils literal">\xintexpr</span> variables generally, or to polynomials.</p> -<div class="section" id="poltosturm-polname-sturmname"> -<span id="poltosturm"></span><h3><a class="toc-backref" href="#id86"><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>, and <span class="docutils literal"><sturmname></span> being -for example <span class="docutils literal">S</span>, the macro starts by computing the derivative -<span class="docutils literal">P'</span>, then computes the opposite of the remainder in the euclidean -division of <span class="docutils literal">P</span> by <span class="docutils literal">P'</span>, then the opposite of the remainder in -the euclidean division of <span class="docutils literal">P'</span> by the first obtained polynomial, -etc... Up to signs following the <span class="docutils literal"><span class="pre">--++--++...</span></span> pattern, these are -the same remainders as in the Euclide algorithm applied to the -computation of the GCD of <span class="docutils literal">P</span> and <span class="docutils literal">P'</span>.</p> -<p>The precise process differs from the above description: the -algorithm first sets <span class="docutils literal">S_0_</span> to be the <em>primitive part</em> of <span class="docutils literal">P</span> and -<span class="docutils literal">S_1_</span> to be the <em>primitive part</em> of <span class="docutils literal">P'</span> (see -<a class="reference internal" href="#policontent-polname">\PolIContent{<polname>}</a>), then at each step the remainder is made -primitive and stored for internal reference as <span class="docutils literal">S_k_</span>, so only -integer-coefficients polynomials are manipulated.</p> -<div class="admonition warning"> -<p class="admonition-title">Warning</p> -<p>This exact procedure will perhaps in future be replaced by a -<em>sub-resultant algorithm</em>, which may bring some speed gain in -obtaining a pseudo-Sturm sequence, but some experimenting is -needed, in the context of realistically realizable computations -by the package; primitive polynomials although a bit costly -have the smallest coefficients hence are the best for the kind of -computations done for root localization, after having computed a -Sturm sequence.</p> -</div> -<p>The last non-zero primitivized remainder <span class="docutils literal">S_N_</span> is, up to sign, -the primitive part of the GCD of <span class="docutils literal">P</span> and <span class="docutils literal">P'</span>. Its roots (real -and complex) are the multiple roots of the original <span class="docutils literal">P</span>. The -original <span class="docutils literal">P</span> was "square-free" (i.e. did not have multiple real -or complex roots) if and only if <span class="docutils literal">S_N_</span> is a constant, which is -then <span class="docutils literal">+1</span> or <span class="docutils literal"><span class="pre">-1</span></span> (its value before primitivization is lost).</p> -<p>The macro then divides each <span class="docutils literal">S_k_</span> by <span class="docutils literal">S_N_</span> and declares the -quotients <span class="docutils literal">S_k</span> as user polynomials for future use. By Gauss -theorem about the contents of integer-coefficients polynomials, -these <span class="docutils literal">S_k</span> also are primitive integer-coefficients polynomials.</p> -<p>This step will be referred to as <em>normalization</em>, and in this -documentation the obtained polynomials are said to constitute the -"Sturm chain" (or "Sturm sequence"), i.e. by convention the "Sturm -chain polynomials" are square-free and primitive. The possibly -non-square-free ones are referred to as <em>non-normalized</em>.</p> -<p>As an exception to the rule, if the original <span class="docutils literal">P</span> was "square-free" -(i.e. did not have multiple real or complex roots) then -normalization is skipped (in that case <span class="docutils literal">S_N_</span> is either <span class="docutils literal">+1</span> or -<span class="docutils literal"><span class="pre">-1</span></span>), so <span class="docutils literal">S_0_</span> is exactly the primitive part of starting -polynomial <span class="docutils literal">P</span>, in the "square-free" case.</p> -<p>The next logical step is to execute <a class="reference internal" href="#polsturmisolatezeros">\PolSturmIsolateZeros{S}</a> or one of its variants. Be careful not to -use the 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"><span class="pre">\PolSturmIsolateZeros{<sturmname>}</span></span> or its variants else the -latter will behave erroneously.</p> -<div class="admonition note"> -<p class="admonition-title">Note</p> -<p>The declaration of the <span class="docutils literal">S_k</span>'s will overwrite -with no warning previously declared polynomials with identical -names <span class="docutils literal">S_k</span>. This is original reason why the macro expects two -names: <span class="docutils literal"><polname></span> and <span class="docutils literal"><sturmname></span>.</p> -<p>It is allowed to use the polynomial name <span class="docutils literal">P</span> as Sturm chain -name <span class="docutils literal">S</span>: <span class="docutils literal"><span class="pre">\PolToSturm{f}(f}</span></span>, but of course fusing the -namespaces is slightly dangerous. And, also <a class="reference internal" href="#polsturmisolatezeros">\PolSturmIsolateZeros</a> creates variables sharing -the <span class="docutils literal"><sturmname></span> prefix, which must be taken into account to -avoid name clashes.</p> -</div> -<div class="admonition warning"> -<p class="admonition-title">Warning</p> -<p>The reason why the <span class="docutils literal">S_k</span>'s are declared as polynomials is -that the associated polynomial functions are needed to compute -the sign changes in the Sturm sequence evaluated at a given -location, as this is the basis mechanism of <a class="reference internal" href="#polsturmisolatezeros">\PolSturmIsolateZeros</a> (on the basis of the <a class="reference external" href="https://en.wikipedia.org/wiki/Sturm%27s_theorem">Sturm theorem</a>).</p> -<p>It is possible that in future the package will only internally -construct such polynomial functions and only the starred variant -will make the normalized (i.e. square-free) Sturm sequence public.</p> -</div> -<p>The integer <span class="docutils literal">N</span> giving the length of the Sturm chain <span class="docutils literal">S_0</span>, -<span class="docutils literal">S_1</span>, ..., <span class="docutils literal">S_N</span> is available as -<a class="reference internal" href="#polsturmchainlength-sturmname">\PolSturmChainLength{<sturmname>}</a>. If all roots of original <span class="docutils literal">P</span> -are real, then <span class="docutils literal">N</span> is both the number of distinct real roots and -the degree of <span class="docutils literal">S_0</span>. In the case of existence of complex roots, -the number of distinct real roots is at most <span class="docutils literal">N</span> and <span class="docutils literal">N</span> is at -most the degree of <span class="docutils literal">S_0</span>.</p> -</blockquote> -</div> -<div class="section" id="id13"> -<span id="id12"></span><h3><a class="toc-backref" href="#id87"><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> (but still -made primitive) 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> -</blockquote> -</div> -<div class="section" id="polsturmisolatezeros-sturmname"> -<span id="polsturmisolatezeros"></span><h3><a class="toc-backref" href="#id88"><span class="docutils literal"><span class="pre">\PolSturmIsolateZeros{<sturmname>}</span></span></a></h3> -<blockquote> -<p>The macro locates, using the <a class="reference external" href="https://en.wikipedia.org/wiki/Sturm%27s_theorem">Sturm Theorem</a>, as many disjoint -intervals as there are distinct 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> -</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="https://www.ctan.org/pkg/xintexpr">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 < z < 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>Let us suppose <span class="docutils literal"><sturmname></span> is <span class="docutils literal">S</span>.</p> -<p>The interval boundaries (and exactly found roots) are made available -for future computations in <span class="docutils literal">\xintexpr/xinteval</span> or <span class="docutils literal">\poldef</span> as -variables <span class="docutils literal">SL_1</span>, <span class="docutils literal">SL_2</span>, etc..., for the left end-points and -<span class="docutils literal">SR_1</span>, <span class="docutils literal">SR_2</span>, ..., for the right end-points.</p> -<p>Additionally, <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> variable <span class="docutils literal">SZ_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> -<div class="admonition important"> -<p class="admonition-title">Important</p> -<p>The variable declarations are done with no check of existence of -previously existing variables with identical names.</p> -</div> -<p>Also, macros <a class="reference internal" href="#polsturmisolatedzeroleft">\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-t-f">\PolSturmIfZeroExactlyKnown{<sturmname>}{<index>}{T}{F}</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, so as to be able for example to -print out bounds of real roots with as many digits as is -significant, even if the digits are zeros.</p> -</div> -<p>The start of the decimal expansion of the <span class="docutils literal"><index></span>-th root is given by -<a class="reference internal" href="#polsturmisolatedzeroleft">\PolSturmIsolatedZeroLeft{<sturmname>}{<index>}</a> if the root is positive, and by -<a class="reference internal" href="#polsturmisolatedzeroright">PolSturmIsolatedZeroRight{<sturmname>}{<index>}</a> if the root is neagtive. 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-num-expr">\PolSturmNbOfRootsOf{<sturmname>}\LessThanOrEqualToExpr{<num. expr.>}</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> -<p>These variables and macros are automatically updated in case of -subsequent usage of <a class="reference internal" href="#polrefineinterval-sturmname-index">\PolRefineInterval*{<sturmname>}{<index>}</a> or -other localization improving macros.</p> -<div class="admonition note"> -<p class="admonition-title">Note</p> -<p>The current polexpr implementation defines the <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> variables -and <a class="reference external" href="https://www.ctan.org/pkg/xint">xinttools</a> arrays as described above with global scope. On the -other hand the Sturm sequence polynomials obey the current scope.</p> -<p>This is perhaps a bit inconsistent and may change in future.</p> -</div> -<div class="admonition note"> -<p class="admonition-title">Note</p> -<p>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="#id89"><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.</p> -<p>After execution, -<a class="reference internal" href="#polsturmisolatedzeromultiplicity-sturmname-index">\PolSturmIsolatedZeroMultiplicity{<sturmname>}{<index>}</a> expands -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">S</span>, <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> -variables <span class="docutils literal">SM_1</span>, <span class="docutils literal">SM_2</span>... hold the multiplicities thus -computed.</p> -<div class="admonition note"> -<p class="admonition-title">Note</p> -<p>Somewhat counter-intuitively, it is not necessary to have -executed the <a class="reference internal" href="#id12">\PolToSturm*</a> starred variant: during its -execution, <a class="reference internal" href="#poltosturm">\PolToSturm</a>, even though it does not declare the -non-square-free Sturm chain polynomials as user-level genuine -polynomials, stores their data in private macros.</p> -</div> -<p>See <span class="docutils literal">The degree nine polynomial with 0.99, 0.999, 0.9999 as triple roots</span> example in <span class="docutils literal"><span class="pre">polexpr-examples.pdf</span></span>.</p> -</blockquote> -<div class="section" id="polsturmisolatezerosandgetmultiplicities-sturmname"> -<span id="polsturmisolatezerosandgetmultiplicities"></span><h4><a class="toc-backref" href="#id90"><span class="docutils literal"><span class="pre">\PolSturmIsolateZerosAndGetMultiplicities{<sturmname>}</span></span></a></h4> -<blockquote> -<p>This is another name for <a class="reference internal" href="#id15">\PolSturmIsolateZeros*{<sturmname>}</a>.</p> -</blockquote> -</div> -</div> -<div class="section" id="id17"> -<span id="id16"></span><h3><a class="toc-backref" href="#id91"><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 "known" 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 <span class="docutils literal">A degree five polynomial with three rational roots</span> in <span class="docutils literal"><span class="pre">polexpr-examples.pdf</span></span>.</p> -</blockquote> -<div class="section" id="polsturmisolatezerosgetmultiplicitiesandrationalroots-sturmname"> -<span id="polsturmisolatezerosgetmultiplicitiesandrationalroots"></span><h4><a class="toc-backref" href="#id92"><span class="docutils literal"><span class="pre">\PolSturmIsolateZerosGetMultiplicitiesAndRationalRoots{<sturmname>}</span></span></a></h4> -<blockquote> -<p>This is another name for <a class="reference internal" href="#id17">\PolSturmIsolateZeros**{<sturmname>}</a>.</p> -</blockquote> -</div> -</div> -<div class="section" id="polsturmisolatezerosandfindrationalroots-sturmname"> -<h3><a class="toc-backref" href="#id93"><span class="docutils literal"><span class="pre">\PolSturmIsolateZerosAndFindRationalRoots{<sturmname>}</span></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="https://www.ctan.org/pkg/xintexpr">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> will be -erroneous regarding the multiplicities of 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="#id94"><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. As a consequence, 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="#id95"><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-exponent"> -<span id="polensureintervallength"></span><h3><a class="toc-backref" href="#id96"><span class="docutils literal"><span class="pre">\PolEnsureIntervalLength{<sturmname>}{<index>}{<exponent>}</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<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-exponent"> -<span id="polensureintervallengths"></span><h3><a class="toc-backref" href="#id97"><span class="docutils literal"><span class="pre">\PolEnsureIntervalLengths{<sturmname>}{<exponent>}</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>.</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<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="#id98"><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"><</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="#id99"><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="#id100"><span class="docutils literal">\PolPrintIntervalsBeginEnv</span></a></h4> -<blockquote> -<p>Default definition (given here for LaTeX, Plain has a variant):</p> -<pre class="literal-block">\newcommand\PolPrintIntervalsBeginEnv{\[\begin{array}{rcccl}}</pre> -<p>A simpler <span class="docutils literal">center</span> environment provides a straightforward way to -obtain a display allowing pagebreaks. Of course redefinitions must -at any rate be kept in sync with <a class="reference internal" href="#polprintintervalsknownroot">\PolPrintIntervalsKnownRoot</a> and -<a class="reference internal" href="#polprintintervalsunknownroot">\PolPrintIntervalsUnknownRoot</a>.</p> -<p>Prior to <span class="docutils literal">0.8.6</span> it was not possible to use here for example -<span class="docutils literal">\begin{align}</span> due to the latter executing twice in contents.</p> -</blockquote> -</div> -<div class="section" id="polprintintervalsendenv"> -<h4><a class="toc-backref" href="#id101"><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="polprintintervalsrowseparator"> -<h4><a class="toc-backref" href="#id102"><span class="docutils literal">\PolPrintIntervalsRowSeparator</span></a></h4> -<blockquote> -<p>Expands by default to <span class="docutils literal">\\</span> with LaTeX and to <span class="docutils literal">\cr</span> with Plain</p> -<p>Added at <span class="docutils literal">0.8.6</span>.</p> -</blockquote> -</div> -<div class="section" id="polprintintervalsknownroot"> -<h4><a class="toc-backref" href="#id103"><span class="docutils literal">\PolPrintIntervalsKnownRoot</span></a></h4> -<blockquote> -<p>Default definition:</p> -<pre class="literal-block">\newcommand\PolPrintIntervalsKnownRoot{% - &&\PolPrintIntervalsTheVar_{\PolPrintIntervalsTheIndex}% - &=&\PolPrintIntervalsPrintExactZero -}</pre> -</blockquote> -</div> -<div class="section" id="polprintintervalsunknownroot"> -<h4><a class="toc-backref" href="#id104"><span class="docutils literal">\PolPrintIntervalsUnknownRoot</span></a></h4> -<blockquote> -<p>Default definition:</p> -<pre class="literal-block">\newcommand\PolPrintIntervalsUnknownRoot{% - \PolPrintIntervalsPrintLeftEndPoint&<&% - \PolPrintIntervalsTheVar_{\PolPrintIntervalsTheIndex}&<&% - \PolPrintIntervalsPrintRightEndPoint -}</pre> -</blockquote> -</div> -<div class="section" id="id18"> -<span id="polprintintervalsprintexactzero"></span><h4><a class="toc-backref" href="#id105"><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="#id106"><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="#id107"><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="#id108"><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@@PrintIntervals...</span></span> macros. We only reproduce here one -definition:</p> -<pre class="literal-block">\newcommand\POL@@PrintIntervalsPrintExactZero{% - \displaystyle - \xintTeXsignedFrac{\PolPrintIntervalsTheLeftEndPoint}% -}%</pre> -<p>Multiplicities are printed using this auxiliary macro:</p> -</blockquote> -<div class="section" id="polprintintervalsprintmultiplicity"> -<h4><a class="toc-backref" href="#id109"><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 class="section" id="polsettosturmchainsignchangesat-foo-sturmname-value"> -<span id="polsettosturmchainsignchangesat"></span><h3><a class="toc-backref" href="#id110"><span class="docutils literal"><span class="pre">\PolSetToSturmChainSignChangesAt{\foo}{<sturmname>}{<value>}</span></span></a></h3> -<blockquote> -<p>Sets macro <span class="docutils literal">\foo</span> to store the number of sign changes in the -already computed normalized Sturm chain with name prefix -<span class="docutils literal"><sturmname></span>, at location <span class="docutils literal"><value></span> (which must be in format as -acceptable by the <a class="reference external" href="https://www.ctan.org/pkg/xint">xintfrac</a> macros.)</p> -<p>The definition is made with global scope. For local scope, use -<span class="docutils literal">[\empty]</span> as extra optional argument.</p> -<p>One can use this immediately after creation of the Sturm chain.</p> -</blockquote> -</div> -<div class="section" id="polsettonbofzeroswithin-foo-sturmname-value-left-value-right"> -<span id="polsettonbofzeroswithin"></span><h3><a class="toc-backref" href="#id111"><span class="docutils literal"><span class="pre">\PolSetToNbOfZerosWithin{\foo}{<sturmname>}{<value_left>}{<value_right>}</span></span></a></h3> -<blockquote> -<p>Sets, assuming the normalized Sturm chain has been already computed, -macro <span class="docutils literal">\foo</span> to store the number of roots of <span class="docutils literal">sturmname_0</span> in -the interval <span class="docutils literal">(value_left, value_right]</span>. The macro first -re-orders end-points if necessary for <span class="docutils literal">value_left <= value_right</span> -to hold.</p> -<p>In accordance to <a class="reference external" href="https://en.wikipedia.org/wiki/Sturm%27s_theorem">Sturm Theorem</a> this is computed as the difference -between the number of sign changes of the Sturm chain at <span class="docutils literal">value_right</span> -and the one at <span class="docutils literal">value_left</span>.</p> -<p>The definition is made with global scope. For local scope, use -<span class="docutils literal">[\empty]</span> as extra optional argument.</p> -<p>One can use this immediately after creation of a Sturm chain.</p> -<p>See also the expandable -<a class="reference internal" href="#polsturmnbofrootsof-sturmname-lessthanorequalto-value">\PolSturmNbOfRootsOf{<sturmname>}\LessThanOrEqualTo{<value>}</a>, -which however 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> -<div class="section" id="pollet-polname-2-polname-1"> -<span id="pollet"></span><h2><a class="toc-backref" href="#id112"><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>. This has the same effect as -<span class="docutils literal"><span class="pre">\PolDef{<polname_2>}{<polname_1>(x)}</span></span> or (better) -<span class="docutils literal"><span class="pre">\PolDef{<polname_2>}{<polname_1>}</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="#id113"><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="#id114"><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. This is -an unfortunate legacy situation related to the original indexing -convention in <a class="reference external" href="https://www.ctan.org/pkg/xint">xinttools</a> arrays.</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-index">\PolNthCoeff{<polname>}{<index>}</a>.</p> -</blockquote> -</div> -<div class="section" id="polget-polname-fromarray-macro"> -<span id="polget"></span><h2><a class="toc-backref" href="#id115"><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"><span class="pre">\macro{<value>}</span></span> gets expanded in an <span class="docutils literal">\edef</span> and then normalized -via <a class="reference external" href="https://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> -</blockquote> -</div> -<div class="section" id="polfromcsv-polname-csv"> -<span id="polfromcsv"></span><h2><a class="toc-backref" href="#id116"><span class="docutils literal"><span class="pre">\PolFromCSV{<polname>}{<csv>}</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="https://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{<polname>}</a>.</p> -</blockquote> -</div> -<div class="section" id="polmapcoeffs-macro-polname"> -<span id="polmapcoeffs"></span><h2><a class="toc-backref" href="#id117"><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.</p> -<p>In the replacement text of <span class="docutils literal">\macro</span>, <span class="docutils literal">\index</span> expands to the -coefficient index (starting at zero for the constant term).</p> -<p>Notice that <span class="docutils literal">\macro</span> will have to handle inputs in the <a class="reference external" href="https://www.ctan.org/pkg/xint">xintfrac</a> -internal format. This means that it probably will have to be -expressed in terms of macros from the <a class="reference external" href="https://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="#id118"><span class="docutils literal"><span class="pre">\PolReduceCoeffs{<polname>}</span></span></a></h2> -<blockquote> -<p>Reduces the internal representations of the coefficients to -their lowest terms.</p> -</blockquote> -</div> -<div class="section" id="id24"> -<span id="id23"></span><h2><a class="toc-backref" href="#id119"><span class="docutils literal"><span class="pre">\PolReduceCoeffs*{<polname>}</span></span></a></h2> -<blockquote> -<p>Reduces the internal representations of the coefficients to their -lowest terms, but ignoring a possible separated "power of ten part".</p> -<p>For example, <a class="reference external" href="https://www.ctan.org/pkg/xint">xintfrac</a> stores an <span class="docutils literal">30e2/50</span> input as <span class="docutils literal">30/50</span> with -a separate <span class="docutils literal">10^2</span> part. This will thus get replaced by <span class="docutils literal">3e^2/5</span> -(or rather whatever <a class="reference external" href="https://www.ctan.org/pkg/xint">xintfrac</a> uses for internal representation), and -not by <span class="docutils literal">60</span> as would result from complete reduction.</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 generally smaller.</p> -</blockquote> -</div> -<div class="section" id="polmakemonic-polname"> -<span id="polmakemonic"></span><h2><a class="toc-backref" href="#id120"><span class="docutils literal"><span class="pre">\PolMakeMonic{<polname>}</span></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, in case the original polynomial had integer -coefficients and the user wants to keep the leading one as common -denominator for typesetting purposes.</p> -</blockquote> -</div> -<div class="section" id="polmakeprimitive-polname"> -<span id="polmakeprimitive"></span><h2><a class="toc-backref" href="#id121"><span class="docutils literal"><span class="pre">\PolMakePrimitive{<polname>}</span></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 class="section" id="poldiff-polname-1-polname-2"> -<span id="poldiff"></span><h2><a class="toc-backref" href="#id122"><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="#id123"><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="#id124"><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="#id125"><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="#id126"><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="#id127"><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="#id128"><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="#id129"><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 <span class="docutils literal">polname_1</span> -and <span class="docutils literal">polname_2</span>. 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> -<div class="section" id="expandable-macros"> -<h1><a class="toc-backref" href="#id130">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>These macros expand completely in two steps except <span class="docutils literal">\PolToExpr</span> and -<span class="docutils literal">\PolToFloatExpr</span> 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="poltoexpr-pol-expr"> -<span id="poltoexpr"></span><h2><a class="toc-backref" href="#id131"><span class="docutils literal"><span class="pre">\PolToExpr{<pol.</span> <span class="pre">expr.>}</span></span></a></h2> -<blockquote> -<p>Produces expandably <a class="footnote-reference brackets" href="#id26" id="id25">4</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="id26"><span class="brackets"><a class="fn-backref" href="#id25">4</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. Then <span class="docutils literal">x</span> is expected as -indeterminate but this can be customized via <a class="reference internal" href="#poltoexprinvar">\PolToExprInVar</a>.</p> -<p>The output uses the letter <span class="docutils literal">x</span> by default, this is customizable -via <a class="reference internal" href="#poltoexprvar">\PolToExprVar</a>. The default output is compatible both with</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, see further -<a class="reference internal" href="#poltoexprcaret">\PolToExprCaret</a> in this context.</p> -<p>The following applies:</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="id27"> -<span id="poltoexprvar"></span><h3><a class="toc-backref" href="#id132"><span class="docutils literal">\PolToExprVar</span></a></h3> -<blockquote> -<p>Defaults to <span class="docutils literal">x</span>. The letter used in the macro output.</p> -</blockquote> -</div> -<div class="section" id="poltoexprinvar"> -<h3><a class="toc-backref" href="#id133"><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 -in the macro input.</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="id28"> -<span id="poltoexprtimes"></span><h3><a class="toc-backref" href="#id134"><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="#id135"><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="#id136"><span class="docutils literal"><span class="pre">\PolToExprCmd{<raw_coeff>}</span></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-exponent"> -<span id="poltoexproneterm"></span><h3><a class="toc-backref" href="#id137"><span class="docutils literal"><span class="pre">\PolToExprOneTerm{<raw_coeff>}{<exponent>}</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-exponent"> -<span id="poltoexpronetermstylea"></span><h3><a class="toc-backref" href="#id138"><span class="docutils literal"><span class="pre">\PolToExprOneTermStyleA{<raw_coeff>}{<exponent>}</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-exponent"> -<span id="poltoexpronetermstyleb"></span><h3><a class="toc-backref" href="#id139"><span class="docutils literal"><span class="pre">\PolToExprOneTermStyleB{<raw_coeff>}{<exponent>}</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="#id140"><span class="docutils literal"><span class="pre">\PolToExprTermPrefix{<raw_coeff>}</span></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="poltofloatexpr-pol-expr"> -<span id="poltofloatexpr"></span><h2><a class="toc-backref" href="#id141"><span class="docutils literal"><span class="pre">\PolToFloatExpr{<pol.</span> <span class="pre">expr.>}</span></span></a></h2> -<blockquote> -<p>Similar to <a class="reference internal" href="#poltoexpr-pol-expr">\PolToExpr{<pol. expr.>}</a> but using -<a class="reference internal" href="#poltofloatexprcmd-raw-coeff">\PolToFloatExprCmd{<raw_coeff>}</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-exponent"> -<span id="poltofloatexproneterm"></span><h3><a class="toc-backref" href="#id142"><span class="docutils literal"><span class="pre">\PolToFloatExprOneTerm{<raw_coeff>}{<exponent>}</span></span></a></h3> -<blockquote> -<p>Similar to <a class="reference internal" href="#poltoexproneterm-raw-coeff-exponent">\PolToExprOneTerm{<raw_coeff>}{<exponent>}</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="poltofloatexprcmd"></span><h3><a class="toc-backref" href="#id143"><span class="docutils literal"><span class="pre">\PolToFloatExprCmd{<raw_coeff>}</span></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">\xintPFloat{#1}</span></span>, which trims trailing -zeroes.</p> -<p><em>changed at 0.8.2</em> Formerly it was using <span class="docutils literal">\xintFloat</span>.</p> -</blockquote> -</div> -</div> -<div class="section" id="id30"> -<span id="id29"></span><h2><a class="toc-backref" href="#id144"><span class="docutils literal"><span class="pre">\PolToExpr*{<pol.</span> <span class="pre">expr.>}</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{<pol. expr.>}</a>.</p> -</blockquote> -</div> -<div class="section" id="id32"> -<span id="id31"></span><h2><a class="toc-backref" href="#id145"><span class="docutils literal"><span class="pre">\PolToFloatExpr*{<pol.</span> <span class="pre">expr.>}</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="polnthcoeff-polname-index"> -<span id="polnthcoeff"></span><h2><a class="toc-backref" href="#id146"><span class="docutils literal"><span class="pre">\PolNthCoeff{<polname>}{<index>}</span></span></a></h2> -<blockquote> -<p>It expands to the raw <span class="docutils literal">N</span>-th coefficient (<span class="docutils literal">N=0</span> corresponds to -the constant coefficient). If <span class="docutils literal">N</span> is out of range, zero (in its -default <a class="reference external" href="https://www.ctan.org/pkg/xint">xintfrac</a> format <span class="docutils literal">0/1[0]</span>) is returned.</p> -<p>Negative indices <span class="docutils literal"><span class="pre">N=-1</span></span>, <span class="docutils literal"><span class="pre">-2</span></span>, ... return the leading -coefficient, sub-leading coefficient, ..., and finally <span class="docutils literal">0/1[0]</span> -for <span class="docutils literal"><span class="pre">N<-1-degree</span></span>.</p> -</blockquote> -</div> -<div class="section" id="polleadingcoeff-polname"> -<span id="polleadingcoeff"></span><h2><a class="toc-backref" href="#id147"><span class="docutils literal"><span class="pre">\PolLeadingCoeff{<polname>}</span></span></a></h2> -<blockquote> -<p>Expands to the leading coefficient.</p> -</blockquote> -</div> -<div class="section" id="poldegree-polname"> -<span id="poldegree"></span><h2><a class="toc-backref" href="#id148"><span class="docutils literal"><span class="pre">\PolDegree{<polname>}</span></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="#id149"><span class="docutils literal"><span class="pre">\PolIContent{<polname>}</span></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="poltolist-polname"> -<span id="poltolist"></span><h2><a class="toc-backref" href="#id150"><span class="docutils literal"><span class="pre">\PolToList{<polname>}</span></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="#id151"><span class="docutils literal"><span class="pre">\PolToCSV{<polname>}</span></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{<polname>}{<csv>}</a>.</p> -</blockquote> -</div> -<div class="section" id="poleval-polname-atexpr-num-expr"> -<span id="polevalatexpr"></span><h2><a class="toc-backref" href="#id152"><span class="docutils literal"><span class="pre">\PolEval{<polname>}\AtExpr{<num.</span> <span class="pre">expr.>}</span></span></a></h2> -<blockquote> -<p>Same output as -<span class="docutils literal">\xinteval{polname(numerical expression)}</span>.</p> -</blockquote> -</div> -<div class="section" id="poleval-polname-at-value"> -<span id="polevalat"></span><h2><a class="toc-backref" href="#id153"><span class="docutils literal"><span class="pre">\PolEval{<polname>}\At{<value>}</span></span></a></h2> -<blockquote> -<p>Evaluates the polynomial at the given value which must be in (or -expand to) a format acceptable to the <a class="reference external" href="https://www.ctan.org/pkg/xint">xintfrac</a> macros.</p> -</blockquote> -</div> -<div class="section" id="polevalreduced-polname-atexpr-num-expr"> -<span id="polevalreducedatexpr"></span><h2><a class="toc-backref" href="#id154"><span class="docutils literal"><span class="pre">\PolEvalReduced{<polname>}\AtExpr{<num.</span> <span class="pre">expr.>}</span></span></a></h2> -<blockquote> -<p>Same output as <span class="docutils literal">\xinteval{reduce(polname(numerical <span class="pre">expression))}</span></span>.</p> -</blockquote> -</div> -<div class="section" id="polevalreduced-polname-at-value"> -<span id="polevalreducedat"></span><h2><a class="toc-backref" href="#id155"><span class="docutils literal"><span class="pre">\PolEvalReduced{<polname>}\At{<value>}</span></span></a></h2> -<blockquote> -<p>Evaluates the polynomial at the value which must be in (or expand -to) a format acceptable to the <a class="reference external" href="https://www.ctan.org/pkg/xint">xintfrac</a> macros, and outputs an -irreducible fraction.</p> -</blockquote> -</div> -<div class="section" id="polfloateval-polname-atexpr-num-expr"> -<span id="polfloatevalatexpr"></span><h2><a class="toc-backref" href="#id156"><span class="docutils literal"><span class="pre">\PolFloatEval{<polname>}\AtExpr{<num.</span> <span class="pre">expr.>}</span></span></a></h2> -<blockquote> -<p>Same output as <span class="docutils literal">\xintfloateval{polname(numerical expression)}</span>.</p> -<div class="admonition attention"> -<p class="admonition-title">Attention!</p> -<p><a class="reference internal" href="#polgenfloatvariant">\PolGenFloatVariant</a> must have -been issued before.</p> -</div> -<p>To use the <em>exact coefficients</em> with <em>exactly executed</em> additions -and multiplications and do the rounding only as the final last step, -the following syntax can be used: <a class="footnote-reference brackets" href="#id34" id="id33">5</a></p> -<pre class="literal-block">\xintfloateval{3.27*\xintexpr f(2.53)\relax^2}</pre> -<dl class="footnote brackets"> -<dt class="label" id="id34"><span class="brackets"><a class="fn-backref" href="#id33">5</a></span></dt> -<dd><p>Cf. <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> documentation about nested expressions.</p> -</dd> -</dl> -</blockquote> -</div> -<div class="section" id="polfloateval-polname-at-value"> -<span id="polfloatevalat"></span><h2><a class="toc-backref" href="#id157"><span class="docutils literal"><span class="pre">\PolFloatEval{<polname>}\At{<value>}</span></span></a></h2> -<blockquote> -<p>Evaluates the polynomial at the value which must be in (or expand -to) a format acceptable to the <a class="reference external" href="https://www.ctan.org/pkg/xint">xintfrac</a> macros.</p> -</blockquote> -</div> -<div class="section" id="expandable-macros-related-to-the-root-localization-routines"> -<h2><a class="toc-backref" href="#id158">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="#id159"><span class="docutils literal"><span class="pre">\PolSturmChainLength{<sturmname>}</span></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-t-f"> -<span id="polsturmifzeroexactlyknown"></span><h3><a class="toc-backref" href="#id160"><span class="docutils literal"><span class="pre">\PolSturmIfZeroExactlyKnown{<sturmname>}{<index>}{T}{F}</span></span></a></h3> -<blockquote> -<p>Executes <span class="docutils literal">T</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">F</span>.</p> -</blockquote> -</div> -<div class="section" id="polsturmisolatedzeroleft-sturmname-index"> -<span id="polsturmisolatedzeroleft"></span><h3><a class="toc-backref" href="#id161"><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>Execution of this macro after some -<a class="reference internal" href="#polrefineinterval-n">\PolRefineInterval{<sturmname>}{<index>}</a> -will take into account the now known tighter bounds.</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="#id162"><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="#id163"><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 <span class="docutils literal">The degree nine polynomial with 0.99, 0.999, 0.9999 as triple roots</span> in <span class="docutils literal"><span class="pre">polexpr-examples.pdf</span></span>.</p> -</blockquote> -</div> -<div class="section" id="polsturmnbofisolatedzeros-sturmname"> -<span id="polsturmnbofisolatedzeros"></span><h3><a class="toc-backref" href="#id164"><span class="docutils literal"><span class="pre">\PolSturmNbOfIsolatedZeros{<sturmname>}</span></span></a></h3> -<blockquote> -<p>Expands to the number of real roots of the polynomial -<span class="docutils literal"><sturmname>_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="#id165"><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="https://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-num-expr"> -<span id="polsturmnbofrootsof"></span><h3><a class="toc-backref" href="#id166"><span class="docutils literal"><span class="pre">\PolSturmNbOfRootsOf{<sturmname>}\LessThanOrEqualToExpr{<num.</span> <span class="pre">expr.>}</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 numerical expression.</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="#id167"><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-num-expr"> -<h3><a class="toc-backref" href="#id168"><span class="docutils literal"><span class="pre">\PolSturmNbWithMultOfRootsOf{<sturmname>}\LessThanOrEqualToExpr{<num.</span> <span class="pre">expr.>}</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="#id169"><span class="docutils literal"><span class="pre">\PolSturmNbOfRationalRoots{<sturmname>}</span></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="#id170"><span class="docutils literal"><span class="pre">\PolSturmNbOfRationalRootsWithMultiplicities{<sturmname>}</span></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="#id171"><span class="docutils literal"><span class="pre">\PolSturmRationalRoot{<sturmname>}{<k>}</span></span></a></h3> -<blockquote> -<p>Expands to the k-th rational root. They are enumerated from left to -right starting at index value <span class="docutils literal">1</span>.</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="#id172"><span class="docutils literal"><span class="pre">\PolSturmRationalRootIndex{<sturmname>}{<k>}</span></span></a></h3> -<blockquote> -<p>Expands to the index of the <span class="docutils literal">k</span>th rational root as part of the -ordered real roots (counted without multiplicities). So -<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="#id173"><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="#id174"><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="https://www.ctan.org/pkg/xint">xintfrac</a> raw <span class="docutils literal">1/1[E]</span> format (if not zero).</p> -</blockquote> -</div> -<div class="section" id="expandable-macros-for-use-within-execution-of-polprintintervals"> -<h3><a class="toc-backref" href="#id175">Expandable macros for use within execution of <span class="docutils literal">\PolPrintIntervals</span></a></h3> -<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> -<div class="section" id="polprintintervalsthevar"> -<h3><a class="toc-backref" href="#id176"><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="#id177"><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="#id178"><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="#id179"><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="#id180"><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="#id181"><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="#id182">Booleans (with default setting as indicated)</a></h1> -<div class="section" id="xintverbosefalse"> -<h2><a class="toc-backref" href="#id183"><span class="docutils literal">\xintverbosefalse</span></a></h2> -<blockquote> -<p>This is actually an <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">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="#id184"><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="#id185"><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="#id186"><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{<pol. expr.>}</a> and <a class="reference internal" href="#poltofloatexpr-pol-expr">\PolToFloatExpr{<pol. expr.>}</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="#id187">Utilies</a></h1> -<div class="section" id="poldectostring-decimal-number"> -<span id="poldectostring"></span><h2><a class="toc-backref" href="#id188"><span class="docutils literal">\PolDecToString{decimal number}</span></a></h2> -<blockquote> -<p>This is a utility macro to print decimal numbers. It is an alias -for <span class="docutils literal">\xintDecToString</span>.</p> -</blockquote> -<blockquote> -<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.</p> -<p>To trim trailing zeroes, one can use -<span class="docutils literal"><span class="pre">\PolDecToString{\xintREZ{#1}}</span></span>.</p> -<p>Attention that a.t.t.o.w. if the argument is for example <span class="docutils literal">1/5</span>, the -macro does not identify that this is in fact a number with a finite -decimal expansion and it outputs <span class="docutils literal">1/5</span>. See current <a class="reference external" href="https://www.ctan.org/pkg/xint">xintfrac</a> -documentation.</p> -</blockquote> -</div> -<div class="section" id="polexprsetup"> -<h2><a class="toc-backref" href="#id189"><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="#id190">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</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="https://www.ctan.org/pkg/xint">xintfrac</a> addition and subtraction always using -least common multiples for the denominators, 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. One can use for example -<span class="docutils literal">\PolToCSV{PQ}</span> to see the internally stored coefficients.</p> -</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">\xintPIrr</span> to the -resulting coefficients, which means that fractions are reduced to -lowest terms but ignoring an already separated <em>power of ten</em> part <span class="docutils literal">[N]</span> -present in the internal representation. 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="#id191">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">"README thinks \numexpr recognizes ^ operator"</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="#id29">\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="#poltofloatexprcmd">\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="https://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="https://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 <span class="docutils literal">The degree 41 polynomial with <span class="pre">-2,</span> <span class="pre">-1.9,</span> <span class="pre">-1.8,</span> <span class="pre">...,</span> 0, 0.1, <span class="pre">...,</span> 1.9, 2 as roots</span> in <span class="docutils literal"><span class="pre">polexpr-examples.pdf</span></span>). -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-num-expr">\PolSturmNbOfRootsOf{<sturmname>}\LessThanOrEqualToExpr{<num. expr.>}</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-num-expr">\PolSturmNbWithMultOfRootsOf{<sturmname>}\LessThanOrEqualToExpr{<num. expr.>}</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{T}{F}</span></span>, -<span class="docutils literal"><span class="pre">\PolIfEndPointIsNegative{T}{F}</span></span>, and -<span class="docutils literal"><span class="pre">\PolIfEndPointIsZero{T}{F}</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-exponent">\PolEnsureIntervalLength{<sturmname>}{<index>}{<exponent>}</a> could under -certain circumstances erroneously replace a non-zero root by -zero,</p></li> -<li><p><a class="reference internal" href="#polensureintervallengths-sturmname-exponent">\PolEnsureIntervalLengths{<sturmname>}{<exponent>}</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 means that the infix operators -<span class="docutils literal">'and'</span>, <span class="docutils literal">'or'</span>, and <span class="docutils literal">'mod'</span> must be replaced -by <span class="docutils literal">&&</span>, <span class="docutils literal">||</span>, and <span class="docutils literal">/:</span> if they -follow immediately a variable name (similarly <span class="docutils literal">'xor'</span> must -be replaced by the <span class="docutils literal">xor()</span> function in such case).</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 -"ople" 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="https://www.ctan.org/pkg/xintexpr">xintexpr</a> which arose as consequences to the deep <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">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> -<li><p>v0.8.1 (2021/04/12)</p> -<ul class="simple"> -<li><p>breaking changes:</p> -<ul> -<li><p>renamed v0.8's <span class="docutils literal">icontent()</span> to <a class="reference internal" href="#cont">cont()</a>.</p></li> -<li><p>renamed v0.8's <span class="docutils literal">lcoeff()</span> to <a class="reference internal" href="#lc">lc()</a>.</p></li> -</ul> -</li> -<li><p>bugfix:</p> -<ul> -<li><p>Sadly, <span class="docutils literal">diff1()</span>, <span class="docutils literal">diff2()</span>, <span class="docutils literal">diffn()</span> were broken -for polynomials of degrees 8 or more, due to a typo and -insufficient testing.</p></li> -<li><p>The package should have (as documented) required <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> 1.4d -but in practice it accepted to work with <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> 1.4c, whose -<span class="docutils literal">\xinteval</span> does not know how to "output" a polynomial.</p></li> -<li><p>The definition of one of the two variants of <a class="reference internal" href="#polsturmnbofrootsof">\PolSturmNbOfRootsOf</a> was broken by an end-of-line space, left-over -from mass conversion from LaTeX to TeX syntax.</p></li> -</ul> -</li> -<li><p>added:</p> -<ul> -<li><p><a class="reference internal" href="#lpol">lpol()</a></p></li> -<li><p><a class="reference internal" href="#lcoeffs">lcoeffs()</a></p></li> -</ul> -</li> -</ul> -</li> -<li><p>v0.8.2 (2021/05/05)</p> -<ul class="simple"> -<li><p>breaking change:</p> -<ul> -<li><p>usage of <span class="docutils literal">\xintPFloat</span> in place of <span class="docutils literal">\xintFloat</span> for -<a class="reference internal" href="#poltofloatexprcmd">\PolToFloatExprCmd</a>.</p></li> -</ul> -</li> -<li><p>improved:</p> -<ul> -<li><p>Some <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> functions such as <span class="docutils literal">rseq()</span> use the semi-colon, -and it was mentioned in the documentation that <a class="reference internal" href="#poldef">\poldef</a> -will be confused by this and that inner semi-colons could be -set within braces <span class="docutils literal">{;}</span> as a work-around. It was not clear from -this documentation that also <a class="reference internal" href="#id8">\PolDef</a> required -this work-around. With this relase only <a class="reference internal" href="#poldef">\poldef</a> but -not <a class="reference internal" href="#id8">\PolDef</a> needs the work-around.</p></li> -</ul> -</li> -<li><p>track <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> <span class="docutils literal">1.4e</span> changes relative to powers.</p></li> -</ul> -</li> -<li><p>v0.8.3 (2021/05/27)</p> -<ul class="simple"> -<li><p>small internal update to track an <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> <span class="docutils literal">1.4h</span> change -regarding handling of exceptions. Will require this version at -least on loading.</p></li> -</ul> -</li> -<li><p>v0.8.4 (2021/11/01)</p> -<ul class="simple"> -<li><p>bugfix: <a class="reference internal" href="#id17">\PolSturmIsolateZeros**{<sturmname>}</a> did not -declare the <span class="docutils literal"><sturmname>_norr</span> and <span class="docutils literal"><sturmname>_sqf_norr</span> -polynomials if original polynomial had no real root!</p></li> -</ul> -</li> -<li><p>v0.8.5 (2021/11/30)</p> -<ul class="simple"> -<li><p>bugfix: support for the <span class="docutils literal">intfrom()</span> function was in the code, -but the declaration to the polynomial parser had not been done.</p></li> -<li><p>track (belatedly) upstream deprecation of <span class="docutils literal">\xintSignedFrac</span> and -<span class="docutils literal">\xintSignedFwOver</span> at <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> <span class="docutils literal">1.4g</span></p></li> -</ul> -</li> -<li><p>v0.8.6 (2022/01/09)</p> -<ul class="simple"> -<li><p>separate <span class="docutils literal"><span class="pre">polexpr-examples.pdf</span></span> from this reference documentation.</p></li> -<li><p>minor improvement to the computation of a priori bounds on real roots.</p></li> -<li><p>add <a class="reference internal" href="#polprintintervalsrowseparator">\PolPrintIntervalsRowSeparator</a> and allow usage of -<span class="docutils literal">amsmath</span> environments in custom <a class="reference internal" href="#polprintintervalsbeginenv">\PolPrintIntervalsBeginEnv</a> -and <a class="reference internal" href="#polprintintervalsendenv">\PolPrintIntervalsEndEnv</a>.</p></li> -</ul> -</li> -</ul> -</div> -<div class="section" id="acknowledgments"> -<h1><a class="toc-backref" href="#id192">Acknowledgments</a></h1> -<p>Thanks to Jürgen Gilg whose question about <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">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> +defined by <code class="docutils literal notranslate"><span class="pre">polexpr</span></code> itself.</p> +</section> +<section id="license-is-lppl-1-3c"> +<h2>License is LPPL 1.3c</h2> +<p>This work is distributed under the conditions of the +LaTeX Project Public License version 1.3c.</p> +<p>See README.md for details.</p> +</section> +<section id="in-memoriam-jurgen-gilg-1967-2022"> +<h2>In memoriam: Jürgen Gilg (1967-2022)</h2> +<p>My first contact with Jürgen was in January 2018, and his <em>little +question</em> about usage of <a class="reference external" href="https://www.ctan.org/pkg/xintexpr">xintexpr</a> for differentiating polynomials +proved the direct cause for the <a class="reference internal" href="polexpr-changes.html#firstrelease"><span class="std std-ref">creation of polexpr</span></a>. His regular comments and questions (often, jointly +with Thomas Söll) largely contributed to motivate the author into +investing time and effort into the somewhat strange occupation of +developing such unusual TeX/LaTeX packages. The topics of our +discussions evolved over the years and were not limited to TeX, LaTeX, +PSTricks or PostScript matters.</p> +<p>I learned to discover and appreciate his unassuming and kind character. +He was very conscientious in all his projects with others and was often +overly generous in his appreciation of people’s contributions. On +receiving the sad news of his unexpected and untimely death, I initially +thought I had been knowing him for at least 10 years, but it is actually +only a bit more than 4 years… I will sorely miss this friendship with +a gentle soul from <em>over the Rhine</em>.</p> +<p>I dedicate the work which has gone into <a class="reference external" href="https://www.ctan.org/pkg/polexpr">polexpr</a> to Jürgen’s memory.</p> +<div class="toctree-wrapper compound"> +</div> +</section> +</section> + + + <div class="clearer"></div> + </div> + </div> + </div> + <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> + <div class="sphinxsidebarwrapper"><h3>Contents of this page</h3> +<ul> +<li><a class="reference internal" href="#">Introduction to polexpr</a><ul> +<li><a class="reference internal" href="#usage-via-xintsession">Usage via xintsession</a></li> +<li><a class="reference internal" href="#license-is-lppl-1-3c">License is LPPL 1.3c</a></li> +<li><a class="reference internal" href="#in-memoriam-jurgen-gilg-1967-2022">In memoriam: Jürgen Gilg (1967-2022)</a></li> +</ul> +</li> +</ul> + + <div role="note" aria-label="source link"> + <h3>This Page</h3> + <ul class="this-page-menu"> + <li><a href="polexpr.rst.txt" + rel="nofollow">Show Source</a></li> + </ul> + </div> + <div> + <h4>Next topic</h4> + <p class="topless"><a href="polexpr-ref.html" + title="next chapter">polexpr reference</a></p> + </div> +<h3><a href="#">Table of Contents</a></h3> +<ul> +<li class="toctree-l1"><a class="reference internal" href="polexpr-ref.html">polexpr reference</a></li> +<li class="toctree-l1"><a class="reference internal" href="polexpr-changes.html">CHANGES</a></li> +</ul> + + </div> + </div> + <div class="clearer"></div> + </div> + <div class="related" role="navigation" aria-label="related navigation"> + <h3>Navigation</h3> + <ul> + <li class="right" style="margin-right: 10px"> + <a href="polexpr-ref.html" title="polexpr reference" + >next</a></li> + <li class="nav-item nav-item-0"><a href="#">polexpr 0.8.7 documentation</a> »</li> + <li class="nav-item nav-item-this"><a href="">Introduction to polexpr</a></li> + </ul> + </div> + <div class="footer" role="contentinfo"> + © Copyright 2022, Jean-François Burnol. + Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 5.0.0+/f58771c09. + </div> + </body> +</html>
\ No newline at end of file diff --git a/Master/texmf-dist/doc/generic/polexpr/polexpr.rst.txt b/Master/texmf-dist/doc/generic/polexpr/polexpr.rst.txt new file mode 100644 index 00000000000..3186ab36806 --- /dev/null +++ b/Master/texmf-dist/doc/generic/polexpr/polexpr.rst.txt @@ -0,0 +1,157 @@ +.. comment: -*- fill-column: 72; mode: rst -*- + +========================= + Introduction to polexpr +========================= + +polexpr_ is a TeX and LaTeX macro package. + +To use it with Plain or formats other than LaTeX:: + + \input polexpr.sty + +To use it with LaTeX:: + + \usepackage{polexpr} + +polexpr_ loads xintexpr_ and extends its syntax with a polynomial type. + +Polynomials are defined via the :ref:`\\poldef <quick>` parser and +can then be manipulated via TeX macros for various operations such +as obtaining G.C.D.s, computing derivatives, or indefinite +integrals... many of these functionalities are available directly +via functions in the syntax recognized by the ``\poldef`` parser. + +Apart from the final step of internally creating some TeX macros +associated with the polynomial name, this is all done completely +expandably, and a polynomial expression can be fetched directly to +``\xinteval`` for a completely expandable operation from start to +finish. + +For polynomials fully declared via ``\poldef``, root localization +implementing the `Sturm algorithm`_ is available via macros. +Arbitrarily long decimal expansion of all real roots can be +obtained, and all rational roots can be found exactly. + +The legacy documentation section which showed examples of root +localization has been moved to the `polexpr-examples.pdf +<polexpr-examples.pdf>`_ document, where both the TeX code and its +output are displayed. + +To access this document (if the previous link for some reason does not +work):: + + texdoc polexpr-examples + + +Usage via xintsession_ +---------------------- + +The simplest manner to get a feeling for the package abilities regarding +in particularl root localization is to use it on the command line +via the xintsession_ interface. Here is an example:: + + $ rlwrap etex xintsession + [...xintsession welcome message...] + Starting in exact mode (floating point evaluations use 16 digits) + >>> &pol + pol mode (i.e. function definitions use \poldef) + >>> f(x) := x^7 - x^6 - 2x + 1; + f = x^7-x^6-2*x+1 + --> &GenFloat(f) lets f become usable as function in fp mode + --> &ROOTS(f) (resp. &ROOTS(f,N)) finds all rational roots exactly and + all irrational roots with at least 10 (resp. N) fractional digits + >>> &ROOTS(f) + Solving for real roots of f and assigning them (please wait...) + (mult. 1) Rootf_1 = -1.0719678841... + (mult. 1) Rootf_2 = 0.4962386948... + (mult. 1) Rootf_3 = 1.3151140860... + Square-free irrational part: x^7-x^6-2*x+1 + --> &REFINEROOTS(f,N) to extend real irr. roots to N fractional digits + >>> &REFINEROOTS(f,40) + Refining real roots of f to 40 digits (please wait...) + (mult. 1) Rootf_1 = -1.0719678841080266034109100331975342338141... + (mult. 1) Rootf_2 = 0.4962386948771497344730618510143671567979... + (mult. 1) Rootf_3 = 1.3151140860165192656960005018679846354234... + +The xintsession_ interface allows to define polynomial variables via its +``&pol`` mode. It also exposes :ref:`all polynomial functions added to the +xintexpr syntax <polexpr08>` by ``polexpr``. Further, as seen in the +example above it also covers some of the ``polexpr`` capabilities +currently implemented via user macros. This is to be considered a work +in progress, the above ``&ROOTS`` and ``&REFINEROOTS`` may be renamed +into something else, and may have been so already since this +documentation was written. + +Any input on the command line at the xintsession_ ``>>>`` prompt which +starts with a backslash is executed as TeX macros, so all macros of +``polexpr`` are in fact already available, including those typesetting +material in background of the interactive session on command line. The +``&ROOTS`` and ``&REFINEROOTS`` direct their outputs to the +terminal rather than to the TeX page as would the typesetting macros +defined by ``polexpr`` itself. + + +License is LPPL 1.3c +-------------------- + +This work is distributed under the conditions of the +LaTeX Project Public License version 1.3c. + +See README.md for details. + + +In memoriam: Jürgen Gilg (1967-2022) +------------------------------------ + +My first contact with Jürgen was in January 2018, and his *little +question* about usage of xintexpr_ for differentiating polynomials +proved the direct cause for the :ref:`creation of polexpr +<firstrelease>`. His regular comments and questions (often, jointly +with Thomas Söll) largely contributed to motivate the author into +investing time and effort into the somewhat strange occupation of +developing such unusual TeX/LaTeX packages. The topics of our +discussions evolved over the years and were not limited to TeX, LaTeX, +PSTricks or PostScript matters. + +I learned to discover and appreciate his unassuming and kind character. +He was very conscientious in all his projects with others and was often +overly generous in his appreciation of people's contributions. On +receiving the sad news of his unexpected and untimely death, I initially +thought I had been knowing him for at least 10 years, but it is actually +only a bit more than 4 years... I will sorely miss this friendship with +a gentle soul from *over the Rhine*. + +I dedicate the work which has gone into polexpr_ to Jürgen's memory. + + +.. _polexpr: https://www.ctan.org/pkg/polexpr + +.. _xinttools: +.. _xintfrac: +.. _xint: https://www.ctan.org/pkg/xint + +.. _xintexpr: https://www.ctan.org/pkg/xintexpr + +.. _xintsession: https://www.ctan.org/pkg/xintsession + +.. _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 + + +.. toctree:: + :hidden: + :maxdepth: 2 + + polexpr-ref + polexpr-changes + + + +.. Local variables: +.. sentence-end-double-space: t; +.. End: diff --git a/Master/texmf-dist/tex/generic/polexpr/polexpr-examples.tex b/Master/texmf-dist/tex/generic/polexpr/polexpr-examples.tex index fa2f330513b..564c1912da5 100644 --- a/Master/texmf-dist/tex/generic/polexpr/polexpr-examples.tex +++ b/Master/texmf-dist/tex/generic/polexpr/polexpr-examples.tex @@ -145,25 +145,12 @@ \makeatletter \catcode`_ 11 -\def\everbatimtop {\MacroFont\small}% default -\let\everbatimbottom\empty -\let\everbatimhook\empty - \def\everbatim {\s@everbatim\@everbatim } -\@namedef{everbatim*}{\s@everbatim\expandafter\@everbatimx\expandafter - {\the\newlinechar}} -\let\everbatimbgcolorcmd\empty -\def\everbatimeverypar{\strut - {\everbatimbgcolorcmd\vrule\@width\linewidth }% - \kern-\linewidth - \kern\everbatimindent } -\def\everbatimindent {\z@} -% voir plus loin atbegindocument +%! ancienne méthode sans doute motivé par possibilité code ferme un groupe? +%! \@namedef{everbatim*}{\s@everbatim\@everbatimx\expandafter +%! {\the\newlinechar}} +\@namedef{everbatim*}{\s@everbatim\@everbatimx } -\def\endeverbatim {\if@newlist \leavevmode\fi\endtrivlist } - -\@namedef{endeverbatim*}{\endeverbatim\aftergroup\everbatimundoparskip} -\def\everbatimundoparskip{\vbox{}\kern-\baselineskip\kern-\parskip} % Note 25 juin 2021 % On ne peut pas emboîter un everbatim à l'intérieur d'un everbatim % ou un everbatim* à l'intérieur d'un everbatim*... @@ -197,6 +184,14 @@ }% \obeylines \@vobeyspaces } +\def\everbatimtop {\MacroFont\small}% default +\let\everbatimhook\empty +\def\everbatimeverypar{\strut + {\everbatimbgcolorcmd\vrule\@width\linewidth }% + \kern-\linewidth + \kern\everbatimindent } +\let\everbatimbgcolorcmd\empty +\def\everbatimindent {\z@} \begingroup \lccode`X 13 @@ -210,31 +205,47 @@ |lowercase[|endgroup% both freezes catcodes and converts X to active ^^M |def|@everbatim #1X#2\end{everbatim}% [#2|end[everbatim]|everbatimbottom ] -|def|@everbatimx #1#2X#3\end{everbatimY}]% - {#3\end{everbatim*}% - \everbatimbottom +|def|@everbatimx #1X#2\end{everbatimY}]% + {#2\end{everbatim*}% +% refactored 2022/01/11, rather than passing \newlinechar value +% as was done formerly via everbatim* (see above) and fetching it here as #1 +% it is thus assumed executed contents will not terminate a scope + \edef\everbatimrestorenewlinechar{\newlinechar\the\newlinechar\relax}% \newlinechar 13 +% refactored 2022/01/11: +% attention, \parskip set to zero for execution of contents +% reason: avoid extra space if everbatim* is in an \item of a list +% between verbatim and output of execution, if it starts a paragraph +% \vskip-\parskip would be no good in case contents create a display + \edef\everbatimrestoreparskip{\parskip\the\parskip}% + \parskip\z@skip % execution as LaTeX code of contents \everbatimxprehook - \scantokens {#3}% - \newlinechar #1\relax + \scantokens {#2}% + \everbatimrestorenewlinechar + \everbatimrestoreparskip \everbatimxposthook }% - % L'espace venant du endofline final mis par \scantokens sera inhibé si #3 se % termine par un % ou un \x, etc... -\let\everbatimxfgcolorcmd\empty +\let\everbatimbottom\empty + +\def\endeverbatim {\if@newlist \leavevmode\fi\endtrivlist } +\@namedef{endeverbatim*}{\endeverbatim} +% \@namedef{endeverbatim*}{\endeverbatim\aftergroup\everbatimundoparskip} +% \def\everbatimundoparskip{\vbox{}\kern-\baselineskip\kern-\parskip} +% \let\everbatimundoparskip\empty + +% rationale: we do not want a group +% see xint.dtx for better way avoiding colorstack overflow problem +% with latex+dvipdfmx \def\everbatimxprehook {\colorlet{everbsavedcolor}{.}% - \everbatimxfgcolorcmd - \smallskip % pour polexpr-examples.tex - % à cause de problèmes avec les - % output en "display" - }% + \everbatimxfgcolorcmd}% +\let\everbatimxfgcolorcmd\empty % default \def\everbatimxposthook {\color{everbsavedcolor}} - \catcode`_ 8 \makeatother @@ -251,9 +262,9 @@ % \verb %\colorlet{verbcolor}{DarkCyan} -\colorlet{verbcolor}{black} +\colorlet{verbcolor}{Maroon} \colorlet{verbsoftwrapiconcolor}{DarkBlue} -\def\MicroFont{\ttfamily%\color{verbcolor} +\def\MicroFont{\ttfamily\color{verbcolor} \makestarlowast\makequotesstraight}% % everbatim/everbatim* @@ -265,11 +276,13 @@ \def\MacroFont{\ttfamily\color{everbatimfgcolor}} %\colorlet{everbatimbgcolor}{WhiteSmoke} -\colorlet{everbatimbgcolor}{Ivory} +%\colorlet{everbatimbgcolor}{Ivory} +\colorlet{everbatimbgcolor}{Beige} \def\everbatimbgcolorcmd{\color{everbatimbgcolor}} %\colorlet{everbatimxfgcolor}{MidnightBlue} -\colorlet{everbatimxfgcolor}{OliveDrab} +%\colorlet{everbatimxfgcolor}{OliveDrab} +\colorlet{everbatimxfgcolor}{Maroon} \def\everbatimxfgcolorcmd{\color{everbatimxfgcolor}} % Notice that \macrocode uses \macro@font which stores the \MacroFont meaning @@ -281,7 +294,7 @@ The package provides a parser |\poldef| of algebraic polynomial -expressions. +expressions. Once defined, a polynomial is usable by its name either as a numerical function in |\xintexpr/\xinteval|, or for additional polynomial @@ -373,11 +386,10 @@ file. \section{A first example} - In this example the polynomial is square-free. \begin{everbatim*} \poldef f(x) := x^7 - x^6 - 2x + 1; - +% \PolToSturm{f}{f} \PolSturmIsolateZeros{f} The \PolTypeset{f} polynomial has \PolSturmNbOfIsolatedZeros{f} distinct real diff --git a/Master/texmf-dist/tex/generic/polexpr/polexpr.sty b/Master/texmf-dist/tex/generic/polexpr/polexpr.sty index 7d3dbb36bda..b652675d916 100644 --- a/Master/texmf-dist/tex/generic/polexpr/polexpr.sty +++ b/Master/texmf-dist/tex/generic/polexpr/polexpr.sty @@ -2,7 +2,7 @@ % License: LPPL 1.3c (author-maintained) % Usage: \input polexpr.sty (Plain or other macro formats) % or \usepackage{polexpr} (LaTeX macro format) -% Release 0.8.6 (2022/01/09) of polexpr.sty. This file inputs +% Release 0.8.7 (2022/05/14) of polexpr.sty. This file inputs % polexprcore.tex % polexprexpr.tex % polexprsturm.tex @@ -54,7 +54,7 @@ \XINTsetupcatcodes% (does \endlinechar13 in particular) \XINT_providespackage \ProvidesPackage{polexpr}% - [2022/01/09 v0.8.6 Polynomial expressions with rational coefficients (JFB)]% + [2022/05/14 v0.8.7 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: @@ -199,12 +199,15 @@ %% %% \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}% +%% Ever since 1.0, catcode sanitisation was minimal and only handled +%% the semicolon. At last 0.8.7 uses \xintexprSafeCatcodes to enhance +%% compatibility with hostile contexts such as babel+french. This +%% adds overhead but at least is coherent with \xintdefvar/\xintdeffunc +\def\PolDef{\xintexprSafeCatcodes\POL@chkopt\POL@oPolDef[x]}% +\def\POL@oPolDef[#1]#2#3{\POL@defpol #2(#1):={#3};}% +\def\poldef{\xintexprSafeCatcodes\POL@defpol}% \def\POL@defpol #1(#2)#3=#4;{% - \POL@restoresemicolon + \xintexprRestoreCatcodes \edef\POL@polname{\xint_zapspaces #1 \xint_gobble_i}% \begingroup \unless\ifxintveryverbose\xintverbosefalse\fi @@ -214,7 +217,7 @@ %% 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]}}}));% + \xintdefvar_a __pol = subs(#4,#2=qraw({{P1.{0/1[0]}{1/1[0]}}}));% \expandafter \endgroup \expandafter\def\expandafter\POL@result\expandafter diff --git a/Master/texmf-dist/tex/generic/polexpr/polexprcore.tex b/Master/texmf-dist/tex/generic/polexpr/polexprcore.tex index 8dcc893844b..8bf7fe2fd0b 100644 --- a/Master/texmf-dist/tex/generic/polexpr/polexprcore.tex +++ b/Master/texmf-dist/tex/generic/polexpr/polexprcore.tex @@ -1,5 +1,5 @@ %% filename: polexprcore.tex -%% Part of the polexpr package (0.8.6, 2022/01/09) +%% Part of the polexpr package (0.8.7, 2022/05/14) %% %% Core routines for infix operators +, -, *, //, /:, ^, ** and functions %% diff --git a/Master/texmf-dist/tex/generic/polexpr/polexprexpr.tex b/Master/texmf-dist/tex/generic/polexpr/polexprexpr.tex index bbc860cbca4..91087bcf4df 100644 --- a/Master/texmf-dist/tex/generic/polexpr/polexprexpr.tex +++ b/Master/texmf-dist/tex/generic/polexpr/polexprexpr.tex @@ -1,5 +1,5 @@ %% filename: polexprexpr.tex -%% Part of the polexpr package (0.8.6, 2022/01/09) +%% Part of the polexpr package (0.8.7, 2022/05/14) %% %% Polynomial extensions to the \xintexpr syntax: %% diff --git a/Master/texmf-dist/tex/generic/polexpr/polexprsturm.tex b/Master/texmf-dist/tex/generic/polexpr/polexprsturm.tex index 0edc8b8f0a2..2f417c33332 100644 --- a/Master/texmf-dist/tex/generic/polexpr/polexprsturm.tex +++ b/Master/texmf-dist/tex/generic/polexpr/polexprsturm.tex @@ -1,5 +1,5 @@ %% filename: polexprsturm.tex -%% Part of the polexpr package (0.8.6, 2022/01/09) +%% Part of the polexpr package (0.8.7, 2022/05/14) %% %% Implements the Sturm localization Algorithm %% Added at polexpr 0.4 |