~ubuntu-branches/debian/squeeze/maxima/squeeze

« back to all changes in this revision

Viewing changes to src/defint.lisp

  • Committer: Bazaar Package Importer
  • Author(s): Camm Maguire
  • Date: 2006-10-18 14:52:42 UTC
  • mto: (1.1.5 upstream)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20061018145242-vzyrm5hmxr8kiosf
ImportĀ upstreamĀ versionĀ 5.10.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
;;; -*-  Mode: Lisp; Package: Maxima; Syntax: Common-Lisp; Base: 10 -*- ;;;;
 
1
;; -*-  Mode: Lisp; Package: Maxima; Syntax: Common-Lisp; Base: 10 -*- ;;;;
2
2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3
3
;;;     The data in this file contains enhancments.                    ;;;;;
4
4
;;;                                                                    ;;;;;
8
8
;;;     (c) copyright 1982 massachusetts institute of technology         ;;;
9
9
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
10
10
 
11
 
(in-package "MAXIMA")
 
11
(in-package :maxima)
12
12
(macsyma-module defint)
13
13
 
14
14
;;;          this is the definite integration package. 
15
 
;       defint does definite integration by trying to find an
16
 
;appropriate method for the integral in question.  the first thing that
17
 
;is looked at is the endpoints of the problem. 
18
 
;
19
 
;       i(grand,var,a,b) will be used for integrate(grand,var,a,b)
 
15
;;      defint does definite integration by trying to find an
 
16
;;appropriate method for the integral in question.  the first thing that
 
17
;;is looked at is the endpoints of the problem. 
 
18
;;
 
19
;;      i(grand,var,a,b) will be used for integrate(grand,var,a,b)
20
20
 
21
 
;;references are to evaluation of definite integrals by symbolic
22
 
;;manipulation by paul s. wang.
 
21
;; References are to "Evaluation of Definite Integrals by Symbolic
 
22
;; Manipulation", by Paul S. Wang,
 
