diff options
author | Karl Berry <karl@freefriends.org> | 2018-01-15 22:20:09 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2018-01-15 22:20:09 +0000 |
commit | 7a4b66cc343bf7b3c01817fc4b5b0ed1934249d9 (patch) | |
tree | 25929c8dd99ea7a16a6da211b688e85af50259e8 | |
parent | 1cffeb47b775226f1d947b95055f86daac06c88a (diff) |
polexpr (15jan18)
git-svn-id: svn://tug.org/texlive/trunk@46318 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r-- | Master/texmf-dist/doc/latex/polexpr/README | 373 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/polexpr/README.md | 67 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/polexpr/polexpr.html | 730 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/polexpr/polexpr.txt | 394 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/polexpr/polexpr.sty | 9 |
5 files changed, 1197 insertions, 376 deletions
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 <name>(x):=<expression in variable 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 + +> <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-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 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> +<meta name="generator" content="Docutils 0.14: http://docutils.sourceforge.net/" /> +<title>Package polexpr documentation</title> +<style type="text/css"> +body{font-size: 14pt;} +/* +:Author: David Goodger (goodger@python.org) +:Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $ +:Copyright: This stylesheet has been placed in the public domain. + +Default cascading style sheet for the HTML output of Docutils. + +See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to +customize this style sheet. +*/ + +/* used to remove borders from tables and images */ +.borderless, table.borderless td, table.borderless th { + border: 0 } + +table.borderless td, table.borderless th { + /* Override padding for "table.docutils td" with "! important". + The right padding separates the table cells. */ + padding: 0 0.5em 0 0 ! important } + +.first { + /* Override more specific margin styles with "! important". */ + margin-top: 0 ! important } + +.last, .with-subtitle { + margin-bottom: 0 ! important } + +.hidden { + display: none } + +.subscript { + vertical-align: sub; + font-size: smaller } + +.superscript { + vertical-align: super; + font-size: smaller } + +a.toc-backref { + text-decoration: none ; + color: black } + +blockquote.epigraph { + margin: 2em 5em ; } + +dl.docutils dd { + margin-bottom: 0.5em } + +object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { + overflow: hidden; +} + +/* Uncomment (and remove this text!) to get bold-faced definition list terms +dl.docutils dt { + font-weight: bold } +*/ + +div.abstract { + margin: 2em 5em } + +div.abstract p.topic-title { + font-weight: bold ; + text-align: center } + +div.admonition, div.attention, div.caution, div.danger, div.error, +div.hint, div.important, div.note, div.tip, div.warning { + margin: 2em ; + border: medium outset ; + padding: 1em } + +div.admonition p.admonition-title, div.hint p.admonition-title, +div.important p.admonition-title, div.note p.admonition-title, +div.tip p.admonition-title { + font-weight: bold ; + font-family: sans-serif } + +div.attention p.admonition-title, div.caution p.admonition-title, +div.danger p.admonition-title, div.error p.admonition-title, +div.warning p.admonition-title, .code .error { + color: red ; + font-weight: bold ; + font-family: sans-serif } + +/* Uncomment (and remove this text!) to get reduced vertical space in + compound paragraphs. +div.compound .compound-first, div.compound .compound-middle { + margin-bottom: 0.5em } + +div.compound .compound-last, div.compound .compound-middle { + margin-top: 0.5em } +*/ + +div.dedication { + margin: 2em 5em ; + text-align: center ; + font-style: italic } + +div.dedication p.topic-title { + font-weight: bold ; + font-style: normal } + +div.figure { + margin-left: 2em ; + margin-right: 2em } + +div.footer, div.header { + clear: both; + font-size: smaller } + +div.line-block { + display: block ; + margin-top: 1em ; + margin-bottom: 1em } + +div.line-block div.line-block { + margin-top: 0 ; + margin-bottom: 0 ; + margin-left: 1.5em } + +div.sidebar { + margin: 0 0 0.5em 1em ; + border: medium outset ; + padding: 1em ; + background-color: #ffffee ; + width: 40% ; + float: right ; + clear: right } + +div.sidebar p.rubric { + font-family: sans-serif ; + font-size: medium } + +div.system-messages { + margin: 5em } + +div.system-messages h1 { + color: red } + +div.system-message { + border: medium outset ; + padding: 1em } + +div.system-message p.system-message-title { + color: red ; + font-weight: bold } + +div.topic { + margin: 2em } + +h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, +h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { + margin-top: 0.4em } + +h1.title { + text-align: center } + +h2.subtitle { + text-align: center } + +hr.docutils { + width: 75% } + +img.align-left, .figure.align-left, object.align-left, table.align-left { + clear: left ; + float: left ; + margin-right: 1em } + +img.align-right, .figure.align-right, object.align-right, table.align-right { + clear: right ; + float: right ; + margin-left: 1em } + +img.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left } + +.align-center { + clear: both ; + text-align: center } + +.align-right { + text-align: right } + +/* reset inner alignment in figures */ +div.align-right { + text-align: inherit } + +/* div.align-center * { */ +/* text-align: left } */ + +.align-top { + vertical-align: top } + +.align-middle { + vertical-align: middle } + +.align-bottom { + vertical-align: bottom } + +ol.simple, ul.simple { + margin-bottom: 1em } + +ol.arabic { + list-style: decimal } + +ol.loweralpha { + list-style: lower-alpha } + +ol.upperalpha { + list-style: upper-alpha } + +ol.lowerroman { + list-style: lower-roman } + +ol.upperroman { + list-style: upper-roman } + +p.attribution { + text-align: right ; + margin-left: 50% } + +p.caption { + font-style: italic } + +p.credits { + font-style: italic ; + font-size: smaller } + +p.label { + white-space: nowrap } + +p.rubric { + font-weight: bold ; + font-size: larger ; + color: maroon ; + text-align: center } + +p.sidebar-title { + font-family: sans-serif ; + font-weight: bold ; + font-size: larger } + +p.sidebar-subtitle { + font-family: sans-serif ; + font-weight: bold } + +p.topic-title { + font-weight: bold } + +pre.address { + margin-bottom: 0 ; + margin-top: 0 ; + font: inherit } + +pre.literal-block, pre.doctest-block, pre.math, pre.code { + margin-left: 2em ; + margin-right: 2em } + +pre.code .ln { color: grey; } /* line numbers */ +pre.code, code { background-color: #eeeeee } +pre.code .comment, code .comment { color: #5C6576 } +pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold } +pre.code .literal.string, code .literal.string { color: #0C5404 } +pre.code .name.builtin, code .name.builtin { color: #352B84 } +pre.code .deleted, code .deleted { background-color: #DEB0A1} +pre.code .inserted, code .inserted { background-color: #A3D289} + +span.classifier { + font-family: sans-serif ; + font-style: oblique } + +span.classifier-delimiter { + font-family: sans-serif ; + font-weight: bold } + +span.interpreted { + font-family: sans-serif } + +span.option { + white-space: nowrap } + +span.pre { + white-space: pre } + +span.problematic { + color: red } + +span.section-subtitle { + /* font-size relative to parent (h1..h6 element) */ + font-size: 80% } + +table.citation { + border-left: solid 1px gray; + margin-left: 1px } + +table.docinfo { + margin: 2em 4em } + +table.docutils { + margin-top: 0.5em ; + margin-bottom: 0.5em } + +table.footnote { + border-left: solid 1px black; + margin-left: 1px } + +table.docutils td, table.docutils th, +table.docinfo td, table.docinfo th { + padding-left: 0.5em ; + padding-right: 0.5em ; + vertical-align: top } + +table.docutils th.field-name, table.docinfo th.docinfo-name { + font-weight: bold ; + text-align: left ; + white-space: nowrap ; + padding-left: 0 } + +/* "booktabs" style (no vertical lines) */ +table.docutils.booktabs { + border: 0px; + border-top: 2px solid; + border-bottom: 2px solid; + border-collapse: collapse; +} +table.docutils.booktabs * { + border: 0px; +} +table.docutils.booktabs th { + border-bottom: thin solid; + text-align: left; +} + +h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, +h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { + font-size: 100% } + +ul.auto-toc { + list-style-type: none } + +</style> +</head> +<body> +<div class="document" id="package-polexpr-documentation"> +<h1 class="title">Package polexpr documentation</h1> + +<!-- comment: -*- fill-column: 72; mode: rst; -*- --> +<div class="section" id="first-examples"> +<h1>First Examples</h1> +<p>The syntax is:</p> +<pre class="literal-block"> +\poldef <name>(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 +under Unicode engines.) One can also issue:</p> +<pre class="literal-block"> +\PolDef{name}{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> +<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">\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> +<dd>again redefines <tt class="docutils literal">f</tt> in terms of its (new) self.</dd> +<dt><tt class="docutils literal">\poldef <span class="pre">k(z):=</span> <span class="pre">f(z)-g(g(z)^2)^2;</span></tt></dt> +<dd>should now define the zero polynomial... Let's check: +<tt class="docutils literal">\[ k(z) = <span class="pre">\PolTypeset[z]{k}</span> \]</tt></dd> +<dt><tt class="docutils literal"><span class="pre">\PolDiff{f}{df_dx}</span></tt></dt> +<dd>sets <tt class="docutils literal">df_dx</tt> to the derivative of <tt class="docutils literal">f</tt>.</dd> +<dt><tt class="docutils literal"><span class="pre">\PolDiff{df_dx}{f_xx}</span></tt></dt> +<dd>obtains second derivative.</dd> +<dt><tt class="docutils literal"><span class="pre">\PolDiff[3]{f}{d3f_dx3}</span></tt></dt> +<dd>computes directly the third derivative. Its name does not have to be +chosen so complicated <tt class="docutils literal">:)</tt>, but the right quote <tt class="docutils literal">'</tt> is not +allowed in polynomial names (currently).</dd> +</dl> +<pre class="literal-block"> +$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 +</pre> +<div class="admonition important"> +<p class="first admonition-title">Important</p> +<p>The package does not currently know rational functions: <tt class="docutils literal">/</tt> in +a parsed polynomial expression does the Euclidean quotient:</p> +<pre class="literal-block"> +(1-x^2)/(1-x) +</pre> +<p>does give <tt class="docutils literal">1+x</tt> but</p> +<pre class="literal-block"> +(1/(1-x))*(1-x^2) +</pre> +<p>evaluates to zero. This will work as expected:</p> +<pre class="last literal-block"> +\poldef k(x):= (x-1)(x-2)(x-3)(x-4)/(x^2-5x+4); +</pre> +</div> +<div class="admonition attention"> +<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> +</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);% +</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> +<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> +</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 +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 +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 +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 +to the (raw) #1th polynomial coefficient.</p> +<ul class="last 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=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 +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 +to a coefficient. Leading zero coefficients are removed from the +polynomial.</p> +<p>(contrived) Example:</p> +<pre class="literal-block"> +\xintAssignArray{1}{-2}{5}{-3}\to\foo +\PolGet{f}\fromarray\foo +</pre> +<p 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>. +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> +<p>Leading zero coefficients are removed:</p> +<pre class="literal-block"> +\PolFromCSV{J}{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 +this can be changed via an optional argument:</p> +<pre class="literal-block"> +\PolTypeset[z]{name} +</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 +(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 +(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> +<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 +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 +<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> +</div> +<div class="section" id="expandable-macros"> +<h1>Expandable macros</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"> +<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> +</tbody> +</table> +<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="#id2">[2]</a></td><td>the letter <tt class="docutils literal">x</tt> is (in this release) not customizable.</td></tr> +</tbody> +</table> +<p>By default zero coefficients are skipped (issue <tt class="docutils literal">\poltoexprtrue</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 +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> +</div> +<div class="section" id="technicalities"> +<h1>Technicalities</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> +<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 +<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 +to big denominators.</p> +<p>It is probable that this convention will be backported as default +behaviour of xintfrac's <tt class="docutils literal">\xintAdd</tt> in a future xint release. When this +change is merged, there will be an impact on coefficients computed by +<tt class="docutils literal">\poldef</tt> 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.</p> +</li> +<li><p class="first">As a consequence of previous rule, user-chosen common denominators +survive addition and multiplications:</p> +<pre class="literal-block"> +\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); +</pre> +<p>gives the polynomial:</p> +<pre class="literal-block"> +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 +</pre> +<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> +<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> +<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> +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> +<li><p class="first">As is to be expected internal structures of the package are barely +documented and unstable. Don't use them.</p> +</li> +</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> +</ul> +<p>Files of 0.2 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> +</div> +</div> +</body> +</html> 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 <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) + + __ 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 |