Next: Package fractals, Previous: Package finance [Contents][Index]
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.
Previous: Introduction to format [Contents][Index]
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
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 to | Pieces and Ordering |
---|---|---|
%poly(x1,...), %p | polynomial in xi | coefficients (ascending exps.) |
%series(eps,n), %s | series in eps through order n | coefficients (ascending exps.) |
%Taylor(eps,n) | Taylor in eps through order n | coefficients (ascending exps.) |
%monicpoly(x1,...),%mp | monic polynomial in xi | leading coef then coefs |
%trig(x1,...), %t | trigonometric sum in xi | sin coefs (ascending), then cos |
%coeff(v,n) | polynomial in v | coefficient of vn and remainder |
Class: Sums | ||
Template(w/abbrev.) | Coersion to | Pieces and Ordering |
---|---|---|
%sum | passive | terms (inpart order) |
%partfrac(x), %pf | partial fraction decomp in x | terms (inpart order) |
Class: Products | ||
Template(w/abbrev.) | Coersion to | Pieces and Ordering |
---|---|---|
%product, %prod | passive | factors (inpart order) |
%factor, %f | factored form | factors (inpart order) |
%factor(minpoly), %f | factored with element adjoined | factors (inpart order) |
%sqfr, %sf | square-free factored form | factors (inpart order) |
Class: Fractions | ||
Template(w/abbrev.) | Coersion to | Pieces and Ordering |
---|---|---|
%frac | passive | numerator and denominator |
%ratsimp, %r | rationally simplified | numerator and denominator |
Class: Complex | ||
Template(w/abbrev.) | Coersion to | Pieces and Ordering |
---|---|---|
%rectform, %g | gaussian form | real and imaginary parts |
%polarform | polar form | magnitude and phase |
Class: Bags | ||
Template(w/abbrev.) | Coersion to | Pieces and Ordering |
---|---|---|
%equation, %eq | equation | l.h.s. and r.h.s. |
%relation(r), %rel | relation; r in (=,>,>=,<,<=,!=) | l.h.s. and r.h.s. |
%list | list | elements |
%matrix | matrix | rows (use %list for elements) |
Class: General | ||
Template(w/abbrev.) | Coersion to | Pieces and Ordering |
---|---|---|
%expression, %expr | passive | the operands (inpart order) |
%preformat(T1,...) | format accord. to chain Ti | the 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,...), %el | formats an element of a matrix |
%num, %denom | formats 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 |
---|---|
%noop | does 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) ]
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.
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.
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.
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]]
Gets the coefficient from the coefficient list clist corresponding
to the keys ki. The keys are matched to variable powers when
clist is a %poly
, %series
or %Taylor
form. If
clist is a %trig
then k1 should be sin
or cos
and the remaining keys are matched to multipliers.
Reconstructs the expression from a coefficient list clist. The coefficient list can be any of the coefficient list forms.
Partitions expr into two polynomials; the first is made of those monomials for which the function test returns true and the second is the remainder. The test function is called on the powers of the vi.
Trigonometric analog to partition poly; The functions sintest and costest select sine and cosine terms, respectively; each are called on the multipliers of the vi.
Analog to partition_poly
for series.
Example:
(%i1) partition_poly((a+b*x)*(c-x)^2,'evenp,x); 2 2 3 2 (%o1) [(a - 2 b c) x + a c , b x + (b c - 2 a c) x]
Support functions
Returns a list of all subexpressions of expr for which the application
predicate(piece,args ... )
returns true
.
Returns a list of all calls in expr involving any of functions.
Returns a list of all argument lists for calls to functions in expr.
Examples:
(%i1) t2:(a+log(b)*x)*(c-log(x))^2$ (%i2) matching_parts(t2,constantp); (%o2) [2, - 1] (%i3) function_calls(t2,log); (%o3) [log(x), log(b)]
Original documentation is located in the share/contrib/format directory and contains an appendix describing the implementation algorithm in more detail.
Next: Package fractals, Previous: Package finance [Contents][Index]