Next: , Previous:   [Contents][Index]

61 Package format


61.1 Introduction to format

The format package was written by Bruce R. Miller, NIST (miller-at-cam.nist.gov).

format is a package for formatting algebraic expressions in Maxima. It provides facilities for user-directed hierarchical structuring of expressions, as well as for directing simplifications to selected subexpressions. It emphasizes a semantic rather than syntactic description of the desired form. The package also provides utilities for obtaining efficiently the coefficients of polynomials, trigonometric sums and power series.

In a general purpose Computer Algebra System (CAS), any particular mathematical expression can take on a variety of forms: expanded form, factored form or anything in between. Each form may have advantages; a given form may be more compact than another, or allow clear expression of certain algorithms. Or it may simply be more informative, particularly if it has physical significance. A CAS contains many tools for transforming expressions. However, most are like Maxima’s factor and expand, operating only on the entire expression or its top level. At the other extreme are operations like substpart which extract a specific part of an expression, then transform and replace it. Unfortunately, the means of specifying the piece of interest is purely syntactic, requiring the user to keep close watch on the form of the arguments to avoid error.

The package described here gives users of Maxima more control over the structure of expressions, and it does so using a more semantic, almost algebraic, language describing the desired structure. It also provides a semantic means of addressing parts of an expression for particular simplifications. For example, to rearrange an expression into a series in eps through order 5, whose terms will be polynomials in x and y, whose coefficients, in turn, will be trigonometric sums in l and g with factored coefficients one uses the command:

format(foo; %series(eps; 5); %poly(x; y);%trig(l; g); %factor);

The principal tool, format, is described in section Functions and Variables for format. It uses procedures in coeflist which obtain coefficients of polynomials, trigonometric sums and power series.


61.2 Functions and Variables for format

Function: format (expr, template1, ...)

Each template indicates the desired form for an expression; either the expected form or that into which it will be transformed. At the same time, the indicated form implies a set of pieces; the next template in the chain applies to those pieces. For example, %poly(x) specifies the transformation into a polynomial in x, with the pieces being the coefficients. The passive %frac treats the expression as a fraction; the pieces are the numerator and denominator. Whereas the next template formats all pieces of the previous layer, positional subtemplates may be used to specify formats for each piece individually. This is most useful when the pieces have unique roles and need to be treated differently, such as a fraction’s numerator and denominator.

The full syntax of a template is

keyword (parameter ; ...)[subtemplate ; ...]

The recognized keywords are described below under Template keywords. The parameters (if not needed) and subtemplates (along with parentheses and brackets) are optional.

In addition to the keyword templates, arithmetic patterns are recognized. This is an expression involving addition, multiplication and exponentiation containing a single instance of a keyword template. In effect, the system ‘solves’ the expression to be formatted for the corresponding part, formats it accordingly and reinserts it. For example, format(X,a+%factor) is equivalent to a+factor(X-a). Any other template is assumed to be a function to be applied to the expression; the result is then formatted according to the rest of the template chain.

Examples for general restructuring:

(%i1) load("format.mac")$
(%i2) format((a+b*x)*(c-x)^2,%poly(x),factor);
                   3                2                        2
(%o2)           b x  - (2 b c - a) x  + c (b c - 2 a) x + a c
(%i3) format((1+2*eps*(q+r*cos(g))^2)^4,%series(eps,2),%trig(g),factor);
                   2      2                2
(%o3) 1 + eps (4 (r  + 2 q ) + 4 cos(2 g) r  + 16 cos(g) q r)
      2        4       2  2      4                4                  3
 + eps  (3 (3 r  + 24 q  r  + 8 q ) + 3 cos(4 g) r  + 24 cos(3 g) q r
                     2      2                 2   2      2
 + 24 cos(g) q r (3 r  + 4 q ) + 12 cos(2 g) r  (r  + 6 q )) + . . .
(%i4) format((1+2*a+a^2)*b + a*(1+2*b+b^2),%sum,%product,%factor);
                                     2          2
(%o4)                       a (b + 1)  + (a + 1)  b
(%i5) format(expand((a+x)^3-a^3),%f-a^3);
                                        3    3
(%o5)                           (x + a)  - a

61.2.1 Template keywords

Keywords come in several classes: Algebraic, Sums, Products, Fractions, Complex, Bags, General, Targeting, Control, Subtemplate Aids, and Convenience.

A few remarks about keywords: A passive keyword does not transform the expression but treats it as a sum, fraction or whatever. The order of the pieces corresponds to the internal ordering; subtemplate usage may be awkward. See the documentation of coerce_bag for a description of the coercions used. Targeting templates are basically shorthand equivalents of structuring templates using subtemplates.

