liepde.red 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462
  1. %********************************************************************
  2. % *
  3. % The program LIEPDE for computing point-, contact- and higher *
  4. % order symmetries of individual ODEs/PDEs or systems of ODEs/PDEs *
  5. % *
  6. % Author: Thomas Wolf *
  7. % Date: 20.July 1996 *
  8. % *
  9. % For details of how to use LIEPDE see the file LIEPDE.TXT or the *
  10. % header of the procedure LIEPDE below. *
  11. % *
  12. %********************************************************************
  13. !#if (equal version!* "REDUCE Development Version")
  14. create!-package('(liepde), nil);
  15. !#endif
  16. symbolic fluid '(print_ logoprint_ nfct_ fname_ adjust_fnc proc_list_
  17. prelim_ individual_ prolong_order !*batch_mode)$
  18. lisp << !*batch_mode:=t$ prelim_:=nil$
  19. individual_:=nil$ prolong_order:=0 >>$
  20. symbolic procedure diffdeg(p,v)$
  21. % liefert Ordnung der Ableitung von p nach v$
  22. % p Liste Varible+Ordnung der Ableitung, v Variable (Atom)
  23. if null p then 0 % alle Variable bearbeitet ?
  24. else if car p=v then % v naechste Variable ?
  25. if cdr p then
  26. if numberp(cadr p) then cadr p % folgt eine Zahl ?
  27. else 1
  28. else 1
  29. else diffdeg(cdr p,v)$ % weitersuchen
  30. symbolic procedure ldiff1(l,v)$
  31. % liefert Liste der Ordnungen der Ableitungen nach den Variablen aus v
  32. % l Liste (Variable + Ordnung)$ v Liste der Variablen
  33. if null v then nil % alle Variable abgearbeitet ?
  34. else cons(diffdeg(l,car v),ldiff1(l,cdr v))$
  35. % Ordnung der Ableitung nach
  36. % erster Variable anhaengen
  37. %----------------------------
  38. algebraic procedure equ_to_expr(a)$
  39. % converts an equation into an expression
  40. begin scalar lde;
  41. return
  42. if a=nil then a else
  43. <<lisp(lde:=reval algebraic a);
  44. if lisp(atom lde) then a else num
  45. if lisp(car lde = 'EQUAL) then lhs a - rhs a
  46. else a
  47. >>
  48. end$ % of equ_to_expr
  49. %********************************************************************
  50. module pdesymmetry$
  51. %********************************************************************
  52. % Routines for finding Symmetries of single or systems of ODEs/PDEs
  53. % Author: Thomas Wolf
  54. % July 1996
  55. symbolic operator totdeg$
  56. symbolic procedure totdeg(p,f)$
  57. % Ordnung (total) der hoechsten Ableitung von f im Ausdruck p
  58. eval(cons('PLUS,ldiff1(car ldifftot(reval p,reval f),fctargs reval f)))$
  59. symbolic procedure diffreltot(p,q,v)$
  60. % liefert komplizierteren Differentialausdruck$
  61. if diffreltotp(p,q,v) then q
  62. else p$
  63. symbolic procedure diffreltotp(p,q,v)$
  64. % liefert t, falls p einfacherer Differentialausdruck, sonst nil
  65. % p, q Paare (liste.power), v Liste der Variablen
  66. % liste Liste aus Var. und Ordn. der Ableit. in Diff.ausdr.,
  67. % power Potenz des Differentialausdrucks
  68. begin scalar n,m$
  69. m:=eval(cons('PLUS,ldiff1(car p,v)))$
  70. n:=eval(cons('PLUS,ldiff1(car q,v)))$
  71. return
  72. if m<n then t
  73. else if n<m then nil
  74. else diffrelp(p,q,v)$
  75. end$
  76. symbolic procedure ldifftot(p,f)$
  77. % leading derivative total degree ordering
  78. % liefert Liste der Variablen + Ordnungen mit Potenz
  79. % p Ausdruck in LISP - Notation, f Funktion
  80. ldifftot1(p,f,fctargs f)$
  81. symbolic procedure ldifftot1(p,f,vl)$
  82. % liefert Liste der Variablen + Ordnungen mit Potenz
  83. % p Ausdruck in LISP - Notation, f Funktion, lv Variablenliste
  84. begin scalar a$
  85. a:=cons(nil,0)$
  86. if not atom p then
  87. if member(car p,list('EXPT,'PLUS,'MINUS,'TIMES,
  88. 'QUOTIENT,'DF,'EQUAL)) then
  89. % erlaubte Funktionen
  90. <<if (car p='PLUS) or (car p='TIMES) or (car p='QUOTIENT)
  91. or (car p='EQUAL) then
  92. <<p:=cdr p$
  93. while p do
  94. <<a:=diffreltot(ldifftot1(car p,f,vl),a,vl)$
  95. p:=cdr p>> >>
  96. else if car p='MINUS then
  97. a:=ldifftot1(cadr p,f,vl)
  98. else if car p='EXPT then % Exponent
  99. if numberp caddr p then
  100. <<a:=ldifftot1(cadr p,f,vl)$
  101. a:=cons(car a,times(caddr p,cdr a))>>
  102. else a:=cons(nil,0)
  103. % Poetenz aus Basis wird mit
  104. % Potenz multipliziert
  105. else if car p='DF then % Ableitung
  106. if cadr p=f then a:=cons(cddr p,1)
  107. % f wird differenziert?
  108. else a:=cons(nil,0)>> % sonst Konstante bzgl. f
  109. else if p=f then a:=cons(nil,1)
  110. % Funktion selbst
  111. else a:=cons(nil,0) % alle uebrigen Fkt. werden
  112. else if p=f then a:=cons(nil,1)$ % wie Konstante behandelt
  113. return a
  114. end$
  115. %---------------------
  116. % Bei jedem totdf2-Aufruf pruefen, ob evtl. kuerzere dylist reicht
  117. % evtl die combidiff-Kette und combi nicht mit in dylist, sond. erst in
  118. % prolong jedesmal frisch generieren.
  119. %symbolic operator desort$
  120. algebraic procedure nextdy(revx,xlist,dy)$
  121. % generates all first order derivatives of lhs dy
  122. % revx = reverse xlist; xlist is the list of variables;
  123. % dy the old derivative
  124. begin
  125. scalar x,n,ldy,rdy,ldyx,sublist;
  126. x:=first revx; revx:=rest revx;
  127. sublist:={};
  128. ldy:=lhs dy;
  129. rdy:=rhs dy;
  130. while lisp(not member(prepsq simp!* algebraic x,
  131. prepsq simp!* algebraic ldy))
  132. and (revx neq {}) do
  133. <<x:=first revx; revx:=rest revx>>;
  134. n:=length xlist;
  135. if revx neq {} then % dy is not the function itself
  136. while first xlist neq x do xlist:=rest xlist;
  137. xlist:=reverse xlist;
  138. % New higher derivatives
  139. while xlist neq {} do
  140. <<x:=first xlist;
  141. ldyx:=df(ldy,x);
  142. sublist:=cons((lisp reval algebraic ldyx)=
  143. mkid(mkid(rdy,!`),n), sublist);
  144. n:=n-1;
  145. xlist:=rest xlist
  146. >>;
  147. return sublist
  148. end$
  149. %---------------------
  150. algebraic procedure subdif1(xlist,ylist,ordr)$
  151. % A list of lists of derivatives of one order for all functions
  152. begin
  153. scalar allsub,revx,i,el,oldsub,newsub;
  154. revx:=reverse xlist;
  155. allsub:={};
  156. oldsub:= for each y in ylist collect y=y;
  157. for i:=1:ordr do % i is the order of next substitutions
  158. <<oldsub:=for each el in oldsub join nextdy(revx,xlist,el);
  159. allsub:=cons(oldsub,allsub)
  160. >>;
  161. return allsub
  162. end$
  163. %---------------------
  164. symbolic procedure combidif(s)$
  165. % extracts the list of derivatives from s: % u`1`1`2 --> (u, 1, 1, 2)
  166. begin scalar temp,ans,no,n1;
  167. s:=reval s; % to guarantee s is in true prefix form
  168. temp:=reverse explode s;
  169. while not null temp do
  170. <<n1:=<<no:=nil;
  171. while (not null temp) and (not eqcar(temp,'!`)) do
  172. <<no:=car temp . no;temp:=cdr temp>>;
  173. compress no
  174. >>;
  175. if (not fixp n1) then n1:=intern n1;
  176. ans:=n1 . ans;
  177. if eqcar(temp,'!`) then <<temp:=cdr temp; temp:=cdr temp>>;
  178. >>;
  179. return ans
  180. end$
  181. %---------------------
  182. symbolic procedure comparedif1(u1l,u2l)$
  183. % u1l, u2l are lists of indicees of differentiation variables
  184. % checks whether u2l has more or at least equally many 1's, 2's, ...
  185. % contained as u1l.
  186. % returns a list of 1's, 2's, ... which are in excess in u2l
  187. % compared with u1l. The returned value is 0 if both are identical
  188. begin
  189. scalar ul;
  190. if u2l=nil then if u1l neq nil then return nil
  191. else return 0
  192. else if u1l=nil then return u2l
  193. else % both are non-nil
  194. if car u1l < car u2l then return nil else
  195. if car u1l = car u2l then return comparedif1(cdr u1l,cdr u2l) else <<
  196. ul:=comparedif1(u1l,cdr u2l);
  197. return if not ul then nil else
  198. if zerop ul then list car u2l else
  199. cons(car u2l,ul)
  200. >>
  201. end$ % of comparedif1
  202. %---------------------
  203. symbolic procedure comparedif2(u1,u1list,du2)$
  204. % checks whether du2 is a derivative of u1 differentiated
  205. % wrt. u1list
  206. begin
  207. scalar u2l;
  208. u2l:=combidif(du2)$ % u2l=(u2, 1, 1, ..)
  209. if car u2l neq u1 then return nil else
  210. return comparedif1(u1list, cdr u2l)
  211. end$ % of comparedif2
  212. %---------------------
  213. symbolic procedure comparedif3(du1,u2,u2list)$
  214. % checks whether u2 differentiated wrt. u2list
  215. % is a derivative of du1
  216. begin
  217. scalar u1l;
  218. u1l:=combidif(du1)$ % u1l=(u1, 1, 1, ..)
  219. if car u1l neq u2 then return nil else
  220. return comparedif1(cdr u1l, u2list)
  221. end$ % of comparedif3
  222. %---------------------
  223. symbolic procedure listdifdif1(du1,deplist)$
  224. % lists all elements of deplist which are *not* derivatives
  225. % of du1
  226. begin
  227. scalar u1,u1list,res,h$
  228. h:=combidif(du1);
  229. u1:=car h;
  230. u1list:=cdr h;
  231. for each h in deplist do
  232. if not comparedif2(u1,u1list,h) then res:=cons(h,res);
  233. return res
  234. end$ % of listdifdif1
  235. %---------------------
  236. symbolic operator dif$
  237. symbolic procedure dif(s,n)$
  238. % e.g.: dif(fnc!`1!`3!`3!`4, 3) --> fnc!`1!`3!`3!`3!`4
  239. begin scalar temp,ans,no,n1,n2,done;
  240. s:=reval s; % to guarantee s is in true prefix form
  241. temp:=reverse explode s;
  242. n2:=reval n;
  243. n2:=explode n2;
  244. while (not null temp) and (not done) do
  245. <<n1:=<<no:=nil;
  246. while (not null temp) and (not eqcar(temp,'!`)) do
  247. <<no:=car temp . no;temp:=cdr temp>>;
  248. compress no
  249. >>;
  250. if (not fixp n1) or ((fixp n1) and (n1 leq n)) then
  251. <<ans:=nconc(n2,ans); ans:='!` . ans; ans:='!! . ans; done:=t>>;
  252. ans:=nconc(no,ans);
  253. if eqcar(temp,'!`) then <<ans:='!` . ans; ans:='!! . ans;
  254. temp:=cdr temp; temp:=cdr temp>>;
  255. >>;
  256. return intern compress nconc(reverse temp,ans);
  257. end$
  258. %---------------------
  259. %symbolic procedure orderofderiv(du)$
  260. %if atom du then (length combidif(du))-1
  261. % else nil$
  262. %---------------------
  263. symbolic procedure mergedepli(li1,li2)$
  264. % li1,li2 are lists of lists
  265. % mergedepli merges the sublists to make one list of lists
  266. begin scalar newdep;
  267. while li1 and li2 do <<
  268. newdep:=union(car li1, car li2) . newdep;
  269. li1:=cdr li1; li2:=cdr li2
  270. >>;
  271. return if li1 then nconc(reversip newdep,li1) else
  272. if li2 then nconc(reversip newdep,li2) else reversip newdep
  273. end$
  274. %---------------------
  275. symbolic procedure adddepli(ex,revdylist)$
  276. begin scalar a,b,c,d;
  277. for each a in revdylist do <<
  278. c:=nil;
  279. for each b in a do
  280. if not my_freeof(ex,b) then c:=b . c;
  281. if c or d then d:=c . d;
  282. >>;
  283. return list(ex,d)
  284. end$
  285. %---------------------
  286. symbolic procedure add_xi_eta_depli(xilist,etalist,revdylist)$
  287. begin
  288. scalar e1,g,h$
  289. for e1:=1:(length xilist) do <<
  290. g:=nth(xilist,e1);
  291. h:=pnth(g,4);
  292. rplaca(h,cadr adddepli(car g,revdylist))
  293. >>;
  294. for e1:=1:(length etalist) do <<
  295. g:=nth(etalist,e1);
  296. h:=pnth(g,3);
  297. rplaca(h,cadr adddepli(car g,revdylist))
  298. >>
  299. end$
  300. %---------------------
  301. symbolic procedure subtest(uik,sb,xlist,ordok,subordinc)$
  302. begin
  303. scalar el5,el6,el7,el8,el9,el10,sbc$
  304. el5:=combidif(uik);
  305. el6:=car el5; el5:=cdr el5; % el6..function name, el5..var.list
  306. el7:=nil; el8:=100; el9:=nil;
  307. sbc:=sb;
  308. while sbc and
  309. ((caaar sbc neq el6) or
  310. (0 neq <<el7:=comparedif1(cdaar sbc,el5);
  311. if el7 and (not zerop el7) and
  312. (length(el7)<el8) then
  313. <<el8 :=length el7;
  314. el9 :=el7;
  315. el10:=car sbc>> else
  316. el7
  317. >>)
  318. ) do sbc:=cdr sbc;
  319. return
  320. if sbc then (cadar sbc . caddar sbc) % simple substitution
  321. else
  322. if el9 then << % uik is total deriv of car el10 wrt el9
  323. uik:=cadr el10 . caddr el10;
  324. % car uik becomes the expr. to replace the former uik
  325. while el9 do <<
  326. uik:=totdf3(car uik, cdr uik, nth(xlist, car el9),
  327. car el9, sb, xlist, ordok, subordinc);
  328. el9:=cdr el9
  329. >>;
  330. uik
  331. >> else % no substitution
  332. nil
  333. end$
  334. %---------------------
  335. symbolic procedure totdf3(s,depli,x,n,sb,xlist,ordok,subordinc)$
  336. % s is the expression to be differentiated wrt. x which is the nth
  337. % variable in xlist
  338. % depli is a list of lists, each being the list of jet-variables
  339. % of order 0,1,2,..., such that s=s(xlist,depli), but
  340. % as little as possible jet-variables in depli
  341. % xlist, depli are lisp lists, i.e. without 'LIST
  342. % - totdf3 calculates total derivative of s(xlist,depli) w.r.t. x which
  343. % is the n'th variable, it returns (df(s,x), newdepli)
  344. % - totdf3 drops jet-variables on which s does not depend
  345. % - totdf3 automatically does substitutions using the list sb which
  346. % is updated if prolongations of substitutions are calculated,
  347. % i.e. sb is destructively changed!!
  348. % - structure of sb: lisp list of lisp lists:
  349. % ((to_be_replaced_jet_var_name, to_be_replaced_jet_var_deriv_1,..),
  350. % subst_expr_in_jet_space_coord, list_of_jet_vars_in_subst_expr)
  351. % - subordinc is a number by how much the order may increase due to
  352. % substitutions sb.
  353. % - ordok is the lowest order which must be accurate. If ordok>0 and
  354. % s is of lower order than ordok then from depli only derivatives
  355. % of order ordok-1-subordinc to ordok-1 are used.
  356. begin
  357. scalar tdf,el1,el2,el3,el4,el5,newdepli,
  358. newdy,dy,ddy,s;
  359. newdepli:=nil; % the new dependence list
  360. newdy:=nil; % the new dep.list due to chain rule
  361. ddy:=nil; % ddy .. derivatives of jet-variables
  362. % resulting from diff. of lower order
  363. %--- Should only terms in the result be acurate that include
  364. %--- derivatives of order>=ordok?
  365. if ordok>0 then <<
  366. tdf:=simp!* 0;
  367. depli:=copy depli;
  368. el2:=length depli;
  369. if el2<(ordok-subordinc) then depli:=nil
  370. else
  371. for el1:=1:(ordok-1-subordinc) do <<
  372. dy:=pnth(depli,el1);
  373. rplaca(dy,nil);
  374. >>
  375. >> else tdf:=simpdf {s,x};
  376. %--- The differentiations wrt. u-derivatives
  377. for each el1 in depli do % for each order do
  378. <<dy:=union(ddy,el1); ddy:=nil;% dy .. occuring jet-var. of this order
  379. while el1 do
  380. <<el2:=car el1; el1:=cdr el1;% el2 is one jet-variable of this order
  381. el3:=simpdf {s,el2};
  382. if zerop el3 then dy:=delete(el2,dy)
  383. else <<
  384. el4:=dif(el2,n); % el4=df(el2,x)
  385. %----- Is el4 to be substituted by sb?
  386. if el5:=subtest(el4,sb,xlist,ordok,subordinc) then <<
  387. el4:=car el5;
  388. newdepli:=mergedepli(newdepli,cdr el5)
  389. >> else ddy:=el4 . ddy;
  390. tdf:=addsq(tdf, multsq(simp!* el4, el3))
  391. >>
  392. >>;
  393. newdy:=dy . newdy
  394. >>;
  395. if ddy then newdy:=ddy . newdy;
  396. newdepli:=mergedepli(reversip newdy,newdepli);
  397. % possibly drop at the end
  398. return (prepsq tdf . newdepli)
  399. end$ % of totdf3
  400. %---------------------
  401. symbolic procedure joinsublists(a)$
  402. % It is assumed, a is either nil or a list of lists or nils which
  403. % have to be joined
  404. if null a then nil
  405. else append(car a,joinsublists(cdr a))$
  406. %---------------------
  407. symbolic procedure depnd(y,xlist)$
  408. for each xx in xlist do
  409. for each x in xx do depend y,x$
  410. %---------------------
  411. algebraic procedure transeq(eqn,xlist,ylist,sb)$
  412. <<for each el1 in sb do eqn:=sub(el1,eqn);
  413. for each el1 in ylist do
  414. for each el2 in xlist do nodepend el1,el2;
  415. eqn>>$
  416. %---------------------
  417. symbolic operator drop$
  418. symbolic procedure drop(a,vl)$
  419. % liefert summe aller terme aus a, die von elementen von vl abhaengen
  420. begin scalar b$
  421. if not((pairp a) and (car a='PLUS)) then b:=a
  422. else
  423. <<vl:=cdr vl; % because vl is an algebraic list
  424. for each c in cdr a do
  425. if not freeoflist(c,vl) then b:=cons(c,b)$
  426. if b then b:=cons('PLUS,reverse b)>>$
  427. return b$
  428. end$
  429. %---------------------
  430. symbolic procedure etamn(u,indxlist,xilist,etalist,
  431. ordok,truesub,subordinc,xlist)$
  432. % determines etamn recursively
  433. % At the end, ulist= list of df(u,i,cdr indxlist) for all i
  434. begin
  435. scalar etam,x,h1,h2,h3,h4,ulist,el,r,cplist,depli;
  436. if (null indxlist) or ((length indxlist)=1) then
  437. <<cplist:=etalist;
  438. while u neq cadar cplist do cplist:=cdr cplist;
  439. etam:=(caar cplist . caddar cplist) . nil;
  440. >> else
  441. etam:=etamn(u,cdr indxlist,xilist,etalist,ordok,truesub,
  442. subordinc,xlist)$
  443. return
  444. if null indxlist then etam
  445. else <<
  446. ulist:=nil;
  447. x:=cdr nth(xilist,car indxlist); % e.g. x := (v3,3,dylist)
  448. r:=if zerop caar etam then simp!* <<depli:=nil;0>>
  449. else simp!* <<
  450. h2:=totdf3(caar etam,cdar etam,car x,cadr x,truesub,xlist,
  451. ordok,subordinc)$
  452. depli:=cdr h2;
  453. car h2
  454. >>;
  455. etam:=cdr etam; % = reverse ulist
  456. cplist:=xilist;
  457. h3:=nil;
  458. while cplist do
  459. <<el:=car cplist; % e.g. el=xi_z
  460. cplist:=cdr cplist;
  461. if (length indxlist)=1 then h1:=dif(u,caddr el)
  462. else <<
  463. h1:=dif(car etam,cadr indxlist); % e.g. h1:=u!`i!`n
  464. etam:=cdr etam;
  465. >>;
  466. ulist:=h1 . ulist;
  467. if not zerop car el then <<
  468. %--- substitution of h1?
  469. if h4:=subtest(h1,truesub,xlist,ordok,subordinc) then
  470. h1:=car h4;
  471. r:=subtrsq(r,
  472. multsq(simp!* h1,
  473. simp!* <<h2:=totdf3(car el,cadddr el,car x,
  474. cadr x,truesub,xlist,0,0)$
  475. if zerop car h2 then 0
  476. else
  477. <<if h4 then
  478. depli:=mergedepli(depli,cdr h4)
  479. else h3:=h1 . h3;
  480. depli:=mergedepli(depli,cdr h2);
  481. car h2
  482. >>
  483. >>
  484. )
  485. );
  486. >>
  487. >>;
  488. if h3 then <<
  489. h3:=list h3;
  490. for h2:=1:(length indxlist) do h3:=nil . h3;
  491. depli:=mergedepli(depli,h3);
  492. >>;
  493. % (if not full then drop(r,'LIST . car revdylist) else r) .
  494. % (reverse ulist)
  495. (prepsq r . depli) . (reverse ulist)
  496. >>
  497. end$ % of etamn
  498. %---------------------
  499. symbolic procedure prolong(uik,xilist,etalist,ordok,truesub,subordinc,
  500. xlist)$
  501. begin
  502. scalar h;
  503. h:=combidif(uik);
  504. h:=car etamn(car h,cdr h,xilist,etalist,ordok,truesub,
  505. subordinc,xlist)$
  506. return (simp!* car h) . cdr h
  507. end$ % of prolong
  508. %---------------------
  509. symbolic procedure callcrack(!*time,cpu,gc,lietrace_,symcon,
  510. flist,vl,xilist,etalist,inequ)$
  511. begin
  512. scalar g,h; % ,batch_mode_old;
  513. if !*time then <<terpri()$
  514. write "time to formulate conditions: ", time() - cpu,
  515. " ms GC time : ", gctime() - gc," ms"$
  516. >>;
  517. if lietrace_ then algebraic <<
  518. write"Symmetry conditions before CRACK: ";
  519. write lisp ('LIST . symcon);
  520. >>;
  521. % batch_mode_old:=!*batch_mode$
  522. % !*batch_mode:=nil$
  523. h:=crack('LIST . symcon,'LIST . inequ,'LIST . flist,'LIST . vl);
  524. % !*batch_mode:=batch_mode_old$
  525. if h neq list('LIST) then
  526. <<h:=cadr h;
  527. symcon:=cdadr h;
  528. for each g in cdaddr h do <<
  529. xilist :=subst(caddr g, cadr g, xilist);
  530. etalist:=subst(caddr g, cadr g, etalist);
  531. inequ :=subst(caddr g, cadr g, inequ);
  532. %--> Erkennung von 'e, 'x siehe:
  533. % h:=intern car explode cadr e1;
  534. %write"h=",h;terpri()$
  535. % if (h='x) or (h='X) then
  536. % xilist :=subst(caddr e1, cadr e1, xilist) else
  537. % if (h='e) or (h='E) or (h="e") or (h="E") then
  538. % etalist:=subst(caddr e1, cadr e1, etalist) else
  539. % rederr("One ansatz does not specify XI_ nor ETA_.")
  540. >>;
  541. if lietrace_ then <<
  542. write"symcon nachher: ",symcon;
  543. write"xilist=", xilist;
  544. write"etalist=", etalist;
  545. >>;
  546. flist:=cdr reval cadddr h;
  547. if print_ then
  548. <<terpri()$
  549. write"Remaining free functions after the last CRACK-run:";
  550. terpri()$
  551. fctprint flist;terpri()$terpri()>>;
  552. >>;
  553. return list(symcon,xilist,etalist,flist,inequ)
  554. end$ % of callcrack
  555. %---------------------
  556. symbolic operator liepde$
  557. symbolic procedure liepde(problem,symtype,flist,inequ)$
  558. comment
  559. problem: {{eq1,eq2, ...}, % equations
  560. { y1, y2, ...}, % functions
  561. { x1, x2, ...} } % variables
  562. % Equations `eqi' can be given as single differential
  563. % expressions which have to vanish or they can be given
  564. % in the form df(..,..[,..]) = .. .
  565. % If the equations are given as single differential
  566. % expressions then the program will try to bring it into
  567. % the `solved form' ..=.. automatically.
  568. % The solved forms (either from input or generated within
  569. % LIEPDE) will be used for substitutions, to find
  570. % all symmetries satisfied by solutions of the equations.
  571. % Sufficient conditions for this procedure to be correct,
  572. % i.e. to get *all* symmetries of the specified type on the
  573. % solution space are:
  574. % - There are equally many equations and functions.
  575. % - Each function is used once for a substitution and
  576. % each equation is used once for a substitution.
  577. % - All functions differentiated on the left hand sides
  578. % (lhs) depend on all variables.
  579. % - In no equation df(..,..[,..]) = .. does the right hand
  580. % side contain the derivative on the lhs nor any
  581. % derivative of it.
  582. % - No equation does contain a lhs or the derivative
  583. % of a lhs of another equation.
  584. % These conditions are checked in LIEPDE and execution
  585. % is stoped if they are not satisfied, i.e. if the input
  586. % was not correct, or if the program was not able to
  587. % write the input expressions properly the solved
  588. % form ..=.. . One then should find for each function
  589. % one derivative which occurs linearly in one equation.
  590. % The chosen derivatives should be as high as possible,
  591. % at least there must no derivative of them occur in any
  592. % equation. An easy way to get the equations in the
  593. % desired form is to use
  594. % FIRST SOLVE({eq1,eq2,...},{list of derivatives})
  595. % NOTE that to improve efficiency it is advisable not to
  596. % express lower order derivatives on the left hand side
  597. % through higher order derivatives on the right hand side.
  598. % SEE also the implications on completeness for the
  599. % determination of generalized symmetries with
  600. % characteristic functions of a given order, as described
  601. % below and the two examples with the Burgers equation.
  602. symtype: {"point"} % for point symmetries
  603. {"contact"} % for contact symmetries, is only
  604. % applicable if only one function,
  605. % only one equation of order>1
  606. {"general",order} % for generalized symmetries of
  607. % order `order' which is an integer>0
  608. % NOTE: Characteristic functions of
  609. % generalized symmetries (i.e. the
  610. % eta_.. if xi_..=0) are equivalent
  611. % if they are equal on the solution
  612. % manifold. Therefore all dependencies
  613. % of characteristic functions on
  614. % the substituted derivatives and their
  615. % derivatives are dropped. This has the
  616. % consequence that if, e.g. for the heat
  617. % equation df(u,t)=df(u,x,2), df(u,t) is
  618. % substituted by df(u,x,2) then
  619. % {"general",2) would not include
  620. % characteristic functions depending
  621. % on df(u,t,x), or df(u,x,3). THEREFORE:
  622. % If you want to find all symmetries up
  623. % to a given order then
  624. % - either avoid substituting lower
  625. % order derivatives by expressions
  626. % involving higher derivatives, or,
  627. % - go up in the order specified in
  628. % symtype.
  629. %
  630. % Example:
  631. %
  632. % depend u,t,x
  633. % liepde({{df(u,t)=df(u,x,2)+df(u,x)**2},
  634. % {u},{t,x}},
  635. % {"general",3},{})
  636. %
  637. % will give 10 symmetries + one infinite
  638. % family of symmetries whereas
  639. %
  640. % liepde({{df(u,x,2)=df(u,t)-df(u,x)**2},
  641. % {u},{t,x}},
  642. % {"general",3},{})
  643. %
  644. % will give 28 symmetries + one infinite
  645. % family of symmetries.
  646. {xi!_x1 =...,
  647. ...
  648. eta!_y3=... } % - An ansatz must specify all xi!_.. for
  649. % all indep. variables and all eta!_..
  650. % for all dep. variables in terms of
  651. % differential expressions which may
  652. % involve unknown functions/constants.
  653. % The dependencies of the unknown
  654. % functions have to declared earlier
  655. % using the DEPEND command.
  656. % - If the ansatz should consist of the
  657. % characteristic functions then set
  658. % all xi!_..=0 and assign the charac-
  659. % teristic functions to the eta!_.. .
  660. flist: {- all parameters and functions in the equations which are to
  661. be determined, such that there exist symmetries,
  662. - if an ansatz has been made in symtype then flist contains
  663. all unknown functions and constants in xi!_.. and eta!_..}
  664. inequ: {all non-vanishing expressions which represent
  665. inequalities for the functions in flist}
  666. Further comments:
  667. The syntax of input is the usual REDUCE syntax. For example, the
  668. derivative of y3 wrt x1 once and x2 twice would be df(y3,x1,x2,2).
  669. --> One exception: If in the equations or in the ansatz the dependence
  670. of a free function F on a derivative, like df(y3,x1,x2,2) shall be
  671. declared then the declaration has to have the form:
  672. DEPEND F, Y3!`1!`2!`2
  673. - the ! has to preceede each special character, like `,
  674. - `i stands for the derivative with respect to the i'th variable in
  675. the list of variables (the third list in the problem above)
  676. If the flag individual_ is t then conditions are investigated for
  677. each equation of a system of equations at first individually before
  678. conditions resulting from other equations are added.
  679. If the flag prelim_ is t then preliminary conditions for equations
  680. of higher than 1st order are formulated and investigated before the
  681. full condition is formulated and investigated by CRACK.
  682. If the REDUCE switch TIME is set on with ON TIME then times for the
  683. individual steps in the calculation are shown.
  684. Further switches and parameters which can be changed to affect the
  685. output and performance of CRACK in solving the symmetry conditions
  686. are listed in the file CRINIT.RED.
  687. ;
  688. begin
  689. scalar cpu, gc, lietrace_, oldadj, eqlist, ylist, xlist, pointp,
  690. contactp, generalp, ansatzp, symord, e1, e2, ordr, sb,
  691. dylist, revdylist, xi, eta, eqordr, eqordrcop, no, eqcopy1,
  692. truesub, deplist, xilist, etalist, dycopy, freelist, eqlen,
  693. dylen, truesubno, minordr, n1, n2, n3, n4, n, h, jetord,
  694. allsub, subdy, lhslist, symcon, subordinc, eqn, depli,
  695. vl, occli, revdycopy, subordinclist, xicop, etacop, flcop,
  696. etapqlist, etapqcop, etapq, batch_mode_old;
  697. backup_reduce_flags()$
  698. cpu:=time()$ gc:=gctime()$
  699. % lietrace_:=t;
  700. oldadj:=adjust_fnc;
  701. adjust_fnc:=nil;
  702. %--------- extracting input data
  703. eqlist:= cdr maklist cadr problem;
  704. ylist := reval maklist caddr problem;
  705. xlist := reval maklist cadddr problem;
  706. if inequ then inequ:=cdr inequ;
  707. eqlen:=length eqlist;
  708. % if 1+eqlen neq length(ylist) then rederr(
  709. % "Number of equations does not match number of unknown functions.");
  710. for each e1 in cdr ylist do
  711. for each e2 in cdr xlist do
  712. if my_freeof(e1,e2) then rederr(
  713. "Not all functions do depend on all variables.");
  714. if atom cadr symtype then % default case
  715. if cadr symtype = "point" then <<pointp :=t;symord:=0>> else
  716. if cadr symtype = "contact" then <<contactp:=t;symord:=1;
  717. if eqlen>1 then rederr(
  718. "Contact symmetries only in case of one equation for one function.")
  719. >> else
  720. if cadr symtype = "general" then <<generalp:=t;symord:=caddr symtype;
  721. if (not fixp symord) or (symord<1) then rederr(
  722. "The order of the generalized symmetry must be an integer > 0.")
  723. >> else rederr("Inconclusive symmetry type.")
  724. else <<
  725. ansatzp:=t; % an ansatz has been made
  726. if length(ylist)+length(xlist) neq length(symtype)+1 then
  727. rederr("Number of assignments in the ansatz is wrong.");
  728. symord:=0;
  729. for each e1 in cdr symtype do
  730. for each e2 in ylist do
  731. <<n:=totdeg(e1,e2);
  732. if n>symord then symord:=n>>;
  733. if symtype = 0 then pointp :=t else
  734. if (symtype = 1) and (length(ylist)=2) then contactp:=t else
  735. generalp:=t
  736. >>$
  737. if flist then flist:=cdr flist;
  738. problem:=0;
  739. %---- Are substitutions already given in the input?
  740. eqcopy1:=eqlist;
  741. while eqcopy1 and (pairp car eqcopy1) and (caar eqcopy1='EQUAL) and
  742. (pairp cadar eqcopy1) and (caadar eqcopy1='DF) do
  743. eqcopy1:=cdr eqcopy1;
  744. if null eqcopy1 then truesub:=eqlist;
  745. eqcopy1:=nil;
  746. %--------- initial printout
  747. if print_ and logoprint_ then <<terpri()$
  748. write "-----------------------------------------------",
  749. "---------------------------"$ terpri()$terpri()$
  750. write"This is LIEPDE - a program for calculating infinitesimal",
  751. " symmetries"; terpri()$
  752. write "of single differential equations or systems of de's";
  753. >>;
  754. terpri();terpri();
  755. if length xlist=2 then write"The ODE"
  756. else write"The PDE";
  757. if length ylist>2 then write"-system";
  758. write " under investigation is :";terpri();
  759. % for each e1 in eqlist do algebraic write"0 = ",lisp e1;
  760. for each e1 in eqlist do algebraic write lisp e1;
  761. terpri()$write "for the function(s) : ";terpri()$
  762. terpri()$fctprint cdr reval ylist;
  763. terpri()$terpri();
  764. eqlist:=for each e1 in eqlist collect algebraic equ_to_expr(lisp e1);
  765. if eqlen > 1 then eqlist:=desort eqlist;
  766. if !*time then <<terpri()$
  767. terpri()$terpri()$
  768. write"=============== Initializations" ;
  769. >>;
  770. %--------- initializations
  771. ordr:=0;
  772. for each e1 in eqlist do <<
  773. h:=0;
  774. for each e2 in cdr ylist do
  775. <<n:=totdeg(e1,e2);
  776. if n>h then h:=n>>;
  777. eqordr:=h . eqordr;
  778. if h>ordr then ordr:=h
  779. >>;
  780. eqordr:=reversip eqordr;
  781. if ordr>symord then jetord:=ordr
  782. else jetord:=symord$
  783. sb:=subdif1(xlist,ylist,jetord)$
  784. eqlist:=cons('LIST,eqlist);
  785. if ansatzp then eqlist:=list('LIST,symtype,eqlist);
  786. if truesub then eqlist:=list('LIST,cons('LIST,truesub),eqlist);
  787. if inequ then eqlist:=list('LIST,cons('LIST,inequ),eqlist);
  788. on evallhseqp;
  789. eqlist:=transeq(eqlist,xlist,ylist,sb);
  790. off evallhseqp;
  791. if inequ then <<inequ :=cdadr eqlist;eqlist:=caddr eqlist>>;
  792. if truesub then <<truesub:=cdadr eqlist;eqlist:=caddr eqlist>>;
  793. if ansatzp then <<symtype:=cdadr eqlist;eqlist:=cdaddr eqlist>>
  794. else eqlist:=cdr eqlist;
  795. ylist:=cdr ylist;
  796. xlist:=cdr xlist;
  797. if lietrace_ and ansatzp then write"ansatz=",symtype;
  798. dylist:=ylist . reverse for each e1 in cdr sb collect
  799. for each e2 in cdr e1 collect caddr e2;
  800. revdylist:=reverse dylist; % dylist with decreasing order
  801. vl:=xlist;
  802. for each e1 in dylist do vl:=append(e1,vl);
  803. vl:='LIST . vl;
  804. if not ansatzp then
  805. deplist:=for n:=0:symord collect nth(dylist,n+1);
  806. % list of variables the xi_, eta_ depend on
  807. xi :=reval algebraic xi!_;
  808. eta:=reval algebraic eta!_;
  809. n:=0;
  810. xilist :=for each e1 in xlist collect
  811. <<n:=n+1;
  812. if pointp or ansatzp then <<
  813. h:=mkid(xi,e1);
  814. if not ansatzp then <<
  815. depnd(h,xlist . deplist);
  816. flist:=h . flist;
  817. depli:=deplist;
  818. >> else depli:=nil
  819. >> else <<h:=0;depli:=nil>>;
  820. {h,e1,n,depli}
  821. >>;
  822. depli:=if (not ansatzp) and (not generalp) then deplist
  823. else nil;
  824. n:=0;
  825. etalist:=for each e1 in ylist collect
  826. <<n:=n+1;
  827. h:=mkid(eta,e1);
  828. if not ansatzp then <<
  829. if not generalp then depnd(h,xlist . deplist);
  830. % the generalp-case is done below when substitutions are known
  831. flist:=h . flist;
  832. >>;
  833. {h,e1,depli}
  834. >>;
  835. if ansatzp then <<
  836. for each e1 in symtype do <<
  837. xilist :=subst(caddr e1, cadr e1, xilist);
  838. etalist:=subst(caddr e1, cadr e1, etalist);
  839. %--> Erkennung von 'e, 'x siehe:
  840. % h:=intern car explode cadr e1;
  841. %write"h=",h;terpri()$
  842. % if (h='x) or (h='X) then
  843. % xilist :=subst(caddr e1, cadr e1, xilist) else
  844. % if (h='e) or (h='E) or (h="e") or (h="E") then
  845. % etalist:=subst(caddr e1, cadr e1, etalist) else
  846. % rederr("One ansatz does not specify XI_ nor ETA_.")
  847. >>;
  848. add_xi_eta_depli(xilist,etalist,revdylist)$
  849. >>;
  850. if lietrace_ then write"xilist=",xilist," etalist=",etalist;
  851. %---- Determining a substitution list for highest derivatives
  852. %---- from eqlist. Substitutions may not be optimal if starting
  853. %---- system is not in standard form
  854. comment: Counting in how many equations each highest
  855. derivative occurs. Those which do not occur allow Stephani-Trick,
  856. those which do occur once and there linearly are substituted by that
  857. equation.
  858. Because one derivative shall be assigned it must be one of
  859. the highest derivatives from each equation used, or one such that
  860. no other derivative in the equation is a derivative of it.
  861. Each equation must be used only once.
  862. Each derivative must be substituted by only one equation.
  863. At first determining the number of occurences of each highest
  864. derivative.
  865. The possiblity of substitutions is checked in each total derivative.
  866. $
  867. if truesub then << %--- determination of freelist %and occurlist
  868. dycopy:=car revdylist; %--- the highest derivatives
  869. while dycopy do
  870. <<e1:=car dycopy; dycopy:=cdr dycopy;
  871. eqcopy1:=eqlist;
  872. while eqcopy1 and my_freeof(car eqcopy1,e1) do
  873. eqcopy1:=cdr eqcopy1;
  874. if null eqcopy1 then freelist :=e1 . freelist
  875. %else occurlist:=e1 . occurlist;
  876. >>
  877. >> else <<
  878. no:=0; % counter of the following repeat-loop
  879. % freelist (and occurlist) are determined
  880. % only in the first run
  881. eqordrcop:=copy eqordr;
  882. % for bookkeeping which equation have been used
  883. repeat <<
  884. no:=no+1; %--- incrementing the loop counter
  885. %--- truesubno is the number of substitutions so far found.
  886. %--- It is necessary at the end to check whether new substitutions
  887. %--- have been found.
  888. if null truesub then truesubno:=0
  889. else truesubno:=length truesub;
  890. %--- substitutions of equations of minimal order are searched first
  891. minordr:=1000; %--- minimal order of the so far unused equations
  892. for each e1 in eqordrcop do
  893. if (e1 neq 0) and (e1<minordr) then minordr:=e1;
  894. dycopy:=copy nth(dylist,minordr+1); %-- all deriv. of order minordr
  895. dylen:=length dycopy;
  896. allsub:=nil;
  897. for n1:=1:dylen do %--- checking all deriv. of order minordr
  898. <<e1:=nth(dycopy,n1); %--- e1 is the current candidate
  899. %--- here test, whether e1 is not a derivative of a lhs of one
  900. %--- of the substitutions car e2 found so far
  901. h:=combidif(e1); n:=car h; h:=cdr h;
  902. e2:=truesub;
  903. while e2 and (null comparedif3(cadar e2,n,h)) do e2:=cdr e2;
  904. if null e2 then <<
  905. n2:=0; %-- number of equations in which the derivative e1 occurs
  906. subdy:=nil;
  907. for n3:=1:eqlen do
  908. if not my_freeof(nth(eqlist,n3),e1) then
  909. % here should also be tested whether derivatives of e1 occur
  910. % and not just my_freeof
  911. %-->
  912. <<n2:=n2+1;
  913. if nth(eqordrcop,n3)=minordr then
  914. %--- equation is not used yet and of the right order
  915. <<e2:=cdr algebraic coeff(lisp nth(eqlist,n3),lisp e1);
  916. if hipow!*=1 then
  917. subdy:=list(n1,n3,list('EQUAL,e1,list('MINUS,
  918. list('QUOTIENT, car e2, cadr e2)))) . subdy
  919. >>
  920. >>;
  921. if n2=0 then if no=1 then freelist:=e1 . freelist else
  922. else
  923. <<%if no=1 then occurlist:=e1 . occurlist;
  924. if subdy then if n2=1 then
  925. <<h:=car subdy;
  926. truesub:=(caddr h) . truesub;
  927. n:=pnth(dycopy ,car h);rplaca(n,0);
  928. n:=pnth(eqordrcop,cadr h);rplaca(n,0);
  929. >> else
  930. allsub:=nconc(allsub,subdy);
  931. >>
  932. >>
  933. >>;
  934. %---- Taking the remaining known substitutions of highest deriv.
  935. h:=subdy:=0;
  936. for each h in allsub do
  937. if (nth(dycopy , car h) neq 0) and
  938. (nth(eqordrcop,cadr h) neq 0) then
  939. <<truesub:=(caddr h) . truesub;
  940. n:=pnth(dycopy ,car h);rplaca(n,0);
  941. n:=pnth(eqordrcop,cadr h);rplaca(n,0);
  942. >>;
  943. >> until (truesub and (length(truesub)=eqlen)) % complete
  944. or (truesubno=length(truesub))$ % no progress
  945. allsub:=eqordrcop:=dycopy:=nil;
  946. if (null truesub) or
  947. (eqlen neq length(truesub)) then rederr(
  948. "Unable to find all substitutions. Input equations as df(..,..)=..!");
  949. >>;
  950. lhslist:=for each e1 in truesub collect cadr e1;
  951. %-- Bringing truesub into a specific form: lisp list of lisp lists:
  952. % ((to_be_replaced_jet_var_name, to_be_replaced_jet_var_deriv_1,..),
  953. % subst_expr_in_jet_space_coord, list_of_jet_vars_in_subst_expr)
  954. truesub:=for each e1 in truesub collect
  955. cons(combidif cadr e1, adddepli(caddr e1,revdylist))$
  956. %--- Checking that no rhs of a substitution contains any lhs or
  957. %--- derivative of a lhs
  958. h:=t; %--- h=nil if lhs's are derivatives of each other
  959. no:=t; %--- no=nil if one lhs can be substituted in a rhs
  960. for each e1 in truesub do
  961. if h and no then <<
  962. n1:=caar e1; n2:=cdar e1; dylen:=length n2;
  963. for each e2 in truesub do <<
  964. %--- comparison of two lhs's
  965. if not(e1 eq e2) and (n1=caar e2) and
  966. comparedif1(n2,cdar e2) then h:=nil; %--- truesub is not ok
  967. %--- can the lhs of e1 be substituted on the rhs?
  968. dycopy:=caddr e2;
  969. for n:=1:dylen do if dycopy then dycopy:=cdr dycopy;
  970. for each e3 in dycopy do
  971. for each e4 in e3 do
  972. if comparedif2(n1,n2,e4) then no:=nil;
  973. >>
  974. >>;
  975. if null h then rederr(
  976. "One substitution can be made in the lhs of another substitution!");
  977. if null no then rederr(
  978. "One substitution can be made in the rhs of another substitution!");
  979. %????????????????????????????????????????????
  980. % %--- Checking that a derivative of each dependent variable is
  981. % %--- substituted once. This is a sufficient condition for having
  982. % %--- a de-system that is a differential Groebner basis
  983. % h:=nil;
  984. % for each e1 in lhslist do h:=adjoin(car combidif e1,h);
  985. % if length(h) neq length(lhslist) then rederr(
  986. % "For at least one function there is more that one substituion!")$
  987. %--- Determine of how much the order may increase by a substitution
  988. subordinc:=0;
  989. subordinclist:=for each h in truesub collect <<
  990. n:=(length caddr h) - (length car h);
  991. if n>subordinc then subordinc:=n;
  992. n
  993. >>;
  994. if lietrace_ then <<terpri()$write"truesub=",truesub;
  995. terpri()$write"freelist=",freelist;
  996. %terpri()$write"occurlist=",occurlist
  997. >>;
  998. %--- To avoid non-uniqueness in the case of the investigation of
  999. %--- generalized symmetries let the characteristics eta_.. (xi_..=0)
  1000. %--- not depend on substituted derivatives
  1001. if generalp and (null ansatzp) then <<
  1002. deplist:=ylist .
  1003. for each dycopy in cdr deplist collect <<
  1004. for each h in lhslist do
  1005. %---- delete h and derivatives of h
  1006. dycopy:=listdifdif1(h,dycopy);
  1007. dycopy
  1008. >>;
  1009. for e1:=1:(length etalist) do <<
  1010. h:=nth(etalist,e1);
  1011. depnd(car h,xlist . deplist);
  1012. h:=pnth(h,3);
  1013. rplaca(h,deplist)
  1014. >>
  1015. >>;
  1016. % reduced set of solution techniques for preliminary conditions
  1017. proc_list_:=delete('multintfac,proc_list_)$
  1018. if !*time then <<terpri()$
  1019. write "time for initializations: ", time() - cpu,
  1020. " ms GC time : ", gctime() - gc," ms"$
  1021. cpu:=time()$ gc:=gctime()$
  1022. >>;
  1023. %------ Determining first short determining equations and solving them
  1024. symcon:=nil;
  1025. n1:=0;
  1026. if prelim_ then
  1027. for each eqn in eqlist do
  1028. <<n1:=n1+1;
  1029. if !*time then <<terpri()$
  1030. terpri()$terpri()$
  1031. write"=============== Preconditions for the ",n1,". equation" ;
  1032. >>;
  1033. revdycopy:=revdylist;
  1034. for e1:=(nth(eqordr,n1) + 1):ordr do revdycopy:=cdr revdycopy;
  1035. n2:=cadr adddepli(eqn,revdycopy); % jet-variables in eqn
  1036. vl:=n2;
  1037. occli:=lastcar n2;
  1038. freelist:=setdiff(car revdycopy,occli);
  1039. if pointp and (subordinc=0) then
  1040. eqn:=drop(eqn,occli) % dropp all terms without a highest deriv.
  1041. else occli:=joinsublists n2$
  1042. % freelist must not contain substituted variables
  1043. freelist:=setdiff(freelist,lhslist);
  1044. % It must be possible to separate wrt freelist variables
  1045. for each n4 in freelist do
  1046. if not freeof(depl!*,n4) then freelist:=delete(n4,freelist);
  1047. If freelist then <<
  1048. n:=nth(eqordr,n1); % order of this equation
  1049. h:=simp!* 0;
  1050. for each e1 in xilist do
  1051. if (cadddr e1) and ((length cadddr e1) > n) then
  1052. % xi (=car e1) is of order n
  1053. h:=addsq(h,
  1054. if car e1 = 0 then simp!* 0
  1055. else <<n3:=mergedepli(n3,cadddr e1);
  1056. multsq(simp!* car e1,
  1057. simpdf {eqn,cadr e1})
  1058. >>
  1059. );
  1060. for each e2 in occli do
  1061. h:=addsq(h,
  1062. multsq(<<n4:=prolong(e2,xilist,etalist,nth(eqordr,n1),
  1063. truesub,subordinc,xlist);
  1064. vl:=mergedepli(vl,cdr n4);
  1065. car n4
  1066. >>,
  1067. simpdf {eqn,e2}
  1068. )
  1069. );
  1070. for each e2 in freelist do
  1071. <<
  1072. e1:=algebraic num lisp coeffn(prepsq h,e2,1);
  1073. if not zerop e1 then symcon:=e1 . symcon>>;
  1074. vl:=joinsublists(xlist . vl)$
  1075. for n2:=1:eqlen do
  1076. <<n4:=nth(lhslist,n2);
  1077. if not my_freeof(eqn,n4) then
  1078. symcon:=subst(cadr nth(truesub,n2), n4, symcon);
  1079. vl:=delete(n4,vl)
  1080. >>;
  1081. if symcon and (individual_ or (n1=eqlen)) then <<
  1082. inequ:=callcrack(!*time,cpu,gc,lietrace_,symcon,
  1083. flist,vl,xilist,etalist,inequ);
  1084. symcon :=car inequ; xilist:=cadr inequ;
  1085. etalist:=caddr inequ; flist :=cadddr inequ;
  1086. inequ :=cadddr cdr inequ;
  1087. cpu:=time()$ gc:=gctime()$
  1088. >>
  1089. >>
  1090. >>;
  1091. %------------ Determining the full symmetry conditions
  1092. n1:=0;
  1093. vl:=nil;
  1094. for each eqn in eqlist do
  1095. <<n1:=n1+1;
  1096. if !*time then <<terpri()$
  1097. terpri()$terpri()$
  1098. write"=============== Full conditions for the ",n1,". equation" ;
  1099. >>;
  1100. n2:=cadr adddepli(eqn,revdylist);
  1101. n3:=n2; % n3 are the variables in the new condition
  1102. symcon:=(reval algebraic num lisp prepsq addsq(
  1103. <<h:=simp!* 0;
  1104. for each e1 in xilist do
  1105. h:=addsq(h,
  1106. if car e1 = 0 then simp!* 0
  1107. else <<n3:=mergedepli(n3,cadddr e1);
  1108. multsq(simp!* car e1,
  1109. simpdf {eqn,cadr e1})
  1110. >>
  1111. );
  1112. h
  1113. >>,
  1114. <<h:=simp!* 0;
  1115. for each e1 in n2 do
  1116. for each e2 in e1 do
  1117. h:=addsq(h,
  1118. multsq(<<n4:=prolong(e2,xilist,etalist,0,truesub,
  1119. 0,xlist );
  1120. n3:=mergedepli(n3,cdr n4);
  1121. car n4
  1122. >>,
  1123. simpdf {eqn,e2}
  1124. )
  1125. );
  1126. h
  1127. >> )) . symcon;
  1128. n3:=joinsublists(xlist . n3)$
  1129. for n2:=1:eqlen do
  1130. <<n4:=nth(lhslist,n2);
  1131. if not my_freeof(eqn,n4) then
  1132. symcon:=subst(cadr nth(truesub,n2), n4, symcon);
  1133. n3:=delete(n4,n3)
  1134. >>;
  1135. vl:=union(vl,n3);
  1136. if individual_ or (n1=eqlen) then <<
  1137. inequ:=callcrack(!*time,cpu,gc,lietrace_,symcon,
  1138. flist,vl,xilist,etalist,inequ);
  1139. symcon :=car inequ; xilist:=cadr inequ;
  1140. etalist:=caddr inequ; flist :=cadddr inequ;
  1141. inequ :=cadddr cdr inequ;
  1142. cpu:=time()$ gc:=gctime()$
  1143. >>
  1144. >>;
  1145. eqn:=sb:=e1:=e2:=n:=h:=dylist:=deplist:=symord:=nil;%occurlist:=nil;
  1146. lisp(adjust_fnc:=oldadj);
  1147. %------- Calculation finished, simplification of the result
  1148. h:=append(for each el in xilist collect car el,
  1149. for each el in etalist collect car el );
  1150. if symcon then for each el in symcon do h:=cons(el,h);
  1151. h:=cons('LIST,h);
  1152. %------- droping redundant constants or functions
  1153. batch_mode_old:=!*batch_mode$
  1154. !*batch_mode:=t$
  1155. sb:=reval dropredundant(h,'LIST . flist,'LIST . vl,list('LIST));
  1156. !*batch_mode:=batch_mode_old$
  1157. if sb then <<
  1158. flist:=cdr cadddr sb;
  1159. h:=caddr sb;
  1160. sb:=cadr sb;
  1161. e1:=nil
  1162. >>;
  1163. %------- absorbing numerical constants into free constants
  1164. h:=reval absorbconst(h,'LIST . flist);
  1165. if h then if sb then sb:=append(sb,cdr h)
  1166. else sb:='LIST . cdr h;
  1167. %------- doing the substitutions
  1168. if sb then <<
  1169. if print_ then <<terpri()$
  1170. write"Free constants and/or functions have been rescaled. ">>$
  1171. for each e1 in cdr sb do <<
  1172. xilist :=subst(caddr e1, reval cadr e1, xilist);
  1173. etalist:=subst(caddr e1, reval cadr e1, etalist);
  1174. symcon :=cdr reval cons('LIST,subst(caddr e1, reval cadr e1, symcon));
  1175. >>;
  1176. >>;
  1177. %------- Computing the prolongation of the symmetry vector
  1178. if fixp(prolong_order) and (prolong_order>0) then <<
  1179. for each e1 in ylist do depnd(e1,list(xlist));
  1180. on evallhseqp;
  1181. sb:=subdif1(cons('LIST,xlist),cons('LIST,ylist),prolong_order)$
  1182. for each e1 in cdr sb do
  1183. for each e2 in cdr e1 do <<
  1184. h:=combidif(caddr e2);
  1185. n1:=mkid(eta,car h);
  1186. for each n2 in cdr h do
  1187. n1:=mkid(n1,nth(xlist,n2));
  1188. h:=car etamn(car h,cdr h,xilist,etalist,0,truesub,0,xlist)$
  1189. n3:=(length cdr h) - 1;
  1190. if n3>jetord then jetord:=n3$
  1191. etapqlist:=cons(list('EQUAL,n1,car h),etapqlist);
  1192. >>
  1193. >>$
  1194. revdylist:=nil;
  1195. %------- output
  1196. if length flist>1 then n:=t
  1197. else n:=nil;
  1198. terpri()$terpri()$
  1199. if null flist then write"No such symmetry does exist. "
  1200. else write"The symmetr",
  1201. if n then "ies are:" else "y is:";
  1202. terpri()$
  1203. xilist:=for each el in xilist collect
  1204. <<e1:=mkid( xi,second el);
  1205. if freeof(flist,e1) then
  1206. for each e2 in fctargs(e1) do nodepend(e1,e2);
  1207. e1:=list('EQUAL,e1,reval car el);
  1208. e1>>;
  1209. etalist:=for each el in etalist collect
  1210. <<e1:=mkid(eta,second el);
  1211. if freeof(flist,e1) then
  1212. for each e2 in fctargs(e1) do nodepend(e1,e2);
  1213. e1:=list('EQUAL,e1,reval car el);
  1214. e1>>;
  1215. %--- Backsubstitution of e.g. u`1`1 --> df(u,x,2)
  1216. for each e1 in ylist do depnd(e1,list(xlist));
  1217. on evallhseqp;
  1218. sb:=subdif1(cons('LIST,xlist),cons('LIST,ylist),jetord)$
  1219. algebraic(
  1220. sb:=for each e1 in sb join
  1221. for each e2 in e1 collect(rhs e2 = lhs e2));
  1222. off evallhseqp;
  1223. xilist :=cdr algebraic(sub(sb,cons('LIST, xilist)));
  1224. etalist :=cdr algebraic(sub(sb,cons('LIST, etalist)));
  1225. etapqlist:=cdr algebraic(sub(sb,cons('LIST,etapqlist)));
  1226. xicop := xilist$
  1227. etacop := etalist$
  1228. etapqcop:=etapqlist$
  1229. sb:=nil$
  1230. flcop:=flist;
  1231. n1:=0;
  1232. for each e1 in flcop do
  1233. <<% if null n2 then n2:=freeof(xicop,e1) and freeof(etacop,e1)$
  1234. if freeof(symcon,e1) then <<
  1235. n1:=n1+1;
  1236. xi:=xicop;eta:=etacop;etapq:=etapqcop;
  1237. for each e2 in flcop do
  1238. if e2 neq e1 then
  1239. <<xi:=subst(0,e2,xi);eta:=subst(0,e2,eta);etapq:=subst(0,e2,etapq)>>
  1240. else
  1241. if null cdr fargs e1 then
  1242. <<xi:=subst(1,e2,xi);eta:=subst(1,e2,eta);etapq:=subst(1,e2,etapq)>>;
  1243. terpri()$write"-------- ",n1,". Symmetry:";terpri()$
  1244. for each e2 in xi do algebraic write reval e2;
  1245. for each e2 in eta do algebraic write reval e2;
  1246. for each e2 in etapq do algebraic write reval e2;
  1247. if cdr fargs e1 then <<terpri()$write"with ";fctprint list(e1);terpri()>>$
  1248. xicop :=subst(0,e1,xicop );
  1249. etacop :=subst(0,e1,etacop );
  1250. etapqcop:=subst(0,e1,etapqcop);
  1251. flcop:=delete(e1,flcop);
  1252. %depl!*:=delete(assoc(e1,depl!*),depl!*)$
  1253. >>;
  1254. >>;
  1255. if flcop neq flist then <<
  1256. terpri()$write"-------- ";terpri()$
  1257. >>;
  1258. if flcop then <<
  1259. if length flist>1 then n:=t
  1260. else n:=nil;
  1261. terpri()$
  1262. if flcop=flist then write"S"
  1263. else write"Further s";
  1264. write"ymmetr",if n then "ies:" else "y:"$
  1265. terpri()$
  1266. for each e1 in xicop do algebraic write reval e1;
  1267. for each e1 in etacop do algebraic write reval e1;
  1268. for each e1 in etapqcop do algebraic write reval e1;
  1269. >>;
  1270. terpri()$
  1271. if flcop then
  1272. <<write"with ";fctprint cdr reval ('LIST . flcop)>>;
  1273. if null symcon then if flcop then
  1274. <<write" which ",if n then "are" else "is"," free. ";
  1275. terpri()>> else
  1276. else
  1277. <<h:=print_;print_:=50$
  1278. if print_ then
  1279. <<terpri()$
  1280. write"which still ",if n then "have" else "has"," to satisfy: ";
  1281. terpri()$
  1282. deprint symcon;
  1283. >> else
  1284. <<terpri()$
  1285. write"which ",if n then "have" else "has",
  1286. " to satisfy conditions. To see them set ";
  1287. terpri()$
  1288. write
  1289. "lisp(print_= max. number of terms of an equation to print);";
  1290. terpri()$
  1291. >>;
  1292. print_:=h
  1293. >>;
  1294. recover_reduce_flags()$
  1295. return list('LIST,'LIST . symcon,'LIST . append(xilist,etalist),
  1296. 'LIST . flist);
  1297. end$ % of liepde
  1298. endmodule$
  1299. end$