diff options
-rw-r--r-- | Master/texmf-dist/doc/latex/polexpr/README.md | 14 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/polexpr/polexpr.html | 347 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/polexpr/polexpr.txt | 167 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/polexpr/polexpr.sty | 237 |
4 files changed, 510 insertions, 255 deletions
diff --git a/Master/texmf-dist/doc/latex/polexpr/README.md b/Master/texmf-dist/doc/latex/polexpr/README.md index e4e8fa3b38f..e0508c86d3e 100644 --- a/Master/texmf-dist/doc/latex/polexpr/README.md +++ b/Master/texmf-dist/doc/latex/polexpr/README.md @@ -65,8 +65,18 @@ Releases Synced with xint 1.3. - 0.4.2 (2018/03/03) Documentation fix. - -Files of 0.4.2 release: +- 0.5 (2018/04/08) + - new macros `\PolMakePrimitive` and `\PolIContent`. + - breaking change: `\PolToSturm` creates a chain of primitive + integer coefficients polynomials. + - breaking change: polynomials created from `\PolFromCSV` or + `\PolGet` get their coefficients normalized via + [xintfrac](http://www.ctan.org/pkg/xint)'s `\xintRaw`. + - experimental change: optional argument to + `\PolSturmIsolateZeros` to localize search. + + +Files of 0.5 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 579a6172254..8eeb33a3811 100644 --- a/Master/texmf-dist/doc/latex/polexpr/polexpr.html +++ b/Master/texmf-dist/doc/latex/polexpr/polexpr.html @@ -362,7 +362,7 @@ ul.auto-toc { <body> <div class="document" id="package-polexpr-documentation"> <h1 class="title">Package polexpr documentation</h1> -<h2 class="subtitle" id="id1">0.4.2 (2018/03/03)</h2> +<h2 class="subtitle" id="id1">0.5 (2018/04/08)</h2> <!-- comment: -*- fill-column: 72; mode: rst; -*- --> <div class="contents topic" id="contents"> @@ -422,64 +422,66 @@ ul.auto-toc { <li><a class="reference internal" href="#polreducecoeffs-polname" id="id80"><tt class="docutils literal">\PolReduceCoeffs{polname}</tt></a></li> <li><a class="reference internal" href="#id15" id="id81"><tt class="docutils literal"><span class="pre">\PolReduceCoeffs*{polname}</span></tt></a></li> <li><a class="reference internal" href="#polmakemonic-polname" id="id82"><tt class="docutils literal">\PolMakeMonic{polname}</tt></a></li> +<li><a class="reference internal" href="#polmakeprimitive-polname" id="id83"><tt class="docutils literal">\PolMakePrimitive{polname}</tt></a></li> </ul> </li> -<li><a class="reference internal" href="#expandable-macros" id="id83">Expandable macros</a><ul> -<li><a class="reference internal" href="#poleval-polname-atexpr-numerical-expression" id="id84"><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="id85"><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="id86"><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="id87"><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="id88"><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="id89"><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="id90"><tt class="docutils literal"><span class="pre">\PolIfCoeffIsPlusOrMinusOne{A}{B}</span></tt></a></li> -<li><a class="reference internal" href="#polleadingcoeff-polname" id="id91"><tt class="docutils literal">\PolLeadingCoeff{polname}</tt></a></li> -<li><a class="reference internal" href="#polnthcoeff-polname-number" id="id92"><tt class="docutils literal"><span class="pre">\PolNthCoeff{polname}{number}</span></tt></a></li> -<li><a class="reference internal" href="#poldegree-polname" id="id93"><tt class="docutils literal">\PolDegree{polname}</tt></a></li> -<li><a class="reference internal" href="#poltoexpr-polname" id="id94"><tt class="docutils literal">\PolToExpr{polname}</tt></a><ul> -<li><a class="reference internal" href="#poltoexproneterm-raw-coeff-number" id="id95"><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="id96"><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="id97"><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="id98"><tt class="docutils literal">\PolToExprCmd{raw_coeff}</tt></a></li> -<li><a class="reference internal" href="#poltoexprtermprefix-raw-coeff" id="id99"><tt class="docutils literal">\PolToExprTermPrefix{raw_coeff}</tt></a></li> -<li><a class="reference internal" href="#id23" id="id100"><tt class="docutils literal">\PolToExprVar</tt></a></li> -<li><a class="reference internal" href="#id24" id="id101"><tt class="docutils literal">\PolToExprTimes</tt></a></li> +<li><a class="reference internal" href="#expandable-macros" id="id84">Expandable macros</a><ul> +<li><a class="reference internal" href="#poleval-polname-atexpr-numerical-expression" id="id85"><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="id86"><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="id87"><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="id88"><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="id89"><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="id90"><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="id91"><tt class="docutils literal"><span class="pre">\PolIfCoeffIsPlusOrMinusOne{A}{B}</span></tt></a></li> +<li><a class="reference internal" href="#polleadingcoeff-polname" id="id92"><tt class="docutils literal">\PolLeadingCoeff{polname}</tt></a></li> +<li><a class="reference internal" href="#polnthcoeff-polname-number" id="id93"><tt class="docutils literal"><span class="pre">\PolNthCoeff{polname}{number}</span></tt></a></li> +<li><a class="reference internal" href="#poldegree-polname" id="id94"><tt class="docutils literal">\PolDegree{polname}</tt></a></li> +<li><a class="reference internal" href="#policontent-polname" id="id95"><tt class="docutils literal">\PolIContent{polname}</tt></a></li> +<li><a class="reference internal" href="#poltoexpr-polname" id="id96"><tt class="docutils literal">\PolToExpr{polname}</tt></a><ul> +<li><a class="reference internal" href="#poltoexproneterm-raw-coeff-number" id="id97"><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="id98"><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="id99"><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="id100"><tt class="docutils literal">\PolToExprCmd{raw_coeff}</tt></a></li> +<li><a class="reference internal" href="#poltoexprtermprefix-raw-coeff" id="id101"><tt class="docutils literal">\PolToExprTermPrefix{raw_coeff}</tt></a></li> +<li><a class="reference internal" href="#id23" id="id102"><tt class="docutils literal">\PolToExprVar</tt></a></li> +<li><a class="reference internal" href="#id24" id="id103"><tt class="docutils literal">\PolToExprTimes</tt></a></li> </ul> </li> -<li><a class="reference internal" href="#id26" id="id102"><tt class="docutils literal"><span class="pre">\PolToExpr*{polname}</span></tt></a></li> -<li><a class="reference internal" href="#poltofloatexpr-polname" id="id103"><tt class="docutils literal">\PolToFloatExpr{polname}</tt></a><ul> -<li><a class="reference internal" href="#poltofloatexproneterm-raw-coeff-number" id="id104"><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="id105"><tt class="docutils literal">\PolToFloatExprCmd{raw_coeff}</tt></a></li> +<li><a class="reference internal" href="#id26" id="id104"><tt class="docutils literal"><span class="pre">\PolToExpr*{polname}</span></tt></a></li> +<li><a class="reference internal" href="#poltofloatexpr-polname" id="id105"><tt class="docutils literal">\PolToFloatExpr{polname}</tt></a><ul> +<li><a class="reference internal" href="#poltofloatexproneterm-raw-coeff-number" id="id106"><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="id107"><tt class="docutils literal">\PolToFloatExprCmd{raw_coeff}</tt></a></li> </ul> </li> -<li><a class="reference internal" href="#id30" id="id106"><tt class="docutils literal"><span class="pre">\PolToFloatExpr*{polname}</span></tt></a></li> -<li><a class="reference internal" href="#poltolist-polname" id="id107"><tt class="docutils literal">\PolToList{polname}</tt></a></li> -<li><a class="reference internal" href="#poltocsv-polname" id="id108"><tt class="docutils literal">\PolToCSV{polname}</tt></a></li> -<li><a class="reference internal" href="#polsturmchainlength-sturmname" id="id109"><tt class="docutils literal">\PolSturmChainLength{sturmname}</tt></a></li> -<li><a class="reference internal" href="#polsturmifzeroexactlyknown-sturmname-index-a-b" id="id110"><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="id111"><tt class="docutils literal"><span class="pre">\PolSturmIsolatedZeroLeft{sturmname}{index}</span></tt></a></li> -<li><a class="reference internal" href="#polsturmisolatedzeroright-sturmname-index" id="id112"><tt class="docutils literal"><span class="pre">\PolSturmIsolatedZeroRight{sturmname}{index}</span></tt></a></li> -<li><a class="reference internal" href="#polsturmnbofisolatedzeros-sturmname" id="id113"><tt class="docutils literal">\PolSturmNbOfIsolatedZeros{sturmname}</tt></a></li> -<li><a class="reference internal" href="#polintervalwidth-sturmname-index" id="id114"><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="id115">Macros for use within execution of <tt class="docutils literal">\PolPrintIntervals</tt></a><ul> -<li><a class="reference internal" href="#id31" id="id116"><tt class="docutils literal">\PolPrintIntervalsTheEndPoint</tt></a></li> -<li><a class="reference internal" href="#id32" id="id117"><tt class="docutils literal">\PolPrintIntervalsTheIndex</tt></a></li> -<li><a class="reference internal" href="#polifendpointispositive-a-b" id="id118"><tt class="docutils literal"><span class="pre">\PolIfEndPointIsPositive{A}{B}</span></tt></a></li> -<li><a class="reference internal" href="#polifendpointisnegative-a-b" id="id119"><tt class="docutils literal"><span class="pre">\PolIfEndPointIsNegative{A}{B}</span></tt></a></li> -<li><a class="reference internal" href="#polifendpointiszero-a-b" id="id120"><tt class="docutils literal"><span class="pre">\PolIfEndPointIsZero{A}{B}</span></tt></a></li> +<li><a class="reference internal" href="#id30" id="id108"><tt class="docutils literal"><span class="pre">\PolToFloatExpr*{polname}</span></tt></a></li> +<li><a class="reference internal" href="#poltolist-polname" id="id109"><tt class="docutils literal">\PolToList{polname}</tt></a></li> +<li><a class="reference internal" href="#poltocsv-polname" id="id110"><tt class="docutils literal">\PolToCSV{polname}</tt></a></li> +<li><a class="reference internal" href="#polsturmchainlength-sturmname" id="id111"><tt class="docutils literal">\PolSturmChainLength{sturmname}</tt></a></li> +<li><a class="reference internal" href="#polsturmifzeroexactlyknown-sturmname-index-a-b" id="id112"><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="id113"><tt class="docutils literal"><span class="pre">\PolSturmIsolatedZeroLeft{sturmname}{index}</span></tt></a></li> +<li><a class="reference internal" href="#polsturmisolatedzeroright-sturmname-index" id="id114"><tt class="docutils literal"><span class="pre">\PolSturmIsolatedZeroRight{sturmname}{index}</span></tt></a></li> +<li><a class="reference internal" href="#polsturmnbofisolatedzeros-sturmname" id="id115"><tt class="docutils literal">\PolSturmNbOfIsolatedZeros{sturmname}</tt></a></li> +<li><a class="reference internal" href="#polintervalwidth-sturmname-index" id="id116"><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="id117">Macros for use within execution of <tt class="docutils literal">\PolPrintIntervals</tt></a><ul> +<li><a class="reference internal" href="#id31" id="id118"><tt class="docutils literal">\PolPrintIntervalsTheEndPoint</tt></a></li> +<li><a class="reference internal" href="#id32" id="id119"><tt class="docutils literal">\PolPrintIntervalsTheIndex</tt></a></li> +<li><a class="reference internal" href="#polifendpointispositive-a-b" id="id120"><tt class="docutils literal"><span class="pre">\PolIfEndPointIsPositive{A}{B}</span></tt></a></li> +<li><a class="reference internal" href="#polifendpointisnegative-a-b" id="id121"><tt class="docutils literal"><span class="pre">\PolIfEndPointIsNegative{A}{B}</span></tt></a></li> +<li><a class="reference internal" href="#polifendpointiszero-a-b" id="id122"><tt class="docutils literal"><span class="pre">\PolIfEndPointIsZero{A}{B}</span></tt></a></li> </ul> </li> -<li><a class="reference internal" href="#poldectostring-decimal-number" id="id121"><tt class="docutils literal">\PolDecToString{decimal number}</tt></a></li> +<li><a class="reference internal" href="#poldectostring-decimal-number" id="id123"><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="id122">Booleans (with default setting as indicated)</a><ul> -<li><a class="reference internal" href="#xintverbosefalse" id="id123"><tt class="docutils literal">\xintverbosefalse</tt></a></li> -<li><a class="reference internal" href="#poltypesetallfalse" id="id124"><tt class="docutils literal">\poltypesetallfalse</tt></a></li> -<li><a class="reference internal" href="#poltoexprallfalse" id="id125"><tt class="docutils literal">\poltoexprallfalse</tt></a></li> +<li><a class="reference internal" href="#booleans-with-default-setting-as-indicated" id="id124">Booleans (with default setting as indicated)</a><ul> +<li><a class="reference internal" href="#xintverbosefalse" id="id125"><tt class="docutils literal">\xintverbosefalse</tt></a></li> +<li><a class="reference internal" href="#poltypesetallfalse" id="id126"><tt class="docutils literal">\poltypesetallfalse</tt></a></li> +<li><a class="reference internal" href="#poltoexprallfalse" id="id127"><tt class="docutils literal">\poltoexprallfalse</tt></a></li> </ul> </li> -<li><a class="reference internal" href="#technicalities" id="id126">Technicalities</a></li> -<li><a class="reference internal" href="#change-log" id="id127">CHANGE LOG</a></li> -<li><a class="reference internal" href="#acknowledgments" id="id128">Acknowledgments</a></li> +<li><a class="reference internal" href="#technicalities" id="id128">Technicalities</a></li> +<li><a class="reference internal" href="#change-log" id="id129">CHANGE LOG</a></li> +<li><a class="reference internal" href="#acknowledgments" id="id130">Acknowledgments</a></li> </ul> </div> <div class="section" id="basic-examples"> @@ -580,7 +582,14 @@ PSTricks-compatible; the letter used in output can be </div> <div class="section" id="examples-of-localization-of-roots"> <h1><a class="toc-backref" href="#id36">Examples of localization of roots</a></h1> -<p>First some remarks about auxiliaries.</p> +<div class="admonition attention"> +<p class="first admonition-title">Attention!</p> +<p class="last">At <tt class="docutils literal">0.5</tt>, <a class="reference internal" href="#poltosturm">\PolToSturm{P}{S}</a> was modified to +create a chain of primitive integer coefficients polynomials. This +speeds up evaluations, hence localization of roots afterwards. Thus +<tt class="docutils literal">S_1</tt> will not necessarily be the derivative of <tt class="docutils literal">S_0</tt>, even if +<tt class="docutils literal">P</tt> is square-free.</p> +</div> <ul> <li><p class="first">To make printed decimal numbers more enjoyable than via <tt class="docutils literal">\xintSignedFrac</tt>:</p> @@ -597,9 +606,10 @@ that one can also do:</p> </pre> <p>to modify output of <a class="reference internal" href="#poltoexpr-polname">\PolToExpr{polname}</a>.</p> </li> -<li><p class="first">for extra info in log file <tt class="docutils literal">\xintverbosetrue</tt>. In fact one can also -work from command line then (I recommend <tt class="docutils literal">rlwrap</tt> for encapsulating -<tt class="docutils literal">latex</tt>).</p> +<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> </ul> <div class="section" id="a-typical-example"> @@ -623,8 +633,10 @@ Here is the second root with ten more decimal digits: And here is the first root with twenty digits after decimal mark: \PolEnsureIntervalLength{f}{1}{-20} \[\PolSturmIsolatedZeroLeft{f}{1}<Z_1<\PolSturmIsolatedZeroRight{f}{1}\] -The derivative polynomial is \PolTypeset{f_1} (from -$\PolDegree{f_0}=7$ we know that original polynomial was square-free). +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 +it is identical with it). \PolToSturm{f_1}{f_1}\PolSturmIsolateZeros{f_1}% It has \PolSturmNbOfIsolatedZeros{f_1} distinct real roots: @@ -691,16 +703,20 @@ It has \PolSturmNbOfIsolatedZeros{P} real roots. \PolTypeset{P} % prints it in expanded form \PolToSturm{P}{P} % we can use same prefix for Sturm chain \PolSturmIsolateZeros{P} % finds 4 real roots +This polynomial has \PolSturmNbOfIsolatedZeros{P} distinct real roots: \PolPrintIntervals{P}% % reports -2 < Z_1 < -1, 0 < Z_2 < 0.1, 0.1 < Z_3 < 0.2, 1 < Z_4 < 2 +Let us refine the second and third intervals to separate the corresponding +roots: \PolRefineInterval*{P}{2}% will refine to 0.0999990 < Z_2 < 0.0999991 \PolRefineInterval*{P}{3}% will refine to 0.100001 < Z_3 < 0.100002 \PolPrintIntervals{P}% +Let us now get to know all roots with 10 digits after decimal mark: \PolEnsureIntervalLengths{P}{-10}% \PolPrintIntervals{P}% now all roots are known 10 decimal digits after mark +Finally, we display 20 digits of the second root: \PolEnsureIntervalLength{P}{2}{-20}% makes Z_2 known with 20 digits after mark -There are $\PolSturmNbOfIsolatedZeros{P}$ distinct real roots and there holds -$\PolSturmIsolatedZeroLeft{P}{2}<Z_2<\PolSturmIsolatedZeroRight{P}{2}$. +\[\PolSturmIsolatedZeroLeft{P}{2}<Z_2<\PolSturmIsolatedZeroRight{P}{2}\] </pre> <p>The last line produces:</p> <pre class="literal-block"> @@ -746,10 +762,24 @@ x^41 <p>Stress test: not a hard challenge to <tt class="docutils literal">xint + polexpr</tt>, but be a bit patient!</p> <pre class="literal-block"> \PolDef{P}{mul((x-i*1e-1), i=-20..20)}% -\PolToSturm{P}{S} % dutifully computes S_0, ..., S_{41} -\PolSturmIsolateZeros{S} % finds *exactly* (but a bit slowly) all 41 roots! -\PolPrintIntervals{S} % nice, isn't it? +\PolToSturm{P}{S} % dutifully computes S_0, ..., S_{41} +\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 +<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> +</div> </div> <div class="section" id="roots-of-chebyshev-polynomials"> <h2><a class="toc-backref" href="#id42">Roots of Chebyshev polynomials</a></h2> @@ -878,19 +908,22 @@ indices act the same in both.)</p> <div class="section" id="polget-polname-fromarray-macro"> <span id="polget"></span><h2><a class="toc-backref" href="#id50"><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>. No -error checks on validity of coefficients as numbers. Each -<tt class="docutils literal">\macro{number}</tt> is expanded in an <tt class="docutils literal">\edef</tt> before being assigned -to a coefficient. Leading zero coefficients are removed from the -polynomial.</p> +<p>Does the converse operation to +<tt class="docutils literal"><span class="pre">\PolAssign{polname}\toarray\macro</span></tt>. Each individual +<tt class="docutils literal">\macro{number}</tt> gets expanded in an <tt class="docutils literal">\edef</tt> and then normalized +via <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a>'s macro <tt class="docutils literal">\xintRaw</tt>.</p> +<p>The leading zeros are removed from the polynomial.</p> <p>(contrived) Example:</p> <pre class="literal-block"> \xintAssignArray{1}{-2}{5}{-3}\to\foo \PolGet{f}\fromarray\foo </pre> -<p>This will define <tt class="docutils literal">f</tt> as would have <tt class="docutils literal">\poldef <span class="pre">f(x):=1-2x+5x^2-3x^3;</span></tt>. -However the coefficients are still in their original form (i.e. -they were not subjected to <tt class="docutils literal">\xintRaw</tt> or similar <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> macro.)</p> +<p>This will define <tt class="docutils literal">f</tt> as would have <tt class="docutils literal">\poldef <span class="pre">f(x):=1-2x+5x^2-3x^3;</span></tt>.</p> +<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Prior to <tt class="docutils literal">0.5</tt>, coefficients were not normalized via +<tt class="docutils literal">\xintRaw</tt> for internal storage.</p> +</div> </blockquote> </div> <div class="section" id="polfromcsv-polname-csv"> @@ -900,15 +933,19 @@ they were not subjected to <tt class="docutils literal">\xintRaw</tt> or similar 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>, but currently left in their original form like e.g. -<tt class="docutils literal">1.5e3</tt> which is not converted to <tt class="docutils literal">15/1[2]</tt> <em>raw</em> <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> -format (this may change).</p> +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> <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>See also expandable macro <a class="reference internal" href="#poltocsv-polname">\PolToCSV</a>.</p> +<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Prior to <tt class="docutils literal">0.5</tt>, coefficients were not normalized via +<tt class="docutils literal">\xintRaw</tt> for internal storage.</p> +</div> </blockquote> </div> <div class="section" id="poltypeset-polname"> @@ -1071,13 +1108,19 @@ polynomial.</blockquote> <p>With, for example, <tt class="docutils literal">polname</tt> being <tt class="docutils literal">P</tt> and <tt class="docutils literal">sturmname</tt> being <tt class="docutils literal">S</tt>, the macro starts by computing polynomials <tt class="docutils literal">S_0 = P</tt>, <tt class="docutils literal">S_1 = P'</tt>, ..., with <tt class="docutils literal">S_{n+1}</tt> the opposite of the remainder of -euclidean division of <tt class="docutils literal"><span class="pre">S_{n-1}</span></tt> by <tt class="docutils literal">S_{n}</tt>. The last non-zero -remainder <tt class="docutils literal">S_N</tt> is up to a factor the GCD of <tt class="docutils literal">P</tt> and <tt class="docutils literal">P'</tt> -hence a constant if and only if <tt class="docutils literal">P</tt> is square-free.</p> +euclidean division of <tt class="docutils literal"><span class="pre">S_{n-1}</span></tt> by <tt class="docutils literal">S_{n}</tt>.</p> +<div class="admonition attention"> +<p class="first admonition-title">Attention!</p> +<p class="last">Since <tt class="docutils literal">0.5</tt>, it further normalizes all these polynomials by making +them primitive (see <a class="reference internal" href="#polmakeprimitive">\PolMakePrimitive</a>).</p> +</div> +<p>The last non-zero remainder <tt class="docutils literal">S_N</tt> is up to a factor the GCD of +<tt class="docutils literal">P</tt> and <tt class="docutils literal">P'</tt> hence it is a constant (i.e. <tt class="docutils literal">1</tt> or <tt class="docutils literal"><span class="pre">-1</span></tt> since +<tt class="docutils literal">0.5</tt>) if and only if <tt class="docutils literal">P</tt> is square-free.</p> <p>In case <tt class="docutils literal">S_N</tt> is not a constant, the macro then goes on with -dividing all <tt class="docutils literal">S_k</tt>'s with <tt class="docutils literal">S_N</tt> (which becomes <tt class="docutils literal">1</tt>).</p> -<p>Thus <tt class="docutils literal">S_0</tt> now has exactly the same real and complex -roots as polynomial <tt class="docutils literal">polname</tt>, but each with multiplicity one.</p> +dividing all <tt class="docutils literal">S_k</tt>'s with <tt class="docutils literal">S_N</tt> (which then becomes <tt class="docutils literal">1</tt>).</p> +<p>Thus <tt class="docutils literal">S_0</tt> has exactly the same real and complex roots as +polynomial <tt class="docutils literal">polname</tt>, but each root being now with multiplicity one.</p> </blockquote> </div> <div class="section" id="id10"> @@ -1350,20 +1393,27 @@ 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="#id83"><tt class="docutils literal">\PolMakePrimitive{polname}</tt></a></h2> +<blockquote> +Divides by the integer content see (<a class="reference internal" href="#policontent">\PolIContent</a>). This thus produces a polynomial with integer +coefficients having no common factor. The sign of the leading +coefficient is not modified.</blockquote> +</div> </div> <div class="section" id="expandable-macros"> -<h1><a class="toc-backref" href="#id83">Expandable macros</a></h1> +<h1><a class="toc-backref" href="#id84">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="#id84"><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="#id85"><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="#id85"><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="#id86"><tt class="docutils literal"><span class="pre">\PolEval{polname}\At{fraction}</span></tt></a></h2> <blockquote> <p>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.</p> @@ -1379,12 +1429,12 @@ e.g. the variables as defined by <a class="reference external" href="PolSturmIso </blockquote> </div> <div class="section" id="polevalreduced-polname-atexpr-numerical-expression"> -<span id="polevalreducedatexpr"></span><h2><a class="toc-backref" href="#id86"><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="#id87"><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="#id87"><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="#id88"><tt class="docutils literal"><span class="pre">\PolEvalReduced{polname}\At{fraction}</span></tt></a></h2> <blockquote> <p>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 @@ -1397,7 +1447,7 @@ could be given as an expression.</p> </blockquote> </div> <div class="section" id="polfloateval-polname-atexpr-numerical-expression"> -<span id="polfloatevalatexpr"></span><h2><a class="toc-backref" href="#id88"><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="#id89"><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 @@ -1435,7 +1485,7 @@ nested expressions.</td></tr> </blockquote> </div> <div class="section" id="polfloateval-polname-at-fraction"> -<span id="polfloatevalat"></span><h2><a class="toc-backref" href="#id89"><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="#id90"><tt class="docutils literal"><span class="pre">\PolFloatEval{polname}\At{fraction}</span></tt></a></h2> <blockquote> <p>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 @@ -1448,7 +1498,7 @@ could be given as an expression.</p> </blockquote> </div> <div class="section" id="polifcoeffisplusorminusone-a-b"> -<span id="polifcoeffisplusorminusone"></span><h2><a class="toc-backref" href="#id90"><tt class="docutils literal"><span class="pre">\PolIfCoeffIsPlusOrMinusOne{A}{B}</span></tt></a></h2> +<span id="polifcoeffisplusorminusone"></span><h2><a class="toc-backref" href="#id91"><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 @@ -1460,25 +1510,34 @@ 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="#id91"><tt class="docutils literal">\PolLeadingCoeff{polname}</tt></a></h2> +<span id="polleadingcoeff"></span><h2><a class="toc-backref" href="#id92"><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="#id92"><tt class="docutils literal"><span class="pre">\PolNthCoeff{polname}{number}</span></tt></a></h2> +<span id="polnthcoeff"></span><h2><a class="toc-backref" href="#id93"><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="#id93"><tt class="docutils literal">\PolDegree{polname}</tt></a></h2> +<span id="poldegree"></span><h2><a class="toc-backref" href="#id94"><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="#id95"><tt class="docutils literal">\PolIContent{polname}</tt></a></h2> +<blockquote> +<p>It expands to the contents of the polynomial, i.e. to the positive +fraction such that dividing by this fraction produces a polynomial +with integer coefficients having no common prime divisor.</p> +<p>See <a class="reference internal" href="#polmakeprimitive">\PolMakePrimitive</a>.</p> +</blockquote> +</div> <div class="section" id="poltoexpr-polname"> -<span id="poltoexpr"></span><h2><a class="toc-backref" href="#id94"><tt class="docutils literal">\PolToExpr{polname}</tt></a></h2> +<span id="poltoexpr"></span><h2><a class="toc-backref" href="#id96"><tt class="docutils literal">\PolToExpr{polname}</tt></a></h2> <blockquote> <p>Expands <a class="footnote-reference" href="#id22" id="id21">[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="id22" rules="none"> @@ -1503,7 +1562,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="#id95"><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="#id97"><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 @@ -1516,13 +1575,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="#id96"><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="#id98"><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="#id97"><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="#id99"><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"> @@ -1536,7 +1595,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="#id98"><tt class="docutils literal">\PolToExprCmd{raw_coeff}</tt></a></h3> +<span id="poltoexprcmd"></span><h3><a class="toc-backref" href="#id100"><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 @@ -1546,21 +1605,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="#id99"><tt class="docutils literal">\PolToExprTermPrefix{raw_coeff}</tt></a></h3> +<span id="poltoexprtermprefix"></span><h3><a class="toc-backref" href="#id101"><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="id23"> -<span id="poltoexprvar"></span><h3><a class="toc-backref" href="#id100"><tt class="docutils literal">\PolToExprVar</tt></a></h3> +<span id="poltoexprvar"></span><h3><a class="toc-backref" href="#id102"><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="id24"> -<span id="poltoexprtimes"></span><h3><a class="toc-backref" href="#id101"><tt class="docutils literal">\PolToExprTimes</tt></a></h3> +<span id="poltoexprtimes"></span><h3><a class="toc-backref" href="#id103"><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 @@ -1570,13 +1629,13 @@ algebra software).</blockquote> </div> </div> <div class="section" id="id26"> -<span id="id25"></span><h2><a class="toc-backref" href="#id102"><tt class="docutils literal"><span class="pre">\PolToExpr*{polname}</span></tt></a></h2> +<span id="id25"></span><h2><a class="toc-backref" href="#id104"><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="#id103"><tt class="docutils literal">\PolToFloatExpr{polname}</tt></a></h2> +<span id="poltofloatexpr"></span><h2><a class="toc-backref" href="#id105"><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 @@ -1595,13 +1654,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="#id104"><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="#id106"><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="id28"></span><h3><a class="toc-backref" href="#id105"><tt class="docutils literal">\PolToFloatExprCmd{raw_coeff}</tt></a></h3> +<span id="id28"></span><h3><a class="toc-backref" href="#id107"><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> @@ -1624,25 +1683,25 @@ in <tt class="docutils literal">xintfrac</tt> raw format.</p> </div> </div> <div class="section" id="id30"> -<span id="id29"></span><h2><a class="toc-backref" href="#id106"><tt class="docutils literal"><span class="pre">\PolToFloatExpr*{polname}</span></tt></a></h2> +<span id="id29"></span><h2><a class="toc-backref" href="#id108"><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="#id107"><tt class="docutils literal">\PolToList{polname}</tt></a></h2> +<span id="poltolist"></span><h2><a class="toc-backref" href="#id109"><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 empty output.)</blockquote> </div> <div class="section" id="poltocsv-polname"> -<span id="poltocsv"></span><h2><a class="toc-backref" href="#id108"><tt class="docutils literal">\PolToCSV{polname}</tt></a></h2> +<span id="poltocsv"></span><h2><a class="toc-backref" href="#id110"><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 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="#id109"><tt class="docutils literal">\PolSturmChainLength{sturmname}</tt></a></h2> +<span id="polsturmchainlength"></span><h2><a class="toc-backref" href="#id111"><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> @@ -1650,7 +1709,7 @@ 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="#id110"><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="#id112"><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> @@ -1667,21 +1726,21 @@ error message (right before everything goes haywire).</p> </blockquote> </div> <div class="section" id="polsturmisolatedzeroleft-sturmname-index"> -<span id="polsturmisolatedzeroleft"></span><h2><a class="toc-backref" href="#id111"><tt class="docutils literal"><span class="pre">\PolSturmIsolatedZeroLeft{sturmname}{index}</span></tt></a></h2> +<span id="polsturmisolatedzeroleft"></span><h2><a class="toc-backref" href="#id113"><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> </div> <div class="section" id="polsturmisolatedzeroright-sturmname-index"> -<span id="polsturmisolatedzeroright"></span><h2><a class="toc-backref" href="#id112"><tt class="docutils literal"><span class="pre">\PolSturmIsolatedZeroRight{sturmname}{index}</span></tt></a></h2> +<span id="polsturmisolatedzeroright"></span><h2><a class="toc-backref" href="#id114"><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> </div> <div class="section" id="polsturmnbofisolatedzeros-sturmname"> -<span id="polsturmnbofisolatedzeros"></span><h2><a class="toc-backref" href="#id113"><tt class="docutils literal">\PolSturmNbOfIsolatedZeros{sturmname}</tt></a></h2> +<span id="polsturmnbofisolatedzeros"></span><h2><a class="toc-backref" href="#id115"><tt class="docutils literal">\PolSturmNbOfIsolatedZeros{sturmname}</tt></a></h2> <blockquote> Expands to the number of real roots of the polynomial <tt class="docutils literal"><sturmname>_0</tt> (which is the number of distinct real roots of the @@ -1689,17 +1748,17 @@ polynomial used to create the Sturm chain via <a class="reference internal" href="#poltosturm-polname-sturmname">\PolToSturm{polname}{sturmname}</a>.</blockquote> </div> <div class="section" id="polintervalwidth-sturmname-index"> -<span id="polintervalwidth"></span><h2><a class="toc-backref" href="#id114"><tt class="docutils literal"><span class="pre">\PolIntervalWidth{sturmname}{index}</span></tt></a></h2> +<span id="polintervalwidth"></span><h2><a class="toc-backref" href="#id116"><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="#id115">Macros for use within execution of <tt class="docutils literal">\PolPrintIntervals</tt></a></h2> +<h2><a class="toc-backref" href="#id117">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="id31"> -<span id="polprintintervalstheendpoint"></span><h3><a class="toc-backref" href="#id116"><tt class="docutils literal">\PolPrintIntervalsTheEndPoint</tt></a></h3> +<span id="polprintintervalstheendpoint"></span><h3><a class="toc-backref" href="#id118"><tt class="docutils literal">\PolPrintIntervalsTheEndPoint</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 @@ -1708,7 +1767,7 @@ or right end point of the considered interval. Serves as default replacement for <a class="reference internal" href="#polprintintervalsprintleftendpoint">\PolPrintIntervalsPrintLeftEndPoint</a> , etc...</blockquote> </div> <div class="section" id="id32"> -<span id="polprintintervalstheindex"></span><h3><a class="toc-backref" href="#id117"><tt class="docutils literal">\PolPrintIntervalsTheIndex</tt></a></h3> +<span id="polprintintervalstheindex"></span><h3><a class="toc-backref" href="#id119"><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 @@ -1719,7 +1778,7 @@ in the replacement text of <a class="reference internal" href="#polprintinterval the other two similar macros.</blockquote> </div> <div class="section" id="polifendpointispositive-a-b"> -<span id="polifendpointispositive"></span><h3><a class="toc-backref" href="#id118"><tt class="docutils literal"><span class="pre">\PolIfEndPointIsPositive{A}{B}</span></tt></a></h3> +<span id="polifendpointispositive"></span><h3><a class="toc-backref" href="#id120"><tt class="docutils literal"><span class="pre">\PolIfEndPointIsPositive{A}{B}</span></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 @@ -1727,7 +1786,7 @@ Within a custom <a class="reference internal" href="#polprintintervalsprintlefte the considered interval end-point is positive, else <tt class="docutils literal">B</tt>.</blockquote> </div> <div class="section" id="polifendpointisnegative-a-b"> -<span id="polifendpointisnegative"></span><h3><a class="toc-backref" href="#id119"><tt class="docutils literal"><span class="pre">\PolIfEndPointIsNegative{A}{B}</span></tt></a></h3> +<span id="polifendpointisnegative"></span><h3><a class="toc-backref" href="#id121"><tt class="docutils literal"><span class="pre">\PolIfEndPointIsNegative{A}{B}</span></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 @@ -1735,7 +1794,7 @@ Within a custom <a class="reference internal" href="#polprintintervalsprintlefte the considered interval end-point is negative, else <tt class="docutils literal">B</tt>.</blockquote> </div> <div class="section" id="polifendpointiszero-a-b"> -<span id="polifendpointiszero"></span><h3><a class="toc-backref" href="#id120"><tt class="docutils literal"><span class="pre">\PolIfEndPointIsZero{A}{B}</span></tt></a></h3> +<span id="polifendpointiszero"></span><h3><a class="toc-backref" href="#id122"><tt class="docutils literal"><span class="pre">\PolIfEndPointIsZero{A}{B}</span></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 @@ -1744,7 +1803,7 @@ the considered interval end-point is zero, else <tt class="docutils literal">B</ </div> </div> <div class="section" id="poldectostring-decimal-number"> -<span id="poldectostring"></span><h2><a class="toc-backref" href="#id121"><tt class="docutils literal">\PolDecToString{decimal number}</tt></a></h2> +<span id="poldectostring"></span><h2><a class="toc-backref" href="#id123"><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 @@ -1761,9 +1820,9 @@ zeroes, one can use <tt class="docutils literal"><span class="pre">\PolDecToStri </div> </div> <div class="section" id="booleans-with-default-setting-as-indicated"> -<h1><a class="toc-backref" href="#id122">Booleans (with default setting as indicated)</a></h1> +<h1><a class="toc-backref" href="#id124">Booleans (with default setting as indicated)</a></h1> <div class="section" id="xintverbosefalse"> -<h2><a class="toc-backref" href="#id123"><tt class="docutils literal">\xintverbosefalse</tt></a></h2> +<h2><a class="toc-backref" href="#id125"><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 @@ -1776,20 +1835,20 @@ unstable and undocumented internal structures.</p> </blockquote> </div> <div class="section" id="poltypesetallfalse"> -<h2><a class="toc-backref" href="#id124"><tt class="docutils literal">\poltypesetallfalse</tt></a></h2> +<h2><a class="toc-backref" href="#id126"><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="#id125"><tt class="docutils literal">\poltoexprallfalse</tt></a></h2> +<h2><a class="toc-backref" href="#id127"><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="technicalities"> -<h1><a class="toc-backref" href="#id126">Technicalities</a></h1> +<h1><a class="toc-backref" href="#id128">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 @@ -1831,17 +1890,6 @@ resulting coefficients, except that the <em>power of ten</em> part <tt class="do reduction of the fraction. This is tentative and may change.</p> <p>Same remark for <a class="reference internal" href="#polantidiff-polname-1-polname-2">\PolAntiDiff{polname_1}{polname_2}</a>.</p> </li> -<li><p class="first">If <tt class="docutils literal">f</tt> was created from comma separated values by macro -<a class="reference internal" href="#polfromcsv-polname-csv">\PolFromCSV{polname}{<csv>}</a>, then the coefficients will be in -the output of <a class="reference internal" href="#poltolist-polname">\PolToList{polname}</a> and <a class="reference internal" href="#poltocsv-polname">\PolToCSV{polname}</a> in -the same format as originally in input: a <tt class="docutils literal">1.3e2</tt> will again be a -<tt class="docutils literal">1.3e2</tt>.</p> -<p>In contrast when such coefficients are used in a <tt class="docutils literal">\poldef</tt> (or -<tt class="docutils literal">\PolDef</tt>) expression, they get transformed during the parsing to -the xintfrac <em>raw</em> format. -This <em>raw</em> format speeds up expansion of xintfrac macros for numerical -evaluations.</p> -</li> <li><p class="first">Currently, the package stores all coefficients from index <tt class="docutils literal">0</tt> to index equal to the polynomial degree inside a single macro, as a list. This data structure is obviously very inefficient for polynomials of @@ -1857,7 +1905,7 @@ documented and unstable. Don't use them.</p> </ul> </div> <div class="section" id="change-log"> -<h1><a class="toc-backref" href="#id127">CHANGE LOG</a></h1> +<h1><a class="toc-backref" href="#id129">CHANGE LOG</a></h1> <ul> <li><p class="first">v0.1 (2018/01/11): initial release. Features:</p> <ul class="simple"> @@ -2034,10 +2082,45 @@ for localization of the real roots of polynomials.</p> <li><p class="first">v0.4.2 (2018/03/03)</p> <p>Documentation fix.</p> </li> +<li><p class="first">v0.5 (2018/04/08)</p> +<ul class="simple"> +<li>bug fixes:<ul> +<li><a class="reference internal" href="#polget-polname-fromarray-macro">\PolGet{polname}\fromarray\macro</a> crashed when <tt class="docutils literal">\macro</tt> was +an <a class="reference external" href="http://www.ctan.org/pkg/xint">xinttools</a> array macro with no items. It now produces the zero +polynomial.</li> +</ul> +</li> +<li>breaking changes:<ul> +<li><a class="reference internal" href="#poltosturm">\PolToSturm</a> creates primitive integer coefficients polynomials. +This speeds up localization of roots via +<a class="reference internal" href="#polsturmisolatezeros">\PolSturmIsolateZeros</a>. In case of user protests the author +will make available again the code producing the bona fide Sturm +polynomials as used formerly.</li> +<li>polynomials created from <a class="reference internal" href="#polfromcsv">\PolFromCSV</a> or <a class="reference internal" href="#polget">\PolGet</a> +get their coefficients normalized via <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a>'s <tt class="docutils literal">\xintRaw</tt>.</li> +</ul> +</li> +<li>experimental change:<ul> +<li>optional argument to <a class="reference internal" href="#polsturmisolatezeros">\PolSturmIsolateZeros</a> (see <a class="reference internal" href="#the-degree-41-polynomial-with-2-1-9-1-8-0-0-1-1-9-2-as-roots">The +degree 41 polynomial with -2, -1.9, -1.8, ..., 0, 0.1, ..., 1.9, 2 +as roots</a> for usage). It will presumably be replaced in future by +an interval specification.</li> +</ul> +</li> +<li>new non-expandable macros:<ul> +<li><a class="reference internal" href="#polmakeprimitive">\PolMakePrimitive</a></li> +</ul> +</li> +<li>new expandable macros:<ul> +<li><a class="reference internal" href="#policontent">\PolIContent</a></li> +</ul> +</li> +</ul> +</li> </ul> </div> <div class="section" id="acknowledgments"> -<h1><a class="toc-backref" href="#id128">Acknowledgments</a></h1> +<h1><a class="toc-backref" href="#id130">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 diff --git a/Master/texmf-dist/doc/latex/polexpr/polexpr.txt b/Master/texmf-dist/doc/latex/polexpr/polexpr.txt index 16cdff04d1e..dd2ab246900 100644 --- a/Master/texmf-dist/doc/latex/polexpr/polexpr.txt +++ b/Master/texmf-dist/doc/latex/polexpr/polexpr.txt @@ -4,8 +4,8 @@ Package polexpr documentation =============================== -0.4.2 (2018/03/03) -================== +0.5 (2018/04/08) +================ .. contents:: @@ -120,7 +120,13 @@ the macro call ``\PolGCD{f_1}{f_2}{k}`` sets ``k`` to the (unitary) GCD of Examples of localization of roots --------------------------------- -First some remarks about auxiliaries. +.. attention:: + + At ``0.5``, `\\PolToSturm{P}{S} <PolToSturm_>`_ was modified to + create a chain of primitive integer coefficients polynomials. This + speeds up evaluations, hence localization of roots afterwards. Thus + ``S_1`` will not necessarily be the derivative of ``S_0``, even if + ``P`` is square-free. - To make printed decimal numbers more enjoyable than via ``\xintSignedFrac``:: @@ -137,9 +143,10 @@ First some remarks about auxiliaries. to modify output of `\\PolToExpr{polname}`_. -- for extra info in log file ``\xintverbosetrue``. In fact one can also - work from command line then (I recommend ``rlwrap`` for encapsulating - ``latex``). +- 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... A typical example @@ -166,8 +173,10 @@ was no further reduction. And here is the first root with twenty digits after decimal mark: \PolEnsureIntervalLength{f}{1}{-20} \[\PolSturmIsolatedZeroLeft{f}{1}<Z_1<\PolSturmIsolatedZeroRight{f}{1}\] - The derivative polynomial is \PolTypeset{f_1} (from - $\PolDegree{f_0}=7$ we know that original polynomial was square-free). + 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 + it is identical with it). \PolToSturm{f_1}{f_1}\PolSturmIsolateZeros{f_1}% It has \PolSturmNbOfIsolatedZeros{f_1} distinct real roots: @@ -238,23 +247,27 @@ A Mignotte type polynomial \PolTypeset{P} % prints it in expanded form \PolToSturm{P}{P} % we can use same prefix for Sturm chain \PolSturmIsolateZeros{P} % finds 4 real roots + This polynomial has \PolSturmNbOfIsolatedZeros{P} distinct real roots: \PolPrintIntervals{P}% % reports -2 < Z_1 < -1, 0 < Z_2 < 0.1, 0.1 < Z_3 < 0.2, 1 < Z_4 < 2 + Let us refine the second and third intervals to separate the corresponding + roots: \PolRefineInterval*{P}{2}% will refine to 0.0999990 < Z_2 < 0.0999991 \PolRefineInterval*{P}{3}% will refine to 0.100001 < Z_3 < 0.100002 \PolPrintIntervals{P}% + Let us now get to know all roots with 10 digits after decimal mark: \PolEnsureIntervalLengths{P}{-10}% \PolPrintIntervals{P}% now all roots are known 10 decimal digits after mark + Finally, we display 20 digits of the second root: \PolEnsureIntervalLength{P}{2}{-20}% makes Z_2 known with 20 digits after mark - There are $\PolSturmNbOfIsolatedZeros{P}$ distinct real roots and there holds - $\PolSturmIsolatedZeroLeft{P}{2}<Z_2<\PolSturmIsolatedZeroRight{P}{2}$. + \[\PolSturmIsolatedZeroLeft{P}{2}<Z_2<\PolSturmIsolatedZeroRight{P}{2}\] The last line produces:: 0.09999900004999650028 < Z_2 < 0.09999900004999650029 The degree 41 polynomial with -2, -1.9, -1.8, ..., 0, 0.1, ..., 1.9, 2 as roots -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :: @@ -299,9 +312,24 @@ 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} - \PolSturmIsolateZeros{S} % finds *exactly* (but a bit slowly) all 41 roots! - \PolPrintIntervals{S} % nice, isn't it? + \PolToSturm{P}{S} % dutifully computes S_0, ..., S_{41} + \PolSturmIsolateZeros[1]{S} % finds *exactly* (but a bit slowly) all 41 roots! + \PolPrintIntervals{S} % nice, isn't it? + +.. note:: + + Release ``0.5`` has experimental addition of optional argument + ``E`` to ``\PolSturmIsolateZeros``. It instructs to search roots only + in interval ``(-10^E, 10^E)``, 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. + + This will probably get replaced in future by the specification of + a general interval. Roots of Chebyshev polynomials ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -453,11 +481,12 @@ Non-expandable macros ``\PolGet{polname}\fromarray\macro`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Does the converse operation to ``\PolAssign{polname}\toarray\macro``. No - error checks on validity of coefficients as numbers. Each - ``\macro{number}`` is expanded in an ``\edef`` before being assigned - to a coefficient. Leading zero coefficients are removed from the - polynomial. + Does the converse operation to + ``\PolAssign{polname}\toarray\macro``. Each individual + ``\macro{number}`` gets expanded in an ``\edef`` and then normalized + via xintfrac_\ 's macro ``\xintRaw``. + + The leading zeros are removed from the polynomial. (contrived) Example:: @@ -465,8 +494,11 @@ Non-expandable macros \PolGet{f}\fromarray\foo This will define ``f`` as would have ``\poldef f(x):=1-2x+5x^2-3x^3;``. - However the coefficients are still in their original form (i.e. - they were not subjected to ``\xintRaw`` or similar xintfrac_ macro.) + + .. note:: + + Prior to ``0.5``, coefficients were not normalized via + ``\xintRaw`` for internal storage. .. _PolFromCSV: @@ -477,9 +509,8 @@ Non-expandable macros 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``, but currently left in their original form like e.g. - ``1.5e3`` which is not converted to ``15/1[2]`` *raw* xintfrac_ - format (this may change). + an ``\edef`` and then put into normalized form via xintfrac_\ 's + macro ``\xintRaw``. Leading zero coefficients are removed:: @@ -489,6 +520,11 @@ Non-expandable macros See also expandable macro `\\PolToCSV <\\PolToCSV{polname}_>`_. + .. note:: + + Prior to ``0.5``, coefficients were not normalized via + ``\xintRaw`` for internal storage. + .. _PolTypeset: ``\PolTypeset{polname}`` @@ -679,15 +715,22 @@ Non-expandable macros With, for example, ``polname`` being ``P`` and ``sturmname`` being ``S``, the macro starts by computing polynomials ``S_0 = P``, ``S_1 = P'``, ..., with ``S_{n+1}`` the opposite of the remainder of - euclidean division of ``S_{n-1}`` by ``S_{n}``. The last non-zero - remainder ``S_N`` is up to a factor the GCD of ``P`` and ``P'`` - hence a constant if and only if ``P`` is square-free. + euclidean division of ``S_{n-1}`` by ``S_{n}``. + + .. attention:: + + Since ``0.5``, it further normalizes all these polynomials by making + them primitive (see `\\PolMakePrimitive`_). + + The last non-zero remainder ``S_N`` is up to a factor the GCD of + ``P`` and ``P'`` hence it is a constant (i.e. ``1`` or ``-1`` since + ``0.5``) if and only if ``P`` is square-free. In case ``S_N`` is not a constant, the macro then goes on with - dividing all ``S_k``'s with ``S_N`` (which becomes ``1``). + dividing all ``S_k``'s with ``S_N`` (which then becomes ``1``). - Thus ``S_0`` now has exactly the same real and complex - roots as polynomial ``polname``, but each with multiplicity one. + Thus ``S_0`` has exactly the same real and complex roots as + polynomial ``polname``, but each root being now with multiplicity one. .. _PolToSturm*: @@ -999,6 +1042,16 @@ Non-expandable macros coefficients and we want to keep the leading one as common denominator. +.. _PolMakePrimitive: + +``\PolMakePrimitive{polname}`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Divides by the integer content see (`\\PolIContent + <PolIContent_>`_). This thus produces a polynomial with integer + coefficients having no common factor. The sign of the leading + coefficient is not modified. + Expandable macros ----------------- @@ -1142,6 +1195,17 @@ and ``\PolToFloatExpr`` (and their auxiliaries) which need a It expands to the degree. This is ``-1`` if zero polynomial but this may change in future. Should it then expand to ``-\infty`` ? +.. _PolIContent: + +``\PolIContent{polname}`` +~~~~~~~~~~~~~~~~~~~~~~~~~ + + It expands to the contents of the polynomial, i.e. to the positive + fraction such that dividing by this fraction produces a polynomial + with integer coefficients having no common prime divisor. + + See `\\PolMakePrimitive <PolMakePrimitive_>`_. + .. _PolToExpr: ``\PolToExpr{polname}`` @@ -1365,7 +1429,6 @@ and ``\PolToFloatExpr`` (and their auxiliaries) which need a There is also an out-of-range check done for some reasonable error message (right before everything goes haywire). - .. _PolSturmIsolatedZeroLeft: ``\PolSturmIsolatedZeroLeft{sturmname}{index}`` @@ -1551,18 +1614,6 @@ Technicalities Same remark for `\\PolAntiDiff{polname_1}{polname_2}`_. -- If ``f`` was created from comma separated values by macro - `\\PolFromCSV{polname}{\<csv\>}`_, then the coefficients will be in - the output of `\\PolToList{polname}`_ and `\\PolToCSV{polname}`_ in - the same format as originally in input: a ``1.3e2`` will again be a - ``1.3e2``. - - In contrast when such coefficients are used in a ``\poldef`` (or - ``\PolDef``) expression, they get transformed during the parsing to - the xintfrac *raw* format. - This *raw* format speeds up expansion of xintfrac macros for numerical - evaluations. - - Currently, the package stores all coefficients from index ``0`` to index equal to the polynomial degree inside a single macro, as a list. This data structure is obviously very inefficient for polynomials of @@ -1737,6 +1788,36 @@ CHANGE LOG Documentation fix. +- v0.5 (2018/04/08) + + * bug fixes: + + - `\\PolGet{polname}\\fromarray\\macro`_ crashed when ``\macro`` was + an xinttools_ array macro with no items. It now produces the zero + polynomial. + * breaking changes: + + - `\\PolToSturm`_ creates primitive integer coefficients polynomials. + This speeds up localization of roots via + `\\PolSturmIsolateZeros`_. In case of user protests the author + will make available again the code producing the bona fide Sturm + polynomials as used formerly. + - polynomials created from `\\PolFromCSV`_ or `\\PolGet <PolGet_>`_ + get their coefficients normalized via xintfrac_\ 's ``\xintRaw``. + * experimental change: + + - optional argument to `\\PolSturmIsolateZeros`_ (see `The + degree 41 polynomial with -2, -1.9, -1.8, ..., 0, 0.1, ..., 1.9, 2 + as roots`_ for usage). It will presumably be replaced in future by + an interval specification. + * new non-expandable macros: + + - `\\PolMakePrimitive`_ + * new expandable macros: + + - `\\PolIContent`_ + + Acknowledgments --------------- diff --git a/Master/texmf-dist/tex/latex/polexpr/polexpr.sty b/Master/texmf-dist/tex/latex/polexpr/polexpr.sty index 7e132905392..02d3ecdec76 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/03/03 v0.4.2 Polynomial expressions with rational coefficients (JFB)]% + [2018/04/08 v0.5 Polynomial expressions with rational coefficients (JFB)]% \RequirePackage{xintexpr}[2018/03/01]% xint 1.3 \edef\POL@restorecatcodes {\catcode`\noexpand\_ \the\catcode`\_ \catcode0 \the\catcode0\relax}% @@ -24,7 +24,7 @@ \else\expandafter\xint_secondoftwo \fi}% \def\POL@split#1.#2;#3#4% separates degree and list of coefficients -% The \empty token is to avoid brace removal issues for degree 0 polynomials +% The \expandafter chain removes the \empty token {\def#3{#1}\expandafter\def\expandafter#4\expandafter{#2}}% % \def\POL@resultfromarray #1{% ATTENTION, **MUST** be executed with @@ -64,8 +64,8 @@ \let\xintPow\POL@pow \let\xintOpp\POL@opp \def\xintSub ##1##2{\xintAdd{##1}{\xintOpp{##2}}}% - % \xintAdd to get \POL@result defined even if numerical only expression - % I could also test \ifPOL@pol, but well, this is very small overhead + % \xintAdd{0} to get \POL@result defined even if numerical only expression + % I could also test \ifPOL@pol, but this is anyhow small overhead \xintAdd{0}% {\csname XINT_expr_userfunc___pol\endcsname {\global\POL@poltrue\def\POL@result{1.\empty{0/1[0]}{1/1[0]}}}}% @@ -209,32 +209,45 @@ }% -\newcommand\PolGet{} +\newcommand\PolGet{}% \def\PolGet#1#2\fromarray#3{% \begingroup % closed in \POL@getfromarray \POL@getfromarray{#1}{#3}% \POL@newpol{#1}% }% \def\POL@getfromarray#1#2{% - \count@=#2{0} %<- intentional space, - % must be > 0, else could create infinite loop + \count@=#2{0} %<- intentional space + \ifnum\count@=\z@ + \def\POL@result{-1.\empty{0/1[0]}}% 0.5 fix for empty array + \else + \xintloop + \edef\POL@tmp{#2{\count@}}% + \edef\POL@tmp{\xintRaw{\POL@tmp}}% +% sadly xinttools (current 1.3a) arrays have no setters for individual items... + \expandafter\let\csname POL@tmparray\the\count@\endcsname\POL@tmp + \if0\xintiiSgn{\POL@tmp}% + \advance\count@\m@ne + \repeat +% dans le cas particulier d'un array avec que des éléments nuls, \count@ est +% ici devenu 0 et la boucle s'est arrêtée car #2{0} était au moins 1. De plus +% \POL@tmparray1 est bien 0/1[0] donc ok pour polynôme nul dans \POL@result + \count\tw@\count@ \xintloop +% on mouline tous les coeffs via \xintRaw + \ifnum\count@>\@ne + \advance\count@\m@ne \edef\POL@tmp{#2{\count@}}% - \xintiiifZero{\POL@tmp}% - {\iftrue}% - {\iffalse}% - \advance\count@\m@ne + \edef\POL@tmp{\xintRaw{\POL@tmp}}% + \expandafter\let\csname POL@tmparray\the\count@\endcsname\POL@tmp \repeat -% should I use \xintRaw ? but if #2 expands only in an \edef, problem -% (but it is not very probable the #2 macro does not already give completely -% expanded contents), I would need to proceed in two steps. Or the \xintRaw -% could get injected at level of \POL@newpol - \def\POL@tmp##1.{{#2{##1}}}% + \count@\count\tw@ + \def\POL@tmp##1.{{\csname POL@tmparray##1\endcsname}}% \edef\POL@result{\the\numexpr\count@-\@ne.\noexpand\empty \xintiloop[1+1]% \expandafter\POL@tmp\xintiloopindex.% \ifnum\xintiloopindex<\count@ \repeat}% + \fi \expandafter \endgroup \expandafter @@ -325,14 +338,14 @@ }% \def\POL@mapcoeffs#1#2{% \begingroup - \def\POL@map@macro{#1}% + \def\POL@mapcoeffs@macro{#1}% \expandafter\expandafter\expandafter\POL@split - \csname POLuserpol@#2\endcsname;\POL@var@deg\POL@var@coeffs + \csname POLuserpol@#2\endcsname;\POL@mapcoeffs@deg\POL@mapcoeffs@coeffs % attention à ne pas faire un \expandafter ici, car brace removal si 1 item - \xintAssignArray\POL@var@coeffs\to\POL@arrayA + \xintAssignArray\POL@mapcoeffs@coeffs\to\POL@arrayA \def\index{0}% \count@\z@ - \expandafter\POL@map@loop\expandafter.\POL@var@coeffs\relax + \expandafter\POL@map@loop\expandafter.\POL@mapcoeffs@coeffs\relax \xintloop % this abuses that \POL@arrayA0 is never 0. \xintiiifZero{\csname POL@arrayA\the\count@\endcsname}% @@ -349,7 +362,7 @@ }% \def\POL@map@loop.#1{\if\relax#1\expandafter\xint_gob_til_dot\fi \advance\count@\@ne - \edef\POL@map@coeff{\POL@map@macro{#1}}% + \edef\POL@map@coeff{\POL@mapcoeffs@macro{#1}}% \expandafter \let\csname POL@arrayA\the\count@\endcsname\POL@map@coeff \edef\index{\the\numexpr\index+\@ne}% @@ -620,28 +633,61 @@ \fi }% +%% IContent and \PolMakePrimitive (0.5) +\def\POL@aux@mgcd@loop#1#2{% + \if\relax#2\expandafter\POL@aux@mgcd@exit\fi + \expandafter + \POL@aux@mgcd@loop\romannumeral0\POL@aux@gcd#1.#2.% +}% +\def\POL@aux@mgcd@exit + \expandafter + \POL@aux@mgcd@loop\romannumeral0\POL@aux@gcd#1.\relax.{\xintiiabs{#1}}% +\def\POL@aux@gcd#1.#2.{% + \if0\xintiiSgn{#1}\expandafter\POL@aux@gcd@exit\fi + \expandafter\POL@aux@gcd\romannumeral0\xintmod {#2}{#1}.#1.}% +\def\POL@aux@gcd@exit + \expandafter\POL@aux@gcd\romannumeral0\xintmod #1#2.#3.{{#1}}% + +\def\POL@icontent #1{\romannumeral0\expandafter + \POL@aux@mgcd@loop\romannumeral`^^@#1\relax}% + +\newcommand\PolIContent[1]{\romannumeral0\expandafter + \POL@aux@mgcd@loop\romannumeral`^^@\PolToList{#1}\relax}% + + +\def\POL@makeprim@macro#1% + {\xintREZ{\xintNum{\xintDiv{#1}{\POL@makeprim@icontent}}}}% +\newcommand\PolMakePrimitive[1]{% + \edef\POL@makeprim@icontent{\PolIContent{#1}}% + \PolMapCoeffs\POL@makeprim@macro{#1}% +}% + %% Sturm Algorithm (polexpr 0.4) +%% 0.5 uses primitive polynomials for faster evaluations afterwards \newcommand\PolToSturm{% \@ifstar{\POL@sturm@normalizefalse}{\POL@sturm@normalizetrue}% \POL@ToSturm }% -\newcommand\POL@ToSturm[2]{% +\def\POL@aux@toint#1{\xintREZ{\xintNum{#1}}}% +\def\POL@ToSturm#1#2{% \edef\POL@sturmname{#2}% \POL@let{\POL@sturmname _0}{#1}% - \POL@mapcoeffs{\xintPIrr}{\POL@sturmname _0}% + \PolMakePrimitive{\POL@sturmname _0}% \POL@Diff@@one{\POL@sturmname _0}{\POL@sturmname _1}% + % re-utiliser \POL@varcoeffs directement? + \PolMakePrimitive{\POL@sturmname _1}% \POL@count\@ne \xintloop \POL@divide{\POL@sturmname _\the\numexpr\POL@count-\@ne}% {\POL@sturmname _\the\POL@count}% \expandafter\POL@split\POL@R;\POL@degR\POL@polR \unless\ifnum\POL@degR=\m@ne - % suis-je sûr format raw certain? - \edef\POL@polR{\xintApply{\POL@dooppandirr}{\POL@polR}}% \advance\POL@count\@ne - \expandafter\edef\csname POLuserpol@\POL@sturmname _\the\POL@count\endcsname - {\POL@degR.\noexpand\empty\POL@polR}% + \expandafter\let + \csname POLuserpol@\POL@sturmname _\the\POL@count\endcsname\POL@R + \edef\POL@makeprim@icontent{-\POL@icontent\POL@polR}% + \POL@mapcoeffs\POL@makeprim@macro{\POL@sturmname _\the\POL@count}% \repeat \edef\POL@sturm@N{\the\POL@count}% \ifPOL@sturm@normalize @@ -650,12 +696,10 @@ \advance\POL@count\m@ne \POL@divide{\POL@sturmname _\the\POL@count}% {\POL@sturmname _\POL@sturm@N}% - \expandafter\POL@split\POL@Q;\POL@degQ\POL@polQ - \edef\POL@polQ % suis-je sûr format raw certain? - {\xintApply{\expandafter\XINT_pirr_start\xint_firstofone}{\POL@polQ}}% - \edef\POL@Q{\POL@degQ.\noexpand\empty\POL@polQ}% - \expandafter\edef\csname POLuserpol@\POL@sturmname _\the\POL@count\endcsname - {\POL@degQ.\noexpand\empty\POL@polQ}% + \expandafter\let + \csname POLuserpol@\POL@sturmname _\the\POL@count\endcsname\POL@Q + % quotient actually belongs to Z[X] + \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]}}% @@ -667,9 +711,10 @@ \unless\ifnum\POL@sturm@N=\POL@count \advance\POL@count\@ne \repeat - \expandafter\let\csname PolSturmChainLength_\POL@sturmname \endcsname\POL@sturm@N + \expandafter\let + \csname PolSturmChainLength_\POL@sturmname \endcsname\POL@sturm@N }% -\def\POL@dooppandirr#1{\xintiiOpp{\XINT_pirr_start#1}}% + \newcommand\PolSturmChainLength[1] {\romannumeral`^^@\csname PolSturmChainLength_#1\endcsname}% \newcommand\PolSetToSturmChainSignChangesAt[4][\global]{% @@ -681,8 +726,8 @@ }% \def\POL@sturmchain@getSV@at#1{% ATTENTION USES \POL@count \def\POL@sturmchain@SV{0}% - \edef\POL@isolz@lastsign{\xintiiSgn{\PolEval{\POL@sturmname _0}\At{#1}}}% - \let\POL@IsoRightSign\POL@isolz@lastsign % needed only for SturmIsolate etc... + \edef\POL@sturmchain@sign{\xintiiSgn{\PolEval{\POL@sturmname _0}\At{#1}}}% + \let\POL@isolz@lastsign\POL@sturmchain@sign \POL@count \z@ \ifnum\POL@isolz@lastsign=\z@ \edef\POL@isolz@lastsign @@ -717,17 +762,63 @@ }% -\newcommand\PolSturmIsolateZeros[1]{% - % #1 name of Sturm chain (already pre-computed from a given polynomial) - \edef\POL@sturmname{#1}% - \edef\POL@sturmlength{\PolSturmChainLength{#1}}% +\newcommand\PolSturmIsolateZeros[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 from a given polynomial) + \edef\POL@sturmname{#2}% + \edef\POL@sturmlength{\PolSturmChainLength{#2}}% + \ifx\empty#1\relax + \POL@isolz@getsignchanges@plusinf + \POL@isolz@getsignchanges@minusinf + \else + \edef\POL@isolz@E{\the\numexpr\xint_zapspaces #1 \xint_gobble_i\relax}% + \POL@sturmchain@getSV@at{1[\POL@isolz@E]}% + \let\POL@isolz@plusinf@SV \POL@sturmchain@SV + \let\POL@isolz@plusinf@sign\POL@sturmchain@sign + \POL@sturmchain@getSV@at{-1[\POL@isolz@E]}% + \let\POL@isolz@minusinf@SV \POL@sturmchain@SV + \let\POL@isolz@minusinf@sign\POL@sturmchain@sign + \ifnum\POL@isolz@plusinf@sign=\z@ + \PackageError{polexpr}% +{The polynomial #2 vanishes at set upper bound 10^\POL@isolz@E}% +{Compile again with a bigger exponent in source. (X to abort).}% + \fi + \ifnum\POL@isolz@minusinf@sign=\z@ + \PackageError{polexpr}% +{The polynomial #2 vanishes at set lower bound -10^\POL@isolz@E}% +{Compile again with a bigger exponent in source. (X to abort).}% + \fi + \fi + \edef\POL@isolz@NbOfRoots + {\the\numexpr\POL@isolz@minusinf@SV-\POL@isolz@plusinf@SV}% + \ifnum\POL@isolz@NbOfRoots=\z@ + \begingroup\globaldefs\@ne + \expandafter\xintAssignArray\expandafter\to\csname POL_ZeroInt#2L\endcsname + \expandafter\xintAssignArray\expandafter\to\csname POL_ZeroInt#2R\endcsname + \endgroup + \else + \begingroup\globaldefs\@ne + \expandafter\POL@isolz@initarray\csname POL_ZeroInt#2L\endcsname + \expandafter\POL@isolz@initarray\csname POL_ZeroInt#2R\endcsname + \endgroup + \ifx\empty#1\relax\expandafter\POL@isolz@getaprioribound\fi + \expandafter\POL@isolz@main + \fi +}% +\def\POL@isolz@initarray#1{% + \expandafter\xintAssignArray + \romannumeral\xintreplicate{\POL@isolz@NbOfRoots}{{0}}\to#1% +}% +\def\POL@isolz@getsignchanges@plusinf{% % Count number of sign changes at plus infinity in Sturm sequence \def\POL@isolz@plusinf@SV{0}% - \edef\POL@isolz@lastsign{\xintiiSgn{\PolLeadingCoeff{#1_0}}}% + \edef\POL@isolz@lastsign{\xintiiSgn{\PolLeadingCoeff{\POL@sturmname _0}}}% \let\POL@isolz@plusinf@sign\POL@isolz@lastsign \POL@count\@ne \xintloop - \edef\POL@isolz@newsign{\xintiiSgn{\PolLeadingCoeff{#1_\the\POL@count}}}% + \edef\POL@isolz@newsign + {\xintiiSgn{\PolLeadingCoeff{\POL@sturmname _\the\POL@count}}}% \unless\ifnum\POL@isolz@newsign=\POL@isolz@lastsign \edef\POL@isolz@plusinf@SV{\the\numexpr\POL@isolz@plusinf@SV+\@ne}% \fi @@ -735,17 +826,20 @@ \ifnum\POL@sturmlength>\POL@count \advance\POL@count\@ne \repeat +}% +\def\POL@isolz@getsignchanges@minusinf{% % Count number of sign changes at minus infinity in Sturm sequence \def\POL@isolz@minusinf@SV{0}% - \edef\POL@isolz@lastsign{\xintiiSgn{\PolLeadingCoeff{#1_0}}}% - \ifodd\PolDegree{#1_0} + \edef\POL@isolz@lastsign{\xintiiSgn{\PolLeadingCoeff{\POL@sturmname _0}}}% + \ifodd\PolDegree{\POL@sturmname _0} \edef\POL@isolz@lastsign{\xintiiOpp{\POL@isolz@lastsign}}% \fi \let\POL@isolz@minusinf@sign\POL@isolz@lastsign \POL@count\@ne \xintloop - \edef\POL@isolz@newsign{\xintiiSgn{\PolLeadingCoeff{#1_\the\POL@count}}}% - \ifodd\PolDegree{#1_\the\POL@count} + \edef\POL@isolz@newsign + {\xintiiSgn{\PolLeadingCoeff{\POL@sturmname _\the\POL@count}}}% + \ifodd\PolDegree{\POL@sturmname _\the\POL@count} \edef\POL@isolz@newsign{\xintiiOpp{\POL@isolz@newsign}}% \fi \unless\ifnum\POL@isolz@newsign=\POL@isolz@lastsign @@ -755,24 +849,6 @@ \ifnum\POL@sturmlength>\POL@count \advance\POL@count\@ne \repeat - \edef\POL@isolz@NbOfRoots - {\the\numexpr\POL@isolz@minusinf@SV-\POL@isolz@plusinf@SV}% - \ifnum\POL@isolz@NbOfRoots=\z@ - \begingroup\globaldefs\@ne - \expandafter\xintAssignArray\expandafter\to\csname POL_ZeroInt#1L\endcsname - \expandafter\xintAssignArray\expandafter\to\csname POL_ZeroInt#1R\endcsname - \endgroup - \else - \begingroup\globaldefs\@ne - \expandafter\POL@isolz@initarray\csname POL_ZeroInt#1L\endcsname - \expandafter\POL@isolz@initarray\csname POL_ZeroInt#1R\endcsname - \endgroup - \expandafter\POL@isolz@getaprioribound - \fi -}% -\def\POL@isolz@initarray#1{% - \expandafter\xintAssignArray - \romannumeral\xintreplicate{\POL@isolz@NbOfRoots}{{0}}\to#1% }% % utility macro for a priori bound on root decimal exponent, via Float Rounding \def\POL@isolz@updateE #1e#2;% @@ -800,7 +876,6 @@ % \ifxintverbose\xintMessage{polexpr}{Info}% % {Roots a priori bounded in absolute value by 10 to the \POL@isolz@E.}% % \fi - \POL@isolz@main }% \def\POL@IsoRight@raw{\POL@IsoRight@Int/1[\POL@isolz@E]}% \def\POL@IsoLeft@raw {\POL@IsoLeft@Int/1[\POL@isolz@E]}% @@ -817,8 +892,9 @@ \global\POL@isolz@nextwillneedrefinefalse \def\POL@IsoRight@Int{0}% \POL@sturmchain@getSV@at\POL@IsoRight@raw - \let\POL@IsoRightSV\POL@sturmchain@SV - \let\POL@IsoAtZeroSV\POL@IsoRightSV + \let\POL@IsoRightSV \POL@sturmchain@SV + \let\POL@IsoRightSign\POL@sturmchain@sign + \let\POL@IsoAtZeroSV \POL@IsoRightSV \let\POL@IsoAtZeroSign\POL@IsoRightSign \ifnum\POL@IsoAtZeroSign=\z@ \xdef\POL@isolz@IntervalIndex @@ -830,7 +906,7 @@ {\xintiiOpp{\xintiiSgn{\PolEval{\POL@sturmname _1}\At{0/1[0]}}}}% \fi \def\POL@IsoLeft@Int{-1}% -10^E isn't a root! - \let\POL@IsoLeftSV\POL@isolz@minusinf@SV + \let\POL@IsoLeftSV \POL@isolz@minusinf@SV \let\POL@IsoLeftSign\POL@isolz@minusinf@sign \edef\POL@isolz@NbOfNegRoots{\the\numexpr\POL@IsoLeftSV-\POL@IsoRightSV}% \gdef\POL@isolz@IntervalIndex{0}% @@ -842,7 +918,8 @@ \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@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 @@ -854,7 +931,8 @@ \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@IsoRightSV \POL@sturmchain@SV + \let\POL@IsoRightSign\POL@sturmchain@sign \POL@isolz@check \ifnum\POL@isolz@IntervalIndex=\POL@isolz@NbOfNegRoots\space \expandafter\xintbreakloop @@ -883,7 +961,7 @@ \fi \endgroup \def\POL@IsoLeft@Int{0}% - \let\POL@IsoLeftSV\POL@IsoAtZeroSV + \let\POL@IsoLeftSV \POL@IsoAtZeroSV \let\POL@IsoLeftSign\POL@IsoAtZeroSign \ifnum\POL@IsoLeftSign=\z@ \xdef\POL@isolz@IntervalIndex{\the\numexpr\POL@isolz@IntervalIndex+\@ne}% @@ -891,8 +969,8 @@ \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! + \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@ @@ -900,7 +978,8 @@ \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@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 @@ -914,7 +993,8 @@ % 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@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 @@ -925,7 +1005,7 @@ \ifnum\POL@IsoLeft@Int < \xint_c_ix \repeat \ifnum\POL@isolz@IntervalIndex<\POL@isolz@NbOfRoots\space - % get now the last, right most, root (or roots) + % get now the last, rightmost, root (or roots) \def\POL@IsoRight@Int{10}% \let\POL@IsoRightSign\POL@@IsoRightSign \let\POL@IsoRightSV\POL@@IsoRightSV @@ -976,7 +1056,8 @@ \xintiloop[1+1] \edef\POL@IsoRight@Int{\xintInc{\POL@IsoLeft@Int}}% \POL@sturmchain@getSV@at\POL@IsoRight@raw - \let\POL@IsoRightSV\POL@sturmchain@SV + \let\POL@IsoRightSV \POL@sturmchain@SV + \let\POL@IsoRightSign\POL@sturmchain@sign \POL@isolz@check \let\POL@IsoLeft@Int\POL@IsoRight@Int \let\POL@IsoLeftSV\POL@IsoRightSV |