Class: Algebraic
Template(w/abbrev.)Coersion toPieces and Ordering
%poly(x1,...), %ppolynomial in xicoefficients (ascending exps.)
%series(eps,n), %sseries in eps through order ncoefficients (ascending exps.)
%Taylor(eps,n)Taylor in eps through order ncoefficients (ascending exps.)
%monicpoly(x1,...),%mpmonic polynomial in xileading coef then coefs
%trig(x1,...), %ttrigonometric sum in xisin coefs (ascending), then cos
%coeff(v,n)polynomial in vcoefficient of vn and remainder

Class: Sums
Template(w/abbrev.)Coersion toPieces and Ordering
%sumpassiveterms (inpart order)
%partfrac(x), %pfpartial fraction decomp in xterms (inpart order)

Class: Products
Template(w/abbrev.)Coersion toPieces and Ordering
%product, %prodpassivefactors (inpart order)
%factor, %ffactored formfactors (inpart order)
%factor(minpoly), %ffactored with element adjoinedfactors (inpart order)
%sqfr, %sfsquare-free factored formfactors (inpart order)

Class: Fractions
Template(w/abbrev.)Coersion toPieces and Ordering
%fracpassivenumerator and denominator
%ratsimp, %rrationally simplifiednumerator and denominator

Class: Complex
Template(w/abbrev.)Coersion toPieces and Ordering
%rectform, %ggaussian formreal and imaginary parts
%polarformpolar formmagnitude and phase

Class: Bags
Template(w/abbrev.)Coersion toPieces and Ordering
%equation, %eqequationl.h.s. and r.h.s.
%relation(r), %relrelation; r in (=,>,>=,<,<=,!=)l.h.s. and r.h.s.
%listlistelements
%matrixmatrixrows (use %list for elements)

Class: General
Template(w/abbrev.)Coersion toPieces and Ordering
%expression, %exprpassivethe operands (inpart order)
%preformat(T1,...)format accord. to chain Tithe result, not the parts

Class: Targeting
Template(w/abbrev.)Function
%arg(n)formats the n-th argument
%lhs(r)formats the l.h.s. of an eqn. or relation (default ’=’)
%rhs(r)formats the l.h.s. of an eqn.
%element(i,...), %elformats an element of a matrix
%num, %denomformats the numerator or denominator of a fraction
%match(P)formats all subexpressions for which P(expr) returns true

Class: Control
Template(w/abbrev.)Function
%if(P1,...)[T1,...,Tn+1]Find first Pi(expr)true, then format expr using Ti, else Tn+1

Class: Subtemplate Aids
Template(w/abbrev.)Function
%noopdoes nothing; used to fill a subtemplate slot
[T1,T2,...]creates a template chain where an individual template was expected
%ditto(T)repeats the template so that it applies to following pices

Class: Convenience
Template(w/abbrev.)Function
%subst(eqns,...)substitutes eqns into expression; result is formatted at next layer
%ratsubst(eqns,...)lratsubst’s eqns into expression; result is formatted at next layer

Example with simplification on subexpression:

(%i1) foo:x^2*sin(y)^4-2*x^2*sin(y)^2+x^4*cos(y)^4-2*x^4*cos(y)^2+x^4+x^2+1$
(%i2) trigsimp(foo);
                     4    2     4         4    2       4
(%o2)              (x  + x ) cos (y) - 2 x  cos (y) + x  + 1
(%i3) format(foo,%p(x),trigsimp);
                                4    4       2    4
(%o3)                     x  sin (y) + x  cos (y) + 1

The following examples illustrate the usage with ‘bags.’

(%i1) format([a=b,c=d,e=f],%equation);
(%o1) [a, c, e] = [b, d, f]
(%i2) format(%,%list);
(%o2) [a = b, c = d, e = f]
(%i3) m1:matrix([a^2+2*a+1=q,b^2+2*b+1=r], [c^2+2*c+1=s,d^2+2*d+1=t])$
(%i4) format(m1,%equation,%matrix[%noop,%list[%noop,%factor]]);
                   [  2             2           ]
                   [ a  + 2 a + 1  b  + 2 b + 1 ]   [ q  r ]
(%o4)              [                            ] = [      ]
                   [  2                     2   ]   [ s  t ]
                   [ c  + 2 c + 1    (d + 1)    ]

61.2.2 User defined templates

New templates can be defined by giving the template keyword the property formatter; the value should be a function (or lambda expression) of the expression to be formatted and any parameters for the template. For example, %rectform and %if could be defined as

put(%rectform,lambda([c],block([r:rectformlist(c)],
      format-piece(r[1]) +%I* format-piece(r[2]))),formatter)

put(%if, lambda([x,test],
      if test(x) then format-piece(x,1)
        else
          format-piece(x,2)),formatter)

