edsexptl.red 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. module edsexptl;
  2. % Experimental (algebraic mode) operators
  3. % Author: David Hartley
  4. % These procedures need the other packages loaded during compilation
  5. load_package 'xideal;
  6. %%%% Characteristic variety, symbol relations and symbol matrix
  7. Comment. At present, algebraic routines.
  8. endcomment;
  9. fluid '(!*varopt !*arbvars xvars!* !*allbranch);
  10. symbolic operator indexnames;
  11. symbolic procedure indexnames u;
  12. begin
  13. u := makelist uniqids foreach k in getrlist u collect !*a2k k;
  14. apply1('indexrange,{{'equal,gensym(),u}});
  15. return u;
  16. end;
  17. algebraic procedure symbol_relations(S,name);
  18. % S:eds, name:id -> symbol_relations:list of 1-form
  19. begin scalar tbl,ix,sys,pis,!*varopt,!*arbvars;
  20. pform name(i,j) = 1;
  21. tbl := tableau S;
  22. ix := indexnames independence S;
  23. for i:=1:first length tbl do
  24. indexrange !!symbol!!index=i;
  25. pis := for i:=1:first length tbl collect
  26. foreach j in ix collect name(i,-j);
  27. sys := for i:=1:first length tbl join
  28. for j:=1:length ix collect (tbl(i,j) - part(pis,i,j));
  29. pis := foreach l in pis join l;
  30. sys := first solve(sys,append(cobasis s,pis));
  31. sys := foreach x in sys join
  32. if lhs x member pis then {lhs x - rhs x} else {};
  33. return sys;
  34. end;
  35. algebraic procedure symbol_matrix(S,name);
  36. % S:eds, name:id -> symbol_matrix:matrix of 0-form
  37. begin scalar sys,wlist,n;
  38. pform name(i) = 0,{!!symbol!!pi(i,j),!!symbol!!w(i)}=1;
  39. n := first length tableau S;
  40. wlist := for i:=1:n collect !!symbol!!w(i);
  41. sys := symbol_relations(S,!!symbol!!pi);
  42. rl := for i:=1:n join
  43. foreach j in indexnames independence S collect
  44. make_rule(!!symbol!!pi(i,-j),!!symbol!!w(i)*name(-j));
  45. let rl;
  46. % sys := (sys where rl);
  47. sys := sys;
  48. % write showrules !!symbol!!pi;
  49. clearrules rl;
  50. matrix !!symbol!!mat(length sys,length wlist);
  51. for i:=1:length sys do
  52. for j:=1:length wlist do
  53. !!symbol!!mat(i,j) := coeffn(part(sys,i),part(wlist,j),1);
  54. return !!symbol!!mat;
  55. end;
  56. algebraic procedure characteristic_variety(S,name);
  57. % S:eds, name:id -> characteristic_variety:{list of 0-form,list of
  58. % variable}
  59. begin scalar ix,m,sys;
  60. scalar xvars!*; % make all 0-forms coefficients
  61. ix := indexnames independence S;
  62. m := symbol_matrix(S,name);
  63. if first length m > second length m then m := tp m;
  64. for i:=1:second length m do
  65. indexrange symbol!!index!!=i;
  66. wlist := for i:=1:second length m collect !!symbol!!w(i);
  67. www := 1;
  68. for i:=1:first length m do
  69. www := (for j:=1:length wlist sum m(i,j)*!!symbol!!w(j))^www;
  70. return {excoeffs www,foreach i in ix collect name(-i)};
  71. end;
  72. algebraic procedure make_rule(lh,rh);
  73. lh => rh;
  74. %%% Invariants, or first integrals.
  75. fluid '(!*edsdebug print_ fname_ time_ xvars!* !*allbranch !*arbvars);
  76. mkform!*('eds!:t,0);
  77. algebraic procedure edsorderp(x,y);
  78. % Just a hook for sort
  79. if ordp(x,y) then 1 else 0;
  80. put('invariants,'psopfn,'invariants);
  81. symbolic procedure invariants u;
  82. if length u = 2 then
  83. (algebraic invariants0(x,y)) where x=car u, y=cadr u
  84. else if length u = 1 then
  85. (algebraic invariants0(x,y)) where x=car u, y=makelist nil
  86. else
  87. rederr "Wrong number of arguments to invariants";
  88. algebraic procedure invariants0(S,C);
  89. begin scalar ans,inv,cfrm,Z,xvars!*;
  90. load_package odesolve,crack;
  91. % Update for CRACK version 1-Dec-2002
  92. setcrackflags();
  93. cfrm := coframing();
  94. if part(S,0) = eds then
  95. << set_coframing S;
  96. if C = {} then C := coordinates S;
  97. S := systemeds S >> % Use systemeds rather than system for
  98. % compiler.
  99. else
  100. S := xauto S;
  101. if C = {} then C := reverse sort(coordinates S,edsorderp);
  102. Z := for a:=1:length S collect lisp mkform!*(mkid('eds!:u,a),0);
  103. ans := foliation(S,C,Z);
  104. inv := solve(ans,Z);
  105. if length Z = 1 then
  106. inv := foreach x in inv collect {x};
  107. if lisp !*edsdebug then write "Constants";
  108. if lisp !*edsdebug then write inv;
  109. if length inv neq 1 then
  110. rederr "Not a unique solution";
  111. set_coframing cfrm;
  112. return foreach x in first inv collect rhs x;
  113. end;
  114. algebraic procedure foliation(S,C,Z);
  115. begin scalar r,n,x,S0,Z0,g,Q,f,f0;
  116. scalar print_,fname_,time_,!*allbranch,!*arbvars,xvars!*;
  117. % Constants
  118. r := length S;
  119. n := length C;
  120. fname_ := 'eds!:c;
  121. % Deal with errors and end case
  122. if r > n then
  123. rerror(eds,000,"Not enough coordinates in foliation");
  124. if r neq length Z then
  125. rerror(eds,000,"Wrong number of invariant labels in foliation");
  126. if r = n then
  127. << g := for a:=1:r collect part(C,a) = part(Z,a);
  128. lisp edsdebug("Intermediate result",g,'prefix);
  129. return g >>;
  130. % Choose truncation
  131. S0 := {}; Z0 := {};
  132. while length S0 < r do
  133. << x := first C;
  134. C := rest C;
  135. Z0 := x . Z0;
  136. S0 := xauto(S xmod {d x}) >>;
  137. C := append(C,rest Z0);
  138. lisp edsdebug("Truncating coordinate : ",x,'prefix);
  139. % Compute foliation for truncation
  140. g := foliation(S0,C,Z);
  141. % Calculate ODE
  142. foreach y in Z do
  143. << lisp(y := !*a2k y); fdomain y=y(eds!:t) >>;
  144. S := pullback(S,g);
  145. S := pullback(S,{x = eds!:t});
  146. Q := foreach f in S collect @eds!:t _| f;
  147. Q := solve(Q,foreach y in Z collect @(y,eds!:t));
  148. if r neq 1 then Q := first Q;
  149. Q := foreach f in Q collect (lhs f - rhs f);
  150. Q := sub(partdf=df,Q);
  151. lisp edsdebug("CRACK ODE",Q,'prefix);
  152. % Solve ODE
  153. Q := crack(Q,{},Z,{});
  154. % Restore 0-form properties of Z (cleared by CRACK)
  155. foreach y in Z do
  156. << lisp(y := !*a2k y); lisp mkform!*(y, 0) >>;
  157. lisp edsdebug("CRACK solution",Q,'prefix);
  158. % Analyse result for the general solution
  159. f := {};
  160. while Q neq {} do
  161. << f := first Q; Q := rest Q;
  162. Z0 := third f;
  163. if first f = {} and length Z0 = r then Q := {}
  164. else if length Z0 > r then
  165. if length(f0 := solve(first f,Z)) = 0 then f := {}
  166. else
  167. << if r = 1 then f0 := {{first f0}};
  168. Z0 := foreach v in Z0 join
  169. if v member Z then {} else {v};
  170. f := {{},append(second f,first f0),Z0};
  171. Q := {} >>
  172. else f := {} >>;
  173. foreach y in Z do
  174. << lisp(y := !*a2k y); remfdomain y >>;
  175. if f = {} then
  176. rerror(eds,000,"Intermediate ODE general solution not found");
  177. % Compose general solution with truncated foliation
  178. g := sub(second f,g);
  179. f := (eds!:t = x) . for a := 1:r collect part(Z0,a) = part(Z,a);
  180. g := sub(f,g);
  181. lisp edsdebug("Intermediate result",g,'prefix);
  182. return g;
  183. end;
  184. %%% Homotopy operator
  185. algebraic procedure poincare df;
  186. % with df a closed p-form POINCARE returns a (p-1)-form f
  187. % satisfying df=d f.
  188. begin scalar f;
  189. pform !!lambda!! = 0;
  190. f := sub(for each c in coordinates df collect c = c * !!lambda!!,df);
  191. % f := sub(for each c in allcoords df collect c = c * !!lambda!!,df);
  192. f := @(!!lambda!!) _| f;
  193. f := int(f,!!lambda!!);
  194. f := sub(!!lambda!! = 1,f) - sub(!!lambda!! = 0,f);
  195. % if d f - df neq 0 then write "error in POINCARE";
  196. return reval f;
  197. end;
  198. %%% Integrability conditions
  199. put('integrability,'rtypefn,'quotelist);
  200. put('integrability,'listfn,'evalintegrability);
  201. symbolic procedure evalintegrability(s,v);
  202. % s:eds|rlist, v:bool -> evalintegrability:rlist
  203. if edsp(s := reval car s) then
  204. !*sys2a1(nonpfaffpart eds_sys edscall closure s,v)
  205. else
  206. algebraic append(s xmod one_forms s,d s xmod one_forms s);
  207. endmodule;
  208. end;