summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/generic/polexpr/polexprsturm.tex
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/generic/polexpr/polexprsturm.tex')
-rw-r--r--Master/texmf-dist/tex/generic/polexpr/polexprsturm.tex211
1 files changed, 109 insertions, 102 deletions
diff --git a/Master/texmf-dist/tex/generic/polexpr/polexprsturm.tex b/Master/texmf-dist/tex/generic/polexpr/polexprsturm.tex
index d590d48aa56..0edc8b8f0a2 100644
--- a/Master/texmf-dist/tex/generic/polexpr/polexprsturm.tex
+++ b/Master/texmf-dist/tex/generic/polexpr/polexprsturm.tex
@@ -1,7 +1,11 @@
-%% This file polexprsturm.tex is part of the polexpr package (0.8.5, 2021/11/30)
-%% Sturm Algorithm (polexpr 0.4)
+%% filename: polexprsturm.tex
+%% Part of the polexpr package (0.8.6, 2022/01/09)
+%%
+%% Implements the Sturm localization Algorithm
+%% Added at polexpr 0.4
+%%
%% 0.5 uses primitive polynomials for faster evaluations afterwards
-%% 0.6 corrects misuse of \@ifstar! (mumble). \PolToSturm* was broken.
+%% 0.6 corrects misuse of \@ifstar (mumble). \PolToSturm* was broken.
%% 0.6's \PolToSturm* defines both normalized and unnormalized, the
%% unnormalized using two underscores, so both are available
%% Sole difference is that \PolToSturm* also declares them as
@@ -9,19 +13,20 @@
%% holding the coefficients in memory
%% 0.6 fixes the case of a constant polynomial P which caused division
%% by zero error from P'.
-%% 0.8 - fixes 0.7.5 failure to have updated to xint 1.4 format the defined
-%% \xintexpr variables holding the localization intervals extremities
-%% - also, it uses the prem() in computing the Sturm chain, for a 3X
-%% speed gain in the case of the "perturbed" first Wilkinson example
-%%
+%% 0.8 - fixes 0.7.5 compatibility bug with xint 1.4 internal format
+%% regarding the defined \xintexpr variables holding the localization
+%% intervals extremities
+%% - also, it uses the prem() in computing the Sturm chain, with a 3X
+%% speed gain in the case of the "perturbed" first Wilkinson example
+%% 0.8.6 has better a priori bounds for positive and negative roots
\newcount\POL@count
\newif\ifPOL@tosturm@makefirstprimitive\POL@tosturm@makefirstprimitivetrue
\newif\ifPOL@isolz@nextwillneedrefine
%%
\def\PolToSturm{\POL@ifstar{\PolToSturm@@}{\PolToSturm@}}%
\def\POL@aux@toint#1{\xintREZ{\xintNum{#1}}}% for polynomials with int. coeffs!
-%% Attention that some macros rely upon this one setting \POL@sturmname
-%% and \POL@sturm@N as it does
+%% Attention that some macros rely upon this one defining \POL@sturmname
+%% and \POL@sturm@N as it currently does
\def\PolToSturm@#1#2{%
\edef\POL@sturmname{#2}%
% 0.6 uses 2 underscores (one before index, one after) to keep in memory
@@ -61,11 +66,9 @@
}%
\def\POL@tosturm@dosturm{%
\POL@Diff@@one{\POL@sturmname _0_}{\POL@sturmname _1_}%
- % re-utiliser \POL@varcoeffs directement?
\POL@makeprimitive{\POL@sturmname _1_}% does not do \POL@newpol
\POL@count\@ne
\xintloop
- % prior to 0.8, code was using here \POL@divide
\POL@getprem{\POL@sturmname _\the\numexpr\POL@count-\@ne\relax _}%
{\POL@sturmname _\the\POL@count _}%
\expandafter\POL@split\POL@R;\POL@degR\POL@polR
@@ -117,7 +120,8 @@
\POL@sturmchain@getSV@at\POL@sturmchain@X
#1\let#2\POL@sturmchain@SV
}%
-\def\POL@sturmchain@getSV@at#1{% ATTENTION USES \POL@count
+% attention that this modifies current \POL@count value
+\def\POL@sturmchain@getSV@at#1{%
\def\POL@sturmchain@SV{0}%
\edef\POL@sturmchain@sign{\xintiiSgn{\POL@eval{\POL@sturmname _0}{#1}}}%
\let\POL@isolz@lastsign\POL@sturmchain@sign
@@ -166,7 +170,6 @@
{\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}}%
@@ -196,10 +199,6 @@
\edef\POL@sturm@N{\@nameuse{PolSturmChainLength_\POL@sturmname}}%
% isolate the roots (detects case of constant polynomial)
\PolSturmIsolateZeros@{\POL@sturmname}%
- % 0.8.4 fix: these declarations were formerly not executed in absence of roots!
- % on ne va pas utiliser de Horner, mais des divisions par X - x, et ces
- % choses vont évoluer, ainsi que le coefficient dominant entier
- % (pour \POL@divide entre autres if faut des noms de user pol)
\XINT_global
\expandafter\let
\csname POLuserpol@\POL@sturmname\POL@sqfnorr\expandafter\endcsname
@@ -219,7 +218,6 @@
\begingroup\globaldefs\@ne
\expandafter\POL@initarray\csname POL_ZM\POL@sturmname*\endcsname{1}%
\endgroup
- % 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
@@ -227,12 +225,10 @@
{\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}}%
-% ATTENTION QUE LA CONVENTION DE SIGNE POUR \POL@findrat@E EST OPPOSÉE À CELLE
-% POUR LE CODE PLUS ANCIEN FAISANT "REFINE"
\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
+ % factor them out from original (Sturm root) polynomial
\ifnum\POL@findrat@E<7 %
\def\POL@findrat@index{1}%
\POL@findrat@loop@secondpass@direct
@@ -252,7 +248,6 @@
\POL@newpol{\POL@sturmname\POL@norr}% with multiplicities
}%
\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_ZK\POL@sturmname*\xintiloopindex\endcsname
@@ -261,8 +256,6 @@
\ifnum\xintiloopindex<\POL@isolz@NbOfRoots\space
\repeat }%
\begingroup\globaldefs\@ne
- % 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
}%
@@ -286,11 +279,6 @@
}%
\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@_
@@ -313,15 +301,13 @@
\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@getE #1/1[#2]{#2}%
\def\POL@findrat@loop@a{%
% attention that the width may have been already smaller than 10^{-6}
\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
@@ -364,9 +350,7 @@
\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^9 au pire donc ok pour \numexpr
- % we will drop integral part in our updating P
+% 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
@@ -382,7 +366,6 @@
\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}%
@@ -474,7 +457,8 @@
{\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
+% using ii version is an abuse
+ \xintiiifNeg{\POL@findrat@Lscaled}%
{% 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]}%
@@ -572,13 +556,8 @@
% 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_
@@ -640,7 +619,7 @@
\fi
}%
\def\POL@isolzmult@defvar@M{%
- % Attention that is used not only in ...GetMultiplicities@ but also
+ % Attention that this is used not only in ...GetMultiplicities@ but also
% in FindRationalRoots
\begingroup\xintglobaldefstrue
% added at 0.7
@@ -739,7 +718,7 @@
% #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)
- % For reasons I have forgotten (no time now) this code **must** be used
+ % For reasons I have forgotten this code **must** be used
% with a *normalized* Sturm chain.
\edef\POL@sturmname{#2}%
\edef\POL@sturmlength{\PolSturmChainLength{#2}}%
@@ -749,22 +728,23 @@
\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]}%
+ \edef\POL@isolz@E@pos{\the\numexpr\xint_zapspaces #1 \xint_gobble_i\relax}%
+ \let\POL@isolz@E@neg\POL@isolz@E@pos
+ \POL@sturmchain@getSV@at{1[\POL@isolz@E@pos]}%
\let\POL@isolz@plusinf@SV \POL@sturmchain@SV
\let\POL@isolz@plusinf@sign\POL@sturmchain@sign
- \POL@sturmchain@getSV@at{-1[\POL@isolz@E]}%
+ \POL@sturmchain@getSV@at{-1[\POL@isolz@E@neg]}%
\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).}%
+{The polynomial #2 vanishes at set upper bound 10^\POL@isolz@E@pos}%
+{Try again with a larger exponent. (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).}%
+{The polynomial #2 vanishes at set lower bound -10^\POL@isolz@E@neg}%
+{Try again with a larger exponent. (X to abort).}%
\fi
\fi
\edef\POL@isolz@NbOfRoots
@@ -792,7 +772,8 @@
}%
\def\POL@initarray#1#2{%
% ATTENTION, if only one item, \xintAssignArray UNBRACES IT
-% so we use an \empty trick to avoid that. Maybe considered a bug of xinttools?
+% (is this to be considered as a bug of xinttools?)
+% We use an \empty trick to avoid that.
\expandafter\xintAssignArray\expandafter\empty
\romannumeral\xintreplicate{\POL@isolz@NbOfRoots}{{#2}}\to#1%
}%
@@ -836,9 +817,18 @@
\advance\POL@count\@ne
\repeat
}%
-% 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}%
+% This utility macro bounds positive roots (strictly) by a 10^Epos
+% and negative roots strictly by some -10^Eneg.
+% (prior to 0.8.6, an E was found with -10^E < all roots < 10^E)
+% To obtain Epos, the Cauchy bound "1 + max_j {-a_j/lc(P)|}"
+% is used, where non-negative a_j/lc(P)'s are ignored.
+% In case the a_j's all have same sign as lc(P) or vanish, there are
+% no positive roots. And the macro in this case outputs an E=0 exponent.
+% But if at least one non-zero a_j has opposite sign to the leading coeff,
+% the produced E will be at least 1.
+% Thus if E=0 on exit, it is proof that there are no (positive) roots.
+\def\POL@isolz@updateE #1;%
+ {\unless\ifnum#1<\POL@isolz@E\space\edef\POL@isolz@E{\the\numexpr#1+\@ne}\fi}%
\def\POL@isolz@getaprioribound{%
\PolAssign{\POL@sturmname _0}\toarray\POL@arrayA
\edef\POL@isolz@leading{\POL@arrayA{\POL@arrayA{0}}}%
@@ -849,19 +839,47 @@
\expandafter\edef\csname POL@arrayA\the\POL@count\endcsname
{\xintDiv{\POL@arrayA\POL@count}\POL@isolz@leading}%
\repeat
- \def\POL@isolz@E{1}% WE SEEK SMALLEST E SUCH HAT -10^E < roots < +10^E
+% We want an E such that 0 < positive roots < +10^E
+ \def\POL@isolz@E{0}%
\advance\POL@count\m@ne
\xintloop
\ifnum\POL@count>\z@
- \expandafter\POL@isolz@updateE
- % use floating point to get decimal exponent
- \romannumeral0\xintfloat[4]% should I use with [2] rather? (should work)
- {\xintAdd{1/1[0]}{\xintAbs{\POL@arrayA\POL@count}}};%
+% only those coefficients with opposite sign to the leading coefficient
+% trigger an E update
+ \xintiiifSgn{\POL@arrayA\POL@count}%
+ {\expandafter\POL@isolz@updateE
+ \the\numexpr\xintilogten{\xintAdd{1/1[0]}{\xintiiOpp{\POL@arrayA\POL@count}}};%
+ }{}{}%
\advance\POL@count\m@ne
\repeat
- % \ifxintverbose\xintMessage{polexpr}{Info}%
- % {Roots a priori bounded in absolute value by 10 to the \POL@isolz@E.}%
- % \fi
+ \let\POL@isolz@E@pos\POL@isolz@E
+% We want an E such that 0 > negative roots > -10^E
+ \def\POL@isolz@E{0}%
+ \POL@count\POL@arrayA{0}\relax
+ \advance\POL@count\m@ne
+ \xintloop
+ \ifnum\POL@count>\@ne
+ \xintiiifSgn{\xintiiOpp{\POL@arrayA\POL@count}}%
+ {\expandafter\POL@isolz@updateE
+ \the\numexpr\xintilogten{\xintAdd{1/1[0]}{\POL@arrayA\POL@count}};%
+ }{}{}%
+ \advance\POL@count\m@ne
+ \xintiiifSgn{\POL@arrayA\POL@count}%
+ {\expandafter\POL@isolz@updateE
+ \the\numexpr\xintilogten{\xintAdd{1/1[0]}{\xintiiOpp{\POL@arrayA\POL@count}}};%
+ }{}{}%
+ \advance\POL@count\m@ne
+ \repeat
+ \ifnum\POL@count=\@ne
+ \xintiiifSgn{\xintiiOpp{\POL@arrayA\POL@count}}%
+ {\expandafter\POL@isolz@updateE
+ \the\numexpr\xintilogten{\xintAdd{1/1[0]}{\POL@arrayA\POL@count}};%
+ }{}{}%
+ \fi
+ \let\POL@isolz@E@neg\POL@isolz@E
+ \ifxintverbose
+ \xintMessage{polexpr}{Info}{Epos=\POL@isolz@E@pos, Eneg=\POL@isolz@E@neg.}%
+ \fi
}%
\def\POL@IsoRight@raw{\POL@IsoRight@Int/1[\POL@isolz@E]}%
\def\POL@IsoLeft@raw {\POL@IsoLeft@Int/1[\POL@isolz@E]}%
@@ -875,8 +893,6 @@
{\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.
\global\POL@isolz@nextwillneedrefinefalse
\def\POL@IsoRight@Int{0}%
\POL@sturmchain@getSV@at\POL@IsoRight@raw
@@ -899,12 +915,13 @@
% \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}%
- \let\POL@isolz@@E\POL@isolz@E
+% 0.8.6 has separate initial E's for positive and negative roots
+ \let\POL@isolz@E\POL@isolz@E@neg
\ifnum\POL@isolz@NbOfNegRoots>\z@
-% refactored at 0.7 to fix cases leading to an intervals with zero as end-point
+% refactored at 0.7 to fix cases leading to intervals having zero as end-point
\POL@isolz@findroots@neg
\fi
- \let\POL@isolz@E\POL@isolz@@E
+ \let\POL@isolz@E\POL@isolz@E@pos
\def\POL@IsoLeft@Int{0}%
\let\POL@IsoLeftSV \POL@IsoAtZeroSV % véritable SV en zéro
\let\POL@IsoLeftSign\POL@IsoAtZeroSign% véritable signe en zéro
@@ -973,10 +990,6 @@
\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
@@ -985,7 +998,7 @@
% 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 now 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
@@ -1101,14 +1114,6 @@
\ifnum\POL@IsoRightSign=\POL@@IsoRightSign\space
\repeat
% now second root has been separated from the one at left end point
-% we update the storage of the root at left for it to have the same number
-% of digits in mantissa. No, I decided not to do that to avoid complications.
- % \begingroup
- % \let\POL@IsoRight@Int\POL@IsoLeft@Int
- % \def\POL@IsoRightSign{0}%
- % \edef\POL@isolz@IntervalIndex{\the\numexpr\POL@isolz@IntervalIndex-\@ne}%
- % \POL@refine@storeleftandright
- % \endgroup
\edef\POL@@IsoRight@Int{\xintDSL{\xintInc{\xintDSR{\POL@IsoLeft@Int}}}}%
\let\POL@IsoLeft@Int\POL@IsoRight@Int
\let\POL@IsoLeftSign\POL@IsoRightSign
@@ -1128,7 +1133,7 @@
% the IsoRightSign is now wrong but here we don't care
\fi\fi
\fi
- % on exit, exact root found iff \POL@IsoRightSign is zero
+ % on exit, exact root has been found iff \POL@IsoRightSign is zero
\POL@refine@storeleftandright
\endgroup
}%
@@ -1224,7 +1229,6 @@
\fi
\begingroup\xintglobaldefstrue
% skip some overhead of \xintdefvar...
- % Let me repeat: ATTENTION to change of internal format at xint 1.4
\XINT_expr_defvar_one{\POL@sturmname L_\POL@isolz@IntervalIndex}%
{{\POL@IsoLeft@rawout}}%
\XINT_expr_defvar_one{\POL@sturmname R_\POL@isolz@IntervalIndex}%
@@ -1235,7 +1239,6 @@
\endgroup
}%
%% \PolRefineInterval
-%% ATTENTION TO xint 1.4 INTERNAL CHANGES
\def\POL@xintexprGetVar#1{\expandafter\expandafter\expandafter\xint_firstofone
\csname XINT_expr_varvalue_#1\endcsname}%
% attention, also used by \POL@findrat@loop@a
@@ -1346,9 +1349,6 @@
%
%
\def\PolIntervalWidth#1#2{%
-% le \xintRez est à cause des E positifs, car trailing zéros explicites
-% si je travaillais à partir des variables xintexpr directement ne devrait
-% pas être nécessaire, mais trop fragile par rapport à chgt internes possibles
\romannumeral0\xintrez{\xintSub{\@nameuse{POL_ZR#1*}{#2}}%
{\@nameuse{POL_ZL#1*}{#2}}}
}%
@@ -1363,7 +1363,8 @@
}%
\def\POL@ensureintervallengths{%
\POL@count\z@
- % \POL@count used by \POL@sturmchain@getSV@at but latter not used
+ % attention that \POL@count would be modified by \POL@sturmchain@getSV@at
+ % but this latter macro not invoked by \POL@ensure@one
\xintloop
\advance\POL@count\@ne
\edef\POL@isolz@IntervalIndex{\the\POL@count}%
@@ -1377,11 +1378,8 @@
\edef\POL@sturmname{#1}%
\edef\POL@ensure@targetE{\the\numexpr#3}%
\edef\POL@isolz@IntervalIndex{\the\numexpr#2}%
-% 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_ZL\POL@sturmname*0\endcsname>\z@
-% je ne fais pas les \expandafter mais je préfèrerais ne pas être à l'intérieur
\POL@ensure@one
\fi
\fi
@@ -1438,8 +1436,9 @@
\catcode`_ 8 %
\catcode`& 4 %
\def\PolPrintIntervals{\POL@ifstar{\PolPrintIntervals@@}{\PolPrintIntervals@}}%
-% As explained in the docs, this is an example of customization so is not
-% itself customizable, apart from redefining it entirely!
+% As explained in the docs, the starred version is an example of customization
+% It is itself basically not easily customizable, except for this:
+\def\PolPrintIntervals@@arraystretch{2}% (the 2 was hardcoded prior to 0.8.6)
\def\PolPrintIntervals@@{%
\begingroup
\def\POL@AfterPrintIntervals{\endgroup}%
@@ -1447,14 +1446,14 @@
\let\PolPrintIntervalsUnknownRoot\POL@@PrintIntervalsUnknownRoot
\let\PolPrintIntervalsKnownRoot\POL@@PrintIntervalsKnownRoot
\ifdefined\array
- \def\arraystretch{2}%
+ \let\arraystretch\PolPrintIntervals@@arraystretch
\def\PolPrintIntervalsBeginEnv{\[\begin{array}{cl}}%\]
\def\PolPrintIntervalsEndEnv{\end{array}\]}%
\else
\def\PolPrintIntervalsBeginEnv{$$\tabskip0pt plus 1000pt minus 1000pt
\halign to\displaywidth\bgroup
- \hfil\vrule height 2\ht\strutbox
- depth 2\dp\strutbox
+ \hfil\vrule height \PolPrintIntervals@@arraystretch\ht\strutbox
+ depth \PolPrintIntervals@@arraystretch\dp\strutbox
width \z@
$####$\tabskip6pt&$####$\hfil
\tabskip0pt plus 1000pt minus 1000pt\cr}%$$
@@ -1476,6 +1475,10 @@
\begingroup\edef\POL@tmp{\endgroup
\unexpanded\expandafter{\PolPrintIntervalsBeginEnv}%
\unexpanded\expandafter{\POL@PrintIntervals@Loop}%
+% This is added at 0.8.6 to allow usage of amsmath environment as they typeset
+% twice: we must prepare for a second execution. Adds slight general overhead.
+ \gdef\noexpand\PolPrintIntervalsTheIndex{1}%
+ \noexpand\POL@PrintIntervals@DoDefs
\unexpanded\expandafter{\PolPrintIntervalsEndEnv}%
}\POL@tmp
\fi
@@ -1485,7 +1488,7 @@
}%
\let\POL@AfterPrintIntervals\empty
\let\PolPrintIntervalsNoRealRoots\empty
-\def\PolPrintIntervalsArrayStretch{1}%
+\def\PolPrintIntervalsArrayStretch{1}% used by non-starred version
\ifdefined\array
\def\PolPrintIntervalsBeginEnv{\[\begin{array}{rcccl}}%
\def\PolPrintIntervalsEndEnv{\end{array}\]}%
@@ -1558,7 +1561,6 @@
}%
\catcode`& 7 %
\catcode`_ 11 %
-\def\POL@PrintIntervals@Loop#1{%
\def\POL@PrintIntervals@Loop{%
\POL@SturmIfZeroExactlyKnown\PolPrintIntervalsTheSturmName
\PolPrintIntervalsTheIndex
@@ -1568,10 +1570,15 @@
\unless\ifnum\PolPrintIntervalsTheIndex>
\@nameuse{POL_ZL\PolPrintIntervalsTheSturmName*0}
\POL@PrintIntervals@DoDefs
- \xint_afterfi{#1\POL@PrintIntervals@Loop}%
+ \xint_afterfi{\PolPrintIntervalsRowSeparator\POL@PrintIntervals@Loop}%
\fi
-}}%
-\ifdefined\array\POL@PrintIntervals@Loop{\\}\else\POL@PrintIntervals@Loop{\cr}\fi
+}%
+% added at 0.8.6:
+\ifdefined\array
+ \def\PolPrintIntervalsRowSeparator{\\}%
+\else
+ \def\PolPrintIntervalsRowSeparator{\cr}%
+\fi
\def\POL@PrintIntervals@DoDefs{%
\xdef\PolPrintIntervalsTheLeftEndPoint{%
\csname POL_ZL\PolPrintIntervalsTheSturmName*\PolPrintIntervalsTheIndex