From 7a4b66cc343bf7b3c01817fc4b5b0ed1934249d9 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Mon, 15 Jan 2018 22:20:09 +0000 Subject: polexpr (15jan18) git-svn-id: svn://tug.org/texlive/trunk@46318 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/latex/polexpr/README | 373 ------------ Master/texmf-dist/doc/latex/polexpr/README.md | 67 +++ Master/texmf-dist/doc/latex/polexpr/polexpr.html | 730 +++++++++++++++++++++++ Master/texmf-dist/doc/latex/polexpr/polexpr.txt | 394 ++++++++++++ Master/texmf-dist/tex/latex/polexpr/polexpr.sty | 9 +- 5 files changed, 1197 insertions(+), 376 deletions(-) delete mode 100644 Master/texmf-dist/doc/latex/polexpr/README create mode 100644 Master/texmf-dist/doc/latex/polexpr/README.md create mode 100644 Master/texmf-dist/doc/latex/polexpr/polexpr.html create mode 100644 Master/texmf-dist/doc/latex/polexpr/polexpr.txt diff --git a/Master/texmf-dist/doc/latex/polexpr/README b/Master/texmf-dist/doc/latex/polexpr/README deleted file mode 100644 index a258011f9dd..00000000000 --- a/Master/texmf-dist/doc/latex/polexpr/README +++ /dev/null @@ -1,373 +0,0 @@ --*- fill-column: 72; mode: text; -*- - -Package polexpr -=============== - -License -------- - -Copyright (C) 2018 Jean-Francois Burnol - -See documentation of package xint for contact information. - -This Work may be distributed and/or modified under the -conditions of the LaTeX Project Public License version 1.3c. -This version of this license is in - - http://www.latex-project.org/lppl/lppl-1-3c.txt - -and version 1.3 or later is part of all distributions of -LaTeX version 2005/12/01 or later. - -This Work has the LPPL maintenance status author-maintained. - -The Author of this Work is Jean-Francois Burnol. - -This Work consists of the package file polexpr.sty and this README. - - -Abstract --------- - -The package provides "\poldef": a parser of polynomial expressions -based upon the "\xintdeffunc" mechanism of package xintexpr. - -The syntax is - - \poldef (x):=; - -where in place of "x" an arbitrary letter is authorized. The expression -uses the operations of algebra (including composition of functions) with -standard operators, fractional numbers (possibly in scientific notation) -and previously defined polynomial functions or other constructs as -recognized by the \xintexpr numerical parser. - -The so-defined name() \xintexpr-function is also known to the package -via its polynomial coefficients, thus allowing dedicated macros to -implement polynomial algorithmics. - -Examples --------- - -\poldef f(x):= 1-x+x^2; - -This 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 than x in the expression, one must pass it as -an extra optional 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". - -\poldef f(z):= f(z)^2; redefines "f" in terms of itself. - -\poldef f(T):= f(f(T)); again redefines "f" in terms of its (new) self. - -\poldef k(z):= f(z)-g(g(z)^2)^2; should now define the zero -polynomial... Let's check: -\[ k(z) = \PolTypeset[z]{k} \] - -\PolDiff{f}{df_dx} sets "df_dx" to the derivative of "f". - -\PolDiff{df_dx}{f_xx} obtains second derivative - -\PolDiff[3]{f}{d3f_dx3} computes directly the third derivative - -$f(z) = \PolTypeset[z]{f} $\newline -$f'(z) = \PolTypeset[z]{df_dx}$\newline -$f''(z) = \PolTypeset[z]{f_xx}$\newline -$f'''(z)= \PolTypeset[z]{d3f_dx3}$\par - -*Important*: the package does not currently know rational functions. -and "/" in a parsed polynomial expression does the Euclidean quotient: - - (1-x^2)/(1-x) does give 1+x but (1/(1-x))*(1-x^2) evaluates to zero. - -*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. - -\poldef k(x):= (x-1)(x-2)(x-3)(x-4)/(x^2-5x+4);% - -\PolTypeset{k} gives the expected x^2-5x+6 - -\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);% - -\PolGCD{f1}{f2}{k} sets "k" to the (unitary) GCD of "f1" and "f2". - -\PolToExpr{k} expandably gives 2-2*x^1-1*x^2+1*x^3 for console -or file output (this is Maple-compatible input syntax). - -Non-expandable macros ---------------------- - -\poldef name(letter):= polynomial expression using 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 letter and are constituted of letters, - digits and underscore characters. See Examples above. - - 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. - - 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. - -\PolLet{g}{f} - Makes a copy of already defined polynomial f to new one g. - Same effect as \PolDef{g}{f(x)} but faster. - -\PolAssign{f}\toarray\Array - Defines a one-argument expandable macro \Array{#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=0, returns the number of coefficients, i.e. 1+degree(f) - for non-zero polynomials. - - - Out-of-range #1's return 0/1[0]. - -\PolGet{f}\fromarray\Array - Does the reverse operation to \PolAssign{f}\toarray\Array. No error - checks on validity of coefficients as numbers. Each \Array{index} - is expanded in an \edef before being assigned to a coefficient. - Leading zero coefficients are removed from the polynomial. - - (contrived) Example: \xintAssignArray{1}{-2}{5}{-3}\to\foo - \PolGet{f}\fromarray\foo - This will define "f" as would have \poldef f(x):=1-2x+5x^2-3x^3; - 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 they are 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} defines the zero - polynomial, which has only one (zero) coefficient. - - See also expandable macro \PolToCSV. - -\PolTypeset[x]{name} - Typesets in descending powers in math mode using the specified - variable (default x.) 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. - -\PolTypeset*[x]{name} - Typesets in ascending powers. - -\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'. - - Coefficients of the result f2 are irreducible fractions - (see `Technicalities`_ for the whole story.) - -\PolDiff[N]{f1}{f2} - This sets f2 to the Nth derivative of f1. Identical arguments - is allowed. With N=0, same effect as \PolLet{f2}{f1}. - With negative N, switched to using \PolAntiDiff. - -\PolAntiDiff{f1}{f2} - This sets f2 to the primitive of f1 vanishing at zero. - - Coefficients of the result f2 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. - -\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{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. - -\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). - - Notice that \macro will have to handle inputs of the shape 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^2\relax}} - to replace nth 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.) - -Expandable macros ------------------ - -All these macros expand completely in two steps except \PolToExpr -which needs a \write, \edef or a \csname...\endcsname context. - -\PolEval{name}\At{value} - It boils down to \xinttheexpr reduce(name(value))\relax. - -\PolNthCoeff{name}{N} - It expands to the raw Nth coefficient (0/1[0] if index is out of - range). With N=-1, -2, ... expands to the leading coefficients. - -\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] - - [1] in a \write, \edef, or \csname...\endcsname, but not under - \romannumeral-`0 - - [2] the letter x is (in this release) not customizable. - - By default zero coefficients are skipped (issue \poltoexprtrue 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. - - 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. - - \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. - -\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.) - -\PolToCSV{f} - Expands to f_0, f_1, f_2, ....., f_N. Converse of \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. - -- 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 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 to big denominators. - - It is probable that this convention will be backported as default - behaviour of xintfrac's \xintAdd in a future xint release. When this - change is merged, there will be an impact on coefficients computed by - \poldef because the change will apply even to the pure numerical - evaluations arising during the initial stage of the parsing. Of course - the coefficients are still the same rational numbers, only - representation as fractions may change. - -- As a consequence of previous rule, user-chosen common denominators - survive addition and multiplications: - - \poldef P(x):= 1/2 + 2/2*x + 3/2*x^3 + 4/2*x^4; - \poldef Q(x):= 1/3 + (2/3)x + (3/3)x^3 + (4/3)x^4; - \poldef PQ(x):= P(x)*Q(x); - - gives the polynomial - - 1/6+4/6*x^1+4/6*x^2+6/6*x^3+20/6*x^4+16/6*x^5+9/6*x^6+24/6*x^7+16/6*x^8 - - where all coefficients have the same denominator 6 (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 "decimal" 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. - -- If f was created from comma separated values by macro \PolFromCSV, - then the exact same coefficients (except those zero coefficients - beyond the leading monomial) will be in the output of \PolToList and - \PolToCSV in their original input form: 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. 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. - -- As is to be expected internal structures of the package are barely - documented and unstable. Don't use them. - - -CHANGE LOG ----------- - -- v0.1 (2018/01/11): initial release. Features: - - *. differentiation and anti-differentiation, - *. Euclidean division and GCDs, - *. various utilities such as \PolFromCSV, \PolToCSV, \PolToExpr. - - Only one-variable polynomials so far. - - Due to lack of available time I have not really yet set-up a - sufficient enough test suite. Bug reports very welcome! diff --git a/Master/texmf-dist/doc/latex/polexpr/README.md b/Master/texmf-dist/doc/latex/polexpr/README.md new file mode 100644 index 00000000000..f5b45b5d23d --- /dev/null +++ b/Master/texmf-dist/doc/latex/polexpr/README.md @@ -0,0 +1,67 @@ +Package polexpr README +====================== + +License +------- + +Copyright (C) 2018 Jean-François Burnol + +See documentation of package [xint](http://www.ctan.org/pkg/xint) for +contact information. + +This Work may be distributed and/or modified under the conditions of the +LaTeX Project Public License version 1.3c. This version of this license +is in + +> + +and version 1.3 or later is part of all distributions of LaTeX version +2005/12/01 or later. + +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. + +Abstract +-------- + +The package provides `\poldef`. This a parser of polynomial expressions +based upon the `\xintdeffunc` mechanism of xintexpr. + +The parsed expressions use the operations of algebra (inclusive of +composition of functions) with standard operators, fractional numbers +(possibly in scientific notation) and previously defined polynomial +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. + +CHANGE LOG +---------- + +- v0.1 (2018/01/11): initial release. Features: + - The `\poldef` parser itself, + - Differentiation and anti-differentiation, + - Euclidean division and GCDs, + - 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. + - Move main documentation from README to separate `polexpr.txt` + file. + - Provide `polexpr.html` as obtained via + [DocUtils](http://docutils.sourceforge.net/docs/index.html) + `rst2html.py`. + - Convert README to (CTAN compatible) Markdown markup. + Due to lack of available time the test suite might not be extensive + enough. Bug reports are very welcome! + diff --git a/Master/texmf-dist/doc/latex/polexpr/polexpr.html b/Master/texmf-dist/doc/latex/polexpr/polexpr.html new file mode 100644 index 00000000000..d5f3237a0b2 --- /dev/null +++ b/Master/texmf-dist/doc/latex/polexpr/polexpr.html @@ -0,0 +1,730 @@ + + + + + + +Package polexpr documentation + + + +
+

