partdf.red 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. module partdf; % Adaption of df module.
  2. % Author: Eberhard Schruefer.
  3. % Modifications by: David Hartley.
  4. fluid '(alglist!* depl!* frlis!* posn!* subfg!* wtl!* fancy!-pos!*
  5. fancy!-line!*);
  6. global '(naturalvector2framevector keepl!* !*product!-rule);
  7. newtok '((!@) partdf);
  8. symbolic procedure simppartdf0 u;
  9. begin scalar v;
  10. if null cdr u then
  11. if coordp(u := reval car u)
  12. and (v := atsoc(u,naturalvector2framevector))
  13. then return !*pf2sq !*pfsq2pf cdr v
  14. else return mksq(list('partdf,u),1);
  15. if null subfg!* or freeindp car u or freeindp cadr u
  16. or (cddr u and freeindp caddr u)
  17. then return mksq('partdf . revlis u,1);
  18. v := cdr u;
  19. u := simp!* car u;
  20. for each j in v do
  21. u := partdfsq(u,!*a2k j);
  22. return u
  23. end;
  24. put('partdf,'simpfn,'simppartdf);
  25. put('partdf,'rtypefn,'getrtypeor);
  26. put('partdf,'partitfn,'partitpartdf);
  27. symbolic procedure partitpartdf u;
  28. if null cdr u then mknatvec !*a2k car u
  29. else 1 .* simppartdf0 u .+ nil;
  30. symbolic procedure simppartdf u;
  31. !*pf2sq partitpartdf u;
  32. symbolic procedure mknatvec u;
  33. begin scalar x,y;
  34. return if x := atsoc(u,naturalvector2framevector)
  35. then !*pfsq2pf cdr x
  36. else if x := opmtch(y := list('partdf,u))
  37. then partitop x
  38. else mkupf y
  39. end;
  40. symbolic procedure partdfsq(u,v);
  41. multsq(addsq(partdff(numr u,v),
  42. multsq(u,partdff(negf denr u,v))),
  43. 1 ./ denr u);
  44. symbolic procedure partdff(u,v);
  45. if domainp u then nil ./ 1
  46. else addsq(if null !*product!-rule then partdft(lt u,v)
  47. else addsq(multpq(lpow u,partdff(lc u,v)),
  48. multsq(partdfpow(lpow u,v),lc u ./ 1)),
  49. partdff(red u,v));
  50. symbolic procedure partdft(u,v);
  51. begin scalar x,y;
  52. x := partdft1(!*t2q u,v);
  53. y := nil ./ 1;
  54. for each j on x do
  55. if null domainp ldpf j then
  56. y := addsq(multsq(if domainp lc ldpf j then
  57. multsq(partdfpow(lpow ldpf j,v),
  58. lc ldpf j ./ 1)
  59. else mksq(list('partdf,prepf ldpf j,v),1),
  60. lc j),y);
  61. return y
  62. end;
  63. symbolic procedure partdft1(u,v);
  64. (if null x then nil
  65. else if domainp x then 1 .* u .+ nil
  66. else addpsf(if sfp mvar x and numr partdfpow(lpow mvar x,v)
  67. then multpsf(exptpsf(partdft1(mvar u ./ 1,v),
  68. ldeg x),
  69. partdft1(cancel(lc x ./ y),v))
  70. else if null sfp mvar x and numr partdfpow(lpow x,v)
  71. then multpsf(!*p2f lpow x .* (1 ./ 1) .+ nil,
  72. partdft1(cancel(lc x ./ y),v))
  73. else multsqpsf(!*p2q lpow x,
  74. partdft1(cancel(lc x ./ y),v)),
  75. partdft1(cancel(red x ./ y),v)))
  76. where x = numr u, y = denr u;
  77. symbolic procedure partdfpow(u,v);
  78. begin scalar x,z; integer n;
  79. n := cdr u;
  80. u := car u;
  81. z := nil ./ 1;
  82. if u eq v then z := 1 ./ 1
  83. else if atomf u then
  84. if x := assoc(u,keepl!*) then
  85. begin scalar alglist!*;
  86. z := partdfsq(simp0 cdr x,v)
  87. end
  88. else if ndepends(if x := get(lid u,'varlist)
  89. then lid u . cdr x
  90. else lid u,v)
  91. then z := mksq(list('partdf,u,v),1)
  92. else return nil ./ 1
  93. else if sfp u then z := partdff(u,v)
  94. else if car u eq '!*sq then z := partdfsq(cadr u,v)
  95. else if x := get(car u,dfn_prop u) then
  96. for each j in
  97. for each k in cdr u collect partdfsq(simp k,v)
  98. do <<if numr j then
  99. z := addsq(multsq(j,simp
  100. subla(pair(caar x,cdr u),cdar x)),
  101. z);
  102. x := cdr x>>
  103. else if car u eq 'partdf then
  104. if ndepends(lid cadr u,v) then
  105. % Too restrictive...
  106. % if assoc(list('partdf,cadr u,v),
  107. % get('partdf,'kvalue)) then
  108. % <<z := mksq(list('partdf,cadr u,v),1);
  109. % for each j in cddr u do
  110. % z := partdfsq(z,j)>>
  111. % More general matching...
  112. if x := partdfsplit(u,v,get('partdf,'kvalue)) then
  113. <<z := mksq(car x,1);
  114. for each j in cdr x do
  115. z := partdfsq(z,j)>>
  116. else
  117. <<z := 'partdf . cadr u . ordn(v . cddr u);
  118. z := if x := opmtch z then simp x
  119. else mksq(z,1)>>
  120. else return nil ./ 1;
  121. if x := atsoc(u,wtl!*) then z := multpq('k!* to (-cdr x),z);
  122. return if n=1 then z else multsq(!*t2q((u to (n-1)) .* n),z)
  123. end;
  124. symbolic procedure partdfsplit(u,v,k);
  125. % u,v:kernel, k:alist -> partdfsplit:list of kernel.
  126. % Input u is (partdf f ...), v is kernel on which f depends, k is
  127. % kvalue list for partdf. Result is nil unless some subderivative
  128. % of (partdf f ... v) is known, in which case, the kernel whose
  129. % derivative is known is the first return value and the remaining
  130. % variables form the rest.
  131. if null k then nil
  132. else if cadr caar k eq cadr u and
  133. v memq cddr caar k and
  134. sublistp(delete(v,cddr caar k),cddr u) then
  135. caar k . listdiff(cddr u,delete(v,cddr caar k))
  136. else partdfsplit(u,v,cdr k);
  137. symbolic procedure sublistp(x,y);
  138. % x,y:list -> sublistp:bool
  139. null x or car x member y and sublistp(cdr x,delete(car x,y));
  140. symbolic procedure listdiff(x,y);
  141. % x,y:list -> listdiff:list
  142. if null y then x
  143. else if null x then nil
  144. else listdiff(delete(car y,x),cdr y);
  145. symbolic procedure ndepends(u,v);
  146. if null u or numberp u or numberp v then nil
  147. else if u=v then u
  148. else if atom u and u memq frlis!* then t
  149. else if (lambda x; x and lndepends(cdr x,v)) assoc(u,depl!*)
  150. then t
  151. else if not atom u and idp car u and get(car u,'dname) then nil
  152. else if not atomf u
  153. and (lndepends(cdr u,v) or ndepends(car u,v)) then t
  154. else if atomf v or idp car v and get(car v,'dname) then nil
  155. else ndependsl(u,cdr v);
  156. symbolic procedure lndepends(u,v);
  157. u and (ndepends(car u,v) or lndepends(cdr u,v));
  158. symbolic procedure ndependsl(u,v);
  159. u and (ndepends(u,car v) or ndependsl(u,cdr v));
  160. symbolic procedure partdfprn u;
  161. if null !*nat then <<prin2!* '!@;
  162. prin2!* "(";
  163. if cddr u then inprint('!*comma!*,0,cdr u)
  164. else maprin cadr u;
  165. prin2!* ")" >>
  166. else begin scalar y; integer l;
  167. l := flatsizec flatindxl cdr u+1;
  168. if l>(linelength nil-spare!*)-posn!* then terpri!* t;
  169. %avoids breaking of the operator over a line;
  170. y := ycoord!*;
  171. prin2!* '!@;
  172. ycoord!* := y - if (null cddr u and indexvp cadr u) or
  173. (cddr u and indexvp caddr u) then 2
  174. else 1;
  175. if ycoord!*<ymin!* then ymin!* := ycoord!*;
  176. if null cddr u then <<maprin cadr u;
  177. ycoord!* := y>>
  178. else <<for each j on cddr u do
  179. <<maprin car j;
  180. if cdr j then prin2!* " ">>;
  181. ycoord!* := y;
  182. if atom cadr u then prin2!* cadr u
  183. else <<prin2!* "(";
  184. maprin cadr u;
  185. prin2!* ")">>>>
  186. end;
  187. put('partdf,'prifn,'partdfprn);
  188. symbolic procedure indexvp u;
  189. null atom u and flagp(car u,'indexvar);
  190. symbolic procedure xpartdfprn(u,l);
  191. fancy!-level(if null cddr u
  192. then begin scalar w;
  193. w := fancy!-prefix!-operator 'partial!-df;
  194. if w eq 'failed then return 'failed;
  195. return fancy!-print!-indexlist1(cdr u,'!_,nil)
  196. end
  197. else fancy!-dfpri0(car u . cadr u .
  198. deradpdf cddr u,l,'partial!-df));
  199. symbolic procedure deradpdf u;
  200. if null cdr u then u
  201. else begin scalar x;
  202. x := derad(car u,{cadr u});
  203. for each j in cddr u do x := derad(j,x);
  204. return x
  205. end;
  206. put('partdf,'fancy!-pprifn,'xpartdfprn);
  207. endmodule;
  208. end;