26
26
search for `Maxima:' below. -wj */
28
28
eval_when([batch,loadfile],
29
if get('GNAUTO,'DIAGEVAL_VERSION)=false
29
if get('gnauto,'diageval_version)=false
30
30
then load("genut"))$
32
32
eval_when(translate,
33
declare_translated(EXWRT_POWER1,VARMULT,DISTRIBUTE,EXWRT_POWER,
34
FREEOFL,STOPEXPANDL1,ORPARTITIONL,LDELETE,
33
declare_translated(exwrt_power1,varmult,distribute,exwrt_power,
34
freeofl,stopexpandl1,orpartitionl,ldelete,
38
DEFINE_VARIABLE(IFORP,FALSE,BOOLEAN)$
39
DEFINE_VARIABLE(EXPANDWRT_DENOM,FALSE,BOOLEAN)$
40
DEFINE_VARIABLE(EXPANDWRT_NONRAT,TRUE,BOOLEAN)$
42
STOPEXPAND(EXP,[VARLIST]):=
43
IF ATOM(EXP) OR MAPATOM(EXP)
45
ELSE BLOCK([PARTSWITCH:TRUE,INFLAG:TRUE,PIECE],
46
STOPEXPANDL(EXP,VARLIST))$
48
EXPANDWRT(EXP,[VARLIST]):=
49
IF ATOM(EXP) OR MAPATOM(EXP)
51
ELSE BLOCK([PARTSWITCH:TRUE,INFLAG:TRUE,PIECE],
52
STOPEXPANDL(EXP,VARLIST))$
54
EXPANDWRTL(EXP,VARLIST):=STOPEXPANDL(EXP,VARLIST)$
56
STOPEXPANDL(EXP,VARLIST):=
57
IF ATOM(EXP) OR MAPATOM(EXP)
59
ELSE BLOCK([INFLAG:TRUE,PARTSWITCH:TRUE,PIECE,IP0DUM],
60
IF (IP0DUM:INPART(EXP,0))="+"
61
THEN MAP(LAMBDA([TERMDUM],STOPEXPANDL(TERMDUM,VARLIST)),EXP)
63
[NONRATDUM,IFORP:TRUE,DENDUM],
66
LDELETE(VARLIST,LAST(ORPARTITIONL(SHOWRATVARS(EXP),"[",VARLIST))),
67
FOR IDUM IN NONRATDUM DO
69
THEN EXP:SUBST(MAP(LAMBDA([DUM],STOPEXPANDL(DUM,VARLIST)),IDUM),
71
IF EXPANDWRT_DENOM AND (DENDUM:DENOM(EXP))#1
72
THEN EXP:NUM(EXP)/STOPEXPANDL(DENDUM,VARLIST),
73
STOPEXPANDL1(EXP,VARLIST)))$
75
STOPEXPANDL1(EXP,VARLIST):=
76
IF ATOM(EXP) OR MAPATOM(EXP)
78
ELSE BLOCK([IP0DUM:INPART(EXP,0),DUM:1,VARFOUND:FALSE],
79
MODEDECLARE(VARFOUND,BOOLEAN),
80
IF FREEOFL(VARLIST,EXP)
82
ELSE IF FREEOF("+",EXP) THEN RETURN(EXP),
84
THEN RETURN(MAP(LAMBDA([TERMDUM],
85
STOPEXPANDL1(TERMDUM,VARLIST)),EXP))
87
THEN IF INPART(EXP,1,0)="+"
88
THEN EXWRT_POWER(EXP,VARLIST)
91
THEN (FOR IDUM IN EXP DO
92
IF NOT FREEOFL(VARLIST,IDUM)
93
THEN (IDUM:STOPEXPANDL1(IDUM,VARLIST),
95
THEN DUM:DISTRIBUTE(DUM,IDUM,VARLIST)
97
DUM:VARMULT(DUM,IDUM,VARLIST)))
99
THEN DUM:VARMULT(IDUM,DUM,VARLIST)
102
ELSE IF MATRIXP(EXP) OR LISTP(EXP)
103
THEN MATRIXMAP(LAMBDA([DUMM],
104
STOPEXPANDL1(DUMM,VARLIST)),
106
ELSE IF IP0DUM="." AND EXPANDWRT_NONRAT
107
THEN REMOVE_NESTED_DOTS0L(MAP(LAMBDA([DUM],
114
EXWRT_POWER(EXP,VARLIST):=BLOCK(
115
[IP1DUM,IP2DUM1,EXWRTLIST,SPLITDUM,FSPLITDUM],
38
define_variable(iforp,false,boolean)$
39
define_variable(expandwrt_denom,false,boolean)$
40
define_variable(expandwrt_nonrat,true,boolean)$
42
stopexpand(exp,[varlist]):=
43
if atom(exp) or mapatom(exp)
45
else block([partswitch:true,inflag:true,piece],
46
stopexpandl(exp,varlist))$
48
expandwrt(exp,[varlist]):=
49
if atom(exp) or mapatom(exp)
51
else block([partswitch:true,inflag:true,piece],
52
stopexpandl(exp,varlist))$
54
expandwrtl(exp,varlist):=stopexpandl(exp,varlist)$
56
stopexpandl(exp,varlist):=
57
if atom(exp) or mapatom(exp)
59
else block([inflag:true,partswitch:true,piece,ip0dum],
60
if (ip0dum:inpart(exp,0))="+"
61
then map(lambda([termdum],stopexpandl(termdum,varlist)),exp)
63
[nonratdum,iforp:true,dendum],
66
ldelete(varlist,last(orpartitionl(showratvars(exp),"[",varlist))),
67
for idum in nonratdum do
69
then exp:subst(map(lambda([dum],stopexpandl(dum,varlist)),idum),
71
if expandwrt_denom and (dendum:denom(exp))#1
72
then exp:num(exp)/stopexpandl(dendum,varlist),
73
stopexpandl1(exp,varlist)))$
75
stopexpandl1(exp,varlist):=
76
if atom(exp) or mapatom(exp)
78
else block([ip0dum:inpart(exp,0),dum:1,varfound:false],
79
modedeclare(varfound,boolean),
80
if freeofl(varlist,exp)
82
else if freeof("+",exp) then return(exp),
84
then return(map(lambda([termdum],
85
stopexpandl1(termdum,varlist)),exp))
87
then if inpart(exp,1,0)="+"
88
then exwrt_power(exp,varlist)
91
then (for idum in exp do
92
if not freeofl(varlist,idum)
93
then (idum:stopexpandl1(idum,varlist),
95
then dum:distribute(dum,idum,varlist)
97
dum:varmult(dum,idum,varlist)))
99
then dum:varmult(idum,dum,varlist)
102
else if matrixp(exp) or listp(exp)
103
then matrixmap(lambda([dumm],
104
stopexpandl1(dumm,varlist)),
106
else if ip0dum="." and expandwrt_nonrat
107
then remove_nested_dots0l(map(lambda([dum],
114
exwrt_power(exp,varlist):=block(
115
[ip1dum,ip2dum1,exwrtlist,splitdum,fsplitdum],
116
116
/* DECLARE(EXWRTLIST,SPECIAL), */
117
IF INPART(EXP,0)#"^" THEN RETURN(EXP),
118
IF NOT FREEOFL(VARLIST,IP1DUM:INPART(EXP,1))
119
AND INTEGERP(IP2DUM1:INPART(EXP,2))
120
AND (MODE_IDENTITY(FIXNUM,IP2DUM1))>1
121
AND INPART(IP1DUM,0)="+"
122
THEN (SPLITDUM:ORPARTITIONL(IP1DUM,"+",VARLIST),
123
IF (FSPLITDUM:FIRST(SPLITDUM))#0
124
THEN (EXWRTLIST:CONS(1,EXWRT_POWER1(LAST(SPLITDUM),IP2DUM1,VARLIST)),
125
SUM(VARMULT(FSPLITDUM^KDUM*IP2DUM1!/(KDUM!*(IP2DUM1-KDUM)!),
126
FIRST(EXWRTLIST:REST(EXWRTLIST)),
117
if inpart(exp,0)#"^" then return(exp),
118
if not freeofl(varlist,ip1dum:inpart(exp,1))
119
and integerp(ip2dum1:inpart(exp,2))
120
and (mode_identity(fixnum,ip2dum1))>1
121
and inpart(ip1dum,0)="+"
122
then (splitdum:orpartitionl(ip1dum,"+",varlist),
123
if (fsplitdum:first(splitdum))#0
124
then (exwrtlist:cons(1,exwrt_power1(last(splitdum),ip2dum1,varlist)),
125
sum(varmult(fsplitdum^kdum*ip2dum1!/(kdum!*(ip2dum1-kdum)!),
126
first(exwrtlist:rest(exwrtlist)),
128
128
/* Maxima: added MODE_IDENTITY for translator */
129
KDUM,0,MODE_IDENTITY(FIXNUM,IP2DUM1)))
130
ELSE FIRST(EXWRT_POWER1(LAST(SPLITDUM),IP2DUM1,VARLIST)))
133
EXWRT_POWER1(EXP,POWERDUM,VARLIST):=(
134
MODEDECLARE(POWERDUM,FIXNUM),
136
[DUM:[EXP,1],FIRSTDUM:STOPEXPANDL1(EXP,VARLIST)],
137
IF POWERDUM=1 THEN RETURN(DUM),
139
THEN FOR IDUM:2 THRU POWERDUM DO
140
DUM:CONS(EXP^IDUM,DUM)
141
ELSE FOR IDUM:2 THRU POWERDUM DO
143
MAP(LAMBDA([DUM],MULTTHRU(DUM,FIRSTDUM)),EXP),DUM),
146
VARMULT(FACT,EXP,VARLIST):=BLOCK(
147
[SPLITDUM:ORPARTITIONL(EXP,"+",VARLIST)],
148
FACT*FIRST(SPLITDUM)+MULTTHRU(FACT,LAST(SPLITDUM)))$
150
DISTRIBUTE(EXP1,EXP2,VARLIST):=BLOCK(
151
[SPLITEXP1:ORPARTITIONL(EXP1,"+",VARLIST),
152
SPLITEXP2:ORPARTITIONL(EXP2,"+",VARLIST),
153
FSPLEXP1,FSPLEXP2,LSPLEXP1,LSPLEXP2],
154
LSPLEXP1:LAST(SPLITEXP1),
155
LSPLEXP2:LAST(SPLITEXP2),
156
(FSPLEXP1:FIRST(SPLITEXP1))*(FSPLEXP2:FIRST(SPLITEXP2))
158
THEN VARMULT(FSPLEXP1,STOPEXPANDL1(LSPLEXP2,VARLIST),VARLIST)
161
THEN VARMULT(FSPLEXP2,STOPEXPANDL1(LSPLEXP1,VARLIST),VARLIST)
163
+(IF INPART(LSPLEXP1,0)="+"
164
THEN MAP(LAMBDA([TERM],STOPEXPANDL1(TERM*LSPLEXP2,VARLIST)),LSPLEXP1)
165
ELSE IF INPART(LSPLEXP2,0)="+"
166
THEN MAP(LAMBDA([TERM],STOPEXPANDL1(TERM*LSPLEXP1,VARLIST)),LSPLEXP2)
167
ELSE LSPLEXP1*LSPLEXP2))$
169
EXPANDWRT_FACTORED(EXP,[VARLIST]):=
170
IF LISTP(EXP) OR MATRIXP(EXP)
171
THEN MATRIXMAP(LAMBDA([DUM],APPLY('EXPANDWRT_FACTORED,CONS(DUM,VARLIST))),
173
ELSE BLOCK([IFORP:TRUE,PIECE,PARTSWITCH:TRUE,INFLAG:TRUE,DUM],
174
DUM:ORPARTITIONL(EXP,"*",VARLIST),
175
FIRST(DUM)*STOPEXPANDL(LAST(DUM),VARLIST))$
177
EVAL_WHEN(BATCH,TTYOFF:FALSE)$
129
kdum,0,mode_identity(fixnum,ip2dum1)))
130
else first(exwrt_power1(last(splitdum),ip2dum1,varlist)))
133
exwrt_power1(exp,powerdum,varlist):=(
134
modedeclare(powerdum,fixnum),
136
[dum:[exp,1],firstdum:stopexpandl1(exp,varlist)],
137
if powerdum=1 then return(dum),
139
then for idum:2 thru powerdum do
140
dum:cons(exp^idum,dum)
141
else for idum:2 thru powerdum do
143
map(lambda([dum],multthru(dum,firstdum)),exp),dum),
146
varmult(fact,exp,varlist):=block(
147
[splitdum:orpartitionl(exp,"+",varlist)],
148
fact*first(splitdum)+multthru(fact,last(splitdum)))$
150
distribute(exp1,exp2,varlist):=block(
151
[splitexp1:orpartitionl(exp1,"+",varlist),
152
splitexp2:orpartitionl(exp2,"+",varlist),
153
fsplexp1,fsplexp2,lsplexp1,lsplexp2],
154
lsplexp1:last(splitexp1),
155
lsplexp2:last(splitexp2),
156
(fsplexp1:first(splitexp1))*(fsplexp2:first(splitexp2))
158
then varmult(fsplexp1,stopexpandl1(lsplexp2,varlist),varlist)
161
then varmult(fsplexp2,stopexpandl1(lsplexp1,varlist),varlist)
163
+(if inpart(lsplexp1,0)="+"
164
then map(lambda([term],stopexpandl1(term*lsplexp2,varlist)),lsplexp1)
165
else if inpart(lsplexp2,0)="+"
166
then map(lambda([term],stopexpandl1(term*lsplexp1,varlist)),lsplexp2)
167
else lsplexp1*lsplexp2))$
169
expandwrt_factored(exp,[varlist]):=
170
if listp(exp) or matrixp(exp)
171
then matrixmap(lambda([dum],apply('expandwrt_factored,cons(dum,varlist))),
173
else block([iforp:true,piece,partswitch:true,inflag:true,dum],
174
dum:orpartitionl(exp,"*",varlist),
175
first(dum)*stopexpandl(last(dum),varlist))$
177
eval_when(batch,ttyoff:false)$