spde.red 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049
  1. module spde; % Determine Lie symmetries of partial differential eqns.
  2. % Author: Fritz Schwarz.
  3. %*******************************************************************$
  4. % $
  5. % This is the REDUCE package SPDE for determining $
  6. % Lie symmetries of partial differential equations $
  7. % Version of November 1986 $
  8. % $
  9. % $
  10. % Fritz Schwarz $
  11. % GMD Institut F1 $
  12. % Postfach 1240 $
  13. % 5205 St. Augustin $
  14. % West Germany $
  15. % $
  16. % Tel. 02241-142782 $
  17. % EARN Id. DBNGMD21.GF1002 $
  18. %*******************************************************************$
  19. create!-package('(spde),'(contrib spde));
  20. algebraic operator x,u,xi,eta,c,xi!*,eta!*$
  21. algebraic operator deq,dx,du,gl,gen,sder,rule$
  22. fluid '(depl!*);
  23. global'(pclass mm nn num!-cgen num!-dgen)$
  24. share pclass,mm,nn$
  25. lisp(pclass:=mm:=nn:=num!-cgen:=num!-dgen:=0)$
  26. lisp(operator simpsys,result,prsys,prsys!*)$
  27. fluid '(!*list kord!*)$
  28. fluid'(uhf dfsub csub czero rdep !*rational)$
  29. fluid'(list!-m list!-deq list!-pq)$
  30. %symbolic procedure prload$
  31. % begin
  32. % if not getd 'solve1 then load solve1,solvetab,quartic;
  33. % if not getd 'depend1 then load depend;
  34. % if not getd 'ratfunpri then load ratprin;
  35. % end$
  36. symbolic procedure prload; nil;
  37. %*******************************************************************$
  38. % Auxiliary RLISP procedures $
  39. %*******************************************************************$
  40. remflag('(ordp),'lose); % We must use this definition.
  41. symbolic procedure ordp(u,v)$
  42. %Modified ordering function which orders kernels with CAR parts;
  43. %DF, ETA, XI and C ahead of anything else;
  44. if null u then null v else if null v then t else
  45. if eq(u,'df) or eq(u,'eta) and not eq(v,'df)
  46. or eq(u,'xi) and not(eq(v,'df) or eq(v,'eta))
  47. or eq(u,'c) and not(eq(v,'df) or eq(v,'eta) or eq(v,'xi)) then t else
  48. if eq(u,'eta) and eq(v,'df)
  49. or eq(u,'xi) and (eq(v,'df) or eq(v,'eta))
  50. or eq(u,'c) and (eq(v,'df) or eq(v,'eta) or eq(v,'xi))
  51. or eq(v,'df) or eq(v,'eta) or eq(v,'xi) or eq(v,'c) then nil else
  52. if atom u then if atom v then
  53. if numberp u then numberp v and not u<v else
  54. if numberp v then t else orderp(u,v) else nil else
  55. if atom v then t else
  56. if car u=car v then ordp(cdr u,cdr v) else ordp(car u,car v)$
  57. symbolic procedure makeset u$
  58. if not u then nil else
  59. if member(car u,cdr u) then makeset cdr u else
  60. car u . makeset cdr u$
  61. symbolic procedure lastmem u$
  62. if cdr u then lastmem cdr u else car u$
  63. symbolic procedure xmember(u,v)$ reverse member(u,reverse v)$
  64. symbolic procedure sacar(a,u)$
  65. if atom u then nil else
  66. if eq(a,car u) and cdr u then list u else
  67. append(sacar(a,car u),sacar(a,cdr u))$
  68. symbolic procedure scar(a,u)$
  69. if atom u then nil else if a=car u then u else
  70. scar(a,car u) or scar(a,cdr u)$
  71. symbolic procedure inter(u,v);
  72. if not u then nil else
  73. if member(car u,v) then
  74. (car u) . inter(cdr u,v) else inter(cdr u,v)$
  75. symbolic procedure compl(u,v)$
  76. if not u then nil else if member(car u,v) then
  77. compl(cdr u,v) else car u . compl(cdr u,v)$
  78. symbolic procedure vlist u$
  79. %U is list of items, returns U with all integers omitted;
  80. if not u then nil else
  81. if numberp car u then vlist cdr u else (car u) . vlist cdr u$
  82. symbolic procedure delnil u$
  83. %U is list, returns U with all occurences of nil deleted;
  84. if not u then nil else
  85. if car u then (car u) . delnil cdr u else delnil cdr u$
  86. symbolic procedure prlist u$
  87. %U is list of items, returns list of all pairs in U;
  88. if not u then nil else
  89. if pairp car u then (car u) . prlist cdr u else prlist cdr u$
  90. symbolic procedure appends(u,v,w)$ append(u,append(v,w))$
  91. symbolic procedure propa(fn,u)$
  92. %FN is predicate of a single argument, U a list;
  93. %Returns T if predicate is true for all elements of U;
  94. begin scalar ind;
  95. ind:=t;
  96. while ind and u do <<ind:=apply1(fn,car u); u:=cdr u>>;
  97. return ind;
  98. end$
  99. symbolic procedure sortx(fn,u)$
  100. begin scalar v,w;
  101. while u do<<v:=maxmem(fn,u); u:=delete(v,u); w:=v . w>>;
  102. return w;
  103. end$
  104. symbolic procedure maxmem(fn,u)$
  105. %FN is function of a single argument, U a list;
  106. %Returns element of U for which FN is maximal;
  107. begin scalar v;
  108. v:=car u;
  109. foreach x in cdr u do
  110. if greaterp(apply1(fn,x),apply1(fn,v)) then v:=x;
  111. return v;
  112. end$
  113. symbolic procedure maxl u$
  114. %U is list of integers, returns largest element of U;
  115. if not u then -10000 else max(car u,maxl cdr u)$
  116. symbolic procedure suml u$
  117. %U is list of integers, returns sum of all elements;
  118. if not u then 0 else plus2(car u,suml cdr u)$
  119. symbolic procedure spde!-subsetp(u,v)$
  120. %U and V are list representing sets;
  121. %Returns T if set U is subset of V;
  122. if not u then t else
  123. member(car u,v) and spde!-subsetp(cdr u,v)$
  124. symbolic procedure product!-set2(u,v)$
  125. %U and V are lists representing sets, returns list representing;
  126. %product set of sets represented by U and V;
  127. begin scalar w;
  128. foreach x in u do foreach y in v do w:=list(x,y) . w;
  129. return w;
  130. end$
  131. symbolic procedure leqgrt(l,i,j)$
  132. i leq j and eqn(l,i) or i geq add1 j$
  133. symbolic procedure fidep u$
  134. assoc(u,depl!*) and cdr assoc(u,depl!*)$
  135. symbolic procedure mkdep u$
  136. foreach x in cdr u do depend1(car u,x,t)$
  137. symbolic procedure rmdep u$
  138. <<rmsubs(); foreach x in cdr u do depend1(car u,x,nil)>>$
  139. symbolic procedure blanks l;
  140. begin scalar u;
  141. u := '(!");
  142. for k:=1:l do u:='! . u;
  143. return compress('!" . u)
  144. end$
  145. symbolic procedure terpri2$ <<terpri(); terpri()>>$
  146. %*******************************************************************$
  147. % Auxiliary procedures for manipulating standard forms $
  148. %*******************************************************************$
  149. symbolic procedure lcf u$ not domainp u and lc u$
  150. symbolic procedure minus!-f u$
  151. %U is s.f., returns T if lnc U is negative;
  152. minusf numr simp reval u$
  153. lisp operator minus!-f$
  154. symbolic procedure lengthn u$
  155. if not u then 0 else
  156. if numberp car u then plus(sub1 car u,lengthn cdr u) else
  157. plus(1,lengthn cdr u)$
  158. symbolic procedure degreef(u,v)$
  159. %U is s.f., V kernel, returns degree of V in U;
  160. if domainp u then 0 else
  161. if mvar u=v then ldeg u else
  162. max(degreef(lc u,v),degreef(red u,v))$
  163. symbolic procedure lengthf u$
  164. %U is prefix s.f., returns printlength for U;
  165. if not u then 0 else
  166. if atom u then flatsizec u else
  167. if eqcar(u,'plus)
  168. then plus(times(3,sub1 length cdr u),lengthf cdr u) else
  169. if eqcar(u,'times) or eqcar(u,'minus)
  170. then plus(sub1 length cdr u,lengthf cdr u) else
  171. if eqcar(u,'quotient) then
  172. if !*rational then add1 add1 max(flatsizec cadr u,flatsizec caddr u)
  173. else add1 plus(flatsizec cadr u,flatsizec caddr u) else
  174. if eqcar(u,'expt) then add1 flatsizec cadr u else
  175. if eqcar(u,'dx) or eqcar(u,'du) then plus(flatsizec cadr u,4) else
  176. if eqcar(u,'xi) or eqcar(u,'eta) or eqcar(u,'c)
  177. or eqcar(u,'x) or eqcar(u,'u) then times(2,length u) else
  178. if eqcar(u,'df) then plus(4,lengthf cadr u,lengthf cddr u) else
  179. plus(lengthf car u,lengthf cdr u)$
  180. lisp operator lengthf$
  181. symbolic procedure diford u$ lengthn cddr u$
  182. symbolic procedure adiff(u,v)$
  183. %U is kernel with CAR part DF, V is kernel;
  184. %Returns U integrated with respect to V;
  185. if not member(v,u) then u else
  186. if length u=3 and member(v,u) then cadr u else
  187. if not cdr member(v,u)
  188. or not numberp cadr member(v,u) then delete(v,u) else
  189. if cadr member(v,u)=2 then
  190. append(xmember(v,u),cddr member(v,u)) else
  191. append(xmember(v,u),(sub1 cadr member(v,u)) . cddr member(v,u))$
  192. symbolic procedure sub!-int!-df u$
  193. %U is kernel with CAR part INT, returns integrated kernel if CADR;
  194. %part of U is DF and integration variable occurs as argument of DF;
  195. if eqcar(cadr u,'df) and member(lastmem u,cadr u) then
  196. adiff(cadr u,lastmem u) else u$
  197. symbolic procedure subintf u$
  198. %U is s.f., performs all integrations which may be done;
  199. %by cancellation of corresponding differentiation;
  200. begin
  201. foreach x in makeset sacar('int,u) do
  202. u:=subst(sub!-int!-df x,x,u);
  203. return numr simp prepf u;
  204. end$
  205. symbolic procedure monop u$
  206. %Returns T if u is monomial;
  207. domainp u or not red u and monop lc u$
  208. symbolic procedure solvef(u,v)$ car solve0(prepf u,v)$
  209. symbolic procedure comfacn u$ lnc ckrn u$
  210. symbolic procedure remfacn u$ quotf(u,lnc ckrn u)$
  211. %*******************************************************************$
  212. % Procedures for manipulating l.d.f.'s, U is always l.d.f. $
  213. % in this section $
  214. %*******************************************************************$
  215. symbolic procedure ldf!-mvar u$
  216. %Returns function argument of mvar U;
  217. (if eqcar(x,'df) then cadr x else x) where x=mvar u;
  218. symbolic procedure ldf!-fvar u$
  219. %Returns all function arguments occuring in U;
  220. makeset foreach x in u collect ldt!-tvar x$
  221. symbolic procedure ldf!-fvar!-part(u,v)$
  222. %V is function xi(i), eta(alpha) or c(k), returns l.d.f. of those;
  223. %terms in U with ldt-tvar x equal to V, overall factors not removed;
  224. begin scalar w;
  225. foreach x in u do if eq(ldt!-tvar x,v) then w:=x . w;
  226. return reverse w;
  227. end$
  228. symbolic procedure ldf!-dep!-var u$
  229. %Returns all variables x(i) or u(alpha) which occur as;
  230. %arguments of XI, ETA or C;
  231. begin scalar v;
  232. foreach x in u do if assoc(ldt!-tvar x,depl!*) then
  233. v:=append(cdr assoc(ldt!-tvar x,depl!*),v);
  234. return makeset v;
  235. end$
  236. symbolic procedure ldf!-pow!-var u$
  237. %Returns all variables x(i) or u(alpha) which occur as powers;
  238. begin scalar v,z;
  239. foreach x in u do v:=append(v,kernels tc x);
  240. foreach y in prlist makeset v do
  241. if eqcar(y,'x) or eqcar(y,'u) then z:=y . z;
  242. return makeset z;
  243. end$
  244. symbolic procedure ldf!-deg(u,v)$
  245. %V is kernel x(i) or u(alpha), returns degree of U in V;
  246. maxl foreach x in u collect degreef(tc x,v)$
  247. symbolic procedure ldf!-spf!-var u$
  248. %Returns all variables x(i) or u(alpha) which occur as;
  249. %arguments of any other kernel than xi, eta or c;
  250. begin scalar v,z;
  251. foreach x in u do v:=append(v,kernels tc x);
  252. foreach y in prlist makeset v do
  253. if not eqcar(y,'x) and not eqcar(y,'u) then
  254. z:=appends(sacar('x,cdr y),sacar('u,cdr y),z);
  255. return makeset z;
  256. end$
  257. symbolic procedure ldf!-all!-var u$
  258. %Returns all variables x(i) or u(alpha) which occur in U;
  259. makeset appends(ldf!-dep!-var u,ldf!-pow!-var u,ldf!-spf!-var u)$
  260. symbolic procedure ldf!-sep!-var u$
  261. %Returns all variables w.r.t. which U may be separated;
  262. compl(compl(ldf!-pow!-var u,ldf!-dep!-var u),ldf!-spf!-var u)$
  263. symbolic procedure ldf!-int!-var u$
  264. %Returns all variables w.r.t. which U may be integrated;
  265. if eqcar(mvar u,'df) then
  266. begin scalar v;
  267. v:=ldf!-all!-var u;
  268. while v and u do
  269. <<v:=compl(v,compl(ldt!-dep car u,ldt!-dfvar car u)); u:=cdr u>>;
  270. return v;
  271. end$
  272. symbolic procedure ldf!-int u$
  273. %U is l.d.f, returns U with all possible integrations performed;
  274. %or unchanged if integration is not possible;
  275. begin scalar v,w,z,test; integer nfun;
  276. a:
  277. test:=nil;
  278. w:=ldf!-int!-var u;
  279. nfun:=find!-nfun();
  280. foreach x in w do
  281. if not smember('int,z:=caadr algebraic int(lisp prepf u,x))
  282. or not smember('int,z:=subintf z) then
  283. <<v:=!*a2k list('c,nfun:=nfun+1); test:=t;
  284. mkdep(v . delete(x,ldf!-all!-var u));
  285. u:=addf(z,!*k2f v)>>;
  286. if test then go to a;
  287. return u;
  288. end$
  289. symbolic procedure ldf!-df!-diff u$
  290. %Returns list of all df-kernels which may be obtained;
  291. %from U by differentiation or nil;
  292. begin scalar dfvar,dfsub,v,w,z0,z; integer n0,nmax;
  293. v:=compl(ldf!-dep!-var u,ldf!-spf!-var u);
  294. if not v then return;
  295. w:=foreach x in v collect list(x,add1 ldf!-deg(u,x));
  296. nmax:=maxl foreach x in w collect cadr x;
  297. while (n0:=n0+1) leq nmax and not(z0:=nil) do
  298. <<foreach x in w do if cadr x geq n0 then z0:=(car x) . z0;
  299. z:=z0 . z>>;
  300. z:=reverse z;
  301. dfvar:=foreach x in car z collect list x;
  302. foreach x in cdr z do dfvar:=
  303. append(dfvar,foreach y in dfvar collect car product!-set2(x,y));
  304. foreach x in dfvar do
  305. begin scalar p,q;
  306. p:=x; q:=u;
  307. while p and q and red q do
  308. <<q:=ldf!-simp numr difff(q,car p); p:=cdr p>>;
  309. if pairp q and not red q and eqcar(mvar q,'df) then
  310. dfsub:=(mvar q) . dfsub;
  311. end;
  312. return makeset dfsub;
  313. end$
  314. symbolic procedure ldf!-sub!-var u$
  315. %Returns function w.r.t. which U may be resolved;
  316. begin scalar v,w,z;
  317. w:=ldf!-all!-var u;
  318. foreach x in u do if not v and not eqcar(z:=tvar x,'df)
  319. and monop tc x and spde!-subsetp(w,ldt!-dep x)
  320. and not smember(z,delete(x,u)) then v:=z;
  321. return v;
  322. end$
  323. symbolic procedure ldf!-simp u$
  324. %Returns l.d.f. form of U;
  325. if not u then nil else
  326. if not red u then numr simp prepf !*k2f mvar u else
  327. begin scalar v;
  328. v:=numr simp prepf u;
  329. if not domainp v then v := quotf(v,cdr comfac v);
  330. return absf v
  331. end$
  332. symbolic procedure ldf!-sep u$
  333. %Returns list of l.d.f. into which U has been separated;
  334. begin scalar v; integer k;
  335. if not(v:=ldf!-sep!-var u) then return list u;
  336. foreach x in v do u:=subst(list('ux,1,k:=k+1),x,u);
  337. return foreach x in coeff!-all(u,'ux) collect
  338. ldf!-simp numr simp prepf x;
  339. end$
  340. symbolic procedure ldf!-subf0 u$
  341. %Returns U with CZERO substituted;
  342. ldf!-simp delnil foreach x in u collect ldt!-subt0 x$
  343. %*******************************************************************$
  344. % Procedures for manipulating l.d.t.'s, U is always l.d.t. $
  345. % in this section $
  346. %*******************************************************************$
  347. symbolic procedure ldt!-tvar u$
  348. %U is l.d.t., returns function argument of tvar U;
  349. (if eqcar(x,'df) then cadr x else x) where x=tvar u$
  350. symbolic procedure ldt!-dfvar u$
  351. %U is l.d.t., returns variables w.r.t. which tvar u is derived or nil;
  352. (if eqcar(x,'df) then vlist cddr x else nil) where x=tvar u$
  353. symbolic procedure ldt!-dep u$
  354. %U is l.d.t., returns list of variables x or y which occur as;
  355. %arguments LDT-tvar u;
  356. (if x then cdr x else nil) where x=assoc(ldt!-tvar u,depl!*)$
  357. symbolic procedure ldt!-subt0 u$
  358. %U is l.d.t., returns U if LDT-tvar u is not on czero;
  359. if not member(ldt!-tvar u,czero) then u else nil$
  360. %*******************************************************************$
  361. % Procedures for constructing the determining system $
  362. %*******************************************************************$
  363. symbolic procedure cresys u$
  364. begin scalar r,v,w,lgl,lsub,depl!*!*,list!-sder;
  365. remprop('df,'kvalue); remprop('df,'klist);
  366. remprop('c,'kvalue); remprop('c,'klist);
  367. prload();
  368. rmsubs();
  369. depl!*:=nil;
  370. if car u then
  371. list!-deq:=foreach x in u collect assoc(x,get(car x,'kvalue)) else
  372. list!-deq:=get('deq,'kvalue);
  373. if eqn(length list!-deq,1) then
  374. begin scalar p;
  375. p:=maxmem(function length,makeset sacar('u,list!-deq));
  376. p:=mk!*sq !*k2q p;
  377. list!-sder:=list list(list('sder, cadaar list!-deq),p);
  378. end else if car u then
  379. list!-sder:=foreach x in list!-deq collect
  380. assoc(list('sder,cadar x),get('sder,'kvalue)) else
  381. list!-sder:=get('sder,'kvalue);
  382. if not list!-deq then rerror(spde,1,
  383. "Differential equations not defined");
  384. if not list!-sder then rerror(spde,2,
  385. "Substitutions for derivatives not defined");
  386. mm:=find!-m list!-deq; nn:=find!-n list!-deq;
  387. list!-m:=
  388. makeset foreach x in sacar('u,list!-deq) collect cadr x;
  389. for k:=1:nn do<<w:=!*a2k list('xi,k) . w; v:=!*a2k list('x,k) . v>>;
  390. for k:=1:mm do if member(k,list!-m) then
  391. <<w:=!*a2k list('eta,k) . w; v:=!*a2k list('u,k) . v>>;
  392. for k:=1:nn do r:=(!*a2k list('dx,k)) . r;
  393. for k:=1:mm do r:=(!*a2k list('du,k)) . r;
  394. for k:=1:mm do depl!*!*:=(!*a2k list('eta,k) . v) . depl!*!*;
  395. for k:=1:nn do depl!*!*:=(!*a2k list('xi,k) . v) . depl!*!*;
  396. depl!*:=depl!*!*;
  397. kord!*:=reverse r;
  398. foreach x in list!-sder do
  399. lsub:=((mvar caadr cadr x) . prepsq caar solvef(caadr cadr assoc
  400. (list('deq,cadar x),list!-deq),mvar caadr cadr x)) . lsub;
  401. foreach x in list!-deq do
  402. begin scalar s,z,lx,lu;
  403. z:=caadr cadr x;
  404. lx:=makeset sacar('x,z);
  405. lu:=makeset sacar('u,z);
  406. foreach y in lx do s:=addf(s,
  407. multf(!*k2f !*a2k list('xi,cadr y),numr simp prepsq difff(z,y)));
  408. foreach y in lu do if length y=2 then
  409. s:=addf(s,multf
  410. (!*k2f !*a2k list('eta,cadr y),numr simp prepsq difff(z,y))) else
  411. s:=addf(s, multf(numr zeta!* cdr y,numr simp prepsq difff(z,y)));
  412. s:=numr subf(s,lsub);
  413. s:=numr subf(s,lsub);
  414. lgl:=append(coeff!-all(s,'u),lgl);
  415. end;
  416. uhf:=list(makeset lgl,foreach x in reverse w collect !*k2q x);
  417. end$
  418. lisp rlistat'(cresys)$
  419. symbolic procedure totder(u,i)$
  420. begin scalar z,v,w;
  421. v:=car difff(u,!*a2k list('x,i));
  422. z:=makeset sacar('u,u);
  423. for k:=1:mm do if member(k,list!-m) then
  424. z:=(!*a2k list('u,k)) . z;
  425. foreach x in makeset z do w:=addf(w,
  426. multf(!*k2f !*a2k append(x,list i),car difff(u,x)));
  427. return numr simp prepf addf(v,w);
  428. end$
  429. symbolic procedure zeta!* u$
  430. if not get('deq,'kvalue) and (eqn(mm,0) or eqn(nn,0)) then
  431. rerror(spde,3,"Number of variables not defined") else
  432. if length u geq 3 then
  433. begin scalar v,w;
  434. prload();
  435. if eqn(nn,0) then nn:=find!-n list!-deq;
  436. v:=totder(numr zeta!* reverse cdr reverse u,car reverse u);
  437. for s:=1:nn do w:=addf(w,
  438. multf(!*k2f !*a2k('u . append(reverse cdr reverse u,list s)),
  439. totder(!*k2f !*a2k list('xi,s),car reverse u)));
  440. return simp prepsq(addf(v,negf w) ./ 1);
  441. end else
  442. begin scalar v,w;
  443. prload();
  444. if eqn(nn,0) then
  445. <<nn :=find!-n list!-deq; mm:=find!-m list!-deq>> else
  446. begin scalar p,z;
  447. for k:=1:mm do z:=cons(k,z);
  448. for k:=1:nn do p:=(!*a2k list('x,k)) . p;
  449. for k:=1:mm do p:=(!*a2k list('u,k)) . p;
  450. for k:=1:nn do mkdep((!*a2k list('xi,k)) . p);
  451. for k:=1:mm do mkdep((!*a2k list('eta,k)) . p);
  452. list!-m:=z;
  453. end;
  454. v:=totder(!*k2f !*a2k list('eta,car u),cadr u);
  455. for s:=1:nn do w:=addf(w,
  456. multf(!*k2f !*a2k list('u,car u,s),
  457. totder(!*k2f !*a2k list('xi,s),car reverse u)));
  458. return simp prepsq(addf(v,negf w) ./ 1);
  459. end$
  460. symbolic procedure simpu u$
  461. !*p2q mksp(('u . (car u . reverse ordn cdr u)),1)$
  462. put('u,'simpfn,'simpu)$
  463. put('zeta,'simpfn,'zeta!*)$
  464. symbolic procedure coeff!-all(u,v)$
  465. begin scalar z;
  466. list!-pq:=nil;
  467. splitrec(u,v,1,nil);
  468. foreach x in list!-pq do
  469. z:=(ldf!-simp numr simp prepf cdr x) . z;
  470. return makeset z;
  471. end$
  472. symbolic procedure splitrec(u,v,p,q)$
  473. if domainp u then
  474. begin scalar y;
  475. p:=multf(u,p);
  476. if y:=assoc(q,list!-pq) then
  477. rplacd(y,addf(cdr y,p)) else list!-pq:=(q . p) . list!-pq;
  478. end else
  479. begin
  480. if eqcar(mvar u,v) and length mvar u greaterp 2
  481. then splitrec(lc u,v,p,(lpow u) . q)
  482. else splitrec(lc u,v,!*t2f(lpow(u) .* p),q);
  483. if red u then splitrec(red u,v,p,q);
  484. end$
  485. symbolic procedure find!-m u$
  486. maxl makeset foreach x in sacar('u,u) collect cadr x$
  487. symbolic procedure find!-n u$
  488. begin scalar vx,vu,wx,wu;
  489. vx:=makeset sacar('x,u);
  490. vu:=makeset sacar('u,u);
  491. foreach x in vx do wx:=(cadr x) . wx;
  492. foreach x in vu do if length x geq 3 then
  493. wu:=append(cddr x,wu);
  494. return max(maxl wx,maxl wu);
  495. end$
  496. %*******************************************************************$
  497. % Procedures for solving the determining system $
  498. %*******************************************************************$
  499. symbolic procedure rule0$
  500. %Searches for equations of the form C(I)=0 and stores them on CZERO;
  501. if uhf then foreach x in car uhf do
  502. if not red x and not eqcar(mvar x,'df)
  503. then czero:=(mvar x) . czero$
  504. symbolic procedure rule1$
  505. %Searches for equations of the form DF(function,variable)=0;
  506. %and stores it on the list RDEP;
  507. if uhf and car uhf then
  508. begin scalar dfsub;
  509. foreach x in car uhf do
  510. if not red x and eqcar(mvar x,'df) and eqn(diford mvar x,1)
  511. then rdep:=(mvar x) . rdep;
  512. if rdep then return t;
  513. end$
  514. symbolic procedure rule1!-diff$
  515. %Searches for equations of the form DF(function,variable)=0;
  516. %which may be obtained by a single differentiation and stores it on;
  517. %the list RDEP;
  518. if uhf and car uhf then
  519. begin scalar u,v,z;
  520. foreach x in car uhf do if(z:=ldf!-df!-diff x) then
  521. u:=append(z,u);
  522. foreach x in u do if eqn(diford x,1) then v:=x . v;
  523. rdep:=makeset v;
  524. if rdep then return t;
  525. end$
  526. symbolic procedure rulec l$
  527. %Searches for equations of length L which may be solved for a;
  528. %function and stores the corresponding rules on CSUB;
  529. if uhf and car uhf then
  530. begin scalar v;
  531. foreach u in car uhf do if leqgrt(length u,l,4)
  532. and (v:=ldf!-sub!-var u) and not smember(v,csub)
  533. and not inter(foreach x in csub collect car x,ldf!-fvar u)
  534. then csub:=(v . prepsq caar solvef(u,v)) . csub;
  535. if csub then return t;
  536. end$
  537. symbolic procedure ruledf l$
  538. %Searches for equations of the form DF(function,derivative list)=0;
  539. %the derivative beeing of order L and stores the resulting;
  540. %substitution polynomial on CSUB;
  541. if uhf and car uhf then
  542. begin scalar dfsub;
  543. foreach x in car uhf do
  544. if not red x and eqcar(mvar x,'df) and eqn(diford mvar x,l)
  545. and not smember(ldf!-mvar x,dfsub) then dfsub:=(mvar x) . dfsub;
  546. csub:=foreach x in dfsub collect(cadr x) . crepol x;
  547. if csub then return t;
  548. end$
  549. symbolic procedure ruledf!-diff l$
  550. %Searches for all equations of the form;
  551. %DF(function,derivative list)=0 which may be obtained by;
  552. %differentiation, picks out those of order L and stores;
  553. %the corresponding substitution polynomial on CSUB;
  554. if uhf and car uhf then
  555. begin scalar v,dfsub;
  556. foreach u in car uhf do v:=append(v,ldf!-df!-diff u);
  557. if not(v:=makeset v) then return;
  558. foreach x in v do if eqn(diford x,l) then dfsub:=x . dfsub;
  559. if not dfsub then return;
  560. csub:=((cadar dfsub) . crepol car dfsub) . csub;
  561. if csub then return t;
  562. end$
  563. symbolic procedure rule!-int l$
  564. %Searches for an equation of length L which may be solved for a;
  565. %function after beeing integrated and stores the corresponding;
  566. %rule on CSUB;
  567. if uhf and car uhf then
  568. begin scalar v,w;
  569. foreach u in car uhf do if not csub and leqgrt(length u,l,4)
  570. and (v:=ldf!-sub!-var(w:=ldf!-int u))
  571. then csub:=list(v . prepsq caar solvef(w,v));
  572. if csub then return t;
  573. end$
  574. symbolic procedure simpsys0$
  575. %Removes variable which are stored on list CZERO;
  576. begin scalar u,v;
  577. if pclass=2 then<<write"Entering SIMPSYS0"; terpri2()>>;
  578. u:=delnil foreach x in car uhf collect ldf!-subf0 x;
  579. v:=foreach x in cadr uhf collect ldf!-subf0 numr x ./ denr x;
  580. uhf:=list(makeset u,v);
  581. if pclass=1 then
  582. begin
  583. terpri2();
  584. if eqn(length czero,1) then
  585. write"Substitution" else write"Substitutions";
  586. terpri();
  587. foreach x in czero do
  588. algebraic write (lisp aeval x),":=0";
  589. terpri();
  590. end;
  591. if pclass=2 then<<write"CZERO:="; prettyprint czero; terpri()>>;
  592. czero:=nil;
  593. if pclass=2 then<<write"Leaving SIMPSYS0"; terpri2()>>;
  594. end$
  595. symbolic procedure simpsys!-rdep$
  596. %Removes dependencies which are stored on list RDEP;
  597. begin scalar u,v;
  598. if pclass=2 then<<write"Entering SIMPSYS!-RDEP"; terpri2()>>;
  599. foreach x in rdep do rmdep cdr x;
  600. u:=makeset delnil foreach x in car uhf collect ldf!-simp x;
  601. v:=foreach x in cadr uhf collect simp prepsq x;
  602. uhf:=list(u,v);
  603. if pclass=1 then
  604. begin
  605. terpri();
  606. write"Dependencies removed"; terpri2();
  607. foreach x in rdep do
  608. <<maprin cadr x; prin2!*" independent of ";
  609. maprin caddr x; terpri!* t;>>;
  610. terpri();
  611. end;
  612. if pclass=2 then<<write"RDEP:='"; prettyprint rdep; terpri()>>;
  613. if pclass=2 then<<write"Leaving SIMPSYS!-RDEP"; terpri2()>>;
  614. end$
  615. symbolic procedure simpsys!-sep$
  616. %Performs all possible separations;
  617. if uhf and car uhf then
  618. begin scalar u,v,test;
  619. if pclass=2 then<<write"Entering SIMPSYS!-SEP"; terpri2()>>;
  620. foreach x in car uhf do
  621. if eqn(length(v:=ldf!-sep x),1) then u:=x . u else
  622. begin
  623. u:=append(v,u);
  624. if pclass=1 or pclass=2 then
  625. begin scalar z; integer l;
  626. terpri();
  627. l:=length car uhf-length member(x,car uhf)+1;
  628. write"Equation ",l," separated into the terms";
  629. terpri();
  630. if pclass=1 then for k:=1:length v do
  631. begin
  632. z:=prepf nth(v,k);
  633. !*list := lengthf z geq 50;
  634. algebraic write"Term ",k," ",z;
  635. end;
  636. if pclass=2 then foreach y in v do prettyprint y;
  637. end;
  638. test:=t;
  639. end;
  640. !*list := nil;
  641. if test then uhf:=list(reverse makeset u,cadr uhf);
  642. if pclass=2 then<<write"Leaving SIMPSYS!-SEP"; terpri2()>>;
  643. end$
  644. symbolic procedure simpsys!-sub$
  645. %Performs all substitutions which are stored on CSUB;
  646. if uhf and car uhf then
  647. begin scalar u,v;
  648. if pclass=2 then<<write"Entering SIMPSYS!-SUB"; terpri2()>>;
  649. if pclass=1 then prrule csub;
  650. if pclass=2 then<<write"CSUB:='"; prettyprint csub; terpri()>>;
  651. u:=makeset delnil foreach x in car uhf collect
  652. ldf!-simp numr subf(x,csub);
  653. v:=foreach x in cadr uhf collect subsq(x,csub);
  654. uhf:=list(u,v);
  655. csub:=nil;
  656. if pclass=2 then<<write"Leaving SIMPSYS!-SUB"; terpri2()>>;
  657. end$
  658. symbolic procedure simpsys$
  659. if not uhf then
  660. rerror(spde,4,"The determining system is not defined") else
  661. if not car uhf then
  662. rerror(spde,5,"The determining system completely solved") else
  663. begin scalar u,v; integer nfun;
  664. prload();
  665. u:=makeset delnil foreach x in car uhf collect ldf!-simp x;
  666. v:=foreach x in cadr uhf collect simp prepsq x;
  667. uhf:=list(u,v);
  668. mark0:
  669. if pclass=1 then<<prsys!*"Entering main loop">> else
  670. if pclass=2 then prtlist"Entering main loop";
  671. czero:=csub:=rdep:=nil;
  672. simpsys!-sep();
  673. rule0();
  674. if czero then<<simpsys0(); go to mark0>>;
  675. if rule1() or rule1!-diff() then<<simpsys!-rdep(); go to mark0>>;
  676. if ruledf 2 or rulec 2 or rule!-int 2 or ruledf!-diff 2
  677. or ruledf 3 or rulec 3 or rule!-int 3 or ruledf!-diff 3
  678. or ruledf 4 or rulec 4 or rule!-int 4 or ruledf!-diff 4
  679. or ruledf 5 or rulec 5 or rule!-int 5 or ruledf!-diff 5
  680. then <<simpsys!-sub(); go to mark0>>;
  681. if car uhf then
  682. <<write"Determining system is not completely solved";
  683. terpri2(); prsys!*"The remaining equations are";
  684. if not zerop(nfun:=find!-nfun()) then
  685. write"Number of functions is ",nfun>>;
  686. end$
  687. symbolic procedure crepol u$
  688. begin scalar l1,f; integer pow,nfun;
  689. nfun:=find!-nfun();
  690. l1:=cdr assoc(car(u:=cdr u),depl!*);
  691. while (u:=cdr u) do
  692. begin scalar v;
  693. v:=car u;
  694. if length u=1 or not numberp cadr u then pow:=1 else
  695. <<pow:=cadr u; u:=delete(pow,u);>>;
  696. for k:=1:pow do
  697. begin scalar w;
  698. w:=!*a2k list('c,nfun:=nfun+1);
  699. mkdep(w . delete(v,l1));
  700. if k=1 then f:=w . f;
  701. if k=2 then f:=list('times,w,v) . f;
  702. if k geq 3 then
  703. f:=list('times,w,list('expt,v,k-1)) . f;
  704. end;
  705. end;
  706. return append('(plus),f);
  707. end$
  708. %*************************************************************$
  709. % Procedures for analysing the result $
  710. %*************************************************************$
  711. symbolic procedure cpar u$
  712. begin scalar v;
  713. v:=makeset appends(sacar('xi,u),sacar('eta,u),sacar('c,u));
  714. foreach x in v do if not assoc(x,depl!*) then v:=delete(x,v);
  715. return v;
  716. end$
  717. symbolic procedure makeset!-c!-x u$
  718. if not u then nil else
  719. if member!-c!-x(car u,cdr u) then makeset!-c!-x cdr u else
  720. car u . makeset!-c!-x cdr u$
  721. symbolic procedure member!-c!-x(u,v)$
  722. if not v then nil else
  723. if equal!-c!-x(u,car v) then v else member!-c!-x(u,cdr v)$
  724. symbolic procedure equal!-c!-x(u,v)$
  725. begin scalar p,q;
  726. p:=scar('c,u) or scar('xi,u) or scar('eta,u);
  727. q:=scar('c,v) or scar('xi,v) or scar('eta,v);
  728. return equal(subst('cxx,p,u),subst('cxx,q,v));
  729. end$
  730. symbolic procedure numgen$ length get('gen,'kvalue)$
  731. symbolic operator numgen$
  732. symbolic procedure gengen$
  733. begin scalar u,z,cgen,dgen; integer ngen;
  734. remprop('gen,'kvalue); remprop('gen,'klist);
  735. foreach x in cadr uhf do u:=append(ldf!-fvar numr x,u);
  736. foreach x in makeset u do
  737. begin scalar v,w;
  738. w:=nil ./ 1;
  739. if assoc(x,depl!*) then
  740. v:=foreach y in cadr uhf collect
  741. simp prepsq(ldf!-fvar!-part(numr y,x) ./denr y) else
  742. v:=foreach y in cadr uhf collect
  743. simp prepsq((lcf ldf!-fvar!-part(numr y,x)) ./denr y);
  744. for k:=1:nn do if numr nth(v,k) then
  745. w:=addsq(multsq(nth(v,k),!*k2q !*a2k list('dx,k)),w);
  746. for k:=1:mm do if numr nth(v,nn+k) then
  747. w:=addsq(multsq(nth(v,nn+k),!*k2q !*a2k list('du,k)),w);
  748. if assoc(x,depl!*) then
  749. cgen:=(absf remfacn numr simp prepf numr w) . cgen else
  750. dgen:=(absf remfacn numr simp prepf numr w) . dgen;
  751. end;
  752. dgen:=makeset dgen; cgen:=makeset!-c!-x cgen;
  753. num!-dgen:=length dgen; num!-cgen:=length cgen;
  754. for k:=1:nn do if member(z:=!*k2f !*a2k list('dx,k),dgen) then
  755. <<setk(list('gen,ngen:=add1 ngen),prepf z); dgen:=delete(z,dgen)>>;
  756. for k:=1:mm do if member(z:=!*k2f !*a2k list('du,k),dgen) then
  757. <<setk(list('gen,ngen:=add1 ngen),prepf z); dgen:=delete(z,dgen)>>;
  758. dgen:=sortx(function length,dgen);
  759. foreach x in dgen do setk(list('gen,ngen:=add1 ngen),prepf x);
  760. cgen:=sortx(function length,cgen);
  761. foreach x in cgen do setk(list('gen,ngen:=add1 ngen),prepf x);
  762. end$
  763. symbolic operator gengen$
  764. algebraic procedure comm(a,b)$
  765. begin scalar z;
  766. if (lisp length list!-deq)=0 then
  767. <<write"Differential equations not defined"; return nil>>;
  768. z:= (for k:=1:nn sum df(a,dx k)*df(b,x k)-df(b,dx k)*df(a,x k))
  769. +(for k:=1:mm sum df(a,du k)*df(b,u k)-df(b,du k)*df(a,u k))$
  770. return z;
  771. end$
  772. algebraic procedure result$
  773. begin integer l;
  774. if (l:=lisp length list!-deq)=1 then
  775. write"The differential equation" else
  776. write"The differential equations";
  777. for j:=1:l do
  778. begin scalar z; integer i,k;
  779. lisp(z:=car cadadr nth(list!-deq,j));
  780. i:=lisp cadar nth(list!-deq,j);
  781. k:=lisp lengthf prepf z;
  782. symbolic(!*list := k>40);
  783. write"DEQ(",i,"):=",lisp prepf z;
  784. end;
  785. !*list := nil;
  786. if (lisp length car uhf) neq 0 then
  787. prsys!*"The determining system is not completely solved" else
  788. <<lisp gengen(); prgen(); comm!-tab()>>;
  789. end$
  790. %*************************************************************$
  791. % Procedures for displaying the output $
  792. %*************************************************************$
  793. symbolic procedure prsys!* u$
  794. if uhf and car uhf then
  795. <<terpri(); write u; terpri(); prsys(); terpri()>>$
  796. symbolic procedure prsys$
  797. begin scalar v;
  798. terpri();
  799. remprop('gl,'kvalue); remprop('gl,'klist);
  800. for k:=1:length car uhf do
  801. begin scalar z; integer l;
  802. z:=prepf nth(car uhf,k);
  803. l:=lengthf prepf nth(car uhf,k);
  804. !*list := l>50;
  805. algebraic write"GL(",k,"):=",z;
  806. setk(list('gl,k),z);
  807. end;
  808. terpri2();
  809. write"The remaining dependencies";
  810. terpri2();
  811. v:=makeset
  812. appends(sacar('xi,car uhf),sacar('eta,car uhf),sacar('c,car uhf));
  813. foreach x in v do write!-dep x;
  814. !*list := nil;
  815. end$
  816. symbolic procedure prrule u$
  817. begin
  818. terpri2();
  819. if eqn(length u,1) then
  820. write"Substitution" else write"Substitutions";
  821. terpri2();
  822. foreach x in u do
  823. <<maprin car x; prin2!*" = "; maprin cdr x; terpri!* t;>>;
  824. terpri();
  825. foreach x in u do foreach y in sacar('c,cdr x) do write!-dep y;
  826. end$
  827. symbolic procedure prtlist u$
  828. <<write u; terpri2(); write"DEPL!*:='"; prettyprint depl!*;
  829. write"UHF:='"; prettyprint uhf>>$
  830. symbolic procedure write!-df!-sub$
  831. if get('df,'kvalue) then
  832. begin scalar w;
  833. w:=get('df,'kvalue);
  834. remprop('df,'kvalue);
  835. terpri();
  836. if length w=1 then write"Constraint" else write"Constraints";
  837. terpri2();
  838. foreach x in w do
  839. begin scalar u,v;
  840. u:=car x;
  841. v:=cadadr x;
  842. algebraic write lisp u,":=",lisp prepsq v;
  843. terpri2();
  844. end;
  845. put('df,'kvalue,w);
  846. end$
  847. algebraic procedure prgen$
  848. begin scalar lcpar;
  849. for k:=1:nn do <<order dx k; factor dx k>>;
  850. for k:=1:mm do factor du k$
  851. lisp(lcpar:=cpar get('gen,'kvalue));
  852. write"The symmetry generators are";
  853. for k:=1:numgen() do
  854. if (lisp lengthf reval list('gen,k)) leq 60 then
  855. <<symbolic(!*list := nil); write"GEN(",k,"):=",gen k>> else
  856. begin scalar z; integer r,s,nt; operator gen!*;
  857. nt:=lisp length(z:=numr simp reval list('gen,k));
  858. r:=lisp maxl foreach x in z collect abs comfacn list x;
  859. if r=1 then r:=0 else r:=lisp flatsizec r;
  860. for l:=1:nt do gen!* l:=lisp prepf list nth(z,l);
  861. for l:=1:nt do
  862. begin
  863. symbolic(!*list := lengthf prepf tc nth(z,l) geq 56);
  864. s:=lisp abs comfacn list nth(z,l);
  865. if r=0 then s:=0 else
  866. if s=1 then s:=-1 else s:=lisp flatsizec s;
  867. if l=1 then write"GEN(",k,"):=",lisp blanks(r-s+1),gen!* 1 else
  868. if minus!-f gen!* l then
  869. write lisp blanks(r-s+6),gen!* l else
  870. write lisp blanks(r-s+6)," + ",gen!* l;
  871. end;
  872. clear gen!*;
  873. symbolic(!*list := nil);
  874. end;
  875. if (lisp length lcpar) neq 0 then
  876. <<write"The remaining dependencies"; lisp terpri()>>;
  877. for k:=1:(lisp length lcpar) do
  878. <<lisp write!-dep nth(lcpar,k);>>;
  879. if (lisp length lcpar) neq 0 then lisp terpri();
  880. lisp write!-df!-sub();
  881. end$
  882. algebraic procedure comm!-tab$
  883. if (lisp num!-dgen) geq 2 then
  884. begin integer nd; scalar v;
  885. nd:=lisp num!-dgen;
  886. write"The non-vanishing commutators of the finite subgroup";
  887. for i:=1:nd-1 do for j:=(i+1):nd do
  888. if(v:=comm(gen i,gen j)) neq 0 then
  889. if (lisp lengthf reval v) leq 60 then
  890. <<symbolic(!*list := nil); write"COMM(",i,",",j,"):= ",v>> else
  891. begin integer r,s,nt; scalar z; operator gen!*;
  892. nt:=lisp length(z:=numr simp reval v);
  893. r:=lisp maxl foreach x in z collect abs comfacn list x;
  894. if r=1 then r:=0 else r:=lisp flatsizec r;
  895. for i:=1:nt do gen!* i:=lisp prepf list nth(z,i);
  896. for l:=1:nt do
  897. begin
  898. symbolic(!*list := lengthf reval list('gen!*,l) geq 63);
  899. s:=lisp abs comfacn list nth(z,l);
  900. if r=0 then s:=0 else
  901. if s=1 then s:=-1 else s:=lisp flatsizec s;
  902. if l=1 then
  903. write"COMM(",i,",",j,"):=",lisp blanks(r-s+1),gen!* 1 else
  904. if minus!-f gen!* l then
  905. write lisp blanks(r-s+9),gen!* l else
  906. write lisp blanks(r-s+9)," + ",gen!* l;
  907. end;
  908. clear gen!*;
  909. end;
  910. symbolic(!*list := nil);
  911. end$
  912. symbolic procedure write!-dep u$
  913. if assoc(reval u,depl!*) then
  914. begin scalar v;
  915. v:=cdr assoc(u,depl!*);
  916. write car u,"(",cadr u,") depends on ";
  917. write caar v,"(",cadar v,")";
  918. foreach x in cdr v do write",",car x,"(",cadr x,")";
  919. terpri2();
  920. end$
  921. symbolic operator write!-dep$
  922. symbolic procedure find!-nfun$
  923. if not get('c,'klist) then 0 else
  924. maxl makeset foreach x in get('c,'klist) collect cadar x$
  925. endmodule;
  926. end;