Fix #4414: Add url for bug reporting page in bug_report
[maxima.git] / share / simplification / facexp.dem
blob5c910d432abd2e62ff5e5328c9a1e3b091a5b30e
1 /*  First load the necessary file: */
2 load("facexp");
3 /* Here is an expression to work with: */
4 exp1:d*e*f^2+c*e*f^2-d*e+c*e+b*c*d+a*c*d;
5 /* The function FACSUM can be used to cast an expression
6         into a form in which it is fully expanded with respect
7         to a specified set of variables, but factored with
8         respect to all other variables: */
9 facsum(exp1,e,f);
10 /*  For the next example, we use EXP2: */
11 exp2:c*d*(x*y*z+w*y*z+u*v^2*z-u*z+u*v^2*y+u*y)
12         +d*e*f^2+c*e*f^2-d*e+c*e+b*c*d;
13 /* Another mode in which FACSUM is useful results in a form
14          in which a second set of variables plays the same role as
15          above, but one level deeper in the expression.  These var-
16          iables are given to FACSUM in a list. */
17 facsum(exp2,c,d,[u,v]);
18 /*  The list can occur in any position in the argument list: */
19 facsum(exp2,[u,v],c,d);
20 /*  Or it can be split up: */
21 facsum(exp2,c,[u],d,[v]);
22 /*  List arguments can be nested arbitrarily deeply,
23          depending upon the requirements of the situation: */
24 exp3:c*d*q*x*y*z+2*c*d*m*p*x*y*z+c*d*m*n*x*y*z
25         +c*d*q*w*y*z+2*c*d*m*p*w*y*z+c*d*m*n*w*y*z+c*d*q*u*v^2*z
26         +2*c*d*m*p*u*v^2*z+c*d*m*n*u*v^2*z-c*d*q*u*z-2*c*d*m*p*u*z
27         -c*d*m*n*u*z+c*d*u*v^2*y+c*d*u*y+d*e*f^2+c*e*f^2
28         -d*e+c*e+b*c*d;
29 facsum(exp3,c,d,[u,v,[z,[m]]]);
30 /*  The arguments of FACSUM need not be atomic. */
31 exp4:subst(log(m+n),c,exp2);
32 facsum(exp4,log(m+n),[e,f]);
33 /*  FACSUM also recognizes in its argument the special
34          form OPERATOR.  This form can be used to indicate to
35          FACSUM that all structures within its argument that 
36          have certain indicated leading operators are to be
37          specially treated.
38          For example, consider the expression EXP5: */
39 exp5:x+(a.b)*(c+d)+(b.a)*(d+c)+log(a*b)*2*(c+d)+log(a/b)*2*(d+c);
40 /* First FACTOR EXP5, to obtain an expression
41          to work on: */
42 exp5_factored:factor(exp5);
43 /* To demonstrate the use of OPERATOR, we recover the original
44          form of EXP5: */
45 facsum(exp5_factored,operator(log,"."));
46 is(%=exp5);
47 /* This form also works: */
48 facsum(exp5_factored,operator(log),operator("."));
49 /* Another function that is related to FACSUM is
50          FACTORFACSUM.  FACTORFACSUM is similar to FACSUM, except
51          that it first factors the expression, then calls FACSUM 
52          on each of the factors.  It can take all the arguments
53          that FACSUM can, including the nested lists and the form
54          OPERATOR.
55                 To get an expression to work on, we use EXP6: */
56 exp6:exp5*2*(e+(h+f)*(e.f));
57 /* And EXPAND it: */
58 exp6_expanded:expand(exp6);
59 /* To illustrate the use of FACTORFACSUM, we recover the 
60          original form of EXP6: */
61 factorfacsum(exp6_expanded,operator(".",log));
62 is(%=exp6);
63 /* There is a switch NEXTLAYERFACTOR[FALSE]
64          which can be used in two ways to control the behavior
65          of FACSUM.  By setting NEXTLAYERFACTOR:TRUE one can force
66          FACSUM to FACTOR the coefficients of the variables specified
67          at any level before it calls itself recursively on the
68          factors of those coefficients:  */
69 exp7:f*h+f*g-2*c*d*f^2+2*c*d*e^2;
70 facsum(exp7,c,[e]),nextlayerfactor:true;
71 facsum(exp7,c,[e]);
72 /* The second method for controlling the behavior of
73          FACSUM is to include the atom NEXTLAYERFACTOR in the
74          in the argument list of FACSUM: */
75 facsum(exp7,c,'nextlayerfactor,[e]);
76 /* Notice that this method produced the same result as
77          simply setting NEXTLAYERFACTOR:TRUE.  The difference
78          between the two methods is that the second method allows
79          one to achieve the effect of NEXTLAYERFACTOR:TRUE for
80          only a few specified levels of the expression, instead
81          of for all levels.  For example, consider EXP8: */
82 exp8:-2*c*d*f^2*h^2*l^2+f*h^2*l^2-4*c*d*f^2*h^2*k*l
83          +2*f*h^2*k*l-4*c*d*f^2*g*h*l+2*f*g*h*l-2*c*d*f^2*h^2*k^2
84          +f*h^2*k^2-4*c*d*f^2*g*h*k+2*f*g*h*k-2*c*d*f^2*g^2
85          +f*g^2+2*c*d*e^2;
86 facsum(exp8,c,'nextlayerfactor,[f]);
87 facsum(exp8,c,[f,'nextlayerfactor]);
89 /* Another switch FACSUM_COMBINE[TRUE] controls the form
90          returned by FACSUM when its argument has a denominator.
91          If FACSUM_COMBINE is TRUE then the form returned will
92          be a ratio of polynomials.  If FALSE, then the denominator
93          factors will be distributed over the terms of the numerator.
94          In either case, both the numerator and denominator will
95          be processed according to the arguments of FACSUM. */
96 exp1/(c*(e+f)+d*e);
97 facsum(exp1/(c*(e+f)+d*e),e,f,[c,d]);
98 facsum(exp1/(c*(e+f)+d*e),e,f,[c,d]),facsum_combine:false;
99 /* It is also possible to control the form of the coefficients
100          of products of quantities specified in the argument list of
101          FACSUM.  (Normally, these coefficients are factored, unless 
102          they are numbers, and the function that is used for this
103          purpose is called NONUMFACTOR.)  But it is possible to use
104          other functions in place of NONUMFACTOR by changing the
105          AUTOMATIC property of FACSUM.  */
106 get('facsum,'automatic);
107 /*  Let us illustrate this procedure by changing from
108          NONUMFACTOR to SQFR. */
109 put('facsum,'sqfr,'automatic);
110 /*  Now compare the behavior of FACSUM to its former 
111          behavior.  Here is what it did with NONUMFACTOR AUTOMATIC: */
112 playback([5,6])$
113 /* And now with SQFR AUTOMATIC: */
114 facsum(exp2,c,d,[u,v]);
115 /*  Since this particular choice for AUTOMATIC is so
116          useful, it is available as a separate function, SQFRFACSUM.
117          More complicated choices are possible, depending on the
118          requirements of the situation.  One possibility is illustrated
119          below.
120            The AUTOMATIC function can be declared FORMAL.  If this
121          is done, then the function will not be applied, but will
122          be introduced into the expression in the places where it
123          would have been applied.  This capability is useful for
124          constructing expressions that one intends to use later
125          in function definitions.  We illustrate with SQFR:
126          (Maxima: NOUN does the same thing, doesn't it. You can define
127          an alias for it if you want to, see genut.mac). */
128 /* DECLARE(SQFR,FORMAL)$ */
129 declare(sqfr,noun)$
130 facsum(exp2,c,d,[u,v]);
131 /*  Now restore the default AUTOMATIC property: */
132 put('facsum,'nonumfactor,'automatic);
133 /* Sometimes one must combine large expressions that
134          have already been processed with FACSUM, perhaps in different
135          Macsymas for reasons of space.  To combine these expressions
136          it is not necessary to FACSUM their sum.  An alternative is
137          to use COLLECTTERMS.  To illustrate the use of COLLECTTERMS,
138          we use EXP9 and EXP10. */
139 exp9:a*u+b;
140 exp10:c*u+d;
141 /* COLLECTERMS(exp, var1, var2..) collects terms of exp that contain
142          like powers of the vari.  */
143 collectterms(exp9+exp10,u);
144 e*u^2+f/u +b+d;
145 exp11:expand(%+exp10*u);
146 collectterms(%,u);
147 /* Another more complex example: */
148 u^2*v+exp11+subst(v,u,exp11);
149 collectterms(%,u,v);
150 /* COLLECTTERMS also accepts arguments in the same form
151          as FACSUM: */
152 exp2;
153 collectterms(exp2,c,d,[u,v]);
154 exp5_factored;
155 collectterms(exp5_factored,operator(log,"."));