crsep.red 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. %*********************************************************************
  2. module separation$
  3. %*********************************************************************
  4. % Routines for separation of de's
  5. % Author: Andreas Brand
  6. % 1990 1994
  7. symbolic procedure get_separ_pde(pdes)$
  8. % Find the directly separable PDE with the most variables
  9. begin scalar p,m$
  10. m:=-1$
  11. while pdes do <<
  12. if get(car pdes,'starde) and
  13. (zerop cdr get(car pdes,'starde)) and
  14. ((null p) or
  15. (get(car pdes,'nvars)<m)) then <<
  16. p:=car pdes$
  17. m:=get(p,'nvars)
  18. >>$
  19. pdes:=cdr pdes$
  20. >>$
  21. return p
  22. end$
  23. symbolic procedure separate(de)$
  24. % Separation of the equation de
  25. % result: a list of equations
  26. % NIL=no separation
  27. if flagp(de,'to_sep) and get(de,'starde) then
  28. begin scalar l$
  29. l:=separ(get(de,'val),get(de,'fcts),get(de,'vars))$
  30. if length l>1 then
  31. <<l:=mkeqlist(for each a in l collect cdr a,get(de,'fcts),
  32. get(de,'vars),delete('to_sep,allflags_),t,
  33. get(de,'orderings))$
  34. if print_ then
  35. <<terpri()$write "Separation of ",de," yields ",l>>$
  36. return l>>
  37. else remflag1(de,'to_sep)$
  38. end$
  39. symbolic procedure termsep(a,x)$
  40. % splits the product a in two parts: the first contains all
  41. % factors dependend on x the second all others
  42. % Result: nil, if no splitting possible
  43. % ((depending on x)(indep on x))
  44. begin scalar l,p,q,sig,l1,l2$
  45. if atom a then if x=a then l:=list(a,1) % Variable
  46. else l:=list(1,a) % Konstante
  47. else if my_freeof(a,x) then l:=list(1,a) % a unabh. von x
  48. else
  49. <<if car a='MINUS then
  50. <<a:=cadr a$
  51. sig:=not sig>>$
  52. if pairp a and (car a='TIMES) then l:=cdr a
  53. else l:=list a$ % l Liste der Faktoren
  54. p:=nil$ % Liste der Faktoren,
  55. % die x enthalten
  56. q:=nil$ % Liste der Faktoren,
  57. % die x nicht enth.
  58. while l do
  59. <<if my_freeof(car l,x) then q:=cons(car l,q)
  60. % Faktor enth. x nicht
  61. else
  62. if pairp car l and (caar l='EXPT) and my_freeof(cadar l,x)
  63. and (pairp caddar l) and (car caddar l='PLUS) then
  64. <<for each s in cdr caddar l do
  65. if my_freeof(s,x) then l1:=cons(s,l1)
  66. else l2:=cons(s,l2)$
  67. if l1 then
  68. <<if cdr l1 then l1:=cons('PLUS,l1)
  69. else l1:=car l1$
  70. q:=cons(list('EXPT,cadar l,l1),q)>>$
  71. if l2 and cdr l2 then l2:=cons('PLUS,l2)
  72. else l2:=car l2$
  73. p:=cons(list('EXPT,cadar l,l2),p)>>
  74. else p:=cons(car l,p)$
  75. l:=cdr l>>$
  76. if p then
  77. if length p>1 then p:=cons('TIMES,p)
  78. else p:=car p$
  79. if q then
  80. if length q>1 then q:=cons('TIMES,q)
  81. else q:=car q$
  82. if p or q then % war Sep. moegl.?
  83. if null p then if sig then l:=list(1,list('MINUS,q))
  84. else l:=list(1,q)
  85. else
  86. if q then if sig then l:=list(p,list('MINUS,q))
  87. else l:=list(p,q)
  88. else if sig then l:=list(p,list('MINUS,1))
  89. else l:=list(p,1)>>$
  90. return l
  91. end$
  92. symbolic procedure sumsep(l,x)$
  93. % Separieren einer Liste von Summanden
  94. % l Liste von Ausdr. in LISP-Notation, x Var.
  95. % Ergebnis: nil, falls keine Sep. moegl.,
  96. % sonst Liste von Listen von Summanden
  97. begin scalar cl,p,q,s$
  98. while l do
  99. if pairp car l and (caar l='QUOTIENT) then
  100. <<p:=termsep(cadar l,x)$
  101. if not q then q:=termsep(caddar l,x)$ % Quotient immer gleich
  102. if p and q then
  103. <<l:=cdr l$
  104. if car q=1 then s:=car p
  105. else s:=list('QUOTIENT,car p,car q)$
  106. if cadr q=1 then p:=list(s,cadr p)
  107. else p:=list(s,list('QUOTIENT,cadr p,cadr q))$
  108. cl:=termsort(cl,p)>>
  109. else
  110. <<l:=nil$
  111. cl:=nil>> >>
  112. else
  113. <<p:=termsep(car l,x)$ % Separieren eines Summanden
  114. if p then % erfolgreich
  115. <<l:=cdr l$
  116. cl:=termsort(cl,p)>> % Terme einordnen
  117. else
  118. <<l:=nil$ % Abbruch
  119. cl:=nil>> >>$ % keine Separ. moegl.
  120. if cl and print_ and (length cl>1) then % output for test
  121. <<terpri()$write "separation w.r.t. "$fctprint list x$
  122. % of linear independence
  123. if pairp caar cl and (caaar cl='QUOTIENT) then
  124. l:=for each s in cl collect cadar s
  125. else l:=for each s in cl collect car s$
  126. if not linearindeptest(l,list x) then cl:=nil>>$
  127. return cl % Liste der Terme, die von x
  128. % unabh. sind
  129. end$
  130. symbolic procedure linearindeptest(l,vl)$
  131. begin scalar l1,flag$
  132. l1:=l$flag:=t$
  133. while flag and pairp l1 do
  134. if freeoflist(car l1,vl) then l1:=cdr l1
  135. else if member(car l1,vl) then l1:=cdr l1
  136. else if (pairp car l1) and (caar l1='EXPT) and
  137. (numberp caddar l1) and member(cadar l1,vl) then l1:=cdr l1
  138. else flag:=nil$
  139. if not flag then
  140. <<terpri()$write "linear independent expressions : "$
  141. for each x in l do eqprint(x)$
  142. if independence_ then
  143. if yesp "Are the expressions linear independent?"
  144. then flag:=t
  145. else flag:=nil
  146. else flag:=t>>$
  147. return flag$
  148. end$
  149. symbolic procedure termsort(cl,p)$
  150. % Zusammenfassen der Terme
  151. % cl Liste von Paaren,p Paar
  152. % Sind bei einem Element von cl und bei p die ersten Teile gleich,
  153. % wird der zweite Teil von p an den des Elements von cl angehaengt
  154. if null cl then list p
  155. else if caar cl=car p then cons(cons(car p,cons(cadr p,cdar cl)),cdr cl)
  156. else cons(car cl,termsort(cdr cl,p))$
  157. symbolic procedure eqsep(eql,ftem)$
  158. % Separieren einer Liste von: Gl. als Liste von Koeffizient + Summ.
  159. % + Liste der Var. nach denen schon erfolglos sep. wurde
  160. % + Liste der Var. nach denen noch nicht separiert wurde
  161. begin scalar vlist1,vlist2,a,x,l,eql1$
  162. while eql do
  163. <<a:=car eql$ % erste Gl. +Listen
  164. vlist1:=cadr a$ % Var. nach d. erfolglos sep. wurde
  165. vlist2:=caddr a$ % Var. nach denen nicht sep. wurde
  166. eql:=cdr eql$
  167. if vlist2 then % noch Var. zu sep.
  168. <<x:=car vlist2$
  169. vlist2:=cdr vlist2$
  170. if my_freeof(cdar a,x) then
  171. eql:=cons(list(car a,vlist1,vlist2),eql)
  172. else
  173. if (my_freeof(cdar a,x) or
  174. member(x,argset smemberl(ftem,list cdar a)))
  175. then eql:=cons(list(car a,cons(x,vlist1),vlist2),eql)
  176. else <<l:=sumsep(cdar a,x)$
  177. % Liste der Gl. die sich durch Sep.
  178. % nach x ergeben
  179. if l then
  180. eql:=append(varapp(l,caar a,nil,append(vlist1,vlist2)),eql)
  181. % nach erfolgr. Sep. wird nach bisher
  182. % erfolglosen Var. sep.
  183. else
  184. eql:=cons(list(car a,cons(x,vlist1),vlist2),eql)>> >>
  185. % erfolgloses Sep.,x wird als
  186. % erfolglose Var. registriert
  187. else eql1:=cons(a,eql1)>>$
  188. return eql1$
  189. end$
  190. symbolic procedure varapp(l,a,v1,v2)$
  191. % an jede Gl. aus l werden v1 und v2 angehaengt
  192. if null l then nil
  193. else
  194. cons(list(cons(cons(caar l,a),cdar l),v1,v2),varapp(cdr l,a,v1,v2))$
  195. symbolic procedure sep(p,ftem,varl)$
  196. % Die Gl. p (in LISP-Notation) wird nach den Var. aus varl separiert
  197. % varl Liste der Variabl.
  198. begin scalar eql,eqlist,a,q$
  199. if pairp p and (car p='QUOTIENT) then
  200. <<q:=cdr reval list('FACTORIZE,caddr p)$
  201. if length q>1 then q:=cons('TIMES,q)
  202. else q:=car q$
  203. p:=cadr p
  204. >>$
  205. if pairp p and (car p='PLUS) then
  206. a:=cons(nil,if not q then cdr p
  207. else for each b in cdr p
  208. collect list('QUOTIENT,b,q))
  209. else
  210. if not q then a:=list(nil,p)
  211. else a:=list(nil,List('QUOTIENT,p,q))$
  212. % Gl. als Liste von Summanden
  213. eql:=list(list(a,nil,varl))$
  214. % Listen der Var. anhaengen
  215. eql:=eqsep(eql,ftem)$
  216. while eql do
  217. <<a:=caar eql$ % Listen der Var. streichen
  218. if cddr a then a:=cons(car a,cons('PLUS,cdr a))
  219. else a:=cons(car a,cadr a)$ % PLUS eintragen
  220. if car a then
  221. if cdar a then a:=cons(cons('TIMES, car a),cdr a)
  222. else a:=cons(caar a,cdr a)
  223. else a:=cons(1,cdr a)$
  224. eqlist:=cons(a,eqlist)$
  225. eql:=cdr eql
  226. >>$
  227. return eqlist
  228. end$
  229. symbolic procedure separ2(p,ftem,varl)$
  230. % Die Gl. p (in LISP-Notation) wird nach den Var. aus varl separiert
  231. % varl Liste der Variabl.
  232. begin scalar eqlist$
  233. if p and not zerop p then
  234. if not (pairp p and (car p='QUOTIENT) and
  235. intersection(argset smemberl(ftem,cadr p),varl)) then
  236. <<eqlist:=sep(p,ftem,varl)$
  237. if eqlist then eqlist:=union(cdr eqlist,list car eqlist)$
  238. >>; % else eqlist is nil
  239. return eqlist
  240. end$
  241. symbolic procedure separ(p,ftem,varl)$
  242. % Die Gl. p (in LISP-Notation) wird nach den Var. aus varl separiert
  243. % varl Liste der Variabl.
  244. begin scalar eql,eqlist,a,b,l,s$
  245. if p and not zerop p then
  246. if not (pairp p and (car p='QUOTIENT) and
  247. intersection(argset smemberl(ftem,cadr p),varl)) then
  248. <<eqlist:=sep(p,ftem,varl)$
  249. if eqlist then eql:=union(cdr eqlist,list car eqlist)$
  250. eqlist:=nil$
  251. while eql do
  252. <<a:=car eql$
  253. l:=eql:=cdr eql$
  254. for each b in l do
  255. <<s:=reval list('QUOTIENT,cdr b,cdr a)$
  256. if not smemberl(append(varl,ftem),s) then
  257. <<eql:=delete(b,eql)$
  258. a:=cons(reval list('PLUS,car a,list('TIMES,s,car b)),cdr a)>>
  259. >>$
  260. eqlist:=cons(a,eqlist)
  261. >>
  262. >> else
  263. eqlist:=list cons(1,p) % FTEM functions in the DENR of p
  264. else eqlist:=list cons(0,0)$
  265. return eqlist
  266. end$
  267. endmodule$
  268. end$