The nset package provides set functions, such as intersection and union, for finite sets that are defined by explicit enumeration. Unlike the package set in Maxima's share library, nset treats lists and sets as distinct objects. This feature makes it possible to work with sets that have members that are either lists or sets.
In addition to functions for finite sets, nset provides some functions related to combinatorics; these include the Stirling numbers, the Bell numbers, and several others.
Download the archive nset-x.tar.gz, where x is the release identifier, from http://www.unk.edu/acad/math/people/willisb. Under Linux, unpack it using
gzip -d nset-x.tar.gz
tar -xvf nset-x.tar
This will create a directory nset-x (again x is the release identifier) that contains the source file nset.lisp, user documentation in html and texi formats, a sample maxima initialization file nset-init.lisp, a README file, and a testing routine test-nset.mac. From the nset-x directory,start Maxima and compile nset using
(C1) compile_file("nset.lisp")$
This will create a file nset.xxx in the nset-x directory. The file extension xxx depends on which Lisp your Maxima uses; under gcl, the extension is "o".
Copy nset.lisp and its compiled forms to a directory that Maxima can find. A good location is Maxima's /share/combinatorics directory. If you don't have write permission for this directory, or if you want to install nset in a different location, that is fine as long as you place it in a directory that Maxima can find.
If you are using Maxima version 5.9.0 or higher, finish the installation by appending the contents of nset-init.lisp to your own maxima-init.lisp file. The Lisp file nset-init.lisp contains replacements for the Maxima functions setup_autoload and generic_autoload. Unlike Maxima's setup_autoload function, the version in nset-init.lisp uses file_search. Without this change, a full pathname must be given to setup_autoload. The autoload function in Maxima 5.9.0 and lower does not recognize some file extensions, such as .x86f and .fasl, as valid extensions for compiled code. The version of generic_autoload in nset-init fixes this problem. Additionally, nset-init.lisp contains autoload statements for all user-level functions in nset.
Maxima versions prior to 5.9.0 do not support initialization files. You may still use nset under these versions of Maxima; you must, however, manually load nset before you use any functions (especially the set function) that are in nset.
Once nset is installed, run its testing code. Do this from a Maxima prompt using the command
(C1) batch("test-nset.mac",'test);
You may need to use the full pathname for the file. The test should end with the statement
..Which was correct Congratulations: No differences!
Please report any errors to the Maxima list.
To use the set functions, begin by loading nset. Provided you have installed the package correctly, load it with the command
(C1) load("nset")$
If Maxima is unable to find nset, use its full pathname. If you have included an autoload statement for all functions in nset in your maxima-init.lisp file, you will not have to manually load nset.
To construct a set with members a1,a2,...,an, use the command set(a1,a2,...,an); to construct the empty set, use set(). If a member is listed more than once, the simplification process eliminates the redundant member.
(C1) set(); (D1) {} (C2) set(a,b,a); (D2) {a, b} (C3) set(a,set(b)); (D3) {a, {b}} (C4) set(a,[b]); (D4) {a, [b]}
Sets are displayed as brace delimited lists; if you would like to be able to input a set using braces, see the section Defining sets with braces.
To construct a set from the elements of a list, use setify
(C4) setify([b,a]); (D4) {a,b}
Set members x and y are equal provided is(x = y) evaluates to true. Thus rat(x) and x are equal as set members; consequently,
(C1) set(x,rat(x)); (D1) {x}
Further, since is((x-1)*(x+1) = x^2 - 1) evaluates to false, (x-1)*(x+1) and x^2-1 are distinct set members; thus
(C2) set((x-1)*(x+1),x^2-1); 2 (D2) {(x - 1) (x + 1), x - 1}
To reduce this set to a singleton set, apply rat to each set member
(C3) map(rat,%); 2 (D3) {x - 1}
To remove redundancies from other sets, you may need to use other simplification functions. Here is an example that uses trigsimp
(C1) set(1, cos(x)^2 + sin(x)^2); 2 2 (D1) {1, SIN (x) + COS (x)} (C2) map(trigsimp,%); (D2) {1}
A set is simplified when its members are non-redundant and sorted. Nset version 1.2 uses the Maxima function orderlessp to order sets; however, future versions of nset might use a different ordering function. Robust application code that uses nset must not depend on a particular ordering.
Some operations on sets, such as substitution, automatically force a re-simplification; for example,
(C1) s : set(a,b,c)$ (C2) subst(c=a,s); (D2) {a, b} (C3) subst([a=x,b=x,c=x],s); (D3) {x} (C4) map(lambda([x],x^2), set(-1,0,1)); (D4) {0, 1}
The nset package treats lists and sets as distinct objects; functions such as union and intersection will signal an error if any argument is a list. If you need to apply a set function to a list, use the setify function to convert it to a set. Thus
(C1) union([1,2],set(a,b)); Function union expects a set, instead found [1,2] -- an error. Quitting. To debug this try DEBUGMODE(TRUE);) (C2) union(setify([1,2]),set(a,b)); (D2) {1, 2, a, b}
To extract all set elements of a set s that satisfy a predicate f, use subset(s,f). (In Maxima, a predicate is a boolean-valued function.) For example, to find the equations in a given set that do not depend on a variable z, use
(C1) subset(set(x+y+z,x-y+4,x+y-5),lambda([e],freeof(z,e))); (D1) {- y + x + 4, y + x - 5}
The section Definitions for Sets has a complete list of the functions in nset
There two ways to to iterate over set members. One way is the use map; for example
(C1) map(f,set(a,b,c)); (D1) {f(a), f(b), f(C)}
The other way is to use for in do
(C1) s : set(a,b,c); (D1) {a, b, C} (C2) for si in s do print(concat(si,1)); a1 b1 C1
The Maxima functions first and rest work correctly on sets. Applied to a set, first returns the first displayed element of a set; which element that is may be implementation-dependent. If s is a set, then rest(s) is equivalent to disjoin(first(s),s). Currently, there are other Maxima functions that work correctly on sets; however, for future versions of nset, they may function differently or not at all.
The nset package uses the Maxima function orderlessp to order set members and the (Lisp-level) function like to test for set member equality. Both of these functions have known bugs (versions 5.9.0 and earlier) that may manifest if you attempt to use sets with members that are lists or matrices that contain expressions in CRE form. An example is
(C1) set([x],[rat(x)]);
This command causes Maxima to halt with an error (the error message depends on which version of Lisp your Maxima uses). Another example is
(C2) setify([[rat(a)],[rat(b)]]);
These bugs are caused by bugs in orderlessp and like; they are not caused by bugs in nset. To illustrate, try the commands
(C1) orderlessp([rat(a)],[rat(b)]); (C2) is([rat(a)]=[rat(a)]);
Until these bugs are fixed, do not construct sets with members that are lists or matrices containing expressions in CRE form; a set with a member in CRE form, however, shouldn't be a problem
(C1) set(x,rat(x)); (D1)/R/ {x}
Maxima's orderlessp has another bug that can cause problems with nset functions; the ordering predicate orderlessp is not transitive. The simplest known example that shows this is
(C1) q : x^2$ (C2) r : (x+1)^2$ (C3) s : x*(x+2)$ (C4) orderlessp(q,r); (D4) TRUE (C5) orderlessp(r,s); (D5) TRUE (C6) orderlessp(q,s); (D6) FALSE
This bug can cause trouble will all nset functions as well as with Maxima functions in general. It's likely, but not certain, that if all set members are either in CRE form or have been simplified using ratsimp, this bug will not manifest.
Maxima's orderless and ordergreat mechanisms are incompatible with nset. If you need to use either orderless or ordergreat, issue these commands before loading nset and do not use the unorder command.
You may encounter two other minor bugs while using nset. Maxima versions 5.5 and earlier had a bug in the tex function that makes the empty set incorrectly translate to TeX; this bug is fixed in the Maxima 5.9.0. Additionally, the setup_autoload function in Maxima 5.9.0 is broken; a fix is in the nset-init.lisp file located in the nset distribution.
Maxima's sign function has a bug that may cause the Kronecker delta function to misbehave; for example
(C1) kron_delta(1/sqrt(2),sqrt(2)/2); (D1) 0
The correct value is 1; the bug is related to the sign bug
(C2) sign(1/sqrt(2)-sqrt(2)/2); (D2) POS (C3)
If you find something that you think might be a nset bug, please report it to the Maxima bug database.
If you'd like to be able to input sets using braces, you may do so by declaring the left brace to be a matchfix operator; this is done using the commands
(C1) matchfix("{","}")$ (C2) "{"([a]) := apply(set,a)$
Now we can define sets using braces; thus
(C3) {}; (D3) {} (C4) {a,{a,b}}; (D4) {a, {a, b}}
To always allow this form of set input, place the two commands in lines (c1) and (c2) in your maxima-init.mac file.
In addition to functions for finite sets, nset provides some functions related to combinatorics; these include the Stirling numbers of the first and second kind, the Bell numbers, multinomial coefficients, partitions of nonnegative integers, and a few others. The nset package also defines a Kronecker delta function.
Stavros Macrakis of Cambridge, Massachusetts and Barton Willis of the University of Nebraska at Kearney (UNK) wrote the nset package and its documentation.
(C1) adjoin(c,set(a,b)); (D1) {a, b, c} (C2) adjoin(a,set(a,b)); (D2) {a, b}
See also disjoin.
(C1) makelist(belln(i),i,0,6); (D1) [1, 1, 2, 5, 15, 52, 203] (C2) is(cardinality(set_partitions(set())) = belln(0)); (D2) TRUE (C3) is(cardinality(set_partitions(set(1,2,3,4,5,6))) = belln(6)); (D3) TRUE
When n isn't a nonnegative integer, belln(n) doesn't simplify
(C7) [belln(x), belln(sqrt(3)), belln(-9)]; (D7) [BELLN(x), BELLN(SQRT(3)), BELLN(- 9)]
The function belln threads over equalities, lists, matrices, and sets.
(C1) cardinality(set()); (D1) 0 (C2) cardinality(set(a,a,b,c)); (D2) 3 (C3) cardinality(set(a,a,b,c)), simp : false; (D3) 3
In line (c3), we see that cardinality works correctly even when simplification has been turned off.
(C1) cartesian_product(set(0,1)); (D1) {[0], [1]} (C2) cartesian_product(set(0,1),set(0,1)); (D2) {[0, 0], [0, 1], [1, 0], [1, 1]} (C3) cartesian_product(set(x),set(y),set(z)); (D3) {[x, y, z]} (C4) cartesian_product(set(x),set(-1,0,1)); (D4) {[x, - 1], [x, 0], [x, 1]}
We can show that 28 is a perfect number using
(C1) s : divisors(28); (D1) {1, 2, 4, 7, 14, 28} (C2) lreduce("+",s)-28; (D2) 28
The function divisors works by simplification; you shouldn't need to manually re-evaluate after a substitution. For example
(C3) divisors(a); (D3) DIVISORS(a) (C4) subst(8,a,%); (D4) {1, 2, 4, 8}
The function divisors threads over equalities, lists, matrices, and sets. Here is an example of threading over a list and an equality.
(C5) divisors([a,b,c=d]); (D5) [DIVISORS(a), DIVISORS(b), DIVISORS(c) = DIVISORS(d)]
(C1) map(emptyp,[set(),[]]); (D1) [TRUE, TRUE] (C2) map(emptyp,[a+b, set(set()), %pi]); (D2) [FALSE, FALSE, FALSE]
(C1) equiv_classes(set(a,b,c),lambda([x,y],is(x=y))); (D1) {{a}, {b}, {c}}
Actually, equiv_classes(s,f) automatically applies the Maxima function is after applying the function f; accordingly, we can re-work the previous example with the command
(C2) equiv_classes(set(a,b,c),"="); (D2) {{a}, {b}, {c}}
Here is another example
(C3) equiv_classes(set(1,2,3,4,5,6,7),lambda([x,y],remainder(x-y,3)=0)); (D3) {{1, 4, 7}, {2, 5}, {3, 6}}
The first argument f should be a predicate (a function that evaluates to true, false, or unknown).
Given one set as the second argument, every(f, set(a1,...,an)) returns true if any f(ai) evaluates to true. Since sets are unordered, 'every' is free to evaluate f(ai) in any order. 'Every' may or may not evaluate all the f(ai)'s. Because the order of evaluation isn't specified, the predicate f should not have side-effects or signal errors for any input. To use 'every' on multiple set arguments, they should first be converted to an ordered sequence so that their relative alignment becomes well-defined.
Given one or more lists as arguments, every(f,[a11,...,a1n],[a21,...],...) evaluates to true if any f(ai1,ai2,...) evaluates to true. 'Every' may or may not evaluate all the f(ai1,ai2,...)'s. Since lists are ordered, 'every' evaluates in the order of increasing 'i'. If the global flag maperror is true (the default), all lists [a11,..a1n], [a21,..], ... must have equal lengths -- otherwise, 'every' signals an error. When the Maxima flag $maperror is false, the list arguments are effectively truncated each to the length of the shortest list.
The Maxima function 'is' automatically applied after evaluating the predicate f; thus the following work correctly
(C1) every("=",[a,b],[a,b]); (D1) TRUE (C2) every("#",[a,b],[a,b]); (D2) FALSE
(C1) extremal_subset(set(-2,-1,0,1,2),abs, max); (D1) {- 2, 2} (C2) extremal_subset(set(sqrt(2), 1.57, %pi/2),sin,min); (D2) {SQRT(2)}
(C2) flatten(f(g(f(f(x))))); (D2) f(g(f(f(x)))) (C3) declare(f,nary); (D3) DONE (C4) ev(d2); (D4) f(g(f(x)))
Applied to a set, flatten gathers all members of set elements that are sets; for example
(C1) flatten(set(a, set(b), set(set(c)))); (D1) {a, b, c} (C2) flatten(set(a,set([a],set(a)))); (D2) {a, [a]}
Flatten works correctly when the main operator is a subscripted function
(C3) flatten(f[5](f[5](x))); (D3) f (x) 5
To flatten an expression, the main operator must be defined for zero or more arguments; if this isn't the case, Maxima will halt with an error. Expressions with special representations, for example CRE expressions, can't be flattened; in this case, flatten returns its argument unchanged.
(C1) fullsetify([a,[a]]); (D1) {a, {a}} (C2) fullsetify([a,f([b])]); (D2) {a, f([b])} (C3)
In line (C2), the argument of f isn't converted to a set because the main operator of f([b]) isn't a list.
To convert just the top-level operator of a list to a set, see setify.
The identity function evaluates to its argument for all inputs. To determine if every member of a set is true, you can use
(C1) every(identity,[true,true]); (D1) TRUE
We say a list [a1,a2,...,am] is a partition of a nonnegative integer n provided (i) each ai is a nonzero integer and (ii) a1 + a2 + ... + am = n. Thus 0 has no partitions.
(C1) integer_partitions(3); (D1) {[1, 1, 1], [1, 2], [3]} (C2) s : integer_partitions(25)$ (C3) cardinality(s); (D3) 1958 (C4) map(lambda([x],apply("+",x)),s); (D4) {25} (C5) integer_partitions(5,3); (D5) {[2, 2, 1], [3, 1, 1], [3, 2, 0], [4, 1, 0], [5, 0, 0]} (C6) integer_partitions(5,2); (D6) {[3, 2], [4, 1], [5, 0]}
To find all partitions that satisfy a condition, use the function subset; here is an example that finds all partitions of 10 that consist of prime numbers
(C1) s : integer_partitions(10)$ (C2) xprimep(x) := integerp(x) and (x > 1) and primep(x)$ (C3) subset(s,lambda([x],every(xprimep,x))); (D3) {[2, 2, 2, 2, 2], [3, 3, 2, 2], [5, 3, 2], [5, 5], [7, 3]}
(Notice that primep(1) is true in Maxima 5.9.0. This disagrees with most definitions of prime.)
The function, kron_delta is declared to be symmetric; thus, for example, kron_delta(i,j) - kron_delta(j,i) evaluates to zero.
Here are a few examples,
(C1) [kron_delta(a,a),kron_delta(a+1,a)]; (D1) [1, 0] (C2) kron_delta(a,b); (D2) KRON_DELTA(a, b)
Assuming that a > b makes sign(|a-b|) evaluate to pos; thus
(C3) assume(a > b)$ (C4) kron_delta(a,b); (D4) 0
If we instead assume that x >= y, then sign(|x-y|) evaluates to pz; in this case, kron_delta(x,y) doesn't simplify
(C5) assume(x >= y)$ (C6) kron_delta(x,y); (D6) KRON_DELTA(x, y)
Finally, since 1/10 - 0.1 evaluates to a floating point number, we have
(C7) kron_delta(1/10,0.1); 1 (D7) KRON_DELTA(--, 0.1) 10
If you want (D7) to evaluate to 1, apply float
(C8) float(%); (D8) 1
(C1) lreduce(f,[1,2,3]); (D1) f(f(1, 2), 3) (C2) lreduce(f,[1,2,3,4]); (D2) f(f(f(1, 2), 3), 4)
Notice that the function f is first applied to the leftmost list elements (thus the name lreduce). When init is defined, the second argument to the inner most function evaluation is init; for example
(C3) lreduce(f,[1,2,3],4); (D3) f(f(f(4, 1), 2), 3)
The function lreduce makes it easy to find the product or sum of the elements of a set or list
(C4)lreduce("+",set(a,b)); (D4) b + a (C5) lreduce("*",set(1,2,3,4,5)); (D5) 120
Unlike most nset functions, when the second argument to @amth{lreduce} is a list, the list isn't coerced to a set. For example
(C6) lreduce(f,[a,a,a]); (D6) f(f(a, a), a) (C7)
See also rreduce, xreduce, and tree_reduce
(C1) makeset(i/j,[i,j],[[a,b],[c,d]]); a c (D1) {-, -} b d (C2) ind : [0,1,2,3]$ (C3) makeset(i^2 + j^2 + k^2, [i,j,k], cartesian_product(ind,ind,ind)); (D3) {0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 17, 18, 19, 22, 27}
(C1) multinomial_coeff(1,2,x); (x + 3)! (D1) -------- 2 x! (C2) minfactorial(%); (x + 1) (x + 2) (x + 3) (D2) ----------------------- 2 (C3) multinomial_coeff(-6,2); (- 4)! (D3) -------- 2 (- 6)! (C4) minfactorial(%); (D4) 10
When n is a nonnegative integer, return the number of distinct integer partitions of n.
If the optional parameter a has the value "list", return a list of the number of distinct partitions of 1,2,3, ... , n. If n isn't a nonnegative integer, return a noun form.
Definition: If n = k1 + k2 + ... + km, where k1 through km are distinct positive integers, we call k1 + k2 + ... + km a distinct partition of n.
(C1) num_partitions(5) = cardinality(integer_partitions(5)); (D1) 7 = 7 (C2) num_partitions(8,list); (D2) [1, 1, 2, 3, 5, 7, 11, 15, 22] (C3) num_partitions(n); (D3) NUM_PARTITIONS(n)
For a nonnegative integer, we should have num_partitions(n) = cardinality(integer_partitions(n)); however, using num_partitions is much faster.
(C1) partition_set(set(2,7,1,8,2,8),evenp); (D1) [{1, 7}, {2, 8}] (C2) partition_set(set(x,rat(y),rat(y)+z,1),lambda([x], ratp(x))); (D2)/R/ [{1, x}, {y, y + z}]
(C1) permutations([a,a]); (D1) {[a, a]} (C2) permutations([a,a,b]); (D2) {[a, a, b], [a, b, a], [b, a, a]} (C3)
If a isn't a list or set, signal an error.
(C1) rreduce(f,[1,2,3]); (D1) f(1, f(2, 3)) (C2) rreduce(f,[1,2,3,4]); (D2) f(1, f(2, f(3, 4)))
Notice that the function f is first applied to the rightmost list elements (thus the name rreduce). When init is defined, the second argument to the inner most function evaluation is init; for example
(C3) rreduce(f,[1,2,3],4); (D3) f(1, f(2, f(3, 4)))
The function rreduce makes it easy to find the product or sum of the elements of a set or list
(C4)rreduce("+",set(a,b)); (D4) b + a (C5) rreduce("*",set(1,2,3,4,5)); (D5) 120
Unlike most nset functions, when the second argument to rreduce is a list, the list isn't coerced to a set. For example
(C6) rreduce(f,[a,a,a]); (D6) f(a, f(a, a)) (C7)
See also lreduce, tree_reduce, and xreduce.
(C1) setp(set(a,a)),simp : false; (D1) TRUE
The function setp could be coded in Maxima as setp(a) := is(inpart(a,0) = set).
We say a set P is a partition of a set S provided
The empty set is a partition of itself (the conditions 1 and 2 being vacuously true); thus
(C1) set_partitions(set()); (D1) {{}}
A few additional examples
(C1) s : set(0,1,2,3,4,5)$ (C2) p : set_partitions(s,3)$
The cardinality of p can be found using stirling2; thus
(C3) cardinality(p) = stirling2(6,3); (D3) 90 = 90
Each member of p should have 3 members; let's check
(C4) map(cardinality,p); (D4) {3}
Finally, for each member of p, the union of its members should equal s; again let's check
(C5) map(lambda([x],apply(union,listify(x))),p); (D5) {{0, 1, 2, 3, 4, 5}}
The first argument f should be a predicate (a function that evaluates to true, false, or unknown).
Given one set as the second argument, some(f, set(a1,...,an)) returns true if any f(ai) evaluates to true. Since sets are unordered, 'some' is free to evaluate f(ai) in any order. 'Some' may or may not evaluate all the f(ai)'s. Because the order of evaluation isn't specified, the predicate f should not have side-effects or signal errors for any input. To use 'some' on multiple set arguments, they should first be converted to an ordered sequence so that their relative alignment becomes well-defined.
Given one or more lists as arguments, some(f,[a11,...,a1n],[a21,...],...) evaluates to true if any f(ai1,ai2,...) evaluates to true. 'Some' may or may not evaluate all the f(ai1,ai2,...)'s. Since lists are ordered, 'some' evaluates in the order of increasing 'i'. If the global flag $maperror is true (the default), all lists [a11,..a1n], [a21,..], ... must have equal lengths -- otherwise, some signals an error. When the Maxima flag $maperror is false, the list arguments are effectively truncated each to the length of the shortest list.
The Maxima function 'is' is automatically applied after evaluating the predicate f; thus the following work correctly
(C1) some("<",[a,b,5],[1,2,8]); (D1) TRUE (C2) some("=",[2,3],[2,7]); (D2) TRUE
The function stirling1 works by simplification; it knows the basic special values (see Donald Knuth, The Art of Computer Programming, third edition, Volume 1, Section 1.2.6, Equations 48, 49, and 50). For Maxima to apply these rules, the arguments must be declared to be integer and the first argument must nonnegative. Here's an example
(C1) declare([n,m],integer)$ (C2) assume(n >= 0)$ (C3) stirling1(n,n); (D3) 1
With a non-integer argument, this simplification isn't made
(C4) stirling1(sqrt(2),sqrt(2)); (D4) STIRLING1(SQRT(2), SQRT(2))
Maxima knows a few other special values; for example
(C5) stirling1(n+1,n); n (n + 1) (D5) --------- 2 (C6) stirling1(n+1,1); (D6) n!
The function stirling2 works by simplification; it knows the basic special values (see Donald Knuth, The Art of Computer Programming, third edition, Volume 1, Section 1.2.6, Equations 48, 49, and 50). For Maxima to apply these rules, the arguments must be declared to be integer and the first argument must nonnegative. Here's an example
(C1) declare([n,m],integer)$ (C2) assume(n >= 0)$ (C3) stirling2(n,n); (D3) 1
With a non-integer argument, this simplification isn't made
(C4) stirling2(%pi,%pi); (D4) STIRLING2(%PI, %PI)
Maxima knows a few other special values; for example
(C5) stirling2(n+9,n+8); (n + 8) (n + 9) (D5) --------------- 2 (C6) stirling2(n+1,2); n (D6) 2 - 1
(C1) subset(set(1,2,x,x+y,z,x+y+z),atom); (D1) {1,2,z} (C2) subset(set(1,2,7,8,9,14),evenp); (D2) {2,8,14}
The second argument to subset must be a Maxima predicate (a boolean-valued function of one argument) if the first argument to subset isn't a list or a set, signal an error. See also partition_set.
The function tree_reduce extends a associative binary operator f : S x S -> S from two arguments to any number of arguments using a minimum depth tree. An example should make this clear
(C1) tree_reduce(f,[a,b,c,d]); (D1) f(f(a, b), f(c, d))
Given an odd number of arguments, tree_reduce "favors" the left side of the tree; for example
(C1) tree_reduce(f,[a,b,c,d,e]); (D1) f(f(f(a, b), f(C, d)), e) (C2)
For addition of floating point numbers, using tree_reduce may give a sum that has a smaller rounding error than using either rreduce or lreduce.
This function is similar to both lreduce and rreduce except that xreduce is free to use either left or right associativity; in particular when f is an associative function and Maxima has a built-in evaluator for it, xreduce may use the nary function; these nary functions include addition, multiplication, 'and', 'or', 'max', 'min', and 'append'. For these operators, we generally expect using xreduce to be faster than using either rreduce or lreduce. When f isn't nary, xreduce uses left-associativity.
Floating point addition is not associative; nevertheless, xreduce uses Maxima's nary addition when the set or list s contains floating point numbers.
This document was generated on 22 December 2003 using the texi2html translator version 1.51a.