summaryrefslogtreecommitdiff
path: root/Master
diff options
context:
space:
mode:
Diffstat (limited to 'Master')
-rw-r--r--Master/texmf-dist/doc/latex/polexpr/README.md4
-rw-r--r--Master/texmf-dist/doc/latex/polexpr/polexpr.html1271
-rw-r--r--Master/texmf-dist/doc/latex/polexpr/polexpr.txt813
-rw-r--r--Master/texmf-dist/tex/latex/polexpr/polexpr.sty1168
4 files changed, 2365 insertions, 891 deletions
diff --git a/Master/texmf-dist/doc/latex/polexpr/README.md b/Master/texmf-dist/doc/latex/polexpr/README.md
index 405f832ae75..d0275013301 100644
--- a/Master/texmf-dist/doc/latex/polexpr/README.md
+++ b/Master/texmf-dist/doc/latex/polexpr/README.md
@@ -73,8 +73,10 @@ Releases
The `'` character can be used in polynomial names.
- 0.6 (2018/11/20)
New feature: multiplicity of roots.
+- 0.7 (2018/12/08)
+ New feature: finding all rational roots.
-Files of 0.6 release:
+Files of 0.7 release:
- README.md,
- polexpr.sty (package file),
diff --git a/Master/texmf-dist/doc/latex/polexpr/polexpr.html b/Master/texmf-dist/doc/latex/polexpr/polexpr.html
index 5408f16b65e..71e7ef3d019 100644
--- a/Master/texmf-dist/doc/latex/polexpr/polexpr.html
+++ b/Master/texmf-dist/doc/latex/polexpr/polexpr.html
@@ -362,137 +362,160 @@ ul.auto-toc {
<body>
<div class="document" id="package-polexpr-documentation">
<h1 class="title">Package polexpr documentation</h1>
-<h2 class="subtitle" id="id1">0.6 (2018/11/20)</h2>
+<h2 class="subtitle" id="id1">0.7 (2018/12/08)</h2>
<!-- comment: -*- fill-column: 72; mode: rst; -*- -->
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
-<li><a class="reference internal" href="#basic-examples" id="id36">Basic Examples</a></li>
-<li><a class="reference internal" href="#examples-of-localization-of-roots" id="id37">Examples of localization of roots</a><ul>
-<li><a class="reference internal" href="#a-typical-example" id="id38">A typical example</a></li>
-<li><a class="reference internal" href="#a-degree-four-polynomial-with-nearby-roots" id="id39">A degree four polynomial with nearby roots</a></li>
-<li><a class="reference internal" href="#the-degree-nine-polynomial-with-0-99-0-999-0-9999-as-triple-roots" id="id40">The degree nine polynomial with 0.99, 0.999, 0.9999 as triple roots</a></li>
-<li><a class="reference internal" href="#a-mignotte-type-polynomial" id="id41">A Mignotte type polynomial</a></li>
-<li><a class="reference internal" href="#the-degree-41-polynomial-with-2-1-9-1-8-0-0-1-1-9-2-as-roots" id="id42">The degree 41 polynomial with -2, -1.9, -1.8, ..., 0, 0.1, ..., 1.9, 2 as roots</a></li>
-<li><a class="reference internal" href="#roots-of-chebyshev-polynomials" id="id43">Roots of Chebyshev polynomials</a></li>
+<li><a class="reference internal" href="#basic-syntax" id="id38">Basic syntax</a></li>
+<li><a class="reference internal" href="#examples-of-localization-of-roots" id="id39">Examples of localization of roots</a><ul>
+<li><a class="reference internal" href="#a-typical-example" id="id40">A typical example</a></li>
+<li><a class="reference internal" href="#a-degree-four-polynomial-with-nearby-roots" id="id41">A degree four polynomial with nearby roots</a></li>
+<li><a class="reference internal" href="#the-degree-nine-polynomial-with-0-99-0-999-0-9999-as-triple-roots" id="id42">The degree nine polynomial with 0.99, 0.999, 0.9999 as triple roots</a></li>
+<li><a class="reference internal" href="#a-degree-five-polynomial-with-three-rational-roots" id="id43">A degree five polynomial with three rational roots</a></li>
+<li><a class="reference internal" href="#a-mignotte-type-polynomial" id="id44">A Mignotte type polynomial</a></li>
+<li><a class="reference internal" href="#the-wilkinson-polynomial" id="id45">The Wilkinson polynomial</a></li>
+<li><a class="reference internal" href="#the-degree-41-polynomial-with-2-1-9-1-8-0-0-1-1-9-2-as-roots" id="id46">The degree 41 polynomial with -2, -1.9, -1.8, ..., 0, 0.1, ..., 1.9, 2 as roots</a></li>
+<li><a class="reference internal" href="#roots-of-chebyshev-polynomials" id="id47">Roots of Chebyshev polynomials</a></li>
</ul>
</li>
-<li><a class="reference internal" href="#non-expandable-macros" id="id44">Non-expandable macros</a><ul>
-<li><a class="reference internal" href="#poldef-polname-letter-expression-in-letter" id="id45"><tt class="docutils literal">\poldef <span class="pre">polname(letter):=</span> expression in letter;</tt></a></li>
-<li><a class="reference internal" href="#poldef-letter-polname-expression-in-letter" id="id46"><tt class="docutils literal"><span class="pre">\PolDef[letter]{polname}{expression</span> in letter}</tt></a></li>
-<li><a class="reference internal" href="#polgenfloatvariant-polname" id="id47"><tt class="docutils literal">\PolGenFloatVariant{polname}</tt></a></li>
-<li><a class="reference internal" href="#pollet-polname-2-polname-1" id="id48"><tt class="docutils literal"><span class="pre">\PolLet{polname_2}={polname_1}</span></tt></a></li>
-<li><a class="reference internal" href="#polgloballet-polname-2-polname-1" id="id49"><tt class="docutils literal"><span class="pre">\PolGlobalLet{polname_2}={polname_1}</span></tt></a></li>
-<li><a class="reference internal" href="#polassign-polname-toarray-macro" id="id50"><tt class="docutils literal"><span class="pre">\PolAssign{polname}\toarray\macro</span></tt></a></li>
-<li><a class="reference internal" href="#polget-polname-fromarray-macro" id="id51"><tt class="docutils literal"><span class="pre">\PolGet{polname}\fromarray\macro</span></tt></a></li>
-<li><a class="reference internal" href="#polfromcsv-polname-csv" id="id52"><tt class="docutils literal"><span class="pre">\PolFromCSV{polname}{&lt;csv&gt;}</span></tt></a></li>
-<li><a class="reference internal" href="#poltypeset-polname" id="id53"><tt class="docutils literal">\PolTypeset{polname}</tt></a><ul>
-<li><a class="reference internal" href="#poltypesetcmd-raw-coeff" id="id54"><tt class="docutils literal">\PolTypesetCmd{raw_coeff}</tt></a></li>
-<li><a class="reference internal" href="#poltypesetone-raw-coeff" id="id55"><tt class="docutils literal">\PolTypesetOne{raw_coeff}</tt></a></li>
-<li><a class="reference internal" href="#id6" id="id56"><tt class="docutils literal">\PolTypesetMonomialCmd</tt></a></li>
-<li><a class="reference internal" href="#poltypesetcmdprefix-raw-coeff" id="id57"><tt class="docutils literal">\PolTypesetCmdPrefix{raw_coeff}</tt></a></li>
+<li><a class="reference internal" href="#non-expandable-macros" id="id48">Non-expandable macros</a><ul>
+<li><a class="reference internal" href="#poldef-polname-letter-expression-in-letter" id="id49"><tt class="docutils literal">\poldef <span class="pre">polname(letter):=</span> expression in letter;</tt></a></li>
+<li><a class="reference internal" href="#poldef-letter-polname-expression-in-letter" id="id50"><tt class="docutils literal"><span class="pre">\PolDef[letter]{polname}{expression</span> in letter}</tt></a></li>
+<li><a class="reference internal" href="#polgenfloatvariant-polname" id="id51"><tt class="docutils literal">\PolGenFloatVariant{polname}</tt></a></li>
+<li><a class="reference internal" href="#pollet-polname-2-polname-1" id="id52"><tt class="docutils literal"><span class="pre">\PolLet{polname_2}={polname_1}</span></tt></a></li>
+<li><a class="reference internal" href="#polgloballet-polname-2-polname-1" id="id53"><tt class="docutils literal"><span class="pre">\PolGlobalLet{polname_2}={polname_1}</span></tt></a></li>
+<li><a class="reference internal" href="#polassign-polname-toarray-macro" id="id54"><tt class="docutils literal"><span class="pre">\PolAssign{polname}\toarray\macro</span></tt></a></li>
+<li><a class="reference internal" href="#polget-polname-fromarray-macro" id="id55"><tt class="docutils literal"><span class="pre">\PolGet{polname}\fromarray\macro</span></tt></a></li>
+<li><a class="reference internal" href="#polfromcsv-polname-csv" id="id56"><tt class="docutils literal"><span class="pre">\PolFromCSV{polname}{&lt;csv&gt;}</span></tt></a></li>
+<li><a class="reference internal" href="#poltypeset-polname" id="id57"><tt class="docutils literal">\PolTypeset{polname}</tt></a><ul>
+<li><a class="reference internal" href="#poltypesetcmd-raw-coeff" id="id58"><tt class="docutils literal">\PolTypesetCmd{raw_coeff}</tt></a></li>
+<li><a class="reference internal" href="#poltypesetone-raw-coeff" id="id59"><tt class="docutils literal">\PolTypesetOne{raw_coeff}</tt></a></li>
+<li><a class="reference internal" href="#id6" id="id60"><tt class="docutils literal">\PolTypesetMonomialCmd</tt></a></li>
+<li><a class="reference internal" href="#poltypesetcmdprefix-raw-coeff" id="id61"><tt class="docutils literal">\PolTypesetCmdPrefix{raw_coeff}</tt></a></li>
</ul>
</li>
-<li><a class="reference internal" href="#id8" id="id58"><tt class="docutils literal"><span class="pre">\PolTypeset*{polname}</span></tt></a></li>
-<li><a class="reference internal" href="#poldiff-polname-1-polname-2" id="id59"><tt class="docutils literal"><span class="pre">\PolDiff{polname_1}{polname_2}</span></tt></a></li>
-<li><a class="reference internal" href="#poldiff-n-polname-1-polname-2" id="id60"><tt class="docutils literal"><span class="pre">\PolDiff[N]{polname_1}{polname_2}</span></tt></a></li>
-<li><a class="reference internal" href="#polantidiff-polname-1-polname-2" id="id61"><tt class="docutils literal"><span class="pre">\PolAntiDiff{polname_1}{polname_2}</span></tt></a></li>
-<li><a class="reference internal" href="#polantidiff-n-polname-1-polname-2" id="id62"><tt class="docutils literal"><span class="pre">\PolAntiDiff[N]{polname_1}{polname_2}</span></tt></a></li>
-<li><a class="reference internal" href="#poldivide-polname-1-polname-2-polname-q-polname-r" id="id63"><tt class="docutils literal"><span class="pre">\PolDivide{polname_1}{polname_2}{polname_Q}{polname_R}</span></tt></a></li>
-<li><a class="reference internal" href="#polquo-polname-1-polname-2-polname-q" id="id64"><tt class="docutils literal"><span class="pre">\PolQuo{polname_1}{polname_2}{polname_Q}</span></tt></a></li>
-<li><a class="reference internal" href="#polrem-polname-1-polname-2-polname-r" id="id65"><tt class="docutils literal"><span class="pre">\PolRem{polname_1}{polname_2}{polname_R}</span></tt></a></li>
-<li><a class="reference internal" href="#polgcd-polname-1-polname-2-polname-gcd" id="id66"><tt class="docutils literal"><span class="pre">\PolGCD{polname_1}{polname_2}{polname_GCD}</span></tt></a></li>
-<li><a class="reference internal" href="#poltosturm-polname-sturmname" id="id67"><tt class="docutils literal"><span class="pre">\PolToSturm{polname}{sturmname}</span></tt></a></li>
-<li><a class="reference internal" href="#id10" id="id68"><tt class="docutils literal"><span class="pre">\PolToSturm*{polname}{sturmname}</span></tt></a></li>
-<li><a class="reference internal" href="#polsettosturmchainsignchangesat-macro-sturmname-fraction" id="id69"><tt class="docutils literal"><span class="pre">\PolSetToSturmChainSignChangesAt{\macro}{sturmname}{fraction}</span></tt></a></li>
-<li><a class="reference internal" href="#polsettonbofzeroswithin-macro-sturmname-value-a-value-b" id="id70"><tt class="docutils literal"><span class="pre">\PolSetToNbOfZerosWithin{\macro}{sturmname}{value_a}{value_b}</span></tt></a></li>
-<li><a class="reference internal" href="#polsturmisolatezeros-sturmname" id="id71"><tt class="docutils literal">\PolSturmIsolateZeros{sturmname}</tt></a></li>
-<li><a class="reference internal" href="#id12" id="id72"><tt class="docutils literal"><span class="pre">\PolSturmIsolateZeros*{sturmname}</span></tt></a></li>
-<li><a class="reference internal" href="#polsturmisolatezerosandgetmultiplicities-sturmname" id="id73"><tt class="docutils literal">\PolSturmIsolateZerosAndGetMultiplicities{sturmname}</tt></a></li>
-<li><a class="reference internal" href="#polrefineinterval-sturmname-index" id="id74"><tt class="docutils literal"><span class="pre">\PolRefineInterval*{sturmname}{index}</span></tt></a></li>
-<li><a class="reference internal" href="#polrefineinterval-n-sturmname-index" id="id75"><tt class="docutils literal"><span class="pre">\PolRefineInterval[N]{sturmname}{index}</span></tt></a></li>
-<li><a class="reference internal" href="#polensureintervallength-sturmname-index-e" id="id76"><tt class="docutils literal"><span class="pre">\PolEnsureIntervalLength{sturmname}{index}{E}</span></tt></a></li>
-<li><a class="reference internal" href="#polensureintervallengths-sturmname-e" id="id77"><tt class="docutils literal"><span class="pre">\PolEnsureIntervalLengths{sturmname}{E}</span></tt></a></li>
-<li><a class="reference internal" href="#polprintintervals-varname-sturmname" id="id78"><tt class="docutils literal"><span class="pre">\PolPrintIntervals[varname]{sturmname}</span></tt></a><ul>
-<li><a class="reference internal" href="#id13" id="id79"><tt class="docutils literal">\PolPrintIntervalsPrintExactZero</tt></a></li>
-<li><a class="reference internal" href="#id14" id="id80"><tt class="docutils literal">\PolPrintIntervalsPrintLeftEndPoint</tt></a></li>
-<li><a class="reference internal" href="#id15" id="id81"><tt class="docutils literal">\PolPrintIntervalsPrintRightEndPoint</tt></a></li>
+<li><a class="reference internal" href="#id8" id="id62"><tt class="docutils literal"><span class="pre">\PolTypeset*{polname}</span></tt></a></li>
+<li><a class="reference internal" href="#poldiff-polname-1-polname-2" id="id63"><tt class="docutils literal"><span class="pre">\PolDiff{polname_1}{polname_2}</span></tt></a></li>
+<li><a class="reference internal" href="#poldiff-n-polname-1-polname-2" id="id64"><tt class="docutils literal"><span class="pre">\PolDiff[N]{polname_1}{polname_2}</span></tt></a></li>
+<li><a class="reference internal" href="#polantidiff-polname-1-polname-2" id="id65"><tt class="docutils literal"><span class="pre">\PolAntiDiff{polname_1}{polname_2}</span></tt></a></li>
+<li><a class="reference internal" href="#polantidiff-n-polname-1-polname-2" id="id66"><tt class="docutils literal"><span class="pre">\PolAntiDiff[N]{polname_1}{polname_2}</span></tt></a></li>
+<li><a class="reference internal" href="#poldivide-polname-1-polname-2-polname-q-polname-r" id="id67"><tt class="docutils literal"><span class="pre">\PolDivide{polname_1}{polname_2}{polname_Q}{polname_R}</span></tt></a></li>
+<li><a class="reference internal" href="#polquo-polname-1-polname-2-polname-q" id="id68"><tt class="docutils literal"><span class="pre">\PolQuo{polname_1}{polname_2}{polname_Q}</span></tt></a></li>
+<li><a class="reference internal" href="#polrem-polname-1-polname-2-polname-r" id="id69"><tt class="docutils literal"><span class="pre">\PolRem{polname_1}{polname_2}{polname_R}</span></tt></a></li>
+<li><a class="reference internal" href="#polgcd-polname-1-polname-2-polname-gcd" id="id70"><tt class="docutils literal"><span class="pre">\PolGCD{polname_1}{polname_2}{polname_GCD}</span></tt></a></li>
+<li><a class="reference internal" href="#poltosturm-polname-sturmname" id="id71"><tt class="docutils literal"><span class="pre">\PolToSturm{polname}{sturmname}</span></tt></a></li>
+<li><a class="reference internal" href="#id10" id="id72"><tt class="docutils literal"><span class="pre">\PolToSturm*{polname}{sturmname}</span></tt></a></li>
+<li><a class="reference internal" href="#polsettosturmchainsignchangesat-macro-sturmname-fraction" id="id73"><tt class="docutils literal"><span class="pre">\PolSetToSturmChainSignChangesAt{\macro}{sturmname}{fraction}</span></tt></a></li>
+<li><a class="reference internal" href="#polsettonbofzeroswithin-macro-sturmname-value-a-value-b" id="id74"><tt class="docutils literal"><span class="pre">\PolSetToNbOfZerosWithin{\macro}{sturmname}{value_a}{value_b}</span></tt></a></li>
+<li><a class="reference internal" href="#polsturmisolatezeros-sturmname" id="id75"><tt class="docutils literal">\PolSturmIsolateZeros{sturmname}</tt></a></li>
+<li><a class="reference internal" href="#id12" id="id76"><tt class="docutils literal"><span class="pre">\PolSturmIsolateZeros*{sturmname}</span></tt></a></li>
+<li><a class="reference internal" href="#id14" id="id77"><tt class="docutils literal"><span class="pre">\PolSturmIsolateZeros**{sturmname}</span></tt></a></li>
+<li><a class="reference internal" href="#polsturmisolatezerosandgetmultiplicities-sturmname" id="id78"><tt class="docutils literal">\PolSturmIsolateZerosAndGetMultiplicities{sturmname}</tt></a></li>
+<li><a class="reference internal" href="#polsturmisolatezerosgetmultiplicitiesandrationalroots-sturmname" id="id79"><tt class="docutils literal">\PolSturmIsolateZerosGetMultiplicitiesAndRationalRoots{sturmname}</tt></a></li>
+<li><a class="reference internal" href="#polsturmisolatezerosandfindrationalroots-sturmname" id="id80"><tt class="docutils literal">\PolSturmIsolateZerosAndFindRationalRoots{sturmname}</tt></a></li>
+<li><a class="reference internal" href="#polrefineinterval-sturmname-index" id="id81"><tt class="docutils literal"><span class="pre">\PolRefineInterval*{sturmname}{index}</span></tt></a></li>
+<li><a class="reference internal" href="#polrefineinterval-n-sturmname-index" id="id82"><tt class="docutils literal"><span class="pre">\PolRefineInterval[N]{sturmname}{index}</span></tt></a></li>
+<li><a class="reference internal" href="#polensureintervallength-sturmname-index-e" id="id83"><tt class="docutils literal"><span class="pre">\PolEnsureIntervalLength{sturmname}{index}{E}</span></tt></a></li>
+<li><a class="reference internal" href="#polensureintervallengths-sturmname-e" id="id84"><tt class="docutils literal"><span class="pre">\PolEnsureIntervalLengths{sturmname}{E}</span></tt></a></li>
+<li><a class="reference internal" href="#polprintintervals-varname-sturmname" id="id85"><tt class="docutils literal"><span class="pre">\PolPrintIntervals[varname]{sturmname}</span></tt></a><ul>
+<li><a class="reference internal" href="#polprintintervalsnorealroots" id="id86"><tt class="docutils literal">\PolPrintIntervalsNoRealRoots</tt></a></li>
+<li><a class="reference internal" href="#polprintintervalsbeginenv" id="id87"><tt class="docutils literal">\PolPrintIntervalsBeginEnv</tt></a></li>
+<li><a class="reference internal" href="#polprintintervalsendenv" id="id88"><tt class="docutils literal">\PolPrintIntervalsEndEnv</tt></a></li>
+<li><a class="reference internal" href="#polprintintervalsknownroot" id="id89"><tt class="docutils literal">\PolPrintIntervalsKnownRoot</tt></a></li>
+<li><a class="reference internal" href="#polprintintervalsunknownroot" id="id90"><tt class="docutils literal">\PolPrintIntervalsUnknownRoot</tt></a></li>
+<li><a class="reference internal" href="#id15" id="id91"><tt class="docutils literal">\PolPrintIntervalsPrintExactZero</tt></a></li>
+<li><a class="reference internal" href="#id16" id="id92"><tt class="docutils literal">\PolPrintIntervalsPrintLeftEndPoint</tt></a></li>
+<li><a class="reference internal" href="#id17" id="id93"><tt class="docutils literal">\PolPrintIntervalsPrintRightEndPoint</tt></a></li>
</ul>
</li>
-<li><a class="reference internal" href="#polmapcoeffs-macro-polname" id="id82"><tt class="docutils literal"><span class="pre">\PolMapCoeffs{\macro}{polname}</span></tt></a></li>
-<li><a class="reference internal" href="#polreducecoeffs-polname" id="id83"><tt class="docutils literal">\PolReduceCoeffs{polname}</tt></a></li>
-<li><a class="reference internal" href="#id17" id="id84"><tt class="docutils literal"><span class="pre">\PolReduceCoeffs*{polname}</span></tt></a></li>
-<li><a class="reference internal" href="#polmakemonic-polname" id="id85"><tt class="docutils literal">\PolMakeMonic{polname}</tt></a></li>
-<li><a class="reference internal" href="#polmakeprimitive-polname" id="id86"><tt class="docutils literal">\PolMakePrimitive{polname}</tt></a></li>
+<li><a class="reference internal" href="#id19" id="id94"><tt class="docutils literal"><span class="pre">\PolPrintIntervals*[varname]{sturmname}</span></tt></a><ul>
+<li><a class="reference internal" href="#polprintintervalsprintmultiplicity" id="id95"><tt class="docutils literal">\PolPrintIntervalsPrintMultiplicity</tt></a></li>
</ul>
</li>
-<li><a class="reference internal" href="#expandable-macros" id="id87">Expandable macros</a><ul>
-<li><a class="reference internal" href="#poleval-polname-atexpr-numerical-expression" id="id88"><tt class="docutils literal"><span class="pre">\PolEval{polname}\AtExpr{numerical</span> expression}</tt></a></li>
-<li><a class="reference internal" href="#poleval-polname-at-fraction" id="id89"><tt class="docutils literal"><span class="pre">\PolEval{polname}\At{fraction}</span></tt></a></li>
-<li><a class="reference internal" href="#polevalreduced-polname-atexpr-numerical-expression" id="id90"><tt class="docutils literal"><span class="pre">\PolEvalReduced{polname}\AtExpr{numerical</span> expression}</tt></a></li>
-<li><a class="reference internal" href="#polevalreduced-polname-at-fraction" id="id91"><tt class="docutils literal"><span class="pre">\PolEvalReduced{polname}\At{fraction}</span></tt></a></li>
-<li><a class="reference internal" href="#polfloateval-polname-atexpr-numerical-expression" id="id92"><tt class="docutils literal"><span class="pre">\PolFloatEval{polname}\AtExpr{numerical</span> expression}</tt></a></li>
-<li><a class="reference internal" href="#polfloateval-polname-at-fraction" id="id93"><tt class="docutils literal"><span class="pre">\PolFloatEval{polname}\At{fraction}</span></tt></a></li>
-<li><a class="reference internal" href="#polifcoeffisplusorminusone-a-b" id="id94"><tt class="docutils literal"><span class="pre">\PolIfCoeffIsPlusOrMinusOne{A}{B}</span></tt></a></li>
-<li><a class="reference internal" href="#polleadingcoeff-polname" id="id95"><tt class="docutils literal">\PolLeadingCoeff{polname}</tt></a></li>
-<li><a class="reference internal" href="#polnthcoeff-polname-number" id="id96"><tt class="docutils literal"><span class="pre">\PolNthCoeff{polname}{number}</span></tt></a></li>
-<li><a class="reference internal" href="#poldegree-polname" id="id97"><tt class="docutils literal">\PolDegree{polname}</tt></a></li>
-<li><a class="reference internal" href="#policontent-polname" id="id98"><tt class="docutils literal">\PolIContent{polname}</tt></a></li>
-<li><a class="reference internal" href="#poltoexpr-polname" id="id99"><tt class="docutils literal">\PolToExpr{polname}</tt></a><ul>
-<li><a class="reference internal" href="#poltoexproneterm-raw-coeff-number" id="id100"><tt class="docutils literal"><span class="pre">\PolToExprOneTerm{raw_coeff}{number}</span></tt></a></li>
-<li><a class="reference internal" href="#poltoexpronetermstylea-raw-coeff-number" id="id101"><tt class="docutils literal"><span class="pre">\PolToExprOneTermStyleA{raw_coeff}{number}</span></tt></a></li>
-<li><a class="reference internal" href="#poltoexpronetermstyleb-raw-coeff-number" id="id102"><tt class="docutils literal"><span class="pre">\PolToExprOneTermStyleB{raw_coeff}{number}</span></tt></a></li>
-<li><a class="reference internal" href="#poltoexprcmd-raw-coeff" id="id103"><tt class="docutils literal">\PolToExprCmd{raw_coeff}</tt></a></li>
-<li><a class="reference internal" href="#poltoexprtermprefix-raw-coeff" id="id104"><tt class="docutils literal">\PolToExprTermPrefix{raw_coeff}</tt></a></li>
-<li><a class="reference internal" href="#id24" id="id105"><tt class="docutils literal">\PolToExprVar</tt></a></li>
-<li><a class="reference internal" href="#id25" id="id106"><tt class="docutils literal">\PolToExprTimes</tt></a></li>
+<li><a class="reference internal" href="#polmapcoeffs-macro-polname" id="id96"><tt class="docutils literal"><span class="pre">\PolMapCoeffs{\macro}{polname}</span></tt></a></li>
+<li><a class="reference internal" href="#polreducecoeffs-polname" id="id97"><tt class="docutils literal">\PolReduceCoeffs{polname}</tt></a></li>
+<li><a class="reference internal" href="#id21" id="id98"><tt class="docutils literal"><span class="pre">\PolReduceCoeffs*{polname}</span></tt></a></li>
+<li><a class="reference internal" href="#polmakemonic-polname" id="id99"><tt class="docutils literal">\PolMakeMonic{polname}</tt></a></li>
+<li><a class="reference internal" href="#polmakeprimitive-polname" id="id100"><tt class="docutils literal">\PolMakePrimitive{polname}</tt></a></li>
</ul>
</li>
-<li><a class="reference internal" href="#id27" id="id107"><tt class="docutils literal"><span class="pre">\PolToExpr*{polname}</span></tt></a></li>
-<li><a class="reference internal" href="#poltofloatexpr-polname" id="id108"><tt class="docutils literal">\PolToFloatExpr{polname}</tt></a><ul>
-<li><a class="reference internal" href="#poltofloatexproneterm-raw-coeff-number" id="id109"><tt class="docutils literal"><span class="pre">\PolToFloatExprOneTerm{raw_coeff}{number}</span></tt></a></li>
-<li><a class="reference internal" href="#poltofloatexprcmd-raw-coeff" id="id110"><tt class="docutils literal">\PolToFloatExprCmd{raw_coeff}</tt></a></li>
+<li><a class="reference internal" href="#expandable-macros" id="id101">Expandable macros</a><ul>
+<li><a class="reference internal" href="#poleval-polname-atexpr-numerical-expression" id="id102"><tt class="docutils literal"><span class="pre">\PolEval{polname}\AtExpr{numerical</span> expression}</tt></a></li>
+<li><a class="reference internal" href="#poleval-polname-at-fraction" id="id103"><tt class="docutils literal"><span class="pre">\PolEval{polname}\At{fraction}</span></tt></a></li>
+<li><a class="reference internal" href="#polevalreduced-polname-atexpr-numerical-expression" id="id104"><tt class="docutils literal"><span class="pre">\PolEvalReduced{polname}\AtExpr{numerical</span> expression}</tt></a></li>
+<li><a class="reference internal" href="#polevalreduced-polname-at-fraction" id="id105"><tt class="docutils literal"><span class="pre">\PolEvalReduced{polname}\At{fraction}</span></tt></a></li>
+<li><a class="reference internal" href="#polfloateval-polname-atexpr-numerical-expression" id="id106"><tt class="docutils literal"><span class="pre">\PolFloatEval{polname}\AtExpr{numerical</span> expression}</tt></a></li>
+<li><a class="reference internal" href="#polfloateval-polname-at-fraction" id="id107"><tt class="docutils literal"><span class="pre">\PolFloatEval{polname}\At{fraction}</span></tt></a></li>
+<li><a class="reference internal" href="#polifcoeffisplusorminusone-a-b" id="id108"><tt class="docutils literal"><span class="pre">\PolIfCoeffIsPlusOrMinusOne{A}{B}</span></tt></a></li>
+<li><a class="reference internal" href="#polleadingcoeff-polname" id="id109"><tt class="docutils literal">\PolLeadingCoeff{polname}</tt></a></li>
+<li><a class="reference internal" href="#polnthcoeff-polname-number" id="id110"><tt class="docutils literal"><span class="pre">\PolNthCoeff{polname}{number}</span></tt></a></li>
+<li><a class="reference internal" href="#poldegree-polname" id="id111"><tt class="docutils literal">\PolDegree{polname}</tt></a></li>
+<li><a class="reference internal" href="#policontent-polname" id="id112"><tt class="docutils literal">\PolIContent{polname}</tt></a></li>
+<li><a class="reference internal" href="#poltoexpr-polname" id="id113"><tt class="docutils literal">\PolToExpr{polname}</tt></a><ul>
+<li><a class="reference internal" href="#poltoexproneterm-raw-coeff-number" id="id114"><tt class="docutils literal"><span class="pre">\PolToExprOneTerm{raw_coeff}{number}</span></tt></a></li>
+<li><a class="reference internal" href="#poltoexpronetermstylea-raw-coeff-number" id="id115"><tt class="docutils literal"><span class="pre">\PolToExprOneTermStyleA{raw_coeff}{number}</span></tt></a></li>
+<li><a class="reference internal" href="#poltoexpronetermstyleb-raw-coeff-number" id="id116"><tt class="docutils literal"><span class="pre">\PolToExprOneTermStyleB{raw_coeff}{number}</span></tt></a></li>
+<li><a class="reference internal" href="#poltoexprcmd-raw-coeff" id="id117"><tt class="docutils literal">\PolToExprCmd{raw_coeff}</tt></a></li>
+<li><a class="reference internal" href="#poltoexprtermprefix-raw-coeff" id="id118"><tt class="docutils literal">\PolToExprTermPrefix{raw_coeff}</tt></a></li>
+<li><a class="reference internal" href="#id28" id="id119"><tt class="docutils literal">\PolToExprVar</tt></a></li>
+<li><a class="reference internal" href="#id29" id="id120"><tt class="docutils literal">\PolToExprTimes</tt></a></li>
</ul>
</li>
-<li><a class="reference internal" href="#id31" id="id111"><tt class="docutils literal"><span class="pre">\PolToFloatExpr*{polname}</span></tt></a></li>
-<li><a class="reference internal" href="#poltolist-polname" id="id112"><tt class="docutils literal">\PolToList{polname}</tt></a></li>
-<li><a class="reference internal" href="#poltocsv-polname" id="id113"><tt class="docutils literal">\PolToCSV{polname}</tt></a></li>
-<li><a class="reference internal" href="#polsturmchainlength-sturmname" id="id114"><tt class="docutils literal">\PolSturmChainLength{sturmname}</tt></a></li>
-<li><a class="reference internal" href="#polsturmifzeroexactlyknown-sturmname-index-a-b" id="id115"><tt class="docutils literal"><span class="pre">\PolSturmIfZeroExactlyKnown{sturmname}{index}{A}{B}</span></tt></a></li>
-<li><a class="reference internal" href="#polsturmisolatedzeroleft-sturmname-index" id="id116"><tt class="docutils literal"><span class="pre">\PolSturmIsolatedZeroLeft{sturmname}{index}</span></tt></a></li>
-<li><a class="reference internal" href="#polsturmisolatedzeroright-sturmname-index" id="id117"><tt class="docutils literal"><span class="pre">\PolSturmIsolatedZeroRight{sturmname}{index}</span></tt></a></li>
-<li><a class="reference internal" href="#polsturmisolatedzeromultiplicity-sturmname-index" id="id118"><tt class="docutils literal"><span class="pre">\PolSturmIsolatedZeroMultiplicity{sturmname}{index}</span></tt></a></li>
-<li><a class="reference internal" href="#polsturmnbofisolatedzeros-sturmname" id="id119"><tt class="docutils literal">\PolSturmNbOfIsolatedZeros{sturmname}</tt></a></li>
-<li><a class="reference internal" href="#polsturmnbofrootsof-sturmname-lessthanorequalto-value" id="id120"><tt class="docutils literal"><span class="pre">\PolSturmNbOfRootsOf{sturmname}\LessThanOrEqualTo{value}</span></tt></a></li>
-<li><a class="reference internal" href="#polsturmnbofrootsof-sturmname-lessthanorequaltoexpr-expression" id="id121"><tt class="docutils literal"><span class="pre">\PolSturmNbOfRootsOf{sturmname}\LessThanOrEqualToExpr{expression}</span></tt></a></li>
-<li><a class="reference internal" href="#polsturmnbwithmultofrootsof-sturmname-lessthanorequalto-value" id="id122"><tt class="docutils literal"><span class="pre">\PolSturmNbWithMultOfRootsOf{sturmname}\LessThanOrEqualTo{value}</span></tt></a></li>
-<li><a class="reference internal" href="#polsturmnbwithmultofrootsof-sturmname-lessthanorequaltoexpr-expression" id="id123"><tt class="docutils literal"><span class="pre">\PolSturmNbWithMultOfRootsOf{sturmname}\LessThanOrEqualToExpr{expression}</span></tt></a></li>
-<li><a class="reference internal" href="#polintervalwidth-sturmname-index" id="id124"><tt class="docutils literal"><span class="pre">\PolIntervalWidth{sturmname}{index}</span></tt></a></li>
-<li><a class="reference internal" href="#macros-for-use-within-execution-of-polprintintervals" id="id125">Macros for use within execution of <tt class="docutils literal">\PolPrintIntervals</tt></a><ul>
-<li><a class="reference internal" href="#id32" id="id126"><tt class="docutils literal">\PolPrintIntervalsTheEndPoint</tt></a></li>
-<li><a class="reference internal" href="#id33" id="id127"><tt class="docutils literal">\PolPrintIntervalsTheIndex</tt></a></li>
-<li><a class="reference internal" href="#polifendpointispositive-a-b" id="id128"><tt class="docutils literal"><span class="pre">\PolIfEndPointIsPositive{A}{B}</span></tt></a></li>
-<li><a class="reference internal" href="#polifendpointisnegative-a-b" id="id129"><tt class="docutils literal"><span class="pre">\PolIfEndPointIsNegative{A}{B}</span></tt></a></li>
-<li><a class="reference internal" href="#polifendpointiszero-a-b" id="id130"><tt class="docutils literal"><span class="pre">\PolIfEndPointIsZero{A}{B}</span></tt></a></li>
+<li><a class="reference internal" href="#id31" id="id121"><tt class="docutils literal"><span class="pre">\PolToExpr*{polname}</span></tt></a></li>
+<li><a class="reference internal" href="#poltofloatexpr-polname" id="id122"><tt class="docutils literal">\PolToFloatExpr{polname}</tt></a><ul>
+<li><a class="reference internal" href="#poltofloatexproneterm-raw-coeff-number" id="id123"><tt class="docutils literal"><span class="pre">\PolToFloatExprOneTerm{raw_coeff}{number}</span></tt></a></li>
+<li><a class="reference internal" href="#poltofloatexprcmd-raw-coeff" id="id124"><tt class="docutils literal">\PolToFloatExprCmd{raw_coeff}</tt></a></li>
</ul>
</li>
-<li><a class="reference internal" href="#poldectostring-decimal-number" id="id131"><tt class="docutils literal">\PolDecToString{decimal number}</tt></a></li>
+<li><a class="reference internal" href="#id35" id="id125"><tt class="docutils literal"><span class="pre">\PolToFloatExpr*{polname}</span></tt></a></li>
+<li><a class="reference internal" href="#poltolist-polname" id="id126"><tt class="docutils literal">\PolToList{polname}</tt></a></li>
+<li><a class="reference internal" href="#poltocsv-polname" id="id127"><tt class="docutils literal">\PolToCSV{polname}</tt></a></li>
+<li><a class="reference internal" href="#polsturmchainlength-sturmname" id="id128"><tt class="docutils literal">\PolSturmChainLength{sturmname}</tt></a></li>
+<li><a class="reference internal" href="#polsturmifzeroexactlyknown-sturmname-index-a-b" id="id129"><tt class="docutils literal"><span class="pre">\PolSturmIfZeroExactlyKnown{sturmname}{index}{A}{B}</span></tt></a></li>
+<li><a class="reference internal" href="#polsturmisolatedzeroleft-sturmname-index" id="id130"><tt class="docutils literal"><span class="pre">\PolSturmIsolatedZeroLeft{sturmname}{index}</span></tt></a></li>
+<li><a class="reference internal" href="#polsturmisolatedzeroright-sturmname-index" id="id131"><tt class="docutils literal"><span class="pre">\PolSturmIsolatedZeroRight{sturmname}{index}</span></tt></a></li>
+<li><a class="reference internal" href="#polsturmisolatedzeromultiplicity-sturmname-index" id="id132"><tt class="docutils literal"><span class="pre">\PolSturmIsolatedZeroMultiplicity{sturmname}{index}</span></tt></a></li>
+<li><a class="reference internal" href="#polsturmnbofisolatedzeros-sturmname" id="id133"><tt class="docutils literal">\PolSturmNbOfIsolatedZeros{sturmname}</tt></a><ul>
+<li><a class="reference internal" href="#polsturmnbofrootsof-sturmname-lessthanorequalto-value" id="id134"><tt class="docutils literal"><span class="pre">\PolSturmNbOfRootsOf{sturmname}\LessThanOrEqualTo{value}</span></tt></a></li>
+<li><a class="reference internal" href="#polsturmnbofrootsof-sturmname-lessthanorequaltoexpr-expression" id="id135"><tt class="docutils literal"><span class="pre">\PolSturmNbOfRootsOf{sturmname}\LessThanOrEqualToExpr{expression}</span></tt></a></li>
+<li><a class="reference internal" href="#polsturmnbwithmultofrootsof-sturmname-lessthanorequalto-value" id="id136"><tt class="docutils literal"><span class="pre">\PolSturmNbWithMultOfRootsOf{sturmname}\LessThanOrEqualTo{value}</span></tt></a></li>
+<li><a class="reference internal" href="#polsturmnbwithmultofrootsof-sturmname-lessthanorequaltoexpr-expression" id="id137"><tt class="docutils literal"><span class="pre">\PolSturmNbWithMultOfRootsOf{sturmname}\LessThanOrEqualToExpr{expression}</span></tt></a></li>
</ul>
</li>
-<li><a class="reference internal" href="#booleans-with-default-setting-as-indicated" id="id132">Booleans (with default setting as indicated)</a><ul>
-<li><a class="reference internal" href="#xintverbosefalse" id="id133"><tt class="docutils literal">\xintverbosefalse</tt></a></li>
-<li><a class="reference internal" href="#poltypesetallfalse" id="id134"><tt class="docutils literal">\poltypesetallfalse</tt></a></li>
-<li><a class="reference internal" href="#poltoexprallfalse" id="id135"><tt class="docutils literal">\poltoexprallfalse</tt></a></li>
+<li><a class="reference internal" href="#polsturmnbofrationalroots-sturmname" id="id138"><tt class="docutils literal">\PolSturmNbOfRationalRoots{sturmname}</tt></a></li>
+<li><a class="reference internal" href="#polsturmnbofrationalrootswithmultiplicities-sturmname" id="id139"><tt class="docutils literal">\PolSturmNbOfRationalRootsWithMultiplicities{sturmname}</tt></a></li>
+<li><a class="reference internal" href="#polsturmrationalroot-sturmname-k" id="id140"><tt class="docutils literal"><span class="pre">\PolSturmRationalRoot{sturmname}{k}</span></tt></a></li>
+<li><a class="reference internal" href="#polsturmrationalrootindex-sturmname-k" id="id141"><tt class="docutils literal"><span class="pre">\PolSturmRationalRootIndex{sturmname}{k}</span></tt></a></li>
+<li><a class="reference internal" href="#polsturmrationalrootmultiplicity-sturmname-k" id="id142"><tt class="docutils literal"><span class="pre">\PolSturmRationalRootMultiplicity{sturmname}{k}</span></tt></a></li>
+<li><a class="reference internal" href="#polintervalwidth-sturmname-index" id="id143"><tt class="docutils literal"><span class="pre">\PolIntervalWidth{sturmname}{index}</span></tt></a></li>
+<li><a class="reference internal" href="#expandable-macros-for-use-within-execution-of-polprintintervals" id="id144">Expandable macros for use within execution of <tt class="docutils literal">\PolPrintIntervals</tt></a><ul>
+<li><a class="reference internal" href="#polprintintervalsthevar" id="id145"><tt class="docutils literal">\PolPrintIntervalsTheVar</tt></a></li>
+<li><a class="reference internal" href="#polprintintervalstheindex" id="id146"><tt class="docutils literal">\PolPrintIntervalsTheIndex</tt></a></li>
+<li><a class="reference internal" href="#polprintintervalsthesturmname" id="id147"><tt class="docutils literal">\PolPrintIntervalsTheSturmName</tt></a></li>
+<li><a class="reference internal" href="#polprintintervalstheleftendpoint" id="id148"><tt class="docutils literal">\PolPrintIntervalsTheLeftEndPoint</tt></a></li>
+<li><a class="reference internal" href="#polprintintervalstherightendpoint" id="id149"><tt class="docutils literal">\PolPrintIntervalsTheRightEndPoint</tt></a></li>
+<li><a class="reference internal" href="#polprintintervalsthemultiplicity" id="id150"><tt class="docutils literal">\PolPrintIntervalsTheMultiplicity</tt></a></li>
</ul>
</li>
-<li><a class="reference internal" href="#technicalities" id="id136">Technicalities</a></li>
-<li><a class="reference internal" href="#change-log" id="id137">CHANGE LOG</a></li>
-<li><a class="reference internal" href="#acknowledgments" id="id138">Acknowledgments</a></li>
+<li><a class="reference internal" href="#poldectostring-decimal-number" id="id151"><tt class="docutils literal">\PolDecToString{decimal number}</tt></a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#booleans-with-default-setting-as-indicated" id="id152">Booleans (with default setting as indicated)</a><ul>
+<li><a class="reference internal" href="#xintverbosefalse" id="id153"><tt class="docutils literal">\xintverbosefalse</tt></a></li>
+<li><a class="reference internal" href="#poltypesetallfalse" id="id154"><tt class="docutils literal">\poltypesetallfalse</tt></a></li>
+<li><a class="reference internal" href="#poltoexprallfalse" id="id155"><tt class="docutils literal">\poltoexprallfalse</tt></a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#polexprsetup" id="id156"><tt class="docutils literal">\polexprsetup</tt></a></li>
+<li><a class="reference internal" href="#technicalities" id="id157">Technicalities</a></li>
+<li><a class="reference internal" href="#change-log" id="id158">CHANGE LOG</a></li>
+<li><a class="reference internal" href="#acknowledgments" id="id159">Acknowledgments</a></li>
</ul>
</div>
-<div class="section" id="basic-examples">
-<h1><a class="toc-backref" href="#id36">Basic Examples</a></h1>
+<div class="section" id="basic-syntax">
+<h1><a class="toc-backref" href="#id38">Basic syntax</a></h1>
<p>The syntax is:</p>
<pre class="literal-block">
\poldef polname(x):= expression in variable x;
@@ -613,7 +636,7 @@ PSTricks-compatible; the letter used in output can be
</dl>
</div>
<div class="section" id="examples-of-localization-of-roots">
-<h1><a class="toc-backref" href="#id37">Examples of localization of roots</a></h1>
+<h1><a class="toc-backref" href="#id39">Examples of localization of roots</a></h1>
<ul>
<li><p class="first">To make printed decimal numbers more enjoyable than via
<tt class="docutils literal">\xintSignedFrac</tt>:</p>
@@ -632,17 +655,12 @@ that one can also do:</p>
</li>
<li><p class="first">For extra info in log file use <tt class="docutils literal">\xintverbosetrue</tt>.</p>
</li>
-<li><p class="first">To make producing this documentation simpler, the results from execution
-of the code snippets are not included. Please try them out yourself...</p>
+<li><p class="first">Only for some of these examples is the output included here.</p>
</li>
</ul>
<div class="section" id="a-typical-example">
-<h2><a class="toc-backref" href="#id38">A typical example</a></h2>
-<p>In this example the polynomial is square-free; we can make sure of that by
-comparing the degree of the first element of the Sturm chain with the
-degree of the original polynomial. In such case the second element of
-the Sturm chain is still the polynomial first derivative, because there
-was no further reduction.</p>
+<h2><a class="toc-backref" href="#id40">A typical example</a></h2>
+<p>In this example the polynomial is square-free.</p>
<pre class="literal-block">
\poldef f(x) := x^7 - x^6 - 2x + 1;
@@ -658,11 +676,11 @@ And here is the first root with twenty digits after decimal mark:
\PolEnsureIntervalLength{f}{1}{-20}
\[\PolSturmIsolatedZeroLeft{f}{1}&lt;Z_1&lt;\PolSturmIsolatedZeroRight{f}{1}\]
The first element of the Sturm chain has degree $\PolDegree{f_0}$. As
-this same as $\PolDegree{f}$ we know that the latter was square free.
-So the derivative is up to a constant \PolTypeset{f_1} (in fact here
+this is the original degreee $\PolDegree{f}$ we know that $f$ is square free.
+Its derivative is up to a constant \PolTypeset{f_1} (in this example
it is identical with it).
\PolToSturm{f_1}{f_1}\PolSturmIsolateZeros{f_1}%
-It has \PolSturmNbOfIsolatedZeros{f_1} distinct real
+The derivative has \PolSturmNbOfIsolatedZeros{f_1} distinct real
roots:
\PolPrintIntervals[W]{f_1}
\PolEnsureIntervalLengths{f_1}{-10}%
@@ -683,7 +701,12 @@ to give the exact value for $X_2$!
</pre>
</div>
<div class="section" id="a-degree-four-polynomial-with-nearby-roots">
-<h2><a class="toc-backref" href="#id39">A degree four polynomial with nearby roots</a></h2>
+<h2><a class="toc-backref" href="#id41">A degree four polynomial with nearby roots</a></h2>
+<p>Notice that this example is a bit outdated as <tt class="docutils literal">0.7</tt> release has
+added <tt class="docutils literal"><span class="pre">\PolSturmIsolateZeros**{sturmname}</span></tt> which would find exactly
+the roots. The steps here retain their interest when one is interested
+in finding isolating intervals for example to prepare some demonstration
+of dichotomy method.</p>
<pre class="literal-block">
\PolDef{Q}{(x-1.050001)(x-1.105001)(x-1.110501)(x-1.111051)}
\PolTypeset{Q}
@@ -706,7 +729,7 @@ to give the exact value for $X_2$!
</pre>
</div>
<div class="section" id="the-degree-nine-polynomial-with-0-99-0-999-0-9999-as-triple-roots">
-<h2><a class="toc-backref" href="#id40">The degree nine polynomial with 0.99, 0.999, 0.9999 as triple roots</a></h2>
+<h2><a class="toc-backref" href="#id42">The degree nine polynomial with 0.99, 0.999, 0.9999 as triple roots</a></h2>
<pre class="literal-block">
% define a user command (xinttools is loaded automatically by polexpr)
\newcommand\showmultiplicities[1]{% #1 = &quot;sturmname&quot;
@@ -738,10 +761,10 @@ The multiplicity is 3 at the root x = 0.99
The multiplicity is 3 at the root x = 0.999
The multiplicity is 3 at the root x = 0.9999
</pre>
-<p>On first pass, these rational roots were found. But multiplicity
-computation works also with (decimal) roots not yet identified or with
-non-decimal or irrational roots.</p>
-<p>Try it out!</p>
+<p>On first pass, these rational roots were found (due to their relative
+magnitudes, using <tt class="docutils literal">\PolSturmIsolateZeros**</tt> was not needed here). But
+multiplicity computation works also with (decimal) roots not yet
+identified or with non-decimal or irrational roots.</p>
<p>It is fun to modify only a tiny bit the polynomial and see if polexpr
survives:</p>
<pre class="literal-block">
@@ -776,10 +799,49 @@ The multiplicity is 1 for the root such that 0.9899888032 &lt; x &lt; 0.98998880
The multiplicity is 1 for the root such that 0.9991447980 &lt; x &lt; 0.9991447981
The multiplicity is 1 for the root such that 0.9997663986 &lt; x &lt; 0.9997663987
</pre>
-<p>Try obtaining this with your pocket calculator! (or IEEE-7554 numerics...)</p>
+</div>
+<div class="section" id="a-degree-five-polynomial-with-three-rational-roots">
+<h2><a class="toc-backref" href="#id43">A degree five polynomial with three rational roots</a></h2>
+<pre class="literal-block">
+\poldef Q(x) := 1581755751184441 x^5
+ -14907697165025339 x^4
+ +48415668972339336 x^3
+ -63952057791306264 x^2
+ +46833913221154895 x
+ -49044360626280925;
+
+\PolToSturm{Q}{Q}
+%\begin{flushleft}
+ \renewcommand\PolTypesetCmdPrefix[1]{\allowbreak\xintiiifSgn{#1}{}{+}{+}}%
+ $Q_0(x) = \PolTypeset{Q_0}$
+%\end{flushleft}
+\PolSturmIsolateZeros**{Q}
+\PolPrintIntervals{Q}
+
+$Q_norr(x) = \PolTypeset{Q_norr}$
+</pre>
+<p>Here, all real roots are rational:</p>
+<pre class="literal-block">
+Z_1 = 833719/265381
+Z_2 = 165707065/52746197
+Z_3 = 355/113
+
+Q_norr(x) = x^2 + 1
+</pre>
+<p>And let's get their decimal expansion too:</p>
+<pre class="literal-block">
+% print decimal expansion of the found roots
+\renewcommand\PolPrintIntervalsPrintExactZero
+ {\xintTrunc{20}{\PolPrintIntervalsTheLeftEndPoint}\dots}
+\PolPrintIntervals{Q}
+
+Z_1 = 3.14159265358107777120...
+Z_2 = 3.14159265358979340254...
+Z_3 = 3.14159292035398230088...
+</pre>
</div>
<div class="section" id="a-mignotte-type-polynomial">
-<h2><a class="toc-backref" href="#id41">A Mignotte type polynomial</a></h2>
+<h2><a class="toc-backref" href="#id44">A Mignotte type polynomial</a></h2>
<pre class="literal-block">
\PolDef{P}{x^10 - (10x-1)^2}%
\PolTypeset{P} % prints it in expanded form
@@ -805,8 +867,89 @@ Finally, we display 20 digits of the second root:
0.09999900004999650028 &lt; Z_2 &lt; 0.09999900004999650029
</pre>
</div>
+<div class="section" id="the-wilkinson-polynomial">
+<h2><a class="toc-backref" href="#id45">The Wilkinson polynomial</a></h2>
+<p>See <a class="reference external" href="https://en.wikipedia.org/wiki/Wilkinson%27s_polynomial">Wilkinson polynomial</a>.</p>
+<pre class="literal-block">
+\documentclass{article}
+\usepackage{polexpr}
+\begin{document}
+%\xintverbosetrue % for the curious...
+
+\poldef f(x) := mul((x - i), i = 1..20);
+
+\renewcommand\PolTypesetCmdPrefix[1]{\allowbreak\xintiiifSgn{#1}{}{+}{+}}%
+\renewcommand\PolTypesetOne[1]{\xintDecToString{#1}}%
+
+\noindent\PolTypeset{f}
+
+\PolToSturm{f}{f}
+\PolSturmIsolateZeros{f}
+\PolPrintIntervals{f}
+
+\clearpage
+
+\poldef g(x) := f(x) - 2**{-23} x**19;
+
+% be patient!
+\PolToSturm{g}{g}
+\noindent\PolTypeset{g_0}% integer coefficient primitive polynomial
+
+\PolSturmIsolateZeros{g}
+\PolEnsureIntervalLengths{g}{-10}
+
+\renewcommand\PolPrintIntervalsPrintMultiplicity{}
+\PolPrintIntervals*{g}
+
+\end{document}
+</pre>
+<p>The first polynomial:</p>
+<pre class="literal-block">
+f(x) = x**20
+- 210 x**19
++ 20615 x**18
+- 1256850 x**17
++ 53327946 x**16
+- 1672280820 x**15
++ 40171771630 x**14
+- 756111184500 x**13
++ 11310276995381 x**12
+- 135585182899530 x**11
++ 1307535010540395 x**10
+- 10142299865511450 x**9
++ 63030812099294896 x**8
+- 311333643161390640 x**7
++ 1206647803780373360 x**6
+- 3599979517947607200 x**5
++ 8037811822645051776 x**4
+- 12870931245150988800 x**3
++ 13803759753640704000 x**2
+- 8752948036761600000 x
++ 2432902008176640000
+</pre>
+<p>is handled fast enough (a few seconds), but the modified one <tt class="docutils literal">f(x) -
+<span class="pre">2**-23</span> <span class="pre">x**19</span></tt> takes about 20x longer (the Sturm chain polynomials
+have integer coefficients with up to 321 digits, whereas (surprisingly
+perhaps) those of the Sturm chain polynomials derived from <tt class="docutils literal">f</tt> never
+have more than 21 digits ...).</p>
+<p>Once the Sturm chain is computed and the zeros isolated, obtaining their
+decimal digits is relatively faster. Here is for the ten real roots of
+<tt class="docutils literal">f(x) - <span class="pre">2**-23</span> <span class="pre">x**19</span></tt> as computed by the code above:</p>
+<pre class="literal-block">
+Z_1 = 0.9999999999...
+Z_2 = 2.0000000000...
+Z_3 = 2.9999999999...
+Z_4 = 4.0000000002...
+Z_5 = 4.9999999275...
+Z_6 = 6.0000069439...
+Z_7 = 6.9996972339...
+Z_8 = 8.0072676034...
+Z_9 = 8.9172502485...
+Z_10 = 20.8469081014...
+</pre>
+</div>
<div class="section" id="the-degree-41-polynomial-with-2-1-9-1-8-0-0-1-1-9-2-as-roots">
-<h2><a class="toc-backref" href="#id42">The degree 41 polynomial with -2, -1.9, -1.8, ..., 0, 0.1, ..., 1.9, 2 as roots</a></h2>
+<h2><a class="toc-backref" href="#id46">The degree 41 polynomial with -2, -1.9, -1.8, ..., 0, 0.1, ..., 1.9, 2 as roots</a></h2>
<pre class="literal-block">
\PolDef{P}{mul((x-i*1e-1), i=-20..20)}% i/10 is same but less efficient
</pre>
@@ -845,26 +988,26 @@ x^41
<pre class="literal-block">
\PolDef{P}{mul((x-i*1e-1), i=-20..20)}%
\PolToSturm{P}{S} % dutifully computes S_0, ..., S_{41}
+% the [1] optional argument limits the search to interval (-10,10)
\PolSturmIsolateZeros[1]{S} % finds *exactly* (but a bit slowly) all 41 roots!
\PolPrintIntervals{S} % nice, isn't it?
</pre>
<div class="admonition note">
<p class="first admonition-title">Note</p>
-<p>Release <tt class="docutils literal">0.5</tt> has experimental addition of optional argument
+<p>Release <tt class="docutils literal">0.5</tt> has <em>experimental</em> addition of optional argument
<tt class="docutils literal">E</tt> to <tt class="docutils literal">\PolSturmIsolateZeros</tt>. It instructs to search roots only
-in interval <tt class="docutils literal"><span class="pre">(-10^E,</span> 10^E)</tt>, extremities assumed to not be roots.
-Thus here:</p>
-<pre class="literal-block">
-\PolSturmIsolateZeros[1]{S}
-</pre>
-<p>gives some speed gain; without it, it turns out in this case that
-<tt class="docutils literal">polexpr</tt> would have started with <tt class="docutils literal"><span class="pre">(-10^6,</span> 10^6)</tt> interval.</p>
-<p class="last">This will probably get replaced in future by the specification of
-a general interval.</p>
+in interval <tt class="docutils literal"><span class="pre">(-10^E,</span> 10^E)</tt>. Important: the extremities are
+<em>assumed to not be roots</em>. In this example, the <tt class="docutils literal">[1]</tt> in
+<tt class="docutils literal"><span class="pre">\PolSturmIsolateZeros[1]{S}</span></tt> gives some speed gain; without it, it
+turns out in this case that <tt class="docutils literal">polexpr</tt> would have started with
+<tt class="docutils literal"><span class="pre">(-10^6,</span> 10^6)</tt> interval.</p>
+<p class="last">Please note that this will probably get replaced in future by the
+specification of a general interval. Do not rely on meaning of this
+optional argument keeping the same.</p>
</div>
</div>
<div class="section" id="roots-of-chebyshev-polynomials">
-<h2><a class="toc-backref" href="#id43">Roots of Chebyshev polynomials</a></h2>
+<h2><a class="toc-backref" href="#id47">Roots of Chebyshev polynomials</a></h2>
<pre class="literal-block">
\newcount\mycount
\poldef T_0(x) := 1;
@@ -887,9 +1030,9 @@ a general interval.</p>
</div>
</div>
<div class="section" id="non-expandable-macros">
-<h1><a class="toc-backref" href="#id44">Non-expandable macros</a></h1>
+<h1><a class="toc-backref" href="#id48">Non-expandable macros</a></h1>
<div class="section" id="poldef-polname-letter-expression-in-letter">
-<span id="poldef"></span><h2><a class="toc-backref" href="#id45"><tt class="docutils literal">\poldef <span class="pre">polname(letter):=</span> expression in letter;</tt></a></h2>
+<span id="poldef"></span><h2><a class="toc-backref" href="#id49"><tt class="docutils literal">\poldef <span class="pre">polname(letter):=</span> expression in letter;</tt></a></h2>
<blockquote>
<p>This evaluates the <em>polynomial expression</em> and stores the coefficients
in a private structure accessible later via other package macros,
@@ -926,7 +1069,7 @@ manually, if needed.</p>
</blockquote>
</div>
<div class="section" id="poldef-letter-polname-expression-in-letter">
-<span id="id2"></span><h2><a class="toc-backref" href="#id46"><tt class="docutils literal"><span class="pre">\PolDef[letter]{polname}{expression</span> in letter}</tt></a></h2>
+<span id="id2"></span><h2><a class="toc-backref" href="#id50"><tt class="docutils literal"><span class="pre">\PolDef[letter]{polname}{expression</span> in letter}</tt></a></h2>
<blockquote>
Does the same as <a class="reference external" href="poldef;">\poldef</a> in an undelimited macro
format (thus avoiding potential problems with the catcode of the
@@ -934,7 +1077,7 @@ semi-colon in presence of some packages.) In absence of the
<tt class="docutils literal">[letter]</tt> optional argument, the variable is assumed to be <tt class="docutils literal">x</tt>.</blockquote>
</div>
<div class="section" id="polgenfloatvariant-polname">
-<span id="polgenfloatvariant"></span><h2><a class="toc-backref" href="#id47"><tt class="docutils literal">\PolGenFloatVariant{polname}</tt></a></h2>
+<span id="polgenfloatvariant"></span><h2><a class="toc-backref" href="#id51"><tt class="docutils literal">\PolGenFloatVariant{polname}</tt></a></h2>
<blockquote>
<p>Makes the polynomial also usable in the <tt class="docutils literal">\xintfloatexpr</tt> parser.
It will therein evaluates via an Horner scheme with coefficients
@@ -953,7 +1096,7 @@ context.</p>
</blockquote>
</div>
<div class="section" id="pollet-polname-2-polname-1">
-<span id="pollet"></span><h2><a class="toc-backref" href="#id48"><tt class="docutils literal"><span class="pre">\PolLet{polname_2}={polname_1}</span></tt></a></h2>
+<span id="pollet"></span><h2><a class="toc-backref" href="#id52"><tt class="docutils literal"><span class="pre">\PolLet{polname_2}={polname_1}</span></tt></a></h2>
<blockquote>
Makes a copy of the already defined polynomial <tt class="docutils literal">polname_1</tt> to a
new one <tt class="docutils literal">polname_2</tt>. Same effect as
@@ -961,12 +1104,12 @@ new one <tt class="docutils literal">polname_2</tt>. Same effect as
<tt class="docutils literal">=</tt> is optional.</blockquote>
</div>
<div class="section" id="polgloballet-polname-2-polname-1">
-<span id="polgloballet"></span><h2><a class="toc-backref" href="#id49"><tt class="docutils literal"><span class="pre">\PolGlobalLet{polname_2}={polname_1}</span></tt></a></h2>
+<span id="polgloballet"></span><h2><a class="toc-backref" href="#id53"><tt class="docutils literal"><span class="pre">\PolGlobalLet{polname_2}={polname_1}</span></tt></a></h2>
<blockquote>
Acts globally.</blockquote>
</div>
<div class="section" id="polassign-polname-toarray-macro">
-<span id="polassign"></span><h2><a class="toc-backref" href="#id50"><tt class="docutils literal"><span class="pre">\PolAssign{polname}\toarray\macro</span></tt></a></h2>
+<span id="polassign"></span><h2><a class="toc-backref" href="#id54"><tt class="docutils literal"><span class="pre">\PolAssign{polname}\toarray\macro</span></tt></a></h2>
<blockquote>
<p>Defines a one-argument expandable macro <tt class="docutils literal"><span class="pre">\macro{#1}</span></tt> which expands
to the (raw) #1th polynomial coefficient.</p>
@@ -989,7 +1132,7 @@ indices act the same in both.)</p>
</blockquote>
</div>
<div class="section" id="polget-polname-fromarray-macro">
-<span id="polget"></span><h2><a class="toc-backref" href="#id51"><tt class="docutils literal"><span class="pre">\PolGet{polname}\fromarray\macro</span></tt></a></h2>
+<span id="polget"></span><h2><a class="toc-backref" href="#id55"><tt class="docutils literal"><span class="pre">\PolGet{polname}\fromarray\macro</span></tt></a></h2>
<blockquote>
<p>Does the converse operation to
<tt class="docutils literal"><span class="pre">\PolAssign{polname}\toarray\macro</span></tt>. Each individual
@@ -1010,19 +1153,19 @@ via <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</
</blockquote>
</div>
<div class="section" id="polfromcsv-polname-csv">
-<span id="polfromcsv"></span><h2><a class="toc-backref" href="#id52"><tt class="docutils literal"><span class="pre">\PolFromCSV{polname}{&lt;csv&gt;}</span></tt></a></h2>
-<blockquote>
-<p>Defines a polynomial directly from the comma separated list of
-values (or a macro expanding to such a list) of its coefficients,
-the constant term being the first item. No validity checks. Spaces
-from the list argument are trimmed. List items are each expanded in
-an <tt class="docutils literal">\edef</tt> and then put into normalized form via <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a>'s
-macro <tt class="docutils literal">\xintRaw</tt>.</p>
-<p>Leading zero coefficients are removed:</p>
+<span id="polfromcsv"></span><h2><a class="toc-backref" href="#id56"><tt class="docutils literal"><span class="pre">\PolFromCSV{polname}{&lt;csv&gt;}</span></tt></a></h2>
+<blockquote>
+<p>Defines a polynomial directly from the comma separated list of values
+(or a macro expanding to such a list) of its coefficients, the <em>first
+item</em> gives the constant term, the <em>last item</em> gives the leading
+coefficient, except if zero, then it is dropped (iteratively). List
+items are each expanded in an <tt class="docutils literal">\edef</tt> and then put into normalized
+form via <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a>'s macro <tt class="docutils literal">\xintRaw</tt>.</p>
+<p>As leading zero coefficients are removed:</p>
<pre class="literal-block">
\PolFromCSV{f}{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
</pre>
-<p>defines the zero polynomial, which has only one (zero) coefficient.</p>
+<p>defines the zero polynomial, which holds only one coefficient.</p>
<p>See also expandable macro <a class="reference internal" href="#poltocsv-polname">\PolToCSV</a>.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
@@ -1032,7 +1175,7 @@ macro <tt class="docutils literal">\xintRaw</tt>.</p>
</blockquote>
</div>
<div class="section" id="poltypeset-polname">
-<span id="poltypeset"></span><h2><a class="toc-backref" href="#id53"><tt class="docutils literal">\PolTypeset{polname}</tt></a></h2>
+<span id="poltypeset"></span><h2><a class="toc-backref" href="#id57"><tt class="docutils literal">\PolTypeset{polname}</tt></a></h2>
<blockquote>
<p>Typesets in descending powers in math mode. It uses letter <tt class="docutils literal">x</tt> but
this can be changed via an optional argument:</p>
@@ -1046,7 +1189,7 @@ 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="#id54"><tt class="docutils literal">\PolTypesetCmd{raw_coeff}</tt></a></h3>
+<span id="poltypesetcmd"></span><h3><a class="toc-backref" href="#id58"><tt class="docutils literal">\PolTypesetCmd{raw_coeff}</tt></a></h3>
<blockquote>
<p>Checks if the coefficient is <tt class="docutils literal">1</tt> or <tt class="docutils literal"><span class="pre">-1</span></tt> and then skips printing
the <tt class="docutils literal">1</tt>, except for the constant term. Also it sets conditional
@@ -1056,7 +1199,7 @@ minus one is handled by <a class="reference internal" href="#poltypesetone-raw-c
</blockquote>
</div>
<div class="section" id="poltypesetone-raw-coeff">
-<span id="poltypesetone"></span><h3><a class="toc-backref" href="#id55"><tt class="docutils literal">\PolTypesetOne{raw_coeff}</tt></a></h3>
+<span id="poltypesetone"></span><h3><a class="toc-backref" href="#id59"><tt class="docutils literal">\PolTypesetOne{raw_coeff}</tt></a></h3>
<blockquote>
<p>The default is <tt class="docutils literal">\xintSignedFrac</tt> but this macro is annoying as it
insists to use a power of ten, and not decimal notation.</p>
@@ -1081,7 +1224,7 @@ which uses decimal notation (at least for the numerator part).</p>
</blockquote>
</div>
<div class="section" id="id6">
-<span id="poltypesetmonomialcmd"></span><h3><a class="toc-backref" href="#id56"><tt class="docutils literal">\PolTypesetMonomialCmd</tt></a></h3>
+<span id="poltypesetmonomialcmd"></span><h3><a class="toc-backref" href="#id60"><tt class="docutils literal">\PolTypesetMonomialCmd</tt></a></h3>
<blockquote>
This decides how a monomial (in variable <tt class="docutils literal">\PolVar</tt> and with
exponent <tt class="docutils literal">\PolIndex</tt>) is to be printed. The default does nothing
@@ -1091,7 +1234,7 @@ for the constant term, <tt class="docutils literal">\PolVar</tt> for the first d
<tt class="docutils literal">\ifnum</tt> tests.</blockquote>
</div>
<div class="section" id="poltypesetcmdprefix-raw-coeff">
-<span id="poltypesetcmdprefix"></span><h3><a class="toc-backref" href="#id57"><tt class="docutils literal">\PolTypesetCmdPrefix{raw_coeff}</tt></a></h3>
+<span id="poltypesetcmdprefix"></span><h3><a class="toc-backref" href="#id61"><tt class="docutils literal">\PolTypesetCmdPrefix{raw_coeff}</tt></a></h3>
<blockquote>
Expands to a <tt class="docutils literal">+</tt> if the <tt class="docutils literal">raw_coeff</tt> is zero or positive, and to
nothing if <tt class="docutils literal">raw_coeff</tt> is negative, as in latter case the
@@ -1102,13 +1245,13 @@ for the first term.</blockquote>
</div>
</div>
<div class="section" id="id8">
-<span id="id7"></span><h2><a class="toc-backref" href="#id58"><tt class="docutils literal"><span class="pre">\PolTypeset*{polname}</span></tt></a></h2>
+<span id="id7"></span><h2><a class="toc-backref" href="#id62"><tt class="docutils literal"><span class="pre">\PolTypeset*{polname}</span></tt></a></h2>
<blockquote>
Typesets in ascending powers. Use e.g. <tt class="docutils literal">[h]</tt> optional argument
(after the <tt class="docutils literal">*</tt>) to use letter <tt class="docutils literal">h</tt> rather than <tt class="docutils literal">x</tt>.</blockquote>
</div>
<div class="section" id="poldiff-polname-1-polname-2">
-<span id="poldiff"></span><h2><a class="toc-backref" href="#id59"><tt class="docutils literal"><span class="pre">\PolDiff{polname_1}{polname_2}</span></tt></a></h2>
+<span id="poldiff"></span><h2><a class="toc-backref" href="#id63"><tt class="docutils literal"><span class="pre">\PolDiff{polname_1}{polname_2}</span></tt></a></h2>
<blockquote>
<p>This sets <tt class="docutils literal">polname_2</tt> to the first derivative of <tt class="docutils literal">polname_1</tt>. It
is allowed to issue <tt class="docutils literal"><span class="pre">\PolDiff{f}{f}</span></tt>, effectively replacing <tt class="docutils literal">f</tt>
@@ -1118,7 +1261,7 @@ by <tt class="docutils literal">f'</tt>.</p>
</blockquote>
</div>
<div class="section" id="poldiff-n-polname-1-polname-2">
-<span id="poldiff-n"></span><h2><a class="toc-backref" href="#id60"><tt class="docutils literal"><span class="pre">\PolDiff[N]{polname_1}{polname_2}</span></tt></a></h2>
+<span id="poldiff-n"></span><h2><a class="toc-backref" href="#id64"><tt class="docutils literal"><span class="pre">\PolDiff[N]{polname_1}{polname_2}</span></tt></a></h2>
<blockquote>
This sets <tt class="docutils literal">polname_2</tt> to the <tt class="docutils literal">N</tt>-th derivative of <tt class="docutils literal">polname_1</tt>.
Identical arguments is allowed. With <tt class="docutils literal">N=0</tt>, same effect as
@@ -1126,7 +1269,7 @@ Identical arguments is allowed. With <tt class="docutils literal">N=0</tt>, same
using <tt class="docutils literal">\PolAntiDiff</tt>.</blockquote>
</div>
<div class="section" id="polantidiff-polname-1-polname-2">
-<span id="polantidiff"></span><h2><a class="toc-backref" href="#id61"><tt class="docutils literal"><span class="pre">\PolAntiDiff{polname_1}{polname_2}</span></tt></a></h2>
+<span id="polantidiff"></span><h2><a class="toc-backref" href="#id65"><tt class="docutils literal"><span class="pre">\PolAntiDiff{polname_1}{polname_2}</span></tt></a></h2>
<blockquote>
<p>This sets <tt class="docutils literal">polname_2</tt> to the primitive of <tt class="docutils literal">polname_1</tt> vanishing
at zero.</p>
@@ -1135,32 +1278,32 @@ at zero.</p>
</blockquote>
</div>
<div class="section" id="polantidiff-n-polname-1-polname-2">
-<span id="polantidiff-n"></span><h2><a class="toc-backref" href="#id62"><tt class="docutils literal"><span class="pre">\PolAntiDiff[N]{polname_1}{polname_2}</span></tt></a></h2>
+<span id="polantidiff-n"></span><h2><a class="toc-backref" href="#id66"><tt class="docutils literal"><span class="pre">\PolAntiDiff[N]{polname_1}{polname_2}</span></tt></a></h2>
<blockquote>
This sets <tt class="docutils literal">polname_2</tt> to the result of <tt class="docutils literal">N</tt> successive integrations on
<tt class="docutils literal">polname_1</tt>. With negative <tt class="docutils literal">N</tt>, it switches to using <tt class="docutils literal">\PolDiff</tt>.</blockquote>
</div>
<div class="section" id="poldivide-polname-1-polname-2-polname-q-polname-r">
-<span id="poldivide"></span><h2><a class="toc-backref" href="#id63"><tt class="docutils literal"><span class="pre">\PolDivide{polname_1}{polname_2}{polname_Q}{polname_R}</span></tt></a></h2>
+<span id="poldivide"></span><h2><a class="toc-backref" href="#id67"><tt class="docutils literal"><span class="pre">\PolDivide{polname_1}{polname_2}{polname_Q}{polname_R}</span></tt></a></h2>
<blockquote>
This sets <tt class="docutils literal">polname_Q</tt> and <tt class="docutils literal">polname_R</tt> to be the quotient and
remainder in the Euclidean division of <tt class="docutils literal">polname_1</tt> by
<tt class="docutils literal">polname_2</tt>.</blockquote>
</div>
<div class="section" id="polquo-polname-1-polname-2-polname-q">
-<span id="polquo"></span><h2><a class="toc-backref" href="#id64"><tt class="docutils literal"><span class="pre">\PolQuo{polname_1}{polname_2}{polname_Q}</span></tt></a></h2>
+<span id="polquo"></span><h2><a class="toc-backref" href="#id68"><tt class="docutils literal"><span class="pre">\PolQuo{polname_1}{polname_2}{polname_Q}</span></tt></a></h2>
<blockquote>
This sets <tt class="docutils literal">polname_Q</tt> to be the quotient in the Euclidean division
of <tt class="docutils literal">polname_1</tt> by <tt class="docutils literal">polname_2</tt>.</blockquote>
</div>
<div class="section" id="polrem-polname-1-polname-2-polname-r">
-<span id="polrem"></span><h2><a class="toc-backref" href="#id65"><tt class="docutils literal"><span class="pre">\PolRem{polname_1}{polname_2}{polname_R}</span></tt></a></h2>
+<span id="polrem"></span><h2><a class="toc-backref" href="#id69"><tt class="docutils literal"><span class="pre">\PolRem{polname_1}{polname_2}{polname_R}</span></tt></a></h2>
<blockquote>
This sets <tt class="docutils literal">polname_R</tt> to be the remainder in the Euclidean division
of <tt class="docutils literal">polname_1</tt> by <tt class="docutils literal">polname_2</tt>.</blockquote>
</div>
<div class="section" id="polgcd-polname-1-polname-2-polname-gcd">
-<span id="polgcd"></span><h2><a class="toc-backref" href="#id66"><tt class="docutils literal"><span class="pre">\PolGCD{polname_1}{polname_2}{polname_GCD}</span></tt></a></h2>
+<span id="polgcd"></span><h2><a class="toc-backref" href="#id70"><tt class="docutils literal"><span class="pre">\PolGCD{polname_1}{polname_2}{polname_GCD}</span></tt></a></h2>
<blockquote>
This sets <tt class="docutils literal">polname_GCD</tt> to be the (monic) GCD of the two first
polynomials. It is a unitary polynomial except if both <tt class="docutils literal">polname_1</tt>
@@ -1186,7 +1329,7 @@ polynomial.</blockquote>
no common factor among the coefficients. -->
</div>
<div class="section" id="poltosturm-polname-sturmname">
-<span id="poltosturm"></span><h2><a class="toc-backref" href="#id67"><tt class="docutils literal"><span class="pre">\PolToSturm{polname}{sturmname}</span></tt></a></h2>
+<span id="poltosturm"></span><h2><a class="toc-backref" href="#id71"><tt class="docutils literal"><span class="pre">\PolToSturm{polname}{sturmname}</span></tt></a></h2>
<blockquote>
<p>With <tt class="docutils literal">polname</tt> being for example <tt class="docutils literal">P</tt>, the macro starts by
computing polynomials <tt class="docutils literal">P</tt> and <tt class="docutils literal">P'</tt>, then computes the (opposite
@@ -1219,19 +1362,22 @@ not done if this last one is the constant <tt class="docutils literal">1</tt> or
original polynomial was square-free. These polynomials are primitive
polynomials too, i.e. with integer coefficients having no common factor.</p>
<p>Thus <tt class="docutils literal">sturmname_0</tt> has exactly the same real and complex roots as
-polynomial <tt class="docutils literal">polname</tt>, but with each root now of multiplicity one.</p>
+polynomial <tt class="docutils literal">polname</tt>, but with each root now of multiplicity one:
+i.e. it is the &quot;square-free part&quot; of original polynomial <tt class="docutils literal">polname</tt>.</p>
<p>Notice that <tt class="docutils literal">sturmname_1</tt> isn't necessarily the derivative of
<tt class="docutils literal">sturmname_0</tt> due to the various normalizations.</p>
-<p>These polynomials <tt class="docutils literal">sturmname_k</tt> (contrarily to the
-<tt class="docutils literal">sturmname_k_</tt> ones) are usable after the macro execution but
-their main utility is for the execution of
-<a class="reference internal" href="#polsturmisolatezeros-sturmname">\PolSturmIsolateZeros{sturmname}</a>.</p>
+<p>The polynomials <tt class="docutils literal">sturmname_k</tt> main utility is for the execution of
+<a class="reference internal" href="#polsturmisolatezeros-sturmname">\PolSturmIsolateZeros{sturmname}</a>. Be careful not to use these
+names <tt class="docutils literal">sturmname_0</tt>, <tt class="docutils literal">sturmname_1</tt>, etc... for defining other
+polynomials after having done <tt class="docutils literal"><span class="pre">\PolToSturm{polname}{sturmname}</span> and
+before executing <span class="pre">``\PolSturmIsolateZeros{sturmname}</span></tt> else the
+latter will behave erroneously.</p>
<p><a class="reference internal" href="#polsturmchainlength-sturmname">\PolSturmChainLength{sturmname}</a> gives the index of the last
element of the Sturm chain.</p>
</blockquote>
</div>
<div class="section" id="id10">
-<span id="id9"></span><h2><a class="toc-backref" href="#id68"><tt class="docutils literal"><span class="pre">\PolToSturm*{polname}{sturmname}</span></tt></a></h2>
+<span id="id9"></span><h2><a class="toc-backref" href="#id72"><tt class="docutils literal"><span class="pre">\PolToSturm*{polname}{sturmname}</span></tt></a></h2>
<blockquote>
<p>Does the same as <a class="reference internal" href="#poltosturm">un-starred version</a> and additionally it
keeps for user usage the memory of the <em>un-normalized</em> Sturm chain
@@ -1242,10 +1388,20 @@ polynomials <tt class="docutils literal">sturmname_k_</tt>, <tt class="docutils
<p class="last">This behaviour was modified at <tt class="docutils literal">0.6</tt>, anyhow the macro was
broken at <tt class="docutils literal">0.5</tt>.</p>
</div>
+<div class="admonition hint">
+<p class="first admonition-title">Hint</p>
+<p class="last">The square-free part of <tt class="docutils literal">polname</tt> is <tt class="docutils literal">sturmname_0</tt>, and their
+quotient is the polynomial with name
+<tt class="docutils literal">sturname_\PolSturmChainLength{sturmname}_</tt>. It thus easy to
+set-up a loop iteratively computing the latter until the last one
+is a constant, thus obtaining the decomposition of an <tt class="docutils literal">f</tt> as
+a product <tt class="docutils literal">c f_1 f_2 f_3 ...</tt> of a constant and square-free (primitive)
+polynomials, where each <tt class="docutils literal">f_i</tt> divides its predecessor.</p>
+</div>
</blockquote>
</div>
<div class="section" id="polsettosturmchainsignchangesat-macro-sturmname-fraction">
-<span id="polsettosturmchainsignchangesat"></span><h2><a class="toc-backref" href="#id69"><tt class="docutils literal"><span class="pre">\PolSetToSturmChainSignChangesAt{\macro}{sturmname}{fraction}</span></tt></a></h2>
+<span id="polsettosturmchainsignchangesat"></span><h2><a class="toc-backref" href="#id73"><tt class="docutils literal"><span class="pre">\PolSetToSturmChainSignChangesAt{\macro}{sturmname}{fraction}</span></tt></a></h2>
<blockquote>
<p>Sets macro <tt class="docutils literal">\macro</tt> to the number of sign changes in the Sturm
chain with name prefix <tt class="docutils literal">sturmname</tt>, at location <tt class="docutils literal">fraction</tt>
@@ -1262,7 +1418,7 @@ use <tt class="docutils literal">[\empty]</tt> as extra optional argument.</p>
</blockquote>
</div>
<div class="section" id="polsettonbofzeroswithin-macro-sturmname-value-a-value-b">
-<span id="polsettonbofzeroswithin"></span><h2><a class="toc-backref" href="#id70"><tt class="docutils literal"><span class="pre">\PolSetToNbOfZerosWithin{\macro}{sturmname}{value_a}{value_b}</span></tt></a></h2>
+<span id="polsettonbofzeroswithin"></span><h2><a class="toc-backref" href="#id74"><tt class="docutils literal"><span class="pre">\PolSetToNbOfZerosWithin{\macro}{sturmname}{value_a}{value_b}</span></tt></a></h2>
<blockquote>
<p>Applies the <a class="reference external" href="https://en.wikipedia.org/wiki/Sturm%27s_theorem">Sturm Theorem</a> to set <tt class="docutils literal">\macro</tt> to the exact number
of <strong>distinct</strong> roots of <tt class="docutils literal">sturmname_0</tt> in the interval <tt class="docutils literal">(value_a,
@@ -1291,12 +1447,12 @@ which requires prior execution of
</blockquote>
</div>
<div class="section" id="polsturmisolatezeros-sturmname">
-<span id="polsturmisolatezeros"></span><h2><a class="toc-backref" href="#id71"><tt class="docutils literal">\PolSturmIsolateZeros{sturmname}</tt></a></h2>
+<span id="polsturmisolatezeros"></span><h2><a class="toc-backref" href="#id75"><tt class="docutils literal">\PolSturmIsolateZeros{sturmname}</tt></a></h2>
<blockquote>
-<p>First, it evaluates using <a class="reference external" href="https://en.wikipedia.org/wiki/Sturm%27s_theorem">Sturm theorem</a> the number of distinct
-real roots of <tt class="docutils literal">sturmname_0</tt>.</p>
-<div class="admonition note">
-<p class="first admonition-title">Note</p>
+<p>The macros locates, using <a class="reference external" href="https://en.wikipedia.org/wiki/Sturm%27s_theorem">Sturm theorem</a>, as many disjoint
+intervals as there are (real) roots.</p>
+<div class="admonition important">
+<p class="first admonition-title">Important</p>
<p>The Sturm chain must have been produced by an earlier
<a class="reference internal" href="#poltosturm-polname-sturmname">\PolToSturm{polname}{sturmname}</a>.</p>
<p>Why does this macro ask for argument the name of Sturm chain,
@@ -1311,47 +1467,63 @@ polynomials <tt class="docutils literal">f_0</tt>, <tt class="docutils literal">
to <tt class="docutils literal">\PolToSturm</tt> must have been made at any rate for
<tt class="docutils literal">\PolSturmIsolateZeros</tt> to be usable.</p>
</div>
-<p>Then it locates, again using <a class="reference external" href="https://en.wikipedia.org/wiki/Sturm%27s_theorem">Sturm theorem</a>, as many disjoint
-intervals as there are roots. Some intervals reduce to singleton
-which are roots. Non-singleton intervals get refined to make sure
-none of their two limit points is a root: they contain each a single
-root, in their respective interiors.</p>
-<!-- This procedure is covariant
-with the independent variable ``x`` becoming ``-x``.
-Hmm, pas sûr et trop fatigué -->
+<p>After its execution they are two types of such intervals (stored in
+memory and accessible via macros or <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> variables, see below):</p>
+<ul class="simple">
+<li>singleton <tt class="docutils literal">{a}</tt>: then <tt class="docutils literal">a</tt> is a root, (necessarily a decimal
+number, but not all such decimal numbers are exactly identified yet).</li>
+<li>open intervals <tt class="docutils literal">(a,b)</tt>: then there is exactly one root <tt class="docutils literal">z</tt>
+such that <tt class="docutils literal">a &lt; z &lt; b</tt>, and the end points are guaranteed to not
+be roots.</li>
+</ul>
<p>The interval boundaries are decimal numbers, originating
in iterated decimal subdivision from initial intervals
-<tt class="docutils literal"><span class="pre">(-10^E,</span> 0)</tt> and <tt class="docutils literal">(0, 10^E)</tt>; if zero is a root it is always
-identified individually. The non-singleton intervals are of the
+<tt class="docutils literal"><span class="pre">(-10^E,</span> 0)</tt> and <tt class="docutils literal">(0, 10^E)</tt> with <tt class="docutils literal">E</tt> chosen initially large
+enough so that all roots are enclosed; if zero is a root it is always
+identified as such. The non-singleton intervals are of the
type <tt class="docutils literal">(a/10^f, <span class="pre">(a+1)/10^f)</span></tt> with <tt class="docutils literal">a</tt> an integer, which is
-neither <tt class="docutils literal">0</tt> nor <tt class="docutils literal"><span class="pre">-1</span></tt>. Hence <tt class="docutils literal">a</tt> and <tt class="docutils literal">a+1</tt> are both positive
-or both negative.</p>
+neither <tt class="docutils literal">0</tt> nor <tt class="docutils literal"><span class="pre">-1</span></tt>. Hence either <tt class="docutils literal">a</tt> and <tt class="docutils literal">a+1</tt> are both positive
+or they are both negative.</p>
+<p>One does not <em>a priori</em> know what will be the lengths of these
+intervals (except that they are always powers of ten), they
+vary depending on how many digits two successive roots have in
+common in their respective decimal expansions.</p>
+<div class="admonition important">
+<p class="first admonition-title">Important</p>
+<p>If some two consecutive intervals share an end-point, no
+information is yet gained about the separation between the two
+roots which could at this stage be arbitrarily small.</p>
+<p class="last">See <a class="reference internal" href="#polrefineinterval-sturmname-index">\PolRefineInterval*{sturmname}{index}</a> which addresses
+this issue.</p>
+</div>
+<!-- This procedure is covariant
+with the independent variable ``x`` becoming ``-x``.
+Hmm, pas sûr et trop fatigué -->
<p>The interval boundaries (and exactly found roots) are made available
for future computations in <tt class="docutils literal">\xintexpr</tt>-essions or polynomial
definitions as variables <tt class="docutils literal">&lt;sturmname&gt;L_1</tt>,
<tt class="docutils literal">&lt;sturmname&gt;L_2</tt>, etc..., for the left end-points and
<tt class="docutils literal">&lt;sturmname&gt;R_1</tt>, <tt class="docutils literal">&lt;sturmname&gt;R_2</tt>, ..., for the right
end-points.</p>
-<p>Also two macro arrays (in the sense of
-<a class="reference external" href="http://www.ctan.org/pkg/xint">xinttools</a>'s <tt class="docutils literal">\xintAssignArray</tt>) are created for holding the
-interval end-points written out in standard decimal notation
-(see <a class="reference internal" href="#poldectostring-decimal-number">\PolDecToString{decimal number}</a>).
-To access these values, macros
-<a class="reference internal" href="#polsturmisolatedzeroleft-sturmname-index">\PolSturmIsolatedZeroLeft{sturmname}{index}</a> and
-<a class="reference internal" href="#polsturmisolatedzeroright-sturmname-index">\PolSturmIsolatedZeroRight{sturmname}{index}</a> are provided.</p>
+<p>Thus for example, if <tt class="docutils literal">sturmname</tt> is <tt class="docutils literal">f</tt>, one can use the
+<a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> variables <tt class="docutils literal">fL_1</tt>, <tt class="docutils literal">fL_2</tt>, ... to refer in expressions
+to the left end-points (or to the exact root, if left and right end
+points coincide). Additionally, <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> variable <tt class="docutils literal">fZ_1_isknown</tt>
+will have value <tt class="docutils literal">1</tt> if the root in the first interval is known,
+and <tt class="docutils literal">0</tt> otherwise. And similarly for the other intervals.</p>
+<p>Also, macros <a class="reference internal" href="#polsturmisolatedzeroleft-sturmname-index">\PolSturmIsolatedZeroLeft{sturmname}{index}</a> and
+<a class="reference internal" href="#polsturmisolatedzeroright-sturmname-index">\PolSturmIsolatedZeroRight{sturmname}{index}</a> are provided which
+expand to these same values, written in decimal notation (i.e.
+pre-processed by <a class="reference internal" href="#poldectostring">\PolDecToString</a>.) And there
+is also <a class="reference internal" href="#polsturmifzeroexactlyknown-sturmname-index-a-b">\PolSturmIfZeroExactlyKnown{sturmname}{index}{A}{B}</a>.</p>
<div class="admonition important">
<p class="first admonition-title">Important</p>
-<p class="last">Trailing zeroes in these stored decimal numbers are significant:
-they are also present in the decimal expansion of the exact root.</p>
-</div>
-<div class="admonition note">
-<p class="first admonition-title">Note</p>
-<p class="last">The actual array macros are <tt class="docutils literal">\POL_ZeroInt&lt;sturmname&gt;L</tt> and
-<tt class="docutils literal">\POL_ZeroInt&lt;sturmname&gt;R</tt> but as these names use the
-non-letter character <tt class="docutils literal">_</tt> and possibly also digits from
-<tt class="docutils literal">sturmname</tt>, the accessor macros above have been made part of
-the package.</p>
+<p class="last">Trailing zeroes in the stored decimal numbers accessible via the
+macros are significant: they are also present in the decimal
+expansion of the exact root.</p>
</div>
+<p>These variables and macros are automatically updated when one next
+uses macros such as <a class="reference internal" href="#polrefineinterval-sturmname-index">\PolRefineInterval*{sturmname}{index}</a>.</p>
<p>The start of decimal expansion of a positive <tt class="docutils literal">k</tt>-th root is given
by <a class="reference internal" href="#polsturmisolatedzeroleft">\PolSturmIsolatedZeroLeft{sturmname}{k}</a>, and for a negative root it is given
by <a class="reference internal" href="#polsturmisolatedzeroright">PolSturmIsolatedZeroRight{sturmname}{k}</a>. These two decimal
@@ -1359,24 +1531,19 @@ 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-lessthanorequalto-value">\PolSturmNbOfRootsOf{sturmname}\LessThanOrEqualTo{value}</a> and
<a class="reference internal" href="#polsturmnbofrootsof-sturmname-lessthanorequaltoexpr-expression">\PolSturmNbOfRootsOf{sturmname}\LessThanOrEqualToExpr{expression}</a>.
-will expandably act as their names indicate.</p>
+will expandably compute respectively the number of real roots at
+most equal to <tt class="docutils literal">value</tt> or <tt class="docutils literal">expression</tt>, and the same but with
+multiplicities.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
-<p class="last">In the current implementation the <tt class="docutils literal"><span class="pre">&lt;sturmname&gt;...</span></tt> <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> variables
-and the <tt class="docutils literal"><span class="pre">\POL_ZeroInt...</span></tt> arrays are globally defined. On the
+<p class="last">In the current implementation the <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> variables
+and <a class="reference external" href="http://www.ctan.org/pkg/xint">xinttools</a> arrays are globally defined. On the
other hand the Sturm sequence polynomials obey the current scope.</p>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
-<p class="last">When two successive roots are located in adjacent intervals, the
-separation between them is not lower bounded. See
-<a class="reference internal" href="#polrefineinterval-sturmname-index">\PolRefineInterval*{sturmname}{index}</a>.</p>
-</div>
-<div class="admonition note">
-<p class="first admonition-title">Note</p>
<p>As all computations are done <em>exactly</em> there can be no errors...
apart those due to bad coding by author. The results are exact
bounds for the mathematically exact real roots.</p>
@@ -1390,7 +1557,7 @@ are studied in numerical mathematics.</p>
</blockquote>
</div>
<div class="section" id="id12">
-<span id="id11"></span><h2><a class="toc-backref" href="#id72"><tt class="docutils literal"><span class="pre">\PolSturmIsolateZeros*{sturmname}</span></tt></a></h2>
+<span id="id11"></span><h2><a class="toc-backref" href="#id76"><tt class="docutils literal"><span class="pre">\PolSturmIsolateZeros*{sturmname}</span></tt></a></h2>
<blockquote>
<p>The macro does the same as <a class="reference internal" href="#polsturmisolatezeros-sturmname">\PolSturmIsolateZeros{sturmname}</a> and
then in addition it does the extra work to determine all
@@ -1400,9 +1567,9 @@ after executing this macro,
to the multiplicity of the root located in the <tt class="docutils literal">index</tt>-th
interval (intervals are enumerated from left to right, with index
starting at <tt class="docutils literal">1</tt>).</p>
-<p>Also, the
-<a class="reference internal" href="#polsturmnbwithmultofrootsof-sturmname-lessthanorequalto-value">\PolSturmNbWithMultOfRootsOf{sturmname}\LessThanOrEqualTo{value}</a>
-will be operant.</p>
+<p>Furthermore, if for example the <tt class="docutils literal">sturmname</tt> is <tt class="docutils literal">f</tt>, <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a>
+variables <tt class="docutils literal">fM_1</tt>, <tt class="docutils literal">fM_2</tt>... hold the multiplicities thus
+computed.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">It is <strong>not</strong> necessary to have executed the <a class="reference internal" href="#id9">PolToSturm*</a> starred
@@ -1412,19 +1579,76 @@ chain), even though it does not make the declarations as <em>user-level</em>
genuine polynomials.</p>
</div>
<p>See <a class="reference internal" href="#the-degree-nine-polynomial-with-0-99-0-999-0-9999-as-triple-roots">The degree nine polynomial with 0.99, 0.999, 0.9999 as triple
-roots</a> for an example of use.</p>
+roots</a> for an example.</p>
+</blockquote>
+</div>
+<div class="section" id="id14">
+<span id="id13"></span><h2><a class="toc-backref" href="#id77"><tt class="docutils literal"><span class="pre">\PolSturmIsolateZeros**{sturmname}</span></tt></a></h2>
+<blockquote>
+<p>The macro does the same as <a class="reference internal" href="#id12">\PolSturmIsolateZeros*{sturmname}</a> and
+in addition it does the extra work to determine all the <em>rational</em>
+roots.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">After execution of this macro, a root is &quot;known&quot; if and only if
+it is rational.</p>
+</div>
+<p>Furthermore, primitive polynomial <tt class="docutils literal">sturmname_sqf_norr</tt> is created
+to match the (square-free) <tt class="docutils literal">sturmname_0</tt> from which all rational
+roots have been removed (see <a class="reference internal" href="#polexprsetup">\polexprsetup</a> for customizing this
+name). The number of distinct rational roots is thus the difference
+between the degrees of these two polynomials (see also
+<a class="reference internal" href="#polsturmnbofrationalroots-sturmname">\PolSturmNbOfRationalRoots{sturmname}</a>).</p>
+<p>And <tt class="docutils literal">sturmname_norr</tt> is <tt class="docutils literal">sturmname_0_</tt> from which all rational
+roots have been removed (see <a class="reference internal" href="#polexprsetup">\polexprsetup</a>), i.e. it contains
+the irrational roots of the original polynomial, with the same
+multiplicities.</p>
+<p>See <a class="reference internal" href="#a-degree-five-polynomial-with-three-rational-roots">A degree five polynomial with three rational
+roots</a> for an example.</p>
</blockquote>
</div>
<div class="section" id="polsturmisolatezerosandgetmultiplicities-sturmname">
-<span id="polsturmisolatezerosandgetmultiplicities"></span><h2><a class="toc-backref" href="#id73"><tt class="docutils literal">\PolSturmIsolateZerosAndGetMultiplicities{sturmname}</tt></a></h2>
+<span id="polsturmisolatezerosandgetmultiplicities"></span><h2><a class="toc-backref" href="#id78"><tt class="docutils literal">\PolSturmIsolateZerosAndGetMultiplicities{sturmname}</tt></a></h2>
<blockquote>
-<p>This is another name for <a class="reference internal" href="#id12">\PolSturmIsolateZeros*{sturmname}</a>.</p>
-<p>See <a class="reference internal" href="#the-degree-nine-polynomial-with-0-99-0-999-0-9999-as-triple-roots">The degree nine polynomial with 0.99, 0.999, 0.9999 as triple
-roots</a> for an example of use.</p>
+This is another name for <a class="reference internal" href="#id12">\PolSturmIsolateZeros*{sturmname}</a>.</blockquote>
+</div>
+<div class="section" id="polsturmisolatezerosgetmultiplicitiesandrationalroots-sturmname">
+<span id="polsturmisolatezerosgetmultiplicitiesandrationalroots"></span><h2><a class="toc-backref" href="#id79"><tt class="docutils literal">\PolSturmIsolateZerosGetMultiplicitiesAndRationalRoots{sturmname}</tt></a></h2>
+<blockquote>
+This is another name for <a class="reference internal" href="#id14">\PolSturmIsolateZeros**{sturmname}</a>.</blockquote>
+</div>
+<div class="section" id="polsturmisolatezerosandfindrationalroots-sturmname">
+<h2><a class="toc-backref" href="#id80"><tt class="docutils literal">\PolSturmIsolateZerosAndFindRationalRoots{sturmname}</tt></a></h2>
+<blockquote>
+<p>This works exactly like <a class="reference internal" href="#id14">\PolSturmIsolateZeros**{sturmname}</a>
+(inclusive of declaring the polynomials <tt class="docutils literal">sturmname_sqf_norr</tt> and
+<tt class="docutils literal">sturmname_norr</tt> with no rational roots) except that it does <em>not</em>
+compute the multiplicities of the <em>non-rational</em> roots.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">There is no macro to find the rational roots but not compute
+their multiplicities at the same time.</p>
+</div>
+<div class="admonition attention">
+<p class="first admonition-title">Attention!</p>
+<p>This macro does <em>not</em> define <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> variables
+<tt class="docutils literal">sturmnameM_1</tt>, <tt class="docutils literal">sturmnameM_2</tt>, ... holding the
+multiplicities and it leaves the multiplicity array (whose accessor
+is <a class="reference internal" href="#polsturmisolatedzeromultiplicity-sturmname-index">\PolSturmIsolatedZeroMultiplicity{sturmname}{index}</a>) into
+a broken state, as all non-rational roots will supposedly have
+multiplicity one. This means that the output of
+<a class="reference internal" href="#id18">\PolPrintIntervals*</a> for example will be
+erroneous for the intervals with irrational roots.</p>
+<p class="last">I decided to document it because finding multiplicities of the
+non rational roots is somewhat costly, and one may be interested
+only into finding the rational roots (of course random
+polynomials with integer coefficients will not have <em>any</em>
+rational root anyhow).</p>
+</div>
</blockquote>
</div>
<div class="section" id="polrefineinterval-sturmname-index">
-<span id="polrefineinterval"></span><h2><a class="toc-backref" href="#id74"><tt class="docutils literal"><span class="pre">\PolRefineInterval*{sturmname}{index}</span></tt></a></h2>
+<span id="polrefineinterval"></span><h2><a class="toc-backref" href="#id81"><tt class="docutils literal"><span class="pre">\PolRefineInterval*{sturmname}{index}</span></tt></a></h2>
<blockquote>
The <tt class="docutils literal">index</tt>-th interval (starting indexing at one) is further
subdivided as many times as is necessary in order for the newer
@@ -1433,21 +1657,21 @@ the original interval. This means that the <tt class="docutils literal">k</tt>th
strictly separated from the other roots.</blockquote>
</div>
<div class="section" id="polrefineinterval-n-sturmname-index">
-<span id="polrefineinterval-n"></span><h2><a class="toc-backref" href="#id75"><tt class="docutils literal"><span class="pre">\PolRefineInterval[N]{sturmname}{index}</span></tt></a></h2>
+<span id="polrefineinterval-n"></span><h2><a class="toc-backref" href="#id82"><tt class="docutils literal"><span class="pre">\PolRefineInterval[N]{sturmname}{index}</span></tt></a></h2>
<blockquote>
The <tt class="docutils literal">index</tt>-th interval (starting count at one) is further
subdivided once, reducing its length by a factor of 10. This is done
<tt class="docutils literal">N</tt> times if the optional argument <tt class="docutils literal">[N]</tt> is present.</blockquote>
</div>
<div class="section" id="polensureintervallength-sturmname-index-e">
-<span id="polensureintervallength"></span><h2><a class="toc-backref" href="#id76"><tt class="docutils literal"><span class="pre">\PolEnsureIntervalLength{sturmname}{index}{E}</span></tt></a></h2>
+<span id="polensureintervallength"></span><h2><a class="toc-backref" href="#id83"><tt class="docutils literal"><span class="pre">\PolEnsureIntervalLength{sturmname}{index}{E}</span></tt></a></h2>
<blockquote>
The <tt class="docutils literal">index</tt>-th interval is subdivided until its length becomes at
most <tt class="docutils literal">10^E</tt>. This means (for <tt class="docutils literal">E&lt;0</tt>) that the first <tt class="docutils literal"><span class="pre">-E</span></tt> digits
after decimal mark of the <tt class="docutils literal">k</tt>th root will then be known exactly.</blockquote>
</div>
<div class="section" id="polensureintervallengths-sturmname-e">
-<span id="polensureintervallengths"></span><h2><a class="toc-backref" href="#id77"><tt class="docutils literal"><span class="pre">\PolEnsureIntervalLengths{sturmname}{E}</span></tt></a></h2>
+<span id="polensureintervallengths"></span><h2><a class="toc-backref" href="#id84"><tt class="docutils literal"><span class="pre">\PolEnsureIntervalLengths{sturmname}{E}</span></tt></a></h2>
<blockquote>
<p>The intervals as obtained from <tt class="docutils literal">\PolSturmIsolateZeros</tt> are (if
necessary) subdivided further by (base 10) dichotomy in order for
@@ -1458,63 +1682,136 @@ than <tt class="docutils literal">10^E</tt> in output only if it did not change
</blockquote>
</div>
<div class="section" id="polprintintervals-varname-sturmname">
-<span id="polprintintervals"></span><h2><a class="toc-backref" href="#id78"><tt class="docutils literal"><span class="pre">\PolPrintIntervals[varname]{sturmname}</span></tt></a></h2>
+<span id="polprintintervals"></span><h2><a class="toc-backref" href="#id85"><tt class="docutils literal"><span class="pre">\PolPrintIntervals[varname]{sturmname}</span></tt></a></h2>
<blockquote>
<p>This is a convenience macro which prints the bounds for the roots
<tt class="docutils literal">Z_1</tt>, <tt class="docutils literal">Z_2</tt>, ... (the optional argument <tt class="docutils literal">varname</tt> allows to
-specify a replacement for the default <tt class="docutils literal">Z</tt>). This will be done in a
+specify a replacement for the default <tt class="docutils literal">Z</tt>). This will be done (by
+default) in a
math mode <tt class="docutils literal">array</tt>, one interval per row, and pattern <tt class="docutils literal">rcccl</tt>,
where the second and fourth column hold the <tt class="docutils literal">&lt;</tt> sign, except when
the interval reduces to a singleton, which means the root is known
-exactly. The user is invited to renewcommand the macro if some other
-type of tabular environment for example is wanted.</p>
-<p>In each array cell the corresponding interval end-point (which may
-be an exactly known root) is available as macro
-<a class="reference internal" href="#polprintintervalstheendpoint">\PolPrintIntervalsTheEndPoint</a> (in decimal notation). And the
-corresponding interval index is available as
-<a class="reference internal" href="#polprintintervalstheindex">\PolPrintIntervalsTheIndex</a>.</p>
-<p>These values may be tested to decide some on-the-fly customization
-(color for example), via the following auxiliaries which can be
-modified by user. Furthermore these auxiliaries can also use the
-following conditionals: <a class="reference internal" href="#polifendpointispositive-a-b">\PolIfEndPointIsPositive{A}{B}</a>,
-<a class="reference internal" href="#polifendpointisnegative-a-b">\PolIfEndPointIsNegative{A}{B}</a>, <a class="reference internal" href="#polifendpointiszero-a-b">\PolIfEndPointIsZero{A}{B}</a>.</p>
+exactly.</p>
+<div class="admonition attention">
+<p class="first admonition-title">Attention!</p>
+<p class="last">This macro was refactored at 0.7, its default output remained
+identical but the ways to customize it got completely
+modified.</p>
+</div>
+<p>See next macros which govern its output.</p>
</blockquote>
-<div class="section" id="id13">
-<span id="polprintintervalsprintexactzero"></span><h3><a class="toc-backref" href="#id79"><tt class="docutils literal">\PolPrintIntervalsPrintExactZero</tt></a></h3>
+<div class="section" id="polprintintervalsnorealroots">
+<h3><a class="toc-backref" href="#id86"><tt class="docutils literal">\PolPrintIntervalsNoRealRoots</tt></a></h3>
<blockquote>
-<p>This is provided to help customize how an exactly known root is
-printed in the right most column of the array. The package
-definition is:</p>
+<p>Executed in place of an <tt class="docutils literal">array</tt> environment, when there are no
+real roots. Default definition:</p>
<pre class="literal-block">
-\newcommand\PolPrintIntervalsPrintExactZero{\PolPrintIntervalsTheEndPoint}%
+\newcommand\PolPrintIntervalsNoRealRoots{}
</pre>
-<p>Recall that this is expanded in an array cell.</p>
-<p>If for example you want to print in red the third root, known
-exactly, the macro could make a test for the value of
-<a class="reference internal" href="#polprintintervalstheindex">\PolPrintIntervalsTheIndex</a> and act accordingly.</p>
</blockquote>
</div>
-<div class="section" id="id14">
-<span id="polprintintervalsprintleftendpoint"></span><h3><a class="toc-backref" href="#id80"><tt class="docutils literal">\PolPrintIntervalsPrintLeftEndPoint</tt></a></h3>
+<div class="section" id="polprintintervalsbeginenv">
+<h3><a class="toc-backref" href="#id87"><tt class="docutils literal">\PolPrintIntervalsBeginEnv</tt></a></h3>
+<blockquote>
+<p>Default definition:</p>
+<pre class="literal-block">
+\newcommand\PolPrintIntervalsBeginEnv{\[\begin{array}{rcccl}}
+</pre>
+</blockquote>
+</div>
+<div class="section" id="polprintintervalsendenv">
+<h3><a class="toc-backref" href="#id88"><tt class="docutils literal">\PolPrintIntervalsEndEnv</tt></a></h3>
+<blockquote>
+<p>Default definition:</p>
+<pre class="literal-block">
+\newcommand\PolPrintIntervalsEndEnv{\end{array}\]}
+</pre>
+</blockquote>
+</div>
+<div class="section" id="polprintintervalsknownroot">
+<h3><a class="toc-backref" href="#id89"><tt class="docutils literal">\PolPrintIntervalsKnownRoot</tt></a></h3>
+<blockquote>
+<p>Default definition:</p>
+<pre class="literal-block">
+\newcommand\PolPrintIntervalsKnownRoot{%
+ &amp;&amp;\PolPrintIntervalsTheVar_{\PolPrintIntervalsTheIndex}%
+ &amp;=&amp;\PolPrintIntervalsPrintExactZero
+}
+</pre>
+</blockquote>
+</div>
+<div class="section" id="polprintintervalsunknownroot">
+<h3><a class="toc-backref" href="#id90"><tt class="docutils literal">\PolPrintIntervalsUnknownRoot</tt></a></h3>
<blockquote>
-<p>Package definition is:</p>
+<p>Default definition:</p>
<pre class="literal-block">
-\newcommand\PolPrintIntervalsPrintLeftEndPoint{\PolPrintIntervalsTheEndPoint}%
+\newcommand\PolPrintIntervalsUnknownRoot{%
+ \PolPrintIntervalsPrintLeftEndPoint&amp;&lt;&amp;%
+ \PolPrintIntervalsTheVar_{\PolPrintIntervalsTheIndex}&amp;&lt;&amp;%
+ \PolPrintIntervalsPrintRightEndPoint
+}
</pre>
</blockquote>
</div>
<div class="section" id="id15">
-<span id="polprintintervalsprintrightendpoint"></span><h3><a class="toc-backref" href="#id81"><tt class="docutils literal">\PolPrintIntervalsPrintRightEndPoint</tt></a></h3>
+<span id="polprintintervalsprintexactzero"></span><h3><a class="toc-backref" href="#id91"><tt class="docutils literal">\PolPrintIntervalsPrintExactZero</tt></a></h3>
<blockquote>
-<p>Package definition is:</p>
+<p>Default definition:</p>
<pre class="literal-block">
-\newcommand\PolPrintIntervalsPrintRightEndPoint{\PolPrintIntervalsTheEndPoint}%
+\newcommand\PolPrintIntervalsPrintExactZero{\PolPrintIntervalsTheLeftEndPoint}
+</pre>
+</blockquote>
+</div>
+<div class="section" id="id16">
+<span id="polprintintervalsprintleftendpoint"></span><h3><a class="toc-backref" href="#id92"><tt class="docutils literal">\PolPrintIntervalsPrintLeftEndPoint</tt></a></h3>
+<blockquote>
+<p>Default definition:</p>
+<pre class="literal-block">
+\newcommand\PolPrintIntervalsPrintLeftEndPoint{\PolPrintIntervalsTheLeftEndPoint}
+</pre>
+</blockquote>
+</div>
+<div class="section" id="id17">
+<span id="polprintintervalsprintrightendpoint"></span><h3><a class="toc-backref" href="#id93"><tt class="docutils literal">\PolPrintIntervalsPrintRightEndPoint</tt></a></h3>
+<blockquote>
+<p>Default definition is:</p>
+<pre class="literal-block">
+\newcommand\PolPrintIntervalsPrintRightEndPoint{\PolPrintIntervalsTheRightEndPoint}
+</pre>
+</blockquote>
+</div>
+</div>
+<div class="section" id="id19">
+<span id="id18"></span><h2><a class="toc-backref" href="#id94"><tt class="docutils literal"><span class="pre">\PolPrintIntervals*[varname]{sturmname}</span></tt></a></h2>
+<blockquote>
+<p>This starred variant produces an alternative output (which
+displays the root multiplicity), and is provided as an
+example of customization.</p>
+<p>As replacement for <a class="reference internal" href="#polprintintervalsknownroot">\PolPrintIntervalsKnownRoot</a>,
+<a class="reference internal" href="#polprintintervalsprintexactzero">\PolPrintIntervalsPrintExactZero</a>,
+<a class="reference internal" href="#polprintintervalsunknownroot">\PolPrintIntervalsUnknownRoot</a> it uses its own
+<tt class="docutils literal"><span class="pre">\POL&#64;&#64;PrintIntervals...</span></tt> macros. We only reproduce here one
+definition:</p>
+<pre class="literal-block">
+\newcommand\POL&#64;&#64;PrintIntervalsPrintExactZero{%
+ \displaystyle
+ \xintSignedFrac{\PolPrintIntervalsTheLeftEndPoint}%
+}%
+</pre>
+<p>Multiplicities are printed using this auxiliary macro:</p>
+</blockquote>
+<div class="section" id="polprintintervalsprintmultiplicity">
+<h3><a class="toc-backref" href="#id95"><tt class="docutils literal">\PolPrintIntervalsPrintMultiplicity</tt></a></h3>
+<blockquote>
+<p>whose default definition is:</p>
+<pre class="literal-block">
+\newcommand\PolPrintIntervalsPrintMultiplicity{(\mbox{mult. }\PolPrintIntervalsTheMultiplicity)}
</pre>
</blockquote>
</div>
</div>
<div class="section" id="polmapcoeffs-macro-polname">
-<span id="polmapcoeffs"></span><h2><a class="toc-backref" href="#id82"><tt class="docutils literal"><span class="pre">\PolMapCoeffs{\macro}{polname}</span></tt></a></h2>
+<span id="polmapcoeffs"></span><h2><a class="toc-backref" href="#id96"><tt class="docutils literal"><span class="pre">\PolMapCoeffs{\macro}{polname}</span></tt></a></h2>
<blockquote>
<p>It modifies ('in-place': original coefficients get lost) each
coefficient of the defined polynomial via the <em>expandable</em> macro
@@ -1534,15 +1831,15 @@ will have to be expressed in terms of macros from <a class="reference external"
</blockquote>
</div>
<div class="section" id="polreducecoeffs-polname">
-<span id="polreducecoeffs"></span><h2><a class="toc-backref" href="#id83"><tt class="docutils literal">\PolReduceCoeffs{polname}</tt></a></h2>
+<span id="polreducecoeffs"></span><h2><a class="toc-backref" href="#id97"><tt class="docutils literal">\PolReduceCoeffs{polname}</tt></a></h2>
<blockquote>
About the same as <tt class="docutils literal"><span class="pre">\PolMapCoeffs{\xintIrr}{polname}</span></tt> (but
maintaining a <tt class="docutils literal">[0]</tt> postfix for speedier <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> parsing when
polynomial function is used for computations.) This is a
one-argument macro, working 'in-place'.</blockquote>
</div>
-<div class="section" id="id17">
-<span id="id16"></span><h2><a class="toc-backref" href="#id84"><tt class="docutils literal"><span class="pre">\PolReduceCoeffs*{polname}</span></tt></a></h2>
+<div class="section" id="id21">
+<span id="id20"></span><h2><a class="toc-backref" href="#id98"><tt class="docutils literal"><span class="pre">\PolReduceCoeffs*{polname}</span></tt></a></h2>
<blockquote>
<p>This starred variant leaves un-touched the decimal exponent in the
internal representation of the fractional coefficients, i.e. if a
@@ -1561,16 +1858,16 @@ expansion speed of the <a class="reference external" href="http://www.ctan.org/p
</blockquote>
</div>
<div class="section" id="polmakemonic-polname">
-<span id="polmakemonic"></span><h2><a class="toc-backref" href="#id85"><tt class="docutils literal">\PolMakeMonic{polname}</tt></a></h2>
+<span id="polmakemonic"></span><h2><a class="toc-backref" href="#id99"><tt class="docutils literal">\PolMakeMonic{polname}</tt></a></h2>
<blockquote>
Divides by the leading coefficient. It is recommended to execute
-<a class="reference internal" href="#id17">\PolReduceCoeffs*{polname}</a> immediately afterwards. This is not
+<a class="reference internal" href="#id21">\PolReduceCoeffs*{polname}</a> immediately afterwards. This is not
done automatically, due to the case the original polynomial had integer
coefficients and we want to keep the leading one as common
denominator.</blockquote>
</div>
<div class="section" id="polmakeprimitive-polname">
-<span id="polmakeprimitive"></span><h2><a class="toc-backref" href="#id86"><tt class="docutils literal">\PolMakePrimitive{polname}</tt></a></h2>
+<span id="polmakeprimitive"></span><h2><a class="toc-backref" href="#id100"><tt class="docutils literal">\PolMakePrimitive{polname}</tt></a></h2>
<blockquote>
Divides by the integer content see (<a class="reference internal" href="#policontent">\PolIContent</a>). This thus produces a polynomial with integer
coefficients having no common factor. The sign of the leading
@@ -1578,60 +1875,60 @@ coefficient is not modified.</blockquote>
</div>
</div>
<div class="section" id="expandable-macros">
-<h1><a class="toc-backref" href="#id87">Expandable macros</a></h1>
+<h1><a class="toc-backref" href="#id101">Expandable macros</a></h1>
<p>All these macros expand completely in two steps except <tt class="docutils literal">\PolToExpr</tt>
and <tt class="docutils literal">\PolToFloatExpr</tt> (and their auxiliaries) which need a
<tt class="docutils literal">\write</tt>, <tt class="docutils literal">\edef</tt> or a <tt class="docutils literal"><span class="pre">\csname...\endcsname</span></tt> context.</p>
<div class="section" id="poleval-polname-atexpr-numerical-expression">
-<span id="polevalatexpr"></span><h2><a class="toc-backref" href="#id88"><tt class="docutils literal"><span class="pre">\PolEval{polname}\AtExpr{numerical</span> expression}</tt></a></h2>
+<span id="polevalatexpr"></span><h2><a class="toc-backref" href="#id102"><tt class="docutils literal"><span class="pre">\PolEval{polname}\AtExpr{numerical</span> expression}</tt></a></h2>
<blockquote>
It boils down to
<tt class="docutils literal">\xinttheexpr polname(numerical <span class="pre">expression)\relax</span></tt>.</blockquote>
</div>
<div class="section" id="poleval-polname-at-fraction">
-<span id="polevalat"></span><h2><a class="toc-backref" href="#id89"><tt class="docutils literal"><span class="pre">\PolEval{polname}\At{fraction}</span></tt></a></h2>
+<span id="polevalat"></span><h2><a class="toc-backref" href="#id103"><tt class="docutils literal"><span class="pre">\PolEval{polname}\At{fraction}</span></tt></a></h2>
<blockquote>
Evaluates the polynomial at value <tt class="docutils literal">fraction</tt> which must be in (or
expand to) a format acceptable to the <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> macros.</blockquote>
</div>
<div class="section" id="polevalreduced-polname-atexpr-numerical-expression">
-<span id="polevalreducedatexpr"></span><h2><a class="toc-backref" href="#id90"><tt class="docutils literal"><span class="pre">\PolEvalReduced{polname}\AtExpr{numerical</span> expression}</tt></a></h2>
+<span id="polevalreducedatexpr"></span><h2><a class="toc-backref" href="#id104"><tt class="docutils literal"><span class="pre">\PolEvalReduced{polname}\AtExpr{numerical</span> expression}</tt></a></h2>
<blockquote>
Boils down to <tt class="docutils literal">\xinttheexpr reduce(polname(numerical <span class="pre">expression))\relax</span></tt>.</blockquote>
</div>
<div class="section" id="polevalreduced-polname-at-fraction">
-<span id="polevalreducedat"></span><h2><a class="toc-backref" href="#id91"><tt class="docutils literal"><span class="pre">\PolEvalReduced{polname}\At{fraction}</span></tt></a></h2>
+<span id="polevalreducedat"></span><h2><a class="toc-backref" href="#id105"><tt class="docutils literal"><span class="pre">\PolEvalReduced{polname}\At{fraction}</span></tt></a></h2>
<blockquote>
Evaluates the polynomial at value <tt class="docutils literal">fraction</tt> which must be in (or
expand to) a format acceptable to the <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> macros, and produce
an irreducible fraction.</blockquote>
</div>
<div class="section" id="polfloateval-polname-atexpr-numerical-expression">
-<span id="polfloatevalatexpr"></span><h2><a class="toc-backref" href="#id92"><tt class="docutils literal"><span class="pre">\PolFloatEval{polname}\AtExpr{numerical</span> expression}</tt></a></h2>
+<span id="polfloatevalatexpr"></span><h2><a class="toc-backref" href="#id106"><tt class="docutils literal"><span class="pre">\PolFloatEval{polname}\AtExpr{numerical</span> expression}</tt></a></h2>
<blockquote>
<p>Boils down to <tt class="docutils literal">\xintthefloatexpr polname(numerical <span class="pre">expression)\relax</span></tt>.</p>
<p>This is done via a Horner Scheme (see <a class="reference internal" href="#poldef">\poldef</a> and
<a class="reference internal" href="#polgenfloatvariant-polname">\PolGenFloatVariant{polname}</a>), with already rounded
-coefficients. <a class="footnote-reference" href="#id20" id="id18">[2]</a> To use the <em>exact coefficients</em> with <em>exactly
+coefficients. <a class="footnote-reference" href="#id24" id="id22">[2]</a> To use the <em>exact coefficients</em> with <em>exactly
executed</em> additions and multiplications, just insert it in the float
-expression as in this example: <a class="footnote-reference" href="#id21" id="id19">[3]</a></p>
+expression as in this example: <a class="footnote-reference" href="#id25" id="id23">[3]</a></p>
<pre class="literal-block">
\xintthefloatexpr 3.27*\xintexpr f(2.53)\relax^2\relax
</pre>
<p>The <tt class="docutils literal">f(2.53)</tt> is exactly computed then rounded at the time of
getting raised to the power <tt class="docutils literal">2</tt>. Moving the <tt class="docutils literal">^2</tt> inside, that
operation would also be treated exactly.</p>
-<table class="docutils footnote" frame="void" id="id20" rules="none">
+<table class="docutils footnote" frame="void" id="id24" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
-<tr><td class="label"><a class="fn-backref" href="#id18">[2]</a></td><td>Anyway each floating point operation starts by rounding its
+<tr><td class="label"><a class="fn-backref" href="#id22">[2]</a></td><td>Anyway each floating point operation starts by rounding its
operands to the floating point precision.</td></tr>
</tbody>
</table>
-<table class="docutils footnote" frame="void" id="id21" rules="none">
+<table class="docutils footnote" frame="void" id="id25" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
-<tr><td class="label"><a class="fn-backref" href="#id19">[3]</a></td><td>The <tt class="docutils literal">\xintexpr</tt> here could be <tt class="docutils literal">\xinttheexpr</tt> but that
+<tr><td class="label"><a class="fn-backref" href="#id23">[3]</a></td><td>The <tt class="docutils literal">\xintexpr</tt> here could be <tt class="docutils literal">\xinttheexpr</tt> but that
would be less efficient. Cf. <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> documentation about
nested expressions.</td></tr>
</tbody>
@@ -1639,14 +1936,14 @@ nested expressions.</td></tr>
</blockquote>
</div>
<div class="section" id="polfloateval-polname-at-fraction">
-<span id="polfloatevalat"></span><h2><a class="toc-backref" href="#id93"><tt class="docutils literal"><span class="pre">\PolFloatEval{polname}\At{fraction}</span></tt></a></h2>
+<span id="polfloatevalat"></span><h2><a class="toc-backref" href="#id107"><tt class="docutils literal"><span class="pre">\PolFloatEval{polname}\At{fraction}</span></tt></a></h2>
<blockquote>
Evaluates the polynomial at value <tt class="docutils literal">fraction</tt> which must be in (or
expand to) a format acceptable to the <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> macros, and produces
a floating point number.</blockquote>
</div>
<div class="section" id="polifcoeffisplusorminusone-a-b">
-<span id="polifcoeffisplusorminusone"></span><h2><a class="toc-backref" href="#id94"><tt class="docutils literal"><span class="pre">\PolIfCoeffIsPlusOrMinusOne{A}{B}</span></tt></a></h2>
+<span id="polifcoeffisplusorminusone"></span><h2><a class="toc-backref" href="#id108"><tt class="docutils literal"><span class="pre">\PolIfCoeffIsPlusOrMinusOne{A}{B}</span></tt></a></h2>
<blockquote>
<p>This macro is a priori undefined.</p>
<p>It is defined via the default <a class="reference internal" href="#poltypesetcmd-raw-coeff">\PolTypesetCmd{raw_coeff}</a> to be
@@ -1658,25 +1955,25 @@ plus or minus one, and <tt class="docutils literal">B</tt> if not.</p>
</blockquote>
</div>
<div class="section" id="polleadingcoeff-polname">
-<span id="polleadingcoeff"></span><h2><a class="toc-backref" href="#id95"><tt class="docutils literal">\PolLeadingCoeff{polname}</tt></a></h2>
+<span id="polleadingcoeff"></span><h2><a class="toc-backref" href="#id109"><tt class="docutils literal">\PolLeadingCoeff{polname}</tt></a></h2>
<blockquote>
Expands to the leading coefficient.</blockquote>
</div>
<div class="section" id="polnthcoeff-polname-number">
-<span id="polnthcoeff"></span><h2><a class="toc-backref" href="#id96"><tt class="docutils literal"><span class="pre">\PolNthCoeff{polname}{number}</span></tt></a></h2>
+<span id="polnthcoeff"></span><h2><a class="toc-backref" href="#id110"><tt class="docutils literal"><span class="pre">\PolNthCoeff{polname}{number}</span></tt></a></h2>
<blockquote>
It expands to the raw <tt class="docutils literal">N</tt>-th coefficient (<tt class="docutils literal">0/1[0]</tt> if the index
number is out of range). With <tt class="docutils literal"><span class="pre">N=-1</span></tt>, <tt class="docutils literal"><span class="pre">-2</span></tt>, ... expands to the
leading coefficients.</blockquote>
</div>
<div class="section" id="poldegree-polname">
-<span id="poldegree"></span><h2><a class="toc-backref" href="#id97"><tt class="docutils literal">\PolDegree{polname}</tt></a></h2>
+<span id="poldegree"></span><h2><a class="toc-backref" href="#id111"><tt class="docutils literal">\PolDegree{polname}</tt></a></h2>
<blockquote>
It expands to the degree. This is <tt class="docutils literal"><span class="pre">-1</span></tt> if zero polynomial but this
may change in future. Should it then expand to <tt class="docutils literal"><span class="pre">-\infty</span></tt> ?</blockquote>
</div>
<div class="section" id="policontent-polname">
-<span id="policontent"></span><h2><a class="toc-backref" href="#id98"><tt class="docutils literal">\PolIContent{polname}</tt></a></h2>
+<span id="policontent"></span><h2><a class="toc-backref" href="#id112"><tt class="docutils literal">\PolIContent{polname}</tt></a></h2>
<blockquote>
<p>It expands to the contents of the polynomial, i.e. to the positive
fraction such that dividing by this fraction produces a polynomial
@@ -1685,13 +1982,13 @@ with integer coefficients having no common prime divisor.</p>
</blockquote>
</div>
<div class="section" id="poltoexpr-polname">
-<span id="poltoexpr"></span><h2><a class="toc-backref" href="#id99"><tt class="docutils literal">\PolToExpr{polname}</tt></a></h2>
+<span id="poltoexpr"></span><h2><a class="toc-backref" href="#id113"><tt class="docutils literal">\PolToExpr{polname}</tt></a></h2>
<blockquote>
-<p>Expands <a class="footnote-reference" href="#id23" id="id22">[4]</a> to <tt class="docutils literal"><span class="pre">coeff_N*x^N+...</span></tt> (descending powers.)</p>
-<table class="docutils footnote" frame="void" id="id23" rules="none">
+<p>Expands <a class="footnote-reference" href="#id27" id="id26">[4]</a> to <tt class="docutils literal"><span class="pre">coeff_N*x^N+...</span></tt> (descending powers.)</p>
+<table class="docutils footnote" frame="void" id="id27" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
-<tr><td class="label"><a class="fn-backref" href="#id22">[4]</a></td><td>in a <tt class="docutils literal">\write</tt>, <tt class="docutils literal">\edef</tt>, or <tt class="docutils literal"><span class="pre">\csname...\endcsname</span></tt>, but
+<tr><td class="label"><a class="fn-backref" href="#id26">[4]</a></td><td>in a <tt class="docutils literal">\write</tt>, <tt class="docutils literal">\edef</tt>, or <tt class="docutils literal"><span class="pre">\csname...\endcsname</span></tt>, but
not under <tt class="docutils literal"><span class="pre">\romannumeral-`0</span></tt>.</td></tr>
</tbody>
</table>
@@ -1710,7 +2007,7 @@ of <tt class="docutils literal">\PolToExpr{f}</tt>, but a simple <tt class="docu
the identical result.</p>
</blockquote>
<div class="section" id="poltoexproneterm-raw-coeff-number">
-<span id="poltoexproneterm"></span><h3><a class="toc-backref" href="#id100"><tt class="docutils literal"><span class="pre">\PolToExprOneTerm{raw_coeff}{number}</span></tt></a></h3>
+<span id="poltoexproneterm"></span><h3><a class="toc-backref" href="#id114"><tt class="docutils literal"><span class="pre">\PolToExprOneTerm{raw_coeff}{number}</span></tt></a></h3>
<blockquote>
<p>This two argument expandable command takes care of the monomial and
its coefficient. The default definition is done in order for
@@ -1723,13 +2020,13 @@ or a minus one. See <a class="reference internal" href="#poltoexprtimes">\PolToE
</blockquote>
</div>
<div class="section" id="poltoexpronetermstylea-raw-coeff-number">
-<span id="poltoexpronetermstylea"></span><h3><a class="toc-backref" href="#id101"><tt class="docutils literal"><span class="pre">\PolToExprOneTermStyleA{raw_coeff}{number}</span></tt></a></h3>
+<span id="poltoexpronetermstylea"></span><h3><a class="toc-backref" href="#id115"><tt class="docutils literal"><span class="pre">\PolToExprOneTermStyleA{raw_coeff}{number}</span></tt></a></h3>
<blockquote>
Holds the default package meaning of
<a class="reference internal" href="#poltoexproneterm-raw-coeff-number">\PolToExprOneTerm{raw_coeff}{number}</a>.</blockquote>
</div>
<div class="section" id="poltoexpronetermstyleb-raw-coeff-number">
-<span id="poltoexpronetermstyleb"></span><h3><a class="toc-backref" href="#id102"><tt class="docutils literal"><span class="pre">\PolToExprOneTermStyleB{raw_coeff}{number}</span></tt></a></h3>
+<span id="poltoexpronetermstyleb"></span><h3><a class="toc-backref" href="#id116"><tt class="docutils literal"><span class="pre">\PolToExprOneTermStyleB{raw_coeff}{number}</span></tt></a></h3>
<blockquote>
<p>For output in this style:</p>
<pre class="literal-block">
@@ -1743,7 +2040,7 @@ To revert to package default, issue
</blockquote>
</div>
<div class="section" id="poltoexprcmd-raw-coeff">
-<span id="poltoexprcmd"></span><h3><a class="toc-backref" href="#id103"><tt class="docutils literal">\PolToExprCmd{raw_coeff}</tt></a></h3>
+<span id="poltoexprcmd"></span><h3><a class="toc-backref" href="#id117"><tt class="docutils literal">\PolToExprCmd{raw_coeff}</tt></a></h3>
<blockquote>
It is the one-argument macro used by the package definition of
<tt class="docutils literal">\PolToExprOneTerm</tt> for the coefficients themselves (when not
@@ -1753,21 +2050,21 @@ to <tt class="docutils literal"><span class="pre">\xintIrr{#1}</span></tt> or to
output forcefully reduced coefficients.</blockquote>
</div>
<div class="section" id="poltoexprtermprefix-raw-coeff">
-<span id="poltoexprtermprefix"></span><h3><a class="toc-backref" href="#id104"><tt class="docutils literal">\PolToExprTermPrefix{raw_coeff}</tt></a></h3>
+<span id="poltoexprtermprefix"></span><h3><a class="toc-backref" href="#id118"><tt class="docutils literal">\PolToExprTermPrefix{raw_coeff}</tt></a></h3>
<blockquote>
Defined identically as <a class="reference internal" href="#poltypesetcmdprefix-raw-coeff">\PolTypesetCmdPrefix{raw_coeff}</a>. It
prefixes with a plus sign for non-negative coefficients, because
they don't carry one by themselves.</blockquote>
</div>
-<div class="section" id="id24">
-<span id="poltoexprvar"></span><h3><a class="toc-backref" href="#id105"><tt class="docutils literal">\PolToExprVar</tt></a></h3>
+<div class="section" id="id28">
+<span id="poltoexprvar"></span><h3><a class="toc-backref" href="#id119"><tt class="docutils literal">\PolToExprVar</tt></a></h3>
<blockquote>
This expands to the variable to use in output (it does not have to
be a single letter, may be an expandable macro.) Initial definition
is <tt class="docutils literal">x</tt>.</blockquote>
</div>
-<div class="section" id="id25">
-<span id="poltoexprtimes"></span><h3><a class="toc-backref" href="#id106"><tt class="docutils literal">\PolToExprTimes</tt></a></h3>
+<div class="section" id="id29">
+<span id="poltoexprtimes"></span><h3><a class="toc-backref" href="#id120"><tt class="docutils literal">\PolToExprTimes</tt></a></h3>
<blockquote>
This expands to the symbol used for multiplication of an
<tt class="docutils literal"><span class="pre">x^{number}</span></tt> by the corresponding coefficient. The default is
@@ -1776,14 +2073,14 @@ this will give output incompatible with some professional computer
algebra software).</blockquote>
</div>
</div>
-<div class="section" id="id27">
-<span id="id26"></span><h2><a class="toc-backref" href="#id107"><tt class="docutils literal"><span class="pre">\PolToExpr*{polname}</span></tt></a></h2>
+<div class="section" id="id31">
+<span id="id30"></span><h2><a class="toc-backref" href="#id121"><tt class="docutils literal"><span class="pre">\PolToExpr*{polname}</span></tt></a></h2>
<blockquote>
Expands to <tt class="docutils literal"><span class="pre">coeff_0+coeff_1*x+coeff_2*x^2+...</span></tt> (ascending powers).
Customizable like <a class="reference internal" href="#poltoexpr-polname">\PolToExpr{polname}</a> via the same macros.</blockquote>
</div>
<div class="section" id="poltofloatexpr-polname">
-<span id="poltofloatexpr"></span><h2><a class="toc-backref" href="#id108"><tt class="docutils literal">\PolToFloatExpr{polname}</tt></a></h2>
+<span id="poltofloatexpr"></span><h2><a class="toc-backref" href="#id122"><tt class="docutils literal">\PolToFloatExpr{polname}</tt></a></h2>
<blockquote>
<p>Similar to <a class="reference internal" href="#poltoexpr-polname">\PolToExpr{polname}</a> but uses <a class="reference external" href="\PolToFloatExprCmd{raw_coeff}">\PolToFloatExprCmd</a>
which by default rounds and converts the coefficients to floating
@@ -1802,13 +2099,13 @@ those output by <tt class="docutils literal">\PolToFloatExpr{polname}</tt>.</p>
</div>
</blockquote>
<div class="section" id="poltofloatexproneterm-raw-coeff-number">
-<span id="poltofloatexproneterm"></span><h3><a class="toc-backref" href="#id109"><tt class="docutils literal"><span class="pre">\PolToFloatExprOneTerm{raw_coeff}{number}</span></tt></a></h3>
+<span id="poltofloatexproneterm"></span><h3><a class="toc-backref" href="#id123"><tt class="docutils literal"><span class="pre">\PolToFloatExprOneTerm{raw_coeff}{number}</span></tt></a></h3>
<blockquote>
Similar to <a class="reference external" href="\PolToExprOneTerm{raw_coeff}{number}">\PolToExprOneTerm</a>. But does not treat
especially coefficients equal to plus or minus one.</blockquote>
</div>
<div class="section" id="poltofloatexprcmd-raw-coeff">
-<span id="id29"></span><h3><a class="toc-backref" href="#id110"><tt class="docutils literal">\PolToFloatExprCmd{raw_coeff}</tt></a></h3>
+<span id="id33"></span><h3><a class="toc-backref" href="#id124"><tt class="docutils literal">\PolToFloatExprCmd{raw_coeff}</tt></a></h3>
<blockquote>
<p>It is the one-argument macro used by <tt class="docutils literal">\PolToFloatExprOneTerm</tt>.
Its package definition is <tt class="docutils literal"><span class="pre">\xintFloat{#1}</span></tt>.</p>
@@ -1830,26 +2127,28 @@ in <tt class="docutils literal">xintfrac</tt> raw format.</p>
</blockquote>
</div>
</div>
-<div class="section" id="id31">
-<span id="id30"></span><h2><a class="toc-backref" href="#id111"><tt class="docutils literal"><span class="pre">\PolToFloatExpr*{polname}</span></tt></a></h2>
+<div class="section" id="id35">
+<span id="id34"></span><h2><a class="toc-backref" href="#id125"><tt class="docutils literal"><span class="pre">\PolToFloatExpr*{polname}</span></tt></a></h2>
<blockquote>
Typesets in ascending powers.</blockquote>
</div>
<div class="section" id="poltolist-polname">
-<span id="poltolist"></span><h2><a class="toc-backref" href="#id112"><tt class="docutils literal">\PolToList{polname}</tt></a></h2>
+<span id="poltolist"></span><h2><a class="toc-backref" href="#id126"><tt class="docutils literal">\PolToList{polname}</tt></a></h2>
<blockquote>
-Expands to <tt class="docutils literal"><span class="pre">{coeff_0}{coeff_1}...{coeff_N}</span></tt> with <tt class="docutils literal">N</tt> = degree
-(except zero polynomial which does give <tt class="docutils literal">{0/1[0]}</tt> and not an
+Expands to <tt class="docutils literal"><span class="pre">{coeff_0}{coeff_1}...{coeff_N}</span></tt> with <tt class="docutils literal">N</tt> = degree, and
+<tt class="docutils literal">coeff_N</tt> the leading coefficient
+(the zero polynomial does give <tt class="docutils literal">{0/1[0]}</tt> and not an
empty output.)</blockquote>
</div>
<div class="section" id="poltocsv-polname">
-<span id="poltocsv"></span><h2><a class="toc-backref" href="#id113"><tt class="docutils literal">\PolToCSV{polname}</tt></a></h2>
+<span id="poltocsv"></span><h2><a class="toc-backref" href="#id127"><tt class="docutils literal">\PolToCSV{polname}</tt></a></h2>
<blockquote>
-Expands to <tt class="docutils literal">coeff_0, coeff_1, coeff_2, <span class="pre">.....,</span> coeff_N</tt>. Converse
+Expands to <tt class="docutils literal">coeff_0, coeff_1, coeff_2, <span class="pre">.....,</span> coeff_N</tt>, starting
+with constant term and ending with leading coefficient. Converse
to <a class="reference internal" href="#polfromcsv-polname-csv">\PolFromCSV</a>.</blockquote>
</div>
<div class="section" id="polsturmchainlength-sturmname">
-<span id="polsturmchainlength"></span><h2><a class="toc-backref" href="#id114"><tt class="docutils literal">\PolSturmChainLength{sturmname}</tt></a></h2>
+<span id="polsturmchainlength"></span><h2><a class="toc-backref" href="#id128"><tt class="docutils literal">\PolSturmChainLength{sturmname}</tt></a></h2>
<blockquote>
<p>Returns the integer <tt class="docutils literal">N</tt> such that <tt class="docutils literal">sturmname_N</tt> is the last one
in the Sturm chain <tt class="docutils literal">sturmname_0</tt>, <tt class="docutils literal">sturmname_1</tt>, ...</p>
@@ -1857,43 +2156,44 @@ in the Sturm chain <tt class="docutils literal">sturmname_0</tt>, <tt class="doc
</blockquote>
</div>
<div class="section" id="polsturmifzeroexactlyknown-sturmname-index-a-b">
-<span id="polsturmifzeroexactlyknown"></span><h2><a class="toc-backref" href="#id115"><tt class="docutils literal"><span class="pre">\PolSturmIfZeroExactlyKnown{sturmname}{index}{A}{B}</span></tt></a></h2>
+<span id="polsturmifzeroexactlyknown"></span><h2><a class="toc-backref" href="#id129"><tt class="docutils literal"><span class="pre">\PolSturmIfZeroExactlyKnown{sturmname}{index}{A}{B}</span></tt></a></h2>
<blockquote>
<p>Executes <tt class="docutils literal">A</tt> if the <tt class="docutils literal">index</tt>-th interval reduces to a singleton,
i.e. the root is known exactly, else <tt class="docutils literal">B</tt>.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
-<p><tt class="docutils literal">index</tt> may be a TeX count, or a <tt class="docutils literal">\value{latexcounter}</tt>, or a
-numerical expression as parsable by <tt class="docutils literal">\numexpr</tt>: it does not
-have to be given via explicit digits.</p>
-<p class="last">This remark applies also to the other package macros with
-<tt class="docutils literal">index</tt> being the name of the argument in this documentation.
-There is also an out-of-range check done for some reasonable
-error message (right before everything goes haywire).</p>
+<p class="last"><tt class="docutils literal">index</tt> is allowed to be something like <tt class="docutils literal">1+2*3</tt> as it is fed
+to <tt class="docutils literal"><span class="pre">\the\numexpr...\relax</span></tt>.</p>
</div>
</blockquote>
</div>
<div class="section" id="polsturmisolatedzeroleft-sturmname-index">
-<span id="polsturmisolatedzeroleft"></span><h2><a class="toc-backref" href="#id116"><tt class="docutils literal"><span class="pre">\PolSturmIsolatedZeroLeft{sturmname}{index}</span></tt></a></h2>
+<span id="polsturmisolatedzeroleft"></span><h2><a class="toc-backref" href="#id130"><tt class="docutils literal"><span class="pre">\PolSturmIsolatedZeroLeft{sturmname}{index}</span></tt></a></h2>
<blockquote>
-Expands to the left end-point for the <tt class="docutils literal">index</tt>-th interval
-obtained via <a class="reference internal" href="#polsturmisolatezeros-sturmname">\PolSturmIsolateZeros{sturmname}</a> and possibly
-refined afterwards.</blockquote>
+<p>Expands to the left end-point for the <tt class="docutils literal">index</tt>-th interval, as
+computed by some earlier <a class="reference internal" href="#polsturmisolatezeros-sturmname">\PolSturmIsolateZeros{sturmname}</a>.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Of course, this is kept updated by macros such as
+<a class="reference internal" href="#polrefineinterval-n">\PolRefineInterval{sturmname}{index}</a>.</p>
+</div>
+<p>The value is pre-formatted using <a class="reference internal" href="#poldectostring">\PolDecTostring</a>.</p>
+</blockquote>
</div>
<div class="section" id="polsturmisolatedzeroright-sturmname-index">
-<span id="polsturmisolatedzeroright"></span><h2><a class="toc-backref" href="#id117"><tt class="docutils literal"><span class="pre">\PolSturmIsolatedZeroRight{sturmname}{index}</span></tt></a></h2>
+<span id="polsturmisolatedzeroright"></span><h2><a class="toc-backref" href="#id131"><tt class="docutils literal"><span class="pre">\PolSturmIsolatedZeroRight{sturmname}{index}</span></tt></a></h2>
<blockquote>
-Expands to the right end-point for the <tt class="docutils literal">index</tt>-th interval
-obtained via <a class="reference internal" href="#polsturmisolatezeros-sturmname">\PolSturmIsolateZeros{sturmname}</a> and possibly
-refined afterwards.</blockquote>
+<p>Expands to the right end-point for the <tt class="docutils literal">index</tt>-th interval as
+computed by some earlier <a class="reference internal" href="#polsturmisolatezeros-sturmname">\PolSturmIsolateZeros{sturmname}</a> and
+possibly refined afterwards.</p>
+<p>The value is pre-formatted using <a class="reference internal" href="#poldectostring">\PolDecTostring</a>.</p>
+</blockquote>
</div>
<div class="section" id="polsturmisolatedzeromultiplicity-sturmname-index">
-<span id="polsturmisolatedzeromultiplicity"></span><h2><a class="toc-backref" href="#id118"><tt class="docutils literal"><span class="pre">\PolSturmIsolatedZeroMultiplicity{sturmname}{index}</span></tt></a></h2>
+<span id="polsturmisolatedzeromultiplicity"></span><h2><a class="toc-backref" href="#id132"><tt class="docutils literal"><span class="pre">\PolSturmIsolatedZeroMultiplicity{sturmname}{index}</span></tt></a></h2>
<blockquote>
<p>Expands to the multiplicity of the unique root contained in the
-<tt class="docutils literal">index</tt>-th interval as determined by
-<a class="reference internal" href="#id12">\PolSturmIsolateZeros*{sturmname}</a> and possibly refined
-afterwards.</p>
+<tt class="docutils literal">index</tt>-th interval.</p>
<div class="admonition attention">
<p class="first admonition-title">Attention!</p>
<p class="last">A prior execution of <a class="reference internal" href="#id12">\PolSturmIsolateZeros*{sturmname}</a> is mandatory.</p>
@@ -1903,15 +2203,22 @@ roots</a> for an example of use.</p>
</blockquote>
</div>
<div class="section" id="polsturmnbofisolatedzeros-sturmname">
-<span id="polsturmnbofisolatedzeros"></span><h2><a class="toc-backref" href="#id119"><tt class="docutils literal">\PolSturmNbOfIsolatedZeros{sturmname}</tt></a></h2>
+<span id="polsturmnbofisolatedzeros"></span><h2><a class="toc-backref" href="#id133"><tt class="docutils literal">\PolSturmNbOfIsolatedZeros{sturmname}</tt></a></h2>
<blockquote>
Expands to the number of real roots of the polynomial
-<tt class="docutils literal">&lt;sturmname&gt;_0</tt> (which is the number of distinct real roots of the
-polynomial used to create the Sturm chain via
+<tt class="docutils literal">&lt;sturmname&gt;_0</tt>, i.e. the number of distinct real roots of the
+polynomial originally used to create the Sturm chain via
<a class="reference internal" href="#poltosturm-polname-sturmname">\PolToSturm{polname}{sturmname}</a>.</blockquote>
+<div class="admonition warning">
+<p class="first admonition-title">Warning</p>
+<p class="last">The next few macros counting roots, with or without multiplicities,
+less than or equal to some value, are under evaluation and may be
+removed from the package if their utility is judged to be not high
+enough. They can be re-coded at user level on the basis of the other
+documented package macros anyway.</p>
</div>
<div class="section" id="polsturmnbofrootsof-sturmname-lessthanorequalto-value">
-<h2><a class="toc-backref" href="#id120"><tt class="docutils literal"><span class="pre">\PolSturmNbOfRootsOf{sturmname}\LessThanOrEqualTo{value}</span></tt></a></h2>
+<h3><a class="toc-backref" href="#id134"><tt class="docutils literal"><span class="pre">\PolSturmNbOfRootsOf{sturmname}\LessThanOrEqualTo{value}</span></tt></a></h3>
<blockquote>
<p>Expands to the number of distinct roots (of the polynomial used to
create the Sturm chain) less than or equal to the <tt class="docutils literal">value</tt> (i.e. a
@@ -1927,7 +2234,7 @@ of the above constraint.</p>
</blockquote>
</div>
<div class="section" id="polsturmnbofrootsof-sturmname-lessthanorequaltoexpr-expression">
-<h2><a class="toc-backref" href="#id121"><tt class="docutils literal"><span class="pre">\PolSturmNbOfRootsOf{sturmname}\LessThanOrEqualToExpr{expression}</span></tt></a></h2>
+<h3><a class="toc-backref" href="#id135"><tt class="docutils literal"><span class="pre">\PolSturmNbOfRootsOf{sturmname}\LessThanOrEqualToExpr{expression}</span></tt></a></h3>
<blockquote>
<p>Expands to the number of distinct roots (of the polynomial
used to create the Sturm chain) which are less than or equal to the
@@ -1940,91 +2247,160 @@ beforehand.</p>
</blockquote>
</div>
<div class="section" id="polsturmnbwithmultofrootsof-sturmname-lessthanorequalto-value">
-<h2><a class="toc-backref" href="#id122"><tt class="docutils literal"><span class="pre">\PolSturmNbWithMultOfRootsOf{sturmname}\LessThanOrEqualTo{value}</span></tt></a></h2>
+<h3><a class="toc-backref" href="#id136"><tt class="docutils literal"><span class="pre">\PolSturmNbWithMultOfRootsOf{sturmname}\LessThanOrEqualTo{value}</span></tt></a></h3>
<blockquote>
<p>Expands to the number counted with multiplicities of the roots (of
the polynomial used to create the Sturm chain) which are less than
or equal to the given <tt class="docutils literal">value</tt>.</p>
<div class="admonition attention">
<p class="first admonition-title">Attention!</p>
-<p class="last"><a class="reference internal" href="#id12">\PolSturmIsolateZeros*{sturmname}</a> or its alias
-<a class="reference internal" href="#polsturmisolatezerosandgetmultiplicities-sturmname">\PolSturmIsolateZerosAndGetMultiplicities{sturmname}</a>
-must have been executed
-beforehand.</p>
+<p class="last"><a class="reference internal" href="#id12">\PolSturmIsolateZeros*{sturmname}</a> (or the double starred
+variant) must have been executed beforehand.</p>
</div>
</blockquote>
</div>
<div class="section" id="polsturmnbwithmultofrootsof-sturmname-lessthanorequaltoexpr-expression">
-<h2><a class="toc-backref" href="#id123"><tt class="docutils literal"><span class="pre">\PolSturmNbWithMultOfRootsOf{sturmname}\LessThanOrEqualToExpr{expression}</span></tt></a></h2>
+<h3><a class="toc-backref" href="#id137"><tt class="docutils literal"><span class="pre">\PolSturmNbWithMultOfRootsOf{sturmname}\LessThanOrEqualToExpr{expression}</span></tt></a></h3>
<blockquote>
<p>Expands to the total number of roots (counted with multiplicities)
which are less than or equal to the given <tt class="docutils literal">expression</tt>.</p>
<div class="admonition attention">
<p class="first admonition-title">Attention!</p>
-<p class="last"><a class="reference internal" href="#id12">\PolSturmIsolateZeros*{sturmname}</a> or its alias
-<a class="reference internal" href="#polsturmisolatezerosandgetmultiplicities-sturmname">\PolSturmIsolateZerosAndGetMultiplicities{sturmname}</a>
-must have been executed
+<p class="last"><a class="reference internal" href="#id12">\PolSturmIsolateZeros*{sturmname}</a> (or the double starred
+variant) must have been executed beforehand.</p>
+</div>
+</blockquote>
+</div>
+</div>
+<div class="section" id="polsturmnbofrationalroots-sturmname">
+<h2><a class="toc-backref" href="#id138"><tt class="docutils literal">\PolSturmNbOfRationalRoots{sturmname}</tt></a></h2>
+<blockquote>
+<p>Expands to the number of rational roots (without multiplicities).</p>
+<div class="admonition attention">
+<p class="first admonition-title">Attention!</p>
+<p class="last"><a class="reference internal" href="#id14">\PolSturmIsolateZeros**{sturmname}</a> must have been executed
+beforehand.</p>
+</div>
+</blockquote>
+</div>
+<div class="section" id="polsturmnbofrationalrootswithmultiplicities-sturmname">
+<h2><a class="toc-backref" href="#id139"><tt class="docutils literal">\PolSturmNbOfRationalRootsWithMultiplicities{sturmname}</tt></a></h2>
+<blockquote>
+<p>Expands to the number of rational roots (counted with multiplicities).</p>
+<div class="admonition attention">
+<p class="first admonition-title">Attention!</p>
+<p class="last"><a class="reference internal" href="#id14">\PolSturmIsolateZeros**{sturmname}</a> must have been executed
+beforehand.</p>
+</div>
+</blockquote>
+</div>
+<div class="section" id="polsturmrationalroot-sturmname-k">
+<h2><a class="toc-backref" href="#id140"><tt class="docutils literal"><span class="pre">\PolSturmRationalRoot{sturmname}{k}</span></tt></a></h2>
+<blockquote>
+<p>Expands to the <tt class="docutils literal">k</tt>th rational root (they are ordered and indexed
+starting at 1 for the most negative).</p>
+<div class="admonition attention">
+<p class="first admonition-title">Attention!</p>
+<p class="last"><a class="reference internal" href="#id14">\PolSturmIsolateZeros**{sturmname}</a> must have been executed
+beforehand.</p>
+</div>
+</blockquote>
+</div>
+<div class="section" id="polsturmrationalrootindex-sturmname-k">
+<h2><a class="toc-backref" href="#id141"><tt class="docutils literal"><span class="pre">\PolSturmRationalRootIndex{sturmname}{k}</span></tt></a></h2>
+<blockquote>
+<p>Expands to <tt class="docutils literal">index</tt> of the <tt class="docutils literal">k</tt>th rational root as part of the
+ordered real roots (without multiplicities). I.e., above macro
+<a class="reference internal" href="#polsturmrationalroot-sturmname-k">\PolSturmRationalRoot{sturmname}{k}</a> is equivalent to this
+nested call:</p>
+<pre class="literal-block">
+\PolSturmIsolatedZeroLeft{sturmname}{\PolSturmRationalRootIndex{sturmname}{k}}
+</pre>
+<div class="admonition attention">
+<p class="first admonition-title">Attention!</p>
+<p class="last"><a class="reference internal" href="#id14">\PolSturmIsolateZeros**{sturmname}</a> must have been executed
+beforehand.</p>
+</div>
+</blockquote>
+</div>
+<div class="section" id="polsturmrationalrootmultiplicity-sturmname-k">
+<h2><a class="toc-backref" href="#id142"><tt class="docutils literal"><span class="pre">\PolSturmRationalRootMultiplicity{sturmname}{k}</span></tt></a></h2>
+<blockquote>
+<p>Expands to the multiplicity of the <tt class="docutils literal">k</tt>th rational root.</p>
+<div class="admonition attention">
+<p class="first admonition-title">Attention!</p>
+<p class="last"><a class="reference internal" href="#id14">\PolSturmIsolateZeros**{sturmname}</a> must have been executed
beforehand.</p>
</div>
</blockquote>
</div>
<div class="section" id="polintervalwidth-sturmname-index">
-<span id="polintervalwidth"></span><h2><a class="toc-backref" href="#id124"><tt class="docutils literal"><span class="pre">\PolIntervalWidth{sturmname}{index}</span></tt></a></h2>
+<span id="polintervalwidth"></span><h2><a class="toc-backref" href="#id143"><tt class="docutils literal"><span class="pre">\PolIntervalWidth{sturmname}{index}</span></tt></a></h2>
<blockquote>
The <tt class="docutils literal">10^E</tt> width of the current <tt class="docutils literal">index</tt>-th root localization
interval. Output is in <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> raw <tt class="docutils literal">1/1[E]</tt> format (if not zero).</blockquote>
</div>
-<div class="section" id="macros-for-use-within-execution-of-polprintintervals">
-<h2><a class="toc-backref" href="#id125">Macros for use within execution of <tt class="docutils literal">\PolPrintIntervals</tt></a></h2>
-<p>More precisely, they can be used within the replacement texts of the
-<a class="reference internal" href="#polprintintervalsprintleftendpoint">\PolPrintIntervalsPrintLeftEndPoint</a>, etc, macros.</p>
-<div class="section" id="id32">
-<span id="polprintintervalstheendpoint"></span><h3><a class="toc-backref" href="#id126"><tt class="docutils literal">\PolPrintIntervalsTheEndPoint</tt></a></h3>
+<div class="section" id="expandable-macros-for-use-within-execution-of-polprintintervals">
+<h2><a class="toc-backref" href="#id144">Expandable macros for use within execution of <tt class="docutils literal">\PolPrintIntervals</tt></a></h2>
+<p>These macros are for usage within custom user redefinitions of
+<a class="reference internal" href="#polprintintervalsknownroot">\PolPrintIntervalsKnownRoot</a>, <a class="reference internal" href="#polprintintervalsunknownroot">\PolPrintIntervalsUnknownRoot</a>, or
+in redefinitions of <a class="reference internal" href="#polprintintervalsprintexactzero">PolPrintIntervalsPrintExactZero</a> (used in the
+default for the former) and of <a class="reference internal" href="#polprintintervalsprintleftendpoint">\PolPrintIntervalsPrintLeftEndPoint</a>,
+<a class="reference internal" href="#polprintintervalsprintrightendpoint">\PolPrintIntervalsPrintRightEndPoint</a> (used in the default for the
+latter).</p>
+<div class="admonition attention">
+<p class="first admonition-title">Attention!</p>
+<p class="last">Some macros formerly mentioned here got removed at 0.7:
+<tt class="docutils literal">\PolPrintIntervalsTheEndPoint</tt>,
+<tt class="docutils literal"><span class="pre">\PolIfEndPointIsPositive{A}{B}</span></tt>,
+<tt class="docutils literal"><span class="pre">\PolIfEndPointIsNegative{A}{B}</span></tt>,
+<tt class="docutils literal"><span class="pre">\PolIfEndPointIsZero{A}{B}</span></tt>.</p>
+</div>
+<div class="section" id="polprintintervalsthevar">
+<h3><a class="toc-backref" href="#id145"><tt class="docutils literal">\PolPrintIntervalsTheVar</tt></a></h3>
<blockquote>
-Within a custom <a class="reference internal" href="#polprintintervalsprintleftendpoint">\PolPrintIntervalsPrintLeftEndPoint</a>, custom
-<a class="reference internal" href="#polprintintervalsprintrightendpoint">\PolPrintIntervalsPrintRightEndPoint</a>, or custom
-<a class="reference internal" href="#polprintintervalsprintexactzero">\PolPrintIntervalsPrintExactZero</a> this macro expands to the left
-or right end point of the considered interval. Serves as default
-replacement for <a class="reference internal" href="#polprintintervalsprintleftendpoint">\PolPrintIntervalsPrintLeftEndPoint</a> , etc...</blockquote>
+Expands to the name (default <tt class="docutils literal">Z</tt>) used for representing the roots,
+which was passed as optional argument <tt class="docutils literal">varname</tt> to
+<a class="reference internal" href="#polprintintervals-varname-sturmname">\PolPrintIntervals[varname]{sturmname}</a>.</blockquote>
</div>
-<div class="section" id="id33">
-<span id="polprintintervalstheindex"></span><h3><a class="toc-backref" href="#id127"><tt class="docutils literal">\PolPrintIntervalsTheIndex</tt></a></h3>
+<div class="section" id="polprintintervalstheindex">
+<h3><a class="toc-backref" href="#id146"><tt class="docutils literal">\PolPrintIntervalsTheIndex</tt></a></h3>
<blockquote>
-Within a custom <a class="reference internal" href="#polprintintervalsprintleftendpoint">\PolPrintIntervalsPrintLeftEndPoint</a>, custom
-<a class="reference internal" href="#polprintintervalsprintrightendpoint">\PolPrintIntervalsPrintRightEndPoint</a>, or custom
-<a class="reference internal" href="#polprintintervalsprintexactzero">\PolPrintIntervalsPrintExactZero</a> this macro expands to the index
-of the considered interval. For example if user wants to print the
-corresponding end points in red, the index value can thus be tested
-in the replacement text of <a class="reference internal" href="#polprintintervalsprintleftendpoint">\PolPrintIntervalsPrintLeftEndPoint</a> and
-the other two similar macros.</blockquote>
+Expands to the index of the considered interval (indexing starting
+at 1 for the leftmost interval).</blockquote>
</div>
-<div class="section" id="polifendpointispositive-a-b">
-<span id="polifendpointispositive"></span><h3><a class="toc-backref" href="#id128"><tt class="docutils literal"><span class="pre">\PolIfEndPointIsPositive{A}{B}</span></tt></a></h3>
+<div class="section" id="polprintintervalsthesturmname">
+<h3><a class="toc-backref" href="#id147"><tt class="docutils literal">\PolPrintIntervalsTheSturmName</tt></a></h3>
<blockquote>
-Within a custom <a class="reference internal" href="#polprintintervalsprintleftendpoint">\PolPrintIntervalsPrintLeftEndPoint</a>, custom
-<a class="reference internal" href="#polprintintervalsprintrightendpoint">\PolPrintIntervalsPrintRightEndPoint</a>, or custom
-<a class="reference internal" href="#polprintintervalsprintexactzero">\PolPrintIntervalsPrintExactZero</a> this macro executes <tt class="docutils literal">A</tt> if
-the considered interval end-point is positive, else <tt class="docutils literal">B</tt>.</blockquote>
+Expands to the argument which was passed as <tt class="docutils literal">sturmname</tt> to
+<a class="reference internal" href="#polprintintervals-varname-sturmname">\PolPrintIntervals[varname]{sturmname}</a>.</blockquote>
</div>
-<div class="section" id="polifendpointisnegative-a-b">
-<span id="polifendpointisnegative"></span><h3><a class="toc-backref" href="#id129"><tt class="docutils literal"><span class="pre">\PolIfEndPointIsNegative{A}{B}</span></tt></a></h3>
+<div class="section" id="polprintintervalstheleftendpoint">
+<h3><a class="toc-backref" href="#id148"><tt class="docutils literal">\PolPrintIntervalsTheLeftEndPoint</tt></a></h3>
<blockquote>
-Within a custom <a class="reference internal" href="#polprintintervalsprintleftendpoint">\PolPrintIntervalsPrintLeftEndPoint</a>, custom
-<a class="reference internal" href="#polprintintervalsprintrightendpoint">\PolPrintIntervalsPrintRightEndPoint</a>, or custom
-<a class="reference internal" href="#polprintintervalsprintexactzero">\PolPrintIntervalsPrintExactZero</a> this macro executes <tt class="docutils literal">A</tt> if
-the considered interval end-point is negative, else <tt class="docutils literal">B</tt>.</blockquote>
+The left end point of the interval, as would be produced by
+<a class="reference internal" href="#polsturmisolatedzeroleft">\PolSturmIsolatedZeroLeft</a> if it was
+used with arguments the Sturm chain name and interval index returned
+by <a class="reference internal" href="#polprintintervalsthesturmname">\PolPrintIntervalsTheSturmName</a> and
+<a class="reference internal" href="#polprintintervalstheindex">\PolPrintIntervalsTheIndex</a>.</blockquote>
</div>
-<div class="section" id="polifendpointiszero-a-b">
-<span id="polifendpointiszero"></span><h3><a class="toc-backref" href="#id130"><tt class="docutils literal"><span class="pre">\PolIfEndPointIsZero{A}{B}</span></tt></a></h3>
+<div class="section" id="polprintintervalstherightendpoint">
+<h3><a class="toc-backref" href="#id149"><tt class="docutils literal">\PolPrintIntervalsTheRightEndPoint</tt></a></h3>
<blockquote>
-Within a custom <a class="reference internal" href="#polprintintervalsprintleftendpoint">\PolPrintIntervalsPrintLeftEndPoint</a>, custom
-<a class="reference internal" href="#polprintintervalsprintrightendpoint">\PolPrintIntervalsPrintRightEndPoint</a>, or custom
-<a class="reference internal" href="#polprintintervalsprintexactzero">\PolPrintIntervalsPrintExactZero</a> this macro executes <tt class="docutils literal">A</tt> if
-the considered interval end-point is zero, else <tt class="docutils literal">B</tt>.</blockquote>
+The right end point of the interval, as would be produced by
+<a class="reference internal" href="#polsturmisolatedzeroright">\PolSturmIsolatedZeroRight</a> for
+this Sturm chain name and index.</blockquote>
+</div>
+<div class="section" id="polprintintervalsthemultiplicity">
+<h3><a class="toc-backref" href="#id150"><tt class="docutils literal">\PolPrintIntervalsTheMultiplicity</tt></a></h3>
+<blockquote>
+The multiplicity of the unique root within the interval of index
+<a class="reference internal" href="#polprintintervalstheindex">\PolPrintIntervalsTheIndex</a>. Makes sense only if the starred (or
+double-starred) variant of <a class="reference internal" href="#polsturmisolatezeros">\PolSturmIsolateZeros</a> was used earlier.</blockquote>
</div>
</div>
<div class="section" id="poldectostring-decimal-number">
-<span id="poldectostring"></span><h2><a class="toc-backref" href="#id131"><tt class="docutils literal">\PolDecToString{decimal number}</tt></a></h2>
+<span id="poldectostring"></span><h2><a class="toc-backref" href="#id151"><tt class="docutils literal">\PolDecToString{decimal number}</tt></a></h2>
<blockquote>
<p>This is a utility macro to print decimal numbers. It has been
backported to <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> (release <tt class="docutils literal">1.3</tt> of <tt class="docutils literal">2018/03/01</tt>) under
@@ -2035,15 +2411,15 @@ now an alias to it.</p>
and <tt class="docutils literal"><span class="pre">\PolDecToString{123.450e-8}</span></tt> to <tt class="docutils literal">0.00000123450</tt> which
illustrates that trailing zeros are not trimmed. To trim trailing
zeroes, one can use <tt class="docutils literal"><span class="pre">\PolDecToString{\xintREZ{#1}}</span></tt>.</p>
-<p>The exact behaviour of this macro may evolve in future releases of
+<p>The precise behaviour of this macro may evolve in future releases of
<a class="reference external" href="http://www.ctan.org/pkg/xint">xint</a>.</p>
</blockquote>
</div>
</div>
<div class="section" id="booleans-with-default-setting-as-indicated">
-<h1><a class="toc-backref" href="#id132">Booleans (with default setting as indicated)</a></h1>
+<h1><a class="toc-backref" href="#id152">Booleans (with default setting as indicated)</a></h1>
<div class="section" id="xintverbosefalse">
-<h2><a class="toc-backref" href="#id133"><tt class="docutils literal">\xintverbosefalse</tt></a></h2>
+<h2><a class="toc-backref" href="#id153"><tt class="docutils literal">\xintverbosefalse</tt></a></h2>
<blockquote>
<p>This is actually an <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> configuration. Setting it to
<tt class="docutils literal">true</tt> triggers the writing of information to the log when new
@@ -2056,20 +2432,41 @@ unstable and undocumented internal structures.</p>
</blockquote>
</div>
<div class="section" id="poltypesetallfalse">
-<h2><a class="toc-backref" href="#id134"><tt class="docutils literal">\poltypesetallfalse</tt></a></h2>
+<h2><a class="toc-backref" href="#id154"><tt class="docutils literal">\poltypesetallfalse</tt></a></h2>
<blockquote>
If <tt class="docutils literal">true</tt>, <a class="reference internal" href="#poltypeset-polname">\PolTypeset{polname}</a> will also typeset the vanishing
coefficients.</blockquote>
</div>
<div class="section" id="poltoexprallfalse">
-<h2><a class="toc-backref" href="#id135"><tt class="docutils literal">\poltoexprallfalse</tt></a></h2>
+<h2><a class="toc-backref" href="#id155"><tt class="docutils literal">\poltoexprallfalse</tt></a></h2>
<blockquote>
If <tt class="docutils literal">true</tt>, <a class="reference internal" href="#poltoexpr-polname">\PolToExpr{polname}</a> and <a class="reference internal" href="#poltofloatexpr-polname">\PolToFloatExpr{polname}</a> will
also include the vanishing coefficients in their outputs.</blockquote>
</div>
</div>
+<div class="section" id="polexprsetup">
+<h1><a class="toc-backref" href="#id156"><tt class="docutils literal">\polexprsetup</tt></a></h1>
+<blockquote>
+<p>Serves to customize the package. Currently only two keys are
+recognized:</p>
+<ul class="simple">
+<li><tt class="docutils literal">norr</tt>: the postfix that <a class="reference internal" href="#id14">\PolSturmIsolateZeros**{sturmname}</a>
+should append to <tt class="docutils literal">sturmname</tt> to declare the primitive polynomial
+obtained from original one after removal of all rational roots.
+The default value is <tt class="docutils literal">_norr</tt> (standing for “no rational roots”).</li>
+<li><tt class="docutils literal">sqfnorr</tt>: the postfix that <a class="reference internal" href="#id14">\PolSturmIsolateZeros**{sturmname}</a>
+should append to <tt class="docutils literal">sturmname</tt> to declare the primitive polynomial
+obtained from original one after removal of all rational roots and
+suppression of all multiplicities.
+The default value is <tt class="docutils literal">_sqf_norr</tt> (standing for “square-free with
+no rational roots”).</li>
+</ul>
+<p>The package executes <tt class="docutils literal">\polexprsetup{norr=_norr,
+sqfnorr=_sqf_norr}</tt> as default.</p>
+</blockquote>
+</div>
<div class="section" id="technicalities">
-<h1><a class="toc-backref" href="#id136">Technicalities</a></h1>
+<h1><a class="toc-backref" href="#id157">Technicalities</a></h1>
<ul>
<li><p class="first">The catcode of the semi-colon is reset temporarily by <a class="reference internal" href="#poldef">\poldef</a> macro in case some other package (for example the French
babel module) may have made it active. This will fail though if the
@@ -2078,7 +2475,7 @@ can use <a class="reference internal" href="#id2">\PolDef{f}{P(x)}</a>
rather. The colon in <tt class="docutils literal">:=</tt> may be active with no consequences.</p>
</li>
<li><p class="first">As a consequence of <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> addition and subtraction always using
-least common multiples for the denominators <a class="footnote-reference" href="#id35" id="id34">[5]</a>, user-chosen common
+least common multiples for the denominators <a class="footnote-reference" href="#id37" id="id36">[5]</a>, user-chosen common
denominators survive additions and multiplications. For example, this:</p>
<pre class="literal-block">
\poldef P(x):= 1/2 + 2/2*x + 3/2*x^3 + 4/2*x^4;
@@ -2094,10 +2491,10 @@ denominators survive additions and multiplications. For example, this:</p>
default) it recognizes and filters out coefficients equal to one or
minus one (since release <tt class="docutils literal">0.3</tt>). One can use for example
<tt class="docutils literal">\PolToCSV{PQ}</tt> to see the internally stored coefficients.</p>
-<table class="docutils footnote" frame="void" id="id35" rules="none">
+<table class="docutils footnote" frame="void" id="id37" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
-<tr><td class="label"><a class="fn-backref" href="#id34">[5]</a></td><td><p class="first last">prior to <tt class="docutils literal">0.4.1</tt>, <tt class="docutils literal">polexpr</tt> used to temporarily patch
+<tr><td class="label"><a class="fn-backref" href="#id36">[5]</a></td><td><p class="first last">prior to <tt class="docutils literal">0.4.1</tt>, <tt class="docutils literal">polexpr</tt> used to temporarily patch
during the parsing of polynomials the <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> macros. This
patch was backported to <a class="reference external" href="http://www.ctan.org/pkg/xint">xint</a> at release <tt class="docutils literal">1.3</tt>.</p>
</td></tr>
@@ -2126,7 +2523,7 @@ documented and unstable. Don't use them.</p>
</ul>
</div>
<div class="section" id="change-log">
-<h1><a class="toc-backref" href="#id137">CHANGE LOG</a></h1>
+<h1><a class="toc-backref" href="#id158">CHANGE LOG</a></h1>
<ul>
<li><p class="first">v0.1 (2018/01/11): initial release. Features:</p>
<ul class="simple">
@@ -2166,7 +2563,7 @@ using expressions in the second argument.</p>
<ul class="simple">
<li><a class="reference internal" href="#poltoexpr">\PolToExpr</a> now by default uses <em>descending</em>
powers (it also treats differently coefficients equal to 1 or -1.)
-Use <a class="reference internal" href="#id26">\PolToExpr*</a> for <em>ascending</em> powers.</li>
+Use <a class="reference internal" href="#id30">\PolToExpr*</a> for <em>ascending</em> powers.</li>
<li><a class="reference internal" href="#polevalat">\PolEval</a> reduced the output to smallest terms,
but as this is costly with big fractions and not needed if e.g.
wrapped in an <tt class="docutils literal">\xintRound</tt> or <tt class="docutils literal">\xintFloat</tt>, this step has been
@@ -2183,7 +2580,7 @@ removed; the former meaning is available as <a class="reference internal" href="
<li><a class="reference internal" href="#poltoexproneterm">\PolToExprOneTerm</a></li>
<li><a class="reference internal" href="#poltofloatexproneterm">\PolToFloatExprOneTerm</a></li>
<li><a class="reference internal" href="#poltoexprcmd">\PolToExprCmd</a></li>
-<li><a class="reference internal" href="#id29">\PolToFloatExprCmd</a></li>
+<li><a class="reference internal" href="#id33">\PolToFloatExprCmd</a></li>
<li><a class="reference internal" href="#poltoexprtermprefix">\PolToExprTermPrefix</a></li>
<li><a class="reference internal" href="#poltoexprvar">\PolToExprVar</a></li>
<li><a class="reference internal" href="#poltoexprtimes">\PolToExprTimes</a></li>
@@ -2268,7 +2665,7 @@ they actually make pre-existing such variant undefined.</p>
<li><a class="reference internal" href="#polprintintervalsprintexactzero">\PolPrintIntervalsPrintExactZero</a></li>
<li><a class="reference internal" href="#polprintintervalsprintleftendpoint">\PolPrintIntervalsPrintLeftEndPoint</a></li>
<li><a class="reference internal" href="#polprintintervalsprintrightendpoint">\PolPrintIntervalsPrintRightEndPoint</a></li>
-<li><a class="reference internal" href="#id16">\PolReduceCoeffs*</a></li>
+<li><a class="reference internal" href="#id20">\PolReduceCoeffs*</a></li>
<li><a class="reference internal" href="#polmakemonic">\PolMakeMonic</a></li>
</ul>
</li>
@@ -2282,11 +2679,11 @@ they actually make pre-existing such variant undefined.</p>
<li><a class="reference internal" href="#polsturmifzeroexactlyknown">\PolSturmIfZeroExactlyKnown</a></li>
<li><a class="reference internal" href="#polsturmisolatedzeroleft">\PolSturmIsolatedZeroLeft</a></li>
<li><a class="reference internal" href="#polsturmisolatedzeroright">\PolSturmIsolatedZeroRight</a></li>
-<li><a class="reference internal" href="#polprintintervalstheendpoint">\PolPrintIntervalsTheEndPoint</a></li>
+<li><tt class="docutils literal">\PolPrintIntervalsTheEndPoint</tt> (removed at 0.7)</li>
<li><a class="reference internal" href="#polprintintervalstheindex">\PolPrintIntervalsTheIndex</a></li>
-<li><a class="reference internal" href="#polifendpointispositive">\PolIfEndPointIsPositive</a></li>
-<li><a class="reference internal" href="#polifendpointisnegative">\PolIfEndPointIsNegative</a></li>
-<li><a class="reference internal" href="#polifendpointiszero">\PolIfEndPointIsZero</a></li>
+<li><tt class="docutils literal">\PolIfEndPointIsPositive</tt> (removed at 0.7)</li>
+<li><tt class="docutils literal">\PolIfEndPointIsNegative</tt> (removed at 0.7)</li>
+<li><tt class="docutils literal">\PolIfEndPointIsZero</tt> (removed at 0.7)</li>
<li><a class="reference internal" href="#polintervalwidth">\PolIntervalWidth</a></li>
<li><a class="reference internal" href="#poldectostring">\PolDecToString</a></li>
</ul>
@@ -2371,15 +2768,65 @@ acts like the <a class="reference internal" href="#polsturmisolatezeros">non-sta
</li>
</ul>
</li>
+<li><p class="first">v0.7 (2018/12/08)</p>
+<ul class="simple">
+<li>breaking changes:<ul>
+<li>although <a class="reference internal" href="#polprintintervals-varname-sturmname">\PolPrintIntervals[varname]{sturmname}</a> default output
+remains the same, some auxiliary macros for user-customization
+have been removed: <tt class="docutils literal">\PolPrintIntervalsTheEndPoint</tt>,
+<tt class="docutils literal"><span class="pre">\PolIfEndPointIsPositive{A}{B}</span></tt>,
+<tt class="docutils literal"><span class="pre">\PolIfEndPointIsNegative{A}{B}</span></tt>, and
+<tt class="docutils literal"><span class="pre">\PolIfEndPointIsZero{A}{B}</span></tt>.</li>
+</ul>
+</li>
+<li>bugfix:<ul>
+<li>it could happen that, contrarily to documentation, an interval
+computed by <a class="reference internal" href="#polsturmisolatezeros-sturmname">\PolSturmIsolateZeros{sturmname}</a> had zero as an
+endpoint,</li>
+<li><a class="reference internal" href="#polensureintervallength-sturmname-index-e">\PolEnsureIntervalLength{sturmname}{index}{E}</a> could under
+certain circumstances erroneously replace a non-zero root by
+zero,</li>
+<li><a class="reference internal" href="#polensureintervallengths-sturmname-e">\PolEnsureIntervalLengths{sturmname}{E}</a> crashed when used with
+a polynomial with no real roots, hence for which no isolation intervals
+existed (thanks to Thomas Söll for report).</li>
+</ul>
+</li>
+<li>new macros:<ul>
+<li><a class="reference internal" href="#id14">\PolSturmIsolateZeros**{sturmname}</a></li>
+<li><a class="reference internal" href="#polsturmisolatezerosgetmultiplicitiesandrationalroots-sturmname">\PolSturmIsolateZerosGetMultiplicitiesAndRationalRoots{sturmname}</a></li>
+<li><a class="reference internal" href="#polsturmisolatezerosandfindrationalroots-sturmname">\PolSturmIsolateZerosAndFindRationalRoots{sturmname}</a></li>
+<li><a class="reference internal" href="#polexprsetup">\polexprsetup</a></li>
+<li><a class="reference internal" href="#id18">\PolPrintIntervals*</a></li>
+<li><a class="reference internal" href="#polprintintervalsnorealroots">\PolPrintIntervalsNoRealRoots</a></li>
+<li><a class="reference internal" href="#polprintintervalsbeginenv">\PolPrintIntervalsBeginEnv</a></li>
+<li><a class="reference internal" href="#polprintintervalsendenv">\PolPrintIntervalsEndEnv</a></li>
+<li><a class="reference internal" href="#polprintintervalsknownroot">\PolPrintIntervalsKnownRoot</a></li>
+<li><a class="reference internal" href="#polprintintervalsunknownroot">\PolPrintIntervalsUnknownRoot</a></li>
+<li><a class="reference internal" href="#polprintintervalsprintmultiplicity">\PolPrintIntervalsPrintMultiplicity</a></li>
+</ul>
+</li>
+<li>new expandable macros:<ul>
+<li><a class="reference internal" href="#polsturmnbofrationalroots-sturmname">\PolSturmNbOfRationalRoots{sturmname}</a></li>
+<li><a class="reference internal" href="#polsturmnbofrationalrootswithmultiplicities-sturmname">\PolSturmNbOfRationalRootsWithMultiplicities{sturmname}</a></li>
+<li><a class="reference internal" href="#polsturmrationalroot-sturmname-k">\PolSturmRationalRoot{sturmname}{k}</a></li>
+<li><a class="reference internal" href="#polsturmrationalrootindex-sturmname-k">\PolSturmRationalRootIndex{sturmname}{k}</a></li>
+<li><a class="reference internal" href="#polsturmrationalrootmultiplicity-sturmname-k">\PolSturmRationalRootMultiplicity{sturmname}{k}</a></li>
+<li><a class="reference internal" href="#polprintintervalsthevar">\PolPrintIntervalsTheVar</a></li>
+<li><a class="reference internal" href="#polprintintervalsthesturmname">\PolPrintIntervalsTheSturmName</a></li>
+<li><a class="reference internal" href="#polprintintervalsthemultiplicity">\PolPrintIntervalsTheMultiplicity</a></li>
+</ul>
+</li>
+</ul>
+</li>
</ul>
</div>
<div class="section" id="acknowledgments">
-<h1><a class="toc-backref" href="#id138">Acknowledgments</a></h1>
+<h1><a class="toc-backref" href="#id159">Acknowledgments</a></h1>
<p>Thanks to Jürgen Gilg whose question about <a class="reference external" href="http://www.ctan.org/pkg/xint">xint</a> usage for
differentiating polynomials was the initial trigger leading to this
package, and to Jürgen Gilg and Thomas Söll for testing it on some
concrete problems.</p>
-<p>Renewed thanks to them on occasion of the <tt class="docutils literal">0.6</tt> release for their
+<p>Renewed thanks to them on occasion of the <tt class="docutils literal">0.6</tt> and <tt class="docutils literal">0.7</tt> releases for their
continued interest.</p>
<p>See README.md for the License.</p>
</div>
diff --git a/Master/texmf-dist/doc/latex/polexpr/polexpr.txt b/Master/texmf-dist/doc/latex/polexpr/polexpr.txt
index da2cbb77790..51008763dcf 100644
--- a/Master/texmf-dist/doc/latex/polexpr/polexpr.txt
+++ b/Master/texmf-dist/doc/latex/polexpr/polexpr.txt
@@ -4,13 +4,13 @@
Package polexpr documentation
===============================
-0.6 (2018/11/20)
+0.7 (2018/12/08)
================
.. contents::
-Basic Examples
---------------
+Basic syntax
+------------
The syntax is::
@@ -161,18 +161,13 @@ Examples of localization of roots
- For extra info in log file use ``\xintverbosetrue``.
-- To make producing this documentation simpler, the results from execution
- of the code snippets are not included. Please try them out yourself...
+- Only for some of these examples is the output included here.
A typical example
~~~~~~~~~~~~~~~~~
-In this example the polynomial is square-free; we can make sure of that by
-comparing the degree of the first element of the Sturm chain with the
-degree of the original polynomial. In such case the second element of
-the Sturm chain is still the polynomial first derivative, because there
-was no further reduction.
+In this example the polynomial is square-free.
::
@@ -190,11 +185,11 @@ was no further reduction.
\PolEnsureIntervalLength{f}{1}{-20}
\[\PolSturmIsolatedZeroLeft{f}{1}<Z_1<\PolSturmIsolatedZeroRight{f}{1}\]
The first element of the Sturm chain has degree $\PolDegree{f_0}$. As
- this same as $\PolDegree{f}$ we know that the latter was square free.
- So the derivative is up to a constant \PolTypeset{f_1} (in fact here
+ this is the original degreee $\PolDegree{f}$ we know that $f$ is square free.
+ Its derivative is up to a constant \PolTypeset{f_1} (in this example
it is identical with it).
\PolToSturm{f_1}{f_1}\PolSturmIsolateZeros{f_1}%
- It has \PolSturmNbOfIsolatedZeros{f_1} distinct real
+ The derivative has \PolSturmNbOfIsolatedZeros{f_1} distinct real
roots:
\PolPrintIntervals[W]{f_1}
\PolEnsureIntervalLengths{f_1}{-10}%
@@ -216,6 +211,13 @@ was no further reduction.
A degree four polynomial with nearby roots
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Notice that this example is a bit outdated as ``0.7`` release has
+added ``\PolSturmIsolateZeros**{sturmname}`` which would find exactly
+the roots. The steps here retain their interest when one is interested
+in finding isolating intervals for example to prepare some demonstration
+of dichotomy method.
+
+
::
\PolDef{Q}{(x-1.050001)(x-1.105001)(x-1.110501)(x-1.111051)}
@@ -273,11 +275,10 @@ In this example, the output will look like this (but using math mode)::
The multiplicity is 3 at the root x = 0.999
The multiplicity is 3 at the root x = 0.9999
-On first pass, these rational roots were found. But multiplicity
-computation works also with (decimal) roots not yet identified or with
-non-decimal or irrational roots.
-
-Try it out!
+On first pass, these rational roots were found (due to their relative
+magnitudes, using ``\PolSturmIsolateZeros**`` was not needed here). But
+multiplicity computation works also with (decimal) roots not yet
+identified or with non-decimal or irrational roots.
It is fun to modify only a tiny bit the polynomial and see if polexpr
survives::
@@ -313,7 +314,46 @@ which produces::
The multiplicity is 1 for the root such that 0.9991447980 < x < 0.9991447981
The multiplicity is 1 for the root such that 0.9997663986 < x < 0.9997663987
-Try obtaining this with your pocket calculator! (or IEEE-7554 numerics...)
+A degree five polynomial with three rational roots
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ \poldef Q(x) := 1581755751184441 x^5
+ -14907697165025339 x^4
+ +48415668972339336 x^3
+ -63952057791306264 x^2
+ +46833913221154895 x
+ -49044360626280925;
+
+ \PolToSturm{Q}{Q}
+ %\begin{flushleft}
+ \renewcommand\PolTypesetCmdPrefix[1]{\allowbreak\xintiiifSgn{#1}{}{+}{+}}%
+ $Q_0(x) = \PolTypeset{Q_0}$
+ %\end{flushleft}
+ \PolSturmIsolateZeros**{Q}
+ \PolPrintIntervals{Q}
+
+ $Q_norr(x) = \PolTypeset{Q_norr}$
+
+Here, all real roots are rational::
+
+ Z_1 = 833719/265381
+ Z_2 = 165707065/52746197
+ Z_3 = 355/113
+
+ Q_norr(x) = x^2 + 1
+
+And let's get their decimal expansion too::
+
+ % print decimal expansion of the found roots
+ \renewcommand\PolPrintIntervalsPrintExactZero
+ {\xintTrunc{20}{\PolPrintIntervalsTheLeftEndPoint}\dots}
+ \PolPrintIntervals{Q}
+
+ Z_1 = 3.14159265358107777120...
+ Z_2 = 3.14159265358979340254...
+ Z_3 = 3.14159292035398230088...
A Mignotte type polynomial
@@ -344,6 +384,93 @@ The last line produces::
0.09999900004999650028 < Z_2 < 0.09999900004999650029
+
+The Wilkinson polynomial
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+See `Wilkinson polynomial`_.
+
+::
+
+ \documentclass{article}
+ \usepackage{polexpr}
+ \begin{document}
+ %\xintverbosetrue % for the curious...
+
+ \poldef f(x) := mul((x - i), i = 1..20);
+
+ \renewcommand\PolTypesetCmdPrefix[1]{\allowbreak\xintiiifSgn{#1}{}{+}{+}}%
+ \renewcommand\PolTypesetOne[1]{\xintDecToString{#1}}%
+
+ \noindent\PolTypeset{f}
+
+ \PolToSturm{f}{f}
+ \PolSturmIsolateZeros{f}
+ \PolPrintIntervals{f}
+
+ \clearpage
+
+ \poldef g(x) := f(x) - 2**{-23} x**19;
+
+ % be patient!
+ \PolToSturm{g}{g}
+ \noindent\PolTypeset{g_0}% integer coefficient primitive polynomial
+
+ \PolSturmIsolateZeros{g}
+ \PolEnsureIntervalLengths{g}{-10}
+
+ \renewcommand\PolPrintIntervalsPrintMultiplicity{}
+ \PolPrintIntervals*{g}
+
+ \end{document}
+
+
+The first polynomial::
+
+ f(x) = x**20
+ - 210 x**19
+ + 20615 x**18
+ - 1256850 x**17
+ + 53327946 x**16
+ - 1672280820 x**15
+ + 40171771630 x**14
+ - 756111184500 x**13
+ + 11310276995381 x**12
+ - 135585182899530 x**11
+ + 1307535010540395 x**10
+ - 10142299865511450 x**9
+ + 63030812099294896 x**8
+ - 311333643161390640 x**7
+ + 1206647803780373360 x**6
+ - 3599979517947607200 x**5
+ + 8037811822645051776 x**4
+ - 12870931245150988800 x**3
+ + 13803759753640704000 x**2
+ - 8752948036761600000 x
+ + 2432902008176640000
+
+is handled fast enough (a few seconds), but the modified one ``f(x) -
+2**-23 x**19`` takes about 20x longer (the Sturm chain polynomials
+have integer coefficients with up to 321 digits, whereas (surprisingly
+perhaps) those of the Sturm chain polynomials derived from ``f`` never
+have more than 21 digits ...).
+
+Once the Sturm chain is computed and the zeros isolated, obtaining their
+decimal digits is relatively faster. Here is for the ten real roots of
+``f(x) - 2**-23 x**19`` as computed by the code above::
+
+ Z_1 = 0.9999999999...
+ Z_2 = 2.0000000000...
+ Z_3 = 2.9999999999...
+ Z_4 = 4.0000000002...
+ Z_5 = 4.9999999275...
+ Z_6 = 6.0000069439...
+ Z_7 = 6.9996972339...
+ Z_8 = 8.0072676034...
+ Z_9 = 8.9172502485...
+ Z_10 = 20.8469081014...
+
+
The degree 41 polynomial with -2, -1.9, -1.8, ..., 0, 0.1, ..., 1.9, 2 as roots
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -391,23 +518,23 @@ Stress test: not a hard challenge to ``xint + polexpr``, but be a bit patient!
\PolDef{P}{mul((x-i*1e-1), i=-20..20)}%
\PolToSturm{P}{S} % dutifully computes S_0, ..., S_{41}
+ % the [1] optional argument limits the search to interval (-10,10)
\PolSturmIsolateZeros[1]{S} % finds *exactly* (but a bit slowly) all 41 roots!
\PolPrintIntervals{S} % nice, isn't it?
.. note::
- Release ``0.5`` has experimental addition of optional argument
+ Release ``0.5`` has *experimental* addition of optional argument
``E`` to ``\PolSturmIsolateZeros``. It instructs to search roots only
- in interval ``(-10^E, 10^E)``, extremities assumed to not be roots.
- Thus here::
-
- \PolSturmIsolateZeros[1]{S}
-
- gives some speed gain; without it, it turns out in this case that
- ``polexpr`` would have started with ``(-10^6, 10^6)`` interval.
+ in interval ``(-10^E, 10^E)``. Important: the extremities are
+ *assumed to not be roots*. In this example, the ``[1]`` in
+ ``\PolSturmIsolateZeros[1]{S}`` gives some speed gain; without it, it
+ turns out in this case that ``polexpr`` would have started with
+ ``(-10^6, 10^6)`` interval.
- This will probably get replaced in future by the specification of
- a general interval.
+ Please note that this will probably get replaced in future by the
+ specification of a general interval. Do not rely on meaning of this
+ optional argument keeping the same.
Roots of Chebyshev polynomials
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -584,18 +711,18 @@ Non-expandable macros
``\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 constant term being the first item. No validity checks. Spaces
- from the list argument are trimmed. List items are each expanded in
- an ``\edef`` and then put into normalized form via xintfrac_\ 's
- macro ``\xintRaw``.
+ 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``.
- Leading zero coefficients are removed::
+ As leading zero coefficients are removed::
\PolFromCSV{f}{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- defines the zero polynomial, which has only one (zero) coefficient.
+ defines the zero polynomial, which holds only one coefficient.
See also expandable macro `\\PolToCSV <\\PolToCSV{polname}_>`_.
@@ -825,15 +952,18 @@ Non-expandable macros
polynomials too, i.e. with integer coefficients having no common factor.
Thus ``sturmname_0`` has exactly the same real and complex roots as
- polynomial ``polname``, but with each root now of multiplicity one.
+ polynomial ``polname``, but with each root now of multiplicity one:
+ i.e. it is the "square-free part" of original polynomial ``polname``.
Notice that ``sturmname_1`` isn't necessarily the derivative of
``sturmname_0`` due to the various normalizations.
- These polynomials ``sturmname_k`` (contrarily to the
- ``sturmname_k_`` ones) are usable after the macro execution but
- their main utility is for the execution of
- `\\PolSturmIsolateZeros{sturmname}`_.
+ The polynomials ``sturmname_k`` main utility is for the execution of
+ `\\PolSturmIsolateZeros{sturmname}`_. Be careful not to use these
+ names ``sturmname_0``, ``sturmname_1``, etc... for defining other
+ polynomials after having done ``\PolToSturm{polname}{sturmname} and
+ before executing ``\PolSturmIsolateZeros{sturmname}`` else the
+ latter will behave erroneously.
`\\PolSturmChainLength{sturmname}`_ gives the index of the last
element of the Sturm chain.
@@ -853,6 +983,16 @@ Non-expandable macros
This behaviour was modified at ``0.6``, anyhow the macro was
broken at ``0.5``.
+ .. hint::
+
+ The square-free part of ``polname`` is ``sturmname_0``, and their
+ quotient is the polynomial with name
+ ``sturname_\PolSturmChainLength{sturmname}_``. It thus easy to
+ set-up a loop iteratively computing the latter until the last one
+ is a constant, thus obtaining the decomposition of an ``f`` as
+ a product ``c f_1 f_2 f_3 ...`` of a constant and square-free (primitive)
+ polynomials, where each ``f_i`` divides its predecessor.
+
.. _PolSetToSturmChainSignChangesAt:
``\PolSetToSturmChainSignChangesAt{\macro}{sturmname}{fraction}``
@@ -913,10 +1053,10 @@ Non-expandable macros
``\PolSturmIsolateZeros{sturmname}``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- First, it evaluates using `Sturm theorem`_ the number of distinct
- real roots of ``sturmname_0``.
+ The macros locates, using `Sturm theorem`_, as many disjoint
+ intervals as there are (real) roots.
- .. note::
+ .. important::
The Sturm chain must have been produced by an earlier
`\\PolToSturm{polname}{sturmname}`_.
@@ -935,23 +1075,42 @@ Non-expandable macros
to ``\PolToSturm`` must have been made at any rate for
``\PolSturmIsolateZeros`` to be usable.
- Then it locates, again using `Sturm theorem`_, as many disjoint
- intervals as there are roots. Some intervals reduce to singleton
- which are roots. Non-singleton intervals get refined to make sure
- none of their two limit points is a root: they contain each a single
- root, in their respective interiors.
+ After its execution they are two types of such intervals (stored in
+ memory and accessible via macros or xintexpr_ variables, see below):
- .. This procedure is covariant
- with the independent variable ``x`` becoming ``-x``.
- Hmm, pas sûr et trop fatigué
+ - 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)``; if zero is a root it is always
- identified individually. The non-singleton intervals are of the
+ ``(-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 ``a`` and ``a+1`` are both positive
- or both negative.
+ neither ``0`` nor ``-1``. Hence either ``a`` and ``a+1`` are both positive
+ or they are both negative.
+
+ One does not *a priori* know what will be the lengths of these
+ intervals (except that they are always powers of ten), they
+ vary depending on how many digits two successive roots have in
+ common in their respective decimal expansions.
+
+ .. important::
+
+ If some two consecutive intervals share an end-point, no
+ information is yet gained about the separation between the two
+ roots which could at this stage be arbitrarily small.
+
+ See `\\PolRefineInterval*{sturmname}{index}`_ which addresses
+ this issue.
+
+ .. This procedure is covariant
+ with the independent variable ``x`` becoming ``-x``.
+ Hmm, pas sûr et trop fatigué
The interval boundaries (and exactly found roots) are made available
for future computations in ``\xintexpr``-essions or polynomial
@@ -960,26 +1119,27 @@ Non-expandable macros
``<sturmname>R_1``, ``<sturmname>R_2``, ..., for the right
end-points.
- Also two macro arrays (in the sense of
- xinttools_'s ``\xintAssignArray``) are created for holding the
- interval end-points written out in standard decimal notation
- (see `\\PolDecToString{decimal number}`_).
- To access these values, macros
- `\\PolSturmIsolatedZeroLeft{sturmname}{index}`_ and
- `\\PolSturmIsolatedZeroRight{sturmname}{index}`_ are provided.
+ Thus for example, if ``sturmname`` is ``f``, one can use the
+ xintexpr_ variables ``fL_1``, ``fL_2``, ... to refer in expressions
+ to the left end-points (or to the exact root, if left and right end
+ points coincide). Additionally, xintexpr_ variable ``fZ_1_isknown``
+ will have value ``1`` if the root in the first interval is known,
+ and ``0`` otherwise. And similarly for the other intervals.
- .. important::
+ Also, macros `\\PolSturmIsolatedZeroLeft{sturmname}{index}`_ and
+ `\\PolSturmIsolatedZeroRight{sturmname}{index}`_ are provided which
+ expand to these same values, written in decimal notation (i.e.
+ pre-processed by `\\PolDecToString <PolDecToString_>`_.) And there
+ is also `\\PolSturmIfZeroExactlyKnown{sturmname}{index}{A}{B}`_.
- Trailing zeroes in these stored decimal numbers are significant:
- they are also present in the decimal expansion of the exact root.
+ .. important::
- .. note::
+ 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.
- The actual array macros are ``\POL_ZeroInt<sturmname>L`` and
- ``\POL_ZeroInt<sturmname>R`` but as these names use the
- non-letter character ``_`` and possibly also digits from
- ``sturmname``, the accessor macros above have been made part of
- the package.
+ These variables and macros are automatically updated when one next
+ uses macros such as `\\PolRefineInterval*{sturmname}{index}`_.
The start of decimal expansion of a positive ``k``-th root is given
by `\\PolSturmIsolatedZeroLeft{sturmname}{k}
@@ -992,25 +1152,20 @@ Non-expandable macros
`\\PolSturmNbOfIsolatedZeros{sturmname}`_.
Furthermore
- `\\PolSturmNbOfRootsOf{sturmname}\\LessThanOrEqualTo{value}`_
- and
+ `\\PolSturmNbOfRootsOf{sturmname}\\LessThanOrEqualTo{value}`_ and
`\\PolSturmNbOfRootsOf{sturmname}\\LessThanOrEqualToExpr{expression}`_.
- will expandably act as their names indicate.
+ will expandably compute respectively the number of real roots at
+ most equal to ``value`` or ``expression``, and the same but with
+ multiplicities.
.. note::
- In the current implementation the ``<sturmname>...`` xintexpr_ variables
- and the ``\POL_ZeroInt...`` arrays are globally defined. On the
+ In the current implementation the xintexpr_ variables
+ and xinttools_ arrays are globally defined. On the
other hand the Sturm sequence polynomials obey the current scope.
.. note::
- When two successive roots are located in adjacent intervals, the
- separation between them is not lower bounded. See
- `\\PolRefineInterval*{sturmname}{index}`_.
-
- .. note::
-
As all computations are done *exactly* there can be no errors...
apart those due to bad coding by author. The results are exact
bounds for the mathematically exact real roots.
@@ -1036,9 +1191,9 @@ Non-expandable macros
interval (intervals are enumerated from left to right, with index
starting at ``1``).
- Also, the
- `\\PolSturmNbWithMultOfRootsOf{sturmname}\\LessThanOrEqualTo{value}`_
- will be operant.
+ Furthermore, if for example the ``sturmname`` is ``f``, xintexpr_
+ variables ``fM_1``, ``fM_2``... hold the multiplicities thus
+ computed.
.. note::
@@ -1049,7 +1204,36 @@ Non-expandable macros
genuine polynomials.
See `The degree nine polynomial with 0.99, 0.999, 0.9999 as triple
- roots`_ for an example of use.
+ roots`_ for an example.
+
+.. _PolSturmIsolateZeros**:
+
+``\PolSturmIsolateZeros**{sturmname}``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ The macro does the same as `\\PolSturmIsolateZeros*{sturmname}`_ and
+ in addition it does the extra work to determine all the *rational*
+ roots.
+
+ .. note::
+
+ After execution of this macro, a root is "known" if and only if
+ it is rational.
+
+ Furthermore, primitive polynomial ``sturmname_sqf_norr`` is created
+ to match the (square-free) ``sturmname_0`` from which all rational
+ roots have been removed (see `\\polexprsetup`_ for customizing this
+ name). The number of distinct rational roots is thus the difference
+ between the degrees of these two polynomials (see also
+ `\\PolSturmNbOfRationalRoots{sturmname}`_).
+
+ And ``sturmname_norr`` is ``sturmname_0_`` from which all rational
+ roots have been removed (see `\\polexprsetup`_), i.e. it contains
+ the irrational roots of the original polynomial, with the same
+ multiplicities.
+
+ See `A degree five polynomial with three rational
+ roots`_ for an example.
.. _PolSturmIsolateZerosAndGetMultiplicities:
@@ -1058,8 +1242,44 @@ Non-expandable macros
This is another name for `\\PolSturmIsolateZeros*{sturmname}`_.
- See `The degree nine polynomial with 0.99, 0.999, 0.9999 as triple
- roots`_ for an example of use.
+.. _PolSturmIsolateZerosGetMultiplicitiesAndRationalRoots:
+
+``\PolSturmIsolateZerosGetMultiplicitiesAndRationalRoots{sturmname}``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ This is another name for `\\PolSturmIsolateZeros**{sturmname}`_.
+
+
+``\PolSturmIsolateZerosAndFindRationalRoots{sturmname}``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ This works exactly like `\\PolSturmIsolateZeros**{sturmname}`_
+ (inclusive of declaring the polynomials ``sturmname_sqf_norr`` and
+ ``sturmname_norr`` with no rational roots) except that it does *not*
+ compute the multiplicities of the *non-rational* roots.
+
+ .. note::
+
+ There is no macro to find the rational roots but not compute
+ their multiplicities at the same time.
+
+ .. attention::
+
+ This macro does *not* define xintexpr_ variables
+ ``sturmnameM_1``, ``sturmnameM_2``, ... holding the
+ multiplicities and it leaves the multiplicity array (whose accessor
+ is `\\PolSturmIsolatedZeroMultiplicity{sturmname}{index}`_) into
+ a broken state, as all non-rational roots will supposedly have
+ multiplicity one. This means that the output of
+ `\\PolPrintIntervals* <PolPrintIntervals*_>`_ for example will be
+ erroneous for the intervals with irrational roots.
+
+ I decided to document it because finding multiplicities of the
+ non rational roots is somewhat costly, and one may be interested
+ only into finding the rational roots (of course random
+ polynomials with integer coefficients will not have *any*
+ rational root anyhow).
+
.. _PolRefineInterval*:
@@ -1110,40 +1330,73 @@ Non-expandable macros
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 in a
+ 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. The user is invited to renewcommand the macro if some other
- type of tabular environment for example is wanted.
+ exactly.
- In each array cell the corresponding interval end-point (which may
- be an exactly known root) is available as macro
- `\\PolPrintIntervalsTheEndPoint`_ (in decimal notation). And the
- corresponding interval index is available as
- `\\PolPrintIntervalsTheIndex`_.
+ .. attention::
+
+ This macro was refactored at 0.7, its default output remained
+ identical but the ways to customize it got completely
+ modified.
+
+ See next macros which govern its output.
+
+``\PolPrintIntervalsNoRealRoots``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ Executed in place of an ``array`` environment, when there are no
+ real roots. Default definition::
+
+ \newcommand\PolPrintIntervalsNoRealRoots{}
+
+``\PolPrintIntervalsBeginEnv``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ Default definition::
+
+ \newcommand\PolPrintIntervalsBeginEnv{\[\begin{array}{rcccl}}
+
+``\PolPrintIntervalsEndEnv``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ Default definition::
+
+ \newcommand\PolPrintIntervalsEndEnv{\end{array}\]}
+
+``\PolPrintIntervalsKnownRoot``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ Default definition::
+
+ \newcommand\PolPrintIntervalsKnownRoot{%
+ &&\PolPrintIntervalsTheVar_{\PolPrintIntervalsTheIndex}%
+ &=&\PolPrintIntervalsPrintExactZero
+ }
+
+``\PolPrintIntervalsUnknownRoot``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ Default definition::
+
+ \newcommand\PolPrintIntervalsUnknownRoot{%
+ \PolPrintIntervalsPrintLeftEndPoint&<&%
+ \PolPrintIntervalsTheVar_{\PolPrintIntervalsTheIndex}&<&%
+ \PolPrintIntervalsPrintRightEndPoint
+ }
- These values may be tested to decide some on-the-fly customization
- (color for example), via the following auxiliaries which can be
- modified by user. Furthermore these auxiliaries can also use the
- following conditionals: `\\PolIfEndPointIsPositive{A}{B}`_,
- `\\PolIfEndPointIsNegative{A}{B}`_, `\\PolIfEndPointIsZero{A}{B}`_.
.. _PolPrintIntervalsPrintExactZero:
``\PolPrintIntervalsPrintExactZero``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- This is provided to help customize how an exactly known root is
- printed in the right most column of the array. The package
- definition is::
- \newcommand\PolPrintIntervalsPrintExactZero{\PolPrintIntervalsTheEndPoint}%
+ Default definition::
- Recall that this is expanded in an array cell.
-
- If for example you want to print in red the third root, known
- exactly, the macro could make a test for the value of
- `\\PolPrintIntervalsTheIndex`_ and act accordingly.
+ \newcommand\PolPrintIntervalsPrintExactZero{\PolPrintIntervalsTheLeftEndPoint}
.. _PolPrintIntervalsPrintLeftEndPoint:
@@ -1151,18 +1404,48 @@ Non-expandable macros
``\PolPrintIntervalsPrintLeftEndPoint``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Package definition is::
+ Default definition::
- \newcommand\PolPrintIntervalsPrintLeftEndPoint{\PolPrintIntervalsTheEndPoint}%
+ \newcommand\PolPrintIntervalsPrintLeftEndPoint{\PolPrintIntervalsTheLeftEndPoint}
.. _PolPrintIntervalsPrintRightEndPoint:
``\PolPrintIntervalsPrintRightEndPoint``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Package definition is::
+ Default definition is::
+
+ \newcommand\PolPrintIntervalsPrintRightEndPoint{\PolPrintIntervalsTheRightEndPoint}
+
+.. _PolPrintIntervals*:
+
+``\PolPrintIntervals*[varname]{sturmname}``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ This starred variant produces an alternative output (which
+ displays the root multiplicity), and is provided as an
+ example of customization.
+
+ As replacement for `\\PolPrintIntervalsKnownRoot`_,
+ `\\PolPrintIntervalsPrintExactZero`_,
+ `\\PolPrintIntervalsUnknownRoot`_ it uses its own
+ ``\POL@@PrintIntervals...`` macros. We only reproduce here one
+ definition::
+
+ \newcommand\POL@@PrintIntervalsPrintExactZero{%
+ \displaystyle
+ \xintSignedFrac{\PolPrintIntervalsTheLeftEndPoint}%
+ }%
+
+ Multiplicities are printed using this auxiliary macro:
+
+``\PolPrintIntervalsPrintMultiplicity``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ whose default definition is::
+
+ \newcommand\PolPrintIntervalsPrintMultiplicity{(\mbox{mult. }\PolPrintIntervalsTheMultiplicity)}
- \newcommand\PolPrintIntervalsPrintRightEndPoint{\PolPrintIntervalsTheEndPoint}%
.. _PolMapCoeffs:
@@ -1549,8 +1832,9 @@ and ``\PolToFloatExpr`` (and their auxiliaries) which need a
``\PolToList{polname}``
~~~~~~~~~~~~~~~~~~~~~~~
- Expands to ``{coeff_0}{coeff_1}...{coeff_N}`` with ``N`` = degree
- (except zero polynomial which does give ``{0/1[0]}`` and not an
+ 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:
@@ -1558,7 +1842,8 @@ and ``\PolToFloatExpr`` (and their auxiliaries) which need a
``\PolToCSV{polname}``
~~~~~~~~~~~~~~~~~~~~~~
- Expands to ``coeff_0, coeff_1, coeff_2, ....., coeff_N``. Converse
+ Expands to ``coeff_0, coeff_1, coeff_2, ....., coeff_N``, starting
+ with constant term and ending with leading coefficient. Converse
to `\\PolFromCSV <\\PolFromCSV{polname}{\<csv\>}_>`_.
.. _PolSturmChainLength:
@@ -1581,32 +1866,36 @@ and ``\PolToFloatExpr`` (and their auxiliaries) which need a
.. note::
- ``index`` may be a TeX count, or a ``\value{latexcounter}``, or a
- numerical expression as parsable by ``\numexpr``: it does not
- have to be given via explicit digits.
-
- This remark applies also to the other package macros with
- ``index`` being the name of the argument in this documentation.
- There is also an out-of-range check done for some reasonable
- error message (right before everything goes haywire).
+ ``index`` is allowed to be something like ``1+2*3`` as it is fed
+ to ``\the\numexpr...\relax``.
.. _PolSturmIsolatedZeroLeft:
``\PolSturmIsolatedZeroLeft{sturmname}{index}``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Expands to the left end-point for the ``index``\ -th interval
- obtained via `\\PolSturmIsolateZeros{sturmname}`_ and possibly
- refined afterwards.
+ Expands to the left end-point for the ``index``\ -th interval, as
+ computed by some earlier `\\PolSturmIsolateZeros{sturmname}`_.
+
+ .. note::
+
+ Of course, this is kept updated by macros such as
+ `\\PolRefineInterval{sturmname}{index} <PolRefineInterval[N]_>`_.
+
+ The value is pre-formatted using `\\PolDecTostring
+ <PolDecToString_>`_.
.. _PolSturmIsolatedZeroRight:
``\PolSturmIsolatedZeroRight{sturmname}{index}``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Expands to the right end-point for the ``index``\ -th interval
- obtained via `\\PolSturmIsolateZeros{sturmname}`_ and possibly
- refined afterwards.
+ Expands to the right end-point for the ``index``\ -th interval as
+ computed by some earlier `\\PolSturmIsolateZeros{sturmname}`_ and
+ possibly refined afterwards.
+
+ The value is pre-formatted using `\\PolDecTostring
+ <PolDecToString_>`_.
.. _PolSturmIsolatedZeroMultiplicity:
@@ -1614,9 +1903,7 @@ and ``\PolToFloatExpr`` (and their auxiliaries) which need a
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expands to the multiplicity of the unique root contained in the
- ``index``\ -th interval as determined by
- `\\PolSturmIsolateZeros*{sturmname}`_ and possibly refined
- afterwards.
+ ``index``\ -th interval.
.. attention::
@@ -1631,12 +1918,20 @@ and ``\PolToFloatExpr`` (and their auxiliaries) which need a
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expands to the number of real roots of the polynomial
- ``<sturmname>_0`` (which is the number of distinct real roots of the
- polynomial used to create the Sturm chain via
+ ``<sturmname>_0``, i.e. the number of distinct real roots of the
+ polynomial originally used to create the Sturm chain via
`\\PolToSturm{polname}{sturmname}`_.
+.. warning::
+
+ The next few macros counting roots, with or without multiplicities,
+ less than or equal to some value, are under evaluation and may be
+ removed from the package if their utility is judged to be not high
+ enough. They can be re-coded at user level on the basis of the other
+ documented package macros anyway.
+
``\PolSturmNbOfRootsOf{sturmname}\LessThanOrEqualTo{value}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expands to the number of distinct roots (of the polynomial used to
create the Sturm chain) less than or equal to the ``value`` (i.e. a
@@ -1652,7 +1947,7 @@ and ``\PolToFloatExpr`` (and their auxiliaries) which need a
of the above constraint.
``\PolSturmNbOfRootsOf{sturmname}\LessThanOrEqualToExpr{expression}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expands to the number of distinct roots (of the polynomial
used to create the Sturm chain) which are less than or equal to the
@@ -1664,7 +1959,7 @@ and ``\PolToFloatExpr`` (and their auxiliaries) which need a
beforehand.
``\PolSturmNbWithMultOfRootsOf{sturmname}\LessThanOrEqualTo{value}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expands to the number counted with multiplicities of the roots (of
the polynomial used to create the Sturm chain) which are less than
@@ -1672,22 +1967,74 @@ and ``\PolToFloatExpr`` (and their auxiliaries) which need a
.. attention::
- `\\PolSturmIsolateZeros*{sturmname}`_ or its alias
- `\\PolSturmIsolateZerosAndGetMultiplicities{sturmname}`_
- must have been executed
- beforehand.
+ `\\PolSturmIsolateZeros*{sturmname}`_ (or the double starred
+ variant) must have been executed beforehand.
``\PolSturmNbWithMultOfRootsOf{sturmname}\LessThanOrEqualToExpr{expression}``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expands to the total number of roots (counted with multiplicities)
which are less than or equal to the given ``expression``.
.. attention::
- `\\PolSturmIsolateZeros*{sturmname}`_ or its alias
- `\\PolSturmIsolateZerosAndGetMultiplicities{sturmname}`_
- must have been executed
+ `\\PolSturmIsolateZeros*{sturmname}`_ (or the double starred
+ variant) must have been executed beforehand.
+
+``\PolSturmNbOfRationalRoots{sturmname}``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ Expands to the number of rational roots (without multiplicities).
+
+ .. attention::
+
+ `\\PolSturmIsolateZeros**{sturmname}`_ must have been executed
+ beforehand.
+
+``\PolSturmNbOfRationalRootsWithMultiplicities{sturmname}``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ Expands to the number of rational roots (counted with multiplicities).
+
+ .. attention::
+
+ `\\PolSturmIsolateZeros**{sturmname}`_ must have been executed
+ beforehand.
+
+``\PolSturmRationalRoot{sturmname}{k}``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ Expands to the ``k``\ th rational root (they are ordered and indexed
+ starting at 1 for the most negative).
+
+ .. attention::
+
+ `\\PolSturmIsolateZeros**{sturmname}`_ must have been executed
+ beforehand.
+
+``\PolSturmRationalRootIndex{sturmname}{k}``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ Expands to ``index`` of the ``k``\ th rational root as part of the
+ ordered real roots (without multiplicities). I.e., above macro
+ `\\PolSturmRationalRoot{sturmname}{k}`_ is equivalent to this
+ nested call::
+
+ \PolSturmIsolatedZeroLeft{sturmname}{\PolSturmRationalRootIndex{sturmname}{k}}
+
+ .. attention::
+
+ `\\PolSturmIsolateZeros**{sturmname}`_ must have been executed
+ beforehand.
+
+``\PolSturmRationalRootMultiplicity{sturmname}{k}``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ Expands to the multiplicity of the ``k``\ th rational root.
+
+ .. attention::
+
+ `\\PolSturmIsolateZeros**{sturmname}`_ must have been executed
beforehand.
.. _PolIntervalWidth:
@@ -1698,66 +2045,66 @@ and ``\PolToFloatExpr`` (and their auxiliaries) which need a
The ``10^E`` width of the current ``index``\ -th root localization
interval. Output is in xintfrac_ raw ``1/1[E]`` format (if not zero).
-Macros for use within execution of ``\PolPrintIntervals``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-More precisely, they can be used within the replacement texts of the
-`\\PolPrintIntervalsPrintLeftEndPoint`_, etc, macros.
+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).
-.. _PolPrintIntervalsTheEndPoint:
+.. attention::
-``\PolPrintIntervalsTheEndPoint``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ Some macros formerly mentioned here got removed at 0.7:
+ ``\PolPrintIntervalsTheEndPoint``,
+ ``\PolIfEndPointIsPositive{A}{B}``,
+ ``\PolIfEndPointIsNegative{A}{B}``,
+ ``\PolIfEndPointIsZero{A}{B}``.
- Within a custom `\\PolPrintIntervalsPrintLeftEndPoint`_, custom
- `\\PolPrintIntervalsPrintRightEndPoint`_, or custom
- `\\PolPrintIntervalsPrintExactZero`_ this macro expands to the left
- or right end point of the considered interval. Serves as default
- replacement for `\\PolPrintIntervalsPrintLeftEndPoint`_ , etc...
+``\PolPrintIntervalsTheVar``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-.. _PolPrintIntervalsTheIndex:
+ Expands to the name (default ``Z``) used for representing the roots,
+ which was passed as optional argument ``varname`` to
+ `\\PolPrintIntervals[varname]{sturmname}`_.
``\PolPrintIntervalsTheIndex``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Within a custom `\\PolPrintIntervalsPrintLeftEndPoint`_, custom
- `\\PolPrintIntervalsPrintRightEndPoint`_, or custom
- `\\PolPrintIntervalsPrintExactZero`_ this macro expands to the index
- of the considered interval. For example if user wants to print the
- corresponding end points in red, the index value can thus be tested
- in the replacement text of `\\PolPrintIntervalsPrintLeftEndPoint`_ and
- the other two similar macros.
-
-.. _PolIfEndPointIsPositive:
+ Expands to the index of the considered interval (indexing starting
+ at 1 for the leftmost interval).
-``\PolIfEndPointIsPositive{A}{B}``
+``\PolPrintIntervalsTheSturmName``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Within a custom `\\PolPrintIntervalsPrintLeftEndPoint`_, custom
- `\\PolPrintIntervalsPrintRightEndPoint`_, or custom
- `\\PolPrintIntervalsPrintExactZero`_ this macro executes ``A`` if
- the considered interval end-point is positive, else ``B``.
+ Expands to the argument which was passed as ``sturmname`` to
+ `\\PolPrintIntervals[varname]{sturmname}`_.
-.. _PolIfEndPointIsNegative:
+``\PolPrintIntervalsTheLeftEndPoint``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-``\PolIfEndPointIsNegative{A}{B}``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ 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`_.
- Within a custom `\\PolPrintIntervalsPrintLeftEndPoint`_, custom
- `\\PolPrintIntervalsPrintRightEndPoint`_, or custom
- `\\PolPrintIntervalsPrintExactZero`_ this macro executes ``A`` if
- the considered interval end-point is negative, else ``B``.
+``\PolPrintIntervalsTheRightEndPoint``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-.. _PolIfEndPointIsZero:
+ The right end point of the interval, as would be produced by
+ `\\\PolSturmIsolatedZeroRight <PolSturmIsolatedZeroRight_>`_ for
+ this Sturm chain name and index.
-``\PolIfEndPointIsZero{A}{B}``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+``\PolPrintIntervalsTheMultiplicity``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Within a custom `\\PolPrintIntervalsPrintLeftEndPoint`_, custom
- `\\PolPrintIntervalsPrintRightEndPoint`_, or custom
- `\\PolPrintIntervalsPrintExactZero`_ this macro executes ``A`` if
- the considered interval end-point is zero, else ``B``.
+ The multiplicity of the unique root within the interval of index
+ `\\PolPrintIntervalsTheIndex`_. Makes sense only if the starred (or
+ double-starred) variant of `\\PolSturmIsolateZeros
+ <PolSturmIsolateZeros_>`_ was used earlier.
.. _PolDecToString:
@@ -1775,7 +2122,7 @@ More precisely, they can be used within the replacement texts of the
illustrates that trailing zeros are not trimmed. To trim trailing
zeroes, one can use ``\PolDecToString{\xintREZ{#1}}``.
- The exact behaviour of this macro may evolve in future releases of
+ The precise behaviour of this macro may evolve in future releases of
xint_.
Booleans (with default setting as indicated)
@@ -1806,6 +2153,26 @@ Booleans (with default setting as indicated)
If ``true``, `\\PolToExpr{polname}`_ and `\\PolToFloatExpr{polname}`_ will
also include the vanishing coefficients in their outputs.
+``\polexprsetup``
+-----------------
+
+ Serves to customize the package. Currently only two keys are
+ recognized:
+
+ - ``norr``: the postfix that `\\PolSturmIsolateZeros**{sturmname}`_
+ should append to ``sturmname`` to declare the primitive polynomial
+ obtained from original one after removal of all rational roots.
+ The default value is ``_norr`` (standing for “no rational roots”).
+
+ - ``sqfnorr``: the postfix that `\\PolSturmIsolateZeros**{sturmname}`_
+ should append to ``sturmname`` to declare the primitive polynomial
+ obtained from original one after removal of all rational roots and
+ suppression of all multiplicities.
+ The default value is ``_sqf_norr`` (standing for “square-free with
+ no rational roots”).
+
+ The package executes ``\polexprsetup{norr=_norr,
+ sqfnorr=_sqf_norr}`` as default.
Technicalities
--------------
@@ -2001,11 +2368,11 @@ CHANGE LOG
- `\\PolSturmIfZeroExactlyKnown <PolSturmIfZeroExactlyKnown_>`_
- `\\PolSturmIsolatedZeroLeft <PolSturmIsolatedZeroLeft_>`_
- `\\PolSturmIsolatedZeroRight <PolSturmIsolatedZeroRight_>`_
- - `\\PolPrintIntervalsTheEndPoint <PolPrintIntervalsTheEndPoint_>`_
- - `\\PolPrintIntervalsTheIndex <PolPrintIntervalsTheIndex_>`_
- - `\\PolIfEndPointIsPositive <PolIfEndPointIsPositive_>`_
- - `\\PolIfEndPointIsNegative <PolIfEndPointIsNegative_>`_
- - `\\PolIfEndPointIsZero <PolIfEndPointIsZero_>`_
+ - ``\PolPrintIntervalsTheEndPoint`` (removed at 0.7)
+ - `\\PolPrintIntervalsTheIndex`_
+ - ``\PolIfEndPointIsPositive`` (removed at 0.7)
+ - ``\PolIfEndPointIsNegative`` (removed at 0.7)
+ - ``\PolIfEndPointIsZero`` (removed at 0.7)
- `\\PolIntervalWidth <PolIntervalWidth_>`_
- `\\PolDecToString <PolDecToString_>`_
* improvements:
@@ -2081,6 +2448,54 @@ CHANGE LOG
- `\\PolSturmNbWithMultOfRootsOf{sturmname}\\LessThanOrEqualTo{value}`_
- `\\PolSturmNbWithMultOfRootsOf{sturmname}\\LessThanOrEqualToExpr{expression}`_
+- v0.7 (2018/12/08)
+
+ * breaking changes:
+
+ - although `\\PolPrintIntervals[varname]{sturmname}`_ default output
+ remains the same, some auxiliary macros for user-customization
+ have been removed: ``\PolPrintIntervalsTheEndPoint``,
+ ``\PolIfEndPointIsPositive{A}{B}``,
+ ``\PolIfEndPointIsNegative{A}{B}``, and
+ ``\PolIfEndPointIsZero{A}{B}``.
+
+ * bugfix:
+
+ - it could happen that, contrarily to documentation, an interval
+ computed by `\\PolSturmIsolateZeros{sturmname}`_ had zero as an
+ endpoint,
+ - `\\PolEnsureIntervalLength{sturmname}{index}{E}`_ could under
+ certain circumstances erroneously replace a non-zero root by
+ zero,
+ - `\\PolEnsureIntervalLengths{sturmname}{E}`_ crashed when used with
+ a polynomial with no real roots, hence for which no isolation intervals
+ existed (thanks to Thomas Söll for report).
+
+ * new macros:
+
+ - `\\PolSturmIsolateZeros**{sturmname}`_
+ - `\\PolSturmIsolateZerosGetMultiplicitiesAndRationalRoots{sturmname}`_
+ - `\\PolSturmIsolateZerosAndFindRationalRoots{sturmname}`_
+ - `\\polexprsetup`_
+ - `\\PolPrintIntervals* <PolPrintIntervals*_>`_
+ - `\\PolPrintIntervalsNoRealRoots`_
+ - `\\PolPrintIntervalsBeginEnv`_
+ - `\\PolPrintIntervalsEndEnv`_
+ - `\\PolPrintIntervalsKnownRoot`_
+ - `\\PolPrintIntervalsUnknownRoot`_
+ - `\\PolPrintIntervalsPrintMultiplicity`_
+
+ * new expandable macros:
+
+ - `\\PolSturmNbOfRationalRoots{sturmname}`_
+ - `\\PolSturmNbOfRationalRootsWithMultiplicities{sturmname}`_
+ - `\\PolSturmRationalRoot{sturmname}{k}`_
+ - `\\PolSturmRationalRootIndex{sturmname}{k}`_
+ - `\\PolSturmRationalRootMultiplicity{sturmname}{k}`_
+ - `\\PolPrintIntervalsTheVar`_
+ - `\\PolPrintIntervalsTheSturmName`_
+ - `\\PolPrintIntervalsTheMultiplicity`_
+
Acknowledgments
---------------
@@ -2090,7 +2505,7 @@ differentiating polynomials was the initial trigger leading to this
package, and to Jürgen Gilg and Thomas Söll for testing it on some
concrete problems.
-Renewed thanks to them on occasion of the ``0.6`` release for their
+Renewed thanks to them on occasion of the ``0.6`` and ``0.7`` releases for their
continued interest.
See README.md for the License.
@@ -2100,6 +2515,8 @@ See README.md for the License.
.. _xintexpr:
.. _xint: http://www.ctan.org/pkg/xint
+.. _Wilkinson polynomial: https://en.wikipedia.org/wiki/Wilkinson%27s_polynomial
+
.. _Sturm algorithm:
.. _Sturm Theorem: https://en.wikipedia.org/wiki/Sturm%27s_theorem
diff --git a/Master/texmf-dist/tex/latex/polexpr/polexpr.sty b/Master/texmf-dist/tex/latex/polexpr/polexpr.sty
index f163fe10f29..601446cf671 100644
--- a/Master/texmf-dist/tex/latex/polexpr/polexpr.sty
+++ b/Master/texmf-dist/tex/latex/polexpr/polexpr.sty
@@ -1,7 +1,7 @@
% author: Jean-François Burnol
% License: LPPL 1.3c (author-maintained)
\ProvidesPackage{polexpr}%
- [2018/11/20 v0.6 Polynomial expressions with rational coefficients (JFB)]%
+ [2018/12/08 v0.7 Polynomial expressions with rational coefficients (JFB)]%
\RequirePackage{xintexpr}[2018/06/17]% xint 1.3c for \ifxintglobaldefs boolean
\edef\POL@restorecatcodes
{\catcode`\noexpand\_ \the\catcode`\_ %
@@ -28,11 +28,28 @@
}%
%% AUXILIARIES
+\catcode`! 3
+%% added at 0.7
+\newcommand\polexprsetup[1]{\POL@setup_parsekeys #1,=!,\xint_bye}%
+\def\POL@setup_parsekeys #1=#2#3,{%
+ \ifx!#2\expandafter\xint_bye\fi
+ \csname POL@setup_setkey_\xint_zapspaces #1 \xint_gobble_i\endcsname
+ \xint_firstoftwo
+ {\PackageWarning{polexpr}{The \detokenize{#1} key is unknown! ignoring}}%
+ {\xintZapLastSpaces{#2#3}}%
+ \POL@setup_parsekeys
+}%
+\catcode`! 11
+\def\POL@setup_setkey_norr #1#2{\edef\POL@norr}%
+\def\POL@setup_setkey_sqfnorr #1#2{\edef\POL@sqfnorr}%
+\polexprsetup{norr=_norr, sqfnorr=_sqf_norr}
+
\newcount\POL@count
\newif\ifPOL@pol
\newif\ifxintveryverbose
\newif\ifpoltypesetall
-\newif\ifPOL@sturm@declareunnormalized
+\newif\ifPOL@tosturm@makefirstprimitive
+\POL@tosturm@makefirstprimitivetrue
\newif\ifPOL@isolz@nextwillneedrefine
\newif\ifpoltoexprall
%% the main exchange structure (stored in macros \POLuserpol@<name>)
@@ -681,9 +698,16 @@
\def\POL@makeprim@macro#1%
{\xintREZ{\xintNum{\xintDiv{#1}{\POL@makeprim@icontent}}}}%
\newcommand\PolMakePrimitive[1]{%
+ % This does not need a full user declared polynomial on input, only
+ % a \POLuserpol@name macro, but on output it is fully declared
\edef\POL@makeprim@icontent{\PolIContent{#1}}%
\PolMapCoeffs\POL@makeprim@macro{#1}%
}%
+\def\POL@makeprimitive#1{%
+ % Avoids declaring the polynomial, internal usage in \PolToSturm
+ \edef\POL@makeprim@icontent{\PolIContent{#1}}%
+ \POL@mapcoeffs\POL@makeprim@macro{#1}%
+}%
%% Sturm Algorithm (polexpr 0.4)
@@ -696,15 +720,16 @@
%% holding the coefficients in memory
%% 0.6 fixes the case of a constant polynomial P which caused division
%% by zero error from P'.
-\newcommand\PolToSturm{\@ifstar
- {\POL@sturm@declareunnormalizedtrue\POL@ToSturm}%
- {\POL@sturm@declareunnormalizedfalse\POL@ToSturm}%
-}%
+\newcommand\PolToSturm{\@ifstar{\PolToSturm@@}{\PolToSturm@}}%
\def\POL@aux@toint#1{\xintREZ{\xintNum{#1}}}% for polynomials with int. coeffs!
-\def\POL@ToSturm#1#2{%
+%% Attention that some macros rely upon this one setting \POL@sturmname
+%% and \POL@sturm@N as it does
+\def\PolToSturm@#1#2{%
\edef\POL@sturmname{#2}%
% 0.6 uses 2 underscores (one before index, one after) to keep in memory
% the unnormalized chain
+ % This supposes #1 to be a genuine polynomial, not only a name with
+ % a \POLuserpol@#1 macro
\POL@let{\POL@sturmname _0_}{#1}%
\ifnum\PolDegree{#1}=\z@
\def\POL@sturm@N{0}%
@@ -713,7 +738,8 @@
% if constant is negative. I also don't worry if polynomial is zero.
\@namedef{POLuserpol@\POL@sturmname _0}{0.\empty{1/1[0]}}%
\else
- \POL@ToSturm@DoSturm
+ \ifPOL@tosturm@makefirstprimitive\POL@makeprimitive{\POL@sturmname _0_}\fi
+ \POL@tosturm@dosturm
\fi
\expandafter
\let\csname PolSturmChainLength_\POL@sturmname\endcsname\POL@sturm@N
@@ -724,22 +750,21 @@
\unless\ifnum\POL@sturm@N=\POL@count
\advance\POL@count\@ne
\repeat
+}%
+\def\PolToSturm@@#1#2{\PolToSturm@{#1}{#2}\POL@tosturm@declareunnormalized}%
+\def\POL@tosturm@declareunnormalized{%
% optionally declare also the unnormalized ones
\POL@count\z@
- \ifPOL@sturm@declareunnormalized
- \POL@count\z@
- \xintloop
- \POL@newpol{\POL@sturmname _\the\POL@count _}%
- \unless\ifnum\POL@sturm@N=\POL@count
- \advance\POL@count\@ne
- \repeat
- \fi
+ \xintloop
+ \POL@newpol{\POL@sturmname _\the\POL@count _}%
+ \unless\ifnum\POL@sturm@N=\POL@count
+ \advance\POL@count\@ne
+ \repeat
}%
-\def\POL@ToSturm@DoSturm{%
- \PolMakePrimitive{\POL@sturmname _0_}%
+\def\POL@tosturm@dosturm{%
\POL@Diff@@one{\POL@sturmname _0_}{\POL@sturmname _1_}%
% re-utiliser \POL@varcoeffs directement?
- \PolMakePrimitive{\POL@sturmname _1_}%
+ \POL@makeprimitive{\POL@sturmname _1_}% does not do \POL@newpol
\POL@count\@ne
\xintloop
\POL@divide{\POL@sturmname _\the\numexpr\POL@count-\@ne\relax _}%
@@ -750,6 +775,7 @@
\expandafter\let
\csname POLuserpol@\POL@sturmname _\the\POL@count _\endcsname\POL@R
\edef\POL@makeprim@icontent{-\POL@icontent\POL@polR}%
+ % this avoids the \POL@newpol from \PolMapCoeffs
\POL@mapcoeffs\POL@makeprim@macro{\POL@sturmname _\the\POL@count _}%
\repeat
\edef\POL@sturm@N{\the\POL@count}%
@@ -763,13 +789,13 @@
\expandafter
\let\csname POLuserpol@\POL@sturmname _\the\POL@count\endcsname\POL@Q
% quotient actually belongs to Z[X] and is primitive
- \POL@mapcoeffs{\POL@aux@toint}{\POL@sturmname _\the\POL@count}%
+ \POL@mapcoeffs\POL@aux@toint{\POL@sturmname _\the\POL@count}%
\ifnum\POL@count>\z@
\repeat
\@namedef{POLuserpol@\POL@sturmname _\POL@sturm@N}{0.\empty{1/1[0]}}%
\else % they are already normalized
- \advance\POL@count\@ne % attention to include last one also
- \xintloop
+ \advance\POL@count\@ne % attention to include last one also
+ \xintloop
\advance\POL@count\m@ne
\expandafter\let
\csname POLuserpol@\POL@sturmname _\the\POL@count\expandafter\endcsname
@@ -777,7 +803,7 @@
\ifnum\POL@count>\z@
\repeat
\fi
- % Back to \POL@ToSturm
+ % Back to \PolToSturm@, \POL@count holds 0
}%
\newcommand\PolSturmChainLength[1]
{\romannumeral`^^@\csname PolSturmChainLength_#1\endcsname}%
@@ -791,19 +817,19 @@
}%
\def\POL@sturmchain@getSV@at#1{% ATTENTION USES \POL@count
\def\POL@sturmchain@SV{0}%
- \edef\POL@sturmchain@sign{\xintiiSgn{\Pol@Eval{\POL@sturmname _0}{#1}}}%
+ \edef\POL@sturmchain@sign{\xintiiSgn{\POL@eval{\POL@sturmname _0}{#1}}}%
\let\POL@isolz@lastsign\POL@sturmchain@sign
\POL@count \z@
\ifnum\POL@isolz@lastsign=\z@
\edef\POL@isolz@lastsign
- {\xintiiSgn{\Pol@Eval{\POL@sturmname _1}{#1}}}%
+ {\xintiiSgn{\POL@eval{\POL@sturmname _1}{#1}}}%
\POL@count \@ne
\fi
\xintloop
\unless\ifnum\POL@sturmlength=\POL@count
\advance\POL@count \@ne
\edef\POL@isolz@newsign
- {\xintiiSgn{\Pol@Eval{\POL@sturmname _\the\POL@count}{#1}}}%
+ {\xintiiSgn{\POL@eval{\POL@sturmname _\the\POL@count}{#1}}}%
\ifnum\POL@isolz@newsign=\numexpr-\POL@isolz@lastsign\relax
\edef\POL@sturmchain@SV{\the\numexpr\POL@sturmchain@SV+\@ne}%
\let\POL@isolz@lastsign=\POL@isolz@newsign
@@ -827,11 +853,431 @@
}%
+% 0.6 added starred variant to count multiplicities
+% 0.7 added double starred variant to locate all rational roots
\newcommand\PolSturmIsolateZeros{\@ifstar
{\PolSturmIsolateZerosAndGetMultiplicities}%
{\PolSturmIsolateZeros@}%
}%
-\newcommand\PolSturmIsolateZerosAndGetMultiplicities[2][\empty]{%
+\newcommand\PolSturmIsolateZerosAndGetMultiplicities{\@ifstar
+ {\PolSturmIsolateZerosGetMultiplicitiesAndRationalRoots}%
+ {\PolSturmIsolateZerosAndGetMultiplicities@}%
+}%
+% on aurait besoin de ça dans xint, mais il aurait un \xintRaw{#1} alors
+\def\POL@xintfrac@getNDE #1%
+ {\expandafter\POL@xintfrac@getNDE@i\romannumeral`^^@#1}%
+\def\POL@xintfrac@getNDE@i #1/#2[#3]#4#5#6{\def#4{#1}\def#5{#2}\def#6{#3}}%
+\newcommand\PolSturmIsolateZerosGetMultiplicitiesAndRationalRoots[2][\empty]{%
+ \PolSturmIsolateZerosAndFindRationalRoots[#1]{#2}%
+ \ifnum\POL@isolz@NbOfRoots>\z@
+ % get multiplicities of irrational (real) roots, if any
+ \ifnum\POL@findrat@nbofirrroots>\z@
+ \POL@findrat@getirrmult
+ \fi
+ \POL@isolzmult@defvar@M
+ \fi
+}%
+% added at 0.7
+\newcommand\PolSturmIsolateZerosAndFindRationalRoots[2][\empty]{%
+ % #1 optional E such that roots are searched in -10^E < x < 10^E
+ % both -10^E and +10^E must not be roots!
+ % #2 name of Sturm chain (already pre-computed)
+ \edef\POL@sturmname{#2}%
+ \edef\POL@sturm@N{\@nameuse{PolSturmChainLength_\POL@sturmname}}%
+ % isolate the roots (detects case of constant polynomial)
+ \PolSturmIsolateZeros@{\POL@sturmname}%
+ \ifnum\POL@isolz@NbOfRoots=\z@
+ % no real roots, define empty arrays nevertheless
+ \begingroup\globaldefs\@ne
+ \expandafter\xintAssignArray\expandafter\to\csname POL_ZeroMult\POL@sturmname\endcsname
+ \expandafter\xintAssignArray\expandafter\to\csname POL_RRIndex\POL@sturmname\endcsname
+ \endgroup
+ \else
+ % all we currently know is that multiplicities are at least one
+ \begingroup\globaldefs\@ne
+ \expandafter\POL@initarray\csname POL_ZeroMult\POL@sturmname\endcsname{1}%
+ \endgroup
+ % on ne va pas utiliser de Horner, mais des divisions par X - x, et ces
+ % choses vont évoluer, ainsi que le coefficient dominant entier
+ % (pour \POL@divide entre autres if faut des noms de user pol)
+ \expandafter\let
+ \csname POLuserpol@\POL@sturmname\POL@sqfnorr\expandafter\endcsname
+ \csname POLuserpol@\POL@sturmname _0\endcsname
+ \expandafter\let
+ \csname POLuserpol@\POL@sturmname\POL@norr\expandafter\endcsname
+ \csname POLuserpol@\POL@sturmname _0_\endcsname
+ % attention formé avec\xintREZ d'où le \xintAbs pas \xintiiAbs
+ % D and its exponent E will get updated along the way
+ \edef\POL@findrat@D{\xintAbs{\PolLeadingCoeff{\POL@sturmname _0}}}%
+ \POL@xintfrac@getNDE\POL@findrat@D\POL@findrat@Dint\POL@_\POL@findrat@Dexp
+ \xintiiifOne{\POL@findrat@Dint}
+ {\let\POL@findrat@E\POL@findrat@Dexp} % aussi ok pour 1[0]
+ {\edef\POL@findrat@E{\the\numexpr\xintLen{\POL@findrat@Dint}%
+ +\POL@findrat@Dexp}}%
+ \POL@initarray\POL@IfMultIsKnown\xint_secondoftwo
+ \let\POL@findrat@nbofirrroots\POL@isolz@NbOfRoots
+ % find all rational roots, and their multiplicities,
+ % factor them out in passing from original (Sturm root) polynomial
+ \ifnum\POL@findrat@E<7
+ \PolEnsureIntervalLength{\POL@sturmname}{1}{-\POL@findrat@E}%
+ \def\POL@findrat@index{1}%
+ \POL@findrat@loop@secondpass@direct
+ \else
+ % we do a first pass scanning for "small" roots p/q (i.e. q < 1000)
+ \def\POL@findrat@index{1}%
+ \POL@findrat@loop@firstpass
+ % and now we do the final pass finding them all
+ \def\POL@findrat@index{1}%
+ \PolEnsureIntervalLength{\POL@sturmname}{1}{-\POL@findrat@E}%
+ \POL@findrat@loop@secondpass
+ \fi
+ % declare the new polynomials
+ \POL@newpol{\POL@sturmname\POL@sqfnorr}% without multiplicities
+ \POL@newpol{\POL@sturmname\POL@norr}% with multiplicities
+ % declare the array holding the interval indices for the rational roots
+ \expandafter\POL@findrat@doRRarray\csname POL_RRIndex\POL@sturmname\endcsname
+ \fi
+}%
+\def\POL@findrat@doRRarray#1{%
+ % il faudrait un \xintAssignArray* qui fasse même expansion que \xintFor*
+ \edef\POL@temp{%
+ \xintiloop[1+1]
+ \romannumeral0\csname POL_ZeroIsKnown\POL@sturmname\xintiloopindex\endcsname
+ \xintbracediloopindex % I should have named it \xintiloopbracedindex...
+ {}%
+ \ifnum\xintiloopindex<\POL@isolz@NbOfRoots\space
+ \repeat }%
+ \begingroup\globaldefs1
+ % attention de ne surtout pas faire un \expandafter ici, car en cas d'un
+ % seul item, \xintAssignArray l'unbraces...
+ \xintAssignArray\POL@temp\to#1%
+ \endgroup
+}%
+\def\POL@findrat@loop@firstpass{%
+ \PolSturmIfZeroExactlyKnown{\POL@sturmname}{\POL@findrat@index}%
+ \POL@findrat@loop@decimal% get its multiplicity
+ \POL@findrat@loop@a
+ \edef\POL@findrat@index{\the\numexpr\POL@findrat@index+\@ne}%
+ \ifnum\POL@findrat@index>\POL@isolz@NbOfRoots
+ \else
+ \expandafter\POL@findrat@loop@firstpass
+ \fi
+}%
+\def\POL@findrat@loop@secondpass{%
+ \PolSturmIfZeroExactlyKnown{\POL@sturmname}{\POL@findrat@index}%
+ {}% nothing more to be done, already stored
+ \POL@findrat@loop@b
+ \edef\POL@findrat@index{\the\numexpr\POL@findrat@index+\@ne}%
+ \ifnum\POL@findrat@index>\POL@isolz@NbOfRoots
+ \else
+ \PolEnsureIntervalLength
+ {\POL@sturmname}{\POL@findrat@index}{-\POL@findrat@E}% dynamic
+ \expandafter\POL@findrat@loop@secondpass
+ \fi
+}%
+\def\POL@findrat@loop@secondpass@direct{%
+ \PolSturmIfZeroExactlyKnown{\POL@sturmname}{\POL@findrat@index}%
+ \POL@findrat@loop@decimal
+ \POL@findrat@loop@b
+ \edef\POL@findrat@index{\the\numexpr\POL@findrat@index+\@ne}%
+ \ifnum\POL@findrat@index>\POL@isolz@NbOfRoots
+ \else
+ \PolEnsureIntervalLength
+ {\POL@sturmname}{\POL@findrat@index}{-\POL@findrat@E}% dynamic
+ \expandafter\POL@findrat@loop@secondpass@direct
+ \fi
+}%
+\def\POL@findrat@loop@decimal{% we have an already found decimal root
+ % we do not go via @storeit, as it is already stored
+ % j'ai beaucoup hésité néanmoins, car je pourrais faire \xintIrr ici,
+ % mais attention aussi à l'interaction avec le \PolDecToString. Les racines
+ % trouvées directement (qui peuvent être des nombres décimaux) sont elles
+ % stockées comme fraction irréductibles (modulo action additionnelle de
+ % \PolDecToString).
+ \POL@xintfrac@getNDE
+ {\xintIrr{\POL@xintexprGetVar{\POL@sturmname L_\POL@findrat@index}}[0]}%
+ \POL@findrat@xN\POL@findrat@xD\POl@_
+ % we can't move this to updatequotients because other branch will
+ % need to do the division first anyhow
+ \edef\POLuserpol@_findrat@oneterm{1.\noexpand\empty
+ {\xintiiOpp\POL@findrat@xN/1[0]}{\POL@findrat@xD/1[0]}}%
+ \POL@divide{\POL@sturmname\POL@sqfnorr}{_findrat@oneterm}% the one without mult.
+ \POL@findrat@loop@updatequotients
+ \POL@findrat@loop@getmultiplicity
+}%
+% lacking from xint 1.3c, but \xintSgn has overhead, so we define ii version
+\def\xintiiifNeg{\romannumeral0\xintiiifneg }%
+\def\xintiiifneg #1%
+{%
+ \ifcase \xintiiSgn{#1}
+ \expandafter\xint_stop_atsecondoftwo
+ \or\expandafter\xint_stop_atsecondoftwo
+ \else\expandafter\xint_stop_atfirstoftwo
+ \fi
+}%
+\def\POL@findrat@getE #1/1[#2]{#2}% /1 as it should be there.
+% so an error will arise if not but cf \POL@refine@getE where I did not put it
+\def\POL@findrat@loop@a{%
+ % we do a first pass to identify roots with denominators < 1000
+ \PolEnsureIntervalLength{\POL@sturmname}{\POL@findrat@index}{-6}%
+ % attention that the width may have been already smaller than 10^{-6}
+ % also attention that one of the bound may be zero
+ \POL@get@IsoLeft@rawin
+ \POL@get@IsoRight@rawin
+ \edef\POL@findrat@localW
+ {\the\numexpr-\expandafter\POL@findrat@getE
+ % do I really need the \xintREZ?
+ \romannumeral0\xintrez
+ {\xintSub{\POL@IsoRight@rawin}{\POL@IsoLeft@rawin}}%
+ }% at least 6, maybe larger
+ \expandafter\POL@get@Int@aux
+ \POL@IsoLeft@rawin\POL@IsoLeft@Int{-\POL@findrat@localW}%
+ \expandafter\POL@get@Int@aux
+ \POL@IsoRight@rawin\POL@IsoRight@Int{-\POL@findrat@localW}%
+ % in case of odd, some waste here
+ \edef\POL@findrat@halflocalW{\the\numexpr(\POL@findrat@localW+1)/2-1}%
+ % Legendre Theorem will be used now but we separate a branch where
+ % everything can be done with \numexpr
+ \ifnum\POL@findrat@localW>10
+ % not implemented yet by lazyness!
+ % this root will be handled in second pass only
+ \else
+ \POL@findrat@gcdloop
+ \fi
+}%
+\def\POL@findrat@gcdloop{%
+ % we must be careful with sign (attention one of the bounds may be zero)
+ \let\POL@findrat@IfNeg\xint_secondoftwo
+ \xintiiifSgn\POL@IsoLeft@Int
+ \POL@findrat@gcdloop@n
+ \POL@findrat@gcdloop@zero
+ \POL@findrat@gcdloop@p
+}%
+\def\POL@findrat@gcdloop@n{%
+ \let\POL@findrat@IfNeg\xint_firstoftwo
+ \let\POL@temp\POL@IsoRight@Int
+ \edef\POL@IsoRight@Int{\xintiiOpp{\POL@IsoLeft@Int}}%
+ \edef\POL@IsoLeft@Int{\xintiiOpp{\POL@temp}}%
+ \xintiiifSgn\POL@IsoLeft@Int
+ \POL@error % impossible branch
+ \POL@findrat@gcdloop@zero
+ \POL@findrat@gcdloop@p
+}%
+\def\POL@findrat@gcdloop@zero{%
+ % the continued fraction would be the one of 1/2, so only 1/2 to test...
+ \edef\POL@findrat@x
+ {1/2\romannumeral\xintreplicate{\POL@findrat@localW}{0}[0]}%
+ \POL@findrat@gcdloop@testit
+}%
+\def\POL@findrat@gcdloop@p{%
+ \edef\POL@findrat@gcdloop@Ap{\xintDec{\xintDouble\POL@IsoRight@Int}}%
+ \edef\POL@findrat@gcdloop@A
+ {2\romannumeral\xintreplicate\POL@findrat@localW{0}}%
+ \xintAssign
+ \xintiiDivision\POL@findrat@gcdloop@Ap\POL@findrat@gcdloop@A
+ \to\POL@findrat@gcdloop@B\POL@findrat@gcdloop@An
+ % on fait de la tambouille pour n'utiliser que \numexpr par la suite
+ % le reste @An est < 2.10^10 au pire donc ok pour \numexpr
+ % we will drop integral part in our updating P
+ \let\POL@findrat@gcdloop@Binitial\POL@findrat@gcdloop@B
+ \def\POL@findrat@gcdloop@B{0}% do as if B1 = 0
+ \def\POL@findrat@gcdloop@Pp{1}% P0
+ \def\POL@findrat@gcdloop@P{0}% P1
+ \def\POL@findrat@gcdloop@Qp{0}% Q0
+ \def\POL@findrat@gcdloop@Q{1}% Q1
+ % A2=An can not be zero, as Ap (=A0) is odd and A (=A1=200...000) is even
+ % first Binitial + P1/Q1 ( = Binitial) can not be root
+ \let\POL@findrat@gcdloop@Ap\POL@findrat@gcdloop@A % A1
+ \let\POL@findrat@gcdloop@A\POL@findrat@gcdloop@An % A2
+ \def\next{\POL@findrat@gcdloop@update}%
+ \def\POL@findrat@gcdloop@done{0}%
+ \POL@findrat@gcdloop@body
+}%
+\def\POL@findrat@gcdloop@body{%
+ % annoying that \numexpr has no divmod... use counts? but groups annoying
+ \edef\POL@findrat@gcdloop@B
+ {\the\numexpr(\POL@findrat@gcdloop@Ap+\POL@findrat@gcdloop@A/2)/%
+ \POL@findrat@gcdloop@A - \@ne}%
+ \edef\POL@findrat@gcdloop@An
+ {\the\numexpr\POL@findrat@gcdloop@Ap-%
+ \POL@findrat@gcdloop@B*\POL@findrat@gcdloop@A}%
+ \edef\POL@findrat@gcdloop@Pn
+ {\the\numexpr\POL@findrat@gcdloop@Pp+%
+ \POL@findrat@gcdloop@B*\POL@findrat@gcdloop@P}%
+ \edef\POL@findrat@gcdloop@Qn
+ {\the\numexpr\POL@findrat@gcdloop@Qp+%
+ \POL@findrat@gcdloop@B*\POL@findrat@gcdloop@Q}%
+ \ifnum\expandafter\xintLength\expandafter{\POL@findrat@gcdloop@Qn}%
+ >\POL@findrat@halflocalW\space
+ \let\next\empty % no solution was found
+ \else
+ % with these conditions on denom, only candidates are by Legendre
+ % theorem among the convergents as computed here
+ \ifnum\POL@findrat@gcdloop@Qn>\POL@findrat@gcdloop@An\space
+ % means that P/Q is in interval and is thus a candidate
+ % it is automatically irreducible
+ \edef\POL@findrat@x{\xintiiAdd
+ {\xintiiMul{\POL@findrat@gcdloop@Qn}{\POL@findrat@gcdloop@Binitial}}%
+ {\POL@findrat@gcdloop@Pn}/\POL@findrat@gcdloop@Qn[0]}%
+ \POL@findrat@gcdloop@testit
+ \if1\POL@findrat@gcdloop@done
+ \let\next\empty % a solution was found
+ \fi
+ \fi
+ \fi
+ \next
+}%
+\def\POL@findrat@gcdloop@update{%
+ \ifnum\POL@findrat@gcdloop@An>\z@
+ \let\POL@findrat@gcdloop@Ap\POL@findrat@gcdloop@A
+ \let\POL@findrat@gcdloop@A\POL@findrat@gcdloop@An
+ \let\POL@findrat@gcdloop@Pp\POL@findrat@gcdloop@P
+ \let\POL@findrat@gcdloop@P\POL@findrat@gcdloop@Pn
+ \let\POL@findrat@gcdloop@Qp\POL@findrat@gcdloop@Q
+ \let\POL@findrat@gcdloop@Q\POL@findrat@gcdloop@Qn
+ \expandafter\POL@findrat@gcdloop@body
+ \fi
+}%
+\def\POL@findrat@gcdloop@testit{%
+ % zero should never occur here
+ \POL@findrat@IfNeg{\edef\POL@findrat@x{-\POL@findrat@x}}{}%
+ \POL@xintfrac@getNDE\POL@findrat@x\POL@findrat@xN\POL@findrat@xD\POL@_
+ \edef\POLuserpol@_findrat@oneterm{1.\noexpand\empty
+ {\xintiiOpp{\POL@findrat@xN}/1[0]}{\POL@findrat@xD/1[0]}}%
+ \POL@divide{\POL@sturmname\POL@sqfnorr}{_findrat@oneterm}% the one without mult.
+ \expandafter\POL@split\POL@R;\POL@degR\POL@polR
+ \ifnum\POL@degR=\m@ne % found a root
+ \POL@findrat@loop@storeit
+ \POL@findrat@loop@updatequotients
+ \POL@findrat@loop@getmultiplicity % will continue updating the mult. one
+ \def\POL@findrat@gcdloop@done{1}%
+ \else
+ \fi
+}%
+% This is second phase
+\def\POL@findrat@loop@b{%
+ \edef\POL@findrat@Lscaled{\xintMul{\POL@findrat@D}%
+ {\POL@xintexprGetVar{\POL@sturmname L_\POL@findrat@index}}}%
+ \edef\POL@findrat@Rscaled{\xintMul{\POL@findrat@D}%
+ {\POL@xintexprGetVar{\POL@sturmname R_\POL@findrat@index}}}%
+ \xintiiifNeg{\POL@findrat@Lscaled}% using ii version is an abuse
+ {% negative interval (right bound possibly zero!)
+ % truncate towards zero (i.e. to the right) the left bound
+ \edef\POL@findrat@Num{\xintNum{\POL@findrat@Lscaled}/1[0]}%
+ % interval boundaries are not root hence in case that was exact
+ % this will not be found as a root; check if in interval
+ \xintifLt\POL@findrat@Num\POL@findrat@Rscaled
+ \POL@findrat@loop@c
+ {}% iterate
+ }%
+ {% positive interval (left bound possibly zero!)
+ % truncate towards zero (i.e. to the left) the right bound
+ \edef\POL@findrat@Num{\xintNum{\POL@findrat@Rscaled}/1[0]}%
+ % check if in interval
+ \xintifGt\POL@findrat@Num\POL@findrat@Lscaled
+ \POL@findrat@loop@c
+ {}% iterate
+ }%
+}%
+\def\POL@findrat@loop@c{%
+ % safer to do the edef as \POL@findrat@x used later in storeit
+ \edef\POL@findrat@x{\xintIrr{\xintDiv\POL@findrat@Num\POL@findrat@D}[0]}%
+ \POL@xintfrac@getNDE\POL@findrat@x\POL@findrat@xN\POL@findrat@xD\POL@_
+ \edef\POLuserpol@_findrat@oneterm{1.\noexpand\empty
+ {\xintiiOpp{\POL@findrat@xN}/1[0]}{\POL@findrat@xD/1[0]}}%
+ \POL@divide{\POL@sturmname\POL@sqfnorr}{_findrat@oneterm}% the one without mult.
+ \expandafter\POL@split\POL@R;\POL@degR\POL@polR
+ \ifnum\POL@degR=\m@ne % found a root
+ \POL@findrat@loop@storeit
+ \POL@findrat@loop@updatequotients
+ \POL@findrat@loop@getmultiplicity % will continue updating the mult. one
+ \fi
+ % iterate
+}%
+\def\POL@findrat@loop@storeit{%
+ % update storage, I can not use storeleftandright here (due to rawout etc...)
+ \expandafter
+ \xdef\csname POL_ZeroInt\POL@sturmname L\POL@findrat@index\endcsname
+ {\PolDecToString{\POL@findrat@x}}%
+ \global\expandafter
+ \let\csname POL_ZeroInt\POL@sturmname R\POL@findrat@index\expandafter\endcsname
+ \csname POL_ZeroInt\POL@sturmname L\POL@findrat@index\endcsname
+ \global\expandafter
+ \let\csname POL_ZeroIsKnown\POL@sturmname\POL@findrat@index\endcsname
+ \xint_stop_atfirstoftwo
+ \begingroup\xintglobaldefstrue
+ \xintdefvar
+ \POL@sturmname L_\POL@findrat@index,%
+ \POL@sturmname R_\POL@findrat@index,%
+ \POL@sturmname Z_\POL@findrat@index _isknown
+ := qfrac(\POL@findrat@x),qfrac(\POL@findrat@x),1;%
+ \endgroup
+}%
+\def\POL@findrat@loop@updatequotients{%
+ % attention last division must have been one testing vanishing of\POL@sqfnorr
+ \expandafter\let\csname POLuserpol@\POL@sturmname\POL@sqfnorr\endcsname\POL@Q
+ % quotient belongs to Z[X] and is primitive
+ \POL@mapcoeffs\POL@aux@toint{\POL@sturmname\POL@sqfnorr}%
+ % update the one with multiplicities
+ \POL@divide{\POL@sturmname\POL@norr}{_findrat@oneterm}%
+ \expandafter\let\csname POLuserpol@\POL@sturmname\POL@norr\endcsname\POL@Q
+ \POL@mapcoeffs\POL@aux@toint{\POL@sturmname\POL@norr}
+ % updating of \POL@findrat@D at end of execution of getmultiplicity
+}%
+\def\POL@findrat@loop@getmultiplicity{%
+ % the one without multiplicity must not be divided again!
+ % check if we have remaining multiplicity
+ \POL@divide{\POL@sturmname\POL@norr}{_findrat@oneterm}%
+ \expandafter\POL@split\POL@R;\POL@degR\POL@polR
+ \ifnum\POL@degR=\m@ne % yes
+ \expandafter\let\csname POLuserpol@\POL@sturmname\POL@norr\endcsname\POL@Q
+ \POL@mapcoeffs\POL@aux@toint{\POL@sturmname\POL@norr}%
+ \expandafter
+ \xdef
+ \csname POL_ZeroMult\POL@sturmname\POL@findrat@index\endcsname
+ {\the\numexpr
+ \csname POL_ZeroMult\POL@sturmname\POL@findrat@index\endcsname+\@ne}%
+ \expandafter\POL@findrat@loop@getmultiplicity
+ \else
+ % done with multiplicity for this rational root, update stuff
+ \edef\POL@findrat@nbofirrroots
+ {\the\numexpr\POL@findrat@nbofirrroots-\@ne}%
+ \@namedef{POL@IfMultIsKnown\POL@findrat@index}{\xint_firstoftwo}%
+ \edef\POL@findrat@D{\xintAbs{\PolLeadingCoeff{\POL@sturmname\POL@sqfnorr}}}%
+ \POL@xintfrac@getNDE\POL@findrat@D\POL@findrat@Dint\POL@_\POL@findrat@Dexp
+ \xintiiifOne{\POL@findrat@Dint}
+ {\let\POL@findrat@E\POL@findrat@Dexp} % aussi ok pour 1[0]
+ {\edef\POL@findrat@E{\the\numexpr\xintLen{\POL@findrat@Dint}%
+ +\POL@findrat@Dexp}}%
+ \fi
+}%
+\def\POL@findrat@getirrmult{%
+ % first get the GCD of remaining pol with its derivative
+ \POL@divide{\POL@sturmname\POL@norr}{\POL@sturmname\POL@sqfnorr}%
+ \expandafter\let
+ % attention au _ (cf. grosse astuce pour \POL@isolzmult@loop)
+ \csname POLuserpol@@_1\POL@sturmname _\endcsname\POL@Q
+ \ifnum\PolDegree{@_1\POL@sturmname _}>\z@
+ % il reste des multiplicités (mais peut-être pour des racines complexes)
+ % (ou pour des racines en-dehors de l'intervalle optionnel)
+ % attention recyclage ici de \POL@isolzmult@loop qui dépend de
+ % la grosse astuce avec \@gobble
+ \POL@makeprimitive{@_1\POL@sturmname _}%
+ \let\POL@originalsturmname\POL@sturmname
+ % trick to get isolzmult@loop to define @@lastGCD to @_1sturmname_
+ % because it will do \POL@sturmname _\POL@sturm@N _
+ \edef\POL@sturmname{@_1\POL@sturmname}%
+ \let\POL@sturm@N\@gobble% !
+ \let\POL@isolz@NbOfRoots@with_unknown_mult\POL@findrat@nbofirrroots
+ \POL@tosturm@makefirstprimitivefalse
+ \POL@isolzmult@loop
+ \POL@tosturm@makefirstprimitivetrue
+ \let\POL@sturmname\POL@originalsturmname
+ \fi
+}%
+
+
+\newcommand\PolSturmIsolateZerosAndGetMultiplicities@[2][\empty]{%
% #1 optional E such that roots are searched in -10^E < x < 10^E
% both -10^E and +10^E must not be roots!
% #2 name of Sturm chain (already pre-computed)
@@ -845,9 +1291,6 @@
\expandafter\xintAssignArray\expandafter\to\csname POL_ZeroMult\POL@sturmname\endcsname
\endgroup
\else
- % store Sturm chain name for usage in the main loop
- \let\POL@originalsturmname\POL@sturmname
- \edef\POL@isolzmult@indices{\xintSeq{1}{\POL@isolz@NbOfRoots}}%
% all we currently know is that multiplicities are at least one
\begingroup\globaldefs\@ne
\expandafter\POL@initarray\csname POL_ZeroMult\POL@sturmname\endcsname{1}%
@@ -857,61 +1300,92 @@
\ifnum\PolDegree{\POL@sturmname _\POL@sturm@N _}>\z@
% scratch array of flags to signal known multiplicities
\POL@initarray\POL@IfMultIsKnown\xint_secondoftwo
+ % this count has utility for the case there are other roots
+ % either complex or outside interval (in case of optional argument)
\let\POL@isolz@NbOfRoots@with_unknown_mult\POL@isolz@NbOfRoots
- \expandafter\expandafter\expandafter\POL@isolzmult@loop
+ % store Sturm chain name, it is needed and altered in isolzmult@loop
+ \let\POL@originalsturmname\POL@sturmname
+ \POL@tosturm@makefirstprimitivefalse
+ \POL@isolzmult@loop
+ \POL@tosturm@makefirstprimitivetrue
+ \let\POL@sturmname\POL@originalsturmname
\fi
+ \POL@isolzmult@defvar@M
\fi
}%
+\def\POL@isolzmult@defvar@M{%
+ % Attention that is used not only in ...GetMultiplicities@ but also
+ % in FindRationalRoots
+ \begingroup\xintglobaldefstrue
+ % added at 0.7
+ \let\x\POL@isolz@NbOfRoots
+ \xintloop
+ \xintdefvar \POL@sturmname M_\x
+ := \csname POL_ZeroMult\POL@sturmname\x\endcsname ;%
+ \edef\x{\the\numexpr\x-\@ne}%
+ \ifnum\x>\z@
+ \repeat
+ \endgroup
+}%
\def\POL@isolzmult@loop{%
- % we are here only if last iteration gave a new PGCD still of degree > 0
- % As 0.6 \PolToSturm keeps memory of unnormalized Sturm chain, we use the
- % PGCD from last iteration and generate a new Sturm chain.
- % ATTENTION: first argument of \PolToSturm MUST NOT CONTAIN \POL@sturmname
- \let\POL@@sturmname\POL@sturmname
- % ATTENTION: we could use an underscore prefix to the name, but attention
- % to tacit multiplication if used in an expression; however \PolEvalAt
- % does not use expression parsing as \PolEvalAtExpr so this would be
- % relatively safe. We must also not overwrite privately used names
- % by polexpr or xint... Using prefix @_1 appears safe. They will accumulate.
- % As the loop may break at any moment, depending on original P, not only
- % on current polynomial which is examined to see if it has zeros, it does
- % not seem to make sense to think about interface to keep memory of all
- % the defined polynomials.
- % \POL@sturm@N supposedly the one from last iteration
- \PolToSturm{\POL@@sturmname _\POL@sturm@N _}{@_1\POL@@sturmname}%
+ % we are here only if last iteration gave a new GCD still of degree > 0
+ % \POL@sturm@N is the one from last iteration
+ % Attention to not use \POL@sturmname directly in first arg. of \PolToSturm
+ % Attention that we need for the case of known roots also to have the last
+ % GCD (with its multiplicities) known as a genuine polynomial
+ % - because of usage of \POL@eval in @isknown branch
+ % - because \PolToSturm@ does a \POL@let which would be anomalous
+ % if the extended structure is not existing
+ \edef\POL@isolzmult@lastGCD{\POL@sturmname _\POL@sturm@N _}%
+ \edef\POL@isolzmult@newsturmname{@_1\POL@sturmname}%
+ \POL@newpol{\POL@isolzmult@lastGCD}%
+ \PolToSturm@{\POL@isolzmult@lastGCD}{\POL@isolzmult@newsturmname}%
% now both \POL@sturmname and \POL@sturm@N have changed
- % if GCD is now a constant, we will not come back here
- \edef\POL@sturmfinaldeg{\PolDegree{\POL@sturmname _\POL@sturm@N _}}%
- \xintFor* ##1 in {\POL@isolzmult@indices}\do
- {%
- \csname POL@IfMultIsKnown##1\endcsname
- {}% nothing to do
- {\def\POL@isolzmult@index{##1}%
- \POL@SturmIfZeroExactlyKnown{\POL@originalsturmname}{##1}%
- \POL@isolzmult@loop@zero_isknown
- \POL@isolzmult@loop@zero_isnotknown
- \POL@isolzmult@loop@sharedbody
- }%
- }%
- \ifnum\POL@sturmfinaldeg>\z@
+ \edef\POL@isolzmult@newGCDdegree{\PolDegree{\POL@sturmname _\POL@sturm@N _}}%
+ \let\POL@isolzmult@index\POL@isolz@NbOfRoots
+ \xintloop
+ % ATTENTION that this executes macros which also modifies \POL@sturmname!
+ % (but not \POL@sturm@N)
+ \POL@isolzmult@doone
+ \edef\POL@isolzmult@index{\the\numexpr\POL@isolzmult@index-\@ne}%
+ \if1\ifnum\POL@isolz@NbOfRoots@with_unknown_mult=\z@ 0\fi
+ \ifnum\POL@isolzmult@index=\z@ 0\fi 1%
+ \repeat
+ \let\POL@sturmname\POL@isolzmult@newsturmname
+ \if1\ifnum\POL@isolz@NbOfRoots@with_unknown_mult=\z@ 0\fi
+ % (if new GCD is constant, time to abort)
+ \ifnum\POL@isolzmult@newGCDdegree=\z@ 0\fi 1%
\expandafter\POL@isolzmult@loop
\fi
}%
-\def\POL@isolzmult@loop@zero_isknown{%
+\def\POL@isolzmult@doone{%
+ \csname POL@IfMultIsKnown\POL@isolzmult@index\endcsname
+ {}% nothing to do
+ {\POL@SturmIfZeroExactlyKnown{\POL@originalsturmname}%
+ {\POL@isolzmult@index}%
+ \POL@isolzmult@loop@isknown
+ \POL@isolzmult@loop@isnotknown
+ \POL@isolzmult@loop@sharedbody
+ }%
+}%
+\def\POL@isolzmult@loop@isknown{%
\xintifZero
- {\Pol@Eval{\POL@sturmname _0_}%
+ % attention that \POL@eval requires a declared polynomial
+ {\POL@eval{\POL@isolzmult@lastGCD}%
{\POL@xintexprGetVar{\POL@originalsturmname L_\POL@isolzmult@index}}}%
{\let\POL@isolzmult@haszero\@ne}%
{\let\POL@isolzmult@haszero\z@}%
}%
-\def\POL@isolzmult@loop@zero_isnotknown{%
+\def\POL@isolzmult@loop@isnotknown{%
\edef\POL@isolzmult@loop@A
{\POL@xintexprGetVar{\POL@originalsturmname L_\POL@isolzmult@index}}
\edef\POL@isolzmult@loop@B
- {\POL@xintexprGetVar{\POL@originalsturmname R_\POL@isolzmult@index}}
+ {\POL@xintexprGetVar{\POL@originalsturmname
+ R_\POL@isolzmult@index}}
+ % attention that \PolSetToNbOfZerosWithin sets \POL@sturmname to 2nd argument
\PolSetToNbOfZerosWithin
\POL@isolzmult@haszero % nb of zeros A < x <= B, here 0 or 1
- \POL@sturmname
+ \POL@isolzmult@newsturmname
\POL@isolzmult@loop@A
\POL@isolzmult@loop@B
}%
@@ -928,10 +1402,6 @@
\@namedef{POL@IfMultIsKnown\POL@isolzmult@index}{\xint_firstoftwo}%
\edef\POL@isolz@NbOfRoots@with_unknown_mult
{\the\numexpr\POL@isolz@NbOfRoots@with_unknown_mult-\@ne}%
- \ifnum\POL@isolz@NbOfRoots@with_unknown_mult=\z@
- \def\POL@sturmfinaldeg{0}% flag to force termination
- \expandafter\expandafter\expandafter\xintBreakFor
- \fi
\fi
}%
@@ -1039,7 +1509,7 @@
}%
% utility macro for a priori bound on root decimal exponent, via Float Rounding
\def\POL@isolz@updateE #1e#2;%
-{\unless\ifnum#2<\POL@isolz@E\space\edef\POL@isolz@E{\the\numexpr#2+\@ne}\fi}%
+ {\unless\ifnum#2<\POL@isolz@E\space\edef\POL@isolz@E{\the\numexpr#2+\@ne}\fi}%
\def\POL@isolz@getaprioribound{%
\PolAssign{\POL@sturmname _0}\toarray\POL@arrayA
\edef\POL@isolz@leading{\POL@arrayA{\POL@arrayA{0}}}%
@@ -1067,12 +1537,14 @@
\def\POL@IsoRight@raw{\POL@IsoRight@Int/1[\POL@isolz@E]}%
\def\POL@IsoLeft@raw {\POL@IsoLeft@Int/1[\POL@isolz@E]}%
\def\POL@IsoRight@rawout{%
- \ifnum\POL@IsoRightSign=\z@\expandafter\xintREZ\fi\POL@IsoRight@raw}%
+ \ifnum\POL@IsoRightSign=\z@\expandafter\xintREZ\fi\POL@IsoRight@raw
+}%
\def\POL@IsoLeft@rawout{%
\ifnum\POL@IsoRightSign=\z@
\expandafter\xint_firstoftwo\else\expandafter\xint_secondoftwo
\fi{\xintREZ\POL@IsoRight@raw}%
- {\POL@IsoLeft@Int/1[\POL@isolz@E]}}%
+ {\POL@IsoLeft@Int/1[\POL@isolz@E]}%
+}%
\def\POL@isolz@main {%
% NOTE 2018/02/16. THIS WILL PRESUMABLY BE RE-ORGANIZED IN FUTURE TO DO
% FIRST POSITIVE ROOTS THEN NEGATIVE ROOTS VIA CHANGE OF VARIABLE TO OPPOSITE.
@@ -1090,116 +1562,137 @@
\edef\POL@IsoRightSV{\the\numexpr\POL@IsoRightSV+\@ne}%
% subtlety here if original polynomial had multiplicities, but ok. I checked!
\edef\POL@IsoRightSign % evaluated twice, but that's not so bad
- {\xintiiOpp{\xintiiSgn{\Pol@Eval{\POL@sturmname _1}{0/1[0]}}}}%
+ {\xintiiOpp{\xintiiSgn{\POL@eval{\POL@sturmname _1}{0/1[0]}}}}%
\fi
\def\POL@IsoLeft@Int{-1}% -10^E isn't a root!
\let\POL@IsoLeftSV \POL@isolz@minusinf@SV
\let\POL@IsoLeftSign\POL@isolz@minusinf@sign
+ % \POL@IsoRight@SV was modified if zero is a root
\edef\POL@isolz@NbOfNegRoots{\the\numexpr\POL@IsoLeftSV-\POL@IsoRightSV}%
\gdef\POL@isolz@IntervalIndex{0}%
- \begingroup
- \let\POL@IsoAtZeroSV\POL@IsoRightSV % locally shifted if root at zero
- \let\POL@IsoAtZeroSign\POL@IsoRightSign
+ \let\POL@isolz@@E\POL@isolz@E
\ifnum\POL@isolz@NbOfNegRoots>\z@
- \def\POL@IsoRight@Int{-1}%
- \xintloop
- \edef\POL@isolz@E{\the\numexpr\POL@isolz@E-\@ne}%
- \POL@sturmchain@getSV@at\POL@IsoRight@raw
- \let\POL@IsoRightSV \POL@sturmchain@SV
- \let\POL@IsoRightSign\POL@sturmchain@sign
- % would an \ifx test be quicker? (to be checked)
- \ifnum\POL@IsoRightSV=\POL@IsoLeftSV\space
- % no roots in-between, sign and SV kept
- \repeat
- \def\POL@IsoLeft@Int{-10}%
- \let\POL@@IsoRightSign\POL@IsoRightSign % zero possible
- \let\POL@@IsoRightSV\POL@IsoRightSV
- \xintloop
- \edef\POL@IsoRight@Int{\the\numexpr\POL@IsoLeft@Int+\@ne}%
-% we could arguably do a more efficient dichotomy here
- \POL@sturmchain@getSV@at\POL@IsoRight@raw
- \let\POL@IsoRightSV \POL@sturmchain@SV
- \let\POL@IsoRightSign\POL@sturmchain@sign
- \POL@isolz@check
- \ifnum\POL@isolz@IntervalIndex=\POL@isolz@NbOfNegRoots\space
- \expandafter\xintbreakloop
- \fi
- \let\POL@IsoLeft@Int\POL@IsoRight@Int
- \let\POL@IsoLeftSign\POL@IsoRightSign
- \let\POL@IsoLeftSV\POL@IsoRightSV
- \ifnum\POL@IsoRight@Int < -\tw@
- \repeat
- \ifnum\POL@isolz@IntervalIndex<\POL@isolz@NbOfNegRoots\space
- \def\POL@IsoRight@Int{-1}%
- \let\POL@IsoRightSign\POL@@IsoRightSign
- \let\POL@IsoRightSV\POL@@IsoRightSV
- \POL@isolz@check
- \ifnum\POL@isolz@IntervalIndex<\POL@isolz@NbOfNegRoots\space
- \def\POL@IsoLeft@Int{-1}%
- \let\POL@IsoLeftSign\POL@IsoRightSign
- \let\POL@IsoLeftSV\POL@IsoRightSV
- \def\POL@IsoRight@Int{0}%
- \let\POL@IsoRightSV\POL@IsoAtZeroSV % altered if 0 was a root
- \let\POL@IsoRightSign\POL@IsoAtZeroSign% id.
-% this will recurse to locate roots with smaller decimal exponents
- \POL@isolz@check % attention that this should not re-evaluate at 0
- \fi
- \fi
+% refactored at 0.7 to fix cases leading to an intervals with zero as end-point
+ \POL@isolz@findroots@neg
\fi
- \endgroup
+ \let\POL@isolz@E\POL@isolz@@E
\def\POL@IsoLeft@Int{0}%
- \let\POL@IsoLeftSV \POL@IsoAtZeroSV
- \let\POL@IsoLeftSign\POL@IsoAtZeroSign
+ \let\POL@IsoLeftSV \POL@IsoAtZeroSV % véritable SV en zéro
+ \let\POL@IsoLeftSign\POL@IsoAtZeroSign% véritable signe en zéro
\ifnum\POL@IsoLeftSign=\z@
\xdef\POL@isolz@IntervalIndex{\the\numexpr\POL@isolz@IntervalIndex+\@ne}%
- \global\POL@isolz@nextwillneedrefinetrue
- \else
- \global\POL@isolz@nextwillneedrefinefalse
\fi
\let\POL@@IsoRightSV \POL@isolz@plusinf@SV
\let\POL@@IsoRightSign\POL@isolz@plusinf@sign % 10^E not a root!
\edef\POL@isolz@NbOfPosRoots
{\the\numexpr\POL@IsoLeftSV-\POL@@IsoRightSV}% attention @@
\ifnum\POL@isolz@NbOfPosRoots>\z@
- \def\POL@IsoRight@Int{1}%
- \xintloop
- \edef\POL@isolz@E{\the\numexpr\POL@isolz@E-\@ne}%
- \POL@sturmchain@getSV@at\POL@IsoRight@raw
- \let\POL@IsoRightSV \POL@sturmchain@SV
- \let\POL@IsoRightSign\POL@sturmchain@sign
- \ifnum\POL@IsoRightSV=\POL@@IsoRightSV\space
- \let\POL@@IsoRightSign\POL@IsoRightSign % root here possible!
- \repeat
- \unless\ifnum\POL@IsoRightSV=\POL@IsoLeftSV\space
- \POL@isolz@check % will recurse inside groups if needed
- \fi
- \def\POL@IsoLeft@Int{1}%
- \let\POL@IsoLeftSV\POL@IsoRightSV
- \let\POL@IsoLeftSign\POL@IsoRightSign
- \xintloop
-% we could arguably do a more efficient dichotomy here
- \edef\POL@IsoRight@Int{\the\numexpr\POL@IsoLeft@Int+\@ne}%
- \POL@sturmchain@getSV@at\POL@IsoRight@raw
- \let\POL@IsoRightSV \POL@sturmchain@SV
- \let\POL@IsoRightSign\POL@sturmchain@sign
- \POL@isolz@check
- \let\POL@IsoLeft@Int\POL@IsoRight@Int
- \let\POL@IsoLeftSign\POL@IsoRightSign
- \let\POL@IsoLeftSV\POL@IsoRightSV
- \ifnum\POL@isolz@IntervalIndex=\POL@isolz@NbOfRoots\space
- \expandafter\xintbreakloop
- \fi
- \ifnum\POL@IsoLeft@Int < \xint_c_ix
- \repeat
- \ifnum\POL@isolz@IntervalIndex<\POL@isolz@NbOfRoots\space
- % get now the last, rightmost, root (or roots)
- \def\POL@IsoRight@Int{10}%
- \let\POL@IsoRightSign\POL@@IsoRightSign
- \let\POL@IsoRightSV\POL@@IsoRightSV
- \POL@isolz@check
- \fi
+ % always do that to avoid zero as end-point whether it is a root or not
+ \global\POL@isolz@nextwillneedrefinetrue
+ \POL@isolz@findroots@pos
+ \fi
+}%
+\def\POL@isolz@findroots@neg{%
+ \def\POL@IsoRight@Int{-1}%
+ \POL@isolz@findnextzeroboundeddecade@neg
+ \def\POL@IsoLeft@Int{-10}%
+ \let\POL@@IsoRightSign\POL@IsoRightSign % a zero there is possible
+ \let\POL@@IsoRightSV \POL@IsoRightSV
+ % this will do possibly recursive \POL@isolz@check's
+ \POL@isolz@explorenexteightsubdecades@neg
+ \ifnum\POL@isolz@IntervalIndex<\POL@isolz@NbOfNegRoots\space
+ % above did not explore -2, -1 for this optimization (SV known at Right)
+ \def\POL@IsoRight@Int{-1}%
+ \let\POL@IsoRightSign\POL@@IsoRightSign
+ \let\POL@IsoRightSV \POL@@IsoRightSV
+ \POL@isolz@check
+ \ifnum\POL@isolz@IntervalIndex<\POL@isolz@NbOfNegRoots\space
+ \def\POL@IsoLeft@Int{-1}%
+ \let\POL@IsoLeftSign\POL@@IsoRightSign
+ \let\POL@IsoLeftSV \POL@@IsoRightSV
+ % I don't like being inside TeX conditionals
+ \expandafter\expandafter\expandafter\POL@isolz@findroots@neg
+ \fi
+ \fi
+}%
+\def\POL@isolz@findnextzeroboundeddecade@neg{%
+ \xintloop
+ \edef\POL@isolz@E{\the\numexpr\POL@isolz@E-\@ne}%
+ \POL@sturmchain@getSV@at\POL@IsoRight@raw
+ \let\POL@IsoRightSV \POL@sturmchain@SV
+ \let\POL@IsoRightSign\POL@sturmchain@sign
+ % would an \ifx test be quicker? (to be checked)
+ \ifnum\POL@IsoRightSV=\POL@IsoLeftSV\space
+ % no roots in-between, iterate
+ \repeat
+}%
+\def\POL@isolz@explorenexteightsubdecades@neg{%
+ \xintloop
+ \edef\POL@IsoRight@Int{\the\numexpr\POL@IsoLeft@Int+\@ne}%
+ % we could arguably do a more efficient dichotomy here
+ \POL@sturmchain@getSV@at\POL@IsoRight@raw
+ \let\POL@IsoRightSV \POL@sturmchain@SV
+ \let\POL@IsoRightSign\POL@sturmchain@sign
+ \POL@isolz@check % may recurse if multiple roots are to be found
+ \ifnum\POL@isolz@IntervalIndex=\POL@isolz@NbOfNegRoots\space
+ \expandafter\xintbreakloop
+ \fi
+ \let\POL@IsoLeft@Int\POL@IsoRight@Int
+ \let\POL@IsoLeftSign\POL@IsoRightSign
+ \let\POL@IsoLeftSV\POL@IsoRightSV
+ \ifnum\POL@IsoRight@Int < -\tw@
+ \repeat
+}%
+\def\POL@isolz@findroots@pos{%
+ % remark (2018/12/08), this needs some refactoring, I hardly understand
+ % the logic and it hides most into the recursion done by \POL@isolz@check
+ % It would probably make more sense to proceed like done for the negative
+ % but here finding the largest roots first.
+ \def\POL@IsoRight@Int{1}%
+ \POL@isolz@findnextzeroboundeddecade@pos
+ \unless\ifnum\POL@IsoRightSV=\POL@IsoLeftSV\space
+ % this actually explores the whole of some interval (0, 10^{e-1}]
+ % in a context where some roots are known to be in (10^{e-1}, 10^{e}]
+ % and none are larger
+ \POL@isolz@check % will recurse inside groups if needed with modified E
+ \fi
+ % we know get the roots in the last 9 decades from 10^{e-1} to 10^{e}
+ % we should arguably do a more efficient dichotomy here
+ \def\POL@IsoLeft@Int{1}%
+ \let\POL@IsoLeftSV\POL@IsoRightSV
+ \let\POL@IsoLeftSign\POL@IsoRightSign
+ \xintloop
+ \edef\POL@IsoRight@Int{\the\numexpr\POL@IsoLeft@Int+\@ne}%
+ \POL@sturmchain@getSV@at\POL@IsoRight@raw
+ \let\POL@IsoRightSV \POL@sturmchain@SV
+ \let\POL@IsoRightSign\POL@sturmchain@sign
+ \POL@isolz@check % recurses in needed
+ \let\POL@IsoLeft@Int\POL@IsoRight@Int
+ \let\POL@IsoLeftSign\POL@IsoRightSign
+ \let\POL@IsoLeftSV\POL@IsoRightSV
+ \ifnum\POL@isolz@IntervalIndex=\POL@isolz@NbOfRoots\space
+ \expandafter\xintbreakloop
+ \fi
+ \ifnum\POL@IsoLeft@Int < \xint_c_ix
+ \repeat
+ \ifnum\POL@isolz@IntervalIndex<\POL@isolz@NbOfRoots\space
+ % get now the last, rightmost, root (or roots)
+ \def\POL@IsoRight@Int{10}%
+ \let\POL@IsoRightSign\POL@@IsoRightSign
+ \let\POL@IsoRightSV\POL@@IsoRightSV
+ \POL@isolz@check
\fi
}%
+\def\POL@isolz@findnextzeroboundeddecade@pos{%
+ \xintloop
+ \edef\POL@isolz@E{\the\numexpr\POL@isolz@E-\@ne}%
+ \POL@sturmchain@getSV@at\POL@IsoRight@raw
+ \let\POL@IsoRightSV \POL@sturmchain@SV
+ \let\POL@IsoRightSign\POL@sturmchain@sign
+ \ifnum\POL@IsoRightSV=\POL@@IsoRightSV\space
+ \let\POL@@IsoRightSign\POL@IsoRightSign % root here possible!
+ \repeat
+}%
\def\POL@isolz@check{% \POL@IsoRightSign must be ready for use here
% \ifxintverbose
% \xintMessage{polexpr}{Info}%
@@ -1220,7 +1713,7 @@
\ifPOL@isolz@nextwillneedrefine
\expandafter\expandafter\expandafter\POL@isolz@refine
\else
- % \POL@IsoRightSign is zero iff root now exactly know
+ % \POL@IsoRightSign is zero iff root now exactly known
\POL@refine@storeleftandright
\ifnum\POL@IsoRightSign=\z@
\global\POL@isolz@nextwillneedrefinetrue
@@ -1275,7 +1768,7 @@
\edef\POL@IsoLeft@Int {\xintDSL{\POL@IsoLeft@Int}}%
\edef\POL@IsoRight@Int{\xintInc{\POL@IsoLeft@Int}}%
\edef\POL@IsoRightSign
- {\xintiiSgn{\Pol@Eval{\POL@sturmname _0}{\POL@IsoRight@raw}}}%
+ {\xintiiSgn{\POL@eval{\POL@sturmname _0}{\POL@IsoRight@raw}}}%
\ifnum\POL@IsoRightSign=\POL@@IsoRightSign\space
\repeat
% now second root has been separated from the one at left end point
@@ -1294,7 +1787,7 @@
\else
\edef\POL@IsoRight@Int{\xintDec{\POL@@IsoRight@Int}}%
\edef\POL@IsoRightSign
- {\xintiiSgn{\Pol@Eval{\POL@sturmname _0}{\POL@IsoRight@raw}}}%
+ {\xintiiSgn{\POL@eval{\POL@sturmname _0}{\POL@IsoRight@raw}}}%
\ifnum\POL@IsoRightSign=\POL@@IsoRightSign\space
\POL@refine@doonce % we need to locate in interval (1, 9) in local scale
\else
@@ -1319,17 +1812,17 @@
\let\POL@@IsoRightSign\POL@IsoRightSign
\edef\POL@IsoRight@Int{\xintiiAdd{4}{\POL@IsoLeft@Int}}% 5
\edef\POL@IsoRightSign
- {\xintiiSgn{\Pol@Eval{\POL@sturmname _0}{\POL@IsoRight@raw}}}%
+ {\xintiiSgn{\POL@eval{\POL@sturmname _0}{\POL@IsoRight@raw}}}%
\ifnum\POL@IsoRightSign=\POL@IsoLeftSign\space
\let\POL@IsoLeft@Int\POL@IsoRight@Int % 5
\edef\POL@IsoRight@Int{\xintiiAdd{2}{\POL@IsoLeft@Int}}%
\edef\POL@IsoRightSign
- {\xintiiSgn{\Pol@Eval{\POL@sturmname _0}{\POL@IsoRight@raw}}}%
+ {\xintiiSgn{\POL@eval{\POL@sturmname _0}{\POL@IsoRight@raw}}}%
\ifnum\POL@IsoRightSign=\POL@IsoLeftSign\space
\let\POL@IsoLeft@Int\POL@IsoRight@Int % 7
\edef\POL@IsoRight@Int{\xintInc{\POL@IsoLeft@Int}}%
\edef\POL@IsoRightSign
- {\xintiiSgn{\Pol@Eval{\POL@sturmname _0}{\POL@IsoRight@raw}}}%
+ {\xintiiSgn{\POL@eval{\POL@sturmname _0}{\POL@IsoRight@raw}}}%
\ifnum\POL@IsoRightSign=\POL@IsoLeftSign\space
\let\POL@IsoLeft@Int\POL@IsoRight@Int % 8
\let\POL@IsoRight@Int\POL@@IsoRight@Int % 9
@@ -1343,7 +1836,7 @@
\let\POL@@IsoRight@Int\POL@IsoRight@Int % 7
\edef\POL@IsoRight@Int{\xintInc{\POL@IsoLeft@Int}}% 6
\edef\POL@IsoRightSign
- {\xintiiSgn{\Pol@Eval{\POL@sturmname _0}{\POL@IsoRight@raw}}}%
+ {\xintiiSgn{\POL@eval{\POL@sturmname _0}{\POL@IsoRight@raw}}}%
\ifnum\POL@IsoRightSign=\POL@IsoLeftSign\space
\let\POL@IsoLeft@Int\POL@IsoRight@Int % 6
\let\POL@IsoRight@Int\POL@@IsoRight@Int % 7
@@ -1358,12 +1851,12 @@
\let\POL@@IsoRight@Int\POL@IsoRight@Int % 5
\edef\POL@IsoRight@Int{\xintiiAdd{2}{\POL@IsoLeft@Int}}%
\edef\POL@IsoRightSign
- {\xintiiSgn{\Pol@Eval{\POL@sturmname _0}{\POL@IsoRight@raw}}}%
+ {\xintiiSgn{\POL@eval{\POL@sturmname _0}{\POL@IsoRight@raw}}}%
\ifnum\POL@IsoRightSign=\POL@IsoLeftSign\space
\let\POL@IsoLeft@Int\POL@IsoRight@Int % 3
\edef\POL@IsoRight@Int{\xintInc{\POL@IsoLeft@Int}}% 4
\edef\POL@IsoRightSign
- {\xintiiSgn{\Pol@Eval{\POL@sturmname _0}{\POL@IsoRight@raw}}}%
+ {\xintiiSgn{\POL@eval{\POL@sturmname _0}{\POL@IsoRight@raw}}}%
\ifnum\POL@IsoRightSign=\POL@IsoLeftSign\space
\let\POL@IsoLeft@Int\POL@IsoRight@Int % 4
\let\POL@IsoRight@Int\POL@@IsoRight@Int % 5
@@ -1377,7 +1870,7 @@
\let\POL@@IsoRight@Int\POL@IsoRight@Int % 3
\edef\POL@IsoRight@Int{\xintInc{\POL@IsoLeft@Int}}% 2
\edef\POL@IsoRightSign
- {\xintiiSgn{\Pol@Eval{\POL@sturmname _0}{\POL@IsoRight@raw}}}%
+ {\xintiiSgn{\POL@eval{\POL@sturmname _0}{\POL@IsoRight@raw}}}%
\ifnum\POL@IsoRightSign=\POL@IsoLeftSign\space
\let\POL@IsoLeft@Int\POL@IsoRight@Int % 2
\let\POL@IsoRight@Int\POL@@IsoRight@Int % 3
@@ -1395,35 +1888,43 @@
\xdef\csname POL_ZeroInt\POL@sturmname
R\POL@isolz@IntervalIndex\endcsname
{\PolDecToString{\POL@IsoRight@rawout}}%
- \begingroup\xintglobaldefstrue
- \xintdefvar\POL@sturmname
- L_\POL@isolz@IntervalIndex:=qfrac(\POL@IsoLeft@rawout);%
- \xintdefvar\POL@sturmname
- R_\POL@isolz@IntervalIndex:=qfrac(\POL@IsoRight@rawout);%
- \endgroup
- % added at 0.6+
+ % added at 0.6
\ifnum\POL@IsoRightSign=\z@
\global
\expandafter
\let\csname POL_ZeroIsKnown\POL@sturmname\POL@isolz@IntervalIndex\endcsname
\xint_stop_atfirstoftwo
\fi
+ \begingroup\xintglobaldefstrue
+ \xintdefvar
+ \POL@sturmname L_\POL@isolz@IntervalIndex,%
+ \POL@sturmname R_\POL@isolz@IntervalIndex,%
+ % added at 0.7
+ \POL@sturmname Z_\POL@isolz@IntervalIndex _isknown
+ := qfrac(\POL@IsoLeft@rawout),%
+ qfrac(\POL@IsoRight@rawout),%
+ \ifnum\POL@IsoRightSign=\z@ 1\else 0\fi;%
+ \endgroup
}%
%% \PolRefineInterval
\def\POL@xintexprGetVar#1{\expandafter\expandafter\expandafter
\XINT_expr_unlock\csname XINT_expr_var_#1\endcsname}%
-\def\POL@set@IsoLeft@rawin{%
+% attention, also used by \POL@findrat@loop@a
+\def\POL@get@IsoLeft@rawin{%
\edef\POL@IsoLeft@rawin
{\POL@xintexprGetVar{\POL@sturmname L_\POL@isolz@IntervalIndex}}%
}%
-\def\POL@set@IsoRight@rawin{%
+% attention, also used by \POL@findrat@loop@a
+\def\POL@get@IsoRight@rawin{%
\edef\POL@IsoRight@rawin
{\POL@xintexprGetVar{\POL@sturmname R_\POL@isolz@IntervalIndex}}%
}%
-\def\POL@set@IsoLeft@Int #1/1[#2]{%
- \edef\POL@IsoLeft@Int{\xintDSH{\POL@isolz@E-#2}{#1}}%
+% attention, also used by \POL@findrat@loop@a
+\def\POL@get@Int@aux #1/1[#2]#3#4{\edef#3{\xintDSH{#4-#2}{#1}}}%
+\def\POL@get@IsoLeft@Int{%
+ \expandafter\POL@get@Int@aux\POL@IsoLeft@rawin\POL@IsoLeft@Int\POL@isolz@E
}%
\newcommand\PolRefineInterval{\@ifstar\POL@srefine@start\POL@refine@start}%
\newcommand\POL@refine@start[3][1]{%
@@ -1441,19 +1942,19 @@
\POL@refine@main}%
}%
\def\POL@refine@sharedbody#1{%
- \POL@set@IsoLeft@rawin
+ \POL@get@IsoLeft@rawin
\edef\POL@IsoLeftSign
- {\xintiiSgn{\Pol@Eval{\POL@sturmname _0}{\POL@IsoLeft@rawin}}}%
+ {\xintiiSgn{\POL@eval{\POL@sturmname _0}{\POL@IsoLeft@rawin}}}%
\ifnum\POL@IsoLeftSign=\z@
% do nothing if that interval was already a singleton
\else
% else both end-points are not roots and there is a single one in-between
- \POL@set@IsoRight@rawin
+ \POL@get@IsoRight@rawin
\edef\POL@IsoRightSign{\the\numexpr-\POL@IsoLeftSign}%
\edef\POL@isolz@E{\expandafter\POL@refine@getE
% je pense que le xintrez ici est superflu
\romannumeral0\xintrez{\xintSub{\POL@IsoRight@rawin}{\POL@IsoLeft@rawin}}}%
- \expandafter\POL@set@IsoLeft@Int\POL@IsoLeft@rawin
+ \POL@get@IsoLeft@Int
\edef\POL@IsoRight@Int{\xintInc{\POL@IsoLeft@Int}}%
#1%
\POL@refine@storeleftandright % \POL@IsoRightSign not zero
@@ -1478,7 +1979,7 @@
\let\POL@@IsoRightSign\POL@IsoRightSign
\edef\POL@IsoRight@Int{\xintInc{\POL@IsoLeft@Int}}%
\edef\POL@IsoRightSign
- {\xintiiSgn{\Pol@Eval{\POL@sturmname _0}{\POL@IsoRight@raw}}}%
+ {\xintiiSgn{\POL@eval{\POL@sturmname _0}{\POL@IsoRight@raw}}}%
\ifnum\POL@IsoRightSign=\z@
\let\POL@IsoLeft@Int\POL@IsoRight@Int % root at 1
\def\POL@IsoLeftSign{0}%
@@ -1491,7 +1992,7 @@
\let\POL@IsoLeft@Int\POL@IsoRight@Int
\edef\POL@IsoRight@Int{\xintDec{\POL@@IsoRight@Int}}%
\edef\POL@IsoRightSign
- {\xintiiSgn{\Pol@Eval{\POL@sturmname _0}{\POL@IsoRight@raw}}}%
+ {\xintiiSgn{\POL@eval{\POL@sturmname _0}{\POL@IsoRight@raw}}}%
\ifnum\POL@IsoRightSign=\z@
\let\POL@IsoLeft@Int\POL@IsoRight@Int % root at 9
\def\POL@IsoLeftSign{0}%
@@ -1525,11 +2026,16 @@
\newcommand\PolEnsureIntervalLengths[2]{% #1 = Sturm chain name,
% localize roots in intervals of length at most 10^{#2}
- \POL@count\z@
- % \POL@count used by \POL@sturmchain@getSV@at but latter not used
\edef\POL@sturmname{#1}%
\edef\POL@ensure@targetE{\the\numexpr#2}%
- \edef\POL@nbofroots{\csname POL_ZeroInt\POL@sturmname L\endcsname 0}%
+ \edef\POL@nbofroots{\csname POL_ZeroInt\POL@sturmname L0\endcsname}%
+ \ifnum\POL@nbofroots>\z@
+ \expandafter\POL@ensureintervallengths
+ \fi
+}%
+\def\POL@ensureintervallengths{%
+ \POL@count\z@
+ % \POL@count used by \POL@sturmchain@getSV@at but latter not used
\xintloop
\advance\POL@count\@ne
\edef\POL@isolz@IntervalIndex{\the\POL@count}%
@@ -1543,20 +2049,27 @@
\edef\POL@sturmname{#1}%
\edef\POL@ensure@targetE{\the\numexpr#3}%
\edef\POL@isolz@IntervalIndex{\the\numexpr#2}%
- \POL@ensure@one
+% peut-être autoriser -1, -2, ... ?
+ \ifnum\POL@isolz@IntervalIndex>\z@
+% 0.7, add this safeguard but attention means this structure must be in place
+ \ifnum\csname POL_ZeroInt\POL@sturmname L0\endcsname>\z@
+% je ne fais pas les \expandafter mais je préfèrerai ne pas être à l'intérieur
+ \POL@ensure@one
+ \fi
+ \fi
}%
\def\POL@ensure@one{%
- \POL@set@IsoLeft@rawin
- \POL@set@IsoRight@rawin
+ \POL@get@IsoLeft@rawin
+ \POL@get@IsoRight@rawin
\edef\POL@ensure@delta{\xintREZ{\xintSub{\POL@IsoRight@rawin}{\POL@IsoLeft@rawin}}}%
\xintiiifZero{\POL@ensure@delta}
{}
{\edef\POL@isolz@E{\expandafter\POL@refine@getE\POL@ensure@delta}%
- \expandafter\POL@set@IsoLeft@Int\POL@IsoLeft@rawin
+ \POL@get@IsoLeft@Int
\edef\POL@IsoRight@Int{\xintInc{\POL@IsoLeft@Int}}%
\ifnum\POL@isolz@E>\POL@ensure@targetE\space
\edef\POL@IsoLeftSign
- {\xintiiSgn{\Pol@Eval{\POL@sturmname _0}{\POL@IsoLeft@raw}}}%
+ {\xintiiSgn{\POL@eval{\POL@sturmname _0}{\POL@IsoLeft@raw}}}%
% at start left and right are not roots, and values of opposite signs
% \edef\POL@IsoRightSign{\the\numexpr-\POL@IsoLeftSign}%
\xintloop
@@ -1576,7 +2089,7 @@
\xintloop
\edef\POL@IsoRight@Int{\xintInc{\POL@IsoLeft@Int}}%
\edef\POL@IsoRightSign
- {\xintiiSgn{\Pol@Eval{\POL@sturmname _0}{\POL@IsoRight@raw}}}%
+ {\xintiiSgn{\POL@eval{\POL@sturmname _0}{\POL@IsoRight@raw}}}%
% if we have found a zero at right boundary the \ifnum test will fail
% and we exit the loop
% else we exit the loop if sign at right boundary is opposite of
@@ -1595,54 +2108,119 @@
\catcode`_ 8
-\newcommand\PolPrintIntervals[2][Z]{%
- \POL@count \@nameuse{POL_ZeroInt#2L}{0}
- \ifnum\POL@count=\z@
-% No real roots.\par
+\newcommand\PolPrintIntervals
+ {\@ifstar{\PolPrintIntervals@@}{\PolPrintIntervals@}}%
+\newcommand\PolPrintIntervals@@{%
+ \begingroup
+ \def\POL@AfterPrintIntervals{\endgroup}%
+ \def\arraystretch{2}%
+ \let\PolPrintIntervalsPrintExactZero\POL@@PrintIntervalsPrintExactZero
+ \let\PolPrintIntervalsUnknownRoot\POL@@PrintIntervalsUnknownRoot
+ \let\PolPrintIntervalsKnownRoot\POL@@PrintIntervalsKnownRoot
+ \def\PolPrintIntervalsBeginEnv{\[\begin{array}{cl}}%\]
+ \def\PolPrintIntervalsEndEnv{\end{array}\]}%
+ \PolPrintIntervals@
+}%
+\newcommand\PolPrintIntervals@[2][Z]{\POL@PrintIntervals{#1}{#2}}%
+\newcommand\POL@PrintIntervals[2]{%
+ \def\PolPrintIntervalsTheSturmName{#2}%
+ \def\PolPrintIntervalsTheVar{#1}%
+ \ifnum\@nameuse{POL_ZeroInt#2L}{0}=\z@
+ \PolPrintIntervalsNoRealRoots
\else
-% There are \the\POL@count\space distinct real roots:\par
- \[\count@\POL@count
- \global\POL@count\@ne
- \begin{array}{rcccl}
- \xintloop
- \POL@SturmIfZeroExactlyKnown{#2}\POL@count
- {% exact root
- &&
- #1_{\the\POL@count}&=&
- \POL@printintervals@prepare{#2R}%
- \PolPrintIntervalsPrintExactZero
- }%
- {% interval with root in its strict interior
- \POL@printintervals@prepare{#2L}%
- \PolPrintIntervalsPrintLeftEndPoint&<&
- #1_{\the\POL@count}&<&
- \POL@printintervals@prepare{#2R}%
- \PolPrintIntervalsPrintRightEndPoint
- }%
- \global\advance\POL@count\@ne
- \unless\ifnum\POL@count>\count@
- \\%
- \repeat
- \end{array}\]
+ \gdef\PolPrintIntervalsTheIndex{1}%
+ \POL@PrintIntervals@DoDefs
+ \begingroup\edef\POL@tmp{\endgroup
+ \unexpanded\expandafter{\PolPrintIntervalsBeginEnv}%
+ \unexpanded\expandafter{\POL@PrintIntervals@Loop}%
+ \unexpanded\expandafter{\PolPrintIntervalsEndEnv}%
+ }\POL@tmp
\fi
+ \POL@AfterPrintIntervals
+}%
+\let\POL@AfterPrintIntervals\@empty
+\newcommand\PolPrintIntervalsNoRealRoots{}%
+\newcommand\PolPrintIntervalsBeginEnv{\[\begin{array}{rcccl}}%
+\newcommand\PolPrintIntervalsEndEnv{\end{array}\]}%
+\newcommand\PolPrintIntervalsKnownRoot{%
+ &&\PolPrintIntervalsTheVar_{\PolPrintIntervalsTheIndex}%
+ &=&\PolPrintIntervalsPrintExactZero
+}%
+\newcommand\PolPrintIntervalsUnknownRoot{%
+ \PolPrintIntervalsPrintLeftEndPoint&<&%
+ \PolPrintIntervalsTheVar_{\PolPrintIntervalsTheIndex}&<&%
+ \PolPrintIntervalsPrintRightEndPoint
+}%
+\newcommand\PolPrintIntervalsPrintExactZero {\PolPrintIntervalsTheLeftEndPoint}%
+\newcommand\PolPrintIntervalsPrintLeftEndPoint {\PolPrintIntervalsTheLeftEndPoint}%
+\newcommand\PolPrintIntervalsPrintRightEndPoint{\PolPrintIntervalsTheRightEndPoint}%
+\newcommand\PolPrintIntervalsPrintMultiplicity{(\mbox{mult. }\PolPrintIntervalsTheMultiplicity)}%
+%
+\newcommand\POL@@PrintIntervalsKnownRoot{%
+ \PolPrintIntervalsPrintMultiplicity&%
+ \PolPrintIntervalsTheVar_{\PolPrintIntervalsTheIndex}=%
+ \PolPrintIntervalsPrintExactZero
+}%
+\newcommand\POL@@PrintIntervalsPrintExactZero{%
+ \displaystyle
+ \xintSignedFrac{\PolPrintIntervalsTheLeftEndPoint}%
+}%
+\newcommand\POL@@PrintIntervalsUnknownRoot{%
+ \PolPrintIntervalsPrintMultiplicity&%
+ \xintifSgn{\PolPrintIntervalsTheLeftEndPoint}%
+ {\xintifSgn{\PolPrintIntervalsTheRightEndPoint}
+ {\PolPrintIntervalsTheVar_{\PolPrintIntervalsTheIndex}=%
+ \PolPrintIntervalsPrintRightEndPoint\dots}%
+ {0>\PolPrintIntervalsTheVar_{\PolPrintIntervalsTheIndex}>%
+ \PolPrintIntervalsPrintLeftEndPoint}%
+ {\PolErrorThisShouldNotHappenPleaseReportToAuthorA}}%
+ {\xintifSgn{\PolPrintIntervalsTheRightEndPoint}
+ {\PolErrorThisShouldNotHappenPleaseReportToAuthorB}%
+ {\PolErrorThisShouldNotHappenPleaseReportToAuthorC}%
+ {0<\PolPrintIntervalsTheVar_{\PolPrintIntervalsTheIndex}<%
+ \PolPrintIntervalsPrintRightEndPoint}}%
+ {\xintifSgn{\PolPrintIntervalsTheRightEndPoint}
+ {\PolErrorThisShouldNotHappenPleaseReportToAuthorD}%
+ {\PolErrorThisShouldNotHappenPleaseReportToAuthorE}%
+ {\PolPrintIntervalsTheVar_{\PolPrintIntervalsTheIndex}=%
+ \PolPrintIntervalsPrintLeftEndPoint\dots}}%
}%
+%
\catcode`_ 11
-\newcommand\PolPrintIntervalsPrintExactZero {\PolPrintIntervalsTheEndPoint}%
-\newcommand\PolPrintIntervalsPrintLeftEndPoint {\PolPrintIntervalsTheEndPoint}%
-\newcommand\PolPrintIntervalsPrintRightEndPoint{\PolPrintIntervalsTheEndPoint}%
-\def\POL@printintervals@prepare#1{%
- \edef\PolPrintIntervalsTheIndex{\the\POL@count}%
- \edef\PolPrintIntervalsTheEndPoint{\@nameuse{POL_ZeroInt#1}\POL@count}%
- \xintiiifSgn{\POL@xintexprGetVar{#1_\PolPrintIntervalsTheIndex}}
- {\let\PolIfEndPointIsPositive\xint_secondoftwo
- \let\PolIfEndPointIsNegative\xint_firstoftwo
- \let\PolIfEndPointIsZero\xint_secondoftwo}
- {\let\PolIfEndPointIsPositive\xint_secondoftwo
- \let\PolIfEndPointIsNegative\xint_secondoftwo
- \let\PolIfEndPointIsZero\xint_firstoftwo}
- {\let\PolIfEndPointIsPositive\xint_firstoftwo
- \let\PolIfEndPointIsNegative\xint_secondoftwo
- \let\PolIfEndPointIsZero\xint_secondoftwo}%
+\def\POL@PrintIntervals@Loop{%
+ \POL@SturmIfZeroExactlyKnown\PolPrintIntervalsTheSturmName
+ \PolPrintIntervalsTheIndex
+ \PolPrintIntervalsKnownRoot
+ \PolPrintIntervalsUnknownRoot
+ \xdef\PolPrintIntervalsTheIndex{\the\numexpr\PolPrintIntervalsTheIndex+\@ne}%
+ \unless\ifnum\PolPrintIntervalsTheIndex>
+ \@nameuse{POL_ZeroInt\PolPrintIntervalsTheSturmName L0}
+ \POL@PrintIntervals@DoDefs
+ \xint_afterfi{\\\POL@PrintIntervals@Loop}%
+ \fi
+}%
+\def\POL@PrintIntervals@DoDefs{%
+ \xdef\PolPrintIntervalsTheLeftEndPoint{%
+ \csname POL_ZeroInt%
+ \PolPrintIntervalsTheSturmName L\PolPrintIntervalsTheIndex
+ \endcsname
+ }%
+ \xdef\PolPrintIntervalsTheRightEndPoint{%
+ \csname POL_ZeroInt%
+ \PolPrintIntervalsTheSturmName R\PolPrintIntervalsTheIndex
+ \endcsname
+ }%
+ \xdef\PolPrintIntervalsTheMultiplicity{%
+ \ifcsname POL_ZeroMult%
+ \PolPrintIntervalsTheSturmName\PolPrintIntervalsTheIndex
+ \endcsname
+ \csname POL_ZeroMult%
+ \PolPrintIntervalsTheSturmName\PolPrintIntervalsTheIndex
+ \endcsname
+ \else
+ ?% or use 0 ?
+ \fi
+ }%
}%
@@ -1650,18 +2228,38 @@
\romannumeral0\csname POL_ZeroIsKnown#1\endcsname{#2}%
}%
\newcommand\POL@SturmIfZeroExactlyKnown[2]{% #1 = sturmname, #2=index
- \romannumeral0\csname POL_ZeroIsKnown#1\the\numexpr#2\relax\endcsname
+ \romannumeral0\csname POL_ZeroIsKnown#1\the\numexpr#2\endcsname
}%
\newcommand\PolSturmIsolatedZeroMultiplicity[2]{%
\romannumeral`^^@\csname POL_ZeroMult#1\endcsname{#2}%
}%
\newcommand\PolSturmIsolatedZeroLeft[2]{%
- \romannumeral`^^@\csname POL_ZeroInt#1L\endcsname{#2}}%
+ \romannumeral`^^@\csname POL_ZeroInt#1L\endcsname{#2}%
+}%
\newcommand\PolSturmIsolatedZeroRight[2]{%
- \romannumeral`^^@\csname POL_ZeroInt#1R\endcsname{#2}}%
+ \romannumeral`^^@\csname POL_ZeroInt#1R\endcsname{#2}%
+}%
\newcommand\PolSturmNbOfIsolatedZeros[1]{%
\romannumeral`^^@\csname POL_ZeroInt#1L0\endcsname
}%
+\newcommand\PolSturmRationalRoot[2]{%
+ \romannumeral`^^@\csname POL_ZeroInt#1L%
+ \csname POL_RRIndex#1\endcsname{#2}\endcsname
+}%
+\newcommand\PolSturmRationalRootIndex[2]{%
+ \romannumeral`^^@\csname POL_RRIndex#1\endcsname{#2}%
+}%
+\newcommand\PolSturmRationalRootMultiplicity[2]{%
+ \romannumeral`^^@\csname POL_ZeroMult#1%
+ \csname POL_RRIndex#1\endcsname{#2}\endcsname
+}%
+\newcommand\PolSturmNbOfRationalRoots[1]{%
+ \romannumeral`^^@\csname POL_RRIndex#10\endcsname
+}%
+\newcommand\PolSturmNbOfRationalRootsWithMultiplicities[1]{%
+% means the \POL@norr must not have been changed in-between...
+ \the\numexpr\PolDegree{#1}-\PolDegree{#1\POL@norr}\relax
+}%
\let\PolDecToString\xintDecToString
@@ -2023,18 +2621,18 @@
%% EXPANDABLE MACROS
-\def\Pol@Eval@fork#1\At#2#3\krof{#2}%
-\newcommand\PolEval[3]{\romannumeral`^^@\Pol@Eval@fork
+\def\POL@eval@fork#1\At#2#3\krof{#2}%
+\newcommand\PolEval[3]{\romannumeral`^^@\POL@eval@fork
#2\PolEvalAt
\At\PolEvalAtExpr\krof {#1}{#3}%
}%
\newcommand\PolEvalAt[2]
{\xintpraw{\csname XINT_expr_userfunc_#1\endcsname{#2}}}%
-\newcommand\Pol@Eval[2]
+\newcommand\POL@eval[2]
{\csname XINT_expr_userfunc_#1\endcsname{#2}}%
\newcommand\PolEvalAtExpr[2]{\xinttheexpr #1(#2)\relax}%
%
-\newcommand\PolEvalReduced[3]{\romannumeral`^^@\Pol@Eval@fork
+\newcommand\PolEvalReduced[3]{\romannumeral`^^@\POL@eval@fork
#2\PolEvalReducedAt
\At\PolEvalReducedAtExpr\krof {#1}{#3}%
}%
@@ -2047,7 +2645,7 @@
{\xintIrr{\romannumeral`^^@\xintthebareeval#1(#2)\relax}[0]}%
}%
%
-\newcommand\PolFloatEval[3]{\romannumeral`^^@\Pol@Eval@fork
+\newcommand\PolFloatEval[3]{\romannumeral`^^@\POL@eval@fork
#2\PolFloatEvalAt
\At\PolFloatEvalAtExpr\krof {#1}{#3}%
}%
@@ -2056,37 +2654,48 @@
\newcommand\PolFloatEvalAtExpr[2]{\xintthefloatexpr #1(#2)\relax}%
-\newcommand\PolSturmMultiplicity[3]{\romannumeral`^^@\Pol@Eval@fork
- #2\PolSturmMultiplicityAt
- \At\PolSturmMultiplicityAtExpr\krof {#1}{#3}%
+\newcommand\PolSturmIntervalIndex[3]{\the\numexpr\POL@eval@fork
+ #2\PolSturmIntervalIndexAt
+ \At\PolSturmIntervalIndexAtExpr\krof {#1}{#3}%
}%
-\newcommand\PolSturmMultiplicityAtExpr[2]
- {\PolSturmMultiplicityAt{#1}{\xinttheexpr#2\relax}}%
-\newcommand\PolSturmMultiplicityAt[2]
- {\expandafter\POL@sturm@mult@at\romannumeral`^^@#2!{#1}}%
-\def\POL@sturm@mult@at#1!#2%
+\newcommand\PolSturmIntervalIndexAtExpr[2]
+ {\PolSturmIntervalIndexAt{#1}{\xinttheexpr#2\relax}}%
+\newcommand\PolSturmIntervalIndexAt[2]
+ {\expandafter\POL@sturm@index@at\romannumeral`^^@#2!{#1}\xint_bye\relax}%
+\def\POL@sturm@index@at#1!#2%
{%
- \xintifZero{\Pol@Eval{#2_0}{#1}}%
- {\POL@sturm@mult@at@iloop 1!{#2}{#1}}% we have a zero
- 0% not a zero
+ \expandafter\POL@sturm@index@at@iloop
+ \romannumeral`^^@\PolSturmNbOfIsolatedZeros{#2}!{#2}{#1}%
}%
-\def\POL@sturm@mult@at@iloop #1!#2#3%
+% implementation is sub-optimal as it should use some kind of binary tree
+% search rather than comparing to the intervals from right to left as here
+\def\POL@sturm@index@at@iloop #1!%
+{%
+ \ifnum #1=\z@ 0\expandafter\xint_bye\fi
+ \POL@sturm@index@at@iloop@a #1!%
+}%
+\def\POL@sturm@index@at@iloop@a #1!#2#3%
{% #1 = index, #2 = sturmname, #3 value
- \PolSturmIfZeroExactlyKnown{#2}{#1}%
- {\xintifEq{\POL@xintexprGetVar{#2L_#1}}{#3}%
- {\PolSturmIsolatedZeroMultiplicity{#2}{#1}}%
-% catcode of ! is 11 in polexpr.sty
- {\expandafter\POL@sturm@mult@at@iloop\the\numexpr#1+\@ne !{#2}{#3}}%
+ \PolSturmIfZeroExactlyKnown{#2}{#1}
+ {\xintifCmp{#3}{\POL@xintexprGetVar{#2L_#1}}%
+ {}%
+ {#1\xint_bye}%
+ {0\xint_bye}%
}%
- {\xintifLt{#3}{\POL@xintexprGetVar{#2R_#1}}%
- {\PolSturmIsolatedZeroMultiplicity{#2}{#1}}%
- {\expandafter\POL@sturm@mult@at@iloop\the\numexpr#1+\@ne !{#2}{#3}}%
+ {\xintifGt{#3}{\POL@xintexprGetVar{#2L_#1}}%
+ {\xintifLt{#3}{\POL@xintexprGetVar{#2R_#1}}%
+ {#1\xint_bye}%
+ {0\xint_bye}%
+ }%
+ {}%
}%
+ % catcode of ! is 11 in polexpr.sty
+ \expandafter\POL@sturm@index@at@iloop\the\numexpr#1-\@ne !{#2}{#3}%
}%
-\def\Pol@LessThanOrEqualTo@fork#1\LessThanOrEqualTo#2#3\krof{#2}%
-\newcommand\PolSturmNbOfRootsOf[3]{\romannumeral`^^@\Pol@LessThanOrEqualTo@fork
+\def\POL@leq@fork#1\LessThanOrEqualTo#2#3\krof{#2}%
+\newcommand\PolSturmNbOfRootsOf[3]{\romannumeral`^^@\POL@leq@fork
#2\PolNbOfRootsLessThanOrEqualTo
\LessThanOrEqualTo\PolNbOfRootsLessThanOrEqualToExpr\krof {#1}{#3}%
}%
@@ -2106,7 +2715,7 @@
\def\POL@nbofrootsleq@prep#1!#2%
{%
\expandafter\POL@nbofrootsleq@iloop\expandafter 1\expandafter !%
- \romannumeral0\xintsgn{\Pol@Eval{#2_0}{#1}}!%
+ \romannumeral0\xintsgn{\POL@eval{#2_0}{#1}}!%
#1!{#2}%
}%
\def\POL@nbofrootsleq@iloop#1!#2!#3!#4%
@@ -2120,7 +2729,7 @@
% the test \xintifLt will be negative
{\xintifLt{#3}{\POL@xintexprGetVar{#4R_#1}}%
{\POL@nbofrootsleq@return
- #1\ifnum#2=\xintSgn{\Pol@Eval{#4_0}{\POL@xintexprGetVar{#4L_#1}}}
+ #1\ifnum#2=\xintSgn{\POL@eval{#4_0}{\POL@xintexprGetVar{#4L_#1}}}
-\@ne\fi !%
}%
{\ifnum#1=\PolSturmNbOfIsolatedZeros{#4}
@@ -2135,9 +2744,8 @@
\the\numexpr\@ne+#1!#2!#3!#4{#1}%
-\def\Pol@LessThanOrEqualTo@fork#1\LessThanOrEqualTo#2#3\krof{#2}%
\newcommand\PolSturmNbWithMultOfRootsOf[3]
-{\the\numexpr0\Pol@LessThanOrEqualTo@fork
+{\the\numexpr0\POL@leq@fork
#2\PolNbWithMultOfRootsLessThanOrEqualTo
\LessThanOrEqualTo\PolNbWithMultOfRootsLessThanOrEqualToExpr\krof {#1}{#3}%
}%
@@ -2158,7 +2766,7 @@
\def\POL@nbwmofrootsleq@prep#1!#2%
{%
\expandafter\POL@nbwmofrootsleq@iloop\expandafter 1\expandafter !%
- \romannumeral0\xintsgn{\Pol@Eval{#2_0}{#1}}!%
+ \romannumeral0\xintsgn{\POL@eval{#2_0}{#1}}!%
#1!{#2}%
}%
\def\POL@nbwmofrootsleq@iloop#1!#2!#3!#4%
@@ -2174,7 +2782,7 @@
{\xintifLt{#3}{\POL@xintexprGetVar{#4R_#1}}%
{\POL@nbwmofrootsleq@return
\unless
- \ifnum#2=\xintSgn{\Pol@Eval{#4_0}{\POL@xintexprGetVar{#4L_#1}}}
+ \ifnum#2=\xintSgn{\POL@eval{#4_0}{\POL@xintexprGetVar{#4L_#1}}}
+\PolSturmIsolatedZeroMultiplicity{#4}{#1}\fi !%
}%
{+\PolSturmIsolatedZeroMultiplicity{#4}{#1}%