Add note that the lapack package needs to loaded to get the functions.
[maxima.git] / doc / info / format.texi.m4
blob808ea34a5a17d7666c760e3045cf2493d80f840d
1 @c -*- mode: texinfo -*-
2 @c translated Miller's postcript file to texi.m4 format by ehm
4 @menu
5 * Introduction to format::
6 * Functions and Variables for format::
7 @end menu
9 @node Introduction to format, Functions and Variables for format
10 @section Introduction to format
12 The @code{format} package was written by Bruce R. Miller, NIST (miller-at-cam.nist.gov).
14 @code{format} is a package for formatting algebraic expressions in
15 Maxima. It provides facilities for user-directed hierarchical
16 structuring of expressions, as well as for directing simplifications to
17 selected subexpressions. It emphasizes a semantic rather than
18 syntactic description of the desired form. The package also provides
19 utilities for obtaining efficiently the coefficients of polynomials,
20 trigonometric sums and power series.
22 In a general purpose Computer Algebra System (CAS), any particular
23 mathematical expression can take on a variety of forms: expanded form,
24 factored form or anything in between. Each form may have advantages; a
25 given form may be more compact than another, or allow clear expression
26 of certain algorithms. Or it may simply be more informative,
27 particularly if it has physical significance.  A CAS contains many tools
28 for transforming expressions. However, most are like Maxima's
29 @code{factor} and @code{expand}, operating only on the entire expression
30 or its top level. At the other extreme are operations like
31 @code{substpart} which extract a specific part of an expression, then
32 transform and replace it.  Unfortunately, the means of specifying the
33 piece of interest is purely syntactic, requiring the user to keep close
34 watch on the form of the arguments to avoid error.
36 The package described here gives users of Maxima more control over the
37 structure of expressions, and it does so using a more semantic, almost
38 algebraic, language describing the desired structure. It also provides a
39 semantic means of addressing parts of an expression for particular
40 simplifications. For example, to rearrange an expression into a series
41 in @code{eps} through order 5, whose terms will be polynomials in
42 @code{x} and @code{y}, whose coefficients, in turn, will be
43 trigonometric sums in @code{l} and @code{g} with factored coefficients
44 one uses the command:@*
46 @noindent
47 @code{format(foo; %series(eps; 5); %poly(x; y);%trig(l; g); %factor);}@*
49 @noindent
50 The principal tool, @code{format}, is described in section
51 @ref{Functions and Variables for format}. It uses procedures in
52 @code{coeflist} which obtain coefficients of polynomials, trigonometric
53 sums and power series.
55 @node Functions and Variables for format,  ,Introduction to format
56 @section Functions and Variables for format
58 @deffn {Function} format (@var{expr}, @var{template@sub{1}}, ...)
59 Each @code{template} indicates the desired form for an expression;
60 either the expected form or that into which it will be transformed. At
61 the same time, the indicated form implies a set of @emph{pieces}; the
62 next template in the chain applies to those pieces. For example,
63 @code{%poly(x)} specifies the transformation into a polynomial in
64 @code{x}, with the pieces being the coefficients. The passive
65 @code{%frac} treats the expression as a fraction; the pieces are the
66 numerator and denominator.  Whereas the next template formats all pieces
67 of the previous layer, positional @emph{subtemplates} may be used to
68 specify formats for each piece individually. This is most useful when
69 the pieces have unique roles and need to be treated differently, such as
70 a fraction's numerator and denominator.
71 @end deffn
73 @noindent
74 The full syntax of a template is@*
76 @code{keyword (parameter ; ...)[subtemplate ; ...]}@*
78 The recognized keywords are described below under @ref{Template keywords}. The parameters (if not
79 needed) and subtemplates (along with parentheses and brackets) are optional.
81 In addition to the keyword templates, arithmetic patterns are
82 recognized.  This is an expression involving addition, multiplication
83 and exponentiation containing a single instance of a keyword
84 template. In effect, the system `solves' the expression to be formatted
85 for the corresponding part, formats it accordingly and reinserts it. For
86 example, @code{format(X,a+%factor)} is equivalent to
87 @code{a+factor(X-a)}. Any other template is assumed to be a function to
88 be applied to the expression; the result is then formatted according to
89 the rest of the template chain.
92 Examples for general restructuring:
93 @c ===beg===
94 @c format((a+b*x)*(c-x)^2,%poly(x),factor);
95 @c format((1+2*eps*(q+r*cos(g))^2)^4,%series(eps,2),%trig(g),factor);
96 @c format((1+2*a+a^2)*b + a*(1+2*b+b^2),%sum,%product,%factor);
97 @c format(expand((a+x)^3-a^3),%f-a^3);
98 @c ===end===
99 @example
100 @group
101 (%i1) load("format.mac")$
102 (%i2) format((a+b*x)*(c-x)^2,%poly(x),factor);
103                    3                2                        2
104 (%o2)           b x  - (2 b c - a) x  + c (b c - 2 a) x + a c
105 (%i3) format((1+2*eps*(q+r*cos(g))^2)^4,%series(eps,2),%trig(g),factor);
106                    2      2                2
107 (%o3) 1 + eps (4 (r  + 2 q ) + 4 cos(2 g) r  + 16 cos(g) q r)
108       2        4       2  2      4                4                  3
109  + eps  (3 (3 r  + 24 q  r  + 8 q ) + 3 cos(4 g) r  + 24 cos(3 g) q r
110                      2      2                 2   2      2
111  + 24 cos(g) q r (3 r  + 4 q ) + 12 cos(2 g) r  (r  + 6 q )) + . . .
112 (%i4) format((1+2*a+a^2)*b + a*(1+2*b+b^2),%sum,%product,%factor);
113                                      2          2
114 (%o4)                       a (b + 1)  + (a + 1)  b
115 @end group
116 @group
117 (%i5) format(expand((a+x)^3-a^3),%f-a^3);
118                                         3    3
119 (%o5)                           (x + a)  - a
120 @end group
121 @end example
123 @subsection Template keywords
124 @anchor{Template keywords}
126 Keywords come in several @emph{classes}: Algebraic, Sums, Products,
127 Fractions, Complex, Bags, General, Targeting, Control, Subtemplate Aids,
128 and Convenience.
130 A few remarks about keywords: A passive keyword does not transform the
131 expression but treats it as a sum, fraction or whatever. The order of
132 the pieces corresponds to the internal ordering; subtemplate usage may
133 be awkward. See the documentation of @code{coerce_bag} for a description
134 of the coercions used. Targeting templates are basically shorthand
135 equivalents of structuring templates using subtemplates.
137 @noindent
138 @multitable @columnfractions .3 .4 .4
139 @strong{Class: @emph{Algebraic}}
140 @headitem Template(w/abbrev.) @tab Coersion to @tab Pieces and Ordering
141 @item @code{%poly(@var{x}@sub{1},...), %p} @tab polynomial in @var{x@sub{i}} @tab coefficients (ascending exps.)
142 @item @code{%series(@emph{eps},@emph{n}), %s} @tab series in @emph{eps} through order @emph{n} @tab coefficients (ascending exps.)
143 @item @code{%Taylor(@emph{eps},@emph{n})} @tab Taylor in @emph{eps} through order @emph{n} @tab coefficients (ascending exps.)
144 @item @code{%monicpoly(@var{x@sub{1}},...),%mp} @tab monic polynomial in @var{x@sub{i}} @tab leading coef then coefs
145 @item @code{%trig(@var{x@sub{1}},...), %t} @tab trigonometric sum in @var{x@sub{i}} @tab @code{sin} coefs (ascending), then @code{cos}
146 @item @code{%coeff(@var{v},@var{n})} @tab polynomial in @var{v} @tab coefficient of @var{v@sup{n}} and remainder
147 @end multitable
149 @noindent
150 @multitable @columnfractions .3 .4 .4
151 @strong{Class: @emph{Sums}}
152 @headitem Template(w/abbrev.) @tab Coersion to @tab Pieces and Ordering
153 @item @code{%sum} @tab @emph{passive} @tab terms (@code{inpart} order)
154 @item @code{%partfrac(@var{x}), %pf} @tab partial fraction decomp in @var{x} @tab terms (@code{inpart} order)
155 @end multitable
157 @noindent
158 @multitable @columnfractions .3 .4 .4
159 @strong{Class: @emph{Products}}
160 @headitem Template(w/abbrev.) @tab Coersion to @tab Pieces and Ordering
161 @item @code{%product, %prod} @tab @emph{passive} @tab factors (@code{inpart} order)
162 @item @code{%factor, %f} @tab factored form @tab factors (@code{inpart} order)
163 @item @code{%factor(@emph{minpoly}), %f} @tab factored with element adjoined @tab factors (@code{inpart} order)
164 @item @code{%sqfr, %sf} @tab square-free factored form @tab factors (@code{inpart} order)
165 @end multitable
167 @noindent
168 @multitable @columnfractions .3 .4 .4
169 @strong{Class: @emph{Fractions}}
170 @headitem Template(w/abbrev.) @tab Coersion to @tab Pieces and Ordering
171 @item @code{%frac} @tab @emph{passive} @tab numerator and denominator
172 @item @code{%ratsimp, %r} @tab rationally simplified @tab numerator and denominator
173 @end multitable
175 @noindent
176 @multitable @columnfractions .3 .4 .4
177 @strong{Class: @emph{Complex}}
178 @headitem Template(w/abbrev.) @tab Coersion to @tab Pieces and Ordering
179 @item @code{%rectform, %g} @tab gaussian form @tab real and imaginary parts
180 @item @code{%polarform} @tab polar form @tab magnitude and phase
181 @end multitable
183 @noindent
184 @multitable @columnfractions .3 .4 .4
185 @strong{Class: @emph{Bags}}
186 @headitem Template(w/abbrev.) @tab Coersion to @tab Pieces and Ordering
187 @item @code{%equation, %eq} @tab equation @tab l.h.s. and r.h.s.
188 @item @code{%relation(@var{r}), %rel} @tab relation; @var{r} in @code{(=,>,>=,<,<=,!=)}  @tab l.h.s. and r.h.s.
189 @item @code{%list} @tab list @tab elements
190 @item @code{%matrix} @tab matrix @tab rows (use @code{%list} for elements)
191 @end multitable
193 @noindent
194 @multitable @columnfractions .3 .4 .4
195 @strong{Class: @emph{General}}
196 @headitem Template(w/abbrev.) @tab Coersion to @tab Pieces and Ordering
197 @item @code{%expression, %expr} @tab @emph{passive} @tab the operands (@code{inpart} order)
198 @item @code{%preformat(@var{T@sub{1}},...)} @tab format accord. to chain @var{T@sub{i}} @tab the result, not the parts
199 @end multitable
201 @noindent
202 @multitable @columnfractions .3 .7
203 @strong{Class: @emph{Targeting}}
204 @headitem Template(w/abbrev.) @tab Function
205 @item @code{%arg(n)} @tab formats the @code{n}-th argument
206 @item @code{%lhs(@var{r})} @tab formats the l.h.s. of an eqn. or relation (default '=')
207 @item @code{%rhs(@var{r})} @tab formats the l.h.s. of an eqn.
208 @item @code{%element(i,...), %el} @tab formats an element of a matrix
209 @item @code{%num, %denom} @tab formats the numerator or denominator of a fraction
210 @item @code{%match(@var{P})} @tab formats all subexpressions for which @var{P(@emph{expr})} returns true
211 @end multitable
213 @noindent
214 @multitable @columnfractions .3 .7
215 @strong{Class: @emph{Control}}
216 @headitem Template(w/abbrev.) @tab Function
217 @item @code{%if(@var{P@sub{1}},...)[@var{T@sub{1}},...,@var{T@sub{n+1}}]} @tab Find first @var{P@sub{i}(@emph{expr})} @arrow{} @code{true}, then format @emph{expr} using @var{T@sub{i}}, else @var{T@sub{n+1}}
218 @end multitable
220 @noindent
221 @multitable @columnfractions .3 .7
222 @strong{Class: @emph{Subtemplate Aids}}
223 @headitem Template(w/abbrev.) @tab Function
224 @item @code{%noop} @tab does nothing; used to fill a subtemplate slot
225 @item @code{[@var{T@sub{1}},@var{T@sub{2}},...]} @tab creates a template chain where an individual template was expected
226 @item @code{%ditto(@var{T})} @tab repeats the template so that it applies to following pices
227 @end multitable
229 @noindent
230 @multitable @columnfractions .3 .7
231 @strong{Class: @emph{Convenience}}
232 @headitem Template(w/abbrev.) @tab Function
233 @item @code{%subst(@emph{eqns},...)} @tab substitutes @emph{eqns} into expression; result is formatted at next layer
234 @item @code{%ratsubst(@emph{eqns},...)} @tab @code{lratsubst}'s @emph{eqns} into expression; result is formatted at next layer
235 @end multitable
238 Example with simplification on subexpression:
239 @c ===beg===
240 @c 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$
241 @c trigsimp(foo);
242 @c format(foo,%p(x),trigsimp);
243 @c format([a=b,c=d,e=f],%equation);
244 @c format(%,%list);
245 @c 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])$
246 @c format(m1,%equation,%matrix[%noop,%list[%noop,%factor]]);
247 @c ===end===
248 @example
249 @group
250 (%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$
251 (%i2) trigsimp(foo);
252                      4    2     4         4    2       4
253 (%o2)              (x  + x ) cos (y) - 2 x  cos (y) + x  + 1
254 (%i3) format(foo,%p(x),trigsimp);
255                                 4    4       2    4
256 (%o3)                     x  sin (y) + x  cos (y) + 1
257 @end group
258 @end example
259 The following examples illustrate the usage with `bags.'
260 @example
261 @group
262 (%i1) format([a=b,c=d,e=f],%equation);
263 (%o1) [a, c, e] = [b, d, f]
264 (%i2) format(%,%list);
265 (%o2) [a = b, c = d, e = f]
266 (%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])$
267 (%i4) format(m1,%equation,%matrix[%noop,%list[%noop,%factor]]);
268                    [  2             2           ]
269                    [ a  + 2 a + 1  b  + 2 b + 1 ]   [ q  r ]
270 (%o4)              [                            ] = [      ]
271                    [  2                     2   ]   [ s  t ]
272                    [ c  + 2 c + 1    (d + 1)    ]
274 @end group
275 @end example
278 @subsection User defined templates
280 New templates can be defined by giving the template keyword the property
281 @code{formatter}; the value should be a function (or lambda expression)
282 of the expression to be formatted and any parameters for the template.
283 For example, @code{%rectform} and @code{%if} could be defined as
285 @code{put(%rectform,lambda([c],block([r:rectformlist(c)],@*
286         @ @ @ @ @ @ format-piece(r[1]) +%I* format-piece(r[2]))),formatter)}@*
288 @code{put(%if, lambda([x,test],@*
289               @ @ @ @ @ @ if test(x) then format-piece(x,1)@*
290               @ @ @ @ @ @ @ @ else@*
291               @ @ @ @ @ @ @ @ @ @ format-piece(x,2)),formatter)}@*
293 @noindent
294 Functions used for defining templates are the following.
296 @deffn {function} %format_piece (@var{piece},{@var{nth}})
297 @code{lratsubst}'s @code{eqns} into expression and the result is formatted at the next layer.
298 Format a given piece of an expression, automatically accounting for
299 subtemplates and the remaining template chain. A specific subtemplate,
300 rather than the next one, can be selected by specifying @var{nth}.
301 @end deffn
303 @deffn {function} %coerce_bag (@var{op},@var{expr})
304 Attempts to coerce @var{expr} into an expression with @var{op} (one of
305 @code{=, #, <, <=, >, >=, [} or matrix) as the top-level operator. It
306 coerces the expression by swapping operands between layers but only if
307 adjacent layers are also lists, matrices or relations. This model
308 assumes that a list of equations, for example, can be viewed as an
309 equation whose sides are lists. Certain combinations, particularly those
310 involving inequalities may not be meaningful, however, so some caution
311 is advised.
312 @end deffn
314 @subsection Determining coefficients
316 We define the `algebras' of polynomials, trigonometric sums and power series to
317 be those expressions that can be cast into the following forms.
319 m4_displaymath(
320 <<<\eqalign{
321 {\bf P}(v_1,\cdots) &=  \{P\,|\, P=\sum_i c_i v^{p_{1,i}}_1 v^{p_{2,i}}_2 \cdots\} \cr
322 {\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
323 {\bf S}(v,O) &= \{S\,|\, S=\sum_i c_i v^{p_i};\,p_n \le O \} 
324 }>>>
327 The variables @var{v@sub{i}} may be any atomic expression in the sense
328 of @code{ratvars}. The shorthands @code{operator(op)} and
329 @code{match(predicate)} may be used to specify all subexpressions having
330 op as an operator, or that pass the predicate, respectively.
332 The coefficients @var{c@sub{i}} and @var{s@sub{i}} are general Maxima
333 expressions. In principle they would be independent of the variables
334 @var{v@sub{i}}, but in practice they may contain non-polynomial
335 dependence (or non-trigonometric, in the trigonometric case).  These
336 non-polynomial cases would include expressions like @code{(1 +
337 x)@sup{n}}, where @code{n} is symbolic. Likewise,
338 @code{(x@sup{a})@sup{b}} is, in general, multivalued; unless @code{a =
339 1} or @code{b} is a member of @code{Z}, or @code{radexpand=all}, it will
340 not be interpreted as @code{x@sup{ab}} is a member of
341 @strong{P}. Furthermore, we extend the algebras to include lists,
342 vectors, matrices and equations, by interpreting a list of polynomials,
343 say, as a polynomial with lists as coefficients.
345 The exponents @var{p@sub{i}} in series are restricted to numbers, but
346 the exponents @var{c@sub{j,i}} and multiples @var{m@sub{j,i}} for
347 polynomials and trigonometric sums may be general expressions
348 (excluding bags).
350 The following functions construct a list of the coefficients and `keys',
351 that is, the exponents or multiples. Note that these are sparse
352 representations; no coefficients are zero.@*
354 @noindent
355 @code{coeffs(P,v@sub{1},...) @arrow{} [[%poly,v@sub{1},...],[c@sub{1},p@sub{1,1},...],...] }@*
356 @code{trig_coeffs(T,v@sub{1},...) @arrow{}}@*
357 @ @ @ @ @ @ @ @ @ @ @ 
358 @code{[[%trig,v@sub{1},...],[[c@sub{1},m@sub{1,1},...],...],[[s@sub{1},m'@sub{1,1},...],...]]}@*
359 @code{series_coeffs(S,v,O) @arrow{} [[%series,v,O],[c@sub{1},p@sub{1}],...,[c@sub{n},p@sub{n}]}@*
360 @code{Taylor_coeffs(S,v,O) @arrow{} [[%Taylor,v,O],[c@sub{1},p@sub{1}],...,[c@sub{n},p@sub{n}]}@*
362 The latter two functions both expand an expression through order
363 @code{O}, but the series version only carries expands arithmetic
364 operations and is often considerably faster than @code{Taylor_coeffs}.
366 Examples:
367 @c ===beg===
368 @c cl1:coeffs((a+b*x)*(c-x)^2,x);
369 @c map('first,rest(coeffs((a+b*x)*(c-x)^2=q0+q1*x+q2*x^2+q3*x^3,x)));
370 @c trig_coeffs(2*(a+cos(x))*cos(x+3*y),x,y);
371 @c series_coeffs((a+b*x)*(c-x)^2,x,2);
372 @c coeffs((a+b*x)*sin(x),x);
373 @c coeffs((a+log(b)*x)*(c-log(x))^2,operator(log));
374 @c ===end===
375 @example
376 @group
377 (%i1) cl1:coeffs((a+b*x)*(c-x)^2,x);
378                        2          2
379 (%o1) [[%poly, x], [a c , 0], [b c  - 2 a c, 1], [a - 2 b c, 2], [b, 3]]
380 (%i2) map('first,rest(coeffs((a+b*x)*(c-x)^2=q0+q1*x+q2*x^2+q3*x^3,x)));
381                 2          2
382 (%o2)       [a c  = q0, b c  - 2 a c = q1, a - 2 b c = q2, b = q3]
383 (%i3) trig_coeffs(2*(a+cos(x))*cos(x+3*y),x,y);
384 (%o3)      [[%trig, x, y], [], [[1, 0, 3], [2 a, 1, 3], [1, 2, 3]]]
385 (%i4) series_coeffs((a+b*x)*(c-x)^2,x,2);
386                               2          2
387 (%o4)   [[%series, x, 2], [a c , 0], [b c  - 2 a c, 1], [a - 2 b c, 2]]
388 (%i5)  coeffs((a+b*x)*sin(x),x);
389 (%o5)             [[%poly, x], [a sin(x), 0], [b sin(x), 1]]
390 (%i6)  coeffs((a+log(b)*x)*(c-log(x))^2,operator(log));
391                                     2           2
392 (%o6) [[%poly, log(x), log(b)], [a c , 0, 0], [c  x, 0, 1], [- 2 a c, 1, 0], 
393                                          [- 2 c x, 1, 1], [a, 2, 0], [x, 2, 1]]
394 @end group
395 @end example
398 @subsection Related functions
400 @deffn {function} get_coef (@var{clist},@var{k@sub{1}},...)
401 Gets the coefficient from the coefficient list @var{clist} corresponding
402 to the keys @var{k@sub{i}}. The keys are matched to variable powers when
403 @var{clist} is a @code{%poly}, @code{%series} or @code{%Taylor} form. If
404 @var{clist} is a @code{%trig} then @var{k@sub{1}} should be @code{sin}
405 or @code{cos} and the remaining keys are matched to multipliers.
406 @end deffn
408 @deffn {function} uncoef (@var{clist})
409 Reconstructs the expression from a coefficient list @var{clist}. The
410 coefficient list can be any of the coefficient list forms.
411 @end deffn
413 @deffn {function} partition_poly (@var{expr},@var{test},@var{v@sub{1}},...)
414 Partitions @var{expr} into two polynomials; the first is made of those
415 monomials for which the function test returns true and the second is the
416 remainder. The test function is called on the powers of the @var{v@sub{i}}.
417 @end deffn
419 @deffn {function} partition_trig (@var{expr},@var{sintest},@var{costest},@var{v@sub{1}},...)
420 Trigonometric analog to partition poly; The functions @var{sintest} and
421 @var{costest} select sine and cosine terms, respectively; each are called on
422 the multipliers of the @var{v@sub{i}}.
423 @end deffn
425 @deffn {function} partition_series (@var{expr},@var{test},@var{v},@var{O})
426 @end deffn
428 @deffn {function} partition_Taylor (@var{expr},@var{test},@var{v},@var{O})
429 Analog to @code{partition_poly} for series.
430 @end deffn
432 @noindent
433 Example:
434 @c ===beg===
435 @c partition_poly((a+b*x)*(c-x)^2,'evenp,x);
436 @c ===end===
437 @example
438 @group
439 (%i1)  partition_poly((a+b*x)*(c-x)^2,'evenp,x);
440                              2      2     3       2
441 (%o1)          [(a - 2 b c) x  + a c , b x  + (b c  - 2 a c) x]
442 @end group
443 @end example
447 @noindent
448 @strong{Support functions}
450 @deffn {function} matching_parts (@var{expr},@var{predicate},@var{args}...)
451 Returns a list of all subexpressions of @var{expr} for which the application
452 @code{predicate(piece,args ... )} returns @code{true}.
453 @end deffn
455 @deffn {function} function_calls (@var{expr},@var{functions}...)
456 Returns a list of all calls in @var{expr} involving any of @var{functions}.
457 @end deffn
459 @deffn {function} function_arguments (@var{expr},@var{functions}...)
460 Returns a list of all argument lists for calls to @var{functions} in @var{expr}.
461 @end deffn
463 @noindent
464 Examples:
465 @c ===beg===
466 @c t2:(a+log(b)*x)*(c-log(x))^2$
467 @c matching_parts(t2,constantp);
468 @c function_calls(t2,log);
469 @c ===end===
470 @example
471 @group
472 (%i1) t2:(a+log(b)*x)*(c-log(x))^2$
473 (%i2) matching_parts(t2,constantp);
474 (%o2)                             [2, - 1]
475 (%i3) function_calls(t2,log);
476 (%o3)                         [log(x), log(b)]
477 @end group
478 @end example
480 @subsection Implementation
482 Original documentation is located in the share/contrib/format directory and contains an
483 appendix describing the implementation algorithm in more detail.