Package polexpr documentation

+ + +
+

First Examples

+

The syntax is:

+
+\poldef <name>(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 +under Unicode engines.) One can also issue:

+
+\PolDef{name}{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.
+
\PolDef{f}{1-x+x^2}
+
does the same as \poldef f(x):= 1-x+x^2; To use another letter +than x in the expression, one must pass it as an extra optional +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.
+
\poldef f(z):= f(z)^2;
+
redefines f in terms of itself.
+
\poldef f(T):= f(f(T));
+
again redefines f in terms of its (new) self.
+
\poldef k(z):= f(z)-g(g(z)^2)^2;
+
should now define the zero polynomial... Let's check: +\[ k(z) = \PolTypeset[z]{k} \]
+
\PolDiff{f}{df_dx}
+
sets df_dx to the derivative of f.
+
\PolDiff{df_dx}{f_xx}
+
obtains second derivative.
+
\PolDiff[3]{f}{d3f_dx3}
+
computes directly the third derivative. Its name does not have to be +chosen so complicated :), but the right quote ' is not +allowed in polynomial names (currently).
+
+
+$f(z)   = \PolTypeset[z]{f}    $\newline
+$f'(z)  = \PolTypeset[z]{df_dx}$\newline
+$f''(z) = \PolTypeset[z]{f_xx}$\newline
+$f'''(z)= \PolTypeset[z]{d3f_dx3}$\par
+
+
+

Important

+

The package does not currently know rational functions: / in +a parsed polynomial expression does the Euclidean quotient:

+
+(1-x^2)/(1-x)
+
+

does give 1+x but

+
+(1/(1-x))*(1-x^2)
+
+

evaluates to zero. This will work as expected:

+
+\poldef k(x):= (x-1)(x-2)(x-3)(x-4)/(x^2-5x+4);
+
+
+
+

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...

+
+

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);%
+
+

the macro call \PolGCD{f1}{f2}{k} sets k to the (unitary) GCD of +f1 and f2.

+
+
\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.)
+
+
+
+

Non-expandable macros

+
+
\poldef name(letter):= polynomial expression using 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 +letter and are constituted of letters, digits and underscore +characters. See Examples above.

+

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.

+

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)}.
+
\PolLet{g}{f}
+
Makes a copy of already defined polynomial f to new one g. Same +effect as \PolDef{g}{f(x)} but faster.
+
\PolAssign{f}\toarray\Array
+

Defines a one-argument expandable macro \Array{#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=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 +error checks on validity of coefficients as numbers. Each +\Array{index} is expanded in an \edef before being assigned +to a coefficient. Leading zero coefficients are removed from the +polynomial.

+

(contrived) Example:

+
+\xintAssignArray{1}{-2}{5}{-3}\to\foo
+\PolGet{f}\fromarray\foo
+
+

This will define f as would have \poldef f(x):=1-2x+5x^2-3x^3;. +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).

+

Leading zero coefficients are removed:

+
+\PolFromCSV{J}{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.

+
+
\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}
+
+

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.

+
+
\PolTypeset*{name}
+
Typesets in ascending powers. Change the letter from its default +x by optional argument.
+
\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'.

+

Coefficients of the result f2 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.
+
\PolAntiDiff{f1}{f2}
+

This sets f2 to the primitive of f1 vanishing at zero.

+

Coefficients of the result f2 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.
+
\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{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.
+
\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).

+

Notice that \macro will have to handle inputs of the shape +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 +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.)
+
+
+
+

Expandable macros

+

All these macros expand completely in two steps except \PolToExpr +which needs a \write, \edef or a \csname...\endcsname context.

+
+
\PolEval{name}\At{value}
+
It boils down to \xinttheexpr reduce(name(value))\relax.
+
\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.
+
\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]

+ + + + + +
[1]in a \write, \edef, or \csname...\endcsname, but +not under \romannumeral-`0.
+ + + + + +
[2]the letter x is (in this release) not customizable.
+

By default zero coefficients are skipped (issue \poltoexprtrue 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.

+

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.

+

\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.

+
+
\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.)
+
\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.

    +
  • +
  • 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 +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 +to big denominators.

    +

    It is probable that this convention will be backported as default +behaviour of xintfrac's \xintAdd in a future xint release. When this +change is merged, there will be an impact on coefficients computed by +\poldef because the change will apply even to the pure numerical +evaluations arising during the initial stage of the parsing. Of course +the coefficients are still the same rational numbers, only +representation as fractions may change.

    +
  • +
  • As a consequence of previous rule, user-chosen common denominators +survive addition and multiplications:

    +
    +\poldef P(x):= 1/2 + 2/2*x + 3/2*x^3 + 4/2*x^4;
    +\poldef Q(x):= 1/3 + (2/3)x + (3/3)x^3 + (4/3)x^4;
    +\poldef PQ(x):= P(x)Q(x);
    +
    +

    gives the polynomial:

    +
    +1/6+4/6*x^1+4/6*x^2+6/6*x^3+20/6*x^4+16/6*x^5+9/6*x^6+24/6*x^7+16/6*x^8
    +
    +

    where all coefficients have the same denominator 6 (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.

    +

    Same remark for \PolAntiDiff.

    +
  • +
  • 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. +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.

    +
  • +
  • As is to be expected internal structures of the package are barely +documented and unstable. Don't use them.

    +
  • +
+
+
+

RELEASES

+
    +
  • 0.1 (2018/01/11): initial release (files README, polexpr.sty).
  • +
  • 0.2 (2018/01/14): documentation moved to polexpr.{txt,html}.
  • +
+

Files of 0.2 release:

+
    +
  • README.md,
  • +
  • polexpr.sty (package file),
  • +
  • polexpr.txt (documentation),
  • +
  • polexpr.html (conversion via DocUtils rst2html.py)
  • +
+

See README.md for the License and the change log.

+
+
+ + diff --git a/Master/texmf-dist/doc/latex/polexpr/polexpr.txt b/Master/texmf-dist/doc/latex/polexpr/polexpr.txt new file mode 100644 index 00000000000..19d5ccdf9c9 --- /dev/null +++ b/Master/texmf-dist/doc/latex/polexpr/polexpr.txt @@ -0,0 +1,394 @@ +.. comment: -*- fill-column: 72; mode: rst; -*- + +Package polexpr documentation +============================= + +First Examples +-------------- + +The syntax is:: + + \poldef (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 +under Unicode engines.) One can also issue:: + + \PolDef{name}{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. + +``\PolDef{f}{1-x+x^2}`` + does the same as ``\poldef f(x):= 1-x+x^2;`` To use another letter + than ``x`` in the expression, one must pass it as an extra optional + 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``. + +``\poldef f(z):= f(z)^2;`` + redefines ``f`` in terms of itself. + +``\poldef f(T):= f(f(T));`` + again redefines ``f`` in terms of its (new) self. + +``\poldef k(z):= f(z)-g(g(z)^2)^2;`` + should now define the zero polynomial... Let's check: + ``\[ k(z) = \PolTypeset[z]{k} \]`` + +``\PolDiff{f}{df_dx}`` + sets ``df_dx`` to the derivative of ``f``. + +``\PolDiff{df_dx}{f_xx}`` + obtains second derivative. + +``\PolDiff[3]{f}{d3f_dx3}`` + computes directly the third derivative. Its name does not have to be + chosen so complicated ``:)``, but the right quote ``'`` is not + allowed in polynomial names (currently). + +:: + + $f(z) = \PolTypeset[z]{f} $\newline + $f'(z) = \PolTypeset[z]{df_dx}$\newline + $f''(z) = \PolTypeset[z]{f_xx}$\newline + $f'''(z)= \PolTypeset[z]{d3f_dx3}$\par + +.. important:: + + The package does not currently know rational functions: ``/`` in + a parsed polynomial expression does the Euclidean quotient:: + + (1-x^2)/(1-x) + + does give ``1+x`` but :: + + (1/(1-x))*(1-x^2) + + evaluates to zero. This will work as expected:: + + \poldef k(x):= (x-1)(x-2)(x-3)(x-4)/(x^2-5x+4); + +.. 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...`` + +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);% + +the macro call ``\PolGCD{f1}{f2}{k}`` sets ``k`` to the (unitary) GCD of +``f1`` and ``f2``. + +``\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.) + +Non-expandable macros +--------------------- + +``\poldef name(letter):= polynomial expression using 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 + letter and are constituted of letters, digits and underscore + characters. See Examples above. + + 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. + + 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)}``. + +``\PolLet{g}{f}`` + Makes a copy of already defined polynomial f to new one g. Same + effect as ``\PolDef{g}{f(x)}`` but faster. + +``\PolAssign{f}\toarray\Array`` + Defines a one-argument expandable macro ``\Array{#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=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 + error checks on validity of coefficients as numbers. Each + ``\Array{index}`` is expanded in an ``\edef`` before being assigned + to a coefficient. Leading zero coefficients are removed from the + polynomial. + + (contrived) Example:: + + \xintAssignArray{1}{-2}{5}{-3}\to\foo + \PolGet{f}\fromarray\foo + + This will define ``f`` as would have ``\poldef f(x):=1-2x+5x^2-3x^3;``. + 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). + + Leading zero coefficients are removed:: + + \PolFromCSV{J}{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``. + +``\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} + + 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. + +``\PolTypeset*{name}`` + Typesets in ascending powers. Change the letter from its default + ``x`` by optional argument. + +``\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'``. + + Coefficients of the result ``f2`` 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``. + +``\PolAntiDiff{f1}{f2}`` + This sets ``f2`` to the primitive of ``f1`` vanishing at zero. + + Coefficients of the result ``f2`` 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``. + +``\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{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. + +``\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). + + Notice that ``\macro`` will have to handle inputs of the shape + ``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 + ``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.) + +Expandable macros +----------------- + +All these macros expand completely in two steps except ``\PolToExpr`` +which needs a ``\write``, ``\edef`` or a ``\csname...\endcsname`` context. + +``\PolEval{name}\At{value}`` + It boils down to ``\xinttheexpr reduce(name(value))\relax``. + +``\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. + +``\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]_ + + .. [1] in a ``\write``, ``\edef``, or ``\csname...\endcsname``, but + not under ``\romannumeral-`0``. + + .. [2] the letter ``x`` is (in this release) not customizable. + + By default zero coefficients are skipped (issue ``\poltoexprtrue`` 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. + + 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. + + ``\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. + +``\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.) + +``\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``. + +- 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 + ``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 + to big denominators. + + It is probable that this convention will be backported as default + behaviour of xintfrac's ``\xintAdd`` in a future xint release. When this + change is merged, there will be an impact on coefficients computed by + ``\poldef`` because the change will apply even to the pure numerical + evaluations arising during the initial stage of the parsing. Of course + the coefficients are still the same rational numbers, only + representation as fractions may change. + +- As a consequence of previous rule, user-chosen common denominators + survive addition and multiplications:: + + \poldef P(x):= 1/2 + 2/2*x + 3/2*x^3 + 4/2*x^4; + \poldef Q(x):= 1/3 + (2/3)x + (3/3)x^3 + (4/3)x^4; + \poldef PQ(x):= P(x)Q(x); + + gives the polynomial:: + + 1/6+4/6*x^1+4/6*x^2+6/6*x^3+20/6*x^4+16/6*x^5+9/6*x^6+24/6*x^7+16/6*x^8 + + where all coefficients have the same denominator 6 (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. + + Same remark for ``\PolAntiDiff``. + +- 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.`` + 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. + +- As is to be expected internal structures of the package are barely + documented and unstable. Don't use them. + +RELEASES +-------- + +- 0.1 (2018/01/11): initial release (files README, polexpr.sty). +- 0.2 (2018/01/14): documentation moved to polexpr.{txt,html}. + +Files of 0.2 release: + +- README.md, +- polexpr.sty (package file), +- polexpr.txt (documentation), +- polexpr.html (conversion via `DocUtils`__ rst2html.py) + + __ http://docutils.sourceforge.net/docs/index.html + +See README.md for the License and the change log. diff --git a/Master/texmf-dist/tex/latex/polexpr/polexpr.sty b/Master/texmf-dist/tex/latex/polexpr/polexpr.sty index 983016987ea..9f2bd0c0ea5 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/11 v0.1 Polynomial expressions with rational coefficients (JFB)]% + [2018/01/14 v0.2 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}% @@ -572,7 +572,7 @@ %% CORE ALGEBRA MACROS %% We do this non-expandably, but in a nestable way... this is the whole -%% point because \xintdeffunc as used by \PolNewPol creates a big nested macro. +%% point because \xintdeffunc as used by \poldef creates a big nested macro. %% The idea is to execute it with another meaning given to \xintAdd etc.., %% so that it operates on "polynomials". This is a mixture of expandable %% and non-expandable techniques. @@ -920,7 +920,10 @@ %% EXPANDABLE MACROS \newcommand\PolEval{}% -\def\PolEval#1#2\At#3{\romannumeral`^^@\xinttheexpr reduce(#1(#3))\relax}% +\def\PolEval#1#2\At#3{% + \romannumeral0\xintpraw % only serves to not print denominator if = 1 + {\xintIrr{\csname XINT_expr_userfunc_#1\endcsname {#3},}[0]}% +}% % \newcommand\PolNthCoeff[2]{\romannumeral`^^@% \expandafter\POL@nthcoeff -- cgit v1.2.3