Functions used for defining templates are the following.

function: %format_piece (piece,nth)

lratsubst’s eqns into expression and the result is formatted at the next layer. Format a given piece of an expression, automatically accounting for subtemplates and the remaining template chain. A specific subtemplate, rather than the next one, can be selected by specifying nth.

function: %coerce_bag (op,expr)

Attempts to coerce expr into an expression with op (one of =, #, <, <=, >, >=, [ or matrix) as the top-level operator. It coerces the expression by swapping operands between layers but only if adjacent layers are also lists, matrices or relations. This model assumes that a list of equations, for example, can be viewed as an equation whose sides are lists. Certain combinations, particularly those involving inequalities may not be meaningful, however, so some caution is advised.

61.2.3 Determining coefficients

We define the ‘algebras’ of polynomials, trigonometric sums and power series to be those expressions that can be cast into the following forms.

$$ \eqalign{ {\bf P}(v_1,\cdots) &= \{P\,|\, P=\sum_i c_i v^{p_{1,i}}_1 v^{p_{2,i}}_2 \cdots\} \cr {\bf T}(v_1,\cdots) &= \{T\,|\, T=\sum_i [ c_i \cos(m_{1,i} v_1+\cdots)+s_i \sin(m'_{1,i} v_1 +\cdots)] \} \cr {\bf S}(v,O) &= \{S\,|\, S=\sum_i c_i v^{p_i};\,p_n \le O \} } $$

The variables vi may be any atomic expression in the sense of ratvars. The shorthands operator(op) and match(predicate) may be used to specify all subexpressions having op as an operator, or that pass the predicate, respectively.

The coefficients ci and si are general Maxima expressions. In principle they would be independent of the variables vi, but in practice they may contain non-polynomial dependence (or non-trigonometric, in the trigonometric case). These non-polynomial cases would include expressions like (1 + x)n, where n is symbolic. Likewise, (xa)b is, in general, multivalued; unless a = 1 or b is a member of Z, or radexpand=all, it will not be interpreted as xab is a member of P. Furthermore, we extend the algebras to include lists, vectors, matrices and equations, by interpreting a list of polynomials, say, as a polynomial with lists as coefficients.

The exponents pi in series are restricted to numbers, but the exponents cj,i and multiples mj,i for polynomials and trigonometric sums may be general expressions (excluding bags).

The following functions construct a list of the coefficients and ‘keys’, that is, the exponents or multiples. Note that these are sparse representations; no coefficients are zero.

coeffs(P,v1,...) → [[%poly,v1,...],[c1,p1,1,...],...]
trig_coeffs(T,v1,...) →
            [[%trig,v1,...],[[c1,m1,1,...],...],[[s1,m'1,1,...],...]]
series_coeffs(S,v,O) → [[%series,v,O],[c1,p1],...,[cn,pn]
Taylor_coeffs(S,v,O) → [[%Taylor,v,O],[c1,p1],...,[cn,pn]

The latter two functions both expand an expression through order O, but the series version only carries expands arithmetic operations and is often considerably faster than Taylor_coeffs.

Examples:

(%i1) cl1:coeffs((a+b*x)*(c-x)^2,x);
                       2          2
(%o1) [[%poly, x], [a c , 0], [b c  - 2 a c, 1], [a - 2 b c, 2], [b, 3]]
(%i2) map('first,rest(coeffs((a+b*x)*(c-x)^2=q0+q1*x+q2*x^2+q3*x^3,x)));
                2          2
(%o2)       [a c  = q0, b c  - 2 a c = q1, a - 2 b c = q2, b = q3]
(%i3) trig_coeffs(2*(a+cos(x))*cos(x+3*y),x,y);
(%o3)      [[%trig, x, y], [], [[1, 0, 3], [2 a, 1, 3], [1, 2, 3]]]
(%i4) series_coeffs((a+b*x)*(c-x)^2,x,2);
                              2          2
(%o4)   [[%series, x, 2], [a c , 0], [b c  - 2 a c, 1], [a - 2 b c, 2]]
(%i5)  coeffs((a+b*x)*sin(x),x);
(%o5)             [[%poly, x], [a sin(x), 0], [b sin(x), 1]]
(%i6)  coeffs((a+log(b)*x)*(c-log(x))^2,operator(log));
                                    2           2
(%o6) [[%poly, log(x), log(b)], [a c , 0, 0], [c  x, 0, 1], [- 2 a c, 1, 0], 
                                         [- 2 c x, 1, 1], [a, 2, 0], [x, 2, 1]]

61.2.5 Implementation

Original documentation is located in the share/contrib/format directory and contains an appendix describing the implementation algorithm in more detail.


Next: , Previous:   [Contents][Index]