diff options
Diffstat (limited to 'Master')
-rw-r--r-- | Master/texmf-dist/doc/latex/polexpr/README.md | 54 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/polexpr/polexpr.html | 820 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/polexpr/polexpr.txt | 713 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/polexpr/polexpr.sty | 202 |
4 files changed, 1383 insertions, 406 deletions
diff --git a/Master/texmf-dist/doc/latex/polexpr/README.md b/Master/texmf-dist/doc/latex/polexpr/README.md index f5b45b5d23d..e6a1026e61c 100644 --- a/Master/texmf-dist/doc/latex/polexpr/README.md +++ b/Master/texmf-dist/doc/latex/polexpr/README.md @@ -22,8 +22,8 @@ This Work has the LPPL maintenance status author-maintained. The Author of this Work is Jean-François Burnol. -This Work consists of the package file polexpr.sty, this README.md and the -documentation file polexpr.txt. +This Work consists of the package file polexpr.sty, this README.md and +the documentation file polexpr.txt. Abstract -------- @@ -37,10 +37,10 @@ composition of functions) with standard operators, fractional numbers functions or other constructs as recognized by the `\xintexpr` numerical parser. -The polynomials are then not only genuine `\xintexpr` numerical -functions but additionally are also known to the package via their -coefficients. This allows dedicated macros to implement polynomial -algorithmics. +The polynomials are then not only genuine `\xintexpr` (and +`\xintfloatexpr`) numerical functions but additionally are known to the +package via their coefficients. This allows dedicated macros to +implement polynomial algorithmics. CHANGE LOG ---------- @@ -52,7 +52,6 @@ CHANGE LOG - Various utilities such as `\PolFromCSV`, `\PolMapCoeffs`, `\PolToCSV`, `\PolToExpr`, ... Only one-variable polynomials so far. - - v0.2 (2018/01/14) - Fix: `"README thinks \numexpr recognizes ^ operator"`. - Convert README to reStructuredText markup. @@ -64,4 +63,45 @@ CHANGE LOG - Convert README to (CTAN compatible) Markdown markup. Due to lack of available time the test suite might not be extensive enough. Bug reports are very welcome! +- v0.3 (2018/01/17) + - bug fixes: + - the `0.1` `\PolEval` accepted expressions for its second + argument, but this was removed by mistake at `0.2`. + Restored. + - incompatible or breaking changes: + - `\PolToExpr` now by default uses *descending* powers (it + also treats differently coefficients equal to 1 or -1.) Use + `\PolToExpr*` for *ascending* powers. + - `\PolEval` reduced the output to smallest terms, but as this is + costly with big fractions and not needed if e.g. wrapped in + an `\xintRound` or `\xintFloat`, this step has been removed; + the former meaning is available as `\PolEvalReduced`. + - new (or newly documented) macros: + - `\PolTypesetCmd` + - `\PolTypesetCmdPrefix`, + - `\PolTypesetMonomialCmd`, + - `\PolEvalReduced`, + - `\PolFloatEval`, + - `\PolToFloatExpr`, + - `\PolToExprOneTerm`, + - `\PolToFloatExprOneTerm`, + - `\PolToExprCmd`, + - `\PolToFloatExprCmd`, + - `\PolToExprTermPrefix`, + - `\PolToExprVar`, + - `\PolToExprTimes`. + - improvements: + - documentation has a table of contents, internal hyperlinks, + standardized signature notations and added explanations. + - one can do `\PolLet{g}={f}` or `\PolLet{g}{f}`. + - `\PolToExpr{f}` is highly customizable. + - `\poldef` and other defining macros prepare the polynomial + functions for usage within `\xintthefloatexpr` (or + `\xintdeffloatvar`). Coefficients are pre-rounded to the + floating point precision. Indispensible for numerical + algorithms, as exact fractions, even reduced, quickly become + very big. See the documentation about how to use the exact + polynomials also in floating point context. +- v0.3.1 (2018/01/18) + Fixes two typos in example code included in the documentation. diff --git a/Master/texmf-dist/doc/latex/polexpr/polexpr.html b/Master/texmf-dist/doc/latex/polexpr/polexpr.html index d5f3237a0b2..962771bdfa7 100644 --- a/Master/texmf-dist/doc/latex/polexpr/polexpr.html +++ b/Master/texmf-dist/doc/latex/polexpr/polexpr.html @@ -6,7 +6,7 @@ <meta name="generator" content="Docutils 0.14: http://docutils.sourceforge.net/" /> <title>Package polexpr documentation</title> <style type="text/css"> -body{font-size: 14pt;} +body{font-size: 13pt;} /* :Author: David Goodger (goodger@python.org) :Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $ @@ -362,35 +362,101 @@ ul.auto-toc { <body> <div class="document" id="package-polexpr-documentation"> <h1 class="title">Package polexpr documentation</h1> +<h2 class="subtitle" id="id1">0.3.1 (2018/01/18)</h2> <!-- comment: -*- fill-column: 72; mode: rst; -*- --> +<div class="contents topic" id="contents"> +<p class="topic-title first">Contents</p> +<ul class="simple"> +<li><a class="reference internal" href="#first-examples" id="id15">First Examples</a></li> +<li><a class="reference internal" href="#non-expandable-macros" id="id16">Non-expandable macros</a><ul> +<li><a class="reference internal" href="#poldef-polname-letter-expression-in-letter" id="id17"><tt class="docutils literal">\poldef <span class="pre">polname(letter):=</span> expression in letter;</tt></a></li> +<li><a class="reference internal" href="#poldef-letter-polname-expression-in-letter" id="id18"><tt class="docutils literal"><span class="pre">\PolDef[letter]{polname}{expression</span> in letter}</tt></a></li> +<li><a class="reference internal" href="#pollet-polname-2-polname-1" id="id19"><tt class="docutils literal"><span class="pre">\PolLet{polname_2}={polname_1}</span></tt></a></li> +<li><a class="reference internal" href="#polassign-polname-toarray-macro" id="id20"><tt class="docutils literal"><span class="pre">\PolAssign{polname}\toarray\macro</span></tt></a></li> +<li><a class="reference internal" href="#polget-polname-fromarray-macro" id="id21"><tt class="docutils literal"><span class="pre">\PolGet{polname}\fromarray\macro</span></tt></a></li> +<li><a class="reference internal" href="#polfromcsv-polname-csv" id="id22"><tt class="docutils literal"><span class="pre">\PolFromCSV{polname}{<csv>}</span></tt></a></li> +<li><a class="reference internal" href="#poltypeset-polname" id="id23"><tt class="docutils literal">\PolTypeset{polname}</tt></a><ul> +<li><a class="reference internal" href="#poltypesetcmd-raw-coeff" id="id24"><tt class="docutils literal">\PolTypesetCmd{raw_coeff}</tt></a></li> +<li><a class="reference internal" href="#poltypesetcmdprefix-raw-coeff" id="id25"><tt class="docutils literal">\PolTypesetCmdPrefix{raw_coeff}</tt></a></li> +<li><a class="reference internal" href="#poltypesetmonomialcmd" id="id26"><tt class="docutils literal">\PolTypesetMonomialCmd</tt></a></li> +</ul> +</li> +<li><a class="reference internal" href="#id5" id="id27"><tt class="docutils literal"><span class="pre">\PolTypeset*{polname}</span></tt></a></li> +<li><a class="reference internal" href="#poldiff-polname-1-polname-2" id="id28"><tt class="docutils literal"><span class="pre">\PolDiff{polname_1}{polname_2}</span></tt></a></li> +<li><a class="reference internal" href="#poldiff-n-polname-1-polname-2" id="id29"><tt class="docutils literal"><span class="pre">\PolDiff[N]{polname_1}{polname_2}</span></tt></a></li> +<li><a class="reference internal" href="#polantidiff-polname-1-polname-2" id="id30"><tt class="docutils literal"><span class="pre">\PolAntiDiff{polname_1}{polname_2}</span></tt></a></li> +<li><a class="reference internal" href="#polantidiff-n-polname-1-polname-2" id="id31"><tt class="docutils literal"><span class="pre">\PolAntiDiff[N]{polname_1}{polname_2}</span></tt></a></li> +<li><a class="reference internal" href="#poldivide-polname-1-polname-2-polname-q-polname-r" id="id32"><tt class="docutils literal"><span class="pre">\PolDivide{polname_1}{polname_2}{polname_Q}{polname_R}</span></tt></a></li> +<li><a class="reference internal" href="#polgcd-polname-1-polname-2-polname-gcd" id="id33"><tt class="docutils literal"><span class="pre">\PolGCD{polname_1}{polname_2}{polname_GCD}</span></tt></a></li> +<li><a class="reference internal" href="#polmapcoeffs-macro-polname" id="id34"><tt class="docutils literal"><span class="pre">\PolMapCoeffs{\macro}{polname}</span></tt></a></li> +<li><a class="reference internal" href="#polreducecoeffs-polname" id="id35"><tt class="docutils literal">\PolReduceCoeffs{polname}</tt></a></li> +</ul> +</li> +<li><a class="reference internal" href="#expandable-macros" id="id36">Expandable macros</a><ul> +<li><a class="reference internal" href="#poleval-polname-at-numerical-expression" id="id37"><tt class="docutils literal"><span class="pre">\PolEval{polname}\At{numerical</span> expression}</tt></a></li> +<li><a class="reference internal" href="#polevalreduced-polname-at-numerical-expression" id="id38"><tt class="docutils literal"><span class="pre">\PolEvalReduced{polname}\At{numerical</span> expression}</tt></a></li> +<li><a class="reference internal" href="#polfloateval-polname-at-numerical-expression" id="id39"><tt class="docutils literal"><span class="pre">\PolFloatEval{polname}\At{numerical</span> expression}</tt></a></li> +<li><a class="reference internal" href="#polnthcoeff-polname-number" id="id40"><tt class="docutils literal"><span class="pre">\PolNthCoeff{polname}{number}</span></tt></a></li> +<li><a class="reference internal" href="#poldegree-polname" id="id41"><tt class="docutils literal">\PolDegree{polname}</tt></a></li> +<li><a class="reference internal" href="#poltoexpr-polname" id="id42"><tt class="docutils literal">\PolToExpr{polname}</tt></a><ul> +<li><a class="reference internal" href="#poltoexproneterm-raw-coeff-number" id="id43"><tt class="docutils literal"><span class="pre">\PolToExprOneTerm{raw_coeff}{number}</span></tt></a></li> +<li><a class="reference internal" href="#poltoexpronetermstyleb-raw-coeff-number" id="id44"><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="id45"><tt class="docutils literal">\PolToExprCmd{raw_coeff}</tt></a></li> +<li><a class="reference internal" href="#poltoexprtermprefix-raw-coeff" id="id46"><tt class="docutils literal">\PolToExprTermPrefix{raw_coeff}</tt></a></li> +<li><a class="reference internal" href="#poltoexprvar" id="id47"><tt class="docutils literal">\PolToExprVar</tt></a></li> +<li><a class="reference internal" href="#poltoexprtimes" id="id48"><tt class="docutils literal">\PolToExprTimes</tt></a></li> +</ul> +</li> +<li><a class="reference internal" href="#id12" id="id49"><tt class="docutils literal"><span class="pre">\PolToExpr*{polname}</span></tt></a></li> +<li><a class="reference internal" href="#poltofloatexpr-polname" id="id50"><tt class="docutils literal">\PolToFloatExpr{polname}</tt></a><ul> +<li><a class="reference internal" href="#poltofloatexproneterm-raw-coeff-number" id="id51"><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="id52"><tt class="docutils literal">\PolToFloatExprCmd{raw_coeff}</tt></a></li> +</ul> +</li> +<li><a class="reference internal" href="#id13" id="id53"><tt class="docutils literal"><span class="pre">\PolToFloatExpr*{polname}</span></tt></a></li> +<li><a class="reference internal" href="#poltolist-polname" id="id54"><tt class="docutils literal">\PolToList{polname}</tt></a></li> +<li><a class="reference internal" href="#poltocsv-polname" id="id55"><tt class="docutils literal">\PolToCSV{polname}</tt></a></li> +</ul> +</li> +<li><a class="reference internal" href="#booleans-with-default-setting-as-indicated" id="id56">Booleans (with default setting as indicated)</a><ul> +<li><a class="reference internal" href="#xintverbosefalse" id="id57"><tt class="docutils literal">\xintverbosefalse</tt></a></li> +<li><a class="reference internal" href="#poltypesetallfalse" id="id58"><tt class="docutils literal">\poltypesetallfalse</tt></a></li> +<li><a class="reference internal" href="#poltoexprallfalse" id="id59"><tt class="docutils literal">\poltoexprallfalse</tt></a></li> +</ul> +</li> +<li><a class="reference internal" href="#technicalities" id="id60">Technicalities</a></li> +<li><a class="reference internal" href="#releases" id="id61">RELEASES</a></li> +<li><a class="reference internal" href="#acknowledgments" id="id62">Acknowledgments</a></li> +</ul> +</div> <div class="section" id="first-examples"> -<h1>First Examples</h1> +<h1><a class="toc-backref" href="#id15">First Examples</a></h1> <p>The syntax is:</p> <pre class="literal-block"> -\poldef <name>(x):=<expression in variable x>; +\poldef polname(x):= expression in variable x; </pre> <p>where in place of <tt class="docutils literal">x</tt> an arbitrary <em>dummy variable</em> is authorized -(i.e. per default any of <tt class="docutils literal"><span class="pre">[a..z|A..Z]</span></tt>; more letters can be declared +(i.e. per default any of <tt class="docutils literal"><span class="pre">[a-z|A-Z]</span></tt>; more letters can be declared under Unicode engines.) One can also issue:</p> <pre class="literal-block"> -\PolDef{name}{expression in variable x} +\PolDef{polname}{expression in variable x} </pre> <p>which admits an optional first argument to modify the variable letter from its default <tt class="docutils literal">x</tt>.</p> <dl class="docutils"> <dt><tt class="docutils literal">\poldef <span class="pre">f(x):=</span> <span class="pre">1-x+x^2;</span></tt></dt> -<dd>defines polynomial <tt class="docutils literal">f</tt>. Polynomial names must start with a letter -and may contain letters, digits, and underscores. The variable must -be a single letter. The colon character is optional. The semi-colon -at end of expression is mandatory.</dd> +<dd>defines polynomial <tt class="docutils literal">f</tt>. Polynomial names must start with a +letter and may contain letters, digits, and underscores. The +variable must be a single letter. The colon character is optional. +The semi-colon at end of expression is mandatory.</dd> <dt><tt class="docutils literal"><span class="pre">\PolDef{f}{1-x+x^2}</span></tt></dt> <dd>does the same as <tt class="docutils literal">\poldef <span class="pre">f(x):=</span> <span class="pre">1-x+x^2;</span></tt> To use another letter than <tt class="docutils literal">x</tt> in the expression, one must pass it as an extra optional argument to <tt class="docutils literal">\PolDef</tt>. Useful if the semi-colon has been assigned some non-standard catcode by some package.</dd> -<dt><tt class="docutils literal"><span class="pre">\PolLet{g}{f}</span></tt></dt> -<dd>saves a copy of <tt class="docutils literal">f</tt> under name <tt class="docutils literal">g</tt>.</dd> +<dt><tt class="docutils literal"><span class="pre">\PolLet{g}={f}</span></tt></dt> +<dd>saves a copy of <tt class="docutils literal">f</tt> under name <tt class="docutils literal">g</tt>. Also usable without <tt class="docutils literal">=</tt>.</dd> <dt><tt class="docutils literal">\poldef <span class="pre">f(z):=</span> <span class="pre">f(z)^2;</span></tt></dt> <dd>redefines <tt class="docutils literal">f</tt> in terms of itself.</dd> <dt><tt class="docutils literal">\poldef <span class="pre">f(T):=</span> <span class="pre">f(f(T));</span></tt></dt> @@ -429,68 +495,127 @@ a parsed polynomial expression does the Euclidean quotient:</p> \poldef k(x):= (x-1)(x-2)(x-3)(x-4)/(x^2-5x+4); </pre> </div> -<div class="admonition attention"> +<div class="admonition attention" id="warningtacit"> <p class="first admonition-title">Attention!</p> -<p class="last"><tt class="docutils literal">1/2 x</tt> skips the space and is treated like <tt class="docutils literal"><span class="pre">1/(2x)</span></tt> because of -the tacit multiplication rules of xintexpr. But this means it gives -zero! Thus one must use <tt class="docutils literal">(1/2)x</tt> or <tt class="docutils literal">1/2*x</tt> or <tt class="docutils literal"><span class="pre">(1/2)*x</span></tt> for -disambiguation: <tt class="docutils literal"><span class="pre">x-1/2*x^2+1/3*x^3...</span></tt></p> +<p><tt class="docutils literal">1/2 x^2</tt> skips the space and is treated like <tt class="docutils literal"><span class="pre">1/(2*x^2)</span></tt> because +of the tacit multiplication rules of xintexpr. But this means it +gives zero! Thus one must use <tt class="docutils literal">(1/2)x^2</tt> or <tt class="docutils literal">1/2*x^2</tt> or +<tt class="docutils literal"><span class="pre">(1/2)*x^2</span></tt> for disambiguation: <tt class="docutils literal">x - 1/2*x^2 + <span class="pre">1/3*x^3...</span></tt>. It is +even simpler to move the denominator to the right: <tt class="docutils literal">x - x^2/2 + +x^3/3 - ...</tt>.</p> +<p class="last">It is worth noting that <tt class="docutils literal"><span class="pre">1/2(x-1)(x-2)</span></tt> suffers the same issue: +<a class="reference external" href="http://www.ctan.org/pkg/xint">xint</a> tacit multiplication always "ties more", hence this gets +interpreted as <tt class="docutils literal"><span class="pre">1/(2*(x-1)*(x-2))</span></tt> which gives zero by polynomial +division. Thus, use one of <tt class="docutils literal"><span class="pre">(1/2)(x-1)(x-2)</span></tt>, <tt class="docutils literal"><span class="pre">1/2*(x-1)(x-2)</span></tt> or +<tt class="docutils literal"><span class="pre">(x-1)(x-2)/2</span></tt>.</p> </div> <p>After:</p> <pre class="literal-block"> -\poldef f1(x):= 25(x-1)(x^2-2)(x-3)(x-4)(x-5);% -\poldef f2(x):= 37(x-1)(x^2-2)(x-6)(x-7)(x-8);% +\poldef f_1(x):= 25(x-1)(x^2-2)(x-3)(x-4)(x-5);% +\poldef f_2(x):= 37(x-1)(x^2-2)(x-6)(x-7)(x-8);% </pre> -<p>the macro call <tt class="docutils literal"><span class="pre">\PolGCD{f1}{f2}{k}</span></tt> sets <tt class="docutils literal">k</tt> to the (unitary) GCD of -<tt class="docutils literal">f1</tt> and <tt class="docutils literal">f2</tt>.</p> +<p>the macro call <tt class="docutils literal"><span class="pre">\PolGCD{f_1}{f_2}{k}</span></tt> sets <tt class="docutils literal">k</tt> to the (unitary) GCD of +<tt class="docutils literal">f_1</tt> and <tt class="docutils literal">f_2</tt> (hence to the expansion of <tt class="docutils literal"><span class="pre">(x-1)(x^2-2)</span></tt>.)</p> <dl class="docutils"> <dt><tt class="docutils literal">\PolToExpr{k}</tt></dt> -<dd>will thus (expandably) give in this case <tt class="docutils literal"><span class="pre">2-2*x^1-1*x^2+1*x^3</span></tt>. -This is useful for console or file output (the syntax is Maple- and -PSTricks-compatible; currently the letter <tt class="docutils literal">x</tt> in output is not -customizable, but this can easily be added if requested from author.)</dd> +<dd>will (expandably) give in this case <tt class="docutils literal"><span class="pre">x^3-x^2-2*x+2</span></tt>. This is +useful for console or file output (the syntax is Maple- and +PSTricks-compatible; the letter used in output can be +(non-expandably) changed via a redefinition of <a class="reference internal" href="#poltoexprvar">\PolToExprVar</a>.)</dd> +<dt><tt class="docutils literal"><span class="pre">\PolToExpr*{k}</span></tt></dt> +<dd>gives ascending powers: <tt class="docutils literal"><span class="pre">2-2*x-x^2+x^3</span></tt>.</dd> </dl> </div> <div class="section" id="non-expandable-macros"> -<h1>Non-expandable macros</h1> -<dl class="docutils"> -<dt><tt class="docutils literal">\poldef <span class="pre">name(letter):=</span> polynomial expression using letter;</tt></dt> -<dd><p class="first">This evaluates the polynomial expression and stores the coefficients +<h1><a class="toc-backref" href="#id16">Non-expandable macros</a></h1> +<div class="section" id="poldef-polname-letter-expression-in-letter"> +<span id="poldef"></span><h2><a class="toc-backref" href="#id17"><tt class="docutils literal">\poldef <span class="pre">polname(letter):=</span> expression in letter;</tt></a></h2> +<blockquote> +<p>This evaluates the <em>polynomial expression</em> and stores the coefficients in a private structure accessible later via other package macros, -under the user-chosen <tt class="docutils literal">name</tt>. Of course previously defined -polynomials are allowed in a new expression. Names must start with a +under the user-chosen <tt class="docutils literal">polname</tt>. Of course the <em>expression</em> can +use other previously defined polynomials. Names must start with a letter and are constituted of letters, digits and underscore -characters. See Examples above.</p> -<p>As a side effect the function <tt class="docutils literal">name()</tt> is recognized as a genuine -<tt class="docutils literal"><span class="pre">\xintexpr...\relax</span></tt> function for (exact) numerical evaluation. It -computes values not according to the original expression but via -the Horner scheme corresponding to the polynomial coefficients.</p> -<p class="last">The original expression is lost after parsing, and in particular +characters. The whole <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> syntax is authorized:</p> +<pre class="literal-block"> +\poldef sin(z) := add((-1)^i z^(2i+1)/(2i+1)!, i = 0..10); +</pre> +<p>With fractional coefficients, beware the <a class="reference internal" href="#warningtacit">tacit multiplication issue</a>.</p> +<p>As a side effect the function <tt class="docutils literal">polname()</tt> is recognized as a +genuine <tt class="docutils literal"><span class="pre">\xintexpr...\relax</span></tt> function for (exact) numerical +evaluation (or within an <tt class="docutils literal">\xintdefvar</tt> assignment.) It computes +values not according to the original expression but via the Horner +scheme corresponding to the polynomial coefficients.</p> +<p>Also, a function with the same name is created for use within +<tt class="docutils literal">\xintfloatexpr</tt> (or <tt class="docutils literal">\xintdeffloatvar</tt>.) This is indispensible +for numerical algorithms as exact computations very quickly lead to +very big fractions. Addition and multiplication steps of the Horner +scheme will be executed as floating-point operations. The +coefficients have already been rounded at time of definition, +according to the then prevailing <tt class="docutils literal">\xinttheDigits</tt> value.</p> +<div class="admonition important"> +<p class="first admonition-title">Important</p> +<p>Package macros (such as derivatives or Euclidean division) +operate with the "exact" polynomials; "floating point" +polynomials are always obtained in a second step.</p> +<p>To modifiy "in-place" the original coefficients of a polynomial +and round them to float precision:</p> +<pre class="literal-block"> +\PolMapCoeffs{\xintFloat}{polname} +% or \xintFloat[P] for precision P digits +</pre> +<p class="last">See <a class="reference internal" href="#polmapcoeffs-macro-polname">\PolMapCoeffs{\macro}{polname}</a>.</p> +</div> +<p>The original expression is lost after parsing, and in particular the package provides no way to typeset it. This has to be done manually, if needed.</p> -</dd> -<dt><tt class="docutils literal"><span class="pre">\PolDef{name}{P(x)}</span></tt></dt> -<dd>Does the same but the variable is assumed to be <tt class="docutils literal">x</tt>. To use -another letter, pass it as first optional argument: -<tt class="docutils literal"><span class="pre">\PolDef[X]{name}{P(X)}</span></tt>.</dd> -<dt><tt class="docutils literal"><span class="pre">\PolLet{g}{f}</span></tt></dt> -<dd>Makes a copy of already defined polynomial f to new one g. Same -effect as <tt class="docutils literal"><span class="pre">\PolDef{g}{f(x)}</span></tt> but faster.</dd> -<dt><tt class="docutils literal"><span class="pre">\PolAssign{f}\toarray\Array</span></tt></dt> -<dd><p class="first">Defines a one-argument expandable macro <tt class="docutils literal"><span class="pre">\Array{#1}</span></tt> which expands +</blockquote> +</div> +<div class="section" id="poldef-letter-polname-expression-in-letter"> +<span id="id2"></span><h2><a class="toc-backref" href="#id18"><tt class="docutils literal"><span class="pre">\PolDef[letter]{polname}{expression</span> in letter}</tt></a></h2> +<blockquote> +Does the same in an undelimited macro format (thus avoiding +potential problems with the catcode of the semi-colon in presence of +some packages.) In absence of the <tt class="docutils literal">[letter]</tt> optional argument, +the variable is assumed to be <tt class="docutils literal">x</tt>.</blockquote> +</div> +<div class="section" id="pollet-polname-2-polname-1"> +<h2><a class="toc-backref" href="#id19"><tt class="docutils literal"><span class="pre">\PolLet{polname_2}={polname_1}</span></tt></a></h2> +<blockquote> +Makes a copy of the already defined polynomial <tt class="docutils literal">polname_1</tt> to a +new one <tt class="docutils literal">polname_2</tt>. Same effect as +<tt class="docutils literal"><span class="pre">\PolDef{polname_2}{polname_1(x)}</span></tt> but with less overhead. The +<tt class="docutils literal">=</tt> is optional.</blockquote> +</div> +<div class="section" id="polassign-polname-toarray-macro"> +<h2><a class="toc-backref" href="#id20"><tt class="docutils literal"><span class="pre">\PolAssign{polname}\toarray\macro</span></tt></a></h2> +<blockquote> +<p>Defines a one-argument expandable macro <tt class="docutils literal"><span class="pre">\macro{#1}</span></tt> which expands to the (raw) #1th polynomial coefficient.</p> -<ul class="last simple"> +<ul class="simple"> <li>Attention, coefficients here are indexed starting at 1.</li> -<li>With #1=-1, -2, ..., <tt class="docutils literal"><span class="pre">\Array{#1}</span></tt> returns leading coefficients.</li> +<li>With #1=-1, -2, ..., <tt class="docutils literal"><span class="pre">\macro{#1}</span></tt> returns leading coefficients.</li> <li>With #1=0, returns the number of coefficients, i.e. <tt class="docutils literal">1 + deg f</tt> for non-zero polynomials.</li> <li>Out-of-range #1's return <tt class="docutils literal">0/1[0]</tt>.</li> </ul> -</dd> -<dt><tt class="docutils literal"><span class="pre">\PolGet{f}\fromarray\Array</span></tt></dt> -<dd><p class="first">Does the converse operation to <tt class="docutils literal"><span class="pre">\PolAssign{f}\toarray\Array</span></tt>. No +<p>See also <a class="reference internal" href="#polnthcoeff-polname-number">\PolNthCoeff{polname}{number}</a>. The main difference is that +with <tt class="docutils literal">\PolAssign</tt>, <tt class="docutils literal">\macro</tt> is made a prefix to <tt class="docutils literal">1 + deg f</tt> +already defined (hidden to user) macros holding individually the +coefficients but <a class="reference internal" href="#polnthcoeff-polname-number">\PolNthCoeff{polname}{number}</a> does each time the job +to expandably recover the <tt class="docutils literal">Nth</tt> coefficient, and due to +expandability can not store it in a macro for future usage (of course, +it can be an argument in an <tt class="docutils literal">\edef</tt>.) The other difference +is the shift by one in indexing, mentioned above (negative +indices act the same in both.)</p> +</blockquote> +</div> +<div class="section" id="polget-polname-fromarray-macro"> +<h2><a class="toc-backref" href="#id21"><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">\Array{index}</tt> is expanded in an <tt class="docutils literal">\edef</tt> before being assigned +<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>(contrived) Example:</p> @@ -498,159 +623,441 @@ polynomial.</p> \xintAssignArray{1}{-2}{5}{-3}\to\foo \PolGet{f}\fromarray\foo </pre> -<p class="last">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>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 xintfrac macro.)</p> -</dd> -<dt><tt class="docutils literal"><span class="pre">\PolFromCSV{f}{comma</span> separated coefficients}</tt></dt> -<dd><p class="first">Defines a polynomial directly from the comma separated list (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 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> xintfrac format (this may -change).</p> +</blockquote> +</div> +<div class="section" id="polfromcsv-polname-csv"> +<h2><a class="toc-backref" href="#id22"><tt class="docutils literal"><span class="pre">\PolFromCSV{polname}{<csv>}</span></tt></a></h2> +<blockquote> +<p>Defines a polynomial directly from the comma separated list of +values (or a macro expanding to such a list) of its coefficients, +the constant term being the first item. No validity checks. Spaces +from the list argument are trimmed. List items are each expanded in +an <tt class="docutils literal">\edef</tt>, 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> xintfrac +format (this may change).</p> <p>Leading zero coefficients are removed:</p> <pre class="literal-block"> -\PolFromCSV{J}{0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +\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 class="last">See also expandable macro <tt class="docutils literal">\PolToCSV</tt>.</p> -</dd> -<dt><tt class="docutils literal">\PolTypeset{name}</tt></dt> -<dd><p class="first">Typesets in descending powers in math mode. It uses letter <tt class="docutils literal">x</tt> but +<p>See also expandable macro <a class="reference internal" href="#poltocsv-polname">\PolToCSV</a>.</p> +</blockquote> +</div> +<div class="section" id="poltypeset-polname"> +<h2><a class="toc-backref" href="#id23"><tt class="docutils literal">\PolTypeset{polname}</tt></a></h2> +<blockquote> +<p>Typesets in descending powers in math mode. It uses letter <tt class="docutils literal">x</tt> but this can be changed via an optional argument:</p> <pre class="literal-block"> -\PolTypeset[z]{name} +\PolTypeset[z]{polname} </pre> <p>By default zero coefficients are skipped (issue <tt class="docutils literal">\poltypesetalltrue</tt> to get all of them in output).</p> -<p class="last">Macros <tt class="docutils literal">\PolTypesetCmd</tt>, <tt class="docutils literal">\PolTypesetPlus</tt>, <tt class="docutils literal">\PolTypesetMonomial</tt> -can help configure the output. See the package code.</p> -</dd> -<dt><tt class="docutils literal"><span class="pre">\PolTypeset*{name}</span></tt></dt> -<dd>Typesets in ascending powers. Change the letter from its default -<tt class="docutils literal">x</tt> by optional argument.</dd> -<dt><tt class="docutils literal"><span class="pre">\PolDiff{f1}{f2}</span></tt></dt> -<dd><p class="first">This sets f2 to the first derivative of <tt class="docutils literal">f1</tt>. It is allowed to -issue <tt class="docutils literal"><span class="pre">\PolDiff{f}{f}</span></tt>, effectively replacing <tt class="docutils literal">f</tt> by <tt class="docutils literal">f'</tt>.</p> -<p class="last">Coefficients of the result <tt class="docutils literal">f2</tt> are irreducible fractions +<p>These commands (whose meanings will be found in the package code) +can be re-defined for customization. Their default definitions are +expandable, but this is not a requirement.</p> +</blockquote> +<div class="section" id="poltypesetcmd-raw-coeff"> +<h3><a class="toc-backref" href="#id24"><tt class="docutils literal">\PolTypesetCmd{raw_coeff}</tt></a></h3> +<blockquote> +<p>Basically will use <tt class="docutils literal">\xintSignedFrac</tt> from <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a>, but checks if +the coefficient is <tt class="docutils literal">1</tt> or <tt class="docutils literal"><span class="pre">-1</span></tt> and then skips printing the +<tt class="docutils literal">1</tt>, except for the constant term...</p> +<p>One can do things such as for example: <a class="footnote-reference" href="#id4" id="id3">[1]</a></p> +<pre class="literal-block"> +\renewcommand\PolTypesetCmd[1]{\num{\xintPFloat[5]{#1}}} +\renewcommand\PolTypesetCmd[1]{\num{\xintRound{4}{#1}}} +</pre> +<p>where e.g. we used the <tt class="docutils literal">\num</tt> macro of <tt class="docutils literal">siunitx</tt> as it +understands floating point notation.</p> +<table class="docutils footnote" frame="void" id="id4" rules="none"> +<colgroup><col class="label" /><col /></colgroup> +<tbody valign="top"> +<tr><td class="label"><a class="fn-backref" href="#id3">[1]</a></td><td>the difference in the syntaxes of <tt class="docutils literal">\xintPFloat</tt> and +<tt class="docutils literal">\xintRound</tt> is explained from the fact that +<tt class="docutils literal">\xintPFloat</tt> by default uses the prevailing precision +hence the extra argument like here <tt class="docutils literal">5</tt> is an optional one.</td></tr> +</tbody> +</table> +</blockquote> +</div> +<div class="section" id="poltypesetcmdprefix-raw-coeff"> +<h3><a class="toc-backref" href="#id25"><tt class="docutils literal">\PolTypesetCmdPrefix{raw_coeff}</tt></a></h3> +<blockquote> +Expands to a <tt class="docutils literal">+</tt> if the <tt class="docutils literal">raw_coeff</tt> is zero or positive, and to +nothing if <tt class="docutils literal">raw_coeff</tt> is negative, as in latter case the +<tt class="docutils literal">\xintSignedFrac</tt> used by <a class="reference internal" href="#poltypesetcmd-raw-coeff">\PolTypesetCmd{raw_coeff}</a> will put +the <tt class="docutils literal">-</tt> sign in front of the fraction (if it is a fraction) and +this will thus serve as separator in the typeset formula. Not used +for the first term.</blockquote> +</div> +<div class="section" id="poltypesetmonomialcmd"> +<h3><a class="toc-backref" href="#id26"><tt class="docutils literal">\PolTypesetMonomialCmd</tt></a></h3> +<blockquote> +This decides how a monomial (in variable <tt class="docutils literal">\PolVar</tt> and with +exponent <tt class="docutils literal">\PolIndex</tt>) is to be printed. The default does nothing +for the constant term, <tt class="docutils literal">\PolVar</tt> for the first degree and +<tt class="docutils literal"><span class="pre">\PolVar^{\PolIndex}</span></tt> for higher degrees monomials. Beware that +<tt class="docutils literal">\PolIndex</tt> expands to digit tokens and needs termination in +<tt class="docutils literal">\ifnum</tt> tests.</blockquote> +</div> +</div> +<div class="section" id="id5"> +<h2><a class="toc-backref" href="#id27"><tt class="docutils literal"><span class="pre">\PolTypeset*{polname}</span></tt></a></h2> +<blockquote> +Typesets in ascending powers. Use e.g. <tt class="docutils literal">[h]</tt> optional argument +(after the <tt class="docutils literal">*</tt>) to use letter <tt class="docutils literal">h</tt> rather than <tt class="docutils literal">x</tt>.</blockquote> +</div> +<div class="section" id="poldiff-polname-1-polname-2"> +<h2><a class="toc-backref" href="#id28"><tt class="docutils literal"><span class="pre">\PolDiff{polname_1}{polname_2}</span></tt></a></h2> +<blockquote> +<p>This sets <tt class="docutils literal">polname_2</tt> to the first derivative of <tt class="docutils literal">polname_1</tt>. It +is allowed to issue <tt class="docutils literal"><span class="pre">\PolDiff{f}{f}</span></tt>, effectively replacing <tt class="docutils literal">f</tt> +by <tt class="docutils literal">f'</tt>.</p> +<p>Coefficients of the result <tt class="docutils literal">polname_2</tt> are irreducible fractions (see <a class="reference internal" href="#technicalities">Technicalities</a> for the whole story.)</p> -</dd> -<dt><tt class="docutils literal"><span class="pre">\PolDiff[N]{f1}{f2}</span></tt></dt> -<dd>This sets <tt class="docutils literal">f2</tt> to the <tt class="docutils literal">N</tt>-th derivative of <tt class="docutils literal">f1</tt>. Identical -arguments is allowed. With <tt class="docutils literal">N=0</tt>, same effect as -<tt class="docutils literal"><span class="pre">\PolLet{f2}{f1}</span></tt>. With negative <tt class="docutils literal">N</tt>, switches to using -<tt class="docutils literal">\PolAntiDiff</tt>.</dd> -<dt><tt class="docutils literal"><span class="pre">\PolAntiDiff{f1}{f2}</span></tt></dt> -<dd><p class="first">This sets <tt class="docutils literal">f2</tt> to the primitive of <tt class="docutils literal">f1</tt> vanishing at zero.</p> -<p class="last">Coefficients of the result <tt class="docutils literal">f2</tt> are irreducible fractions +</blockquote> +</div> +<div class="section" id="poldiff-n-polname-1-polname-2"> +<h2><a class="toc-backref" href="#id29"><tt class="docutils literal"><span class="pre">\PolDiff[N]{polname_1}{polname_2}</span></tt></a></h2> +<blockquote> +This sets <tt class="docutils literal">polname_2</tt> to the <tt class="docutils literal">N</tt>-th derivative of <tt class="docutils literal">polname_1</tt>. +Identical arguments is allowed. With <tt class="docutils literal">N=0</tt>, same effect as +<tt class="docutils literal"><span class="pre">\PolLet{polname_2}={polname_1}</span></tt>. With negative <tt class="docutils literal">N</tt>, switches to +using <tt class="docutils literal">\PolAntiDiff</tt>.</blockquote> +</div> +<div class="section" id="polantidiff-polname-1-polname-2"> +<h2><a class="toc-backref" href="#id30"><tt class="docutils literal"><span class="pre">\PolAntiDiff{polname_1}{polname_2}</span></tt></a></h2> +<blockquote> +<p>This sets <tt class="docutils literal">polname_2</tt> to the primitive of <tt class="docutils literal">polname_1</tt> vanishing +at zero.</p> +<p>Coefficients of the result <tt class="docutils literal">polname_2</tt> are irreducible fractions (see <a class="reference internal" href="#technicalities">Technicalities</a> for the whole story.)</p> -</dd> -<dt><tt class="docutils literal"><span class="pre">\PolAntiDiff[N]{f1}{f2}</span></tt></dt> -<dd>This sets <tt class="docutils literal">f2</tt> to the result of <tt class="docutils literal">N</tt> successive integrations on -<tt class="docutils literal">f1</tt>. With negative <tt class="docutils literal">N</tt>, it switches to using <tt class="docutils literal">\PolDiff</tt>.</dd> -<dt><tt class="docutils literal"><span class="pre">\PolDivide{f1}{f2}{Q}{R}</span></tt></dt> -<dd>This sets <tt class="docutils literal">Q</tt> and <tt class="docutils literal">R</tt> to be the quotient and remainder in the -Euclidean division of <tt class="docutils literal">f1</tt> by <tt class="docutils literal">f2</tt>.</dd> -<dt><tt class="docutils literal"><span class="pre">\PolGCD{f}{g}{k}</span></tt></dt> -<dd>This sets <tt class="docutils literal">k</tt> to be the G.C.D. It is a unitary polynomial except -if both <tt class="docutils literal">f</tt> and <tt class="docutils literal">g</tt> vanish, then <tt class="docutils literal">k</tt> is the zero polynomial.</dd> -<dt><tt class="docutils literal"><span class="pre">\PolMapCoeffs{\macro}{name}</span></tt></dt> -<dd><p class="first">It modifies each coefficient of the defined polynomial via the -<em>expandable</em> macro <tt class="docutils literal">\macro</tt>. The degree is adjusted as necessary -if some leading coefficients vanish after the operation. In -replacement text of <tt class="docutils literal">\macro</tt>, <tt class="docutils literal">\index</tt> expands to the -coefficient index (which is defined to be zero for the constant -term).</p> +</blockquote> +</div> +<div class="section" id="polantidiff-n-polname-1-polname-2"> +<h2><a class="toc-backref" href="#id31"><tt class="docutils literal"><span class="pre">\PolAntiDiff[N]{polname_1}{polname_2}</span></tt></a></h2> +<blockquote> +This sets <tt class="docutils literal">polname_2</tt> to the result of <tt class="docutils literal">N</tt> successive integrations on +<tt class="docutils literal">polname_1</tt>. With negative <tt class="docutils literal">N</tt>, it switches to using <tt class="docutils literal">\PolDiff</tt>.</blockquote> +</div> +<div class="section" id="poldivide-polname-1-polname-2-polname-q-polname-r"> +<h2><a class="toc-backref" href="#id32"><tt class="docutils literal"><span class="pre">\PolDivide{polname_1}{polname_2}{polname_Q}{polname_R}</span></tt></a></h2> +<blockquote> +This sets <tt class="docutils literal">polname_Q</tt> and <tt class="docutils literal">polname_R</tt> to be the quotient and +remainder in the Euclidean division of <tt class="docutils literal">polname_1</tt> by +<tt class="docutils literal">polname_2</tt>.</blockquote> +</div> +<div class="section" id="polgcd-polname-1-polname-2-polname-gcd"> +<h2><a class="toc-backref" href="#id33"><tt class="docutils literal"><span class="pre">\PolGCD{polname_1}{polname_2}{polname_GCD}</span></tt></a></h2> +<blockquote> +This sets <tt class="docutils literal">polname_GCD</tt> to be the G.C.D. It is a unitary +polynomial except if both <tt class="docutils literal">polname_1</tt> and <tt class="docutils literal">polname_2</tt> vanish, +then <tt class="docutils literal">polname_GCD</tt> is the zero polynomial.</blockquote> +</div> +<div class="section" id="polmapcoeffs-macro-polname"> +<h2><a class="toc-backref" href="#id34"><tt class="docutils literal"><span class="pre">\PolMapCoeffs{\macro}{polname}</span></tt></a></h2> +<blockquote> +<p>It modifies ('in-place': original coefficients get lost) each +coefficient of the defined polynomial via the <em>expandable</em> macro +<tt class="docutils literal">\macro</tt>. The degree is adjusted as necessary if some leading +coefficients vanish after the operation. In replacement text of +<tt class="docutils literal">\macro</tt>, <tt class="docutils literal">\index</tt> expands to the coefficient index (which is +defined to be zero for the constant term).</p> <p>Notice that <tt class="docutils literal">\macro</tt> will have to handle inputs of the shape -<tt class="docutils literal">A/B[N]</tt> (xintfrac internal notation). This means that it probably +<tt class="docutils literal">A/B[N]</tt> (<a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> internal notation). This means that it probably will have to be expressed in terms of macros from xintfrac package.</p> <p>Example:</p> <pre class="literal-block"> \def\foo#1{\xintMul{#1}{\the\numexpr\index*\index\relax}} </pre> -<p class="last">(or with <tt class="docutils literal"><span class="pre">\xintSqr{\xindex}</span></tt>) to replace <tt class="docutils literal">n</tt>-th coefficient +<p>(or with <tt class="docutils literal"><span class="pre">\xintSqr{\index}</span></tt>) to replace <tt class="docutils literal">n</tt>-th coefficient <tt class="docutils literal">f_n</tt> by <tt class="docutils literal">f_n*n^2</tt>.</p> -</dd> -<dt><tt class="docutils literal">\PolReduceCoeffs{name}</tt></dt> -<dd>About the same as <tt class="docutils literal"><span class="pre">\PolMapCoeffs{\xintIrr}{name}</span></tt> (but adds -<tt class="docutils literal">[0]</tt> postfix which speeds up xintfrac operations when -evaluating.)</dd> -</dl> +</blockquote> +</div> +<div class="section" id="polreducecoeffs-polname"> +<h2><a class="toc-backref" href="#id35"><tt class="docutils literal">\PolReduceCoeffs{polname}</tt></a></h2> +<blockquote> +About the same as <tt class="docutils literal"><span class="pre">\PolMapCoeffs{\xintIrr}{polname}</span></tt> (but +maintaining a <tt class="docutils literal">[0]</tt> postfix for speedier <a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> parsing when +polynomial function is used for computations.) This is a +one-argument macro, working 'in-place'.</blockquote> +</div> </div> <div class="section" id="expandable-macros"> -<h1>Expandable macros</h1> +<h1><a class="toc-backref" href="#id36">Expandable macros</a></h1> <p>All these macros expand completely in two steps except <tt class="docutils literal">\PolToExpr</tt> -which needs 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> -<dl class="docutils"> -<dt><tt class="docutils literal"><span class="pre">\PolEval{name}\At{value}</span></tt></dt> -<dd>It boils down to <tt class="docutils literal">\xinttheexpr <span class="pre">reduce(name(value))\relax</span></tt>.</dd> -<dt><tt class="docutils literal"><span class="pre">\PolNthCoeff{name}{N}</span></tt></dt> -<dd>It expands to the raw <tt class="docutils literal">N</tt>-th coefficient (<tt class="docutils literal">0/1[0]</tt> if index 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.</dd> -<dt><tt class="docutils literal">\PolDegree{name}</tt></dt> -<dd>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> ?</dd> -<dt><tt class="docutils literal">\PolToExpr{f}</tt></dt> -<dd><p class="first">Expands to <tt class="docutils literal">f_0 + f_1*x + f_2*x^2 + ...</tt> (ascending powers). <a class="footnote-reference" href="#id3" id="id1">[1]</a>, -<a class="footnote-reference" href="#id4" id="id2">[2]</a></p> -<table class="docutils footnote" frame="void" id="id3" rules="none"> +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-at-numerical-expression"> +<h2><a class="toc-backref" href="#id37"><tt class="docutils literal"><span class="pre">\PolEval{polname}\At{numerical</span> expression}</tt></a></h2> +<blockquote> +<p>It boils down to <tt class="docutils literal">\xinttheexpr polname(numerical <span class="pre">expression)\relax</span></tt>.</p> +<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p>The <tt class="docutils literal">0.2</tt> version stupidly tried to be clever and as a result +of a misguided optimization choked if <tt class="docutils literal">value</tt> was not a number +but a numerical expression (a sum e.g.), but the more powerful +behaviour has been reinstored at <tt class="docutils literal">0.3</tt> release.</p> +<p class="last">The <tt class="docutils literal">0.1</tt> and <tt class="docutils literal">0.2</tt> version did a <tt class="docutils literal">reduce</tt> which however is +costly on big fractions and irrelevant if the output is served as +argument of <tt class="docutils literal">\xintRound</tt> or <tt class="docutils literal">\xintFloat</tt>. Thus <tt class="docutils literal">reduce</tt> was +removed, and former meaning is now available as +<a class="reference internal" href="#polevalreduced-polname-at-numerical-expression">\PolEvalReduced{polname}\At{numerical expression}</a></p> +</div> +</blockquote> +</div> +<div class="section" id="polevalreduced-polname-at-numerical-expression"> +<h2><a class="toc-backref" href="#id38"><tt class="docutils literal"><span class="pre">\PolEvalReduced{polname}\At{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="polfloateval-polname-at-numerical-expression"> +<h2><a class="toc-backref" href="#id39"><tt class="docutils literal"><span class="pre">\PolFloatEval{polname}\At{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>), with +already rounded coefficients. <a class="footnote-reference" href="#id8" id="id6">[2]</a> To use the <em>exact coefficients</em> +(and <em>exact</em> additions and multiplications), just insert it in the +float expression as in this example: <a class="footnote-reference" href="#id9" id="id7">[3]</a></p> +<pre class="literal-block"> +\xintthefloatexpr 3.27*\xintexpr f(2.53)\relax^2\relax +</pre> +<p>The <tt class="docutils literal">f(2.53)</tt> is exactly computed then rounded at the time of +getting raised to the power <tt class="docutils literal">2</tt>. Moving the <tt class="docutils literal">^2</tt> inside, that +operation would also be treated exactly.</p> +<table class="docutils footnote" frame="void" id="id8" rules="none"> <colgroup><col class="label" /><col /></colgroup> <tbody valign="top"> -<tr><td class="label"><a class="fn-backref" href="#id1">[1]</a></td><td>in a <tt class="docutils literal">\write</tt>, <tt class="docutils literal">\edef</tt>, or <tt class="docutils literal"><span class="pre">\csname...\endcsname</span></tt>, but -not under <tt class="docutils literal"><span class="pre">\romannumeral-`0</span></tt>.</td></tr> +<tr><td class="label"><a class="fn-backref" href="#id6">[2]</a></td><td>Anyway each floating point operation starts by rounding its +operands to the floating point precision.</td></tr> </tbody> </table> -<table class="docutils footnote" frame="void" id="id4" rules="none"> +<table class="docutils footnote" frame="void" id="id9" rules="none"> +<colgroup><col class="label" /><col /></colgroup> +<tbody valign="top"> +<tr><td class="label"><a class="fn-backref" href="#id7">[3]</a></td><td>The <tt class="docutils literal">\xintexpr</tt> could be <tt class="docutils literal">\xinttheexpr</tt> but that would be +less efficient. Cf. <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> documentation about nested +expressions.</td></tr> +</tbody> +</table> +</blockquote> +</div> +<div class="section" id="polnthcoeff-polname-number"> +<h2><a class="toc-backref" href="#id40"><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"> +<h2><a class="toc-backref" href="#id41"><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="poltoexpr-polname"> +<h2><a class="toc-backref" href="#id42"><tt class="docutils literal">\PolToExpr{polname}</tt></a></h2> +<blockquote> +<p>Expands <a class="footnote-reference" href="#id11" id="id10">[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="id11" rules="none"> <colgroup><col class="label" /><col /></colgroup> <tbody valign="top"> -<tr><td class="label"><a class="fn-backref" href="#id2">[2]</a></td><td>the letter <tt class="docutils literal">x</tt> is (in this release) not customizable.</td></tr> +<tr><td class="label"><a class="fn-backref" href="#id10">[4]</a></td><td>in a <tt class="docutils literal">\write</tt>, <tt class="docutils literal">\edef</tt>, or <tt class="docutils literal"><span class="pre">\csname...\endcsname</span></tt>, but +not under <tt class="docutils literal"><span class="pre">\romannumeral-`0</span></tt>.</td></tr> </tbody> </table> -<p>By default zero coefficients are skipped (issue <tt class="docutils literal">\poltoexprtrue</tt> to +<p>By default zero coefficients are skipped (issue <tt class="docutils literal">\poltoexpralltrue</tt> to get all of them in output).</p> -<p>No <tt class="docutils literal">+</tt> sign before negative coefficients, for compliance with Maple -input format. This means though that parsing the result back via -naive delimited macros is difficult, see <tt class="docutils literal">\PolToList</tt> and <tt class="docutils literal">\PolToCSV</tt> -for more low-level formats making it easier to get expandably some -output of one's choice, which may possibly be parsed later on by -other macros of one's design, or from other packages.</p> -<p>Of course <tt class="docutils literal">\PolToExpr{f}</tt> can be inserted in a poldef, as the +<p>By default, no <tt class="docutils literal">+</tt> sign before negative coefficients, for +compliance with Maple input format (but see +<a class="reference internal" href="#poltoexprtermprefix-raw-coeff">\PolToExprTermPrefix{raw_coeff}</a>.) Also, like the default +behaviour of <a class="reference internal" href="#poltypeset-polname">\PolTypeset{polname}</a>, does not print (for the non +constant terms) coefficients equal to plus or minus one. The degree +one monomial is output as <tt class="docutils literal">x</tt>, not <tt class="docutils literal">x^1</tt>. Complete customization is +possible, see next macros.</p> +<p>Of course <tt class="docutils literal">\PolToExpr{f}</tt> can be inserted in a <tt class="docutils literal">\poldef</tt>, as the latter expands token by token, hence will force complete expansion -of <tt class="docutils literal">\PolToExpr{f}</tt>, but simply <tt class="docutils literal">f(x)</tt> will be more efficient for the -identical result.</p> -<p class="last"><tt class="docutils literal">\PolToExprCmd</tt> is the one-argument macro used by <tt class="docutils literal">\PolToExpr</tt> for the -coefficients, it defaults to <tt class="docutils literal"><span class="pre">\xintPRaw{\xintRawWithZeros{#1}}</span></tt>. One -will have to redefine it to use <tt class="docutils literal"><span class="pre">\xintIrr{#1}</span></tt> in place of -<tt class="docutils literal"><span class="pre">\xintRawWithZeros{#1}</span></tt> to get in output reduced coefficients.</p> -</dd> -<dt><tt class="docutils literal">\PolToList{f}</tt></dt> -<dd>Expands to <tt class="docutils literal"><span class="pre">{f_0}{f_1}...{f_N}</span></tt> with <tt class="docutils literal">N</tt> = degree of f (except -zero polynomial which does give <tt class="docutils literal">{0/1[0]}</tt> and not an empty -output.)</dd> -<dt><tt class="docutils literal">\PolToCSV{f}</tt></dt> -<dd>Expands to <tt class="docutils literal">f_0, f_1, f_2, <span class="pre">.....,</span> f_N</tt>. Converse to -<tt class="docutils literal">\PolFromCSV</tt>.</dd> -</dl> +of <tt class="docutils literal">\PolToExpr{f}</tt>, but a simple <tt class="docutils literal">f(x)</tt> is more efficient for +the identical result.</p> +</blockquote> +<div class="section" id="poltoexproneterm-raw-coeff-number"> +<h3><a class="toc-backref" href="#id43"><tt class="docutils literal"><span class="pre">\PolToExprOneTerm{raw_coeff}{number}</span></tt></a></h3> +<blockquote> +<p>This two argument expandable command takes care of the monomial and +its coefficient. The default definition is done in order for +coefficients of absolute value <tt class="docutils literal">1</tt> not be printed explicitely +(except of course for the constant term). Also by default, the +monomial of degree one is <tt class="docutils literal">x</tt> not <tt class="docutils literal">x^1</tt>, and <tt class="docutils literal">x^0</tt> is skipped.</p> +<p>For compatibility with Maple input requirements, by default a <tt class="docutils literal">*</tt> +always precedes the <tt class="docutils literal">x^number</tt>, except if the coefficient is a one +or a minus one. See <a class="reference internal" href="#poltoexprtimes">\PolToExprTimes</a>.</p> +</blockquote> +</div> +<div class="section" id="poltoexpronetermstyleb-raw-coeff-number"> +<h3><a class="toc-backref" href="#id44"><tt class="docutils literal"><span class="pre">\PolToExprOneTermStyleB{raw_coeff}{number}</span></tt></a></h3> +<blockquote> +<p>For output in this style:</p> +<pre class="literal-block"> +2*x^11/3+3*x^8/7-x^5−x^4/4−x^3−x^2/2−2*x+1 +</pre> +<p>issue <tt class="docutils literal">\let\PolToExprOneTerm\PolToExprOneTermStyleB</tt> before using +<tt class="docutils literal">\PolToExpr</tt>. Note that then <tt class="docutils literal">\PolToExprCmd</tt> isn't used at all.</p> +<p>To suppress the <tt class="docutils literal">*</tt>'s, cf. <a class="reference internal" href="#poltoexprtimes">\PolToExprTimes</a>.</p> +</blockquote> +</div> +<div class="section" id="poltoexprcmd-raw-coeff"> +<h3><a class="toc-backref" href="#id45"><tt class="docutils literal">\PolToExprCmd{raw_coeff}</tt></a></h3> +<blockquote> +It is the one-argument macro used by the package definition of +<tt class="docutils literal">\PolToExprOneTerm</tt> for the coefficients themselves (when not +equal to plus or minus one), and it defaults to +<tt class="docutils literal"><span class="pre">\xintPRaw{\xintRawWithZeros{#1}}</span></tt>. One will have to redefine it +to <tt class="docutils literal"><span class="pre">\xintIrr{#1}</span></tt> or to <tt class="docutils literal"><span class="pre">\xintPRaw{\xintIrr{#1}}</span></tt> to obtain in the +output forcefully reduced coefficients.</blockquote> +</div> +<div class="section" id="poltoexprtermprefix-raw-coeff"> +<h3><a class="toc-backref" href="#id46"><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="poltoexprvar"> +<h3><a class="toc-backref" href="#id47"><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="poltoexprtimes"> +<h3><a class="toc-backref" href="#id48"><tt class="docutils literal">\PolToExprTimes</tt></a></h3> +<blockquote> +This expands to the symbol used for multiplication of an +<tt class="docutils literal"><span class="pre">x^{number}</span></tt> by the corresponding coefficient. The default is +<tt class="docutils literal">*</tt>. Redefine the macro to expand to nothing to get rid of it (but +this will give output incompatible with some professional computer +algebra software).</blockquote> +</div> +</div> +<div class="section" id="id12"> +<h2><a class="toc-backref" href="#id49"><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"> +<h2><a class="toc-backref" href="#id50"><tt class="docutils literal">\PolToFloatExpr{polname}</tt></a></h2> +<blockquote> +<p>Similar to <a class="reference internal" href="#poltoexpr-polname">\PolToExpr{polname}</a> but uses <a class="reference external" href="\PolToFloatExprCmd{raw_coeff}">\PolToFloatExprCmd</a> +which by default rounds and converts the coefficients to floating +point format.</p> +<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p>The polynomial function for usage in <tt class="docutils literal">\xintfloatexpr</tt> is +already prepared with the rounded coefficients, but the latter +are not easily recoverable (and especially not expandably) from +this. Thus <tt class="docutils literal">\PolToFloatExprCmd</tt> operates from the <em>exact</em> +coefficients anew. This means though that if the prevailing float +precision was changed with <tt class="docutils literal"><span class="pre">\xintDigits:=P;</span></tt> syntax, the output +will obey this precision <tt class="docutils literal">P</tt>, but the polynomial function was +defined earlier and operates on floating point numbers with +coefficients which were rounded at time of definition.</p> +<p class="last">This may change in future, if the pre-rounded coefficients are +stored in a more easily accessible data structure.</p> +</div> +</blockquote> +<div class="section" id="poltofloatexproneterm-raw-coeff-number"> +<h3><a class="toc-backref" href="#id51"><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"> +<h3><a class="toc-backref" href="#id52"><tt class="docutils literal">\PolToFloatExprCmd{raw_coeff}</tt></a></h3> +<blockquote> +<p>It is the one-argument macro used by <tt class="docutils literal">\PolToFloatExprOneTerm</tt>. +Its package definition is <tt class="docutils literal"><span class="pre">\xintFloat{#1}</span></tt>.</p> +<div class="admonition caution"> +<p class="first admonition-title">Caution!</p> +<p>Currently (<a class="reference external" href="http://www.ctan.org/pkg/xint">xint</a> <tt class="docutils literal">1.2p</tt>) <tt class="docutils literal">\xintFloat{0}</tt> outputs <tt class="docutils literal">0.e0</tt> +which is perfectly acceptable input for Python, but not for +Maple. Thus, one should better leave the <a class="reference internal" href="#poltoexprallfalse">\poltoexprallfalse</a> +toggle to its default <tt class="docutils literal">\iffalse</tt> state, if one intends to use +the output in a Maple worksheet.</p> +<p>But even then the zero polynomial will cause a problem. Workaround:</p> +<pre class="literal-block"> +\renewcommand\PolToFloatExprCmd[1]{\xintiiifZero{#1}{0.0}{\xintFloat{#1}}} +</pre> +<p class="last">Usage of <tt class="docutils literal">\xintiiifZero</tt> and not <tt class="docutils literal">\xintifZero</tt> is only for +optimization (I can't help it) because <tt class="docutils literal">#1</tt> is known to be +in <tt class="docutils literal">xintfrac</tt> raw format.</p> +</div> +</blockquote> +</div> +</div> +<div class="section" id="id13"> +<h2><a class="toc-backref" href="#id53"><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"> +<h2><a class="toc-backref" href="#id54"><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"> +<h2><a class="toc-backref" href="#id55"><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> +<div class="section" id="booleans-with-default-setting-as-indicated"> +<h1><a class="toc-backref" href="#id56">Booleans (with default setting as indicated)</a></h1> +<div class="section" id="xintverbosefalse"> +<h2><a class="toc-backref" href="#id57"><tt class="docutils literal">\xintverbosefalse</tt></a></h2> +<blockquote> +<p>This is actually an <a class="reference external" href="http://www.ctan.org/pkg/xint">xintexpr</a> configuration. Setting it to +<tt class="docutils literal">true</tt> triggers the writing of information to the log when new +polynomials are defined.</p> +<div class="admonition caution"> +<p class="first admonition-title">Caution!</p> +<p class="last">The macro meanings as written to the log are to be considered +unstable and undocumented internal structures.</p> +</div> +</blockquote> +</div> +<div class="section" id="poltypesetallfalse"> +<h2><a class="toc-backref" href="#id58"><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="#id59"><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>Technicalities</h1> +<h1><a class="toc-backref" href="#id60">Technicalities</a></h1> <ul> -<li><p class="first">The catcode of the semi-colon is reset temporarily by <tt class="docutils literal">\poldef</tt> macro in -case some other package (for example the French babel module) may have -made it active. This will fail though if the whole thing was already -part of a macro argument, in such cases one can use <tt class="docutils literal">\PolDef</tt> rather. -The colon in <tt class="docutils literal">:=</tt> may be active with no consequences.</p> -</li> -<li><p class="first">Beware the <tt class="docutils literal">1/2 x</tt> problem: as mentioned above, it will be give zero due -to the tacit multiplication rules of <tt class="docutils literal">\xintexpr</tt> and to the fact that -the package will do the Euclidean division of <tt class="docutils literal">1</tt> by polynomial <tt class="docutils literal">2x</tt>.</p> +<li><p class="first">The catcode of the semi-colon is reset temporarily by <a class="reference internal" href="#poldef">\poldef</a> macro in case some other package (for example the French +babel module) may have made it active. This will fail though if the +whole thing was already part of a macro argument, in such cases one +can use <a class="reference internal" href="#id2">\PolDef{f}{P(x)}</a> +rather. The colon in <tt class="docutils literal">:=</tt> may be active with no consequences.</p> </li> <li><p class="first">During execution of polynomial operations by <tt class="docutils literal">\poldef</tt> (but not during the initial purely numerical parsing of the expression), the -xintfrac macro <tt class="docutils literal">\xintAdd</tt> is temporarily patched to always express +<a class="reference external" href="http://www.ctan.org/pkg/xint">xintfrac</a> macro <tt class="docutils literal">\xintAdd</tt> is temporarily patched to always express <tt class="docutils literal">a/b + c/d</tt> with <tt class="docutils literal"><span class="pre">l.c.m.(b,d)</span></tt> as denominator. Indeed the current (xint 1.2p) <tt class="docutils literal">\xintAdd</tt> uses <tt class="docutils literal"><span class="pre">(ad+bc)/bd</span></tt> formula except if <tt class="docutils literal">b</tt> divides <tt class="docutils literal">d</tt> or <tt class="docutils literal">d</tt> divides <tt class="docutils literal">b</tt>, which quickly leads in real life @@ -677,33 +1084,41 @@ survive addition and multiplications:</p> <p>where all coefficients have the same denominator 6 (which in this example is the <tt class="docutils literal">l.c.m</tt> of the denominators of the reduced coefficients.)</p> </li> -<li><p class="first"><tt class="docutils literal">\PolDiff</tt> always applies <tt class="docutils literal">\xintIrr</tt> to the resulting coefficients, except -that the <em>power of ten</em> part <tt class="docutils literal">[N]</tt> (for example an input in scientific -notation such as <tt class="docutils literal">1.23e5</tt> gives <tt class="docutils literal">123/1[3]</tt> internally in xintfrac) is not -taken into account in the reduction of the fraction. This is tentative -and may change.</p> -<p>Same remark for <tt class="docutils literal">\PolAntiDiff</tt>.</p> +<li><p class="first"><a class="reference internal" href="#poldiff-polname-1-polname-2">\PolDiff{polname_1}{polname_2}</a> always applies <tt class="docutils literal">\xintIrr</tt> to the +resulting coefficients, except that the <em>power of ten</em> part <tt class="docutils literal">[N]</tt> +(for example an input in scientific notation such as <tt class="docutils literal">1.23e5</tt> gives +<tt class="docutils literal">123/1[3]</tt> internally in xintfrac) is not taken into account in the +reduction of the fraction. This is tentative and may change.</p> +<p>Same remark for <a class="reference internal" href="#polantidiff-polname-1-polname-2">\PolAntiDiff{polname_1}{polname_2}</a>.</p> </li> -<li><p class="first">If <tt class="docutils literal">f</tt> was created from comma separated values by macro PolFromCSV, -then the coefficients will be in the output of <tt class="docutils literal">\PolToList</tt> and -<tt class="docutils literal">\PolToCSV</tt> 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> +<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 is an unavoidable consequence of usage -by poldef of <tt class="docutils literal">\xintdeffunc</tt> which itself is based on <tt class="docutils literal">\xintexpr.</tt> +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 does not as a result of <tt class="docutils literal">\poldef</tt> add to the TeX -memory an already pre-computed <em>array</em> structure for the polynomial -coefficients, as would be constructed by <tt class="docutils literal"><span class="pre">\PolAssign{f}\toarray\macro</span></tt>. -Such structures are used, but for internal calculations in temporarily -restricted scopes. Apart from the function <tt class="docutils literal">f()</tt> known to the -(numerical) <tt class="docutils literal">\xintexpr</tt> parser (whose meaning can be found in the log -file after xintverbosetrue), the data is (currently) stored in a -single other macro encapsulating the degree, and the coefficients as a -list. This may evolve in future.</p> +<li><p class="first">Currently, the package stores all coefficients from index <tt class="docutils literal">0</tt> to +index equal to the polynomial degree inside a single macro, as a list. +This data structure is obviously very inefficient for polynomials of +high degree and few coefficients (as an example with <tt class="docutils literal">\poldef +<span class="pre">f(x):=x^1000</span> + x^500;</tt> the subsequent definition <tt class="docutils literal">\poldef <span class="pre">g(x):=</span> +<span class="pre">f(x)^2;</span></tt> will do of the order of 1,000,000 multiplications and +additions involvings only zeroes... which does take time). This +may change in the future.</p> +</li> +<li><p class="first">Tests have been made with Newton's iteration (for which computing +exactly the derivative is precisely what this package is made for) or +Regula Falsi method for locating roots: using exact computations leads +quickly to gigantic fractions (but dichotomy method much less so). It +is thus recommended to use <tt class="docutils literal">\xintdeffloatvar</tt> or +<tt class="docutils literal">\xintthefloatexpr</tt> contexts for any kind of numerical mathematics. +Of course, exact computations are invaluable for number theory or +combinatorics...</p> </li> <li><p class="first">As is to be expected internal structures of the package are barely documented and unstable. Don't use them.</p> @@ -711,19 +1126,38 @@ documented and unstable. Don't use them.</p> </ul> </div> <div class="section" id="releases"> -<h1>RELEASES</h1> -<ul class="simple"> -<li>0.1 (2018/01/11): initial release (files README, polexpr.sty).</li> -<li>0.2 (2018/01/14): documentation moved to polexpr.{txt,html}.</li> +<h1><a class="toc-backref" href="#id61">RELEASES</a></h1> +<ul> +<li><p class="first">0.1 (2018/01/11)</p> +<p>Initial release (files README, polexpr.sty).</p> +</li> +<li><p class="first">0.2 (2018/01/14)</p> +<p>Documentation moved to polexpr.{txt,html}.</p> +</li> +<li><p class="first">0.3 (2018/01/17)</p> +<p>Make polynomials known to <tt class="docutils literal">\xintfloatexpr</tt> and improve +documentation.</p> +</li> +<li><p class="first">0.3.1 (2018/01/18)</p> +<p>Fix two typos in documentation.</p> +</li> </ul> -<p>Files of 0.2 release:</p> +<p>Files of 0.3.1 release:</p> <ul class="simple"> <li>README.md,</li> <li>polexpr.sty (package file),</li> <li>polexpr.txt (documentation),</li> <li>polexpr.html (conversion via <a class="reference external" href="http://docutils.sourceforge.net/docs/index.html">DocUtils</a> rst2html.py)</li> </ul> -<p>See README.md for the License and the change log.</p> +<p>See README.md for the License and the change log (there were +some breaking changes from 0.2 to 0.3).</p> +</div> +<div class="section" id="acknowledgments"> +<h1><a class="toc-backref" href="#id62">Acknowledgments</a></h1> +<p>Thanks to Jürgen Gilg whose question about <a class="reference external" href="http://www.ctan.org/pkg/xint">xint</a> usage for +differentiating polynomials was the initial trigger leading to this +package, and to Jürgen Gilg and Thomas Söll for testing it on some +concrete problems.</p> </div> </div> </body> diff --git a/Master/texmf-dist/doc/latex/polexpr/polexpr.txt b/Master/texmf-dist/doc/latex/polexpr/polexpr.txt index 19d5ccdf9c9..2825128f004 100644 --- a/Master/texmf-dist/doc/latex/polexpr/polexpr.txt +++ b/Master/texmf-dist/doc/latex/polexpr/polexpr.txt @@ -1,29 +1,35 @@ .. comment: -*- fill-column: 72; mode: rst; -*- -Package polexpr documentation -============================= +=============================== + Package polexpr documentation +=============================== + +0.3.1 (2018/01/18) +================== + +.. contents:: First Examples -------------- The syntax is:: - \poldef <name>(x):=<expression in variable x>; + \poldef polname(x):= expression in variable x; where in place of ``x`` an arbitrary *dummy variable* is authorized -(i.e. per default any of ``[a..z|A..Z]``; more letters can be declared +(i.e. per default any of ``[a-z|A-Z]``; more letters can be declared under Unicode engines.) One can also issue:: - \PolDef{name}{expression in variable x} + \PolDef{polname}{expression in variable x} which admits an optional first argument to modify the variable letter from its default ``x``. ``\poldef f(x):= 1-x+x^2;`` - defines polynomial ``f``. Polynomial names must start with a letter - and may contain letters, digits, and underscores. The variable must - be a single letter. The colon character is optional. The semi-colon - at end of expression is mandatory. + defines polynomial ``f``. Polynomial names must start with a + letter and may contain letters, digits, and underscores. The + variable must be a single letter. The colon character is optional. + The semi-colon at end of expression is mandatory. ``\PolDef{f}{1-x+x^2}`` does the same as ``\poldef f(x):= 1-x+x^2;`` To use another letter @@ -31,9 +37,9 @@ from its default ``x``. argument to ``\PolDef``. Useful if the semi-colon has been assigned some non-standard catcode by some package. -``\PolLet{g}{f}`` - saves a copy of ``f`` under name ``g``. - +``\PolLet{g}={f}`` + saves a copy of ``f`` under name ``g``. Also usable without ``=``. + ``\poldef f(z):= f(z)^2;`` redefines ``f`` in terms of itself. @@ -46,7 +52,7 @@ from its default ``x``. ``\PolDiff{f}{df_dx}`` sets ``df_dx`` to the derivative of ``f``. - + ``\PolDiff{df_dx}{f_xx}`` obtains second derivative. @@ -77,73 +83,141 @@ from its default ``x``. \poldef k(x):= (x-1)(x-2)(x-3)(x-4)/(x^2-5x+4); +.. _warningtacit: + .. attention:: - ``1/2 x`` skips the space and is treated like ``1/(2x)`` because of - the tacit multiplication rules of \xintexpr. But this means it gives - zero! Thus one must use ``(1/2)x`` or ``1/2*x`` or ``(1/2)*x`` for - disambiguation: ``x-1/2*x^2+1/3*x^3...`` + ``1/2 x^2`` skips the space and is treated like ``1/(2*x^2)`` because + of the tacit multiplication rules of \xintexpr. But this means it + gives zero! Thus one must use ``(1/2)x^2`` or ``1/2*x^2`` or + ``(1/2)*x^2`` for disambiguation: ``x - 1/2*x^2 + 1/3*x^3...``. It is + even simpler to move the denominator to the right: ``x - x^2/2 + + x^3/3 - ...``. + + It is worth noting that ``1/2(x-1)(x-2)`` suffers the same issue: + xint_ tacit multiplication always "ties more", hence this gets + interpreted as ``1/(2*(x-1)*(x-2))`` which gives zero by polynomial + division. Thus, use one of ``(1/2)(x-1)(x-2)``, ``1/2*(x-1)(x-2)`` or + ``(x-1)(x-2)/2``. After:: - \poldef f1(x):= 25(x-1)(x^2-2)(x-3)(x-4)(x-5);% - \poldef f2(x):= 37(x-1)(x^2-2)(x-6)(x-7)(x-8);% + \poldef f_1(x):= 25(x-1)(x^2-2)(x-3)(x-4)(x-5);% + \poldef f_2(x):= 37(x-1)(x^2-2)(x-6)(x-7)(x-8);% -the macro call ``\PolGCD{f1}{f2}{k}`` sets ``k`` to the (unitary) GCD of -``f1`` and ``f2``. +the macro call ``\PolGCD{f_1}{f_2}{k}`` sets ``k`` to the (unitary) GCD of +``f_1`` and ``f_2`` (hence to the expansion of ``(x-1)(x^2-2)``.) ``\PolToExpr{k}`` - will thus (expandably) give in this case ``2-2*x^1-1*x^2+1*x^3``. - This is useful for console or file output (the syntax is Maple- and - PSTricks-compatible; currently the letter ``x`` in output is not - customizable, but this can easily be added if requested from author.) + will (expandably) give in this case ``x^3-x^2-2*x+2``. This is + useful for console or file output (the syntax is Maple- and + PSTricks-compatible; the letter used in output can be + (non-expandably) changed via a redefinition of `\\PolToExprVar`_.) + +``\PolToExpr*{k}`` + gives ascending powers: ``2-2*x-x^2+x^3``. Non-expandable macros --------------------- -``\poldef name(letter):= polynomial expression using letter;`` - This evaluates the polynomial expression and stores the coefficients +.. _poldef;: + +``\poldef polname(letter):= expression in letter;`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + This evaluates the *polynomial expression* and stores the coefficients in a private structure accessible later via other package macros, - under the user-chosen ``name``. Of course previously defined - polynomials are allowed in a new expression. Names must start with a + under the user-chosen ``polname``. Of course the *expression* can + use other previously defined polynomials. Names must start with a letter and are constituted of letters, digits and underscore - characters. See Examples above. + characters. The whole xintexpr_ syntax is authorized:: + + \poldef sin(z) := add((-1)^i z^(2i+1)/(2i+1)!, i = 0..10); + + With fractional coefficients, beware the `tacit multiplication issue + <warningtacit_>`_. + + As a side effect the function ``polname()`` is recognized as a + genuine ``\xintexpr...\relax`` function for (exact) numerical + evaluation (or within an ``\xintdefvar`` assignment.) It computes + values not according to the original expression but via the Horner + scheme corresponding to the polynomial coefficients. + + Also, a function with the same name is created for use within + ``\xintfloatexpr`` (or ``\xintdeffloatvar``.) This is indispensible + for numerical algorithms as exact computations very quickly lead to + very big fractions. Addition and multiplication steps of the Horner + scheme will be executed as floating-point operations. The + coefficients have already been rounded at time of definition, + according to the then prevailing ``\xinttheDigits`` value. + + .. important:: + + Package macros (such as derivatives or Euclidean division) + operate with the "exact" polynomials; "floating point" + polynomials are always obtained in a second step. + + To modifiy "in-place" the original coefficients of a polynomial + and round them to float precision:: - As a side effect the function ``name()`` is recognized as a genuine - ``\xintexpr...\relax`` function for (exact) numerical evaluation. It - computes values not according to the original expression but via - the Horner scheme corresponding to the polynomial coefficients. + \PolMapCoeffs{\xintFloat}{polname} + % or \xintFloat[P] for precision P digits + + See `\\PolMapCoeffs{\\macro}{polname}`_. The original expression is lost after parsing, and in particular the package provides no way to typeset it. This has to be done manually, if needed. -``\PolDef{name}{P(x)}`` - Does the same but the variable is assumed to be ``x``. To use - another letter, pass it as first optional argument: - ``\PolDef[X]{name}{P(X)}``. +.. _PolDef: + +``\PolDef[letter]{polname}{expression in letter}`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Does the same in an undelimited macro format (thus avoiding + potential problems with the catcode of the semi-colon in presence of + some packages.) In absence of the ``[letter]`` optional argument, + the variable is assumed to be ``x``. + +``\PolLet{polname_2}={polname_1}`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -``\PolLet{g}{f}`` - Makes a copy of already defined polynomial f to new one g. Same - effect as ``\PolDef{g}{f(x)}`` but faster. + Makes a copy of the already defined polynomial ``polname_1`` to a + new one ``polname_2``. Same effect as + ``\PolDef{polname_2}{polname_1(x)}`` but with less overhead. The + ``=`` is optional. -``\PolAssign{f}\toarray\Array`` - Defines a one-argument expandable macro ``\Array{#1}`` which expands +``\PolAssign{polname}\toarray\macro`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Defines a one-argument expandable macro ``\macro{#1}`` which expands to the (raw) #1th polynomial coefficient. - Attention, coefficients here are indexed starting at 1. - - With #1=-1, -2, ..., ``\Array{#1}`` returns leading coefficients. + - With #1=-1, -2, ..., ``\macro{#1}`` returns leading coefficients. - With #1=0, returns the number of coefficients, i.e. ``1 + deg f`` for non-zero polynomials. - Out-of-range #1's return ``0/1[0]``. -``\PolGet{f}\fromarray\Array`` - Does the converse operation to ``\PolAssign{f}\toarray\Array``. No + See also `\\PolNthCoeff{polname}{number}`_. The main difference is that + with ``\PolAssign``, ``\macro`` is made a prefix to ``1 + deg f`` + already defined (hidden to user) macros holding individually the + coefficients but `\\PolNthCoeff{polname}{number}`_ does each time the job + to expandably recover the ``Nth`` coefficient, and due to + expandability can not store it in a macro for future usage (of course, + it can be an argument in an ``\edef``.) The other difference + is the shift by one in indexing, mentioned above (negative + indices act the same in both.) + +``\PolGet{polname}\fromarray\macro`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Does the converse operation to ``\PolAssign{polname}\toarray\macro``. No error checks on validity of coefficients as numbers. Each - ``\Array{index}`` is expanded in an ``\edef`` before being assigned + ``\macro{number}`` is expanded in an ``\edef`` before being assigned to a coefficient. Leading zero coefficients are removed from the polynomial. @@ -156,166 +230,432 @@ Non-expandable macros However the coefficients are still in their original form (i.e. they were not subjected to ``\xintRaw`` or similar xintfrac macro.) -``\PolFromCSV{f}{comma separated coefficients}`` - Defines a polynomial directly from the comma separated list (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 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). +``\PolFromCSV{polname}{<csv>}`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Defines a polynomial directly from the comma separated list of + values (or a macro expanding to such a list) of its coefficients, + the constant term being the first item. No validity checks. Spaces + from the list argument are trimmed. List items are each expanded in + an ``\edef``, 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). Leading zero coefficients are removed:: - \PolFromCSV{J}{0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + \PolFromCSV{f}{0, 0, 0, 0, 0, 0, 0, 0, 0, 0} defines the zero polynomial, which has only one (zero) coefficient. - See also expandable macro ``\PolToCSV``. + See also expandable macro `\\PolToCSV <\\PolToCSV{polname}_>`_. + +``\PolTypeset{polname}`` +~~~~~~~~~~~~~~~~~~~~~~~~ -``\PolTypeset{name}`` Typesets in descending powers in math mode. It uses letter ``x`` but this can be changed via an optional argument:: - \PolTypeset[z]{name} + \PolTypeset[z]{polname} By default zero coefficients are skipped (issue ``\poltypesetalltrue`` to get all of them in output). - Macros ``\PolTypesetCmd``, ``\PolTypesetPlus``, ``\PolTypesetMonomial`` - can help configure the output. See the package code. + These commands (whose meanings will be found in the package code) + can be re-defined for customization. Their default definitions are + expandable, but this is not a requirement. + +``\PolTypesetCmd{raw_coeff}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + Basically will use ``\xintSignedFrac`` from xintfrac_, but checks if + the coefficient is ``1`` or ``-1`` and then skips printing the + ``1``, except for the constant term... + + One can do things such as for example: [#]_ + + :: + + \renewcommand\PolTypesetCmd[1]{\num{\xintPFloat[5]{#1}}} + \renewcommand\PolTypesetCmd[1]{\num{\xintRound{4}{#1}}} + + where e.g. we used the ``\num`` macro of ``siunitx`` as it + understands floating point notation. -``\PolTypeset*{name}`` - Typesets in ascending powers. Change the letter from its default - ``x`` by optional argument. + .. [#] the difference in the syntaxes of ``\xintPFloat`` and + ``\xintRound`` is explained from the fact that + ``\xintPFloat`` by default uses the prevailing precision + hence the extra argument like here ``5`` is an optional one. -``\PolDiff{f1}{f2}`` - This sets f2 to the first derivative of ``f1``. It is allowed to - issue ``\PolDiff{f}{f}``, effectively replacing ``f`` by ``f'``. +``\PolTypesetCmdPrefix{raw_coeff}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Coefficients of the result ``f2`` are irreducible fractions + Expands to a ``+`` if the ``raw_coeff`` is zero or positive, and to + nothing if ``raw_coeff`` is negative, as in latter case the + ``\xintSignedFrac`` used by `\\PolTypesetCmd{raw_coeff}`_ will put + the ``-`` sign in front of the fraction (if it is a fraction) and + this will thus serve as separator in the typeset formula. Not used + for the first term. + +``\PolTypesetMonomialCmd`` +^^^^^^^^^^^^^^^^^^^^^^^^^^ + + This decides how a monomial (in variable ``\PolVar`` and with + exponent ``\PolIndex``) is to be printed. The default does nothing + for the constant term, ``\PolVar`` for the first degree and + ``\PolVar^{\PolIndex}`` for higher degrees monomials. Beware that + ``\PolIndex`` expands to digit tokens and needs termination in + ``\ifnum`` tests. + +``\PolTypeset*{polname}`` +~~~~~~~~~~~~~~~~~~~~~~~~~ + + Typesets in ascending powers. Use e.g. ``[h]`` optional argument + (after the ``*``) to use letter ``h`` rather than ``x``. + +``\PolDiff{polname_1}{polname_2}`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + This sets ``polname_2`` to the first derivative of ``polname_1``. It + is allowed to issue ``\PolDiff{f}{f}``, effectively replacing ``f`` + by ``f'``. + + Coefficients of the result ``polname_2`` are irreducible fractions (see `Technicalities`_ for the whole story.) -``\PolDiff[N]{f1}{f2}`` - This sets ``f2`` to the ``N``-th derivative of ``f1``. Identical - arguments is allowed. With ``N=0``, same effect as - ``\PolLet{f2}{f1}``. With negative ``N``, switches to using - ``\PolAntiDiff``. +``\PolDiff[N]{polname_1}{polname_2}`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + This sets ``polname_2`` to the ``N``-th derivative of ``polname_1``. + Identical arguments is allowed. With ``N=0``, same effect as + ``\PolLet{polname_2}={polname_1}``. With negative ``N``, switches to + using ``\PolAntiDiff``. -``\PolAntiDiff{f1}{f2}`` - This sets ``f2`` to the primitive of ``f1`` vanishing at zero. +``\PolAntiDiff{polname_1}{polname_2}`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Coefficients of the result ``f2`` are irreducible fractions + This sets ``polname_2`` to the primitive of ``polname_1`` vanishing + at zero. + + Coefficients of the result ``polname_2`` are irreducible fractions (see `Technicalities`_ for the whole story.) -``\PolAntiDiff[N]{f1}{f2}`` - This sets ``f2`` to the result of ``N`` successive integrations on - ``f1``. With negative ``N``, it switches to using ``\PolDiff``. +``\PolAntiDiff[N]{polname_1}{polname_2}`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + This sets ``polname_2`` to the result of ``N`` successive integrations on + ``polname_1``. With negative ``N``, it switches to using ``\PolDiff``. + +``\PolDivide{polname_1}{polname_2}{polname_Q}{polname_R}`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + This sets ``polname_Q`` and ``polname_R`` to be the quotient and + remainder in the Euclidean division of ``polname_1`` by + ``polname_2``. -``\PolDivide{f1}{f2}{Q}{R}`` - This sets ``Q`` and ``R`` to be the quotient and remainder in the - Euclidean division of ``f1`` by ``f2``. +``\PolGCD{polname_1}{polname_2}{polname_GCD}`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -``\PolGCD{f}{g}{k}`` - This sets ``k`` to be the G.C.D. It is a unitary polynomial except - if both ``f`` and ``g`` vanish, then ``k`` is the zero polynomial. + This sets ``polname_GCD`` to be the G.C.D. It is a unitary + polynomial except if both ``polname_1`` and ``polname_2`` vanish, + then ``polname_GCD`` is the zero polynomial. -``\PolMapCoeffs{\macro}{name}`` - It modifies each coefficient of the defined polynomial via the - *expandable* macro ``\macro``. The degree is adjusted as necessary - if some leading coefficients vanish after the operation. In - replacement text of ``\macro``, ``\index`` expands to the - coefficient index (which is defined to be zero for the constant - term). +``\PolMapCoeffs{\macro}{polname}`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + It modifies ('in-place': original coefficients get lost) each + coefficient of the defined polynomial via the *expandable* macro + ``\macro``. The degree is adjusted as necessary if some leading + coefficients vanish after the operation. In replacement text of + ``\macro``, ``\index`` expands to the coefficient index (which is + defined to be zero for the constant term). Notice that ``\macro`` will have to handle inputs of the shape - ``A/B[N]`` (xintfrac internal notation). This means that it probably + ``A/B[N]`` (xintfrac_ internal notation). This means that it probably will have to be expressed in terms of macros from xintfrac package. Example:: \def\foo#1{\xintMul{#1}{\the\numexpr\index*\index\relax}} - (or with ``\xintSqr{\xindex}``) to replace ``n``-th coefficient + (or with ``\xintSqr{\index}``) to replace ``n``-th coefficient ``f_n`` by ``f_n*n^2``. -``\PolReduceCoeffs{name}`` - About the same as ``\PolMapCoeffs{\xintIrr}{name}`` (but adds - ``[0]`` postfix which speeds up xintfrac operations when - evaluating.) +``\PolReduceCoeffs{polname}`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + About the same as ``\PolMapCoeffs{\xintIrr}{polname}`` (but + maintaining a ``[0]`` postfix for speedier xintfrac_ parsing when + polynomial function is used for computations.) This is a + one-argument macro, working 'in-place'. Expandable macros ----------------- All these macros expand completely in two steps except ``\PolToExpr`` -which needs a ``\write``, ``\edef`` or a ``\csname...\endcsname`` context. +and ``\PolToFloatExpr`` (and their auxiliaries) which need a +``\write``, ``\edef`` or a ``\csname...\endcsname`` context. -``\PolEval{name}\At{value}`` - It boils down to ``\xinttheexpr reduce(name(value))\relax``. +``\PolEval{polname}\At{numerical expression}`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -``\PolNthCoeff{name}{N}`` - It expands to the raw ``N``-th coefficient (``0/1[0]`` if index is - out of range). With ``N=-1``, ``-2``, ... expands to the leading - coefficients. + It boils down to ``\xinttheexpr polname(numerical expression)\relax``. + + .. note:: + + The ``0.2`` version stupidly tried to be clever and as a result + of a misguided optimization choked if ``value`` was not a number + but a numerical expression (a sum e.g.), but the more powerful + behaviour has been reinstored at ``0.3`` release. + + The ``0.1`` and ``0.2`` version did a ``reduce`` which however is + costly on big fractions and irrelevant if the output is served as + argument of ``\xintRound`` or ``\xintFloat``. Thus ``reduce`` was + removed, and former meaning is now available as + `\\PolEvalReduced{polname}\\At{numerical expression}`_ + +``\PolEvalReduced{polname}\At{numerical expression}`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Boils down to ``\xinttheexpr reduce(polname(numerical expression))\relax``. + +``\PolFloatEval{polname}\At{numerical expression}`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Boils down to ``\xintthefloatexpr polname(numerical expression)\relax``. + + This is done via a Horner Scheme (see `\\poldef <poldef;_>`_), with + already rounded coefficients. [#]_ To use the *exact coefficients* + (and *exact* additions and multiplications), just insert it in the + float expression as in this example: [#]_ + + :: + + \xintthefloatexpr 3.27*\xintexpr f(2.53)\relax^2\relax + + The ``f(2.53)`` is exactly computed then rounded at the time of + getting raised to the power ``2``. Moving the ``^2`` inside, that + operation would also be treated exactly. + + .. [#] Anyway each floating point operation starts by rounding its + operands to the floating point precision. + + .. [#] The ``\xintexpr`` could be ``\xinttheexpr`` but that would be + less efficient. Cf. xintexpr_ documentation about nested + expressions. + +``\PolNthCoeff{polname}{number}`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + It expands to the raw ``N``-th coefficient (``0/1[0]`` if the index + number is out of range). With ``N=-1``, ``-2``, ... expands to the + leading coefficients. + +``\PolDegree{polname}`` +~~~~~~~~~~~~~~~~~~~~~~~ -``\PolDegree{name}`` It expands to the degree. This is ``-1`` if zero polynomial but this may change in future. Should it then expand to ``-\infty`` ? -``\PolToExpr{f}`` - Expands to ``f_0 + f_1*x + f_2*x^2 + ...`` (ascending powers). [1]_, - [2]_ +``\PolToExpr{polname}`` +~~~~~~~~~~~~~~~~~~~~~~~ - .. [1] in a ``\write``, ``\edef``, or ``\csname...\endcsname``, but - not under ``\romannumeral-`0``. + Expands [#]_ to ``coeff_N*x^N+...`` (descending powers.) - .. [2] the letter ``x`` is (in this release) not customizable. + .. [#] in a ``\write``, ``\edef``, or ``\csname...\endcsname``, but + not under ``\romannumeral-`0``. - By default zero coefficients are skipped (issue ``\poltoexprtrue`` to + By default zero coefficients are skipped (issue ``\poltoexpralltrue`` to get all of them in output). - No ``+`` sign before negative coefficients, for compliance with Maple - input format. This means though that parsing the result back via - naive delimited macros is difficult, see ``\PolToList`` and ``\PolToCSV`` - for more low-level formats making it easier to get expandably some - output of one's choice, which may possibly be parsed later on by - other macros of one's design, or from other packages. + By default, no ``+`` sign before negative coefficients, for + compliance with Maple input format (but see + `\\PolToExprTermPrefix{raw_coeff}`_.) Also, like the default + behaviour of `\\PolTypeset{polname}`_, does not print (for the non + constant terms) coefficients equal to plus or minus one. The degree + one monomial is output as ``x``, not ``x^1``. Complete customization is + possible, see next macros. - Of course ``\PolToExpr{f}`` can be inserted in a \poldef, as the + Of course ``\PolToExpr{f}`` can be inserted in a ``\poldef``, as the latter expands token by token, hence will force complete expansion - of ``\PolToExpr{f}``, but simply ``f(x)`` will be more efficient for the - identical result. + of ``\PolToExpr{f}``, but a simple ``f(x)`` is more efficient for + the identical result. + +``\PolToExprOneTerm{raw_coeff}{number}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + This two argument expandable command takes care of the monomial and + its coefficient. The default definition is done in order for + coefficients of absolute value ``1`` not be printed explicitely + (except of course for the constant term). Also by default, the + monomial of degree one is ``x`` not ``x^1``, and ``x^0`` is skipped. + + For compatibility with Maple input requirements, by default a ``*`` + always precedes the ``x^number``, except if the coefficient is a one + or a minus one. See `\\PolToExprTimes`_. + +``\PolToExprOneTermStyleB{raw_coeff}{number}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + For output in this style:: + + 2*x^11/3+3*x^8/7-x^5−x^4/4−x^3−x^2/2−2*x+1 + + issue ``\let\PolToExprOneTerm\PolToExprOneTermStyleB`` before using + ``\PolToExpr``. Note that then ``\PolToExprCmd`` isn't used at all. + + To suppress the ``*``'s, cf. `\\PolToExprTimes`_. + +``\PolToExprCmd{raw_coeff}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + It is the one-argument macro used by the package definition of + ``\PolToExprOneTerm`` for the coefficients themselves (when not + equal to plus or minus one), and it defaults to + ``\xintPRaw{\xintRawWithZeros{#1}}``. One will have to redefine it + to ``\xintIrr{#1}`` or to ``\xintPRaw{\xintIrr{#1}}`` to obtain in the + output forcefully reduced coefficients. + +``\PolToExprTermPrefix{raw_coeff}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + Defined identically as `\\PolTypesetCmdPrefix{raw_coeff}`_. It + prefixes with a plus sign for non-negative coefficients, because + they don't carry one by themselves. + +``\PolToExprVar`` +^^^^^^^^^^^^^^^^^ + + This expands to the variable to use in output (it does not have to + be a single letter, may be an expandable macro.) Initial definition + is ``x``. + +``\PolToExprTimes`` +^^^^^^^^^^^^^^^^^^^ + + This expands to the symbol used for multiplication of an + ``x^{number}`` by the corresponding coefficient. The default is + ``*``. Redefine the macro to expand to nothing to get rid of it (but + this will give output incompatible with some professional computer + algebra software). + +``\PolToExpr*{polname}`` +~~~~~~~~~~~~~~~~~~~~~~~~ + + Expands to ``coeff_0+coeff_1*x+coeff_2*x^2+...`` (ascending powers). + Customizable like `\\PolToExpr{polname}`_ via the same macros. + +``\PolToFloatExpr{polname}`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Similar to `\\PolToExpr{polname}`_ but uses `\\PolToFloatExprCmd + <\\PolToFloatExprCmd{raw_coeff}>`_ + which by default rounds and converts the coefficients to floating + point format. + + .. note:: + + The polynomial function for usage in ``\xintfloatexpr`` is + already prepared with the rounded coefficients, but the latter + are not easily recoverable (and especially not expandably) from + this. Thus ``\PolToFloatExprCmd`` operates from the *exact* + coefficients anew. This means though that if the prevailing float + precision was changed with ``\xintDigits:=P;`` syntax, the output + will obey this precision ``P``, but the polynomial function was + defined earlier and operates on floating point numbers with + coefficients which were rounded at time of definition. + + This may change in future, if the pre-rounded coefficients are + stored in a more easily accessible data structure. + +``\PolToFloatExprOneTerm{raw_coeff}{number}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + Similar to `\\PolToExprOneTerm + <\\PolToExprOneTerm{raw_coeff}{number}>`_. But does not treat + especially coefficients equal to plus or minus one. + +``\PolToFloatExprCmd{raw_coeff}`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + It is the one-argument macro used by ``\PolToFloatExprOneTerm``. + Its package definition is ``\xintFloat{#1}``. + + .. caution:: + + Currently (xint_ ``1.2p``) ``\xintFloat{0}`` outputs ``0.e0`` + which is perfectly acceptable input for Python, but not for + Maple. Thus, one should better leave the `\\poltoexprallfalse`_ + toggle to its default ``\iffalse`` state, if one intends to use + the output in a Maple worksheet. - ``\PolToExprCmd`` is the one-argument macro used by ``\PolToExpr`` for the - coefficients, it defaults to ``\xintPRaw{\xintRawWithZeros{#1}}``. One - will have to redefine it to use ``\xintIrr{#1}`` in place of - ``\xintRawWithZeros{#1}`` to get in output reduced coefficients. + But even then the zero polynomial will cause a problem. Workaround:: -``\PolToList{f}`` - Expands to ``{f_0}{f_1}...{f_N}`` with ``N`` = degree of f (except - zero polynomial which does give ``{0/1[0]}`` and not an empty - output.) + \renewcommand\PolToFloatExprCmd[1]{\xintiiifZero{#1}{0.0}{\xintFloat{#1}}} + + Usage of ``\xintiiifZero`` and not ``\xintifZero`` is only for + optimization (I can't help it) because ``#1`` is known to be + in ``xintfrac`` raw format. + +``\PolToFloatExpr*{polname}`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Typesets in ascending powers. + +``\PolToList{polname}`` +~~~~~~~~~~~~~~~~~~~~~~~ + + Expands to ``{coeff_0}{coeff_1}...{coeff_N}`` with ``N`` = degree + (except zero polynomial which does give ``{0/1[0]}`` and not an + empty output.) + +``\PolToCSV{polname}`` +~~~~~~~~~~~~~~~~~~~~~~ + + Expands to ``coeff_0, coeff_1, coeff_2, ....., coeff_N``. Converse + to `\\PolFromCSV <\\PolFromCSV{polname}{\<csv\>}_>`_. + +Booleans (with default setting as indicated) +-------------------------------------------- + +``\xintverbosefalse`` +~~~~~~~~~~~~~~~~~~~~~ + + This is actually an xintexpr_ configuration. Setting it to + ``true`` triggers the writing of information to the log when new + polynomials are defined. + + .. caution:: + + The macro meanings as written to the log are to be considered + unstable and undocumented internal structures. + +``\poltypesetallfalse`` +~~~~~~~~~~~~~~~~~~~~~~~ + + If ``true``, `\\PolTypeset{polname}`_ will also typeset the vanishing + coefficients. + + +``\poltoexprallfalse`` +~~~~~~~~~~~~~~~~~~~~~~ + + If ``true``, `\\PolToExpr{polname}`_ and `\\PolToFloatExpr{polname}`_ will + also include the vanishing coefficients in their outputs. -``\PolToCSV{f}`` - Expands to ``f_0, f_1, f_2, ....., f_N``. Converse to - ``\PolFromCSV``. Technicalities -------------- -- The catcode of the semi-colon is reset temporarily by ``\poldef`` macro in - case some other package (for example the French babel module) may have - made it active. This will fail though if the whole thing was already - part of a macro argument, in such cases one can use ``\PolDef`` rather. - The colon in ``:=`` may be active with no consequences. - -- Beware the ``1/2 x`` problem: as mentioned above, it will be give zero due - to the tacit multiplication rules of ``\xintexpr`` and to the fact that - the package will do the Euclidean division of ``1`` by polynomial ``2x``. +- The catcode of the semi-colon is reset temporarily by `\\poldef + <poldef;_>`_ macro in case some other package (for example the French + babel module) may have made it active. This will fail though if the + whole thing was already part of a macro argument, in such cases one + can use `\\PolDef{f}{P(x)} <PolDef_>`_ + rather. The colon in ``:=`` may be active with no consequences. - During execution of polynomial operations by ``\poldef`` (but not during the initial purely numerical parsing of the expression), the - xintfrac macro ``\xintAdd`` is temporarily patched to always express + xintfrac_ macro ``\xintAdd`` is temporarily patched to always express ``a/b + c/d`` with ``l.c.m.(b,d)`` as denominator. Indeed the current (xint 1.2p) ``\xintAdd`` uses ``(ad+bc)/bd`` formula except if ``b`` divides ``d`` or ``d`` divides ``b``, which quickly leads in real life @@ -343,35 +683,43 @@ Technicalities where all coefficients have the same denominator 6 (which in this example is the ``l.c.m`` of the denominators of the reduced coefficients.) -- ``\PolDiff`` always applies ``\xintIrr`` to the resulting coefficients, except - that the *power of ten* part ``[N]`` (for example an input in scientific - notation such as ``1.23e5`` gives ``123/1[3]`` internally in xintfrac) is not - taken into account in the reduction of the fraction. This is tentative - and may change. +- `\\PolDiff{polname_1}{polname_2}`_ always applies ``\xintIrr`` to the + resulting coefficients, except that the *power of ten* part ``[N]`` + (for example an input in scientific notation such as ``1.23e5`` gives + ``123/1[3]`` internally in xintfrac) is not taken into account in the + reduction of the fraction. This is tentative and may change. - Same remark for ``\PolAntiDiff``. + 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``. -- If ``f`` was created from comma separated values by macro \PolFromCSV, - then the coefficients will be in the output of ``\PolToList`` and - ``\PolToCSV`` 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 is an unavoidable consequence of usage - by \poldef of ``\xintdeffunc`` which itself is based on ``\xintexpr.`` + the xintfrac *raw* format. This *raw* format speeds up expansion of xintfrac macros for numerical evaluations. -- Currently, the package does not as a result of ``\poldef`` add to the TeX - memory an already pre-computed *array* structure for the polynomial - coefficients, as would be constructed by ``\PolAssign{f}\toarray\macro``. - Such structures are used, but for internal calculations in temporarily - restricted scopes. Apart from the function ``f()`` known to the - (numerical) ``\xintexpr`` parser (whose meaning can be found in the log - file after \xintverbosetrue), the data is (currently) stored in a - single other macro encapsulating the degree, and the coefficients as a - list. This may evolve in future. +- Currently, the package stores all coefficients from index ``0`` to + index equal to the polynomial degree inside a single macro, as a list. + This data structure is obviously very inefficient for polynomials of + high degree and few coefficients (as an example with ``\poldef + f(x):=x^1000 + x^500;`` the subsequent definition ``\poldef g(x):= + f(x)^2;`` will do of the order of 1,000,000 multiplications and + additions involvings only zeroes... which does take time). This + may change in the future. + +- Tests have been made with Newton's iteration (for which computing + exactly the derivative is precisely what this package is made for) or + Regula Falsi method for locating roots: using exact computations leads + quickly to gigantic fractions (but dichotomy method much less so). It + is thus recommended to use ``\xintdeffloatvar`` or + ``\xintthefloatexpr`` contexts for any kind of numerical mathematics. + Of course, exact computations are invaluable for number theory or + combinatorics... - As is to be expected internal structures of the package are barely documented and unstable. Don't use them. @@ -379,10 +727,24 @@ Technicalities RELEASES -------- -- 0.1 (2018/01/11): initial release (files README, polexpr.sty). -- 0.2 (2018/01/14): documentation moved to polexpr.{txt,html}. +- 0.1 (2018/01/11) + + Initial release (files README, polexpr.sty). -Files of 0.2 release: +- 0.2 (2018/01/14) + + Documentation moved to polexpr.{txt,html}. + +- 0.3 (2018/01/17) + + Make polynomials known to ``\xintfloatexpr`` and improve + documentation. + +- 0.3.1 (2018/01/18) + + Fix two typos in documentation. + +Files of 0.3.1 release: - README.md, - polexpr.sty (package file), @@ -391,4 +753,17 @@ Files of 0.2 release: __ http://docutils.sourceforge.net/docs/index.html -See README.md for the License and the change log. +See README.md for the License and the change log (there were +some breaking changes from 0.2 to 0.3). + +Acknowledgments +--------------- + +Thanks to Jürgen Gilg whose question about xint_ usage for +differentiating polynomials was the initial trigger leading to this +package, and to Jürgen Gilg and Thomas Söll for testing it on some +concrete problems. + +.. _xintfrac: +.. _xintexpr: +.. _xint: http://www.ctan.org/pkg/xint diff --git a/Master/texmf-dist/tex/latex/polexpr/polexpr.sty b/Master/texmf-dist/tex/latex/polexpr/polexpr.sty index 9f2bd0c0ea5..752efa3fa77 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/01/14 v0.2 Polynomial expressions with rational coefficients (JFB)]% + [2018/01/18 v0.3.1 Polynomial expressions with rational coefficients (JFB)]% \RequirePackage{xintexpr}[2016/03/19]% xint 1.2g (or 1.2c 2015/11/16 at least) \edef\POL@restorecatcodes {\catcode`\noexpand\_ \the\catcode`\_ \catcode0 \the\catcode0\relax}% @@ -76,12 +76,16 @@ %% \def\POL@newpol#1{% \expandafter\POL@ifZero\csname POLuserpol@#1\endcsname - {\@namedef{XINT_expr_userfunc_#1}##1,{0/1[0]}}% + {\@namedef{XINT_expr_userfunc_#1}##1,{0/1[0]}% + \@namedef{XINT_flexpr_userfunc_#1}##1,{0[0]}}% {\POL@newpolhorner{#1}}% \unless\ifcsname XINT_expr_userfuncNE:#1\endcsname\POL@addtoextras{#1}\fi \expandafter\XINT_expr_defuserfunc \csname XINT_expr_func_#1\expandafter\endcsname \csname XINT_expr_userfunc_#1\endcsname + \expandafter\XINT_expr_defuserfunc + \csname XINT_flexpr_func_#1\expandafter\endcsname + \csname XINT_flexpr_userfunc_#1\endcsname \ifxintverbose\POL@info{#1}\fi }% \def\POL@info #1{% @@ -90,7 +94,11 @@ associated to \string\XINT_expr_userfunc_#1\space whose meaning uses Horner scheme: \expandafter\meaning - \csname XINT_expr_userfunc_#1\endcsname}% + \csname XINT_expr_userfunc_#1\endcsname^^J% + \@spaces And \string\XINT_flexpr_userfunc_#1\space for + the \string\xintfloatexpr\space parser has meaning + \expandafter\meaning + \csname XINT_flexpr_userfunc_#1\endcsname}% }% % \def\POL@newpolhorner#1{% @@ -102,17 +110,37 @@ \edef\POL@var@coeffs{\xintRevWithBraces{\POL@var@coeffs}}% \begingroup \expandafter\POL@newpol@horner\POL@var@coeffs\relax + \expandafter + \endgroup + \expandafter\def\csname XINT_expr_userfunc_#1\expandafter\endcsname + \expandafter##\expandafter1\expandafter,\expandafter{\POL@tmp{##1}}% + \begingroup + \expandafter\POL@newpol@floathorner\POL@var@coeffs\relax + \expandafter \endgroup - \expandafter\let\csname XINT_expr_userfunc_#1\endcsname\POL@tmp + \expandafter\def\csname XINT_flexpr_userfunc_#1\expandafter\endcsname + \expandafter##\expandafter1\expandafter,\expandafter{\POL@tmp{##1}}% }% \def\POL@newpol@horner#1{\let\xintAdd\relax\let\xintMul\relax - \gdef\POL@tmp##1,{#1}\POL@newpol@horner@loop.}% + \def\POL@tmp##1{#1}\POL@newpol@horner@loop.}% \def\POL@newpol@horner@loop.#1{% \if\relax#1\expandafter\xint_gob_til_dot\fi - \xdef\POL@tmp##1,{\xintiiifZero{#1}{\@firstofone}{\xintAdd{#1}}% - {\xintMul{##1}{\POL@tmp##1,}}}% + \edef\POL@tmp##1{\xintiiifZero{#1} + {\@firstofone}{\xintAdd{#1}}% + {\xintMul{##1}{\POL@tmp{##1}}}}% \POL@newpol@horner@loop.% }% +\def\POL@newpol@floathorner#1{\let\XINTinFloatAdd\relax\let\XINTinFloatMul\relax + \def\xintAdd{\XINTinFloatAdd}\def\xintMul{\XINTinFloatMul}% + \edef\POL@tmp##1{\XINTinFloatdigits{#1}}% + \POL@newpol@floathorner@loop.}% +\def\POL@newpol@floathorner@loop.#1{% + \if\relax#1\expandafter\xint_gob_til_dot\fi + \edef\POL@tmp##1{\xintiiifZero{#1} + {\@firstofone}{\xintAdd{\XINTinFloatdigits{#1}}}% + {\xintMul{##1}{\POL@tmp{##1}}}}% + \POL@newpol@floathorner@loop.% +}% %% Customizes xintexpr.sty's \XINT_NewExpr (\POL@addtoextras{name}) \begingroup \catcode`~ 12 @@ -150,15 +178,24 @@ \def\POL@redefinemacros{\POL@original_redefinemacros\POL@redefineextras}% \let\POL@redefineextras\@empty % -\newcommand\PolLet[2]{% +\newcommand\PolLet[2]{\if=\noexpand#2\expandafter\xint_firstoftwo + \else\expandafter\xint_secondoftwo\fi + \POL@@let\POL@let {#1}{#2}}% +\def\POL@@let#1#2#3{\POL@let{#1}{#3}}% +\def\POL@let#1#2{% \expandafter\let\csname POLuserpol@#1\expandafter\endcsname \csname POLuserpol@#2\endcsname \unless\ifcsname XINT_expr_userfuncNE:#1\endcsname\POL@addtoextras{#1}\fi \expandafter\let\csname XINT_expr_userfunc_#1\expandafter\endcsname \csname XINT_expr_userfunc_#2\endcsname + \expandafter\let\csname XINT_flexpr_userfunc_#1\expandafter\endcsname + \csname XINT_flexpr_userfunc_#2\endcsname \expandafter\XINT_expr_defuserfunc \csname XINT_expr_func_#1\expandafter\endcsname \csname XINT_expr_userfunc_#1\endcsname + \expandafter\XINT_expr_defuserfunc + \csname XINT_flexpr_func_#1\expandafter\endcsname + \csname XINT_flexpr_userfunc_#1\endcsname \ifxintverbose\POL@info{#1}\fi }% @@ -230,12 +267,12 @@ \newif\ifpoltypesetall -\newcommand\PolTypesetPlus[1]{\xintiiifSgn{#1}{}{+}{+}}% +\newcommand\PolTypesetCmdPrefix[1]{\xintiiifSgn{#1}{}{+}{+}}% \newcommand\PolTypesetCmd[1]{\xintifOne{\xintiiAbs{#1}}% {\ifnum\PolIndex=\z@\xintiiSgn{#1}\else \xintiiifSgn{#1}{-}{}{}\fi}% {\xintSignedFrac{#1}}}% -\newcommand\PolTypesetMonomial{% +\newcommand\PolTypesetMonomialCmd{% \ifcase\PolIndex\space % \or\PolVar @@ -262,12 +299,12 @@ \fi \def\PolVar{#1}% \ifnum\POL@var@deg<\z@ - \PolTypesetCmd{0/1[0]}% + \PolTypesetCmd{0/1[0]}\PolTypesetMonomialCmd \else \ifnum\POL@var@deg=\z@ - \expandafter\PolTypesetCmd\POL@var@coeffs + \expandafter\PolTypesetCmd\POL@var@coeffs\PolTypesetMonomialCmd \else - \def\POL@ts@plus##1{\let\POL@ts@plus\PolTypesetPlus}% + \def\POL@ts@prefix##1{\let\POL@ts@prefix\PolTypesetCmdPrefix}% \expandafter\POL@ts@loop \romannumeral-`0\POL@ts@reverse{\POL@var@coeffs}\relax \fi @@ -282,12 +319,12 @@ \if\relax#1\expandafter\xint_gob_til_dot\fi \xintiiifZero{#1}% {}% - {\POL@ts@plus{#1}\PolTypesetCmd{#1}\PolTypesetMonomial}% + {\POL@ts@prefix{#1}\PolTypesetCmd{#1}\PolTypesetMonomialCmd}% \edef\PolIndex{\the\numexpr\PolIndex+\POL@@ne@or@m@ne}\POL@ts@check.% }% \def\POL@ts@nocheck.#1{% \if\relax#1\expandafter\xint_gob_til_dot\fi - \POL@ts@plus{#1}\PolTypesetCmd{#1}\PolTypesetMonomial + \POL@ts@prefix{#1}\PolTypesetCmd{#1}\PolTypesetMonomialCmd \edef\PolIndex{\the\numexpr\PolIndex+\POL@@ne@or@m@ne}\POL@ts@nocheck.% }% @@ -495,7 +532,7 @@ \else\xint_afterfi{\POL@Iterate\POL@Diff@one}% \fi }% -\def\POL@Diff@no #1#2{\PolLet{#2}{#1}}% +\def\POL@Diff@no #1#2{\POL@let{#2}{#1}}% \def\POL@Diff@one #1#2{% \expandafter\expandafter\expandafter\POL@split \csname POLuserpol@#1\endcsname;\POL@var@deg\POL@var@coeffs @@ -920,11 +957,17 @@ %% EXPANDABLE MACROS \newcommand\PolEval{}% -\def\PolEval#1#2\At#3{% +\def\PolEval#1#2\At#3{\romannumeral`^^@\xinttheexpr #1(#3)\relax}% +% +\newcommand\PolEvalReduced{}% +\def\PolEvalReduced#1#2\At#3{% \romannumeral0\xintpraw % only serves to not print denominator if = 1 - {\xintIrr{\csname XINT_expr_userfunc_#1\endcsname {#3},}[0]}% + {\xintIrr{\romannumeral`^^@\xintthebareeval#1(#3)\relax}[0]}% }% % +\newcommand\PolFloatEval{}% +\def\PolFloatEval#1#2\At#3{\romannumeral`^^@\xintthefloatexpr #1(#3)\relax}% +% \newcommand\PolNthCoeff[2]{\romannumeral`^^@% \expandafter\POL@nthcoeff \romannumeral0\xintnthelt{\ifnum\numexpr#2<\z@#2\else(#2)+1\fi}% @@ -949,34 +992,119 @@ \newif\ifpoltoexprall \newcommand\PolToExprCmd[1]{\xintPRaw{\xintRawWithZeros{#1}}}% -\newcommand\PolToExprCmdWithSep[1]{\xintiiifSgn{#1}{}{+}{+}\PolToExprCmd{#1}}% -\newcommand\PolToExpr[1]{\expandafter\expandafter\expandafter - \POL@toexpr\csname POLuserpol@#1\endcsname\relax}% -% -\def\POL@toexpr#1.\empty{% - \ifnum#1<\z@ - \PolToExprCmd{0/1[0]}\expandafter\@gobbletwo +\newcommand\PolToFloatExprCmd[1]{\xintFloat{#1}}% +\let\PolToExprTermPrefix\PolTypesetCmdPrefix +\newcommand\PolToExprOneTerm[2]{% + \ifnum#2=\z@ + \PolToExprCmd{#1}% + \else + \xintifOne{\xintiiAbs{#1}} + {\xintiiifSgn{#1}{-}{}{}}% + from \PolToExprTermPrefix + {\PolToExprCmd{#1}\PolToExprTimes}% + \fi + \ifcase\xintiiAbs{#2} %<-- space here mandatory + \or\PolToExprVar + \else\PolToExprVar^\xintiiAbs{#2}% + \fi +}% +\newcommand\PolToExprOneTermStyleB[2]{% + \ifnum#2=\z@ + \xintNumerator{#1}% \else - \expandafter\POL@toexpr@a - \fi}% + \xintifOne{\xintiiAbs{\xintNumerator{#1}}} + {\xintiiifSgn{#1}{-}{}{}}% + from \PolToExprTermPrefix + {\xintNumerator{#1}\PolToExprTimes}% + \fi + \ifcase\xintiiAbs{#2} %<-- space here mandatory + \or\PolToExprVar + \else\PolToExprVar^\xintiiAbs{#2}% + \fi + \xintiiifOne{\xintDenominator{#1}}{}{/\xintDenominator{#1}}% +}% +\newcommand\PolToFloatExprOneTerm[2]{% + \ifnum#2=\z@ + \PolToFloatExprCmd{#1}% + \else + \PolToFloatExprCmd{#1}\PolToExprTimes + \fi + \ifcase\xintiiAbs{#2} %<-- space here mandatory + \or\PolToExprVar + \else\PolToExprVar^\xintiiAbs{#2}% + \fi +}% +\newcommand\PolToExprTimes{*}% +\newcommand\PolToExprVar{x}% +\newcommand\PolToExpr[1]{% + \if*\noexpand#1\expandafter\xint_firstoftwo\else + \expandafter\xint_secondoftwo\fi + \PolToExprAscending\PolToExprDescending{#1}}% +\newcommand\PolToFloatExpr[1]{% + \if*\noexpand#1\expandafter\xint_firstoftwo\else + \expandafter\xint_secondoftwo\fi + \PolToFloatExprAscending\PolToFloatExprDescending{#1}}% +\newcommand\PolToExprAscending[2]{% + \expandafter\POL@toexpr\csname POLuserpol@#2\endcsname + \PolToExprOneTerm\POL@toexprA}% +\newcommand\PolToFloatExprAscending[2]{% + \expandafter\POL@toexpr\csname POLuserpol@#2\endcsname + \PolToFloatExprOneTerm\POL@toexprA}% +\newcommand\PolToExprDescending[1]{% + \expandafter\POL@toexpr\csname POLuserpol@#1\endcsname + \PolToExprOneTerm\POL@toexprD}% +\newcommand\PolToFloatExprDescending[1]{% + \expandafter\POL@toexpr\csname POLuserpol@#1\endcsname + \PolToFloatExprOneTerm\POL@toexprD}% % -\def\POL@toexpr@a #1{\ifpoltoexprall\expandafter\POL@toexprall@b - \else\expandafter\POL@toexpr@b - \fi{#1}{}\PolToExprCmd0.}% +\def\POL@toexpr#1#2#3{\expandafter\POL@toexpr@ + \expandafter#3\expandafter#2#1\relax}% +\def\POL@toexpr@#1#2#3.{% + \ifnum#3<\z@ + #2{0/1[0]}{0}\expandafter\xint_gobble_v + \else + \expandafter#1% + \fi {#3}#2}% % +\def\POL@toexprA #1#2\empty#3{% + \ifpoltoexprall\expandafter\POL@toexprall@b + \else\expandafter\POL@toexpr@b + \fi {#3}#2{0}1.% +}% +\def\POL@toexprD #1#2#3\relax{% #3 has \empty to prevent brace removal + \expandafter\POL@toexprD@a\expandafter#2% + \the\numexpr #1\expandafter.\romannumeral0\xintrevwithbraces{#3}\relax +}% +\def\POL@toexprD@a #1#2.#3{% + \ifpoltoexprall\expandafter\POL@toexprall@b + \else\expandafter\POL@toexpr@b + \fi{#3}#1{-#2}\the\numexpr\@ne+-#2.% +}% \def\POL@toexpr@b #1#2#3{% \xintiiifZero{#1}% - {\expandafter\POL@toexpr@loop\expandafter#3}% - {#3{#1}#2\expandafter\POL@toexpr@loop\expandafter\PolToExprCmdWithSep}% - \expandafter\POL@toexpr@b\the\numexpr\@ne+% + {\expandafter\POL@toexpr@loop\expandafter\POL@toexpr@b}% + {#2{#1}{#3}% + \expandafter\POL@toexpr@loop\expandafter\POL@toexpr@c}% + \expandafter#2% +}% +\def\POL@toexpr@c #1#2#3{% + \xintiiifZero{#1}% + {}% + {\PolToExprTermPrefix{#1}#2{#1}{#3}}% + \expandafter\POL@toexpr@loop\expandafter\POL@toexpr@c + \expandafter#2% }% \def\POL@toexprall@b #1#2#3{% - #3{#1}#2% - \expandafter\POL@toexpr@loop\expandafter\PolToExprCmdWithSep - \expandafter\POL@toexprall@b\the\numexpr\@ne+% + #2{#1}{#3}% + \expandafter\POL@toexpr@loop\expandafter\POL@toexprall@c + \expandafter#2% +}% +\def\POL@toexprall@c #1#2#3{% + \PolToExprTermPrefix{#1}#2{#1}{#3}% + \expandafter\POL@toexpr@loop\expandafter\POL@toexprall@c + \expandafter#2% }% \def\POL@toexpr@loop#1#2#3.#4{% - \if\relax#4\expandafter\xint_gob_til_dot\fi #2{#4}{*x^#3}#1#3.% + \if\relax#4\expandafter\xint_gob_til_dot\fi + #1{#4}#2{#3}\the\numexpr\@ne+#3.% }% |