23
;; (http://www.lcs.mit.edu/publications/pubs/pdf/MIT-LCS-TR-092.pdf)
23
24
;;
24
25
;;      nointegrate is a macsyma level flag which inhibits indefinite
25
 
;integration.
26
 
;       abconv is a macsyma level flag which inhibits the absolute
27
 
;convergence test.
28
 
;
29
 
;       $defint is the top level function that takes the user input
30
 
;and does minor changes to make the integrand ready for the package.
31
 
;
32
 
;       next comes defint, which is the function that does the
33
 
;integration.  it is often called recursively from the bowels of the
34
 
;package.  defint does some of the easy cases and dispatches to:
35
 
;
36
 
;       dintegrate.  this program first sees if the limits of
37
 
;integration are 0,inf or minf,inf.  if so it sends the problem to
38
 
;ztoinf or mtoinf, respectivly.
39
 
;       else, dintegrate tries:
40
 
;
41
 
;       intsc1 - does integrals of sin's or cos's or exp(%i var)'s
42
 
;                when the interval is 0,2 %pi or 0,%pi.
43
 
;                method is conversion to rational function and find
44
 
;                residues in the unit circle. [wang, pp 107-109]
45
 
;
46
 
;       ratfnt - does rational functions over finite interval by
47
 
;                doing polynomial part directly, and converting
48
 
;                the rational part to an integral on 0,inf and finding
49
 
;                the answer by residues.
50
 
;
51
 
;       zto1   - i(x^(k-1)*(1-x)^(l-1),x,0,1) = beta(k,l)  or
52
 
;                i(log(x)*x^(x-1)*(1-x)^(l-1),x,0,1) = psi...
53
 
;                [wang, pp 116,117]
54
 
;
55
 
;       dintrad- i(x^m/(a*x^2+b*x+c)^(n+3/2),x,0,inf) [wang, p 74]
56
 
;
57
 
;       dintlog- i(log(g(x))*f(x),x,0,inf) = 0 (by symetry) or
58
 
;                tries an integration by parts.  (only routine to
59
 
;                try integration by parts) [wang, pp 93-95]
60
 
;
61
 
;       dintexp- i(f(exp(x)),x,a,b) = i(f(x+1),x,a',b')
62
 
;
63
 
;dintegrate also tries indefinite integration based on certain 
64
 
;predicates (such as abconv) and tries breaking up the integrand
65
 
;over a sum or tries a change of variable.
66
 
;
67
 
;       ztoinf is the routine for doing integrals over the range 0,inf.
68
 
;          it goes over a series of routines and sees if any will work:
69
 
;
70
 
;          scaxn  - sc(b*x^n) (sc stands for sin or cos) [wang, pp 81-83]
71
 
;
72
 
;          ssp    - a*sc^n(r*x)/x^m  [wang, pp 83,84]
73
 
;
74
 
;          zmtorat- rational function. done by multiplication by plog(-x)
75
 
;                   and finding the residues over the keyhole contour
76
 
;                   [wang, pp 59-61]
77
 
;
78
 
;          log*rat- r(x)*log^n(x) [wang, pp 89-92]
79
 
;
80
 
;          logquad0 log(x)/(a*x^2+b*x+c) uses formula
81
 
;                   i(log(x)/(x^2+2*x*a*cos(t)+a^2),x,0,inf) =
82
 
;                   t*log(a)/sin(t).  a better formula might be
83
 
;                   i(log(x)/(x+b)/(x+c),x,0,inf) = 
84
 
;                   (log^2(b)-log^2(c))/(2*(b-c))
85
 
;
86
 
;          batapp - x^(p-1)/(b*x^n+a)^m uses formula related to the beta
87
 
;                   function [wang, p 71]
88
 
;                   there is also a special case when m=1 and a*b<0
89
 
;                   see [wang, p 65]
90
 
;
91
 
;          sinnu  - x^-a*n(x)/d(x) [wang, pp 69-70]
92
 
;
93
 
;          ggr    - x^r*exp(a*x^n+b) 
94
 
;
95
 
;          dintexp- see dintegrate
96
 
;
97
 
;     ztoinf also tries 1/2*mtoinf if the integrand is an even function
98
 
;
99
 
; mtoinf is the routine for doing integrals on minf,inf.  
100
 
;        it too tries a series of routines and sees if any succeed.
101
 
;
102
 
;        scaxn  - when the integrand is an even function, see ztoinf
103
 
;
104
 
;        mtosc  - exp(%i*m*x)*r(x) by residues on either the upper half
105
 
;                 plane or the lower half plane, depending on whether
106
 
;                 m is positive or negative.
107
 
;
108
 
;        zmtorat- does rational function by finding residues in upper
109
 
;                 half plane
110
 
;
111
 
;        dintexp- see dintegrate
112
 
;
113
 
;        rectzto%pi2 - poly(x)*rat(exp(x)) by finding residues in
114
 
;                      rectangle [wang, pp98-100]
115
 
;
116
 
;        ggrm   - x^r*exp((x+a)^n+b)
117
 
;
118
 
;   mtoinf also tries 2*ztoinf if the integrand is an even function.
 
26
;;integration.
 
27
;;      abconv is a macsyma level flag which inhibits the absolute
 
28
;;convergence test.
 
29
;;
 
30
;;      $defint is the top level function that takes the user input
 
31
;;and does minor changes to make the integrand ready for the package.
 
32
;;
 
33
;;      next comes defint, which is the function that does the
 
34
;;integration.  it is often called recursively from the bowels of the
 
35
;;package.  defint does some of the easy cases and dispatches to:
 
36
;;
 
37
;;      dintegrate.  this program first sees if the limits of
 
38
;;integration are 0,inf or minf,inf.  if so it sends the problem to
 
39
;;ztoinf or mtoinf, respectivly.
 
40
;;      else, dintegrate tries:
 
41
;;
 
42
;;      intsc1 - does integrals of sin's or cos's or exp(%i var)'s
 
43
;;               when the interval is 0,2 %pi or 0,%pi.
 
44
;;               method is conversion to rational function and find
 
45
;;               residues in the unit circle. [wang, pp 107-109]
 
46
;;
 
47
;;      ratfnt - does rational functions over finite interval by
 
48
;;               doing polynomial part directly, and converting
 
49
;;               the rational part to an integral on 0,inf and finding
 
50
;;               the answer by residues.
 
51
;;
 
52
;;      zto1   - i(x^(k-1)*(1-x)^(l-1),x,0,1) = beta(k,l)  or
 
53
;;               i(log(x)*x^(x-1)*(1-x)^(l-1),x,0,1) = psi...
 
54
;;               [wang, pp 116,117]
 
55
;;
 
56
;;      dintrad- i(x^m/(a*x^2+b*x+c)^(n+3/2),x,0,inf) [wang, p 74]
 
57
;;
 
58
;;      dintlog- i(log(g(x))*f(x),x,0,inf) = 0 (by symetry) or
 
59
;;               tries an integration by parts.  (only routine to
 
60
;;               try integration by parts) [wang, pp 93-95]
 
61
;;
 
62
;;      dintexp- i(f(exp(k*x)),x,a,inf) = i(f(x+1)/(x+1),x,0,inf)
 
63
;;               or i(f(x)/x,x,0,inf)/k. First case hold for a=0;
 
64
;;               the second for a=minf. [wang 96-97]
 
65
;;
 
66
;;dintegrate also tries indefinite integration based on certain 
 
67
;;predicates (such as abconv) and tries breaking up the integrand
 
68
;;over a sum or tries a change of variable.
 
69
;;
 
70
;;      ztoinf is the routine for doing integrals over the range 0,inf.
 
71
;;          it goes over a series of routines and sees if any will work:
 
72
;;
 
73
;;         scaxn  - sc(b*x^n) (sc stands for sin or cos) [wang, pp 81-83]
 
74
;;
 
75
;;         ssp    - a*sc^n(r*x)/x^m  [wang, pp 86,87]
 
76
;;
 
77
;;         zmtorat- rational function. done by multiplication by plog(-x)
 
78
;;                  and finding the residues over the keyhole contour
 
79
;;                  [wang, pp 59-61]
 
80
;;
 
81
;;         log*rat- r(x)*log^n(x) [wang, pp 89-92]
 
82
;;
 
83
;;         logquad0 log(x)/(a*x^2+b*x+c) uses formula
 
84
;;                  i(log(x)/(x^2+2*x*a*cos(t)+a^2),x,0,inf) =
 
85
;;                  t*log(a)/sin(t).  a better formula might be
 
86
;;                  i(log(x)/(x+b)/(x+c),x,0,inf) = 
 
87
;;                  (log^2(b)-log^2(c))/(2*(b-c))
 
88
;;
 
89
;;         batapp - x^(p-1)/(b*x^n+a)^m uses formula related to the beta
 
90
;;                  function [wang, p 71]
 
91
;;                  there is also a special case when m=1 and a*b<0
 
92
;;                  see [wang, p 65]
 
93
;;
 
94
;;          sinnu  - x^-a*n(x)/d(x) [wang, pp 69-70]
 
95
;;
 
96
;;         ggr    - x^r*exp(a*x^n+b) 
 
97
;;
 
98
;;         dintexp- see dintegrate
 
99
;;
 
100
;;     ztoinf also tries 1/2*mtoinf if the integrand is an even function
 
101
;;
 
102
;; mtoinf is the routine for doing integrals on minf,inf.  
 
103
;;        it too tries a series of routines and sees if any succeed.
 
104
;;
 
105
;;       scaxn  - when the integrand is an even function, see ztoinf
 
106
;;
 
107
;;       mtosc  - exp(%i*m*x)*r(x) by residues on either the upper half
 
108
;;                plane or the lower half plane, depending on whether
 
109
;;                m is positive or negative.
 
110
;;
 
111
;;       zmtorat- does rational function by finding residues in upper
 
112
;;                half plane
 
113
;;
 
114
;;       dintexp- see dintegrate
 
115
;;
 
116
;;       rectzto%pi2 - poly(x)*rat(exp(x)) by finding residues in
 
117
;;                     rectangle [wang, pp98-100]
 
118
;;
 
119
;;       ggrm   - x^r*exp((x+a)^n+b)
 
120
;;
 
121
;;   mtoinf also tries 2*ztoinf if the integrand is an even function.
119
122
 
120
123
(load-macsyma-macros rzmac)
121
124
 
122
 
(DECLARE-TOP(*lexpr $DIFF $LIMIT $SUBSTITUTE $EZGCD $RATSIMP context)
123
 
         (*expr subfunmake $coeff $logcontract $radcan $makegamma
124
 
                $constantp $subvarp MAXIMA-SUBSTITUTE freeof ith
125
 
                $oddp $hipow $multthru $xthru $num $denom 
126
 
                stripdollar MAXIMA-FIND sdiff partition
127
 
                constant free mapatom
128
 
 
129
 
                $ratdisrep ratdisrep $ratp ratp ratnumerator 
130
 
                sratsimp ratdenominator $ratsubst ratnump ratcoef
131
 
                pterm rdis pdis ratrep newvar pdivide pointergp
132
 
                      
133
 
                $factor factor $sqfr oddelm zerop1
134
 
 
135
 
                $asksign asksign $sign ask-integer assume forget
136
 
                      
137
 
                $residue residue res res1 polelist partnum
138
 
 
139
 
                solve solvex sinint
140
 
                      
141
 
                $rectform $realpart $imagpart trisplit cabs
142
 
                      
143
 
                among involve notinvolve  
144
 
                numden* ratgreaterp
145
 
                subin polyinx genfind xor fmt polyp numden andmapcar
146
 
                abless1 even1 rddeg tansc radicalp deg simplerd
147
 
                no-err-sub oscip %einvolve sin-sq-cos-sq-sub)
 
125
(declare-top(*lexpr $diff $limit $substitute $ezgcd $ratsimp context)
 
126
            (*expr subfunmake $coeff $logcontract $radcan $makegamma
 
127
                   $constantp $subvarp maxima-substitute freeof ith
 
128
                   $oddp $hipow $multthru $xthru $num $denom 
 
129
                   stripdollar maxima-find sdiff partition
 
130
                   constant free mapatom
 
131
 
 
132
                   $ratdisrep ratdisrep $ratp ratp ratnumerator 
 
133
                   sratsimp ratdenominator $ratsubst ratnump ratcoef
 
134
                   pterm rdis pdis ratrep newvar pdivide pointergp
 
135
                      
 
136
                   $factor factor $sqfr oddelm zerop1
 
137
 
 
138
                   $asksign asksign $sign ask-integer assume forget
 
139
                      
 
140
                   $residue residue res res1 polelist partnum
 
141
 
 
142
                   solve solvex sinint
 
143
                      
 
144
                   $rectform $realpart $imagpart trisplit cabs
 
145
                      
 
146
                   among involve notinvolve  
 
147
                   numden* ratgreaterp
 
148
                   subin polyinx genfind xor fmt polyp numden andmapcar
 
149
                   abless1 even1 rddeg tansc radicalp deg simplerd
 
150
                   no-err-sub oscip %einvolve sin-sq-cos-sq-sub)
148
151
                      
149
152
;;;rsn* is in comdenom. does a ratsimp of numerator.
150
 
         (SPECIAL *DEF2* PCPRNTD MTOINF* RSN* SEMIRAT*
151
 
                  SN* SD* LEADCOEF CHECKFACTORS 
152
 
                  *NODIVERG RD* EXP1
153
 
                  UL1 LL1 *DFLAG BPTU BPTD PLM* ZN ZD
154
 
                  *UPDN UL LL EXP PE* PL* RL* PL*1 RL*1
155
 
                  LOOPSTOP* VAR NN* ND* DN* p*
156
 
                  IND* FACTORS RLM*
157
 
                  PLOGABS *ZEXPTSIMP? SCFLAG
158
 
                  sin-cos-recur rad-poly-recur dintlog-recur
159
 
                  dintexp-recur defintdebug defint-assumptions
160
 
                  current-assumptions
161
 
                  global-defint-assumptions)
 
153
            (special *def2* pcprntd *mtoinf* rsn* semirat*
 
154
                     sn* sd* leadcoef checkfactors 
 
155
                     *nodiverg rd* exp1
 
156
                     *ul1* *ll1* *dflag bptu bptd plm* zn
 
157
                     #+nil zd
 
158
                     *updn ul ll exp pe* pl* rl* pl*1 rl*1
 
159
                     loopstop* var nn* nd* dn* p*
 
160
                     ind* factors rlm*
 
161
                     plogabs *zexptsimp? *scflag*
 
162
                     *sin-cos-recur* *rad-poly-recur* *dintlog-recur*
 
163
                     *dintexp-recur* defintdebug *defint-assumptions*
 
164
                     *current-assumptions*
 
165
                     *global-defint-assumptions*)
162
166
         
163
 
         (ARRAY* (NOTYPE *I* 1 *J* 1))
164
 
         (GENPREFIX DEF)
165
 
         (muzzled t)
166
 
         ;expvar
167
 
         (special $intanalysis $abconvtest $noprincipal $nointegrate)
168
 
         ;impvar
169
 
         (special $solveradcan $solvetrigwarn *roots *failures 
170
 
                 $logabs $tlimswitch $maxposex $maxnegex
171
 
                 $trigsign $savefactors $radexpand $breakup $%emode
172
 
                 $float $exptsubst dosimp context rp-polylogp
173
 
                 %P%I HALF%PI %PI2 HALF%PI3 VARLIST genvar
174
 
                 $domain $m1pbranch errorsw errrjfflag raterr
175
 
                 limitp $algebraic
176
 
                 ;;LIMITP T Causes $ASKSIGN to do special things
177
 
                 ;;For DEFINT like eliminate epsilon look for prin-inf
178
 
                 ;;take realpart and imagpart.
179
 
                 integer-info
180
 
                 ;;If LIMITP is non-null ask-integer conses 
181
 
                 ;;its assumptions onto this list.
182
 
                 generate-atan2))
183
 
                           ;If this switch is () then RPART returns ATAN's
184
 
                           ;instead of ATAN2's
 
167
            (array* (notype *i* 1 *j* 1))
 
168
            (genprefix def)
 
169
            (muzzled t)
 
170
                                        ;expvar
 
171
            (special $intanalysis $abconvtest $noprincipal $nointegrate)
 
172
                                        ;impvar
 
173
            (special $solveradcan $solvetrigwarn *roots *failures 
 
174
                     $logabs $tlimswitch $maxposex $maxnegex
 
175
                     $trigsign $savefactors $radexpand $breakup $%emode
 
176
                     $float $exptsubst dosimp context rp-polylogp
 
177
                     %p%i half%pi %pi2 half%pi3 varlist genvar
 
178
                     $domain $m1pbranch errorsw errrjfflag raterr
 
179
                     limitp $algebraic
 
180
                     ;;LIMITP T Causes $ASKSIGN to do special things
 
181
                     ;;For DEFINT like eliminate epsilon look for prin-inf
 
182
                     ;;take realpart and imagpart.
 
183
                     integer-info
 
184
                     ;;If LIMITP is non-null ask-integer conses 
 
185
                     ;;its assumptions onto this list.
 
186
                     generate-atan2))
 
187
                                        ;If this switch is () then RPART returns ATAN's
 
188
                                        ;instead of ATAN2's
185
189
 
186
190
(declare-top(special infinities real-infinities infinitesimals))
187
 
(cond ;These are really defined in LIMIT but DEFINT uses them also.
 
191
(cond    ;These are really defined in LIMIT but DEFINT uses them also.
188
192
  ((not (boundp 'infinities))
189
 
  (setq INFINITIES '($INF $MINF $INFINITY))
190
 
  (setq REAL-INFINITIES '($INF $MINF))
191
 
  (setq INFINITESIMALS '($ZEROA $ZEROB))))
 
193
   (setq infinities '($inf $minf $infinity))
 
194
   (setq real-infinities '($inf $minf))
 
195
   (setq infinitesimals '($zeroa $zerob))))
192
196
 
193
197
(defmvar defintdebug () "If true Defint prints out debugging information")
194
198
 
195
 
(DEFMVAR INTEGERL NIL
196
 
  "An integer-list for non-atoms found out to be INTEGERs")
197
 
 
198
 
(DEFMVAR NONINTEGERL NIL
199
 
  "A non-integer-list for non-atoms found out to be NONINTEGERs")
200
 
 
201
 
(DEFUN $DEFINT (EXP VAR LL UL)
202
 
 (let ((global-defint-assumptions ())
203
 
       (integer-info ()) (integerl integerl) (nonintegerl nonintegerl))
204
 
 (with-new-context (context)
205
 
 (unwind-protect
206
 
       (let ((defint-assumptions ())  (*def2* ())  (rad-poly-recur ())
207
 
             (sin-cos-recur ())  (dintexp-recur ())  (dintlog-recur 0.)
208
 
             (ans nil)  (orig-exp exp)  (orig-var var)
209
 
             (orig-ll ll)  (orig-ul ul) 
210
 
             (pcprntd nil)  (*NODIVerg nil)  ($logabs t)  (limitp t)
211
 
             (rp-polylogp ())
212
 
             ($domain '$real) ($m1pbranch ())) ;Try this out.
213
 
 
214
 
            (FIND-FUNCTION '$LIMIT)
215
 
            (make-global-assumptions) ;sets global-defint-assumptions
216
 
            (FIND-FUNCTION '$RESIDUE)
217
 
            (SETQ EXP (RATDISREP EXP))
218
 
            (SETQ VAR (RATDISREP VAR))
219
 
            (SETQ LL (RATDISREP LL))
220
 
            (SETQ UL (RATDISREP UL))
221
 
            (COND (($CONSTANTP VAR)
222
 
                   (merror "Variable of integration not a variable: ~M"
223
 
                           VAR))
224
 
                  (($SUBVARP VAR)  (SETQ VAR (STRIPDOLLAR (CAAR VAR)))
225
 
                                   (SETQ EXP ($SUBSTITUTE VAR orig-VAR EXP))))
226
 
            (COND ((NOT (ATOM VAR))
227
 
                   (merror "Improper variable of integration: ~M" VAR))
228
 
                  ((OR (AMONG VAR UL)
229
 
                       (AMONG VAR LL)) 
230
 
                   (SETQ VAR (STRIPDOLLAR VAR))
231
 
                   (SETQ EXP ($SUBSTITUTE VAR orig-VAR EXP))))
232
 
            (cond ((not (equal ($ratsimp ($imagpart ll)) 0))
233
 
                   (merror "Defint: Lower limit of integration must be real."))
234
 
                  ((not (equal ($ratsimp ($imagpart ul)) 0))
235
 
                   (merror
236
 
                    "Defint: Upper limit of integration must be real.")))
237
 
 
238
 
            (COND ((SETQ ANS (DEFINT EXP VAR LL UL))
239
 
                   (SETQ ANS (SUBST orig-VAR VAR ANS))
240
 
                   (COND ((atom ans)  ans)
241
 
                         ((and (free ans '%limit)
242
 
                               (free ans '%integrate)
243
 
                               (OR (not (free ans '$INF))
244
 
                                   (not (free ans '$MINF))
245
 
                                   (not (free ans '$INFINITY))))
246
 
                          (diverg))
247
 
                         ((not (free ans '$und))
248
 
                         `((%integrate) ,orig-exp ,orig-var ,orig-ll ,orig-ul))
249
 
                              (t ANS)))
250
 
                  (t `((%integrate) ,orig-exp ,orig-var ,orig-ll ,orig-ul))))
251
 
       (forget-global-assumptions)))))
252
 
 
253
 
(DEFUN EEZZ (EXP LL UL)
254
 
       (COND ((OR (polyinx EXP VAR nil)
255
 
                  (CATCH 'PIN%EX (PIN%EX EXP)))
256
 
              (SETQ EXP (ANTIDERIV EXP))
257
 
;;;If antideriv can't do it, returns nil
258
 
;;;use limit to evaluate every answer returned by antideriv.
259
 
              (COND ((NULL EXP) NIL)
260
 
                    (t (INTSUBS EXP LL UL))))))
 
199
(defmvar integerl nil
 
200
  "An integer-list for non-atoms found out to be `integer's")
 
201
 
 
202
(defmvar nonintegerl nil
 
203
  "A non-integer-list for non-atoms found out to be `noninteger's")
 
204
 
 
205
(defun $defint (exp var ll ul)
 
206
  (let ((*global-defint-assumptions* ())
 
207
        (integer-info ()) (integerl integerl) (nonintegerl nonintegerl))
 
208
    (with-new-context (context)
 
209
      (unwind-protect
 
210
           (let ((*defint-assumptions* ())  (*def2* ())  (*rad-poly-recur* ())
 
211
                 (*sin-cos-recur* ())  (*dintexp-recur* ())  (*dintlog-recur* 0.)
 
212
                 (ans nil)  (orig-exp exp)  (orig-var var)
 
213
                 (orig-ll ll)  (orig-ul ul) 
 
214
                 (pcprntd nil)  (*nodiverg nil)  ($logabs t)  (limitp t)
 
215
                 (rp-polylogp ())
 
216
                 ($domain '$real) ($m1pbranch ())) ;Try this out.
 
217
 
 
218
             (find-function '$limit)
 
219
             (make-global-assumptions) ;sets *global-defint-assumptions*
 
220
             (find-function '$residue)
 
221
             (setq exp (ratdisrep exp))
 
222
             (setq var (ratdisrep var))
 
223
             (setq ll (ratdisrep ll))
 
224
             (setq ul (ratdisrep ul))
 
225
             (cond (($constantp var)
 
226
                    (merror "Variable of integration not a variable: ~M"
 
227
                            var))
 
228
                   (($subvarp var)  (setq var (stripdollar (caar var)))
 
229
                    (setq exp ($substitute var orig-var exp))))
 
230
             (cond ((not (atom var))
 
231
                    (merror "Improper variable of integration: ~M" var))
 
232
                   ((or (among var ul)
 
233
                        (among var ll)) 
 
234
                    (setq var (stripdollar var))
 
235
                    (setq exp ($substitute var orig-var exp))))
 
236
             (cond ((not (equal ($ratsimp ($imagpart ll)) 0))
 
237
                    (merror "Defint: Lower limit of integration must be real."))
 
238
                   ((not (equal ($ratsimp ($imagpart ul)) 0))
 
239
                    (merror
 
240
                     "Defint: Upper limit of integration must be real.")))
 
241
 
 
242
             (cond ((setq ans (defint exp var ll ul))
 
243
                    (setq ans (subst orig-var var ans))
 
244
                    (cond ((atom ans)  ans)
 
245
                          ((and (free ans '%limit)
 
246
                                (free ans '%integrate)
 
247
                                (or (not (free ans '$inf))
 
248
                                    (not (free ans '$minf))
 
249
                                    (not (free ans '$infinity))))
 
250
                           (diverg))
 
251
                          ((not (free ans '$und))
 
252
                           `((%integrate) ,orig-exp ,orig-var ,orig-ll ,orig-ul))
 
253
                          (t ans)))
 
254
                   (t `((%integrate) ,orig-exp ,orig-var ,orig-ll ,orig-ul))))
 
255
        (forget-global-assumptions)))))
 
256
 
 
257
(defun eezz (exp ll ul)
 
258
  (cond ((or (polyinx exp var nil)
 
259
             (catch 'pin%ex (pin%ex exp)))
 
260
         (setq exp (antideriv exp))
 
261
         ;; If antideriv can't do it, returns nil
 
262
         ;; use limit to evaluate every answer returned by antideriv.
 
263
         (cond ((null exp) nil)
 
264
               (t (intsubs exp ll ul))))))
261
265
;;;Hack the expression up for exponentials.
262
266
 
263
267
(defun sinintp (expr var)
264
 
;;; Is this expr a candidate for SININT ?
265
 
       (let ((expr (factor expr))
266
 
             (numer nil)
267
 
             (denom nil))
268
 
            (setq numer ($num expr))
269
 
            (setq denom ($denom expr))
270
 
            (cond ((polyinx numer var nil)
271
 
                   (cond ((and (polyinx denom var nil)
272
 
                               (deg-lessp denom var 2))
273
 
                          t)))
274
 
;;;ERF type things go here.
275
 
                  ((let ((exponent (%einvolve numer)))
276
 
                        (and (polyinx exponent var nil)
277
 
                             (deg-lessp exponent var 2)))
278
 
                   (cond ((free denom var)
279
 
                          t))))))
 
268
  ;; Is this expr a candidate for SININT ?
 
269
  (let ((expr (factor expr))
 
270
        (numer nil)
 
271
        (denom nil))
 
272
    (setq numer ($num expr))
 
273
    (setq denom ($denom expr))
 
274
    (cond ((polyinx numer var nil)
 
275
           (cond ((and (polyinx denom var nil)
 
276
                       (deg-lessp denom var 2))
 
277
                  t)))
 
278
          ;;ERF type things go here.
 
279
          ((let ((exponent (%einvolve numer)))
 
280
             (and (polyinx exponent var nil)
 
281
                  (deg-lessp exponent var 2)))
 
282
           (cond ((free denom var)
 
283
                  t))))))
280
284
 
281
285
(defun deg-lessp (expr var power)
282
 
       (cond  ((or (atom expr) 
283
 
                   (mnump expr)) t)
284
 
              ((or (mtimesp expr) 
285
 
                   (mplusp expr))
286
 
               (do ((ops (cdr expr) (cdr ops)))
287
 
                   ((null ops) t)
288
 
                   (cond ((not (deg-lessp (car ops) var power))
289
 
                          (return ())))))
290
 
              ((mexptp expr)
291
 
               (and (or (not (alike1 (cadr expr) var))
292
 
                        (and (numberp (caddr expr))
293
 
                             (not (eq (asksign (m+ power (m- (caddr expr))))
294
 
                                      '$negative))))
295
 
                    (deg-lessp (cadr expr) var power)))))
 
286
  (cond  ((or (atom expr) 
 
287
              (mnump expr)) t)
 
288
         ((or (mtimesp expr) 
 
289
              (mplusp expr))
 
290
          (do ((ops (cdr expr) (cdr ops)))
 
291
              ((null ops) t)
 
292
            (cond ((not (deg-lessp (car ops) var power))
 
293
                   (return ())))))
 
294
         ((mexptp expr)
 
295
          (and (or (not (alike1 (cadr expr) var))
 
296
                   (and (numberp (caddr expr))
 
297
                        (not (eq (asksign (m+ power (m- (caddr expr))))
 
298
                                 '$negative))))
 
299
               (deg-lessp (cadr expr) var power)))
 
300
         ((and (consp expr)
 
301
               (member 'array (car expr))
 
302
               (not (eq var (caar expr))))
 
303
          ;; We have some subscripted variable that's not our variable
 
304
          ;; (I think), so it's deg-lessp.
 
305
          ;;
 
306
          ;; FIXME: Is this the best way to handle this?  Are there
 
307
          ;; other cases we're mising here?
 
308
          t)))
296
309
 
297
 
(DEFUN ANTIDERIV (A)
298
 
       (let ((limitp ())
299
 
             (Ans ())
300
 
             (generate-atan2 ()))
301
 
         (setq ans (SININT A VAR))
302
 
         (COND ((AMONG '%INTEGRATE Ans)  NIL) 
303
 
               (T (SIMPLIFY Ans)))))
 
310
(defun antideriv (a)
 
311
  (let ((limitp ())
 
312
        (ans ())
 
313
        (generate-atan2 ()))
 
314
    (setq ans (sinint a var))
 
315
    (cond ((among '%integrate ans)  nil) 
 
316
          (t (simplify ans)))))
304
317
 
305
318
;;;This routine tries to take a limit a couple of ways.
306
319
(defmfun get-limit nargs
310
323
          (t (cond ((and (or (equal nargs 3) (equal nargs 4))
311
324
                         (memq (setq val (arg 3)) '($inf $minf)))
312
325
                    (setq var (arg 2))
313
 
                    (setq exp (MAXIMA-SUBSTITUTE (m^t var -1) var (arg 1)))
 
326
                    (setq exp (maxima-substitute (m^t var -1) var (arg 1)))
314
327
                    (cond ((eq val '$inf)  (setq dir '$plus))
315
328
                          (t (setq dir '$minus)))
316
 
                    ;(setq ans (apply 'limit-no-err `(,exp ,var 0 ,dir)))
 
329
                                        ;(setq ans (apply 'limit-no-err `(,exp ,var 0 ,dir)))
317
330
                    (setq ans (limit-no-err exp var 0 dir))
318
331
                    (cond ((not (among '%limit ans))  ans)
319
332
                          (t ()))))))))
320
333
 
321
 
;(defun limit-no-err nargs
322
 
;  (let ((errorsw t)  (ans ()))
323
 
;    (setq ans (catch 'errorsw (apply '$limit (listify nargs))))
324
 
;    (cond ((not (eq ans t))  ans)
325
 
;         (t nil))))
 
334
;;(defun limit-no-err nargs
 
335
;;  (let ((errorsw t)  (ans ()))
 
336
;;    (setq ans (catch 'errorsw (apply '$limit (listify nargs))))
 
337
;;    (cond ((not (eq ans t))  ans)
 
338
;;        (t nil))))
326
339
(defun limit-no-err (&rest argvec)
327
340
  (declare (special errorsw))
328
341
  (let ((errorsw t) (ans nil))
329
342
    (setq ans (catch 'errorsw (apply '$limit argvec)))
330
343
    (if (eq ans t) nil ans)))
331
344
 
332
 
(DEFUN INTCV (NV IND FLAG)
333
 
  (let ((D (bx**n+a nv))
334
 
        (*ROOTS ())  (*FAILURES ())  ($BREAKUP ()))
335
 
    (cond ((AND (EQ UL '$INF)
336
 
                (EQUAL LL 0)
337
 
                (EQUAL (CADR D) 1)) ())
338
 
          (t (SOLVE (m+t 'YX (m*t -1. NV)) VAR 1.)
339
 
             (COND (*ROOTS (SETQ D (SUBST VAR 'YX (CADDAR *ROOTS)))
340
 
                           (COND (FLAG (INTCV2 D IND NV))
341
 
                                 (T (INTCV1 D IND NV))))
 
345
#+nil
 
346
(defun intcv (nv ind flag)
 
347
  (let ((d (bx**n+a nv))
 
348
        (*roots ())  (*failures ())  ($breakup ()))
 
349
    (cond ((and (eq ul '$inf)
 
350
                (equal ll 0)
 
351
                (equal (cadr d) 1)) ())
 
352
          (t (solve (m+t 'yx (m*t -1. nv)) var 1.)
 
353
             (format t "*roots = ~A~%" *roots)
 
354
             (format t "subst ~A~%" (caddar *roots))
 
355
             (cond (*roots
 
356
                    (setq d (subst var 'yx (caddar *roots)))
 
357
                    (format t "d = ~A~%" d)
 
358
                    (cond (flag (intcv2 d ind nv))
 
359
                          (t (intcv1 d ind nv))))
342
360
                   (t ()))))))
343
361
 
344
 
(DEFUN INTCV1 (D IND NV) 
345
 
       (COND ((AND (INTCV2 D IND NV)
346
 
                   (NOT (alike1 LL1 UL1)))
347
 
              (let ((*DEF2* t))
348
 
                   (DEFINT EXP1 VAR LL1 UL1)))))
349
 
 
350
 
(DEFUN INTCV2 (D IND NV)
351
 
       (INTCV3 D IND NV)
352
 
       (AND (COND ((AND (ZEROP1 (m+ LL UL))
353
 
                        (EVENFN NV VAR))
354
 
                   (SETQ EXP1 (m* 2 EXP1)
355
 
                         LL1 (LIMCP NV VAR 0 '$PLUS)))
356
 
                  (T (SETQ LL1 (LIMCP NV VAR LL '$PLUS))))
357
 
            (SETQ UL1 (LIMCP NV VAR UL '$MINUS))))
358
 
 
359
 
(DEFUN LIMCP (A B C D) 
360
 
       (let ((Ans ($LIMIT A B C D)))
361
 
            (COND ((NOT (OR (null ans)
362
 
                            (among '%limit ans)
363
 
                            (AMONG '$IND Ans)
364
 
                            (AMONG '$UND Ans)))
365
 
                   Ans))))
366
 
 
367
 
(DEFUN INTCV3 (D IND NV)
368
 
       (SETQ NN* ($RATSIMP (SDIFF D VAR)))
369
 
       (SETQ EXP1 (SUBST 'YX NV EXP))
370
 
       (SETQ EXP1 (m* NN* (COND (IND EXP)
371
 
                                (T (SUBST D VAR EXP1)))))
372
 
       (SETQ EXP1 (sRATSIMP (SUBST VAR 'YX EXP1))))
373
 
 
374
 
(DEFUN DEFINT (EXP VAR LL UL)
375
 
 (let ((old-assumptions defint-assumptions)  (current-assumptions ()))
376
 
  (unwind-protect
377
 
   (prog ()
378
 
      (setq current-assumptions (make-defint-assumptions 'noask))
379
 
      (let ((exp (resimplify exp))            
380
 
            (var (resimplify var))
381
 
            ($exptsubst t)
382
 
            (loopstop* 0)
383
 
            ;; D (not used? -- cwh)
384
 
            ANS NN* DN* ND* $NOPRINCIPAL)
385
 
           (cond ((setq ans (defint-list exp var ll ul))
386
 
                  (return ans))
387
 
                 ((OR (ZEROP1 EXP)
388
 
                      (ALIKE1 UL LL))
389
 
                  (RETURN 0.))
390
 
                 ((NOT (AMONG VAR EXP))
391
 
                  (COND ((OR (MEMQ UL '($INF $MINF))
392
 
                             (MEMQ LL '($INF $MINF)))
393
 
                         (Diverg))
394
 
                        (T (SETQ ANS (m* EXP (m+ UL (m- LL))))
395
 
                           (return ANS)))))
396
 
           (let* ((EXP (RMCONST1 EXP))
397
 
                  (C (CAR EXP))
398
 
                  (EXP (%i-out-of-denom (CDR EXP))))
399
 
             (COND ((AND (NOT $NOINTEGRATE)
400
 
                         (NOT (ATOM EXP))
401
 
                         (or (among 'mqapply exp)
402
 
                             (NOT (MEMQ (CAAR EXP)
403
 
                                        '(MEXPT MPLUS MTIMES %SIN %COS
404
 
                                                %TAN %SINH %COSH %TANH
405
 
                                                %LOG %ASIN %ACOS %ATAN
406
 
                                                %COT %ACOT %SEC 
407
 
                                                %ASEC %CSC %ACSC 
408
 
                                                %DERIVATIVE)))))
409
 
                    (COND ((SETQ ANS (ANTIDERIV EXP))
410
 
                           (SETQ ANS (INTSUBS ANS LL UL))
411
 
                           (return (m* C ANS)))
412
 
                          (t (return nil)))))
413
 
             (SETQ EXP (TANSC EXP))
414
 
             (cond ((setq  ans (initial-analysis exp var ll ul))
415
 
                    (return (m* c ans))))
416
 
             (return nil))))
417
 
   (restore-defint-assumptions old-assumptions current-assumptions))))
 
362
(defun intcv (nv ind flag)
 
363
  (let ((d (bx**n+a nv))
 
364
        (*roots ())  (*failures ())  ($breakup ()))
 
365
    (cond ((and (eq ul '$inf)
 
366
                (equal ll 0)
 
367
                (equal (cadr d) 1)) ())
 
368
          (t
 
369
           ;; This is a hack!  If nv is of the form b*x^n+a, we can
 
370
           ;; solve the equation manually instead of using solve.
 
371
           ;; Why?  Because solve asks us for the sign of yx and
 
372
           ;; that's bogus.
 
373
           (cond (d
 
374
                  ;; Solve yx = b*x^n+a, for x.  Any root will do.  So we
 
375
                  ;; have x = ((yx-a)/b)^(1/n).
 
376
                  (destructuring-bind (a n b)
 
377
                      d
 
378
                    (let ((root (power* (div (sub 'yx a) b) (inv n))))
 
379
                      (cond (t
 
380
                             (setq d (subst var 'yx root))
 
381
                             (cond (flag (intcv2 d ind nv))
 
382
                                   (t (intcv1 d ind nv))))
 
383
                            ))))
 
384
                 (t
 
385
                  (solve (m+t 'yx (m*t -1. nv)) var 1.)
 
386
                  (cond (*roots
 
387
                         (setq d (subst var 'yx (caddar *roots)))
 
388
                         (cond (flag (intcv2 d ind nv))
 
389
                               (t (intcv1 d ind nv))))
 
390
                        (t ()))))))))
 
391
 
 
392
(defun intcv1 (d ind nv) 
 
393
  (cond ((and (intcv2 d ind nv)
 
394
              (not (alike1 *ll1* *ul1*)))
 
395
         (let ((*def2* t))
 
396
           (defint exp1 var *ll1* *ul1*)))))
 
397
 
 
398
(defun intcv2 (d ind nv)
 
399
  (intcv3 d ind nv)
 
400
  (and (cond ((and (zerop1 (m+ ll ul))
 
401
                   (evenfn nv var))
 
402
              (setq exp1 (m* 2 exp1)
 
403
                    *ll1* (limcp nv var 0 '$plus)))
 
404
             (t (setq *ll1* (limcp nv var ll '$plus))))
 
405
       (setq *ul1* (limcp nv var ul '$minus))))
 
406
 
 
407
(defun limcp (a b c d) 
 
408
  (let ((ans ($limit a b c d)))
 
409
    (cond ((not (or (null ans)
 
410
                    (among '%limit ans)
 
411
                    (among '$ind ans)
 
412
                    (among '$und ans)))
 
413
           ans))))
 
414
 
 
415
(defun intcv3 (d ind nv)
 
416
  (setq nn* ($ratsimp (sdiff d var)))
 
417
  (setq exp1 (subst 'yx nv exp))
 
418
  (setq exp1 (m* nn* (cond (ind exp)
 
419
                           (t (subst d var exp1)))))
 
420
  (setq exp1 (sratsimp (subst var 'yx exp1))))
 
421
 
 
422
(defun defint (exp var ll ul)
 
423
  (let ((old-assumptions *defint-assumptions*)  (*current-assumptions* ()))
 
424
    (unwind-protect
 
425
         (prog ()
 
426
            (setq *current-assumptions* (make-defint-assumptions 'noask))
 
427
            (let ((exp (resimplify exp))            
 
428
                  (var (resimplify var))
 
429
                  ($exptsubst t)
 
430
                  (loopstop* 0)
 
431
                  ;; D (not used? -- cwh)
 
432
                  ans nn* dn* nd* $noprincipal)
 
433
              (cond ((setq ans (defint-list exp var ll ul))
 
434
                     (return ans))
 
435
                    ((or (zerop1 exp)
 
436
                         (alike1 ul ll))
 
437
                     (return 0.))
 
438
                    ((not (among var exp))
 
439
                     (cond ((or (memq ul '($inf $minf))
 
440
                                (memq ll '($inf $minf)))
 
441
                            (diverg))
 
442
                           (t (setq ans (m* exp (m+ ul (m- ll))))
 
443
                              (return ans)))))
 
444
              (let* ((exp (rmconst1 exp))
 
445
                     (c (car exp))
 
446
                     (exp (%i-out-of-denom (cdr exp))))
 
447
                (cond ((and (not $nointegrate)
 
448
                            (not (atom exp))
 
449
                            (or (among 'mqapply exp)
 
450
                                (not (memq (caar exp)
 
451
                                           '(mexpt mplus mtimes %sin %cos
 
452
                                             %tan %sinh %cosh %tanh
 
453
                                             %log %asin %acos %atan
 
454
                                             %cot %acot %sec 
 
455
                                             %asec %csc %acsc 
 
456
                                             %derivative)))))
 
457
                       (cond ((setq ans (antideriv exp))
 
458
                              (setq ans (intsubs ans ll ul))
 
459
                              (return (m* c ans)))
 
460
                             (t (return nil)))))
 
461
                (setq exp (tansc exp))
 
462
                (cond ((setq  ans (initial-analysis exp var ll ul))
 
463
                       (return (m* c ans))))
 
464
                (return nil))))
 
465
      (restore-defint-assumptions old-assumptions *current-assumptions*))))
418
466
 
419
467
(defun defint-list (exp var ll ul)
420
 
       (COND ((AND (NOT (ATOM EXP)) 
421
 
                   (MEMQ (CAAR EXP)
422
 
                         '(MEQUAL MLIST $MATRIX)))
423
 
              (let ((ANS (CONS (CAR EXP)
424
 
                               (MAPCAR
425
 
                                #'(LAMBDA (SUB-EXP)
426
 
                                    (DEFINT SUB-EXP VAR LL UL))
427
 
                                (CDR EXP)))))
428
 
                   (COND (ANS (simplify ANS))
429
 
                         (T NIL))))
430
 
             (t nil)))
 
468
  (cond ((and (not (atom exp)) 
 
469
              (memq (caar exp)
 
470
                    '(mequal mlist $matrix)))
 
471
         (let ((ans (cons (car exp)
 
472
                          (mapcar
 
473
                           #'(lambda (sub-exp)
 
474
                               (defint sub-exp var ll ul))
 
475
                           (cdr exp)))))
 
476
           (cond (ans (simplify ans))
 
477
                 (t nil))))
 
478
        (t nil)))
431
479
 
432
480
(defun initial-analysis (exp var ll ul)
433
 
       (let ((pole (cond ((not $intanalysis)
434
 
                          '$no)          ;don't do any checking.
435
 
                         (t (poles-in-interval exp var ll ul)))))
436
 
            (cond ((eq pole '$no)
437
 
                   (cond ((and (oddfn exp var)
438
 
                               (or (and (eq ll '$minf)
439
 
                                        (eq ul '$inf))
440
 
                                   (eq ($sign (m+ ll ul))
441
 
                                       '$zero)))  0)
442
 
                         (t (parse-integrand exp var ll ul))))
443
 
                  ((eq pole '$unknown)  ())
444
 
                  (t (principal-value-integral exp var ll ul pole)))))
 
481
  (let ((pole (cond ((not $intanalysis)
 
482
                     '$no)              ;don't do any checking.
 
483
                    (t (poles-in-interval exp var ll ul)))))
 
484
    (cond ((eq pole '$no)
 
485
           (cond ((and (oddfn exp var)
 
486
                       (or (and (eq ll '$minf)
 
487
                                (eq ul '$inf))
 
488
                           (eq ($sign (m+ ll ul))
 
489
                               '$zero)))  0)
 
490
                 (t (parse-integrand exp var ll ul))))
 
491
          ((eq pole '$unknown)  ())
 
492
          (t (principal-value-integral exp var ll ul pole)))))
445
493
 
446
494
(defun parse-integrand (exp var ll ul)
447
495
  (let (ans)
448
 
       (COND ((SETQ ANS (EEZZ EXP LL UL))  ans)
449
 
             ((and (RATP EXP VAR)
450
 
                   (setq ans (method-by-limits EXP VAR LL UL)))  ans)
451
 
             ((and (mplusp EXP)
452
 
                   (setq ans (INTBYTERM EXP T)))  ans)
453
 
             ((setq ans (method-by-limits EXP VAR LL UL))  ans)
454
 
             (t ()))))
 
496
    (cond ((setq ans (eezz exp ll ul))  ans)
 
497
          ((and (ratp exp var)
 
498
                (setq ans (method-by-limits exp var ll ul)))  ans)
 
499
          ((and (mplusp exp)
 
500
                (setq ans (intbyterm exp t)))  ans)
 
501
          ((setq ans (method-by-limits exp var ll ul))  ans)
 
502
          (t ()))))
455
503
 
456
 
(DEFUN RMCONST1 (E)
457
 
  (COND ((AMONG VAR E) 
458
 
         (PARTITION E VAR 1))
459
 
        (T (CONS E 1))))
 
504
(defun rmconst1 (e)
 
505
  (cond ((among var e) 
 
506
         (partition e var 1))
 
507
        (t (cons e 1))))
460
508
 
461
509
 
462
510
(defun method-by-limits (exp var ll ul)
463
 
 (let ((old-assumptions defint-assumptions))
464
 
   (setq current-assumptions (make-defint-assumptions 'noask))
465
 
;;Should be a PROG inside of unwind-protect, but Multics has a compiler
466
 
;;bug wrt. and I want to test this code now.
467
 
   (unwind-protect
468
 
       (COND ((and (and (EQ UL '$INF)
469
 
                        (eq ll '$minf))  (mtoinf exp var)))
470
 
             ((and (and (eq ul '$inf)
471
 
                        (equal ll 0.))  (ztoinf exp var)))
 
511
  (let ((old-assumptions *defint-assumptions*))
 
512
    (setq *current-assumptions* (make-defint-assumptions 'noask))
 
513
    ;;Should be a PROG inside of unwind-protect, but Multics has a compiler
 
514
    ;;bug wrt. and I want to test this code now.
 
515
    (unwind-protect
 
516
         (cond ((and (and (eq ul '$inf)
 
517
                          (eq ll '$minf))
 
518
                     (mtoinf exp var)))
 
519
               ((and (and (eq ul '$inf)
 
520
                          (equal ll 0.))
 
521
                     (ztoinf exp var)))
472
522
;;;This seems((and (and (eq ul '$inf)
473
523
;;;fairly losing        (setq exp (subin (m+ ll var) exp))
474
524
;;;                     (setq ll 0.))
475
525
;;;                (ztoinf exp var)))
476
 
             ((and (equal ll 0.)
477
 
                    (freeof var ul) (eq ($asksign ul) '$pos) (zto1 exp)))
478
 
;            ((and (and (equal ul 1.)
479
 
;                       (equal ll 0.))  (zto1 exp)))
480
 
             (t (dintegrate exp var ll ul)))
481
 
       (restore-defint-assumptions old-assumptions defint-assumptions))))
 
526
               ((and (equal ll 0.)
 
527
                     (freeof var ul)
 
528
                     (eq ($asksign ul) '$pos)
 
529
                     (zto1 exp)))
 
530
               ;;            ((and (and (equal ul 1.)
 
531
               ;;                       (equal ll 0.))  (zto1 exp)))
 
532
               (t (dintegrate exp var ll ul)))
 
533
      (restore-defint-assumptions old-assumptions *defint-assumptions*))))
482
534
       
483
535
 
484
 
(DEFUN DINTEGRATE (EXP VAR LL UL)
485
 
   (let ((ans nil) (arg nil) (scflag nil) 
486
 
         (*dflag nil) ($%emode t))
 
536
(defun dintegrate (exp var ll ul)
 
537
  (let ((ans nil) (arg nil) (*scflag* nil) 
 
538
        (*dflag nil) ($%emode t))
487
539
;;;NOT COMPLETE for sin's and cos's.
488
 
        (cond ((and (not sin-cos-recur)
489
 
                    (oscip exp)
490
 
                    (SETQ SCFLAG T)
491
 
                    (INTSC1 ll ul exp)))
492
 
              ((and (not rad-poly-recur)
493
 
                    (notinvolve exp '(%log))
494
 
                    (not (%einvolve exp))
495
 
                    (method-radical-poly exp var ll ul)))
496
 
              ((and (not (equal dintlog-recur 2.))
497
 
                    (SETQ arg (INVOLVE EXP '(%log)))
498
 
                    (DINTLOG EXP arg)))
499
 
              ((and (not dintexp-recur)
500
 
                    (SETQ arg (%EINVOLVE exp))
501
 
                    (DINTEXP EXP var)))
502
 
              ((and (NOT (RATP EXP VAR)) 
503
 
                    (SETQ ANS ($EXPAND EXP))
504
 
                    (NOT (ALIKE1 ANS EXP))
505
 
                    (INTBYTERM ANS T)))
506
 
              ((setq ans (antideriv exp))
507
 
               (intsubs ans ll ul))
508
 
              (t nil))))
 
540
    (cond ((and (not *sin-cos-recur*)
 
541
                (oscip exp)
 
542
                (setq *scflag* t)
 
543
                (intsc1 ll ul exp)))
 
544
          ((and (not *rad-poly-recur*)
 
545
                (notinvolve exp '(%log))
 
546
                (not (%einvolve exp))
 
547
                (method-radical-poly exp var ll ul)))
 
548
          ((and (not (equal *dintlog-recur* 2.))
 
549
                (setq arg (involve exp '(%log)))
 
550
                (dintlog exp arg)))
 
551
          ((and (not *dintexp-recur*)
 
552
                (setq arg (%einvolve exp))
 
553
                (dintexp exp var)))
 
554
          ((and (not (ratp exp var)) 
 
555
                (setq ans ($expand exp))
 
556
                (not (alike1 ans exp))
 
557
                (intbyterm ans t)))
 
558
          ((setq ans (antideriv exp))
 
559
           (intsubs ans ll ul))
 
560
          (t nil))))
509
561
 
510
562
(defun method-radical-poly (exp var ll ul)
511
563
;;;Recursion stopper
512
 
  (let ((rad-poly-recur t)   ;recursion stopper
 
564
  (let ((*rad-poly-recur* t)            ;recursion stopper
513
565
        (result ()))
514
 
    (cond ((and (sinintp EXP VAR) 
 
566
    (cond ((and (sinintp exp var) 
515
567
                (setq result (antideriv exp))
516
568
                (intsubs result ll ul)))
517
 
          ((and (RATP EXP VAR)
518
 
                (setq result (RATFNT EXP))))
 
569
          ((and (ratp exp var)
 
570
                (setq result (ratfnt exp))))
519
571
          ((and (setq result (antideriv exp))
520
572
                (intsubs result ll ul)))
521
 
          ((AND (NOT SCFLAG)
522
 
                (NOT (EQ UL '$INF))
 
573
          ((and (not *scflag*)
 
574
                (not (eq ul '$inf))
523
575
                (radic exp var)
524
 
                (KINDP34)
525
 
                (setq result (CV EXP))))
 
576
                (kindp34)
 
577
                (setq result (cv exp))))
526
578
          (t ()))))
527
579
 
528
580
;;; LIMIT loss can't set logabs to true for these cases.
547
599
                  (intsubs anti-deriv (m+ (caar previous-pole) 'epsilon)
548
600
                           (m+ (caar current-pole) (m- 'epsilon))))))
549
601
                           
550
 
;;;Hack answer to simplify "Correctly".
551
 
    (cond ((not (freeof '%log ans)) 
552
 
           (setq ans ($logcontract ans))))
553
 
    (setq ans (get-limit (get-limit ans 'epsilon 0 '$plus) 'prin-inf '$inf))
554
 
;;;Return setion.
555
 
    (cond ((or (null ans)
556
 
               (not (free ans '$infinity)) 
557
 
               (not (free ans '$ind)))  ())
558
 
          ((or (among '$minf ans)
559
 
               (among '$inf ans)
560
 
               (among '$und ans))
561
 
           (diverg))
562
 
          (t (principal) ans)))
 
602
  ;;Hack answer to simplify "Correctly".
 
603
  (cond ((not (freeof '%log ans)) 
 
604
         (setq ans ($logcontract ans))))
 
605
  (setq ans (get-limit (get-limit ans 'epsilon 0 '$plus) 'prin-inf '$inf))
 
606
  ;;Return setion.
 
607
  (cond ((or (null ans)
 
608
             (not (free ans '$infinity)) 
 
609
             (not (free ans '$ind)))  ())
 
610
        ((or (among '$minf ans)
 
611
             (among '$inf ans)
 
612
             (among '$und ans))
 
613
         (diverg))
 
614
        (t (principal) ans)))
563
615
 
564
616
(defun interval-list (pole-list ll ul)
565
617
  (let ((first (car (first pole-list)))
578
630
             (setq pole-list (append (list (cons ll 'ignored)) pole-list)))))
579
631
  pole-list)
580
632
 
581
 
(DEFUN CV (EXP)
582
 
  (if (not (or (real-infinityp ll) (real-infinityp ul)))
583
 
      (method-by-limits (INTCV3 (M// (m+t LL (m*t UL VAR))
584
 
                                     (m+t 1. VAR)) NIL 'YX)
585
 
                        VAR 0. '$INF)
586
 
      ()))
587
 
 
588
 
(DEFUN RATFNT (EXP)
589
 
   (let ((e (pqr exp)))
590
 
     (COND ((EQUAL 0. (CAR E))  (CV EXP))
591
 
           ((EQUAL 0. (CDR E))  (EEZZ (CAR E) LL UL))
592
 
           (T (m+t (EEZZ (CAR E) LL UL)
593
 
                   (CV (M// (CDR E) DN*)))))))
594
 
 
595
 
(DEFUN PQR (E)
596
 
  (let ((VARLIST (list var)))
597
 
       (NEWVAR E)
598
 
       (SETQ E (CDR (RATREP* E)))
599
 
       (SETQ DN* (PDIS (RATDENOMINATOR E)))
600
 
       (SETQ E (PDIVIDE (RATNUMERATOR E) (RATDENOMINATOR E)))
601
 
       (CONS (SIMPLIFY (RDIS (CAR E))) (SIMPLIFY (RDIS (CADR E))))))
 
633
;; Assumes EXP is a rational expression with no polynomial part and
 
634
;; converts the finite integration to integration over a half-infinite
 
635
;; interval.  The substitution y = (x-a)/(b-x) is used.  Equivalently,
 
636
;; x = (b*y+a)/(y+1).
 
637
;;
 
638
;; (I'm guessing CV means Change Variable here.)
 
639
#+nil
 
640
(defun cv (exp)
 
641
  (if (not (or (real-infinityp ll) (real-infinityp ul)))
 
642
      (method-by-limits (intcv3 (m// (m+t ll (m*t ul var))
 
643
                                     (m+t 1. var)) nil 'yx)
 
644
                        var 0. '$inf)
 
645
      ()))
 
646
 
 
647
(defun cv (exp)
 
648
  (if (not (or (real-infinityp ll) (real-infinityp ul)))
 
649
      ;; FIXME!  This is a hack.  We apply the transformation with
 
650
      ;; symbolic limits and then substitute the actual limits later.
 
651
      ;; That way method-by-limits (usually?) sees a simpler
 
652
      ;; integrand.
 
653
      ;;
 
654
      ;; See Bugs 938235 and 941457.  These fail because $FACTOR is
 
655
      ;; unable to factor the transformed result.  This needs more
 
656
      ;; work (in other places).
 
657
      (let ((trans (intcv3 (m// (m+t 'll (m*t 'ul var))
 
658
                                (m+t 1. var))
 
659
                           nil 'yx)))
 
660
        (setf trans (subst ll 'll trans))
 
661
        (setf trans (subst ul 'ul trans))
 
662
        (method-by-limits trans var 0. '$inf))
 
663
      ()))
 
664
 
 
665
(defun ratfnt (exp)
 
666
  (let ((e (pqr exp)))
 
667
    (cond ((equal 0. (car e))  (cv exp))
 
668
          ((equal 0. (cdr e))  (eezz (car e) ll ul))
 
669
          (t (m+t (eezz (car e) ll ul)
 
670
                  (cv (m// (cdr e) dn*)))))))
 
671
 
 
672
(defun pqr (e)
 
673
  (let ((varlist (list var)))
 
674
    (newvar e)
 
675
    (setq e (cdr (ratrep* e)))
 
676
    (setq dn* (pdis (ratdenominator e)))
 
677
    (setq e (pdivide (ratnumerator e) (ratdenominator e)))
 
678
    (cons (simplify (rdis (car e))) (simplify (rdis (cadr e))))))
602
679
 
603
680
 
604
 
(DEFUN INTBYTERM (EXP *NODIVERG)
 
681
(defun intbyterm (exp *nodiverg)
605
682
  (let ((saved-exp exp))
606
 
    (COND ((mplusp EXP)
607
 
           (let ((ans (CATCH 'Divergent 
608
 
                              (ANDMAPCAR #'(LAMBDA (new-exp) 
609
 
                                             (let ((*def2* t))
610
 
                                               (DEFINT new-exp VAR LL UL)))
611
 
                                         (CDR EXP)))))
612
 
                (COND ((NULL ans) NIL)
613
 
                      ((EQ ans 'Divergent)
614
 
                       (let ((*NODIVerg nil))
615
 
                         (cond ((setq ans (ANTIDERIV saved-EXP))
616
 
                                (intsubs ans ll ul))
617
 
                               (t nil))))
618
 
                      (T (sRATSIMP (m+l ans))))))
 
683
    (cond ((mplusp exp)
 
684
           (let ((ans (catch 'divergent 
 
685
                        (andmapcar #'(lambda (new-exp) 
 
686
                                       (let ((*def2* t))
 
687
                                         (defint new-exp var ll ul)))
 
688
                                   (cdr exp)))))
 
689
             (cond ((null ans) nil)
 
690
                   ((eq ans 'divergent)
 
691
                    (let ((*nodiverg nil))
 
692
                      (cond ((setq ans (antideriv saved-exp))
 
693
                             (intsubs ans ll ul))
 
694
                            (t nil))))
 
695
                   (t (sratsimp (m+l ans))))))
619
696
;;;If leadop isn't plus don't do anything.
620
697
          (t nil))))
621
698
 
622
 
(DEFUN KINDP34 NIL
623
 
  (NUMDEN EXP)
 
699
(defun kindp34 nil
 
700
  (numden exp)
624
701
  (let* ((d dn*)
625
 
         (a (COND ((and (ZEROP1 ($LIMIT D VAR LL '$PLUS))
626
 
                        (eq (limit-pole (m+ exp (m+ (m- LL) VAR)) var LL '$PLUS) '$yes))
 
702
         (a (cond ((and (zerop1 ($limit d var ll '$plus))
 
703
                        (eq (limit-pole (m+ exp (m+ (m- ll) var))
 
704
                                        var ll '$plus)
 
705
                            '$yes))
627
706
                   t)
628
707
                  (t nil)))
629
 
         (b (COND ((and (ZEROP1 ($LIMIT D VAR UL '$MINUS))
630
 
                        (eq (limit-pole (m+ exp (m+ UL (m- VAR))) var UL '$MINUS) '$yes))
 
708
         (b (cond ((and (zerop1 ($limit d var ul '$minus))
 
709
                        (eq (limit-pole (m+ exp (m+ ul (m- var)))
 
710
                                        var ul '$minus)
 
711
                            '$yes))
631
712
                   t)
632
713
                  (t nil))))
633
714
    (or a b)))
634
715
 
635
 
(DEFUN Diverg NIL
636
 
  (COND (*NODIVERG (THROW 'Divergent 'Divergent))
637
 
        (T (MERROR "Integral is divergent"))))
 
716
(defun diverg nil
 
717
  (cond (*nodiverg (throw 'divergent 'divergent))
 
718
        (t (merror "Integral is divergent"))))
638
719
 
639
720
(defun make-defint-assumptions (ask-or-not)
640
721
  (cond ((null (order-limits ask-or-not))  ())
641
 
        (t (mapc 'forget defint-assumptions)
642
 
           (setq defint-assumptions ())
 
722
        (t (mapc 'forget *defint-assumptions*)
 
723
           (setq *defint-assumptions* ())
643
724
           (let ((sign-ll (cond ((eq ll '$inf)  '$pos)
644
725
                                ((eq ll '$minf) '$neg)
645
726
                                (t ($sign ($limit ll)))))
651
732
                                   ((and (eq ul '$minf)
652
733
                                         (not (eq ll '$minf)))  '$neg)
653
734
                                   (t ($sign ($limit (m+ ul (m- ll))))))))
654
 
                (cond ((eq sign-ul-ll '$pos)
655
 
                       (setq defint-assumptions
656
 
                             `(,(assume `((mgreaterp) ,var ,ll))
657
 
                               ,(assume `((mgreaterp) ,ul ,var)))))
658
 
                      ((eq sign-ul-ll '$neg)
659
 
                       (setq defint-assumptions
660
 
                             `(,(assume `((mgreaterp) ,var ,ul))
661
 
                               ,(assume `((mgreaterp) ,ll ,var))))))
662
 
                (cond ((and (eq sign-ll '$pos)
663
 
                            (eq sign-ul '$pos))
664
 
                       (setq defint-assumptions
665
 
                             `(,(assume `((mgreaterp) ,var 0))
666
 
                               ,@defint-assumptions)))
667
 
                      ((and (eq sign-ll '$neg)
668
 
                            (eq sign-ul '$neg))
669
 
                       (setq defint-assumptions
670
 
                             `(,(assume `((mgreaterp) 0 ,var))
671
 
                               ,@defint-assumptions)))
672
 
                      (t defint-assumptions))))))
 
735
             (cond ((eq sign-ul-ll '$pos)
 
736
                    (setq *defint-assumptions*
 
737
                          `(,(assume `((mgreaterp) ,var ,ll))
 
738
                            ,(assume `((mgreaterp) ,ul ,var)))))
 
739
                   ((eq sign-ul-ll '$neg)
 
740
                    (setq *defint-assumptions*
 
741
                          `(,(assume `((mgreaterp) ,var ,ul))
 
742
                            ,(assume `((mgreaterp) ,ll ,var))))))
 
743
             (cond ((and (eq sign-ll '$pos)
 
744
                         (eq sign-ul '$pos))
 
745
                    (setq *defint-assumptions*
 
746
                          `(,(assume `((mgreaterp) ,var 0))
 
747
                            ,@*defint-assumptions*)))
 
748
                   ((and (eq sign-ll '$neg)
 
749
                         (eq sign-ul '$neg))
 
750
                    (setq *defint-assumptions*
 
751
                          `(,(assume `((mgreaterp) 0 ,var))
 
752
                            ,@*defint-assumptions*)))
 
753
                   (t *defint-assumptions*))))))
673
754
 
674
755
(defun restore-defint-assumptions (old-assumptions assumptions)
675
756
  (do ((llist assumptions (cdr llist)))
676
757
      ((null llist) t)
677
 
      (forget (car llist)))
 
758
    (forget (car llist)))
678
759
  (do ((llist old-assumptions (cdr llist)))
679
760
      ((null llist) t)
680
 
      (assume (car llist))))
 
761
    (assume (car llist))))
681
762
 
682
763
(defun make-global-assumptions ()
683
 
            (setq global-defint-assumptions
684
 
                  (cons (assume '((mgreaterp) *z* 0.))
685
 
                        global-defint-assumptions))
686
 
;;; *Z* is a "zero parameter" for this package.
687
 
;;; Its also used to transform.
688
 
;;  limit(exp,var,val,dir) -- limit(exp,tvar,0,dir)
689
 
            (setq global-defint-assumptions
690
 
                  (cons (assume '((mgreaterp) epsilon 0.))
691
 
                        global-defint-assumptions))        
692
 
            (setq global-defint-assumptions
693
 
                  (cons (assume '((mlessp) epsilon 1.0e-8))
694
 
                        global-defint-assumptions)) 
695
 
;;; EPSILON is used in principal vaule code to denote the familiar
696
 
;;; mathematical entity.
697
 
            (setq global-defint-assumptions
698
 
                  (cons (assume '((mgreaterp) prin-inf 1.0e+8))
699
 
                        global-defint-assumptions)))
 
764
  (setq *global-defint-assumptions*
 
765
        (cons (assume '((mgreaterp) *z* 0.))
 
766
              *global-defint-assumptions*))
 
767
  ;; *Z* is a "zero parameter" for this package.
 
768
  ;; Its also used to transform.
 
769
  ;;  limit(exp,var,val,dir) -- limit(exp,tvar,0,dir)
 
770
  (setq *global-defint-assumptions*
 
771
        (cons (assume '((mgreaterp) epsilon 0.))
 
772
              *global-defint-assumptions*))        
 
773
  (setq *global-defint-assumptions*
 
774
        (cons (assume '((mlessp) epsilon 1.0e-8))
 
775
              *global-defint-assumptions*)) 
 
776
  ;; EPSILON is used in principal vaule code to denote the familiar
 
777
  ;; mathematical entity.
 
778
  (setq *global-defint-assumptions*
 
779
        (cons (assume '((mgreaterp) prin-inf 1.0e+8))
 
780
              *global-defint-assumptions*)))
 
781
 
700
782
;;; PRIN-INF Is a special symbol in the principal value code used to
701
783
;;; denote an end-point which is proceeding to infinity.
702
784
 
703
785
(defun forget-global-assumptions ()
704
 
       (do ((llist global-defint-assumptions (cdr llist)))
705
 
           ((null llist) t)
706
 
           (forget (car llist)))
707
 
       (cond ((not (null integer-info))
708
 
              (do ((llist integer-info (cdr llist)))
709
 
                  ((null llist) t)
710
 
                  (I-$remove `(,(cadar llist) ,(caddar llist)))))))
711
 
 
712
 
(DEFUN order-limits (ask-or-not)
713
 
       (cond ((or (not (equal ($imagpart ll) 0))
714
 
                  (not (equal ($imagpart ul) 0)))  ())
715
 
             (t (COND ((ALIKE1 LL (m*t -1 '$INF))
716
 
                       (SETQ LL '$MINF)))
717
 
                (COND ((ALIKE1 UL (m*t -1 '$INF))
718
 
                       (SETQ UL '$MINF)))
719
 
                (cond ((alike1 ll (m*t -1 '$minf))
720
 
                       (setq ll '$inf)))
721
 
                (cond ((alike1 ul (m*t -1 '$minf))
722
 
                       (setq ul '$inf)))
723
 
                (COND ((EQ UL '$INF) NIL)
724
 
                      ((EQ LL '$MINF)
725
 
                       (SETQ EXP (SUBIN (m- VAR) EXP))
726
 
                       (SETQ LL (m- ul))
727
 
                       (SETQ UL '$INF))
728
 
                      ((eq ll '$inf)
729
 
                       (setq ll ul)
730
 
                       (setq ul '$inf)
731
 
                       (setq exp (m- exp))))
732
 
;;;Fix limits so that ll < ul. 
733
 
                (let ((D (COMPLM ask-or-not)))
734
 
                     (COND ((EQUAL D -1.)
735
 
                            (SETQ exp (m- exp))
736
 
                            (SETQ D LL)
737
 
                            (SETQ LL UL)
738
 
                            (SETQ UL D))
739
 
                           (T T))))))
740
 
 
741
 
(DEFUN COMPLM (ask-or-not)
 
786
  (do ((llist *global-defint-assumptions* (cdr llist)))
 
787
      ((null llist) t)
 
788
    (forget (car llist)))
 
789
  (cond ((not (null integer-info))
 
790
         (do ((llist integer-info (cdr llist)))
 
791
             ((null llist) t)
 
792
           (i-$remove `(,(cadar llist) ,(caddar llist)))))))
 
793
 
 
794
(defun order-limits (ask-or-not)
 
795
  (cond ((or (not (equal ($imagpart ll) 0))
 
796
             (not (equal ($imagpart ul) 0)))  ())
 
797
        (t (cond ((alike1 ll (m*t -1 '$inf))
 
798
                  (setq ll '$minf)))
 
799
           (cond ((alike1 ul (m*t -1 '$inf))
 
800
                  (setq ul '$minf)))
 
801
           (cond ((alike1 ll (m*t -1 '$minf))
 
802
                  (setq ll '$inf)))
 
803
           (cond ((alike1 ul (m*t -1 '$minf))
 
804
                  (setq ul '$inf)))
 
805
           (cond ((eq ul '$inf) nil)
 
806
                 ((eq ll '$minf)
 
807
                  (setq exp (subin (m- var) exp))
 
808
                  (setq ll (m- ul))
 
809
                  (setq ul '$inf))
 
810
                 ((eq ll '$inf)
 
811
                  (setq ll ul)
 
812
                  (setq ul '$inf)
 
813
                  (setq exp (m- exp))))
 
814
           ;;Fix limits so that ll < ul. 
 
815
           (let ((d (complm ask-or-not)))
 
816
             (cond ((equal d -1.)
 
817
                    (setq exp (m- exp))
 
818
                    (setq d ll)
 
819
                    (setq ll ul)
 
820
                    (setq ul d))
 
821
                   (t t))))))
 
822
 
 
823
(defun complm (ask-or-not)
742
824
  (let ((askflag (cond ((eq ask-or-not 'ask)  t)
743
825
                       (t nil)))
744
 
        (A ()))
745
 
    (COND ((ALIKE1 UL LL)  0.)
746
 
          ((EQ (SETQ A (cond (askflag ($asksign ($limit (m+t UL (m- LL)))))
747
 
                             (t ($sign ($limit (m+t UL (m- LL)))))))
748
 
               '$pos)  1.)
749
 
          ((EQ A '$neg)  -1.)
750
 
          (T 1.))))
751
 
 
752
 
 
753
 
(DEFUN INTSUBS (E A B)
 
826
        (a ()))
 
827
    (cond ((alike1 ul ll)  0.)
 
828
          ((eq (setq a (cond (askflag ($asksign ($limit (m+t ul (m- ll)))))
 
829
                             (t ($sign ($limit (m+t ul (m- ll)))))))
 
830
               '$pos)
 
831
           1.)
 
832
          ((eq a '$neg)  -1.)
 
833
          (t 1.))))
 
834
 
 
835
 
 
836
(defun intsubs (e a b)
754
837
  (cond ((easy-subs e a b))
755
 
        (t (setq current-assumptions
 
838
        (t (setq *current-assumptions*
756
839
                 (make-defint-assumptions 'ask)) ;get forceful!
757
840
           (let ((generate-atan2 ())  ($algebraic t)
758
841
                 (rpart ())  (ipart ()))
759
 
             (desetq (rpart . ipart) (cond ((not (free e '$%i))
760
 
                                            (trisplit e))
761
 
                                           (t (cons e 0))))
 
842
             (desetq (rpart . ipart)
 
843
                     (cond ((not (free e '$%i))
 
844
                            (trisplit e))
 
845
                           (t (cons e 0))))
762
846
             (cond ((not (equal (sratsimp ipart) 0))  
763
847
                    (let ((rans (cond ((limit-subs rpart a b))
764
848
                                      (t (m-
774
858
                            (t (same-sheet-subs rpart a b)))))))))
775
859
 
776
860
(defun easy-subs (e ll ul)
777
 
    (cond ((or (infinityp ll) (infinityp ul)) ())
778
 
          (t (cond ((polyinx e var ())
779
 
                    (let ((ll-val (no-err-sub ll e))
780
 
                          (ul-val (no-err-sub ul e)))
781
 
                      (cond ((and ll-val ul-val)  (m- ul-val ll-val))
782
 
                            (t ()))))
783
 
                   (t ())))))
 
861
  (cond ((or (infinityp ll) (infinityp ul)) ())
 
862
        (t (cond ((polyinx e var ())
 
863
                  (let ((ll-val (no-err-sub ll e))
 
864
                        (ul-val (no-err-sub ul e)))
 
865
                    (cond ((and ll-val ul-val)  (m- ul-val ll-val))
 
866
                          (t ()))))
 
867
                 (t ())))))
784
868
 
785
869
(defun limit-subs (e ll ul)
786
870
  (cond ((not (free e '%atan))  ())
787
871
        (t (setq e ($multthru e))
788
872
           (let ((a1 ($limit e var ll '$plus))  
789
873
                 (a2 ($limit e var ul '$minus)))
790
 
             (cond ((MEMQ A1 '($INF $MINF $INFINITY ))
791
 
                    (COND ((MEMQ A2 '($INF $MINF $INFINITY))
792
 
                           (COND ((EQ A2 A1)  (Diverg))
793
 
                                 (T ())))
794
 
                          (T (Diverg))))
795
 
                   ((MEMQ A2 '($INF $MINF $INFINITY))  (Diverg))
796
 
                   ((OR (MEMQ A1 '($UND $IND))
797
 
                        (MEMQ A2 '($UND $IND)))  ())
798
 
                   (T (m- A2 A1)))))))
 
874
             (cond ((memq a1 '($inf $minf $infinity ))
 
875
                    (cond ((memq a2 '($inf $minf $infinity))
 
876
                           (cond ((eq a2 a1)  (diverg))
 
877
                                 (t ())))
 
878
                          (t (diverg))))
 
879
                   ((memq a2 '($inf $minf $infinity))  (diverg))
 
880
                   ((or (memq a1 '($und $ind))
 
881
                        (memq a2 '($und $ind)))  ())
 
882
                   (t (m- a2 a1)))))))
799
883
 
800
884
;;;This function works only on things with ATAN's in them now.
801
885
(defun same-sheet-subs (exp ll ul &aux ans)
802
886
  (let ((poles (atan-poles exp ll ul)))
803
 
;POLES -> ((mlist) ((mequal) ((%atan) foo) replacement) ......) 
804
 
;We can then use $SUBSTITUTE
 
887
    ;;POLES -> ((mlist) ((mequal) ((%atan) foo) replacement) ......) 
 
888
    ;;We can then use $SUBSTITUTE
805
889
    (setq ans ($limit exp var ll '$plus))
806
890
    (setq exp (sratsimp ($substitute poles exp)))
807
891
    (m- ($limit exp var ul '$minus) ans)))
811
895
 
812
896
(defun atan-pole1 (exp ll ul &aux ipart)
813
897
  (cond 
814
 
   ((mapatom exp)  ())
815
 
   ((matanp exp) ;neglect multiplicity and '$unknowns for now.
816
 
    (desetq (exp . ipart) (trisplit exp))
817
 
    (cond 
818
 
     ((not (equal (sratsimp ipart) 0))  ())
819
 
     (t (let ((pole (poles-in-interval (let (($algebraic t))
820
 
                                         (sratsimp (cadr exp)))
821
 
                                       var ll ul)))
822
 
          (cond ((and pole (not (or (eq pole '$unknown)
823
 
                                    (eq pole '$no))))
824
 
                 (do ((l pole (cdr l)) (llist ()))
825
 
                     ((null l)  llist)
826
 
                   (cond 
827
 
                    ((eq (caar l) ll)  t) ;Skip this one by definition.
828
 
                    (t (let ((low-lim ($limit (cadr exp) var (caar l) '$minus))
829
 
                             (up-lim ($limit (cadr exp) var (caar l) '$plus)))
830
 
                         (cond ((and (not (eq low-lim up-lim))
831
 
                                     (real-infinityp low-lim)
832
 
                                     (real-infinityp up-lim))
833
 
                                (let ((change (if (eq low-lim '$minf)
834
 
                                                  (m- '$%pi)
835
 
                                                   '$%pi)))
836
 
                                  (setq llist (cons `((mequal simp) ,exp  ,(m+ exp change))
837
 
                                                   llist)))))))))))))))
838
 
   (t (do ((l (cdr exp) (cdr l))
839
 
           (llist ()))
840
 
          ((null l)  llist)
841
 
        (setq llist (append llist (atan-pole1 (car l) ll ul)))))))
842
 
 
843
 
(DEFUN DIFAPPLY (N D S FN1)
844
 
  (PROG (K M R $NOPRINCIPAL) 
845
 
        (COND ((eq ($asksign (m+ (DEG D) (m- S) (m- 2.)))  '$neg)
846
 
               (RETURN NIL)))
847
 
        (SETQ $NOPRINCIPAL T)
848
 
        (COND ((OR (NOT (mexptp D))
849
 
                   (NOT (NUMBERP (SETQ R (CADDR D)))))
850
 
               (RETURN NIL))
851
 
              ((AND (EQUAL N 1.)
852
 
                    (EQ FN1 'MTORAT)
853
 
                    (EQUAL 1. (DEG (CADR D))))
854
 
               (RETURN 0.)))
855
 
        (SETQ M (DEG (SETQ D (CADR D))))
856
 
        (SETQ K (m// (m+ S 2.) M))
857
 
        (COND ((eq (ask-integer (m// (m+ S 2.) M) '$any)  '$yes)
858
 
               NIL)
859
 
              (T (SETQ K (M+ 1 K))))
860
 
        (COND ((eq ($sign (m+ r (m- k))) '$pos)
861
 
               (RETURN (DIFFHK FN1 N D K (m+ R (m- K)))))))) 
862
 
 
863
 
(DEFUN DIFFHK (FN1 N D R M)
864
 
  (PROG (D1 *DFLAG) 
865
 
        (SETQ *DFLAG T)
866
 
        (SETQ D1 (FUNCALL FN1 N
867
 
                          (m^ (m+t '*Z* D) R)
868
 
                          (m* R (DEG D))))
869
 
        (COND (D1 (RETURN (DIFAP1 D1 R '*Z* M 0.)))))) 
870
 
 
871
 
(DEFUN PRINCIPAL NIL
872
 
       (COND ($NOPRINCIPAL (Diverg))
873
 
             ((NOT PCPRNTD)
874
 
              (PRINC "Principal Value")
875
 
              (SETQ PCPRNTD T))))
876
 
 
877
 
(DEFUN RIB (E S)
878
 
  (let (*UPDN C) 
879
 
    (COND ((OR (MNUMP E) (CONSTANT E))
880
 
           (SETQ BPTU (CONS E BPTU)))
881
 
          (t (SETQ E (RMCONST1 E))
882
 
             (SETQ C (CAR E))
883
 
             (SETQ NN* (CDR E))
884
 
             (SETQ ND* S)
885
 
             (SETQ E (CATCH 'PTIMES%E (PTIMES%E NN* ND*)))
886
 
             (COND ((NULL E) NIL)
887
 
                   (T (SETQ E (m* C E))
888
 
                      (COND (*UPDN (SETQ BPTU (CONS E BPTU)))
889
 
                            (T (SETQ BPTD (CONS E BPTD))))))))))
890
 
 
891
 
(DEFUN PTIMES%E (TERM N)
892
 
       (COND ((POLYINX TERM VAR NIL) TERM)
893
 
             ((AND (mexptp TERM)
894
 
                   (EQ (CADR TERM) '$%E)
895
 
                   (POLYINX (CADDR TERM) VAR NIL)
896
 
                   (eq ($sign (m+ (DEG ($realpart (CADDR TERM))) -1.))
897
 
                       '$neg)
898
 
                   (eq ($sign (m+ (DEG (SETQ NN* ($imagpart (CADDR TERM)))) 
899
 
                                     -2.))
900
 
                       '$neg))
901
 
              (COND ((EQ ($askSIGN (RATCOEF NN* VAR)) '$pos) 
902
 
                     (SETQ *UPDN T))
903
 
                    (T (SETQ *UPDN NIL)))
904
 
              TERM)
905
 
             ((AND (mtimesp TERM)
906
 
                   (SETQ NN* (POLFACTORS TERM))
907
 
                   (OR (NULL (CAR NN*))
908
 
                       (eq ($sign (m+ n (m- (deg (car nn*)))))
909
 
                           '$pos))
910
 
                   (PTIMES%E (CADR NN*) N)
911
 
                   TERM))
912
 
             (T (THROW 'PTIMES%E NIL))))
913
 
 
914
 
(DEFUN CSEMIDOWN (N D VAR)
 
898
    ((mapatom exp)  ())
 
899
    ((matanp exp)        ;neglect multiplicity and '$unknowns for now.
 
900
     (desetq (exp . ipart) (trisplit exp))
 
901
     (cond 
 
902
       ((not (equal (sratsimp ipart) 0))  ())
 
903
       (t (let ((pole (poles-in-interval (let (($algebraic t))
 
904
                                           (sratsimp (cadr exp)))
 
905
                                         var ll ul)))
 
906
            (cond ((and pole (not (or (eq pole '$unknown)
 
907
                                      (eq pole '$no))))
 
908
                   (do ((l pole (cdr l)) (llist ()))
 
909
                       ((null l)  llist)
 
910
                     (cond 
 
911
                       ((eq (caar l) ll)  t) ;Skip this one by definition.
 
912
                       (t (let ((low-lim ($limit (cadr exp) var (caar l) '$minus))
 
913
                                (up-lim ($limit (cadr exp) var (caar l) '$plus)))
 
914
                            (cond ((and (not (eq low-lim up-lim))
 
915
                                        (real-infinityp low-lim)
 
916
                                        (real-infinityp up-lim))
 
917
                                   (let ((change (if (eq low-lim '$minf)
 
918
                                                     (m- '$%pi)
 
919
                                                     '$%pi)))
 
920
                                     (setq llist (cons `((mequal simp) ,exp  ,(m+ exp change))
 
921
                                                       llist)))))))))))))))
 
922
    (t (do ((l (cdr exp) (cdr l))
 
923
            (llist ()))
 
924
           ((null l)  llist)
 
925
         (setq llist (append llist (atan-pole1 (car l) ll ul)))))))
 
926
 
 
927
(defun difapply (n d s fn1)
 
928
  (prog (k m r $noprincipal) 
 
929
     (cond ((eq ($asksign (m+ (deg d) (m- s) (m- 2.)))  '$neg)
 
930
            (return nil)))
 
931
     (setq $noprincipal t)
 
932
     (cond ((or (not (mexptp d))
 
933
                (not (numberp (setq r (caddr d)))))
 
934
            (return nil))
 
935
           ((and (equal n 1.)
 
936
                 (eq fn1 'mtorat)
 
937
                 (equal 1. (deg (cadr d))))
 
938
            (return 0.)))
 
939
     (setq m (deg (setq d (cadr d))))
 
940
     (setq k (m// (m+ s 2.) m))
 
941
     (cond ((eq (ask-integer (m// (m+ s 2.) m) '$any)  '$yes)
 
942
            nil)
 
943
           (t (setq k (m+ 1 k))))
 
944
     (cond ((eq ($sign (m+ r (m- k))) '$pos)
 
945
            (return (diffhk fn1 n d k (m+ r (m- k)))))))) 
 
946
 
 
947
(defun diffhk (fn1 n d r m)
 
948
  (prog (d1 *dflag) 
 
949
     (setq *dflag t)
 
950
     (setq d1 (funcall fn1 n
 
951
                       (m^ (m+t '*z* d) r)
 
952
                       (m* r (deg d))))
 
953
     (cond (d1 (return (difap1 d1 r '*z* m 0.)))))) 
 
954
 
 
955
(defun principal nil
 
956
  (cond ($noprincipal (diverg))
 
957
        ((not pcprntd)
 
958
         (princ "Principal Value")
 
959
         (setq pcprntd t))))
 
960
 
 
961
(defun rib (e s)
 
962
  (let (*updn c) 
 
963
    (cond ((or (mnump e) (constant e))
 
964
           (setq bptu (cons e bptu)))
 
965
          (t (setq e (rmconst1 e))
 
966
             (setq c (car e))
 
967
             (setq nn* (cdr e))
 
968
             (setq nd* s)
 
969
             (setq e (catch 'ptimes%e (ptimes%e nn* nd*)))
 
970
             (cond ((null e) nil)
 
971
                   (t (setq e (m* c e))
 
972
                      (cond (*updn (setq bptu (cons e bptu)))
 
973
                            (t (setq bptd (cons e bptd))))))))))
 
974
 
 
975
(defun ptimes%e (term n)
 
976
  (cond ((polyinx term var nil) term)
 
977
        ((and (mexptp term)
 
978
              (eq (cadr term) '$%e)
 
979
              (polyinx (caddr term) var nil)
 
980
              (eq ($sign (m+ (deg ($realpart (caddr term))) -1.))
 
981
                  '$neg)
 
982
              (eq ($sign (m+ (deg (setq nn* ($imagpart (caddr term)))) 
 
983
                             -2.))
 
984
                  '$neg))
 
985
         (cond ((eq ($asksign (ratcoef nn* var)) '$pos) 
 
986
                (setq *updn t))
 
987
               (t (setq *updn nil)))
 
988
         term)
 
989
        ((and (mtimesp term)
 
990
              (setq nn* (polfactors term))
 
991
              (or (null (car nn*))
 
992
                  (eq ($sign (m+ n (m- (deg (car nn*)))))
 
993
                      '$pos))
 
994
              (ptimes%e (cadr nn*) n)
 
995
              term))
 
996
        (t (throw 'ptimes%e nil))))
 
997
 
 
998
(defun csemidown (n d var)
915
999
  (let ((pcprntd t)) ;Not sure what to do about PRINCIPAL values here.
916
 
    (PRINCIP (RES N D #'LOWERHALF #'(lambda (X)
 
1000
    (princip (res n d #'lowerhalf #'(lambda (x)
917
1001
                                      (cond ((equal ($imagpart x) 0)  t)
918
1002
                                            (t ())))))))
919
1003
 
920
 
(DEFUN LOWERHALF (J) (EQ ($askSIGN ($imagpart J)) '$neg)) 
921
 
 
922
 
(DEFUN UPPERHALF (J) (EQ ($askSIGN ($imagpart J)) '$pos)) 
923
 
 
924
 
 
925
 
(DEFUN CSEMIUP (N D VAR)
 
1004
(defun lowerhalf (j)
 
1005
  (eq ($asksign ($imagpart j)) '$neg))
 
1006
 
 
1007
(defun upperhalf (j)
 
1008
  (eq ($asksign ($imagpart j)) '$pos))
 
1009
 
 
1010
 
 
1011
(defun csemiup (n d var)
926
1012
  (let ((pcprntd t)) ;I'm not sure what to do about PRINCIPAL values here.
927
 
    (PRINCIP (RES N D #'UPPERHALF #'(lambda (X)
 
1013
    (princip (res n d #'upperhalf #'(lambda (x)
928
1014
                                      (cond ((equal ($imagpart x) 0)  t)
929
1015
                                            (t ())))))))
930
1016
 
931
 
(DEFUN PRINCIP (N)
932
 
       (cond ((null n) nil)
933
 
             (t (m*t '$%I ($RECTFORM (m+ (COND ((CAR N)
934
 
                                                (m*t 2. (CAR N)))
935
 
                                               (T 0.))
936
 
                                         (COND ((CADR N)
937
 
                                                (PRINCIPAL)
938
 
                                                (CADR N))
939
 
                                               (T 0.))))))))
940
 
 
941
 
 
942
 
(DEFUN SCONVERT (E)
943
 
       (COND ((ATOM E) E)
944
 
             ((POLYINX E VAR NIL) E)
945
 
             ((EQ (CAAR E) '%SIN)
946
 
              (m* '((RAT) -1. 2.)
947
 
                  '$%I
948
 
                  (m+t (m^t '$%E (m*t '$%I (CADR E)))
949
 
                       (m- (m^t '$%E (m*t (m- '$%I) (CADR E)))))))
950
 
             ((EQ (CAAR E) '%COS)
951
 
              (mul* '((RAT) 1. 2.)
952
 
                    (m+t (m^t '$%E (m*t '$%I (CADR E)))
953
 
                         (m^t '$%E (m*t (m- '$%I) (CADR E))))))
954
 
             (T (simplify
955
 
                 (CONS (LIST (CAAR E)) (MAPCAR #'SCONVERT (CDR E)))))))
956
 
 
957
 
(DEFUN POLFACTORS (EXP)
 
1017
(defun princip (n)
 
1018
  (cond ((null n) nil)
 
1019
        (t (m*t '$%i ($rectform (m+ (cond ((car n)
 
1020
                                           (m*t 2. (car n)))
 
1021
                                          (t 0.))
 
1022
                                    (cond ((cadr n)
 
1023
                                           (principal)
 
1024
                                           (cadr n))
 
1025
                                          (t 0.))))))))
 
1026
 
 
1027
 
 
1028
(defun sconvert (e)
 
1029
  (cond ((atom e) e)
 
1030
        ((polyinx e var nil) e)
 
1031
        ((eq (caar e) '%sin)
 
1032
         (m* '((rat) -1. 2.)
 
1033
             '$%i
 
1034
             (m+t (m^t '$%e (m*t '$%i (cadr e)))
 
1035
                  (m- (m^t '$%e (m*t (m- '$%i) (cadr e)))))))
 
1036
        ((eq (caar e) '%cos)
 
1037
         (mul* '((rat) 1. 2.)
 
1038
               (m+t (m^t '$%e (m*t '$%i (cadr e)))
 
1039
                    (m^t '$%e (m*t (m- '$%i) (cadr e))))))
 
1040
        (t (simplify
 
1041
            (cons (list (caar e)) (mapcar #'sconvert (cdr e)))))))
 
1042
 
 
1043
(defun polfactors (exp)
958
1044
  (let (poly rest)
959
 
       (COND ((mplusp exp)  nil)
960
 
             (t (cond ((mtimesp EXP)
961
 
                       (SETQ EXP (REVERSE (CDR EXP))))
962
 
                      (T (SETQ EXP (LIST EXP))))
963
 
                (mapc #'(lambda (term)
964
 
                         (cond ((polyinx term var nil)
965
 
                                (push term poly))
966
 
                               (t (push term rest))))
967
 
                      exp)
968
 
                (list (m*l poly) (m*l rest))))))
969
 
 
970
 
(DEFUN ESAP (E)
971
 
       (PROG (D) 
972
 
             (COND ((ATOM E) (RETURN E))
973
 
                   ((NOT (AMONG '$%E E)) (RETURN E))
974
 
                   ((AND (mexptp E)
975
 
                         (EQ (CADR E) '$%E))
976
 
                    (SETQ D ($imagpart (CADDR E)))
977
 
                    (RETURN (m* (m^t '$%E ($realpART (CADDR E)))
978
 
                                   (m+ `((%COS) ,D)
979
 
                                          (m*t '$%I `((%SIN) ,D))))))
980
 
                   (T (RETURN (simplify (CONS (LIST (CAAR E))
981
 
                                              (MAPCAR #'ESAP (CDR E)))))))))
982
 
 
983
 
(DEFUN MTOSC (GRAND)
984
 
  (NUMDEN GRAND)
 
1045
    (cond ((mplusp exp)  nil)
 
1046
          (t (cond ((mtimesp exp)
 
1047
                    (setq exp (reverse (cdr exp))))
 
1048
                   (t (setq exp (list exp))))
 
1049
             (mapc #'(lambda (term)
 
1050
                       (cond ((polyinx term var nil)
 
1051
                              (push term poly))
 
1052
                             (t (push term rest))))
 
1053
                   exp)
 
1054
             (list (m*l poly) (m*l rest))))))
 
1055
 
 
1056
(defun esap (e)
 
1057
  (prog (d) 
 
1058
     (cond ((atom e) (return e))
 
1059
           ((not (among '$%e e)) (return e))
 
1060
           ((and (mexptp e)
 
1061
                 (eq (cadr e) '$%e))
 
1062
            (setq d ($imagpart (caddr e)))
 
1063
            (return (m* (m^t '$%e ($realpart (caddr e)))
 
1064
                        (m+ `((%cos) ,d)
 
1065
                            (m*t '$%i `((%sin) ,d))))))
 
1066
           (t (return (simplify (cons (list (caar e))
 
1067
                                      (mapcar #'esap (cdr e)))))))))
 
1068
 
 
1069
(defun mtosc (grand)
 
1070
  (numden grand)
985
1071
  (let ((n nn*)
986
1072
        (d dn*)
987
1073
        plf bptu bptd s upans downans)
988
 
    (COND ((not (or (POLYINX D VAR NIL)
989
 
                    (AND (SETQ GRAND (%EINVOLVE D))
990
 
                         (AMONG '$%I GRAND)
991
 
                         (POLYINX (SETQ D ($RATSIMP (M// D (m^t '$%E GRAND))))
992
 
                                  VAR
993
 
                                  NIL)
994
 
                         (SETQ N (M// N (m^t '$%E GRAND))))))  nil)
995
 
          ((EQUAL (SETQ S (DEG D)) 0)  NIL)
 
1074
    (cond ((not (or (polyinx d var nil)
 
1075
                    (and (setq grand (%einvolve d))
 
1076
                         (among '$%i grand)
 
1077
                         (polyinx (setq d ($ratsimp (m// d (m^t '$%e grand))))
 
1078
                                  var
 
1079
                                  nil)
 
1080
                         (setq n (m// n (m^t '$%e grand))))))  nil)
 
1081
          ((equal (setq s (deg d)) 0)  nil)
996
1082
;;;Above tests for applicability of this method.
997
 
          ((and (or (SETQ PLF (POLFACTORS N))  t)
998
 
                (SETQ N ($EXPAND (COND ((CAR PLF)
999
 
                                        (m*t 'X* (SCONVERT (CADR PLF))))
1000
 
                                       (T (SCONVERT N)))))
1001
 
                (COND ((mplusp N)  (SETQ N (CDR N)))
1002
 
                      (T (SETQ N (LIST N))))
 
1083
          ((and (or (setq plf (polfactors n))  t)
 
1084
                (setq n ($expand (cond ((car plf)
 
1085
                                        (m*t 'x* (sconvert (cadr plf))))
 
1086
                                       (t (sconvert n)))))
 
1087
                (cond ((mplusp n)  (setq n (cdr n)))
 
1088
                      (t (setq n (list n))))
1003
1089
                (do ((do-var n (cdr do-var)))
1004
1090
                    ((null do-var) t)
1005
1091
                  (cond ((rib (car do-var) s))
1006
1092
                        (t (return nil))))
1007
1093
;;;Function RIB sets up the values of BPTU and BPTD
1008
 
                (COND ((CAR PLF)
1009
 
                       (SETQ BPTU (SUBST (CAR PLF) 'X* BPTU))
1010
 
                       (SETQ BPTD (SUBST (CAR PLF) 'X* BPTD))
1011
 
                       t) ;CROCK, CROCK. This is TERRIBLE code.
 
1094
                (cond ((car plf)
 
1095
                       (setq bptu (subst (car plf) 'x* bptu))
 
1096
                       (setq bptd (subst (car plf) 'x* bptd))
 
1097
                       t)        ;CROCK, CROCK. This is TERRIBLE code.
1012
1098
                      (t t))
1013
1099
;;;If there is BPTU then CSEMIUP must succeed.
1014
1100
;;;Likewise for BPTD.
1021
1107
           (sratsimp (m* '$%pi (m+ upans (m- downans))))))))
1022
1108
 
1023
1109
 
1024
 
(DEFUN EVENFN (E var)
1025
 
       (let ((temp (m+ (m- E) (cond ((atom var)
1026
 
                                     ($substitute (m- var) var e))
1027
 
                                    (t ($ratsubst (m- var) var E))))))
1028
 
            (cond ((zerop1 temp)
1029
 
                   t)
1030
 
                  ((zerop1 ($ratsimp temp))
1031
 
                   t)
1032
 
                  (t nil))))
 
1110
(defun evenfn (e var)
 
1111
  (let ((temp (m+ (m- e)
 
1112
                  (cond ((atom var)
 
1113
                         ($substitute (m- var) var e))
 
1114
                        (t ($ratsubst (m- var) var e))))))
 
1115
    (cond ((zerop1 temp)
 
1116
           t)
 
1117
          ((zerop1 ($ratsimp temp))
 
1118
           t)
 
1119
          (t nil))))
1033
1120
                
1034
 
(DEFUN ODDFN (E VAR)       
1035
 
       (let ((temp (m+ e (cond ((atom var)
1036
 
                                ($SUBSTITUTE (m- VAR) var E))
1037
 
                               (t ($ratsubst (m- var) var e))))))
1038
 
            (cond ((zerop1 temp)
1039
 
                   t)
1040
 
                  ((zerop1 ($ratsimp temp))
1041
 
                   t)
1042
 
                  (t nil))))
1043
 
 
1044
 
(DEFUN ZTOINF (GRAND VAR)
1045
 
       (PROG (N D SN* SD* VARLIST
1046
 
                S NC DC
1047
 
                ANS R $SAVEFACTORS CHECKFACTORS temp test-var)
1048
 
             (SETQ $SAVEFACTORS T SN* (SETQ SD* (LIST 1.)))
1049
 
             (COND ((eq ($sign (m+ LOOPSTOP* -1))
1050
 
                        '$pos)
1051
 
                    (RETURN NIL))
1052
 
                   ((SETQ temp (OR (SCAXN GRAND)
1053
 
                                   (SSP GRAND))) 
1054
 
                    (RETURN temp))
1055
 
                   ((INVOLVE GRAND '(%SIN %COS %TAN))
1056
 
                    (SETQ GRAND (SCONVERT GRAND))
1057
 
                    (GO ON)))
1058
 
 
1059
 
             (COND ((POLYINX GRAND VAR NIL)
1060
 
                    (Diverg))
1061
 
                   ((AND (RATP GRAND VAR)
1062
 
                         (mtimesp GRAND)
1063
 
                         (ANDMAPCAR #'SNUMDEN (CDR GRAND)))
1064
 
                    (SETQ NN* (M*L SN*)
1065
 
                          SN* NIL)
1066
 
                    (SETQ DN* (M*L SD*)
1067
 
                          SD* NIL))
1068
 
                   (t (NUMDEN GRAND)))
 
1121
(defun oddfn (e var)       
 
1122
  (let ((temp (m+ e (cond ((atom var)
 
1123
                           ($substitute (m- var) var e))
 
1124
                          (t ($ratsubst (m- var) var e))))))
 
1125
    (cond ((zerop1 temp)
 
1126
           t)
 
1127
          ((zerop1 ($ratsimp temp))
 
1128
           t)
 
1129
          (t nil))))
 
1130
 
 
1131
(defun ztoinf (grand var)
 
1132
  (prog (n d sn* sd* varlist
 
1133
         s nc dc
 
1134
         ans r $savefactors checkfactors temp test-var)
 
1135
     (setq $savefactors t sn* (setq sd* (list 1.)))
 
1136
     (cond ((eq ($sign (m+ loopstop* -1))
 
1137
                '$pos)
 
1138
            (return nil))
 
1139
           ((setq temp (or (scaxn grand)
 
1140
                           (ssp grand))) 
 
1141
            (return temp))
 
1142
           ((involve grand '(%sin %cos %tan))
 
1143
            (setq grand (sconvert grand))
 
1144
            (go on)))
 
1145
 
 
1146
     (cond ((polyinx grand var nil)
 
1147
            (diverg))
 
1148
           ((and (ratp grand var)
 
1149
                 (mtimesp grand)
 
1150
                 (andmapcar #'snumden (cdr grand)))
 
1151
            (setq nn* (m*l sn*)
 
1152
                  sn* nil)
 
1153
            (setq dn* (m*l sd*)
 
1154
                  sd* nil))
 
1155
           (t (numden grand)))
1069
1156
;;;
1070
1157
;;;New section.
1071
 
    (SETQ N (RMCONST1 NN*))
1072
 
    (SETQ D (RMCONST1 DN*))
1073
 
    (SETQ NC (CAR N))
1074
 
    (SETQ N (CDR N))
1075
 
    (SETQ DC (CAR D))
1076
 
    (SETQ D (CDR D))
1077
 
    (COND ((POLYINX D VAR NIL) 
1078
 
           (SETQ S (DEG D)))
1079
 
          (T (GO FINDOUT)))
1080
 
    (COND ((AND (SETQ R (FINDP N))
1081
 
                (eq (ask-integer R '$integer) '$yes)
1082
 
                (SETQ test-var (BXM D S))
1083
 
                (SETQ ans (APPLY 'FAN (CONS (m+ 1. R) test-var))))
1084
 
           (RETURN (m* (M// NC DC) ($RATSIMP ans))))
1085
 
          ((and (RATP GRAND VAR)
1086
 
                (SETQ ANS (ZMTORAT N (COND ((mtimesp d) d)
1087
 
                                           (T ($SQFR d)))
1088
 
                                   S #'ZTORAT)))
1089
 
          (RETURN (m* (M// NC DC) ANS)))
1090
 
          ((AND (EVENFN D VAR) 
1091
 
                (SETQ NN* (P*LOGNXP N S)))
1092
 
           (SETQ ANS (LOG*RAT (CAR NN*) D (CADR NN*)))
1093
 
           (RETURN (m* (M// NC DC) ANS)))
1094
 
          ((INVOLVE GRAND '(%LOG))
1095
 
           (COND ((SETQ ANS (LOGQUAD0 GRAND))
1096
 
                  (RETURN (m* (M// NC DC) ANS)))
1097
 
                 (T (RETURN NIL)))))
1098
 
 FINDOUT
1099
 
    (COND ((SETQ temp (BATAPP GRAND)) 
1100
 
           (RETURN temp))
1101
 
          (T nil))
1102
 
  ON
1103
 
    (COND ((let ((MTOINF* nil))
1104
 
                (SETQ temp (GGR GRAND T)))
1105
 
           (RETURN temp))
1106
 
          ((mplusp GRAND)
1107
 
           (COND ((let ((*NODIVERG t))
1108
 
                       (SETQ ANS (CATCH 'Divergent
1109
 
                                         (ANDMAPCAR #'(LAMBDA (G)
1110
 
                                                        (ZTOINF G VAR))
1111
 
                                                    (CDR GRAND)))))
1112
 
                  (COND ((EQ ANS 'Divergent) NIL)
1113
 
                        (T (RETURN (sRATSIMP (m+l ANS)))))))))
 
1158
     (setq n (rmconst1 nn*))
 
1159
     (setq d (rmconst1 dn*))
 
1160
     (setq nc (car n))
 
1161
     (setq n (cdr n))
 
1162
     (setq dc (car d))
 
1163
     (setq d (cdr d))
 
1164
     (cond ((polyinx d var nil) 
 
1165
            (setq s (deg d)))
 
1166
           (t (go findout)))
 
1167
     (cond ((and (setq r (findp n))
 
1168
                 (eq (ask-integer r '$integer) '$yes)
 
1169
                 (setq test-var (bxm d s))
 
1170
                 (setq ans (apply 'fan (cons (m+ 1. r) test-var))))
 
1171
            (return (m* (m// nc dc) ($ratsimp ans))))
 
1172
           ((and (ratp grand var)
 
1173
                 (setq ans (zmtorat n (cond ((mtimesp d) d)
 
1174
                                            (t ($sqfr d)))
 
1175
                                    s #'ztorat)))
 
1176
                   (return (m* (m// nc dc) ans)))
 
1177
           ((and (evenfn d var) 
 
1178
                 (setq nn* (p*lognxp n s)))
 
1179
            (setq ans (log*rat (car nn*) d (cadr nn*)))
 
1180
            (return (m* (m// nc dc) ans)))
 
1181
           ((involve grand '(%log))
 
1182
            (cond ((setq ans (logquad0 grand))
 
1183
                   (return (m* (m// nc dc) ans)))
 
1184
                  (t (return nil)))))
 
1185
     findout
 
1186
     (cond ((setq temp (batapp grand)) 
 
1187
            (return temp))
 
1188
           (t nil))
 
1189
     on
 
1190
     (cond ((let ((*mtoinf* nil))
 
1191
              (setq temp (ggr grand t)))
 
1192
            (return temp))
 
1193
           ((mplusp grand)
 
1194
            (cond ((let ((*nodiverg t))
 
1195
                     (setq ans (catch 'divergent
 
1196
                                 (andmapcar #'(lambda (g)
 
1197
                                                (ztoinf g var))
 
1198
                                            (cdr grand)))))
 
1199
                   (cond ((eq ans 'divergent) nil)
 
1200
                         (t (return (sratsimp (m+l ans)))))))))
1114
1201
 
1115
 
    (COND ((AND (EVENFN GRAND VAR)
1116
 
                (SETQ LOOPSTOP* (M+ 1 LOOPSTOP*))
1117
 
                (SETQ ANS (method-by-limits grand var '$minf '$inf)))
1118
 
           (return (m*t '((RAT) 1. 2.) ANS)))
1119
 
          (T (RETURN NIL)))))
 
1202
     (cond ((and (evenfn grand var)
 
1203
                 (setq loopstop* (m+ 1 loopstop*))
 
1204
                 (setq ans (method-by-limits grand var '$minf '$inf)))
 
1205
            (return (m*t '((rat) 1. 2.) ans)))
 
1206
           (t (return nil)))))
1120
1207
   
1121
 
(DEFUN ZTORAT (N D S)
1122
 
       (COND ((AND (NULL *DFLAG)
1123
 
                   (SETQ S (DIFAPPLY N D NN* #'ZTORAT)))
1124
 
              S)
1125
 
             ((SETQ N (let ((PLOGABS ()))
1126
 
                        (KEYHOLE (m* `((%PLOG) ,(m- VAR)) N) D VAR)))
1127
 
              (m- N))
1128
 
             (T (MERROR "Keyhole failed"))))
1129
 
 
1130
 
(SETQ *DFLAG NIL) 
1131
 
 
1132
 
(DEFUN LOGQUAD0 (EXP)
 
1208
(defun ztorat (n d s)
 
1209
  (cond ((and (null *dflag)
 
1210
              (setq s (difapply n d nn* #'ztorat)))
 
1211
         s)
 
1212
        ((setq n (let ((plogabs ()))
 
1213
                   (keyhole (m* `((%plog) ,(m- var)) n) d var)))
 
1214
         (m- n))
 
1215
        (t (merror "Keyhole failed"))))
 
1216
 
 
1217
(setq *dflag nil) 
 
1218
 
 
1219
(defun logquad0 (exp)
1133
1220
  (let ((a ()) (b ())  (c ()))
1134
 
    (COND ((SETQ EXP (LOGQUAD EXP))
1135
 
           (SETQ A (CAR EXP) B (CADR EXP) C (CADDR EXP))
1136
 
           ($asksign b) ;let the data base know about the sign of B.
1137
 
           (COND ((EQ ($askSIGN C) '$pos)
1138
 
                  (SETQ C (m^ (M// C A) '((RAT) 1. 2.)))
 
1221
    (cond ((setq exp (logquad exp))
 
1222
           (setq a (car exp) b (cadr exp) c (caddr exp))
 
1223
           ($asksign b)   ;let the data base know about the sign of B.
 
1224
           (cond ((eq ($asksign c) '$pos)
 
1225
                  (setq c (m^ (m// c a) '((rat) 1. 2.)))
1139
1226
                  (setq b (simplify 
1140
 
                           `((%ACOS) ,(add* 'epsilon (M// B (mul* 2. A C))))))
1141
 
                  (setq a (M// (m* B `((%LOG) ,C))
1142
 
                               (mul* A (Simplify `((%SIN) ,B)) C)))
 
1227
                           `((%acos) ,(add* 'epsilon (m// b (mul* 2. a c))))))
 
1228
                  (setq a (m// (m* b `((%log) ,c))
 
1229
                               (mul* a (simplify `((%sin) ,b)) c)))
1143
1230
                  (get-limit a 'epsilon 0 '$plus))))
1144
1231
          (t ()))))
1145
1232
        
1146
 
(DEFUN LOGQUAD (EXP)
1147
 
  (let ((VARLIST (list var)))
1148
 
    (NEWVAR EXP)
1149
 
    (SETQ EXP (CDR (RATREP* EXP)))
1150
 
    (COND ((AND (ALIKE1 (PDIS (CAR EXP))
1151
 
                        `((%LOG) ,VAR))
1152
 
                (NOT (ATOM (CDR EXP)))
1153
 
                (EQUAL (CADR (CDR EXP)) 2.)
 
1233
(defun logquad (exp)
 
1234
  (let ((varlist (list var)))
 
1235
    (newvar exp)
 
1236
    (setq exp (cdr (ratrep* exp)))
 
1237
    (cond ((and (alike1 (pdis (car exp))
 
1238
                        `((%log) ,var))
 
1239
                (not (atom (cdr exp)))
 
1240
                (equal (cadr (cdr exp)) 2.)
1154
1241
                (not (equal (pterm (cddr exp) 0.) 0.)))
1155
 
           (SETQ EXP (MAPCAR 'PDIS (CDR (ODDELM (CDR EXP)))))))))
1156
 
 
1157
 
(DEFUN MTOINF (GRAND VAR) 
1158
 
  (PROG (ANS SD* SN* P* PE* N D S NC DC $SAVEFACTORS CHECKFACTORS temp)
1159
 
    (SETQ $SAVEFACTORS T)
1160
 
    (SETQ SN* (SETQ SD* (LIST 1.)))
1161
 
    (COND ((eq ($sign (m+ LOOPSTOP* -1)) '$pos)
1162
 
           (RETURN NIL))
1163
 
          ((INVOLVE GRAND '(%SIN %COS))
1164
 
           (COND ((AND (EVENFN GRAND VAR)
1165
 
                       (or (SETQ temp (SCAXN GRAND))
1166
 
                           (setq temp (ssp grand))))
1167
 
                  (RETURN (m*t 2. temp)))
1168
 
                 ((SETQ temp (MTOSC GRAND))
1169
 
                  (RETURN temp))
1170
 
                 (T (GO EN))))
1171
 
          ((among '$%i (%EINVOLVE GRAND))
1172
 
           (COND ((SETQ temp (MTOSC GRAND))
1173
 
                  (RETURN temp))
1174
 
                 (T (GO EN)))))
1175
 
    (COND ((POLYINX GRAND VAR NIL)
1176
 
           (Diverg))
1177
 
          ((AND (RATP GRAND VAR)
1178
 
                (mtimesp GRAND)
1179
 
                (ANDMAPCAR #'SNUMDEN (CDR GRAND)))
1180
 
           (SETQ NN* (M*L SN*) SN* NIL)
1181
 
           (SETQ DN* (M*L SD*) SD* NIL))
1182
 
          (t (numden grand)))
1183
 
    (SETQ N (RMCONST1 NN*))
1184
 
    (SETQ D (RMCONST1 DN*))
1185
 
    (SETQ NC (CAR N))
1186
 
    (SETQ N (CDR N))
1187
 
    (SETQ DC (CAR D))
1188
 
    (SETQ D (CDR D))
1189
 
    (COND ((POLYINX D VAR NIL)
1190
 
           (SETQ S (DEG D))))
1191
 
    (COND ((AND (NOT (%einvolve grand))
1192
 
                (NOTINVOLVE EXP '(%SINH %COSH %TANH))
1193
 
                (SETQ P* (FINDP N))
1194
 
                (eq (ask-integer P* '$integer) '$yes)
1195
 
                (SETQ PE* (BXM D S)))
1196
 
           (COND ((AND (eq (ask-integer (CADDR PE*) '$even) '$yes)
1197
 
                       (eq (ask-integer P* '$even) '$yes))
1198
 
                  (COND ((SETQ ANS (APPLY 'FAN (CONS (m+ 1. P*) PE*)))
1199
 
                         (SETQ ANS (m*t 2. ANS))
1200
 
                         (RETURN (m* (M// NC DC) ANS)))))
1201
 
                 ((EQUAL (CAR PE*) 1.)
1202
 
                  (COND ((AND (SETQ ANS (APPLY 'FAN (CONS (m+ 1. P*) PE*)))
1203
 
                              (SETQ NN* (FAN (m+ 1. P*)
1204
 
                                             (CAR PE*)
1205
 
                                             (m* -1.(CADR PE*))
1206
 
                                             (CADDR PE*)
1207
 
                                             (CADDDR PE*))))
1208
 
                         (SETQ ANS (m+ ANS (m*t (m^ -1. P*) NN*)))
1209
 
                         (RETURN (m* (M// NC DC) ANS))))))))
1210
 
    (COND ((RATP GRAND VAR)
1211
 
           (SETQ ANS (m*t '$%PI (ZMTORAT N (COND ((mtimesp d) d)
1212
 
                                                 (T ($SQFR d)))
1213
 
                                         S
1214
 
                                         #'MTORAT)))
1215
 
           (RETURN (m* (M// NC DC) ANS)))
1216
 
          ((AND (OR (%einvolve grand)
1217
 
                    (INVOLVE GRAND '(%SINH %COSH %TANH)))
1218
 
                (P*PIN%EX N) ;setq's P* and PE*...Barf again.
1219
 
                (SETQ ANS (CATCH 'PIN%EX (PIN%EX D))))
1220
 
           (COND ((NULL P*)
1221
 
                  (RETURN (DINTEXP GRAND VAR)))
1222
 
                 ((AND (ZEROP1 (get-LIMIT GRAND VAR '$INF))
1223
 
                       (ZEROP1 (get-LIMIT GRAND VAR '$MINF))
1224
 
                       (SETQ ANS (RECTZTO%PI2 (M*L P*) (M*L PE*) D)))
1225
 
                  (RETURN (m* (M// NC DC) ANS)))
1226
 
                 (T (Diverg)))))
1227
 
    EN
1228
 
    (COND ((SETQ ANS (GGRM GRAND)) 
1229
 
           (RETURN ANS))
1230
 
          ((AND (EVENFN GRAND VAR)
1231
 
                (SETQ LOOPSTOP* (M+ 1 LOOPSTOP*))
1232
 
                (SETQ ANS (method-by-limits grand var 0 '$inf)))
1233
 
           (RETURN (m*t 2. ANS)))
1234
 
          (T (RETURN NIL)))))
1235
 
 
1236
 
(DEFUN LINPOWER0 (EXP VAR)
1237
 
       (COND ((AND (SETQ EXP (LINPOWER EXP VAR))
1238
 
                   (eq (ask-integer (CADDR EXP) '$even)
1239
 
                       '$yes)
1240
 
                   (RATGREATERP 0. (CAR EXP)))
1241
 
              EXP))) 
 
1242
           (setq exp (mapcar 'pdis (cdr (oddelm (cdr exp)))))))))
 
1243
 
 
1244
(defun mtoinf (grand var) 
 
1245
  (prog (ans sd* sn* p* pe* n d s nc dc $savefactors checkfactors temp)
 
1246
     (setq $savefactors t)
 
1247
     (setq sn* (setq sd* (list 1.)))
 
1248
     (cond ((eq ($sign (m+ loopstop* -1)) '$pos)
 
1249
            (return nil))
 
1250
           ((involve grand '(%sin %cos))
 
1251
            (cond ((and (evenfn grand var)
 
1252
                        (or (setq temp (scaxn grand))
 
1253
                            (setq temp (ssp grand))))
 
1254
                   (return (m*t 2. temp)))
 
1255
                  ((setq temp (mtosc grand))
 
1256
                   (return temp))
 
1257
                  (t (go en))))
 
1258
           ((among '$%i (%einvolve grand))
 
1259
            (cond ((setq temp (mtosc grand))
 
1260
                   (return temp))
 
1261
                  (t (go en)))))
 
1262
     (cond ((polyinx grand var nil)
 
1263
            (diverg))
 
1264
           ((and (ratp grand var)
 
1265
                 (mtimesp grand)
 
1266
                 (andmapcar #'snumden (cdr grand)))
 
1267
            (setq nn* (m*l sn*) sn* nil)
 
1268
            (setq dn* (m*l sd*) sd* nil))
 
1269
           (t (numden grand)))
 
1270
     (setq n (rmconst1 nn*))
 
1271
     (setq d (rmconst1 dn*))
 
1272
     (setq nc (car n))
 
1273
     (setq n (cdr n))
 
1274
     (setq dc (car d))
 
1275
     (setq d (cdr d))
 
1276
     (cond ((polyinx d var nil)
 
1277
            (setq s (deg d))))
 
1278
     (cond ((and (not (%einvolve grand))
 
1279
                 (notinvolve exp '(%sinh %cosh %tanh))
 
1280
                 (setq p* (findp n))
 
1281
                 (eq (ask-integer p* '$integer) '$yes)
 
1282
                 (setq pe* (bxm d s)))
 
1283
            (cond ((and (eq (ask-integer (caddr pe*) '$even) '$yes)
 
1284
                        (eq (ask-integer p* '$even) '$yes))
 
1285
                   (cond ((setq ans (apply 'fan (cons (m+ 1. p*) pe*)))
 
1286
                          (setq ans (m*t 2. ans))
 
1287
                          (return (m* (m// nc dc) ans)))))
 
1288
                  ((equal (car pe*) 1.)
 
1289
                   (cond ((and (setq ans (apply 'fan (cons (m+ 1. p*) pe*)))
 
1290
                               (setq nn* (fan (m+ 1. p*)
 
1291
                                              (car pe*)
 
1292
                                              (m* -1.(cadr pe*))
 
1293
                                              (caddr pe*)
 
1294
                                              (cadddr pe*))))
 
1295
                          (setq ans (m+ ans (m*t (m^ -1. p*) nn*)))
 
1296
                          (return (m* (m// nc dc) ans))))))))
 
1297
     (cond ((ratp grand var)
 
1298
            (setq ans (m*t '$%pi (zmtorat n (cond ((mtimesp d) d)
 
1299
                                                  (t ($sqfr d)))
 
1300
                                          s
 
1301
                                          #'mtorat)))
 
1302
            (return (m* (m// nc dc) ans)))
 
1303
           ((and (or (%einvolve grand)
 
1304
                     (involve grand '(%sinh %cosh %tanh)))
 
1305
                 (p*pin%ex n)         ;setq's P* and PE*...Barf again.
 
1306
                 (setq ans (catch 'pin%ex (pin%ex d))))
 
1307
            ;; We have an integral of the form p(x)*F(exp(x)), where
 
1308
            ;; p(x) is a polynomial.
 
1309
            (cond ((null p*)
 
1310
                   ;; No polynomial
 
1311
                   (return (dintexp grand var)))
 
1312
                  ((not (and (zerop1 (get-limit grand var '$inf))
 
1313
                             (zerop1 (get-limit grand var '$minf))))
 
1314
                   ;; These limits must exist for the integral to converge.
 
1315
                   (diverg))
 
1316
                  ((setq ans (rectzto%pi2 (m*l p*) (m*l pe*) d))
 
1317
                   ;; This only handles the case when the F(z) is a
 
1318
                   ;; rational function.
 
1319
                   (return (m* (m// nc dc) ans)))
 
1320
                  ((setq ans (log-transform (m*l p*) (m*l pe*) d))
 
1321
                   ;; If we get here, F(z) is not a rational function.
 
1322
                   ;; We transform it using the substitution x=log(y)
 
1323
                   ;; which gives us an integral of the form
 
1324
                   ;; p(log(y))*F(y)/y, which maxima should be able to
 
1325
                   ;; handle.
 
1326
                   (return (m* (m// nc dc) ans)))
 
1327
                  (t
 
1328
                   ;; Give up.  We don't know how to handle this.
 
1329
                   (return nil)))))
 
1330
     en
 
1331
     (cond ((setq ans (ggrm grand)) 
 
1332
            (return ans))
 
1333
           ((and (evenfn grand var)
 
1334
                 (setq loopstop* (m+ 1 loopstop*))
 
1335
                 (setq ans (method-by-limits grand var 0 '$inf)))
 
1336
            (return (m*t 2. ans)))
 
1337
           (t (return nil)))))
 
1338
 
 
1339
(defun linpower0 (exp var)
 
1340
  (cond ((and (setq exp (linpower exp var))
 
1341
              (eq (ask-integer (caddr exp) '$even)
 
1342
                  '$yes)
 
1343
              (ratgreaterp 0. (car exp)))
 
1344
         exp)))
1242
1345
 
1243
1346
;;; given (b*x+a)^n+c returns  (a b n c)
1244
 
(DEFUN LINPOWER (EXP VAR)
1245
 
 (let (LINPART DEG LC C VARLIST) 
1246
 
      (COND ((NOT (POLYP EXP))   NIL)
1247
 
            (t (let ((varlist (list var)))
1248
 
                 (NEWVAR EXP)
1249
 
                 (SETQ LINPART (CADR (RATREP* EXP)))
1250
 
                 (COND ((ATOM LINPART)
1251
 
                        NIL)
1252
 
                       (t (SETQ DEG (CADR LINPART)) 
 
1347
(defun linpower (exp var)
 
1348
  (let (linpart deg lc c varlist) 
 
1349
    (cond ((not (polyp exp))   nil)
 
1350
          (t (let ((varlist (list var)))
 
1351
               (newvar exp)
 
1352
               (setq linpart (cadr (ratrep* exp)))
 
1353
               (cond ((atom linpart)
 
1354
                      nil)
 
1355
                     (t (setq deg (cadr linpart)) 
1253
1356
;;;get high degree of poly
1254
 
                          (SETQ LINPART ($DIFF EXP VAR (m+ deg -1))) 
 
1357
                        (setq linpart ($diff exp var (m+ deg -1))) 
1255
1358
;;;diff down to linear.
1256
 
                          (SETQ LC (SDIFF LINPART VAR)) 
 
1359
                        (setq lc (sdiff linpart var))   
1257
1360
;;;all the way to constant.
1258
 
                          (SETQ LINPART ($RATSIMP (M// LINPART lc))) 
1259
 
                          (SETQ LC ($RATSIMP (M// LC `((MFACTORIAL) ,DEG))))
 
1361
                        (setq linpart ($ratsimp (m// linpart lc))) 
 
1362
                        (setq lc ($ratsimp (m// lc `((mfactorial) ,deg))))
1260
1363
;;;get rid of factorial from differentiation.
1261
 
                          (SETQ C ($RATSIMP (m+ EXP (m* (m- LC)
1262
 
                                                        (m^ LINPART DEG)))))))
 
1364
                        (setq c ($ratsimp (m+ exp (m* (m- lc)
 
1365
                                                      (m^ linpart deg)))))))
1263
1366
;;;Sees if can be expressed as (a*x+b)^n + part freeof x.
1264
 
                 (COND ((NOT (AMONG VAR c))
1265
 
                        `(,LC ,LINPART ,DEG ,C))
1266
 
                       (t nil)))))))
1267
 
 
1268
 
(DEFUN MTORAT (N D S)
1269
 
  (let ((SEMIRAT* t)) 
1270
 
       (COND ((AND (NULL *DFLAG)
1271
 
                   (SETQ S (DIFAPPLY N D s #'MTORAT)))
1272
 
              S)
1273
 
             (T (CSEMIUP N D VAR)))))
1274
 
 
1275
 
(DEFUN ZMTORAT (N D S FN1)
1276
 
 (PROG (C) 
1277
 
   (COND ((eq ($sign (m+ S (M+ 1 (SETQ NN* (DEG N))))) 
1278
 
              '$neg)
1279
 
          (Diverg))
1280
 
         ((eq ($sign (m+ s -4))
1281
 
              '$neg)
1282
 
          (GO ON)))
1283
 
   (SETQ D ($FACTOR D))
1284
 
   (SETQ C (RMCONST1 D))
1285
 
   (SETQ D (CDR C))
1286
 
   (SETQ C (CAR C))
1287
 
   (COND
1288
 
    ((mtimesp D)
1289
 
     (SETQ D (CDR D))
1290
 
     (SETQ N (PARTNUM N D))
1291
 
     (let ((RSN* t))
1292
 
          (SETQ N ($XTHRU (M+L
1293
 
                           (MAPCAR #'(LAMBDA (A B) 
1294
 
                                        (M// (FUNCALL FN1 (CAR A) B (DEG B)) 
1295
 
                                             (CADR A)))
1296
 
                                   N
1297
 
                                   D)))))
1298
 
     (RETURN (COND (C (M// N C)) 
1299
 
                   (T N)))))
1300
 
   ON
1301
 
 
1302
 
   (SETQ N (FUNCALL FN1 N D S))
1303
 
   (RETURN  (sRATSIMP (COND (C  (M// N C))
1304
 
                               (T N))))))
1305
 
 
1306
 
(DEFUN PFRNUM (F G N N2 VAR)
1307
 
  (let ((VARLIST (list var))  GENVAR)
1308
 
       (SETQ F (POLYFORM F)
1309
 
             G (POLYFORM G)
1310
 
             N (POLYFORM N)
1311
 
             N2 (POLYFORM N2))
1312
 
       (SETQ VAR (CAADR (RATREP* VAR)))
1313
 
       (SETQ F (RESPROG0 F G N N2))
1314
 
       (LIST (LIST (PDIS (CADR F)) (PDIS (CDDR F)))
1315
 
             (LIST (PDIS (CAAR F)) (PDIS (CDAR F))))))
1316
 
 
1317
 
(DEFUN POLYFORM (E)
1318
 
       (PROG (F D)
1319
 
             (NEWVAR E)
1320
 
             (SETQ F (RATREP* E))
1321
 
             (AND (EQUAL (CDDR F) 1)
1322
 
                  (RETURN (CADR F)))
1323
 
             (AND (EQUAL (LENGTH (SETQ D (CDDR F))) 3)
1324
 
                  (NOT (AMONG (CAR D)
1325
 
                              (CADR F)))
1326
 
                  (RETURN (LIST (CAR D)
1327
 
                                (f* -1 (CADR D))
1328
 
                                (PTIMES (CADR F) (CADDR D)))))
1329
 
             (MERROR "Bug from PFRNUM in RESIDU")))
1330
 
 
1331
 
(DEFUN PARTNUM (N DL)
1332
 
  (let ((n2 1)  ANS NL)
1333
 
       (do ((dl dl (cdr dl)))
1334
 
           ((null (cdr dl))
1335
 
            (nconc ans (ncons (list n n2))))
1336
 
           (SETQ NL (PFRNUM (CAR DL) (M*L (CDR DL)) N N2 VAR))
1337
 
           (SETQ ANS (NCONC ANS (NCONS (CAR NL))))
1338
 
           (SETQ N2 (CADADR NL) N (CAADR NL) NL NIL))))
1339
 
 
1340
 
(DEFUN GGRM (E)
1341
 
  (PROG (POLY EXPO MTOINF* MB  VARLIST  GENVAR L C GVAR) 
1342
 
    (SETQ VARLIST (LIST VAR))
1343
 
    (SETQ MTOINF* T)
1344
 
    (COND ((AND (SETQ EXPO (%EINVOLVE E))
1345
 
                (POLYP (SETQ POLY ($RATSIMP (M// E (m^t '$%E EXPO)))))
1346
 
                (SETQ L (CATCH 'GGRM (GGR (m^t '$%E EXPO) NIL))))
1347
 
           (SETQ MTOINF* NIL)
1348
 
           (SETQ MB (m- (SUBIN 0. (CADR L))))
1349
 
           (SETQ POLY (m+ (SUBIN (m+t MB VAR) POLY)
1350
 
                          (SUBIN (m+t MB (m*t -1. VAR)) POLY))))
1351
 
          (T (RETURN NIL)))
1352
 
    (SETQ EXPO (CADDR L)
1353
 
          C (CADDDR L)
1354
 
          L (m* -1. (CAR L))
1355
 
          E NIL)
1356
 
    (NEWVAR POLY)
1357
 
    (SETQ POLY (CDR (RATREP* POLY)))
1358
 
    (SETQ MB (m^ (PDIS (CDR POLY)) -1.) 
1359
 
          POLY (CAR POLY))
1360
 
    (SETQ GVAR (CAADR (RATREP* VAR)))
1361
 
    (COND ((OR (ATOM POLY)
1362
 
               (POINTERGP GVAR (CAR POLY))) 
1363
 
           (SETQ POLY (LIST 0. POLY)))
1364
 
          (T (SETQ POLY (CDR POLY))))
1365
 
    (return (do ((poly poly (cddr poly)))
1366
 
                ((null poly)
1367
 
                 (mul* (m^t '$%E C) (m^t EXPO -1.) MB (M+L E)))
1368
 
                (SETQ E (CONS (GGRM1 (CAR POLY) (PDIS (CADR POLY)) L EXPO)
1369
 
                              E))))))
1370
 
 
1371
 
(DEFUN GGRM1 (D K A B)
1372
 
       (SETQ B (M// (m+t 1. D) B))
1373
 
       (m* K `((%GAMMA) ,B) (m^ A (m- B)))) 
1374
 
 
1375
 
(DEFUN RADIC (E V) 
1376
 
;;;If rd* is t the m^ts must just be free of var.
1377
 
;;;If rd* is () the m^ts must be mnump's.
1378
 
       (let ((rd* ())) 
1379
 
            (RADICALP E V)))
1380
 
 
1381
 
(DEFUN KEYHOLE (N D VAR)
1382
 
       (let ((SEMIRAT* ()))
1383
 
         (SETQ N (RES N D #'(LAMBDA (J) 
1384
 
                              (OR (NOT (equal ($imagpart j) 0))
1385
 
                                  (EQ ($askSIGN J) '$neg)))
1386
 
                          #'(LAMBDA (J)
1387
 
                              (COND ((EQ ($askSIGN J) '$pos)
1388
 
                                     T)
1389
 
                                    (T (Diverg))))))
1390
 
         (let ((RSN* t))
1391
 
           ($rectform ($multthru (m+ (COND ((CAR N) (CAR N))
1392
 
                                           (T 0.))
1393
 
                                     (COND ((CADR N) (CADR N))
1394
 
                                           (T 0.))))))))
1395
 
 
1396
 
(DEFUN SKR (E)
1397
 
       (PROG (M R K) 
1398
 
             (COND ((ATOM E) (RETURN NIL)))
1399
 
             (SETQ E (PARTITION E VAR 1))
1400
 
             (SETQ M (CAR E))
1401
 
             (SETQ E (CDR E))
1402
 
             (COND ((SETQ R (SINRX E)) (RETURN (LIST M R 1)))
1403
 
                   ((AND (mexptp E)
1404
 
                         (eq (ask-integer (SETQ K (CADDR E)) '$integer) '$yes)
1405
 
                         (SETQ R (SINRX (CADR E))))
1406
 
                    (RETURN (LIST M R K)))))) 
1407
 
 
1408
 
(DEFUN SINRX (E)
1409
 
       (COND ((and (consp e) (EQ (CAAR E) '%SIN))
1410
 
              (COND ((EQ (CADR E) VAR) 1.)
1411
 
                    ((AND (SETQ E (PARTITION (CADR E) VAR 1)) (EQ (CDR E) VAR))
1412
 
                     (CAR E)))))) 
1413
 
 
1414
 
(DECLARE-TOP(SPECIAL N)) 
1415
 
 
1416
 
 
1417
 
(DEFUN SSP (EXP)
1418
 
 (PROG (U N C) 
1419
 
       (setq exp ($substitute (m^t `((%sin) ,var) 2.)
1420
 
                              (m+t 1. (m- (m^t `((%cos) ,var) 2.)))
1421
 
                              exp))
1422
 
       (numden exp)
1423
 
       (setq u nn*)
1424
 
       (COND ((AND (SETQ N (FINDP DN*))
1425
 
                   (eq (ask-integer N '$integer) '$yes))
1426
 
              (COND ((SETQ C (SKR U)) 
1427
 
                     (RETURN (SCMP C N)))
1428
 
                    ((AND (mplusp U)
1429
 
                          (SETQ C (ANDMAPCAR #'SKR (CDR U))))
1430
 
                     (RETURN (m+l (MAPCAR #'(LAMBDA (J) (SCMP J N))
1431
 
                                          C)))))))))
1432
 
 
1433
 
(DECLARE-TOP(UNSPECIAL N)) 
1434
 
 
1435
 
(DEFUN SCMP (C N)
1436
 
       (m* (CAR C) (m^ (CADR C) (m+ N -1)) `((%SIGNUM) ,(CADR C))
1437
 
           (SINSP (CADDR C) N)))
1438
 
 
1439
 
(DEFUN SEVN (N)
1440
 
       (m* HALF%PI ($MAKEGAMMA `((%BINOMIAL) ,(m+t (m+ N -1) '((RAT) -1. 2.))
1441
 
                                             ,(m+ N -1)))))
1442
 
 
1443
 
 
1444
 
(DEFUN SFORX (N)
1445
 
  (COND ((EQUAL N 1.) 
1446
 
         HALF%PI) 
1447
 
        (T (BYGAMMA (m+ N -1) 0.)))) 
1448
 
 
1449
 
(DEFUN SINSP (L K)
1450
 
  (let ((I ())
1451
 
        (J ()))
1452
 
    (COND ((eq ($sign (m+ L (m- (m+ K -1))))
 
1367
               (cond ((not (among var c))
 
1368
                      `(,lc ,linpart ,deg ,c))
 
1369
                     (t nil)))))))
 
1370
 
 
1371
(defun mtorat (n d s)
 
1372
  (let ((semirat* t)) 
 
1373
    (cond ((and (null *dflag)
 
1374
                (setq s (difapply n d s #'mtorat)))
 
1375
           s)
 
1376
          (t (csemiup n d var)))))
 
1377
 
 
1378
(defun zmtorat (n d s fn1)
 
1379
  (prog (c) 
 
1380
     (cond ((eq ($sign (m+ s (m+ 1 (setq nn* (deg n))))) 
 
1381
                '$neg)
 
1382
            (diverg))
 
1383
           ((eq ($sign (m+ s -4))
 
1384
                '$neg)
 
1385
            (go on)))
 
1386
     (setq d ($factor d))
 
1387
     (setq c (rmconst1 d))
 
1388
     (setq d (cdr c))
 
1389
     (setq c (car c))
 
1390
     (cond
 
1391
       ((mtimesp d)
 
1392
        (setq d (cdr d))
 
1393
        (setq n (partnum n d))
 
1394
        (let ((rsn* t))
 
1395
          (setq n ($xthru (m+l
 
1396
                           (mapcar #'(lambda (a b) 
 
1397
                                       (m// (funcall fn1 (car a) b (deg b)) 
 
1398
                                            (cadr a)))
 
1399
                                   n
 
1400
                                   d)))))
 
1401
        (return (cond (c (m// n c)) 
 
1402
                      (t n)))))
 
1403
     on
 
1404
 
 
1405
     (setq n (funcall fn1 n d s))
 
1406
     (return  (sratsimp (cond (c  (m// n c))
 
1407
                              (t n))))))
 
1408
 
 
1409
(defun pfrnum (f g n n2 var)
 
1410
  (let ((varlist (list var))  genvar)
 
1411
    (setq f (polyform f)
 
1412
          g (polyform g)
 
1413
          n (polyform n)
 
1414
          n2 (polyform n2))
 
1415
    (setq var (caadr (ratrep* var)))
 
1416
    (setq f (resprog0 f g n n2))
 
1417
    (list (list (pdis (cadr f)) (pdis (cddr f)))
 
1418
          (list (pdis (caar f)) (pdis (cdar f))))))
 
1419
 
 
1420
(defun polyform (e)
 
1421
  (prog (f d)
 
1422
     (newvar e)
 
1423
     (setq f (ratrep* e))
 
1424
     (and (equal (cddr f) 1)
 
1425
          (return (cadr f)))
 
1426
     (and (equal (length (setq d (cddr f))) 3)
 
1427
          (not (among (car d)
 
1428
                      (cadr f)))
 
1429
          (return (list (car d)
 
1430
                        (f* -1 (cadr d))
 
1431
                        (ptimes (cadr f) (caddr d)))))
 
1432
     (merror "Bug from `pfrnum' in `residu'")))
 
1433
 
 
1434
(defun partnum (n dl)
 
1435
  (let ((n2 1)  ans nl)
 
1436
    (do ((dl dl (cdr dl)))
 
1437
        ((null (cdr dl))
 
1438
         (nconc ans (ncons (list n n2))))
 
1439
      (setq nl (pfrnum (car dl) (m*l (cdr dl)) n n2 var))
 
1440
      (setq ans (nconc ans (ncons (car nl))))
 
1441
      (setq n2 (cadadr nl) n (caadr nl) nl nil))))
 
1442
 
 
1443
(defun ggrm (e)
 
1444
  (prog (poly expo *mtoinf* mb  varlist  genvar l c gvar) 
 
1445
     (setq varlist (list var))
 
1446
     (setq *mtoinf* t)
 
1447
     (cond ((and (setq expo (%einvolve e))
 
1448
                 (polyp (setq poly ($ratsimp (m// e (m^t '$%e expo)))))
 
1449
                 (setq l (catch 'ggrm (ggr (m^t '$%e expo) nil))))
 
1450
            (setq *mtoinf* nil)
 
1451
            (setq mb (m- (subin 0. (cadr l))))
 
1452
            (setq poly (m+ (subin (m+t mb var) poly)
 
1453
                           (subin (m+t mb (m*t -1. var)) poly))))
 
1454
           (t (return nil)))
 
1455
     (setq expo (caddr l)
 
1456
           c (cadddr l)
 
1457
           l (m* -1. (car l))
 
1458
           e nil)
 
1459
     (newvar poly)
 
1460
     (setq poly (cdr (ratrep* poly)))
 
1461
     (setq mb (m^ (pdis (cdr poly)) -1.) 
 
1462
           poly (car poly))
 
1463
     (setq gvar (caadr (ratrep* var)))
 
1464
     (cond ((or (atom poly)
 
1465
                (pointergp gvar (car poly))) 
 
1466
            (setq poly (list 0. poly)))
 
1467
           (t (setq poly (cdr poly))))
 
1468
     (return (do ((poly poly (cddr poly)))
 
1469
                 ((null poly)
 
1470
                  (mul* (m^t '$%e c) (m^t expo -1.) mb (m+l e)))
 
1471
               (setq e (cons (ggrm1 (car poly) (pdis (cadr poly)) l expo)
 
1472
                             e))))))
 
1473
 
 
1474
(defun ggrm1 (d k a b)
 
1475
  (setq b (m// (m+t 1. d) b))
 
1476
  (m* k `((%gamma) ,b) (m^ a (m- b)))) 
 
1477
 
 
1478
(defun radic (e v) 
 
1479
  ;;If rd* is t the m^ts must just be free of var.
 
1480
  ;;If rd* is () the m^ts must be mnump's.
 
1481
  (let ((rd* ())) 
 
1482
    (radicalp e v)))
 
1483
 
 
1484
(defun keyhole (n d var)
 
1485
  (let ((semirat* ()))
 
1486
    (setq n (res n d #'(lambda (j) 
 
1487
                         (or (not (equal ($imagpart j) 0))
 
1488
                             (eq ($asksign j) '$neg)))
 
1489
                 #'(lambda (j)
 
1490
                     (cond ((eq ($asksign j) '$pos)
 
1491
                            t)
 
1492
                           (t (diverg))))))
 
1493
    (let ((rsn* t))
 
1494
      ($rectform ($multthru (m+ (cond ((car n) (car n))
 
1495
                                      (t 0.))
 
1496
                                (cond ((cadr n) (cadr n))
 
1497
                                      (t 0.))))))))
 
1498
 
 
1499
;; Look at an expression e of the form sin(r*x)^k, where k is an
 
1500
;; integer.  Return the list (1 r k).  (Not sure if the first element
 
1501
;; of the list is always 1 because I'm not sure what partition is
 
1502
;; trying to do here.)
 
1503
(defun skr (e)
 
1504
  (prog (m r k) 
 
1505
     (cond ((atom e) (return nil)))
 
1506
     (setq e (partition e var 1))
 
1507
     (setq m (car e))
 
1508
     (setq e (cdr e))
 
1509
     (cond ((setq r (sinrx e))
 
1510
            (return (list m r 1)))
 
1511
           ((and (mexptp e)
 
1512
                 (eq (ask-integer (setq k (caddr e)) '$integer) '$yes)
 
1513
                 (setq r (sinrx (cadr e))))
 
1514
            (return (list m r k)))))) 
 
1515
 
 
1516
;; Look at an expression e of the form sin(r*x) and return r.
 
1517
(defun sinrx (e)
 
1518
  (cond ((and (consp e) (eq (caar e) '%sin))
 
1519
         (cond ((eq (cadr e) var)
 
1520
                1.)
 
1521
               ((and (setq e (partition (cadr e) var 1))
 
1522
                     (eq (cdr e) var))
 
1523
                (car e))))))
 
1524
 
 
1525
 
 
1526
 
 
1527
;; integrate(a*sc(r*x)^k/x^n,x,0,inf).
 
1528
(defun ssp (exp)
 
1529
  (prog (u n c)
 
1530
     ;; I don't think this needs to be special.
 
1531
     #+nil
 
1532
     (declare (special n))
 
1533
     ;; Replace (1-cos(x)^2) with sin(x)^2.
 
1534
     (setq exp ($substitute (m^t `((%sin) ,var) 2.)
 
1535
                            (m+t 1. (m- (m^t `((%cos) ,var) 2.)))
 
1536
                            exp))
 
1537
     (numden exp)
 
1538
     (setq u nn*)
 
1539
     (cond ((and (setq n (findp dn*))
 
1540
                 (eq (ask-integer n '$integer) '$yes))
 
1541
            ;; n is the power of the denominator.
 
1542
            (cond ((setq c (skr u))
 
1543
                   ;; The simple case.
 
1544
                   (return (scmp c n)))
 
1545
                  ((and (mplusp u)
 
1546
                        (setq c (andmapcar #'skr (cdr u))))
 
1547
                   ;; Do this for a sum of such terms.
 
1548
                   (return (m+l (mapcar #'(lambda (j) (scmp j n))
 
1549
                                        c)))))))))
 
1550
 
 
1551
;; We have an integral of the form sin(r*x)^k/x^n.  C is the list (1 r k).
 
1552
;;
 
1553
;; The substitution y=r*x converts this integral to
 
1554
;;
 
1555
;;   r^(n-1)*integral(sin(y)^k/y^n,y,0,inf)
 
1556
;;
 
1557
;; (If r is negative, we need to negate the result.)
 
1558
;;
 
1559
;; The recursion Wang gives on p. 87 has a typo.  The second term
 
1560
;; should be subtracted from the first.  This formula is given in G&R,
 
1561
;; 3.82, formula 12.
 
1562
;;
 
1563
;; integrate(sin(x)^r/x^s,x) =
 
1564
;;    r*(r-1)/(s-1)/(s-2)*integrate(sin(x)^(r-2)/x^(s-2),x)
 
1565
;;    - r^2/(s-1)/(s-2)*integrate(sin(x)^r/x^(s-2),x)
 
1566
;;
 
1567
;; (Limits are assumed to be 0 to inf.)
 
1568
;;
 
1569
;; This recursion ends up with integrals with s = 1 or 2 and
 
1570
;;
 
1571
;; integrate(sin(x)^p/x,x,0,inf) = integrate(sin(x)^(p-1),x,0,%pi/2)
 
1572
;;
 
1573
;; with p > 0 and odd.  This latter integral is known to maxima, and
 
1574
;; it's value is beta(p/2,1/2)/2.
 
1575
;;
 
1576
;; integrate(sin(x)^2/x^2,x,0,inf) = %pi/2*binomial(q-3/2,q-1)
 
1577
;;
 
1578
;; where q >= 2.
 
1579
;; 
 
1580
(defun scmp (c n)
 
1581
  ;; Compute sign(r)*r^(n-1)*integrate(sin(y)^k/y^n,y,0,inf)
 
1582
  (m* (car c)
 
1583
      (m^ (cadr c) (m+ n -1))
 
1584
      `((%signum) ,(cadr c))
 
1585
      (sinsp (caddr c) n)))
 
1586
 
 
1587
;; integrate(sin(x)^n/x^2,x,0,inf) = pi/2*binomial(n-3/2,n-1).
 
1588
;; Express in terms of Gamma functions, though.
 
1589
(defun sevn (n)
 
1590
  (m* half%pi ($makegamma `((%binomial) ,(m+t (m+ n -1) '((rat) -1. 2.))
 
1591
                            ,(m+ n -1)))))
 
1592
 
 
1593
 
 
1594
;; integrate(sin(x)^n/x,x,0,inf) = beta((n+1)/2,1/2)/2, for n odd and
 
1595
;; n > 0.
 
1596
(defun sforx (n)
 
1597
  (cond ((equal n 1.) 
 
1598
         half%pi) 
 
1599
        (t (bygamma (m+ n -1) 0.)))) 
 
1600
 
 
1601
;; This implements the recursion for computing
 
1602
;; integrate(sin(y)^l/y^k,y,0,inf).  (Note the change in notation from
 
1603
;; the above!)
 
1604
(defun sinsp (l k)
 
1605
  (let ((i ())
 
1606
        (j ()))
 
1607
    (cond ((eq ($sign (m+ l (m- (m+ k -1))))
1453
1608
               '$neg)
1454
 
           (Diverg))
1455
 
          ((NOT (EVEN1 (m+ L K)))
1456
 
           NIL)
1457
 
          ((EQUAL K 2.)
1458
 
           (SEVN (m// L 2.)))
1459
 
          ((EQUAL K 1.) 
1460
 
           (SFORX L))
1461
 
          ((eq ($sign  (m+ K -2.))
 
1609
           ;; Integral diverges if l-(k-1) < 0.
 
1610
           (diverg))
 
1611
          ((not (even1 (m+ l k)))
 
1612
           ;; If l + k is not even, return NIL.  (Is this the right
 
1613
           ;; thing to do?)
 
1614
           nil)
 
1615
          ((equal k 2.)
 
1616
           ;; We have integrate(sin(y)^l/y^2).  Use sevn to evaluate.
 
1617
           (sevn (m// l 2.)))
 
1618
          ((equal k 1.)
 
1619
           ;; We have integrate(sin(y)^l/y,y)
 
1620
           (sforx l))
 
1621
          ((eq ($sign  (m+ k -2.))
1462
1622
               '$pos)
1463
 
           (SETQ I (m* (m+ K -1) (SETQ J (m+ K -2.))))
1464
 
           (m+ (m* L (m+ L -1) (m^t I -1.) (SINSP (m+ L -2.) J))
1465
 
               (m* (m- (m^ L 2)) (m^t I -1.)
1466
 
                   (SINSP L J)))))))
1467
 
 
1468
 
(DEFUN FPART (A)
1469
 
  (COND ((NULL A) 0.)
1470
 
        ((NUMBERP A) 0.)
1471
 
        ((MNUMP A)
1472
 
         (LIST (CAR A) (REMAINDER (CADR A) (CADDR A)) (CADDR A)))
1473
 
        ((AND (ATOM A) (ABLESS1 A)) A)
1474
 
        ((AND (mplusp A)
1475
 
              (NULL (CDDDR A))
1476
 
              (ABLESS1 (CADDR A)))
1477
 
         (CADDR A)))) 
1478
 
 
1479
 
(DEFUN THRAD (E)
1480
 
       (COND ((POLYINX E VAR NIL) 0.)
1481
 
             ((AND (mexptp E) 
1482
 
                   (EQ (CADR E) VAR)
1483
 
                   (MNUMP (CADDR E)))
1484
 
              (FPART (CADDR E)))
1485
 
             ((mtimesp E)
1486
 
              (m+l (MAPCAR #'THRAD E)))))
 
1623
           (setq i (m* (m+ k -1)
 
1624
                       (setq j (m+ k -2.))))
 
1625
           ;; j = k-2, i = (k-1)*(k-2)
 
1626
           ;;
 
1627
           ;; 
 
1628
           ;; The main recursion:
 
1629
           ;;
 
1630
           ;; i(sin(y)^l/y^k)
 
1631
           ;;    = l*(l-1)/(k-1)/(k-2)*i(sin(y)^(l-2)/y^k)
 
1632
           ;;      - l^2/(k-1)/(k-1)*i(sin(y)^l/y^(k-2))
 
1633
           (m+ (m* l (m+ l -1)
 
1634
                   (m^t i -1.)
 
1635
                   (sinsp (m+ l -2.) j))
 
1636
               (m* (m- (m^ l 2))
 
1637
                   (m^t i -1.)
 
1638
                   (sinsp l j)))))))
 
1639
 
 
1640
(defun fpart (a)
 
1641
  (cond ((null a) 0.)
 
1642
        ((numberp a) 0.)
 
1643
        ((mnump a)
 
1644
         (list (car a) (remainder (cadr a) (caddr a)) (caddr a)))
 
1645
        ((and (atom a) (abless1 a)) a)
 
1646
        ((and (mplusp a)
 
1647
              (null (cdddr a))
 
1648
              (abless1 (caddr a)))
 
1649
         (caddr a)))) 
 
1650
 
 
1651
(defun thrad (e)
 
1652
  (cond ((polyinx e var nil) 0.)
 
1653
        ((and (mexptp e) 
 
1654
              (eq (cadr e) var)
 
1655
              (mnump (caddr e)))
 
1656
         (fpart (caddr e)))
 
1657
        ((mtimesp e)
 
1658
         (m+l (mapcar #'thrad e)))))
1487
1659
 
1488
1660
 
1489
1661
;;; THE FOLLOWING FUNCTION IS FOR TRIG FUNCTIONS OF THE FOLLOWING TYPE:
1490
1662
;;; LOWER LIMIT=0 B A MULTIPLE OF %PI SCA FUNCTION OF SIN (X) COS (X)
1491
1663
;;; B<=%PI2
1492
1664
 
1493
 
(DEFUN PERIOD (P E VAR)
1494
 
  (and (ALIKE1 (no-err-sub var E) (setq e (NO-ERR-SUB (m+ P VAR) E)))
 
1665
(defun period (p e var)
 
1666
  (and (alike1 (no-err-sub var e) (setq e (no-err-sub (m+ p var) e)))
1495
1667
       ;; means there was no error
1496
1668
       (not (eq e t))))
1497
1669
 
1498
 
(DEFUN INFR (A)
 
1670
(defun infr (a)
1499
1671
  (let ((var '$%i)
1500
1672
        (r (subin 0. a))
1501
1673
        c)
1502
 
       (SETQ C (SUBIN 1. (m+ A (m*t -1. R))))
1503
 
       (SETQ A (IGPRT (m* '((RAT) 1. 2.) C)))
1504
 
       (CONS A (m+ R (m*t (M+ C (m* -2. A)) '$%PI)))))
 
1674
    (setq c (subin 1. (m+ a (m*t -1. r))))
 
1675
    (setq a (igprt (m* '((rat) 1. 2.) c)))
 
1676
    (cons a (m+ r (m*t (m+ c (m* -2. a)) '$%pi)))))
1505
1677
 
1506
 
(DEFUN IGPRT (R) 
1507
 
       (M+ R (m* -1. (FPART R)))) 
 
1678
(defun igprt (r) 
 
1679
  (m+ r (m* -1. (fpart r)))) 
1508
1680
 
1509
1681
 
1510
1682
;;;Try making exp(%i*var) --> yy, if result is rational then do integral
1511
1683
;;;around unit circle. Make corrections for limits of integration if possible.
1512
 
(DEFUN SCRAT (SC B)
1513
 
  (let* ((exp-form (sconvert sc)) ;Exponentialize
1514
 
         (rat-form (MAXIMA-SUBSTITUTE 'yy (m^t '$%e (m*t '$%i var))
1515
 
                               exp-form))) ;Try to make Rational fun.
1516
 
        (COND ((AND (RATP rat-form 'YY)
1517
 
                    (NOT (AMONG VAR rat-form)))
1518
 
               (COND ((ALIKE1 B %PI2) 
1519
 
                      (let ((ans (ZTO%PI2 rat-form 'YY)))
1520
 
                           (cond (ans ans)
1521
 
                                 (t nil))))
1522
 
                     ((AND (EQ B '$%PI)
1523
 
                           (EVENFN exp-form VAR))
1524
 
                      (let ((ans (ZTO%PI2 rat-form 'YY)))
1525
 
                           (cond (ans (m*t '((RAT) 1. 2.) ans))
1526
 
                                 (t nil))))
1527
 
                     ((AND (ALIKE1 B HALF%PI)
1528
 
                           (EVENFN exp-form VAR)
1529
 
                           (ALIKE1 rat-form 
1530
 
                                   (NO-ERR-SUB (m+t '$%PI (m*t -1. VAR))
1531
 
                                                    rat-form)))
1532
 
                           (let ((ans (ZTO%PI2 rat-form 'yy)))
1533
 
                                (cond (ans (m*t '((RAT) 1. 4.) ans))
1534
 
                                      (t nil)))))))))
 
1684
(defun scrat (sc b)
 
1685
  (let* ((exp-form (sconvert sc))       ;Exponentialize
 
1686
         (rat-form (maxima-substitute 'yy (m^t '$%e (m*t '$%i var))
 
1687
                                      exp-form))) ;Try to make Rational fun.
 
1688
    (cond ((and (ratp rat-form 'yy)
 
1689
                (not (among var rat-form)))
 
1690
           (cond ((alike1 b %pi2) 
 
1691
                  (let ((ans (zto%pi2 rat-form 'yy)))
 
1692
                    (cond (ans ans)
 
1693
                          (t nil))))
 
1694
                 ((and (eq b '$%pi)
 
1695
                       (evenfn exp-form var))
 
1696
                  (let ((ans (zto%pi2 rat-form 'yy)))
 
1697
                    (cond (ans (m*t '((rat) 1. 2.) ans))
 
1698
                          (t nil))))
 
1699
                 ((and (alike1 b half%pi)
 
1700
                       (evenfn exp-form var)
 
1701
                       (alike1 rat-form 
 
1702
                               (no-err-sub (m+t '$%pi (m*t -1. var))
 
1703
                                           rat-form)))
 
1704
                  (let ((ans (zto%pi2 rat-form 'yy)))
 
1705
                    (cond (ans (m*t '((rat) 1. 4.) ans))
 
1706
                          (t nil)))))))))
1535
1707
 
1536
1708
;;; Do integrals of sin and cos. this routine makes sure lower limit
1537
1709
;;; is zero.
1538
 
(defun INTSC1 (A B E)
 
1710
(defun intsc1 (a b e)
1539
1711
  (let ((limit-diff (m+ b (m* -1 a)))
1540
1712
        ($%emode t)
1541
1713
        ($trigsign t)
1542
 
        (sin-cos-recur t)) ;recursion stopper
1543
 
     (PROG (ANS D NZP2 L) 
1544
 
           (COND ((OR (NOT (MNUMP (M// limit-diff '$%PI)))
1545
 
                      (NOT (PERIOD %PI2 E VAR)))
1546
 
                  (RETURN NIL))
1547
 
                 ((not (equal a 0.))
1548
 
                  (setq e (MAXIMA-SUBSTITUTE (m+ a var) var e))
1549
 
                  (setq a 0.)
1550
 
                  (setq b limit-diff)))
 
1714
        (*sin-cos-recur* t))            ;recursion stopper
 
1715
    (prog (ans d nzp2 l) 
 
1716
       (cond ((or (not (mnump (m// limit-diff '$%pi)))
 
1717
                  (not (period %pi2 e var)))
 
1718
              (return nil))
 
1719
             ((not (equal a 0.))
 
1720
              (setq e (maxima-substitute (m+ a var) var e))
 
1721
              (setq a 0.)
 
1722
              (setq b limit-diff)))
1551
1723
;;;Multiples of 2*%pi in limits.
1552
 
           (COND ((eq (ask-integer (SETQ D (let (($float nil))
1553
 
                                             (m// limit-diff %pi2))) '$integer)
1554
 
                      '$yes)
1555
 
                  (SETQ ANS (m* D (COND ((SETQ ANS (INTSC E %PI2 VAR))
1556
 
                                         (RETURN ans))
1557
 
                                        (T (RETURN NIL)))))))
1558
 
                  (COND ((RATGREATERP %PI2 B)
1559
 
                         (RETURN (INTSC E B VAR)))
1560
 
                        (T (SETQ L A) 
1561
 
                           (SETQ A 0.)))
1562
 
                  (SETQ B (INFR B))
1563
 
                  (COND ((NULL L) 
1564
 
                         (SETQ NZP2 (CAR B))
1565
 
                         (SETQ limit-diff 0.)
1566
 
                         (GO OUT)))
1567
 
                  (SETQ L (INFR L))
1568
 
                  (SETQ limit-diff
1569
 
                        (m*t -1. (COND ((SETQ ANS (INTSC E (CDR L) VAR)) 
1570
 
                                        ANS)
1571
 
                                       (T (RETURN NIL)))))
1572
 
                  (SETQ NZP2 (m+ (CAR B) (m- (CAR L))))
1573
 
             OUT  (SETQ ANS (add* (COND ((ZEROP1 NZP2) 0.)
1574
 
                                        ((SETQ ANS (INTSC E %PI2 VAR))
1575
 
                                         (m*t NZP2 ANS))
1576
 
                                        (T (RETURN NIL)))
1577
 
                                  (COND ((ZEROP1 (CDR B)) 0.)
1578
 
                                        ((SETQ ANS (INTSC E (CDR B) VAR))
1579
 
                                         ANS)
1580
 
                                        (T (RETURN NIL)))
1581
 
                                  limit-diff))
1582
 
             (RETURN ANS))))
1583
 
 
1584
 
(DEFUN INTSC (SC B VAR)
1585
 
       (COND ((EQ ($sign B) '$neg)
1586
 
              (SETQ B (m*t -1. B))
1587
 
              (SETQ SC (m* -1. (SUBIN (m*t -1. VAR) SC)))))
1588
 
       (SETQ SC (PARTITION SC VAR 1))
1589
 
       (COND ((SETQ B (INTSC0 (CDR SC) B VAR))
1590
 
              (m* (resimplify (CAR SC)) B))))
1591
 
 
1592
 
(DEFUN INTSC0 (SC B VAR)
 
1724
       (cond ((eq (ask-integer (setq d (let (($float nil))
 
1725
                                         (m// limit-diff %pi2))) '$integer)
 
1726
                  '$yes)
 
1727
              (setq ans (m* d (cond ((setq ans (intsc e %pi2 var))
 
1728
                                     (return ans))
 
1729
                                    (t (return nil)))))))
 
1730
       (cond ((ratgreaterp %pi2 b)
 
1731
              (return (intsc e b var)))
 
1732
             (t (setq l a) 
 
1733
                (setq a 0.)))
 
1734
       (setq b (infr b))
 
1735
       (cond ((null l) 
 
1736
              (setq nzp2 (car b))
 
1737
              (setq limit-diff 0.)
 
1738
              (go out)))
 
1739
       (setq l (infr l))
 
1740
       (setq limit-diff
 
1741
             (m*t -1. (cond ((setq ans (intsc e (cdr l) var)) 
 
1742
                             ans)
 
1743
                            (t (return nil)))))
 
1744
       (setq nzp2 (m+ (car b) (m- (car l))))
 
1745
       out  (setq ans (add* (cond ((zerop1 nzp2) 0.)
 
1746
                                  ((setq ans (intsc e %pi2 var))
 
1747
                                   (m*t nzp2 ans))
 
1748
                                  (t (return nil)))
 
1749
                            (cond ((zerop1 (cdr b)) 0.)
 
1750
                                  ((setq ans (intsc e (cdr b) var))
 
1751
                                   ans)
 
1752
                                  (t (return nil)))
 
1753
                            limit-diff))
 
1754
       (return ans))))
 
1755
 
 
1756
(defun intsc (sc b var)
 
1757
  (cond ((eq ($sign b) '$neg)
 
1758
         (setq b (m*t -1. b))
 
1759
         (setq sc (m* -1. (subin (m*t -1. var) sc)))))
 
1760
  (setq sc (partition sc var 1))
 
1761
  (cond ((setq b (intsc0 (cdr sc) b var))
 
1762
         (m* (resimplify (car sc)) b))))
 
1763
 
 
1764
(defun intsc0 (sc b var)
1593
1765
  (let ((nn* (scprod sc))
1594
1766
        (dn* ()))
1595
 
       (COND (NN* (COND ((ALIKE1 B HALF%PI)
1596
 
                         (BYGAMMA (CAR NN*) (CADR NN*)))
1597
 
                        ((EQ B '$%PI)
1598
 
                         (cond ((eq (real-branch (cadr nn*) -1.) '$yes)
1599
 
                                 (m* (m+ 1. (m^ -1 (CADR NN*)))
1600
 
                                     (BYGAMMA (car nn*) (cadr nn*))))))
1601
 
                        ((ALIKE1 B %PI2)
1602
 
                         (COND ((or (AND (eq (ask-integer (CAR NN*) '$even)
1603
 
                                             '$yes)
1604
 
                                         (eq (ask-integer (CADR NN*) '$even)
1605
 
                                             '$yes))
1606
 
                                     (and (ratnump (car nn*))
1607
 
                                          (eq (real-branch (car nn*) -1.)
1608
 
                                              '$yes)
1609
 
                                          (ratnump (cadr nn*))
1610
 
                                          (eq (real-branch (cadr nn*) -1.)
1611
 
                                              '$yes)))
1612
 
                                 (m* 4. (BYGAMMA (car nn*) (cadr nn*))))
1613
 
                                ((or (eq (ask-integer (car nn*) '$odd) '$yes)
1614
 
                                     (eq (ask-integer (cadr nn*) '$odd) '$yes))
1615
 
                                 0.)
1616
 
                                (t nil)))
1617
 
                         ((ALIKE1 B HALF%PI3)
1618
 
                          (m* (m+ 1. (m^ -1 (CADR NN*)) (m^ -1 (m+l NN*)))
1619
 
                              (bygamma (car nn*) (cadr nn*))))))
1620
 
             (t (cond ((AND (OR (EQ B '$%PI)
1621
 
                                (ALIKE1 B %PI2)
1622
 
                                (ALIKE1 B HALF%PI))
1623
 
                            (SETQ DN* (SCRAT SC B)))
1624
 
                       DN*)
1625
 
                      ((SETQ NN* (ANTIDERIV SC))
1626
 
                       (sin-cos-intsubs nn* var 0. b))
1627
 
                      (t ()))))))
 
1767
    (cond (nn* (cond ((alike1 b half%pi)
 
1768
                      (bygamma (car nn*) (cadr nn*)))
 
1769
                     ((eq b '$%pi)
 
1770
                      (cond ((eq (real-branch (cadr nn*) -1.) '$yes)
 
1771
                             (m* (m+ 1. (m^ -1 (cadr nn*)))
 
1772
                                 (bygamma (car nn*) (cadr nn*))))))
 
1773
                     ((alike1 b %pi2)
 
1774
                      (cond ((or (and (eq (ask-integer (car nn*) '$even)
 
1775
                                          '$yes)
 
1776
                                      (eq (ask-integer (cadr nn*) '$even)
 
1777
                                          '$yes))
 
1778
                                 (and (ratnump (car nn*))
 
1779
                                      (eq (real-branch (car nn*) -1.)
 
1780
                                          '$yes)
 
1781
                                      (ratnump (cadr nn*))
 
1782
                                      (eq (real-branch (cadr nn*) -1.)
 
1783
                                          '$yes)))
 
1784
                             (m* 4.     (bygamma (car nn*) (cadr nn*))))
 
1785
                            ((or (eq (ask-integer (car nn*) '$odd) '$yes)
 
1786
                                 (eq (ask-integer (cadr nn*) '$odd) '$yes))
 
1787
                             0.)
 
1788
                            (t nil)))
 
1789
                     ((alike1 b half%pi3)
 
1790
                      (m* (m+ 1. (m^ -1 (cadr nn*)) (m^ -1 (m+l nn*)))
 
1791
                          (bygamma (car nn*) (cadr nn*))))))
 
1792
          (t (cond ((and (or (eq b '$%pi)
 
1793
                             (alike1 b %pi2)
 
1794
                             (alike1 b half%pi))
 
1795
                         (setq dn* (scrat sc b)))
 
1796
                    dn*)
 
1797
                   ((setq nn* (antideriv sc))
 
1798
                    (sin-cos-intsubs nn* var 0. b))
 
1799
                   (t ()))))))
1628
1800
 
1629
1801
;;;Is careful about substitution of limits where the denominator may be zero
1630
1802
;;;because of various assumptions made.
1639
1811
         (denom (pdis (cddr rat-exp))))
1640
1812
    (cond ((not (equal (intsubs num ll ul) 0.))
1641
1813
           (intsubs exp ll ul))
 
1814
          ;; Why do we want to return zero when the denom is not zero?
 
1815
          ;; That doesn't seem to make sense to me (rtoy).  Checking
 
1816
          ;; for a zero denominator makes sense, but what we should
 
1817
          ;; return in that case?  0 seems like a bad choice.  $inf or
 
1818
          ;; $undefined seem like better choices.  Or maybe just
 
1819
          ;; signaling an error?
 
1820
          #+nil  
1642
1821
          ((not (equal ($asksign denom) '$zero))
1643
1822
           0.)
 
1823
          ((equal ($asksign denom) '$zero)
 
1824
           '$undefined)
1644
1825
          (t (let (($%piargs ()))
1645
1826
               (intsubs exp ll ul))))))
1646
1827
 
1647
 
(DEFUN SCPROD (E)
1648
 
 (let ((great-minus-1 #'(lambda (temp)
1649
 
                          (ratgreaterp temp -1)))
1650
 
       m n)
1651
 
   (COND
1652
 
    ((SETQ M (Powerofx E `((%SIN) ,VAR) great-minus-1 VAR))
1653
 
     (list m 0.))
1654
 
    ((SETQ N (Powerofx E `((%COS) ,VAR) great-minus-1 VAR))
1655
 
     (SETQ M 0.)
1656
 
     (list 0. n))
1657
 
    ((AND (mtimesp E)
1658
 
          (OR (SETQ M (Powerofx (CADR E) `((%SIN) ,VAR) great-minus-1 VAR))
1659
 
              (SETQ N (Powerofx (CADR E) `((%COS) ,VAR) great-minus-1 VAR)))
1660
 
          (COND
1661
 
           ((NULL M)
1662
 
            (SETQ M (Powerofx (CADDR E) `((%SIN) ,VAR) great-minus-1 VAR)))
1663
 
           (T (SETQ N (Powerofx (CADDR E) `((%COS) ,VAR) great-minus-1 VAR))))
1664
 
          (NULL (CDDDR E)))
1665
 
     (list m n))
1666
 
    (T ()))))
 
1828
(defun scprod (e)
 
1829
  (let ((great-minus-1 #'(lambda (temp)
 
1830
                           (ratgreaterp temp -1)))
 
1831
        m n)
 
1832
    (cond
 
1833
      ((setq m (powerofx e `((%sin) ,var) great-minus-1 var))
 
1834
       (list m 0.))
 
1835
      ((setq n (powerofx e `((%cos) ,var) great-minus-1 var))
 
1836
       (setq m 0.)
 
1837
       (list 0. n))
 
1838
      ((and (mtimesp e)
 
1839
            (or (setq m (powerofx (cadr e) `((%sin) ,var) great-minus-1 var))
 
1840
                (setq n (powerofx (cadr e) `((%cos) ,var) great-minus-1 var)))
 
1841
            (cond
 
1842
              ((null m)
 
1843
               (setq m (powerofx (caddr e) `((%sin) ,var) great-minus-1 var)))
 
1844
              (t (setq n (powerofx (caddr e) `((%cos) ,var) great-minus-1 var))))
 
1845
            (null (cdddr e)))
 
1846
       (list m n))
 
1847
      (t ()))))
1667
1848
 
1668
1849
(defun real-branch (exponent value)
1669
 
;;;Says wether (m^t value exponent) has at least one real branch.
1670
 
;;;Only works for values of 1 and -1 now.
1671
 
;;;Returns $yes $no $unknown.
1672
 
       (cond ((equal value 1.)
1673
 
              '$yes)
1674
 
             ((eq (ask-integer exponent '$integer) '$yes)
1675
 
              '$yes)
1676
 
             ((ratnump exponent)
1677
 
              (cond ((eq ($oddp (caddr exponent)) t)
1678
 
                     '$yes)
1679
 
                    (t '$no)))
1680
 
             (t '$unknown)))
1681
 
 
1682
 
(DEFUN BYGAMMA (M N)
1683
 
       (let ((one-half (m//t 1. 2.)))
1684
 
       (m* one-half `(($BETA) ,(m* one-half (m+t 1. M))
1685
 
                              ,(m* one-half (m+t 1. N))))))
1686
 
 
1687
 
;Seems like Guys who call this don't agree on what it should return.
1688
 
(DEFUN Powerofx (E X P VAR)
1689
 
       (SETQ E (COND ((NOT (AMONG VAR E)) NIL)
1690
 
                     ((ALIKE1 E X) 1.)
1691
 
                     ((ATOM E) NIL)
1692
 
                     ((AND (mexptp E)
1693
 
                           (ALIKE1 (CADR E) X)
1694
 
                           (NOT (AMONG VAR (CADDR E))))
1695
 
                      (CADDR E))))
1696
 
       (COND ((NULL E) NIL)
1697
 
             ((FUNCALL P E) E))) 
1698
 
 
1699
 
(DECLARE-TOP(SPECIAL L C K)) 
1700
 
 
1701
 
(COMMENT (THE FOLLOWING FUNC IS NOT COMPLETE)) 
1702
 
 
1703
 
;(DEFUN ZTO1 (E)
1704
 
;  (prog (ans k l)
1705
 
;    (COND ((NOTINVOLVE E '(%SIN %COS %TAN %LOG))
1706
 
;          (cond ((SETQ ANS (BATAP E))
1707
 
;                 (return ans)))))
1708
 
;    (cond ((AND (NOTINVOLVE E '(%SIN %COS %TAN))
1709
 
;               (AMONG '%LOG E))
1710
 
;          (COND ((SETQ ANS (BATAP (M// E `((%LOG) ,VAR))))
1711
 
;                 (SETQ K NN* L DN*)
1712
 
;                 (SETQ ANS (m* ANS
1713
 
;                               (m+ (subfunmake '$PSI '(0) (list K))
1714
 
;                                   (m* -1. (subfunmake '$PSI
1715
 
;                                                       '(0)
1716
 
;                                                       (ncons (m+ K
1717
 
;                                                                  L)))))))
1718
 
;                 (return ans)))))))
1719
 
 
1720
 
 
1721
 
 
1722
 
(DEFUN BATA0 (E)
1723
 
  (COND ((ATOM E) NIL)
1724
 
        ((AND (mtimesp E)
1725
 
              (NULL (CDDDR E))
1726
 
              (OR (AND (SETQ K (FINDP (CADR E)))
1727
 
                       (SETQ C (BXM (CADDR E) (POLYINX (CADDR E) VAR NIL))))
1728
 
                  (AND (SETQ K (FINDP (CADDR E)))
1729
 
                       (SETQ C (BXM (CADR E) (POLYINX (CADR E) VAR NIL))))))
1730
 
         T)
1731
 
        ((SETQ C (BXM E (POLYINX E VAR NIL)))
1732
 
         (SETQ K 0.)))) 
1733
 
 
1734
 
;(DEFUN BATAP (E) 
1735
 
;  (PROG (K C L) 
1736
 
;    (COND ((NOT (BATA0 E)) (RETURN NIL))
1737
 
;         ((AND (EQUAL -1. (CADDDR C))
1738
 
;               (EQ ($askSIGN (SETQ K (m+ 1. K)))
1739
 
;                   '$pos)
1740
 
;               (EQ ($askSIGN (SETQ L (m+ 1. (CAR C))))
1741
 
;                   '$pos)
1742
 
;               (ALIKE1 (CADR C)
1743
 
;                       (m^ UL (CADDR C)))
1744
 
;               (SETQ E (CADR C))
1745
 
;               (EQ ($askSIGN (SETQ C (CADDR C))) '$pos))
1746
 
;          (RETURN (M// (m* (m^ UL (m+t K (m* C (m+t -1. L))))
1747
 
;                           `(($BETA) ,(SETQ NN* (M// K C))
1748
 
;                                     ,(SETQ DN* L)))
1749
 
;                       C))))))
1750
 
 
1751
 
 
1752
 
;;; Integrals of the form i(log(x)^m*x^k*(a+b*x^n)^l,x,0,ul) with
1753
 
;;; ul>0, b<0, a=-b*ul^n, k>-1, l>-1, n>0, m a nonnegative integer. 
1754
 
;;; These integrals are essentially partial derivatives of the 
1755
 
;;; Beta function (i.e. the Eulerian integral of the first kind).
1756
 
;;; Note that, currently, with the default setting intanalysis:true,
1757
 
;;; this function might not even be called for some of these integrals.
1758
 
;;; However, this can be palliated by setting intanalysis:false. 
 
1850
  ;; Says wether (m^t value exponent) has at least one real branch.
 
1851
  ;; Only works for values of 1 and -1 now.  Returns $yes $no
 
1852
  ;; $unknown.
 
1853
  (cond ((equal value 1.)
 
1854
         '$yes)
 
1855
        ((eq (ask-integer exponent '$integer) '$yes)
 
1856
         '$yes)
 
1857
        ((ratnump exponent)
 
1858
         (cond ((eq ($oddp (caddr exponent)) t)
 
1859
                '$yes)
 
1860
               (t '$no)))
 
1861
        (t '$unknown)))
 
1862
 
 
1863
;; Compute beta((m+1)/2,(n+1)/2)/2.
 
1864
(defun bygamma (m n)
 
1865
  (let ((one-half (m//t 1. 2.)))
 
1866
    (m* one-half `(($beta) ,(m* one-half (m+t 1. m))
 
1867
                   ,(m* one-half (m+t 1. n))))))
 
1868
 
 
1869
;;Seems like Guys who call this don't agree on what it should return.
 
1870
(defun powerofx (e x p var)
 
1871
  (setq e (cond ((not (among var e)) nil)
 
1872
                ((alike1 e x) 1.)
 
1873
                ((atom e) nil)
 
1874
                ((and (mexptp e)
 
1875
                      (alike1 (cadr e) x)
 
1876
                      (not (among var (caddr e))))
 
1877
                 (caddr e))))
 
1878
  (cond ((null e) nil)
 
1879
        ((funcall p e) e))) 
 
1880
 
 
1881
 
 
1882
(comment (the following func is not complete)) 
 
1883
 
 
1884
;;(DEFUN ZTO1 (E)
 
1885
;;  (prog (ans k l)
 
1886
;;    (COND ((NOTINVOLVE E '(%SIN %COS %TAN %LOG))
 
1887
;;         (cond ((SETQ ANS (BATAP E))
 
1888
;;                (return ans)))))
 
1889
;;    (cond ((AND (NOTINVOLVE E '(%SIN %COS %TAN))
 
1890
;;              (AMONG '%LOG E))
 
1891
;;         (COND ((SETQ ANS (BATAP (M// E `((%LOG) ,VAR))))
 
1892
;;                (SETQ K NN* L DN*)
 
1893
;;                (SETQ ANS (m* ANS
 
1894
;;                              (m+ (subfunmake '$PSI '(0) (list K))
 
1895
;;                                  (m* -1. (subfunmake '$PSI
 
1896
;;                                                      '(0)
 
1897
;;                                                      (ncons (m+ K
 
1898
;;                                                                 L)))))))
 
1899
;;                (return ans)))))))
 
1900
 
 
1901
 
 
1902
 
 
1903
;; Check e for an expression of the form x^kk*(b*x^n+a)^l.  If it
 
1904
;; matches, Return the two values kk and (list l a n b).
 
1905
(defun bata0 (e)
 
1906
  (let (k c)
 
1907
    (cond ((atom e) nil)
 
1908
          ((and (mtimesp e)
 
1909
                (null (cdddr e))
 
1910
                (or (and (setq k (findp (cadr e)))
 
1911
                         (setq c (bxm (caddr e) (polyinx (caddr e) var nil))))
 
1912
                    (and (setq k (findp (caddr e)))
 
1913
                         (setq c (bxm (cadr e) (polyinx (cadr e) var nil))))))
 
1914
           (values k c))
 
1915
          ((setq c (bxm e (polyinx e var nil)))
 
1916
           (setq k 0.)
 
1917
           (values k c)))))
 
1918
 
 
1919
 
 
1920
;;(DEFUN BATAP (E) 
 
1921
;;  (PROG (K C L) 
 
1922
;;    (COND ((NOT (BATA0 E)) (RETURN NIL))
 
1923
;;        ((AND (EQUAL -1. (CADDDR C))
 
1924
;;              (EQ ($askSIGN (SETQ K (m+ 1. K)))
 
1925
;;                  '$pos)
 
1926
;;              (EQ ($askSIGN (SETQ L (m+ 1. (CAR C))))
 
1927
;;                  '$pos)
 
1928
;;              (ALIKE1 (CADR C)
 
1929
;;                      (m^ UL (CADDR C)))
 
1930
;;              (SETQ E (CADR C))
 
1931
;;              (EQ ($askSIGN (SETQ C (CADDR C))) '$pos))
 
1932
;;         (RETURN (M// (m* (m^ UL (m+t K (m* C (m+t -1. L))))
 
1933
;;                          `(($BETA) ,(SETQ NN* (M// K C))
 
1934
;;                                    ,(SETQ DN* L)))
 
1935
;;                      C))))))
 
1936
 
 
1937
 
 
1938
;; Integrals of the form i(log(x)^m*x^k*(a+b*x^n)^l,x,0,ul).  There
 
1939
;; are two cases to consider: One case has ul>0, b<0, a=-b*ul^n, k>-1,
 
1940
;; l>-1, n>0, m a nonnegative integer.  The second case has ul=inf, l < 0.
 
1941
;;
 
1942
;; These integrals are essentially partial derivatives of the Beta
 
1943
;; function (i.e. the Eulerian integral of the first kind).  Note
 
1944
;; that, currently, with the default setting intanalysis:true, this
 
1945
;; function might not even be called for some of these integrals.
 
1946
;; However, this can be palliated by setting intanalysis:false.
1759
1947
 
1760
1948
(defun zto1 (e)                         
1761
1949
  (when (or (mtimesp e) (mexptp e))
1762
 
    (let ((m 0) (log (list '(%log) var)))
1763
 
      (flet ((set-m (p) (setq m p)))
1764
 
            (find-if #'(lambda (fac) (powerofx fac log #'set-m var)) (cdr e)))
 
1950
    (let ((m 0)
 
1951
          (log (list '(%log) var)))
 
1952
      (flet ((set-m (p)
 
1953
               (setq m p)))
 
1954
        (find-if #'(lambda (fac)
 
1955
                     (powerofx fac log #'set-m var))
 
1956
                 (cdr e)))
1765
1957
      (when (and (freeof var m) 
1766
1958
                 (eq (ask-integer m '$integer) '$yes)
1767
1959
                 (not (eq ($asksign m) '$neg))) 
1768
1960
        (setq e (m//t e (list '(mexpt) log m)))
1769
 
        (multiple-value-bind
1770
 
         (k/n l n b) (batap-new e)
1771
 
         (when k/n
1772
 
           (let ((beta (simplify (list '($beta) k/n l)))
1773
 
                 (m (if (eq ($asksign m) '$zero) 0 m)))
1774
 
             ;; The result looks like B(k/n,l) ( ... ).
1775
 
             ;; Perhaps, we should just $factor, instead of
1776
 
             ;; pulling out beta like this.
1777
 
             (m*t
1778
 
              beta
1779
 
              ($fullratsimp
1780
 
               (m//t
1781
 
                (m*t
1782
 
                 (m^t (m-t b) (m1-t l))
1783
 
                 (m^t ul (m*t n (m1-t l)))
1784
 
                 (m^t n (m-t (m1+t m)))
1785
 
                 ($at ($diff (m*t (m^t ul (m*t n var)) (list '($beta) var l))
1786
 
                             var m) (list '(mequal) var k/n))) 
1787
 
                beta))))))))))
 
1961
        (cond
 
1962
          ((eq ul '$inf)
 
1963
           (multiple-value-bind (kk s d r cc)
 
1964
               (batap-inf e)
 
1965
             ;; We have i(x^kk/(d+cc*x^r)^s,x,0,inf) =
 
1966
             ;; beta(aa,bb)/(cc^aa*d^bb*r).  Compute this, and then
 
1967
             ;; differentiate it m times to get the log term
 
1968
             ;; incorporated.
 
1969
             (when kk
 
1970
               (let* ((aa (div (add 1 var) r))
 
1971
                      (bb (sub s aa))
 
1972
                      (m (if (eq ($asksign m) '$zero)
 
1973
                             0
 
1974
                             m)))
 
1975
               (let ((res (div `(($beta) ,aa ,bb)
 
1976
                               (mul (m^t cc aa)
 
1977
                                    (m^t d bb)
 
1978
                                    r))))
 
1979
                 ($at ($diff res var m)
 
1980
                      (list '(mequal) var kk)))))))
 
1981
          (t
 
1982
           (multiple-value-bind
 
1983
                 (k/n l n b) (batap-new e)
 
1984
             (when k/n
 
1985
               (let ((beta (simplify (list '($beta) k/n l)))
 
1986
                     (m (if (eq ($asksign m) '$zero) 0 m)))
 
1987
                 ;; The result looks like B(k/n,l) ( ... ).
 
1988
                 ;; Perhaps, we should just $factor, instead of
 
1989
                 ;; pulling out beta like this.
 
1990
                 (m*t
 
1991
                  beta
 
1992
                  ($fullratsimp
 
1993
                   (m//t
 
1994
                    (m*t
 
1995
                     (m^t (m-t b) (m1-t l))
 
1996
                     (m^t ul (m*t n (m1-t l)))
 
1997
                     (m^t n (m-t (m1+t m)))
 
1998
                     ($at ($diff (m*t (m^t ul (m*t n var))
 
1999
                                      (list '($beta) var l))
 
2000
                                 var m)
 
2001
                          (list '(mequal) var k/n)))
 
2002
                    beta))))))))))))
1788
2003
 
1789
2004
 
1790
2005
;;; If e is of the form given below, make the obvious change
1796
2011
;;; of course would give wrong results.
1797
2012
 
1798
2013
(defun batap-new (e) 
1799
 
  (let (k c) 
1800
 
    (declare (special k c))
1801
 
    ;; Parse e
1802
 
    (when (bata0 e)
1803
 
      (multiple-value-bind
1804
 
       ;; e=x^k*(a+b*x^n)^l
1805
 
       (l a n b)  (values-list c)
1806
 
       (when (and (freeof var k) (freeof var n) (freeof var l)
1807
 
                  (alike1 a (m-t (m*t b (m^t ul n))))
1808
 
                  (eq ($asksign b) '$neg)
1809
 
                  (eq ($asksign (setq k (m1+t k))) '$pos)
1810
 
                  (eq ($asksign (setq l (m1+t l))) '$pos)
1811
 
                  (eq ($asksign n) '$pos))
1812
 
         (values (m//t k n) l n b))))))
1813
 
 
1814
 
 
1815
 
 
1816
 
(DEFUN BATAPP (E)
1817
 
       (PROG (K C D L AL) 
1818
 
             (COND ((NOT (OR (EQUAL LL 0) (EQ LL '$MINF)))
1819
 
                    (SETQ E (SUBIN (m+ LL VAR) E))))
1820
 
             (COND ((NOT (BATA0 E)) (RETURN NIL))
1821
 
                   ((AND (RATGREATERP (SETQ AL (CADDR C)) 0.)
1822
 
                         (EQ ($askSIGN (SETQ K (M// (m+ 1. K)
1823
 
                                                       AL)))
1824
 
                             '$pos)
1825
 
                         (RATGREATERP (SETQ L (m* -1. (CAR C)))
1826
 
                                      K)
1827
 
                         (EQ ($askSIGN (m* (SETQ D (CADR C))
1828
 
                                           (SETQ C (CADDDR C))))
1829
 
                             '$pos))
1830
 
                    (SETQ L (m+ L (m*t -1. K)))
1831
 
                    (RETURN (M// `(($BETA) ,K ,L)
1832
 
                                  (mul* AL (m^ C K) (m^ D L)))))))) 
1833
 
 
1834
 
(DECLARE-TOP(UNSPECIAL L C K)) 
1835
 
 
1836
 
(DEFUN GAMMA1 (C A B D)
1837
 
       (m* (m^t '$%E D)
1838
 
           (m^ (m* B (m^ A (SETQ C (M// (m+t C 1.) B))))
1839
 
               -1.)
1840
 
           `((%GAMMA) ,C)))
 
2014
  ;; Parse e
 
2015
  (multiple-value-bind (k c)
 
2016
      (bata0 e)
 
2017
    (when k
 
2018
      ;; e=x^k*(a+b*x^n)^l
 
2019
      (destructuring-bind (l a n b)
 
2020
          c
 
2021
        (when (and (freeof var k)
 
2022
                   (freeof var n)
 
2023
                   (freeof var l)
 
2024
                   (alike1 a (m-t (m*t b (m^t ul n))))
 
2025
                   (eq ($asksign b) '$neg)
 
2026
                   (eq ($asksign (setq k (m1+t k))) '$pos)
 
2027
                   (eq ($asksign (setq l (m1+t l))) '$pos)
 
2028
                   (eq ($asksign n) '$pos))
 
2029
          (values (m//t k n) l n b))))))
 
2030
 
 
2031
 
 
2032
;; Wang p. 71 gives the following formula for a beta function:
 
2033
;;
 
2034
;; integrate(x^(k-1)/(c*x^r+d)^s,x,0,inf)
 
2035
;;   = beta(a,b)/(c^a*d^b*r)
 
2036
;;
 
2037
;; where a = k/r > 0, b = s - a > 0, s > k > 0, r > 0, c*d > 0.
 
2038
;;
 
2039
;; This function matches this and returns k-1, d, r, c, a, b.  And
 
2040
;; also checks that all the conditions hold.  If not, NIL is returned.
 
2041
;;
 
2042
(defun batap-inf (e)
 
2043
  (multiple-value-bind (k c)
 
2044
      (bata0 e)
 
2045
    (when k
 
2046
      (destructuring-bind (l d r cc)
 
2047
          c
 
2048
        (let* ((s (mul -1 l))
 
2049
               (kk (add k 1))
 
2050
               (a (div kk r))
 
2051
               (b (sub s a)))
 
2052
          (when (and (freeof var k)
 
2053
                     (freeof var r)
 
2054
                     (freeof var l)
 
2055
                     (eq ($asksign kk) '$pos)
 
2056
                     (eq ($asksign a) '$pos)
 
2057
                     (eq ($asksign b) '$pos)
 
2058
                     (eq ($asksign (sub s k)) '$pos)
 
2059
                     (eq ($asksign r) '$pos)
 
2060
                     (eq ($asksign (mul cc d)) '$pos))
 
2061
            (values k s d r cc)))))))
 
2062
  
 
2063
 
 
2064
;; Handles beta integrals.
 
2065
(defun batapp (e)
 
2066
  (cond ((not (or (equal ll 0)
 
2067
                  (eq ll '$minf)))
 
2068
         (setq e (subin (m+ ll var) e))))
 
2069
  (multiple-value-bind (k c)
 
2070
      (bata0 e)
 
2071
    (cond ((null k)
 
2072
           nil)
 
2073
          (t
 
2074
           (destructuring-bind (l d al c)
 
2075
               c
 
2076
             ;; e = x^k*(d+c*x^al)^l.
 
2077
             (let ((new-k (m// (m+ 1 k) al)))
 
2078
               (when (and (ratgreaterp al 0.)
 
2079
                          (eq ($asksign new-k) '$pos)
 
2080
                          (ratgreaterp (setq l (m* -1. l))
 
2081
                                       new-k)
 
2082
                          (eq ($asksign (m* d c))
 
2083
                              '$pos))
 
2084
                 (setq l (m+ l (m*t -1. new-k)))
 
2085
                 (m// `(($beta) ,new-k ,l)
 
2086
                      (mul* al (m^ c new-k) (m^ d l))))))))))
 
2087
 
 
2088
 
 
2089
;; Compute exp(d)*gamma((c+1)/b)/b/a^((c+1)/b).  In essence, this is
 
2090
;; the value of integrate(x^c*exp(d-a*x^b),x,0,inf).
 
2091
(defun gamma1 (c a b d)
 
2092
  (m* (m^t '$%e d)
 
2093
      (m^ (m* b (m^ a (setq c (m// (m+t c 1.) b))))
 
2094
          -1.)
 
2095
      `((%gamma) ,c)))
1841
2096
       
1842
 
(DEFUN ZTO%PI2 (GRAND VAR)
1843
 
       (let ((result (UNITCIR ($RATSIMP (M// GRAND VAR)) VAR)))
1844
 
            (cond (result (sratsimp (m* (m- '$%I) result)))
1845
 
                  (t nil))))
 
2097
(defun zto%pi2 (grand var)
 
2098
  (let ((result (unitcir ($ratsimp (m// grand var)) var)))
 
2099
    (cond (result (sratsimp (m* (m- '$%i) result)))
 
2100
          (t nil))))
1846
2101
 
1847
 
(DEFUN UNITCIR (GRAND VAR)
1848
 
  (NUMDEN GRAND)
1849
 
  (let ((result (PRINCIP (RES NN* DN* #'(LAMBDA (PT)
1850
 
                                          (RATGREATERP 1 (CABS PT)))
1851
 
                                      #'(LAMBDA (PT)
1852
 
                                          (ALIKE1 1 (CABS PT)))))))
1853
 
       (cond (result (m* '$%PI result))
1854
 
             (t nil))))
 
2102
(defun unitcir (grand var)
 
2103
  (numden grand)
 
2104
  (let ((result (princip (res nn* dn* #'(lambda (pt)
 
2105
                                          (ratgreaterp 1 (cabs pt)))
 
2106
                              #'(lambda (pt)
 
2107
                                  (alike1 1 (cabs pt)))))))
 
2108
    (cond (result (m* '$%pi result))
 
2109
          (t nil))))
1855
2110
 
1856
2111
 
1857
 
(DEFUN LOGX1 (EXP LL UL)
 
2112
(defun logx1 (exp ll ul)
1858
2113
  (let ((arg nil))
1859
 
    (COND
1860
 
     ((AND (NOTINVOLVE EXP '(%SIN %COS %TAN %ATAN %ASIN %ACOS))
1861
 
           (SETQ ARG (INVOLVE EXP '(%LOG))))
1862
 
      (COND ((EQ ARG VAR)
1863
 
             (COND ((RATGREATERP 1. LL)
1864
 
                    (COND ((NOT (EQ UL '$INF))
1865
 
                           (INTCV1 (m^t '$%E (m- VAR)) () (m- `((%LOG) ,VAR))))
1866
 
                          (T (INTCV1 (m^t '$%E VAR) () `((%LOG) ,VAR)))))))
1867
 
            (t (INTCV ARG NIL nil)))))))
 
2114
    (cond
 
2115
      ((and (notinvolve exp '(%sin %cos %tan %atan %asin %acos))
 
2116
            (setq arg (involve exp '(%log))))
 
2117
       (cond ((eq arg var)
 
2118
              (cond ((ratgreaterp 1. ll)
 
2119
                     (cond ((not (eq ul '$inf))
 
2120
                            (intcv1 (m^t '$%e (m- var)) () (m- `((%log) ,var))))
 
2121
                           (t (intcv1 (m^t '$%e var) () `((%log) ,var)))))))
 
2122
             (t (intcv arg nil nil)))))))
1868
2123
 
1869
2124
 
1870
 
(DEFUN SCAXN (E)
1871
 
  (let (IND S G) 
1872
 
       (COND ((ATOM E)  NIL)
1873
 
             ((AND (OR (EQ (CAAR E) '%SIN)
1874
 
                       (EQ (CAAR E) '%COS))
1875
 
                   (SETQ IND (CAAR E))
1876
 
                   (SETQ E (BX**N (CADR E))))
1877
 
              (COND ((EQUAL (CAR E) 1.)  '$IND)
1878
 
                    ((ZEROP (SETQ S (let ((sign ($askSIGN (CADR E))))
1879
 
                                         (cond ((eq sign '$pos) 1)
1880
 
                                               ((eq sign '$neg) -1)
1881
 
                                               ((eq sign '$zero) 0)))))
1882
 
                     NIL)
1883
 
                    ((not (EQ ($askSIGN (m+ -1 (CAR E)))  '$pos))
1884
 
                     nil)
1885
 
                    (t (SETQ G (GAMMA1 0. (m* S (CADR E)) (CAR E) 0.))
1886
 
                       (SETQ E (m* G `((,IND) ,(M// HALF%PI (CAR E))))) 
1887
 
                       (m* (COND ((AND (EQ IND '%SIN)
1888
 
                                       (EQUAL S -1.))
1889
 
                                  -1.)
1890
 
                                 (T 1.))
1891
 
                           E)))))))
 
2125
;; Wang 81-83.  Unfortunately, the pdf version has page 82 as all
 
2126
;; black, so here is, as best as I can tell, what Wang is doing.
 
2127
;; Fortunately, p. 81 has the necessary hints.
 
2128
;;
 
2129
;; First consider integrate(exp(%i*k*x^n),x) around the closed contour
 
2130
;; consisting of the real axis from 0 to R, the arc from the angle 0
 
2131
;; to %pi/(2*n) and the ray from the arc back to the origin.
 
2132
;;
 
2133
;; There are no poles in this region, so the integral must be zero.
 
2134
;; But consider the integral on the three parts.  The real axis is the
 
2135
;; integral we want.  The return ray is
 
2136
;;
 
2137
;;   exp(%i*%pi/2/n) * integrate(exp(%i*k*(t*exp(%i*%pi/2/n))^n),t,R,0)
 
2138
;;     = exp(%i*%pi/2/n) * integrate(exp(%i*k*t^n*exp(%i*%pi/2)),t,R,0)
 
2139
;;     = -exp(%i*%pi/2/n) * integrate(exp(-k*t^n),t,0,R)
 
2140
;;
 
2141
;; As R -> infinity, this last integral is gamma(1/n)/k^(1/n)/n.
 
2142
;;
 
2143
;; We assume the integral on the circular arc approaches 0 as R ->
 
2144
;; infinity.  (Need to prove this.)
 
2145
;;
 
2146
;; Thus, we have 
 
2147
;;
 
2148
;;   integrate(exp(%i*k*t^n),t,0,inf) 
 
2149
;;     = exp(%i*%pi/2/n) * gamma(1/n)/k^(1/n)/n.
 
2150
;;
 
2151
;; Equating real and imaginary parts gives us the desired results:
 
2152
;;
 
2153
;; integrate(cos(k*t^n),t,0,inf) = G * cos(%pi/2/n)
 
2154
;; integrate(sin(k*t^n),t,0,inf) = G * sin(%pi/2/n)
 
2155
;;
 
2156
;; where G = gamma(1/n)/k^(1/n)/n.
 
2157
;;
 
2158
(defun scaxn (e)
 
2159
  (let (ind s g) 
 
2160
    (cond ((atom e)  nil)
 
2161
          ((and (or (eq (caar e) '%sin)
 
2162
                    (eq (caar e) '%cos))
 
2163
                (setq ind (caar e))
 
2164
                (setq e (bx**n (cadr e))))
 
2165
           ;; Ok, we have cos(b*x^n) or sin(b*x^n), and we set e = (a
 
2166
           ;; b n) where the arg of the trig function is b*x^n+a.
 
2167
           (cond ((equal (car e) 1.)
 
2168
                  ;; a = 1.  Give up.
 
2169
                  '$ind)
 
2170
                 ((zerop (setq s (let ((sign ($asksign (cadr e))))
 
2171
                                   (cond ((eq sign '$pos) 1)
 
2172
                                         ((eq sign '$neg) -1)
 
2173
                                         ((eq sign '$zero) 0)))))
 
2174
                  ;; s is the sign of b.  Give up if it's zero.
 
2175
                  nil)
 
2176
                 ((not (eq ($asksign (m+ -1 (car e)))  '$pos))
 
2177
                  ;; Give up if a-1 <= 0
 
2178
                  nil)
 
2179
                 (t
 
2180
                  ;; We can apply our formula now.  g = gamma(1/n)/n/b^(1/n)
 
2181
                  (setq g (gamma1 0. (m* s (cadr e)) (car e) 0.))
 
2182
                  (setq e (m* g `((,ind) ,(m// half%pi (car e))))) 
 
2183
                  (m* (cond ((and (eq ind '%sin)
 
2184
                                  (equal s -1.))
 
2185
                             -1.)
 
2186
                            (t 1.))
 
2187
                      e)))))))
1892
2188
                      
1893
2189
 
1894
 
(COMMENT THIS IS THE SECOND PART OF THE DEFINITE INTEGRAL PACKAGE) 
1895
 
 
1896
 
(DECLARE-TOP(SPECIAL VAR PLM* PL* RL* PL*1 RL*1)) 
1897
 
 
1898
 
(DEFUN P*LOGNXP (A S)
1899
 
  (let (B) 
1900
 
    (COND ((NOT (AMONG '%LOG A)) 
 
2190
(comment this is the second part of the definite integral package) 
 
2191
 
 
2192
(declare-top(special var plm* pl* rl* pl*1 rl*1)) 
 
2193
 
 
2194
(defun p*lognxp (a s)
 
2195
  (let (b) 
 
2196
    (cond ((not (among '%log a)) 
1901
2197
           ())
1902
 
          ((AND (POLYINX (SETQ B (MAXIMA-SUBSTITUTE 1. `((%LOG) ,VAR) A))
1903
 
                         VAR T)
1904
 
                (eq ($sign (m+ S (M+ 1 (DEG B))))
 
2198
          ((and (polyinx (setq b (maxima-substitute 1. `((%log) ,var) a))
 
2199
                         var t)
 
2200
                (eq ($sign (m+ s (m+ 1 (deg b))))
1905
2201
                    '$pos)
1906
 
                (EVENFN B VAR)
1907
 
                (SETQ A (LOGNXP ($RATSIMP (M// A B)))))
1908
 
           (LIST B A)))))
1909
 
 
1910
 
(DEFUN LOGNXP (A)
1911
 
   (COND ((ATOM A) NIL)
1912
 
         ((AND (EQ (CAAR A) '%LOG) 
1913
 
               (EQ (CADR A) VAR)) 1.)
1914
 
         ((AND (mexptp A)
1915
 
               (NUMBERP (CADDR A))
1916
 
               (LOGNXP (CADR A)))
1917
 
          (CADDR A)))) 
1918
 
 
1919
 
(COMMENT CHECK THE FOLLOWING FUNCTION FOR UNUSED PROG VAR A) 
1920
 
 
1921
 
(DEFUN LOGCPI0 (N D)
1922
 
  (PROG (PL DP) 
1923
 
        (SETQ PL (POLELIST D #'UPPERHALF #'(LAMBDA (J)
1924
 
                                             (COND ((ZEROP1 J) NIL)
1925
 
                                                   ((equal ($imagpart j) 0)
1926
 
                                                    T)))))
1927
 
        (cond ((null pl)
1928
 
               (return nil)))
1929
 
        (SETQ FACTORS (CAR PL) 
1930
 
              PL (CDR PL))
1931
 
        (COND ((OR (CADR PL)
1932
 
                   (CADDR PL))
1933
 
               (SETQ DP (SDIFF D VAR))))
1934
 
        (COND ((SETQ PLM* (CAR PL))
1935
 
               (SETQ RLM* (RESIDUE N (COND (LEADCOEF FACTORS)
1936
 
                                           (T D))
1937
 
                                   PLM*))))
1938
 
        (COND ((SETQ PL* (CADR PL)) 
1939
 
               (SETQ RL* (RES1 N DP PL*))))
1940
 
        (COND ((SETQ PL*1 (CADDR PL))
1941
 
               (SETQ RL*1 (RES1 N DP PL*1))))
1942
 
        (RETURN (m*t (m//t 1. 2.)
1943
 
                     (m*t '$%PI 
1944
 
                          (PRINCIP 
1945
 
                           (LIST (COND ((SETQ NN* (APPEND RL* RLM*))
1946
 
                                        (M+L NN*)))
1947
 
                                 (COND (RL*1 (M+L RL*1))))))))))
 
2202
                (evenfn b var)
 
2203
                (setq a (lognxp ($ratsimp (m// a b)))))
 
2204
           (list b a)))))
 
2205
 
 
2206
(defun lognxp (a)
 
2207
  (cond ((atom a) nil)
 
2208
        ((and (eq (caar a) '%log) 
 
2209
              (eq (cadr a) var)) 1.)
 
2210
        ((and (mexptp a)
 
2211
              (numberp (caddr a))
 
2212
              (lognxp (cadr a)))
 
2213
         (caddr a)))) 
 
2214
 
 
2215
(comment check the following function for unused prog var a) 
 
2216
 
 
2217
(defun logcpi0 (n d)
 
2218
  (prog (pl dp) 
 
2219
     (setq pl (polelist d #'upperhalf #'(lambda (j)
 
2220
                                          (cond ((zerop1 j) nil)
 
2221
                                                ((equal ($imagpart j) 0)
 
2222
                                                 t)))))
 
2223
     (cond ((null pl)
 
2224
            (return nil)))
 
2225
     (setq factors (car pl) 
 
2226
           pl (cdr pl))
 
2227
     (cond ((or (cadr pl)
 
2228
                (caddr pl))
 
2229
            (setq dp (sdiff d var))))
 
2230
     (cond ((setq plm* (car pl))
 
2231
            (setq rlm* (residue n (cond (leadcoef factors)
 
2232
                                        (t d))
 
2233
                                plm*))))
 
2234
     (cond ((setq pl* (cadr pl)) 
 
2235
            (setq rl* (res1 n dp pl*))))
 
2236
     (cond ((setq pl*1 (caddr pl))
 
2237
            (setq rl*1 (res1 n dp pl*1))))
 
2238
     (return (m*t (m//t 1. 2.)
 
2239
                  (m*t '$%pi 
 
2240
                       (princip 
 
2241
                        (list (cond ((setq nn* (append rl* rlm*))
 
2242
                                     (m+l nn*)))
 
2243
                              (cond (rl*1 (m+l rl*1))))))))))
1948
2244
 
1949
 
(DEFUN LOGNX2 (NN DN PL RL)
 
2245
(defun lognx2 (nn dn pl rl)
1950
2246
  (do ((pl pl (cdr pl))
1951
2247
       (rl rl (cdr rl))
1952
2248
       (ans ()))
1953
2249
      ((or (null pl)
1954
2250
           (null rl))  ans)
1955
 
    (SETQ ANS (CONS (m* DN (car rl) (m^ `((%PLOG) ,(car pl)) NN))
1956
 
                    ANS))))
 
2251
    (setq ans (cons (m* dn (car rl) (m^ `((%plog) ,(car pl)) nn))
 
2252
                    ans))))
1957
2253
 
1958
 
(DEFUN LOGCPJ (N D I)
1959
 
 (SETQ N (APPEND
1960
 
          (COND (PLM* (LIST (mul* (m*t '$%i %pi2)
1961
 
                                  (M+L
1962
 
                                   (RESIDUE (m* (m^ `((%PLOG) ,VAR) I)
1963
 
                                                N)
1964
 
                                            D
1965
 
                                            PLM*))))))
1966
 
          (LOGNX2 I (m*t '$%i %pi2) PL* RL*)
1967
 
          (LOGNX2 I %P%I PL*1 RL*1)))
1968
 
 (COND ((NULL N) 0)
1969
 
       (T (SIMPLIFY (M+L N)))))
 
2254
(defun logcpj (n d i)
 
2255
  (setq n (append
 
2256
           (cond (plm* (list (mul* (m*t '$%i %pi2)
 
2257
                                   (m+l
 
2258
                                    (residue (m* (m^ `((%plog) ,var) i)
 
2259
                                                 n)
 
2260
                                             d
 
2261
                                             plm*))))))
 
2262
           (lognx2 i (m*t '$%i %pi2) pl* rl*)
 
2263
           (lognx2 i %p%i pl*1 rl*1)))
 
2264
  (cond ((null n) 0)
 
2265
        (t (simplify (m+l n)))))
1970
2266
 
1971
2267
 
1972
2268
;;should replace these references to *i* and *j* to symbol-value arrays.
1973
2269
;;here and in SUMI, and LOGCPI.  These are the only references in this file.
1974
2270
;;I did change I to *I* 
1975
2271
 
1976
 
#-cl ;in case other lisps don't understand internal declares.
 
2272
#-cl          ;in case other lisps don't understand internal declares.
1977
2273
(declare-top(special *i* *j*))
1978
2274
 
1979
 
(DEFUN LOG*RAT (N D M)
1980
 
  (PROG (LEADCOEF FACTORS C PLM* PL* RL* PL*1 RL*1 RLM*)
1981
 
        (declare (special *i* *j*))
1982
 
;       (ARRAY *I* T (M+ 1 M))
1983
 
;       (ARRAY *J* T (M+ 1 M))
1984
 
        (setq *i* (*ARRAY nil T (M+ 1 M)))
1985
 
        (setq *j* (*ARRAY nil T (M+ 1 M)))
1986
 
        (SETQ C 0.)
1987
 
        (STORE (aref *J* C) 0.)
1988
 
        (do ((c 0. (m+ 1 c)))
1989
 
            ((equal c m)
1990
 
             (return (logcpi n d m)))
1991
 
         (STORE (aref *I* C) (LOGCPI N D C))
1992
 
         (STORE (aref *J* C) (LOGCPJ N FACTORS C)))))
 
2275
;; Handle integral(n(x)/d(x)*log(x)^m,x,0,inf).  n and d are
 
2276
;; polynomials.
 
2277
(defun log*rat (n d m)
 
2278
  (prog (leadcoef factors c plm* pl* rl* pl*1 rl*1 rlm*)
 
2279
     (declare (special *i* *j*))
 
2280
     ;; (ARRAY *I* T (M+ 1 M))
 
2281
     ;; (ARRAY *J* T (M+ 1 M))
 
2282
     (setq *i* (*array nil t (m+ 1 m)))
 
2283
     (setq *j* (*array nil t (m+ 1 m)))
 
2284
     (setq c 0.)
 
2285
     (store (aref *j* c) 0.)
 
2286
     (do ((c 0. (m+ 1 c)))
 
2287
         ((equal c m)
 
2288
          (return (logcpi n d m)))
 
2289
       (store (aref *i* c) (logcpi n d c))
 
2290
       (store (aref *j* c) (logcpj n factors c)))))
1993
2291
 
1994
 
(DEFUN LOGCPI (N D C)
 
2292
(defun logcpi (n d c)
1995
2293
  (declare (special *j*))
1996
 
  (COND ((EQUAL C 0.)
1997
 
         (LOGCPI0 N D))
1998
 
        (T (m* '((RAT) 1. 2.)
1999
 
               (m+ (aref *J* C) (m* -1. (SUMI C)))))))
 
2294
  (cond ((equal c 0.)
 
2295
         (logcpi0 n d))
 
2296
        (t (m* '((rat) 1. 2.)
 
2297
               (m+ (aref *j* c) (m* -1. (sumi c)))))))
2000
2298
 
2001
 
(DEFUN SUMI (C)
 
2299
(defun sumi (c)
2002
2300
  (declare (special *i*))
2003
2301
  (do ((k 1. (m+ 1 k))
2004
2302
       (ans ()))
2005
2303
      ((equal k c)
2006
2304
       (m+l ans))
2007
 
     (SETQ ANS (CONS (mul* ($MAKEGAMMA `((%BINOMIAL) ,C ,K))
2008
 
                           (m^t '$%PI K)
2009
 
                           (m^t '$%I K)
2010
 
                           (aref *I* (m+ C (m- K))))
2011
 
                     ANS))))
 
2305
    (setq ans (cons (mul* ($makegamma `((%binomial) ,c ,k))
 
2306
                          (m^t '$%pi k)
 
2307
                          (m^t '$%i k)
 
2308
                          (aref *i* (m+ c (m- k))))
 
2309
                    ans))))
2012
2310
 
2013
 
(DEFUN FAN (P M A N B)
 
2311
(defun fan (p m a n b)
2014
2312
  (let ((povern (m// p n))
2015
2313
        (ab (m// a b)))
2016
 
    (COND
2017
 
     ((OR (eq (ask-integer POVERN '$integer) '$yes)
2018
 
          (NOT (equal ($imagpart ab) 0)))  ())
2019
 
     (t (let ((IND ($askSIGN AB)))
2020
 
          (COND ((eq IND '$zero) NIL)
2021
 
                ((eq ind '$neg) nil)
2022
 
                ((NOT (RATGREATERP M POVERN)) NIL)
2023
 
                (t (M// (m* '$%pi
2024
 
                            ($MAKEGAMMA `((%BINOMIAL) ,(m+ -1. M (m- POVERN))
2025
 
                                                      ,(m+t -1. M)))
2026
 
                            `((mabs) ,(m^ A (m+ POVERN (m- m)))))
2027
 
                        (m* (m^ b povern)
2028
 
                            N
2029
 
                            `((%SIN) ,(m*t '$%PI POVERN)))))))))))
 
2314
    (cond
 
2315
      ((or (eq (ask-integer povern '$integer) '$yes)
 
2316
           (not (equal ($imagpart ab) 0)))  ())
 
2317
      (t (let ((ind ($asksign ab)))
 
2318
           (cond ((eq ind '$zero) nil)
 
2319
                 ((eq ind '$neg) nil)
 
2320
                 ((not (ratgreaterp m povern)) nil)
 
2321
                 (t (m// (m* '$%pi
 
2322
                             ($makegamma `((%binomial) ,(m+ -1. m (m- povern))
 
2323
                                           ,(m+t -1. m)))
 
2324
                             `((mabs) ,(m^ a (m+ povern (m- m)))))
 
2325
                         (m* (m^ b povern)
 
2326
                             n
 
2327
                             `((%sin) ,(m*t '$%pi povern)))))))))))
2030
2328
 
2031
2329
 
2032
2330
;;Makes a new poly such that np(x)-np(x+2*%i*%pi)=p(x).
2035
2333
;;of the varibale of integration.
2036
2334
;;Can probably be made simpler now.
2037
2335
 
2038
 
(DEFUN MAKPOLY (P)
 
2336
(defun makpoly (p)
2039
2337
  (let ((n (deg p))  (ans ())  (varlist ())  (gp ())  (cl ())  (zz ()))
2040
 
    (SETQ ANS (GENPOLY (M+ 1 N))) ;Make poly with gensyms of 1 higher deg.
2041
 
    (setq cl (cdr ans)) ;Coefficient list
2042
 
    (SETQ VARLIST (APPEND CL (LIST VAR))) ;Make VAR most important.
2043
 
    (SETQ GP (CAR ANS)) ;This is the poly with gensym coeffs.
 
2338
    (setq ans (genpoly (m+ 1 n))) ;Make poly with gensyms of 1 higher deg.
 
2339
    (setq cl (cdr ans))                 ;Coefficient list
 
2340
    (setq varlist (append cl (list var))) ;Make VAR most important.
 
2341
    (setq gp (car ans))          ;This is the poly with gensym coeffs.
2044
2342
;;;Now, poly(x)-poly(x+2*%i*%pi)=p(x), P is the original poly.
2045
 
    (SETQ ANS (m+ GP (SUBIN (m+t (m*t '$%i %pi2) VAR) (m- GP)) (m- P)))
2046
 
    (NEWVAR ANS)
2047
 
    (SETQ ANS (RATREP* ANS)) ;Rational rep with VAR leading.
2048
 
    (SETQ ZZ (COEFSOLVE N CL (COND ((NOT (EQ (CAADR ANS) ;What is Lead Var.
2049
 
                                             (GENFIND (CAR ANS) VAR)))
2050
 
                                    (LIST 0 (CADR ANS)));No VAR in ans.
2051
 
                                   ((CDADR ANS)))));The real Poly.
 
2343
    (setq ans (m+ gp (subin (m+t (m*t '$%i %pi2) var) (m- gp)) (m- p)))
 
2344
    (newvar ans)
 
2345
    (setq ans (ratrep* ans))           ;Rational rep with VAR leading.
 
2346
    (setq zz (coefsolve n cl (cond ((not (eq (caadr ans) ;What is Lead Var.
 
2347
                                             (genfind (car ans) var)))
 
2348
                                    (list 0 (cadr ans))) ;No VAR in ans.
 
2349
                                   ((cdadr ans))))) ;The real Poly.
2052
2350
    (if (or (null zz) (null gp)) 
2053
 
      -1
2054
 
      ($SUBSTITUTE ZZ GP))));Substitute Values for gensyms.
2055
 
 
2056
 
(DEFUN COEFSOLVE (N CL E)    
2057
 
  (DO (($BREAKUP)
2058
 
       (EQL (NCONS (PDIS (PTERM E N))) (CONS (PDIS (PTERM E M)) EQL))
2059
 
       (M (m+ N -1) (m+ M -1)))
2060
 
      ((SIGNP L M) (SOLVEX EQL CL NIL NIL))))
2061
 
 
2062
 
(DEFUN RECTZTO%PI2 (P PE D)
2063
 
(PROG (DP N PL A B C denom-exponential)
2064
 
(if (not (and (SETQ denom-exponential (CATCH 'PIN%EX (PIN%EX D)))
2065
 
              (%e-integer-coeff pe)
2066
 
              (%e-integer-coeff d)))
2067
 
  (return ()))
2068
 
(SETQ N (m* (COND ((NULL P) -1.)
2069
 
                  (T ($EXPAND (m*t '$%i %pi2 (MAKPOLY P)))))
2070
 
            PE))
2071
 
  (let ((var 'z*)
2072
 
        (leadcoef ()))
2073
 
    (SETQ PL (CDR (POLELIST DENOM-EXPONENTIAL #'(LAMBDA (J) 
2074
 
                                    (OR (NOT (equal ($imagpart J) 0))
2075
 
                                        (EQ ($askSIGN ($realpart J)) '$neg)))
2076
 
                            #'(LAMBDA (J)
2077
 
                                (NOT (EQ ($askSIGN ($realpart J)) '$zero)))))))
2078
 
  (COND ((NULL PL)  (RETURN NIL))
2079
 
        ((OR (CADR PL)
2080
 
             (CADDR PL))  (SETQ DP (SDIFF D VAR))))
2081
 
  (COND ((CADR PL)  (SETQ B (MAPCAR #'log-imag-0-2%pi (CADR PL)))
2082
 
                    (SETQ B (RES1 N DP B))
2083
 
                    (setq b (m+l b)))
2084
 
        (t (setq b 0.)))
2085
 
   (COND ((CADDR PL)
2086
 
          (let ((temp (MAPCAR #'log-imag-0-2%pi (CADDR PL))))
2087
 
            (setq c (append temp (mapcar #'(lambda (j) 
2088
 
                                             (m+ (m*t '$%i %pi2) j))
2089
 
                                         temp)))
2090
 
            (SETQ C (RES1 N DP C))
2091
 
            (setq c (m+l c))))
2092
 
         (t (setq c 0.)))
2093
 
   (COND ((CAR PL)
2094
 
          (let ((poles (mapcar #'log-imag-0-2%pi (caar pl)))
2095
 
                (exp (m// n (subst (m^t '$%e var) 'z* denom-exponential))))
2096
 
               (SETQ A (mapcar #'(lambda (j) 
2097
 
                                   ($RESIDUE exp var j))
2098
 
                               poles))
2099
 
               (setq a (m+l a))))
2100
 
         (t (setq a 0.)))
2101
 
   (RETURN (sRATSIMP (m+ a b (m* '((rat) 1. 2.) c))))))
2102
 
 
2103
 
(DEFUN GENPOLY (I)
 
2351
        -1
 
2352
        ($substitute zz gp))))         ;Substitute Values for gensyms.
 
2353
 
 
2354
(defun coefsolve (n cl e)    
 
2355
  (do (($breakup)
 
2356
       (eql (ncons (pdis (pterm e n))) (cons (pdis (pterm e m)) eql))
 
2357
       (m (m+ n -1) (m+ m -1)))
 
2358
      ((signp l m) (solvex eql cl nil nil))))
 
2359
 
 
2360
;; Integrate(p(x)*f(exp(x))/g(exp(x)),x,minf,inf) by applying the
 
2361
;; transformation y = exp(x) to get
 
2362
;; integrate(p(log(y))*f(y)/g(y)/y,y,0,inf).  This should be handled
 
2363
;; by dintlog.
 
2364
(defun log-transform (p pe d)
 
2365
  (let ((new-p (subst (list '(%log) var) var p))
 
2366
        (new-pe (subst var 'z* (catch 'pin%ex (pin%ex pe))))
 
2367
        (new-d (subst var 'z* (catch 'pin%ex (pin%ex d)))))
 
2368
    (defint (div (div (mul new-p new-pe) new-d) var) var 0 ul)))
 
2369
  
 
2370
;; This implements Wang's algorithm in Chapter 5.2, pp. 98-100.
 
2371
;;
 
2372
;; This is a very brief description of the algorithm.  Basically, we
 
2373
;; have integrate(R(exp(x))*p(x),x,minf,inf), where R(x) is a rational
 
2374
;; function and p(x) is a polynomial.
 
2375
;;
 
2376
;; We find a polynomial q(x) such that q(x) - q(x+2*%i*%pi) = p(x).
 
2377
;; Then consider a contour integral of R(exp(z))*q(z) over a
 
2378
;; rectangular contour.  Opposite corners of the rectangle are (-R,
 
2379
;; 2*%i*%pi) and (R, 0).
 
2380
;;
 
2381
;; Wang shows that this contour integral, in the limit, is the
 
2382
;; integral of R(exp(x))*q(x)-R(exp(x))*q(x+2*%i*%pi), which is
 
2383
;; exactly the integral we're looking for.
 
2384
;;
 
2385
;; Thus, to find the value of the contour integral, we just need the
 
2386
;; residues of R(exp(z))*q(z).  The only tricky part is that we want
 
2387
;; the log function to have an imaginary part between 0 and 2*%pi
 
2388
;; instead of -%pi to %pi.
 
2389
(defun rectzto%pi2 (p pe d)
 
2390
  (prog (dp n pl a b c denom-exponential)
 
2391
     (if (not (and (setq denom-exponential (catch 'pin%ex (pin%ex d)))
 
2392
                   (%e-integer-coeff pe)
 
2393
                   (%e-integer-coeff d)))
 
2394
         (return ()))
 
2395
     (setq n (m* (cond ((null p) -1.)
 
2396
                       (t ($expand (m*t '$%i %pi2 (makpoly p)))))
 
2397
                 pe))
 
2398
     (let ((var 'z*)
 
2399
           (leadcoef ()))
 
2400
       ;; Find the poles of the denominator.  denom-exponential is the
 
2401
       ;; denominator of R(x).
 
2402
       ;;
 
2403
       ;; It seems as if polelist returns a list of several items.
 
2404
       ;; The first element is a list consisting of the pole and (z -
 
2405
       ;; pole).  We don't care about this, so we take the rest of the
 
2406
       ;; result.  I think the second element of the list is an alist
 
2407
       ;; consisting of the pole and it's multiplicity.  I don't know
 
2408
       ;; what the rest of the list is.
 
2409
       (setq pl (cdr (polelist denom-exponential
 
2410
                               #'(lambda (j)
 
2411
                                   ;; The imaginary part is nonzero,
 
2412
                                   ;; or the realpart is negative.
 
2413
                                   (or (not (equal ($imagpart j) 0))
 
2414
                                       (eq ($asksign ($realpart j)) '$neg)))
 
2415
                               #'(lambda (j)
 
2416
                                   ;; The realpart is not zero.
 
2417
                                   (not (eq ($asksign ($realpart j)) '$zero)))))))
 
2418
     ;; Not sure what this does.
 
2419
     (cond ((null pl)
 
2420
            (return nil))
 
2421
           ((or (cadr pl)
 
2422
                (caddr pl))
 
2423
            (setq dp (sdiff d var))))
 
2424
     ;; Not sure what this does.
 
2425
     (cond ((cadr pl)
 
2426
            (setq b (mapcar #'log-imag-0-2%pi (cadr pl)))
 
2427
            (setq b (res1 n dp b))
 
2428
            (setq b (m+l b)))
 
2429
           (t (setq b 0.)))
 
2430
     ;; Not sure what this does either.
 
2431
     (cond ((caddr pl)
 
2432
            (let ((temp (mapcar #'log-imag-0-2%pi (caddr pl))))
 
2433
              (setq c (append temp (mapcar #'(lambda (j) 
 
2434
                                               (m+ (m*t '$%i %pi2) j))
 
2435
                                           temp)))
 
2436
              (setq c (res1 n dp c))
 
2437
              (setq c (m+l c))))
 
2438
           (t (setq c 0.)))
 
2439
     (cond ((car pl)
 
2440
            ;; We have the poles of deonom-exponential, so we need to
 
2441
            ;; convert them to the actual pole values for R(exp(x)),
 
2442
            ;; by taking the log of the value of poles.
 
2443
            (let ((poles (mapcar #'(lambda (p)
 
2444
                                     (log-imag-0-2%pi (car p)))
 
2445
                                 (car pl)))
 
2446
                  (exp (m// n (subst (m^t '$%e var) 'z* denom-exponential))))
 
2447
              ;; Compute the residues at all of these poles and sum
 
2448
              ;; them up.
 
2449
              (setq a (mapcar #'(lambda (j) 
 
2450
                                  ($residue exp var j))
 
2451
                              poles))
 
2452
              (setq a (m+l a))))
 
2453
           (t (setq a 0.)))
 
2454
     (return (sratsimp (m+ a b (m* '((rat) 1. 2.) c))))))
 
2455
 
 
2456
(defun genpoly (i)
2104
2457
  (do ((i i (m+ i -1))
2105
2458
       (c (gensym) (gensym))
2106
2459
       (cl ())
2107
2460
       (ans ()))
2108
2461
      ((zerop i)
2109
2462
       (cons (m+l ans) cl))
2110
 
    (SETQ ANS (CONS (m* C (m^t VAR I)) ANS))
2111
 
    (SETQ CL (CONS C CL))))
2112
 
 
2113
 
(DECLARE-TOP(SPECIAL *FAILFLAG *LHFLAG LHV *INDICATOR CNT *DISCONFLAG)) 
2114
 
 
 
2463
    (setq ans (cons (m* c (m^t var i)) ans))
 
2464
    (setq cl (cons c cl))))
 
2465
 
 
2466
;;(declare-top(special *failflag *lhflag lhv *indicator cnt *disconflag)) 
 
2467
 
 
2468
#+nil
2115
2469
(defun %e-integer-coeff (exp)
2116
2470
  (cond ((mapatom exp) t)
2117
2471
        ((and (mexptp exp)
2120
2474
                  '$yes))  t)
2121
2475
        (t (andmapc '%e-integer-coeff (cdr exp)))))
2122
2476
 
2123
 
(DEFUN WLINEARPOLY (E VAR)
2124
 
       (COND ((AND (SETQ E (POLYINX E VAR T))
2125
 
                   (EQUAL (DEG E) 1.))
2126
 
              (SUBIN 1. E)))) 
2127
 
 
2128
 
(DECLARE-TOP(SPECIAL E $EXPONENTIALIZE))
2129
 
 
2130
 
(DEFUN PIN%EX (EXP)
2131
 
  (PIN%EX0 (COND ((NOTINVOLVE EXP '(%SINH %COSH %TANH)) EXP)
2132
 
                 (T (SETQ EXP (let (($EXPONENTIALIZE t))
2133
 
                                ($expand EXP)))))))
2134
 
 
2135
 
(DEFUN PIN%EX0 (E)
2136
 
  (COND ((NOT (AMONG VAR E))  E)
2137
 
        ((ATOM E)  (THROW 'PIN%EX NIL))
2138
 
        ((AND (mexptp E)
2139
 
              (EQ (CADR E)  '$%E))
2140
 
         (COND ((EQ (CADDR E) VAR)  'Z*)
 
2477
;; Check to see if each term in exp that is of the form exp(k*x) has
 
2478
;; an integer value for k.
 
2479
(defun %e-integer-coeff (exp)
 
2480
  (cond ((mapatom exp) t)
 
2481
        ((and (mexptp exp)
 
2482
              (eq (cadr exp) '$%e))
 
2483
         (eq (ask-integer ($coeff (caddr exp) var) '$integer)
 
2484
             '$yes))
 
2485
        (t (andmapc '%e-integer-coeff (cdr exp)))))
 
2486
 
 
2487
(defun wlinearpoly (e var)
 
2488
  (cond ((and (setq e (polyinx e var t))
 
2489
              (equal (deg e) 1.))
 
2490
         (subin 1. e)))) 
 
2491
 
 
2492
;; Test to see if exp is of the form f(exp(x)), and if so, replace
 
2493
;; exp(x) with 'z*.  That is, basically return f(z*).
 
2494
(defun pin%ex (exp)
 
2495
  (declare (special $exponentialize))
 
2496
  (pin%ex0 (cond ((notinvolve exp '(%sinh %cosh %tanh))
 
2497
                  exp)
 
2498
                 (t
 
2499
                  (let (($exponentialize t))
 
2500
                    (setq exp ($expand exp)))))))
 
2501
 
 
2502
(defun pin%ex0 (e)
 
2503
  ;; Does e really need to be special here?  Seems to be ok without
 
2504
  ;; it; testsuite works.
 
2505
  #+nil
 
2506
  (declare (special e))
 
2507
  (cond ((not (among var e))
 
2508
         e)
 
2509
        ((atom e)
 
2510
         (throw 'pin%ex nil))
 
2511
        ((and (mexptp e)
 
2512
              (eq (cadr e)  '$%e))
 
2513
         (cond ((eq (caddr e) var)
 
2514
                'z*)
2141
2515
               ((let ((linterm (wlinearpoly (caddr e) var)))
2142
2516
                  (and linterm
2143
2517
                       (m* (subin 0 e) (m^t 'z* linterm)))))
2144
 
               (T (THROW 'PIN%EX NIL))))
2145
 
        ((mtimesp E)  (m*l (MAPCAR #'PIN%EX0 (CDR E))))
2146
 
        ((mplusp E)  (m+l (MAPCAR #'PIN%EX0 (CDR E))))
2147
 
        (T (THROW 'PIN%EX NIL))))
2148
 
 
2149
 
(DECLARE-TOP (UNSPECIAL E)) 
2150
 
 
2151
 
(DEFUN P*PIN%EX (ND*)
2152
 
       (SETQ ND* ($FACTOR ND*))
2153
 
       (COND ((POLYINX ND* VAR NIL) (SETQ P* (CONS ND* P*)) T)
2154
 
             ((CATCH 'PIN%EX (PIN%EX ND*)) (SETQ PE* (CONS ND* PE*)) T)
2155
 
             ((mtimesp ND*)
2156
 
              (andMAPCAR #'P*PIN%EX (CDR ND*)))))
2157
 
 
2158
 
(DEFUN FINDSUB (P)
2159
 
       (COND ((FINDP P) NIL)
2160
 
             ((SETQ ND* (BX**N P)) 
2161
 
              (m^t VAR (CAR ND*)))
2162
 
             ((SETQ P (BX**N+A P))
2163
 
              (m* (CADDR P) (m^t VAR (CADR P)))))) 
2164
 
 
2165
 
(DEFUN FUNCLOGOR%E (E)
2166
 
  (PROG (ANS ARG NVAR R) 
2167
 
    (COND ((OR (RATP E VAR)
2168
 
               (INVOLVE E '(%SIN %COS %TAN))
2169
 
               (NOT (SETQ ARG (XOR (AND (SETQ ARG (INVOLVE E '(%LOG)))
2170
 
                                        (SETQ R '%LOG))
2171
 
                                   (%EINVOLVE E)))))
2172
 
           (RETURN NIL)))
2173
 
AG (SETQ NVAR (COND ((EQ R '%LOG) `((%LOG) ,ARG))
2174
 
                    (T (m^t '$%E ARG))))
2175
 
   (SETQ ANS (MAXIMA-SUBSTITUTE (m^t 'YX -1.) (m^t NVAR -1.) (MAXIMA-SUBSTITUTE 'YX nvar E)))
2176
 
   (COND ((NOT (AMONG VAR ANS))  (RETURN (LIST (SUBST VAR 'YX ANS) NVAR)))
2177
 
         ((AND (NULL R) 
2178
 
               (SETQ ARG (FINDSUB ARG)))
2179
 
          (GO AG)))))
2180
 
 
2181
 
(DEFUN DINTBYPART (U V A B)
 
2518
               (t
 
2519
                (throw 'pin%ex nil))))
 
2520
        ((mtimesp e)
 
2521
         (m*l (mapcar #'pin%ex0 (cdr e))))
 
2522
        ((mplusp e)
 
2523
         (m+l (mapcar #'pin%ex0 (cdr e))))
 
2524
        (t
 
2525
         (throw 'pin%ex nil))))
 
2526
 
 
2527
;; Test to see if exp is of the form p(x)*f(exp(x)).  If so, set p* to
 
2528
;; be p(x) and set pe* to f(exp(x)).
 
2529
(defun p*pin%ex (nd*)
 
2530
  (setq nd* ($factor nd*))
 
2531
  (cond ((polyinx nd* var nil)
 
2532
         (setq p* (cons nd* p*)) t)
 
2533
        ((catch 'pin%ex (pin%ex nd*))
 
2534
         (setq pe* (cons nd* pe*)) t)
 
2535
        ((mtimesp nd*)
 
2536
         (andmapcar #'p*pin%ex (cdr nd*)))))
 
2537
 
 
2538
(defun findsub (p)
 
2539
  (cond ((findp p) nil)
 
2540
        ((setq nd* (bx**n p)) 
 
2541
         (m^t var (car nd*)))
 
2542
        ((setq p (bx**n+a p))
 
2543
         (m* (caddr p) (m^t var (cadr p)))))) 
 
2544
 
 
2545
;; I think this is looking at f(exp(x)) and tries to find some
 
2546
;; rational function R and some number k such that f(exp(x)) =
 
2547
;; R(exp(k*x)).
 
2548
(defun funclogor%e (e)
 
2549
  (prog (ans arg nvar r) 
 
2550
     (cond ((or (ratp e var)
 
2551
                (involve e '(%sin %cos %tan))
 
2552
                (not (setq arg (xor (and (setq arg (involve e '(%log)))
 
2553
                                         (setq r '%log))
 
2554
                                    (%einvolve e)))))
 
2555
            (return nil)))
 
2556
     ag (setq nvar (cond ((eq r '%log) `((%log) ,arg))
 
2557
                         (t (m^t '$%e arg))))
 
2558
     (setq ans (maxima-substitute (m^t 'yx -1.) (m^t nvar -1.) (maxima-substitute 'yx nvar e)))
 
2559
     (cond ((not (among var ans))  (return (list (subst var 'yx ans) nvar)))
 
2560
           ((and (null r) 
 
2561
                 (setq arg (findsub arg)))
 
2562
            (go ag)))))
 
2563
 
 
2564
;; Integration by parts.
 
2565
;;
 
2566
;; integrate(u(x)*diff(v(x),x),x,a,b)
 
2567
;;              |b
 
2568
;;   = u(x)*v(x)| - integrate(v(x)*diff(u(x),x))
 
2569
;;              |a
 
2570
;;
 
2571
(defun dintbypart (u v a b)
2182
2572
;;;SINCE ONLY CALLED FROM DINTLOG TO get RID OF LOGS - IF LOG REMAINS, QUIT
2183
 
       (let ((ad (antideriv v)))
2184
 
            (COND ((or (NULL AD)
2185
 
                       (INVOLVE AD '(%LOG)))
2186
 
                   NIL)
2187
 
                  (t (let ((P1 (m* U AD))
2188
 
                           (P2 (m* AD (SDIFF U VAR))))
2189
 
                          (let ((P1-part1 (get-LIMit P1 VAR B '$MINUS))
2190
 
                                (p1-part2 (get-LIMIT P1 VAR A '$PLUS)))
2191
 
                               (cond ((or (null p1-part1)
2192
 
                                          (null p1-part2))
2193
 
                                      nil)
2194
 
                                     (t (let ((P2 (Let ((*DEF2* t))
2195
 
                                                       (DEFINT P2 VAR A B))))
2196
 
                                             (COND (P2 (add* p1-part1 
2197
 
                                                             (m- p1-part2)
2198
 
                                                             (m- P2)))
2199
 
                                                   (t nil)))))))))))
 
2573
  (let ((ad (antideriv v)))
 
2574
    (cond ((or (null ad)
 
2575
               (involve ad '(%log)))
 
2576
           nil)
 
2577
          (t (let ((p1 (m* u ad))
 
2578
                   (p2 (m* ad (sdiff u var))))
 
2579
               (let ((p1-part1 (get-limit p1 var b '$minus))
 
2580
                     (p1-part2 (get-limit p1 var a '$plus)))
 
2581
                 (cond ((or (null p1-part1)
 
2582
                            (null p1-part2))
 
2583
                        nil)
 
2584
                       (t (let ((p2 (let ((*def2* t))
 
2585
                                      (defint p2 var a b))))
 
2586
                            (cond (p2 (add* p1-part1 
 
2587
                                            (m- p1-part2)
 
2588
                                            (m- p2)))
 
2589
                                  (t nil)))))))))))
2200
2590
 
2201
 
(DEFUN DINTEXP (EXP arg &aux ans)
2202
 
  (let ((dintexp-recur t))    ;recursion stopper
2203
 
    (COND ((and (sinintp exp var) ;To be moved higher in the code.
 
2591
;; integrate(f(exp(k*x)),x,a,b), where f(z) is rational.
 
2592
;;
 
2593
;; See Wang p. 96-97.
 
2594
;;
 
2595
;; If the limits are minf to inf, we use the substitution y=exp(k*x)
 
2596
;; to get integrate(f(y)/y,y,0,inf)/k.  If the limits are 0 to inf,
 
2597
;; use the substitution s+1=exp(k*x) to get
 
2598
;; integrate(f(s+1)/(s+1),s,0,inf).
 
2599
(defun dintexp (exp arg &aux ans)
 
2600
  (let ((*dintexp-recur* t))            ;recursion stopper
 
2601
    (cond ((and (sinintp exp var)     ;To be moved higher in the code.
2204
2602
                (setq ans (antideriv exp))
2205
 
                (setq ans (intsubs ans ll ul))))
2206
 
          ((setq ANS (FUNCLOGOR%E EXP))
2207
 
           (COND ((AND (EQUAL LL 0.) (EQ UL '$INF))
2208
 
                  (SETQ EXP (SUBIN (m+t 1. arg) (CAR ANS)))
2209
 
                  (SETQ ANS (m+t -1. (CADR ANS))))
2210
 
                 (T (SETQ EXP (CAR ANS))
2211
 
                    (SETQ ANS (CADR ANS))))
2212
 
             (INTCV ANS T NIL)))))
 
2603
                (setq ans (intsubs ans ll ul)))
 
2604
           ;; If we can integrate it directly, do so and take the
 
2605
           ;; appropriate limits.
 
2606
           )
 
2607
          ((setq ans (funclogor%e exp))
 
2608
           ;; ans is the list (f(x) exp(k*x)).
 
2609
           (cond ((and (equal ll 0.)
 
2610
                       (eq ul '$inf))
 
2611
                  ;; Use the substitution s + 1 = exp(k*x).  The
 
2612
                  ;; integral becomes integrate(f(s+1)/(s+1),s,0,inf)
 
2613
                  (setq exp (subin (m+t 1. arg) (car ans)))
 
2614
                  (setq ans (m+t -1. (cadr ans))))
 
2615
                 (t
 
2616
                  ;; Use the substitution y=exp(k*x) because the
 
2617
                  ;; limits are minf to inf.
 
2618
                  (setq exp (car ans))
 
2619
                  (setq ans (cadr ans))))
 
2620
           ;; Apply the substitution and integrate it.
 
2621
           (intcv ans t nil)))))
2213
2622
 
2214
 
(DEFUN DINTLOG (EXP ARG)
2215
 
(let ((dintlog-recur (f1+ dintlog-recur))) ;recursion stopper
2216
 
 (PROG (ANS D) 
2217
 
       (COND ((AND (EQ UL '$INF)
2218
 
                   (EQUAL LL 0.)
2219
 
                   (EQ ARG VAR)
2220
 
                   (EQUAL 1. ($RATSIMP (M// EXP (m* (m- (SUBIN (m^t VAR -1.)
2221
 
                                                               EXP))
2222
 
                                                    (m^t VAR -2.))))))
2223
 
              (RETURN 0.))
 
2623
;; integrate(log(g(x))*f(x),x,0,inf)
 
2624
(defun dintlog (exp arg)
 
2625
  (let ((*dintlog-recur* (f1+ *dintlog-recur*))) ;recursion stopper
 
2626
    (prog (ans d) 
 
2627
       (cond ((and (eq ul '$inf)
 
2628
                   (equal ll 0.)
 
2629
                   (eq arg var)
 
2630
                   (equal 1. ($ratsimp (m// exp (m* (m- (subin (m^t var -1.)
 
2631
                                                               exp))
 
2632
                                                    (m^t var -2.))))))
 
2633
              ;; Make the substitution y=1/x.  If the integrand has
 
2634
              ;; exactly the same form, the answer has to be 0.
 
2635
              (return 0.))
2224
2636
             ((setq ans (antideriv exp))
 
2637
              ;; It's easy if we have the antiderivative.
2225
2638
              (return (intsubs ans ll ul)))
2226
 
             ((SETQ ANS (LOGX1 EXP LL UL))
2227
 
              (RETURN ANS)))
2228
 
       (SETQ ANS (M// EXP `((%LOG) ,ARG)))
2229
 
       (COND ((INVOLVE ANS '(%LOG)) (RETURN NIL))
2230
 
             ((AND (EQ ARG VAR)
2231
 
                   (EQUAL 0. (NO-ERR-SUB 0. ANS))
2232
 
                   (SETQ D (let ((*DEF2* t))
2233
 
                                (DEFINT (m* ANS (m^t VAR '*Z*))
2234
 
                                        VAR LL UL))))
2235
 
              (RETURN (DERIVAT '*Z* 1. D 0.)))
2236
 
             ((SETQ ANS (DINTBYPART `((%LOG) ,ARG) ANS LL UL))
2237
 
              (RETURN ANS))))))
2238
 
 
2239
 
(DEFUN DERIVAT (VAR N E PT) (SUBIN PT (APPLY '$DIFF (LIST E VAR N)))) 
2240
 
 
2241
 
;;;MAYBPC RETURNS (COEF EXPO CONST)
2242
 
(DEFUN MAYBPC (E VAR)
2243
 
       (COND (MTOINF* (THROW 'GGRM (LINPOWER0 E VAR)))
2244
 
             ((AND (NOT MTOINF*)
2245
 
                   (NULL (SETQ E (BX**N+A E)))) ;bx**n+a --> (a b n) or nil.
2246
 
              NIL)                              ;with var being x.
2247
 
             ((AND (AMONG '$%I (CADDR E))
2248
 
                   (ZEROP1 ($realpart (CADDR E)))
2249
 
                   (SETQ ZN ($imagPART (CADDR E)))
2250
 
                   (EQ ($askSIGN (CADR E)) '$pos))
2251
 
              (COND ((EQ ($askSIGN ZN) '$neg)
2252
 
                     (SETQ VAR -1.)
2253
 
                     (SETQ ZN (m- ZN)))
2254
 
                    (T (SETQ VAR 1.)))
2255
 
              (SETQ ZD (m^t '$%E (M// (mul* VAR '$%I '$%PI (m+t 1. ND*))
2256
 
                                      (m*t 2. (CADR E)))))
2257
 
              `(,ZN ,(CADR E) ,(CAR E)))
2258
 
             ((AND (OR (EQ (SETQ VAR ($askSIGN ($realPART (CADDR E)))) '$neg)
2259
 
                       (EQUAL VAR '$zero))
2260
 
                   (equal ($imagpart (CADR E)) 0)
2261
 
                   (RATGREATERP (CADR E) 0.))
2262
 
              `(,(m- (CADDR E)) ,(CADR E) ,(CAR E)))))
2263
 
 
2264
 
(DEFUN GGR (E IND)
2265
 
 (PROG (C ZD ZN NN* DN* ND* DOSIMP $%EMODE) 
2266
 
   (SETQ ND* 0.)
2267
 
   (COND (IND (SETQ E ($EXPAND E))
2268
 
              (COND ((AND (mplusp E)
2269
 
                          (let ((*NODIVERG t))
2270
 
                               (SETQ E (CATCH 'Divergent
2271
 
                                               (ANDMAPCAR
2272
 
                                                #'(LAMBDA (J) 
2273
 
                                                    (GGR J NIL))
2274
 
                                                (CDR E))))))
2275
 
                     (COND ((EQ E 'Divergent) NIL)
2276
 
                           (T (RETURN (sRATSIMP (CONS '(MPLUS) E)))))))))
2277
 
   (SETQ E (RMCONST1 E))
2278
 
   (SETQ C (CAR E))
2279
 
   (SETQ E (CDR E))
2280
 
   (COND ((SETQ E (GGR1 E VAR))
2281
 
          (SETQ E (APPLY 'GAMMA1 E))
2282
 
          (COND (ZD (SETQ $%EMODE T)
2283
 
                    (SETQ DOSIMP T)
2284
 
                    (SETQ E (m* ZD E))))))
2285
 
   (COND (E (RETURN (m* C E))))))
2286
 
 
2287
 
 
2288
 
 
2289
 
(DEFUN GGR1 (E VAR) 
2290
 
       (COND ((ATOM E) NIL)
2291
 
             ((AND (mexptp E)
2292
 
                   (EQ (CADR E) '$%E))
2293
 
              (COND ((SETQ E (MAYBPC (CADDR E) VAR)) (CONS 0. E))))
2294
 
             ((AND (mtimesp E)
2295
 
                   (NULL (CDDDR E))
2296
 
                   (OR (AND (SETQ DN* (XTORTERM (CADR E) VAR))
2297
 
                            (RATGREATERP (SETQ ND* ($realPART DN*))
2298
 
                                         -1.)
2299
 
                            (SETQ NN* (GGR1 (CADDR E) VAR)))
2300
 
                       (AND (SETQ DN* (XTORTERM (CADDR E) VAR))
2301
 
                            (RATGREATERP (SETQ ND* ($realPART DN*))
2302
 
                                         -1.)
2303
 
                            (SETQ NN* (GGR1 (CADR E) VAR)))))
2304
 
              (RPLACA NN* DN*))))
2305
 
 
2306
 
 
2307
 
(DEFUN BX**N+A (E)
2308
 
;;; returns list of (a b n) or nil.
2309
 
       (COND ((EQ E VAR) 
2310
 
              (LIST 0. 1. 1.))
2311
 
             ((OR (ATOM E) 
2312
 
                  (MNUMP E)) ())
2313
 
             (t (let ((a (NO-ERR-SUB 0. E)))
2314
 
                     (cond ((null a)  ())
2315
 
                           (t (SETQ E (m+ E (m*t -1. A)))
2316
 
                              (COND ((SETQ E (BX**N E))
2317
 
                                     (CONS A E))
2318
 
                                    (t ()))))))))
2319
 
 
2320
 
(DEFUN BX**N (E)
2321
 
;;;returns a list (n e) or nil.
2322
 
       (let ((N ()))
2323
 
            (AND (SETQ N (XEXPONGET E VAR))
2324
 
                 (NOT (AMONG VAR
2325
 
                             (SETQ E (let (($maxposex 1)
2326
 
                                           ($maxnegex 1))
2327
 
                                       ($EXPAND (M// E (m^t VAR N)))))))
2328
 
                 (LIST N E))))
2329
 
 
2330
 
(DEFUN XEXPONGET (E NN*)
2331
 
       (COND ((ATOM E) (COND ((EQ E VAR) 1.)))
2332
 
             ((MNUMP E) NIL)
2333
 
             ((AND (mexptp E)
2334
 
                   (EQ (CADR E) NN*)
2335
 
                   (NOT (AMONG NN* (CADDR E))))
2336
 
              (CADDR E))
2337
 
             (T (ORMAPC #'(LAMBDA (J)
2338
 
                            (XEXPONGET J NN*))
2339
 
                        (CDR E)))))
 
2639
             ((setq ans (logx1 exp ll ul))
 
2640
              (return ans)))
 
2641
       ;; Ok, the easy cases didn't work.  We now try integration by
 
2642
       ;; parts.  Set ANS to f(x).
 
2643
       (setq ans (m// exp `((%log) ,arg)))
 
2644
       (cond ((involve ans '(%log))
 
2645
              ;; Bad. f(x) contains a log term, so we give up.
 
2646
              (return nil))
 
2647
             ((and (eq arg var)
 
2648
                   (equal 0. (no-err-sub 0. ans))
 
2649
                   (setq d (let ((*def2* t))
 
2650
                             (defint (m* ans (m^t var '*z*))
 
2651
                                 var ll ul))))
 
2652
              ;; The arg of the log function is the same as the
 
2653
              ;; integration variable.  We can do something a little
 
2654
              ;; simpler than integration by parts.  We have something
 
2655
              ;; like f(x)*log(x).  Consider f(x)*x^z.  If we
 
2656
              ;; differentiate this wrt to z, the integrand becomes
 
2657
              ;; f(x)*log(x)*x^z.  When we evaluate this at z = 0, we
 
2658
              ;; get the desired integrand.
 
2659
              ;;
 
2660
              ;; So we need f(0) to be 0 at 0.  If we can integrate
 
2661
              ;; f(x)*x^z, then we differentiate the result and
 
2662
              ;; evaluate it at z = 0.
 
2663
              (return (derivat '*z* 1. d 0.)))
 
2664
             ((setq ans (dintbypart `((%log) ,arg) ans ll ul))
 
2665
              ;; Try integration by parts.
 
2666
              (return ans))))))
 
2667
 
 
2668
;; Compute diff(e,var,n) at the point pt.
 
2669
(defun derivat (var n e pt)
 
2670
  (subin pt (apply '$diff (list e var n)))) 
 
2671
 
 
2672
;;; GGR and friends
 
2673
 
 
2674
;; MAYBPC returns (COEF EXPO CONST)
 
2675
;;
 
2676
;; This basically picks off b*x^n+a and returns the list
 
2677
;; (b n a).  It may also set the global *zd*.
 
2678
(defun maybpc (e var)
 
2679
  (declare (special *zd*))
 
2680
  (cond (*mtoinf* (throw 'ggrm (linpower0 e var)))
 
2681
        ((and (not *mtoinf*)
 
2682
              (null (setq e (bx**n+a e)))) ;bx**n+a --> (a n b) or nil.
 
2683
         nil)                           ;with var being x.
 
2684
        ;; At this point, e is of the form (a n b)
 
2685
        ((and (among '$%i (caddr e))
 
2686
              (zerop1 ($realpart (caddr e)))
 
2687
              (setq zn ($imagpart (caddr e)))
 
2688
              (eq ($asksign (cadr e)) '$pos))
 
2689
         ;; If we're here, b is complex, and n > 0.  zn = imagpart(b).
 
2690
         ;;
 
2691
         ;; Set var to the same sign as zn.
 
2692
         (cond ((eq ($asksign zn) '$neg)
 
2693
                (setq var -1.)
 
2694
                (setq zn (m- zn)))
 
2695
               (t (setq var 1.)))
 
2696
         ;; zd = exp(var*%i*%pi*(1+nd)/(2*n). (ZD is special!)
 
2697
         (setq *zd* (m^t '$%e (m// (mul* var '$%i '$%pi (m+t 1. nd*))
 
2698
                                   (m*t 2. (cadr e)))))
 
2699
         ;; Return zn, n, a.
 
2700
         `(,(caddr e) ,(cadr e) ,(car e)))
 
2701
        ((and (or (eq (setq var ($asksign ($realpart (caddr e)))) '$neg)
 
2702
                  (equal var '$zero))
 
2703
              (equal ($imagpart (cadr e)) 0)
 
2704
              (ratgreaterp (cadr e) 0.))
 
2705
         ;; We're here if realpart(b) <= 0, and n >= 0.  Then return -b, n, a.
 
2706
         `(,(caddr e) ,(cadr e) ,(car e)))))
 
2707
 
 
2708
;; Integrate x^m*exp(b*x^n+a), with realpart(m) > -1.
 
2709
;;
 
2710
;; See Wang, pp. 84-85.
 
2711
;;
 
2712
;; I believe the formula Wang gives is incorrect.  The derivation is
 
2713
;; correct except for the last step.
 
2714
;;
 
2715
;; Let J = integrate(x^m*exp(%i*k*x^n),x,0,inf), with k < 0.
 
2716
;;
 
2717
;; Then J = exp(-%pi*%i*(m+1)/(2*n))*integrate(R^m*exp(k*R^n),R,0,inf)
 
2718
;;
 
2719
;; Wang seems to say this last integral is gamma(s/n/(-k)^s) where s =
 
2720
;; (m+1)/n.  But that seems wrong.  If we use the substitution x =
 
2721
;; (y/k)^(1/n), we end up with the result:
 
2722
;;
 
2723
;;   integrate(y^((m+1)/n-1)*exp(-y),y,0,inf)/k^((m+1)/n)/n.
 
2724
;;
 
2725
;; or gamma((m+1)/n)/k^((m+1)/n)/n.
 
2726
;;
 
2727
#+nil
 
2728
(defun ggr (e ind)
 
2729
  (prog (c *zd* zn nn* dn* nd* dosimp $%emode)
 
2730
     (declare (special *zd*))
 
2731
     (setq nd* 0.)
 
2732
     (cond (ind (setq e ($expand e))
 
2733
                (cond ((and (mplusp e)
 
2734
                            (let ((*nodiverg t))
 
2735
                              (setq e (catch 'divergent
 
2736
                                        (andmapcar
 
2737
                                         #'(lambda (j) 
 
2738
                                             (ggr j nil))
 
2739
                                         (cdr e))))))
 
2740
                       (cond ((eq e 'divergent) nil)
 
2741
                             (t (return (sratsimp (cons '(mplus) e)))))))))
 
2742
     (setq e (rmconst1 e))
 
2743
     (setq c (car e))
 
2744
     (setq e (cdr e))
 
2745
     (cond ((setq e (ggr1 e var))
 
2746
            ;; e = (m b n a).  I think we want to compute
 
2747
            ;; gamma((m+1)/n)/k^((m+1)/n)/n.
 
2748
            ;;
 
2749
            ;; FIXME: If n > m + 1, the integral converges.  We need
 
2750
            ;; to check for this.
 
2751
            (progn
 
2752
              (format t "e = ~A~%" e)
 
2753
              (format t "asksign ~A = ~A~%"
 
2754
                      (sub (third e) (add ($realpart (first e)) 1))
 
2755
                      ($asksign (sub (third e) (add ($realpart (first e)) 1)))))
 
2756
            
 
2757
            (setq e (apply #'gamma1 e))
 
2758
            ;; NOTE: *zd* (Ick!) is special and might be set by maybpc.
 
2759
            (when *zd*
 
2760
              ;; FIXME: Why do we set %emode here?  Shouldn't we just
 
2761
              ;; bind it?  And why do we want it bound to T anyway?
 
2762
              ;; Shouldn't the user control that?  The same goes for
 
2763
              ;; dosimp.
 
2764
              ;;(setq $%emode t)
 
2765
              (setq dosimp t)
 
2766
              (setq e (m* *zd* e)))))
 
2767
     (cond (e (return (m* c e))))))
 
2768
 
 
2769
(defun ggr (e ind)
 
2770
  (prog (c *zd* zn nn* dn* nd* dosimp $%emode)
 
2771
     (declare (special *zd*))
 
2772
     (setq nd* 0.)
 
2773
     (cond (ind (setq e ($expand e))
 
2774
                (cond ((and (mplusp e)
 
2775
                            (let ((*nodiverg t))
 
2776
                              (setq e (catch 'divergent
 
2777
                                        (andmapcar
 
2778
                                         #'(lambda (j) 
 
2779
                                             (ggr j nil))
 
2780
                                         (cdr e))))))
 
2781
                       (cond ((eq e 'divergent) nil)
 
2782
                             (t (return (sratsimp (cons '(mplus) e)))))))))
 
2783
     (setq e (rmconst1 e))
 
2784
     (setq c (car e))
 
2785
     (setq e (cdr e))
 
2786
     (cond ((setq e (ggr1 e var))
 
2787
            ;; e = (m b n a).  I think we want to compute
 
2788
            ;; gamma((m+1)/n)/k^((m+1)/n)/n.
 
2789
            ;;
 
2790
            ;; FIXME: If n > m + 1, the integral converges.  We need
 
2791
            ;; to check for this.
 
2792
            (destructuring-bind (m b n a)
 
2793
                e
 
2794
              ;; Check for convergence.  If b is complex, we need n -
 
2795
              ;; m > 1.  If b is real, we need b < 0.
 
2796
              (when (and (zerop1 ($imagpart b))
 
2797
                         (not (eq ($asksign b) '$neg)))
 
2798
                (diverg))
 
2799
              (when (and (not (zerop1 ($imagpart b)))
 
2800
                         (not (eq ($asksign (sub n (add m 1))) '$pos)))
 
2801
                (diverg))
 
2802
              (setq e (gamma1 m (cond ((zerop1 ($imagpart b))
 
2803
                                       ;; If we're here, b must be negative.
 
2804
                                       (neg b))
 
2805
                                      (t
 
2806
                                       ;; Complex b.  Take the imaginary part
 
2807
                                       `((mabs) ,($imagpart b))))
 
2808
                              n a))
 
2809
              ;; NOTE: *zd* (Ick!) is special and might be set by maybpc.
 
2810
              (when *zd*
 
2811
                ;; FIXME: Why do we set %emode here?  Shouldn't we just
 
2812
                ;; bind it?  And why do we want it bound to T anyway?
 
2813
                ;; Shouldn't the user control that?  The same goes for
 
2814
                ;; dosimp.
 
2815
                ;;(setq $%emode t)
 
2816
                (setq dosimp t)
 
2817
                (setq e (m* *zd* e))))))
 
2818
     (cond (e (return (m* c e))))))
 
2819
 
 
2820
 
 
2821
;; Match x^m*exp(b*x^n+a).  If it does, return (list m b n a).
 
2822
(defun ggr1 (e var) 
 
2823
  (cond ((atom e) nil)
 
2824
        ((and (mexptp e)
 
2825
              (eq (cadr e) '$%e))
 
2826
         ;; We're looking at something like exp(f(var)).  See if it's
 
2827
         ;; of the form b*x^n+a, and return (list 0 b n a).  (The 0 is
 
2828
         ;; so we can graft something onto it if needed.)
 
2829
         (cond ((setq e (maybpc (caddr e) var))
 
2830
                (cons 0. e))))
 
2831
        ((and (mtimesp e)
 
2832
              ;; E should be the product of exactly 2 terms
 
2833
              (null (cdddr e))
 
2834
              ;; Check to see if one of the terms is of the form
 
2835
              ;; var^p.  If so, make sure the realpart of p > -1.  If
 
2836
              ;; so, check the other term has the right form via
 
2837
              ;; another call to ggr1.
 
2838
              (or (and (setq dn* (xtorterm (cadr e) var))
 
2839
                       (ratgreaterp (setq nd* ($realpart dn*))
 
2840
                                    -1.)
 
2841
                       (setq nn* (ggr1 (caddr e) var)))
 
2842
                  (and (setq dn* (xtorterm (caddr e) var))
 
2843
                       (ratgreaterp (setq nd* ($realpart dn*))
 
2844
                                    -1.)
 
2845
                       (setq nn* (ggr1 (cadr e) var)))))
 
2846
         ;; Both terms have the right form and nn* contains the arg of
 
2847
         ;; the exponential term.  Put dn* as the car of nn*.  The
 
2848
         ;; result is something like (m b n a) when we have the
 
2849
         ;; expression x^m*exp(b*x^n+a).
 
2850
         (rplaca nn* dn*))))
 
2851
 
 
2852
 
 
2853
;; Match b*x^n+a.  If a match is found, return the list (a n b).
 
2854
;; Otherwise, return NIL
 
2855
(defun bx**n+a (e)
 
2856
  (cond ((eq e var) 
 
2857
         (list 0. 1. 1.))
 
2858
        ((or (atom e) 
 
2859
             (mnump e)) ())
 
2860
        (t (let ((a (no-err-sub 0. e)))
 
2861
             (cond ((null a)  ())
 
2862
                   (t (setq e (m+ e (m*t -1. a)))
 
2863
                      (cond ((setq e (bx**n e))
 
2864
                             (cons a e))
 
2865
                            (t ()))))))))
 
2866
 
 
2867
;; Match b*x^n.  Return the list (n b) if found or NIL if not.
 
2868
(defun bx**n (e)
 
2869
  (let ((n ()))
 
2870
    (and (setq n (xexponget e var))
 
2871
         (not (among var
 
2872
                     (setq e (let (($maxposex 1)
 
2873
                                   ($maxnegex 1))
 
2874
                               ($expand (m// e (m^t var n)))))))
 
2875
         (list n e))))
 
2876
 
 
2877
(defun xexponget (e nn*)
 
2878
  (cond ((atom e) (cond ((eq e var) 1.)))
 
2879
        ((mnump e) nil)
 
2880
        ((and (mexptp e)
 
2881
              (eq (cadr e) nn*)
 
2882
              (not (among nn* (caddr e))))
 
2883
         (caddr e))
 
2884
        (t (ormapc #'(lambda (j)
 
2885
                       (xexponget j nn*))
 
2886
                   (cdr e)))))
2340
2887
 
2341
2888
 
2342
2889
;;; given (b*x^n+a)^m returns (m a n b)
2343
 
(DEFUN BXM (E IND)
2344
 
(let (m r)
2345
 
  (COND ((OR (ATOM E)
2346
 
             (MNUMP E)
2347
 
             (INVOLVE E '(%LOG %SIN %COS %TAN))
2348
 
             (%EINVOLVE E))  NIL)
2349
 
        ((mtimesp E)  NIL)
2350
 
        ((mexptp E)  (COND ((AMONG VAR (CADDR E))  NIL)
2351
 
                           ((SETQ R (BX**N+A (CADR E))) 
2352
 
                            (CONS (caddr e) R))))
2353
 
        ((SETQ R (BX**N+A E))  (CONS 1. R))
2354
 
        ((not (null IND))
 
2890
(defun bxm (e ind)
 
2891
  (let (m r)
 
2892
    (cond ((or (atom e)
 
2893
               (mnump e)
 
2894
               (involve e '(%log %sin %cos %tan))
 
2895
               (%einvolve e))  nil)
 
2896
          ((mtimesp e)  nil)
 
2897
          ((mexptp e)  (cond ((among var (caddr e))  nil)
 
2898
                             ((setq r (bx**n+a (cadr e))) 
 
2899
                              (cons (caddr e) r))))
 
2900
          ((setq r (bx**n+a e))  (cons 1. r))
 
2901
          ((not (null ind))
2355
2902
;;;Catches Unfactored forms.
2356
 
         (SETQ M (M// (SDIFF E VAR) E))
2357
 
         (NUMDEN M)
2358
 
         (SETQ M NN*)
2359
 
         (setq r dn*)
2360
 
         (COND 
2361
 
          ((AND (SETQ R (BX**N+A ($ratsimp r)))
2362
 
                (NOT (AMONG VAR (SETQ M (M// M (m* (CADR R) (CADDR R)
2363
 
                                                   (m^t VAR (m+t -1.
2364
 
                                                                (CADR R))))))))
2365
 
                (SETQ E (M// (SUBIN 0. E) (m^t (CAR R) M))))
2366
 
           (COND ((equal E 1.)
2367
 
                  (CONS M R))
2368
 
                 (T (SETQ E (m^ E (M// 1. M)))
2369
 
                    (LIST M (m* E (CAR R)) (CADR R) 
2370
 
                          (m* E (CADDR R))))))))
2371
 
        (t ()))))
 
2903
           (setq m (m// (sdiff e var) e))
 
2904
           (numden m)
 
2905
           (setq m nn*)
 
2906
           (setq r dn*)
 
2907
           (cond 
 
2908
             ((and (setq r (bx**n+a ($ratsimp r)))
 
2909
                   (not (among var (setq m (m// m (m* (cadr r) (caddr r)
 
2910
                                                      (m^t var (m+t -1.
 
2911
                                                                    (cadr r))))))))
 
2912
                   (setq e (m// (subin 0. e) (m^t (car r) m))))
 
2913
              (cond ((equal e 1.)
 
2914
                     (cons m r))
 
2915
                    (t (setq e (m^ e (m// 1. m)))
 
2916
                       (list m (m* e (car r)) (cadr r) 
 
2917
                             (m* e (caddr r))))))))
 
2918
          (t ()))))
2372
2919
 
2373
2920
;;;Is E = VAR raised to some power? If so return power or 0.
2374
 
(DEFUN FINDP (E) 
2375
 
       (COND ((NOT (AMONG VAR E)) 0.)
2376
 
             (T (XTORTERM E VAR))))
 
2921
(defun findp (e) 
 
2922
  (cond ((not (among var e)) 0.)
 
2923
        (t (xtorterm e var))))
2377
2924
 
2378
 
(DEFUN XTORTERM (E VAR1)
 
2925
(defun xtorterm (e var1)
2379
2926
;;;Is E = VAR1 raised to some power? If so return power.
2380
 
       (COND ((ALIKE1 E VAR1) 1.)
2381
 
             ((ATOM E) NIL)
2382
 
             ((AND (mexptp E)
2383
 
                   (ALIKE1 (CADR E) VAR1)
2384
 
                   (NOT (AMONG VAR (CADDR E))))
2385
 
              (CADDR E)))) 
 
2927
  (cond ((alike1 e var1) 1.)
 
2928
        ((atom e) nil)
 
2929
        ((and (mexptp e)
 
2930
              (alike1 (cadr e) var1)
 
2931
              (not (among var (caddr e))))
 
2932
         (caddr e)))) 
2386
2933
 
2387
 
(DEFUN TBF (L)
2388
 
       (m^ (m* (m^ (CADDR L) '((RAT) 1. 2.))
2389
 
               (m+ (CADR L) (m^ (m* (CAR L) (CADDR L))
2390
 
                                '((RAT) 1. 2.))))
2391
 
           -1.))
 
2934
(defun tbf (l)
 
2935
  (m^ (m* (m^ (caddr l) '((rat) 1. 2.))
 
2936
          (m+ (cadr l) (m^ (m* (car l) (caddr l))
 
2937
                           '((rat) 1. 2.))))
 
2938
      -1.))
2392
2939
 
2393
2940
(defun radbyterm (d l)
2394
2941
  (do ((l l (cdr l))
2395
2942
       (ans ()))
2396
2943
      ((null l)
2397
2944
       (m+l ans))
2398
 
    (let (((const . integrand) (rmconst1 (car l))))
2399
 
         (setq ans (cons (m* const (dintrad0 integrand d))
2400
 
                         ans)))))
2401
 
 
2402
 
(DEFUN SQDTC (E IND)
2403
 
       (PROG (A B C VARLIST) 
2404
 
             (SETQ VARLIST (LIST VAR))
2405
 
             (NEWVAR E)
2406
 
             (SETQ E (CDADR (RATREP* E)))
2407
 
             (SETQ C (PDIS (PTERM E 0.)))
2408
 
             (SETQ B (m*t (m//t 1. 2.) (PDIS (PTERM E 1.))))
2409
 
             (SETQ A (PDIS (PTERM E 2.)))
2410
 
             (COND ((AND (EQ ($askSIGN (m+ B (m^ (m* A C)
2411
 
                                                 '((RAT) 1. 2.))))
2412
 
                             '$pos)
2413
 
                         (OR (AND IND
2414
 
                                  (NOT (EQ ($askSIGN A) '$neg))
2415
 
                                  (EQ ($askSIGN C) '$pos))
2416
 
                             (AND (EQ ($askSIGN A) '$pos)
2417
 
                                  (NOT (EQ ($askSIGN C) '$neg)))))
2418
 
                    (RETURN (LIST A B C)))))) 
2419
 
 
2420
 
(DEFUN DIFAP1 (E PWR VAR M PT)
2421
 
       (M// (mul* (COND ((eq (ask-integer M '$even) '$yes)
2422
 
                          1.)
2423
 
                         (T -1.))
2424
 
                   `((%GAMMA) ,PWR)
2425
 
                   (DERIVAT VAR M E PT))
2426
 
             `((%GAMMA) ,(m+ PWR M)))) 
2427
 
 
2428
 
(DEFUN SQRTINVOLVE (E)
2429
 
       (COND ((ATOM E) NIL)
2430
 
             ((MNUMP E) NIL)
2431
 
             ((AND (mexptp E) 
2432
 
                   (AND (MNUMP (CADDR E))
2433
 
                        (NOT (NUMBERP (CADDR E)))
2434
 
                        (EQUAL (CADDR (CADDR E)) 2.))
2435
 
                   (AMONG VAR (CADR E)))
2436
 
              (CADR E))
2437
 
             (T (ORMAPC #'SQRTINVOLVE (CDR E))))) 
2438
 
 
2439
 
(DEFUN BYDIF (R S D)
2440
 
       (let ((B 1)  p)
2441
 
            (SETQ D (m+ (m*t '*Z* VAR) D))
2442
 
            (COND ((OR (ZEROP1 (SETQ P (m+ S (m*t -1. R))))
2443
 
                       (AND (ZEROP1 (m+ 1. P))
2444
 
                            (SETQ B VAR)))
2445
 
                   (DIFAP1 (DINTRAD0 B (m^ D '((RAT) 3. 2.)))
2446
 
                                    '((RAT) 3. 2.) '*Z* R 0.))
2447
 
                   ((EQ ($askSIGN P) '$pos)
2448
 
                    (DIFAP1 (DIFAP1 (DINTRAD0 1. (m^ (m+t 'Z** D)
2449
 
                                                     '((RAT) 3. 2.)))
2450
 
                                    '((RAT) 3. 2.) '*Z* R 0.)
2451
 
                            '((RAT) 3. 2.) 'Z** P 0.)))))
 
2945
    (destructuring-let (((const . integrand) (rmconst1 (car l))))
 
2946
      (setq ans (cons (m* const (dintrad0 integrand d))
 
2947
                      ans)))))
 
2948
 
 
2949
(defun sqdtc (e ind)
 
2950
  (prog (a b c varlist) 
 
2951
     (setq varlist (list var))
 
2952
     (newvar e)
 
2953
     (setq e (cdadr (ratrep* e)))
 
2954
     (setq c (pdis (pterm e 0.)))
 
2955
     (setq b (m*t (m//t 1. 2.) (pdis (pterm e 1.))))
 
2956
     (setq a (pdis (pterm e 2.)))
 
2957
     (cond ((and (eq ($asksign (m+ b (m^ (m* a c)
 
2958
                                         '((rat) 1. 2.))))
 
2959
                     '$pos)
 
2960
                 (or (and ind
 
2961
                          (not (eq ($asksign a) '$neg))
 
2962
                          (eq ($asksign c) '$pos))
 
2963
                     (and (eq ($asksign a) '$pos)
 
2964
                          (not (eq ($asksign c) '$neg)))))
 
2965
            (return (list a b c)))))) 
 
2966
 
 
2967
(defun difap1 (e pwr var m pt)
 
2968
  (m// (mul* (cond ((eq (ask-integer m '$even) '$yes)
 
2969
                    1.)
 
2970
                   (t -1.))
 
2971
             `((%gamma) ,pwr)
 
2972
             (derivat var m e pt))
 
2973
       `((%gamma) ,(m+ pwr m)))) 
 
2974
 
 
2975
(defun sqrtinvolve (e)
 
2976
  (cond ((atom e) nil)
 
2977
        ((mnump e) nil)
 
2978
        ((and (mexptp e) 
 
2979
              (and (mnump (caddr e))
 
2980
                   (not (numberp (caddr e)))
 
2981
                   (equal (caddr (caddr e)) 2.))
 
2982
              (among var (cadr e)))
 
2983
         (cadr e))
 
2984
        (t (ormapc #'sqrtinvolve (cdr e)))))
 
2985
 
 
2986
(defun bydif (r s d)
 
2987
  (let ((b 1)  p)
 
2988
    (setq d (m+ (m*t '*z* var) d))
 
2989
    (cond ((or (zerop1 (setq p (m+ s (m*t -1. r))))
 
2990
               (and (zerop1 (m+ 1. p))
 
2991
                    (setq b var)))
 
2992
           (difap1 (dintrad0 b (m^ d '((rat) 3. 2.)))
 
2993
                   '((rat) 3. 2.) '*z* r 0.))
 
2994
          ((eq ($asksign p) '$pos)
 
2995
           (difap1 (difap1 (dintrad0 1. (m^ (m+t 'z** d)
 
2996
                                            '((rat) 3. 2.)))
 
2997
                           '((rat) 3. 2.) '*z* r 0.)
 
2998
                   '((rat) 3. 2.) 'z** p 0.)))))
2452
2999
 
2453
 
(DEFUN DINTRAD0 (N D)
2454
 
       (let (L R S) 
2455
 
         (COND ((AND (mexptp D) 
2456
 
                     (EQUAL (DEG (CADR D)) 2.))
2457
 
                (COND ((ALIKE1 (CADDR D) '((RAT) 3. 2.))
2458
 
                       (COND ((AND (EQUAL N 1.)
2459
 
                                   (SETQ L (SQDTC (CADR D) T)))
2460
 
                              (TBF L))
2461
 
                             ((AND (EQ N VAR)
2462
 
                                   (SETQ L (SQDTC (CADR D) NIL)))
2463
 
                              (TBF (REVERSE L)))))
2464
 
                      ((AND (SETQ R (FINDP N))
2465
 
                            (OR (EQ ($askSIGN (m+ -1. (m-  R) (m*t 2.
2466
 
                                                                   (CADDR D))))
2467
 
                                    '$pos)
2468
 
                                (Diverg))
2469
 
                            (SETQ S (m+ '((RAT) -3. 2.) (CADDR D)))
2470
 
                            (EQ ($askSIGN S) '$pos)
2471
 
                            (eq (ask-integer S '$integer) '$yes))
2472
 
                       (BYDIF R S (CADR D)))
2473
 
                      ((POLYINX N VAR NIL)
2474
 
                       (RADBYTERM D (CDR N))))))))
 
3000
(defun dintrad0 (n d)
 
3001
  (let (l r s) 
 
3002
    (cond ((and (mexptp d) 
 
3003
                (equal (deg (cadr d)) 2.))
 
3004
           (cond ((alike1 (caddr d) '((rat) 3. 2.))
 
3005
                  (cond ((and (equal n 1.)
 
3006
                              (setq l (sqdtc (cadr d) t)))
 
3007
                         (tbf l))
 
3008
                        ((and (eq n var)
 
3009
                              (setq l (sqdtc (cadr d) nil)))
 
3010
                         (tbf (reverse l)))))
 
3011
                 ((and (setq r (findp n))
 
3012
                       (or (eq ($asksign (m+ -1. (m-  r) (m*t 2.
 
3013
                                                              (caddr d))))
 
3014
                               '$pos)
 
3015
                           (diverg))
 
3016
                       (setq s (m+ '((rat) -3. 2.) (caddr d)))
 
3017
                       (eq ($asksign s) '$pos)
 
3018
                       (eq (ask-integer s '$integer) '$yes))
 
3019
                  (bydif r s (cadr d)))
 
3020
                 ((polyinx n var nil)
 
3021
                  (radbyterm d (cdr n))))))))
2475
3022
 
2476
3023
 
2477
3024
;;;Looks at the IMAGINARY part of a log and puts it in the interval 0 2*%pi.
2479
3026
  (let ((plog (simplify `((%plog) ,x))))
2480
3027
    (cond ((not (free plog '%plog))
2481
3028
           (subst '%log '%plog plog))
2482
 
          (t (let (((real . imag) (trisplit plog)))
 
3029
          (t (destructuring-let (((real . imag) (trisplit plog)))
2483
3030
               (cond ((eq ($asksign imag) '$neg)
2484
3031
                      (setq imag (m+ imag %pi2)))
2485
3032
                     ((eq ($asksign (m- imag %pi2)) '$pos)
2490
3037
            
2491
3038
;;; Temporary fix for a lacking in taylor, which loses with %i in denom.
2492
3039
;;; Besides doesn't seem like a bad thing to do in general.
2493
 
(defun %i-out-of-denom (exp)
2494
 
       (let ((denom ($denom exp))
2495
 
             (den-conj nil))
2496
 
            (cond ((among '$%i denom)
2497
 
                   (setq den-conj (MAXIMA-SUBSTITUTE (m- '$%i) '$%i denom))
2498
 
                   (setq exp (m* den-conj ($ratsimp (m// exp den-conj))))
2499
 
                   (setq exp (simplify ($multthru  (sratsimp exp)))))
2500
 
                  (t exp))))
 
3040
#+nil
 
3041
(defun %i-out-of-denom (exp)
 
3042
  (let ((denom ($denom exp))
 
3043
        (den-conj nil))
 
3044
    (cond ((among '$%i denom)
 
3045
           (setq den-conj (maxima-substitute (m- '$%i) '$%i denom))
 
3046
           (setq exp (m* den-conj ($ratsimp (m// exp den-conj))))
 
3047
           (setq exp (simplify ($multthru  (sratsimp exp)))))
 
3048
          (t exp))))
 
3049
 
 
3050
(defun %i-out-of-denom (exp)
 
3051
  (let ((denom ($denom exp)))
 
3052
    (cond ((among '$%i denom)
 
3053
           ;; Multiply the denominator by it's conjugate to get rid of
 
3054
           ;; %i.
 
3055
           (let* ((den-conj (maxima-substitute (m- '$%i) '$%i denom))
 
3056
                  (num ($num exp))
 
3057
                  (new-denom ($ratsimp (m* denom den-conj))))
 
3058
             ;; If the new denominator still contains %i, just give
 
3059
             ;; up.  Otherwise, multiply the numerator by the
 
3060
             ;; conjugate and divide by the new denominator.
 
3061
             (if (among '$%i new-denom)
 
3062
                 exp
 
3063
                 (setq exp (m// (m* num den-conj) new-denom)))))
 
3064
          (t exp))))
2501
3065
 
2502
3066
;;; LL and UL must be real otherwise this routine return $UNKNOWN.
2503
3067
;;; Returns $no $unknown or a list of poles in the interval (ll ul)
2504
3068
;;; for exp w.r.t. var.
2505
3069
;;; Form of list ((pole . multiplicity) (pole1 . multiplicity) ....)
2506
3070
(defun poles-in-interval (exp var ll ul)
2507
 
 (let* ((denom (cond ((mplusp exp)
2508
 
                      ($denom (sratsimp exp)))
2509
 
                     ((and (mexptp exp)
2510
 
                           (free (caddr exp) var)
2511
 
                           (eq ($asksign (caddr exp)) '$neg))
2512
 
                      (m^ (cadr exp) (m- (caddr exp))))
2513
 
                     (t ($denom exp))))
2514
 
        (roots (real-roots denom var))
2515
 
        (ll-pole (limit-pole exp var ll '$plus))
2516
 
        (ul-pole (limit-pole exp var ul '$minus)))
2517
 
       (cond ((or (eq roots '$failure)
2518
 
                  (null ll-pole)
2519
 
                  (null ul-pole))   '$unknown)
2520
 
             ((and (eq roots '$no)
2521
 
                   (eq ll-pole '$no)
2522
 
                   (eq ul-pole '$no))  '$no)
2523
 
             (t (cond ((equal roots '$no)
2524
 
                       (setq roots ())))
2525
 
                (do ((dummy roots (cdr dummy))
2526
 
                     (pole-list (cond ((not (eq ll-pole '$no))
2527
 
                                       `((,ll . 1)))
2528
 
                                      (t nil))))
2529
 
                    ((null dummy)
2530
 
                     (cond ((not (eq ul-pole '$no))
2531
 
                            (sort-poles (push `(,ul . 1) pole-list)))
2532
 
                           ((not (null pole-list))
2533
 
                            (sort-poles pole-list))
2534
 
                           (t '$no)))
2535
 
                    (let* ((soltn (caar dummy))
2536
 
                           ;; (multiplicity (cdar dummy)) (not used? -- cwh)
2537
 
                           (root-in-ll-ul (in-interval soltn ll ul)))
2538
 
                          (cond ((eq root-in-ll-ul '$no) '$no)
2539
 
                                ((eq root-in-ll-ul '$yes)
2540
 
                                 (let ((lim-ans (is-a-pole exp soltn)))
2541
 
                                      (cond ((null lim-ans)
2542
 
                                             (return '$unknown))
2543
 
                                            ((equal lim-ans 0)
2544
 
                                             '$no)
2545
 
                                            (t (push (car dummy)
2546
 
                                                     pole-list))))))))))))
 
3071
  (let* ((denom (cond ((mplusp exp)
 
3072
                       ($denom (sratsimp exp)))
 
3073
                      ((and (mexptp exp)
 
3074
                            (free (caddr exp) var)
 
3075
                            (eq ($asksign (caddr exp)) '$neg))
 
3076
                       (m^ (cadr exp) (m- (caddr exp))))
 
3077
                      (t ($denom exp))))
 
3078
         (roots (real-roots denom var))
 
3079
         (ll-pole (limit-pole exp var ll '$plus))
 
3080
         (ul-pole (limit-pole exp var ul '$minus)))
 
3081
    (cond ((or (eq roots '$failure)
 
3082
               (null ll-pole)
 
3083
               (null ul-pole))   '$unknown)
 
3084
          ((and (eq roots '$no)
 
3085
                (eq ll-pole '$no)
 
3086
                (eq ul-pole '$no))  '$no)
 
3087
          (t (cond ((equal roots '$no)
 
3088
                    (setq roots ())))
 
3089
             (do ((dummy roots (cdr dummy))
 
3090
                  (pole-list (cond ((not (eq ll-pole '$no))
 
3091
                                    `((,ll . 1)))
 
3092
                                   (t nil))))
 
3093
                 ((null dummy)
 
3094
                  (cond ((not (eq ul-pole '$no))
 
3095
                         (sort-poles (push `(,ul . 1) pole-list)))
 
3096
                        ((not (null pole-list))
 
3097
                         (sort-poles pole-list))
 
3098
                        (t '$no)))
 
3099
               (let* ((soltn (caar dummy))
 
3100
                      ;; (multiplicity (cdar dummy)) (not used? -- cwh)
 
3101
                      (root-in-ll-ul (in-interval soltn ll ul)))
 
3102
                 (cond ((eq root-in-ll-ul '$no) '$no)
 
3103
                       ((eq root-in-ll-ul '$yes)
 
3104
                        (let ((lim-ans (is-a-pole exp soltn)))
 
3105
                          (cond ((null lim-ans)
 
3106
                                 (return '$unknown))
 
3107
                                ((equal lim-ans 0)
 
3108
                                 '$no)
 
3109
                                (t (push (car dummy)
 
3110
                                         pole-list))))))))))))
2547
3111
 
2548
3112
 
2549
3113
;;;Returns $YES if there is no pole and $NO if there is one.
2553
3117
                           '$no)
2554
3118
                          (t (get-limit (m* exp var) var limit direction))))
2555
3119
                   (t '$no))))
2556
 
       (cond ((eq ans '$no)   '$no)
2557
 
                  ((null ans)   nil)
2558
 
                  ((equal ans 0.)   '$no)
2559
 
                  (t '$yes))))
 
3120
    (cond ((eq ans '$no)   '$no)
 
3121
          ((null ans)   nil)
 
3122
          ((eq ans '$und) '$no)
 
3123
          ((equal ans 0.)   '$no)
 
3124
          (t '$yes))))
2560
3125
 
2561
3126
;;;Takes care of forms that the ratio test fails on.
2562
3127
(defun special-convergent-formp (exp limit)
2573
3138
               (freeof '$%i exparg))
2574
3139
           '$no)
2575
3140
          (t (cond
2576
 
              ((and (freeof '$%i 
2577
 
                            (%einvolve 
2578
 
                             (setq exp 
2579
 
                                   (sratsimp (m// exp (m^t '$%e exparg))))))
2580
 
                    (equal (get-limit exp var limit)  0))
 
3141
               ((and (freeof '$%i 
 
3142
                             (%einvolve 
 
3143
                              (setq exp 
 
3144
                                    (sratsimp (m// exp (m^t '$%e exparg))))))
 
3145
                     (equal (get-limit exp var limit)  0))
2581
3146
                '$yes)
2582
 
              (t '$no))))))
 
3147
               (t '$no))))))
2583
3148
 
2584
3149
(defun sc-converg-form (exp limit)       
2585
 
 (prog (scarg trigpow)
2586
 
  (setq exp ($expand exp))
2587
 
  (setq scarg (involve (sin-sq-cos-sq-sub exp) '(%sin %cos)))
2588
 
  (cond ((null scarg) (return '$no))
2589
 
        ((and (polyinx scarg var ())
2590
 
              (eq ($asksign (m- ($hipow scarg var) 1)) '$pos)) (return '$yes))
2591
 
        ((not (freeof var (sdiff scarg var)))
2592
 
         (return '$no))
2593
 
        ((and (setq trigpow ($hipow exp `((%sin) ,scarg)))
2594
 
              (eq (ask-integer trigpow '$odd) '$yes)
2595
 
              (equal (get-limit (m// exp `((%sin) ,scarg)) var limit)
2596
 
                     0))
2597
 
         (return '$yes))
2598
 
        ((and (setq trigpow ($hipow exp `((%cos) ,scarg)))
2599
 
              (eq (ask-integer trigpow '$odd) '$yes)
2600
 
              (equal (get-limit (m// exp `((%cos) ,scarg)) var limit)
2601
 
                     0))
2602
 
         (return '$yes))
2603
 
        (t (return '$no)))))
 
3150
  (prog (scarg trigpow)
 
3151
     (setq exp ($expand exp))
 
3152
     (setq scarg (involve (sin-sq-cos-sq-sub exp) '(%sin %cos)))
 
3153
     (cond ((null scarg) (return '$no))
 
3154
           ((and (polyinx scarg var ())
 
3155
                 (eq ($asksign (m- ($hipow scarg var) 1)) '$pos)) (return '$yes))
 
3156
           ((not (freeof var (sdiff scarg var)))
 
3157
            (return '$no))
 
3158
           ((and (setq trigpow ($hipow exp `((%sin) ,scarg)))
 
3159
                 (eq (ask-integer trigpow '$odd) '$yes)
 
3160
                 (equal (get-limit (m// exp `((%sin) ,scarg)) var limit)
 
3161
                        0))
 
3162
            (return '$yes))
 
3163
           ((and (setq trigpow ($hipow exp `((%cos) ,scarg)))
 
3164
                 (eq (ask-integer trigpow '$odd) '$yes)
 
3165
                 (equal (get-limit (m// exp `((%cos) ,scarg)) var limit)
 
3166
                        0))
 
3167
            (return '$yes))
 
3168
           (t (return '$no)))))
2604
3169
 
2605
3170
(defun is-a-pole (exp soltn)
2606
 
       (get-limit ($radcan 
2607
 
                   (m* (MAXIMA-SUBSTITUTE (m+ 'epsilon soltn) var exp)
2608
 
                         'epsilon))
2609
 
                  'epsilon 0 '$plus))
 
3171
  (get-limit ($radcan 
 
3172
              (m* (maxima-substitute (m+ 'epsilon soltn) var exp)
 
3173
                  'epsilon))
 
3174
             'epsilon 0 '$plus))
2610
3175
 
2611
3176
(defun in-interval (place ll ul)
2612
 
        ;; real values for ll and ul; place can be imaginary.
 
3177
  ;; real values for ll and ul; place can be imaginary.
2613
3178
  (let ((order (ask-greateq ul ll)))
2614
3179
    (cond ((eq order '$yes))
2615
3180
          ((eq order '$no) (let ((temp ul)) (setq ul ll ll temp)))
2616
 
          (t (merror "Incorrect limits given to DEFINT:~%~M"
 
3181
          (t (merror "Incorrect limits given to `defint':~%~M"
2617
3182
                     (list '(mlist simp) ll ul)))))
2618
3183
  (if (not (equal ($imagpart place) 0))
2619
3184
      '$no
2623
3188
 
2624
3189
(defun real-roots (exp var)
2625
3190
  (let (($solvetrigwarn (cond (defintdebug t) ;Rest of the code for
2626
 
                              (t ())))           ;TRIGS in denom needed.
 
3191
                              (t ())))  ;TRIGS in denom needed.
2627
3192
        ($solveradcan (cond ((or (among '$%i exp)
2628
3193
                                 (among '$%e exp)) t)
2629
3194
                            (t nil)))
2630
 
        *roots *failures) ;special vars for solve.
2631
 
       (cond ((not (among var exp))   '$no)
2632
 
             (t (solve exp var 1)
2633
 
                (cond (*failures '$failure)
2634
 
                      (t (do ((dummy *roots (cddr dummy))
2635
 
                              (rootlist))
2636
 
                             ((null dummy)
2637
 
                              (cond ((not (null rootlist))
2638
 
                                     rootlist)
2639
 
                                    (t '$no)))
2640
 
                           (cond ((equal ($imagpart (caddar dummy)) 0)
2641
 
                                  (setq rootlist 
2642
 
                                        (cons (cons 
2643
 
                                               ($rectform (caddar dummy))
2644
 
                                               (cadr dummy))
2645
 
                                              rootlist)))))))))))
 
3195
        *roots *failures)               ;special vars for solve.
 
3196
    (cond ((not (among var exp))   '$no)
 
3197
          (t (solve exp var 1)
 
3198
             (cond (*failures '$failure)
 
3199
                   (t (do ((dummy *roots (cddr dummy))
 
3200
                           (rootlist))
 
3201
                          ((null dummy)
 
3202
                           (cond ((not (null rootlist))
 
3203
                                  rootlist)
 
3204
                                 (t '$no)))
 
3205
                        (cond ((equal ($imagpart (caddar dummy)) 0)
 
3206
                               (setq rootlist 
 
3207
                                     (cons (cons 
 
3208
                                            ($rectform (caddar dummy))
 
3209
                                            (cadr dummy))
 
3210
                                           rootlist)))))))))))
2646
3211
 
2647
3212
(defun ask-greateq (x y)
2648
3213
;;; Is x > y. X or Y can be $MINF or $INF, zeroA or zeroB.
2649
 
       (let ((x (cond ((among 'zeroa x)
2650
 
                       (subst 0 'zeroa x))
2651
 
                      ((among 'zerob x)
2652
 
                       (subst 0 'zerob x))
2653
 
                      ((among 'epsilon x)
2654
 
                       (subst 0 'epsilon x))
2655
 
                      ((or (among '$inf x)
2656
 
                           (among '$minf x))
2657
 
                       ($limit x))
2658
 
                      (t x)))
2659
 
             (y (cond ((among 'zeroa y)
2660
 
                       (subst 0 'zeroa y))
2661
 
                      ((among 'zerob y)
2662
 
                       (subst 0 'zerob y))
2663
 
                      ((among 'epsilon y)
2664
 
                       (subst 0 'epsilon y))
2665
 
                      ((or (among '$inf y)
2666
 
                           (among '$minf y))
2667
 
                       ($limit y))
2668
 
                      (t y))))
2669
 
            (cond ((eq x '$inf)
2670
 
                   '$yes)
2671
 
                  ((eq x '$minf)
2672
 
                   '$no)
2673
 
                  ((eq y '$inf)
2674
 
                   '$no)
2675
 
                  ((eq y '$minf)
2676
 
                   '$yes)
2677
 
                  (t (let ((ans ($asksign (m+ x (m- y)))))
2678
 
                          (cond ((memq ans '($zero $pos))
 
3214
  (let ((x (cond ((among 'zeroa x)
 
3215
                  (subst 0 'zeroa x))
 
3216
                 ((among 'zerob x)
 
3217
                  (subst 0 'zerob x))
 
3218
                 ((among 'epsilon x)
 
3219
                  (subst 0 'epsilon x))
 
3220
                 ((or (among '$inf x)
 
3221
                      (among '$minf x))
 
3222
                  ($limit x))
 
3223
                 (t x)))
 
3224
        (y (cond ((among 'zeroa y)
 
3225
                  (subst 0 'zeroa y))
 
3226
                 ((among 'zerob y)
 
3227
                  (subst 0 'zerob y))
 
3228
                 ((among 'epsilon y)
 
3229
                  (subst 0 'epsilon y))
 
3230
                 ((or (among '$inf y)
 
3231
                      (among '$minf y))
 
3232
                  ($limit y))
 
3233
                 (t y))))
 
3234
    (cond ((eq x '$inf)
 
3235
           '$yes)
 
3236
          ((eq x '$minf)
 
3237
           '$no)
 
3238
          ((eq y '$inf)
 
3239
           '$no)
 
3240
          ((eq y '$minf)
 
3241
           '$yes)
 
3242
          (t (let ((ans ($asksign (m+ x (m- y)))))
 
3243
               (cond ((memq ans '($zero $pos))
 
3244
                      '$yes)
 
3245
                     ((eq ans '$neg)
 
3246
                      '$no)
 
3247
                     (t '$unknown)))))))
 
3248
 
 
3249
(defun sort-poles (pole-list)
 
3250
  (sort pole-list #'(lambda (x y)
 
3251
                      (cond ((eq (ask-greateq (car x) (car y))
2679
3252
                                 '$yes)
2680
 
                                ((eq ans '$neg)
2681
 
                                 '$no)
2682
 
                                (t '$unknown)))))))
2683
 
 
2684
 
(defun sort-poles (pole-list)
2685
 
       (sort pole-list #'(lambda (x y)
2686
 
                                (cond ((eq (ask-greateq (car x) (car y))
2687
 
                                           '$yes)
2688
 
                                       nil)
2689
 
                                      (t t)))))
 
3253
                             nil)
 
3254
                            (t t)))))