ctintro.red 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. module ctintro;
  2. fluid('(dummy_id!* g_dvnames));
  3. % g_dvnames is a vector.
  4. % patches and extensions of some functions of the packages ASSIST and
  5. % DUMMY
  6. %
  7. load_package dummy;
  8. %
  9. % function REMSYM is generalised to take account of partial symmetries
  10. symbolic procedure remsym u;
  11. % ALLOWS TO ELIMINATE THE DECLARED SYMMETRIES.
  12. for each j in u do
  13. if flagp(j,'symmetric) then remflag(list j,'symmetric)
  14. else
  15. if flagp(j,'antisymmetric) then remflag(list j,'antisymmetric)
  16. else remprop(j,'symtree);
  17. % function SYMMETRIZE is generalized for total antisymmetrization
  18. % and for lists of (cyclic-)permutations.
  19. symbolic procedure sym_sign u;
  20. % u is a standard form for the kernel of a tensor.
  21. % if the permutation sign of indices is + then returns u else
  22. % returns negf u.
  23. (if permp!:(ordn y,y) then u else negf u)where y=car select_vars mvar u;
  24. symbolic procedure simpsumsym(u);
  25. % The use is SYMMETRIZE(LIST(A,B,...J),operator,perm_function,[perm_sign])
  26. % or SYMMETRIZE(LIST(LIST(A,B,C...)),operator,perm_function,[perm_sign]).
  27. % [perm_sign] is optional for antisymmetric sums.
  28. % works even if tensors depend explicitly on variables.
  29. % Works both for OPFN and symbolic procedure functions.
  30. % Is not valid for general expressions.
  31. if length u geq 5 then rederr("less than 5 arguments required for symmetrize")
  32. else
  33. begin scalar ut,uu,x,res,oper,fn,sym,bool,boolfn;
  34. integer n, thesign;
  35. thesign := 1;
  36. fn:= caddr u;
  37. oper:=cadr u;
  38. if not idp oper then typerr(oper,"operator") else
  39. if null flagp(oper,'opfn) then
  40. if null get(oper,'simpfn) then put(oper,'simpfn,'simpiden);
  41. flag(list oper, 'listargp);
  42. sym:=if cdddr u then
  43. if cadddr u eq 'perm_sign then t;
  44. if sym and null permp!:(cdar u, ordn cdar u) then thesign:=-thesign;
  45. if not(gettype fn eq 'procedure) then typerr(fn,"procedure");
  46. ut:= select_vars car u;
  47. uu:=(if flagp(fn,'opfn) then <<boolfn:=t; reval x>>
  48. else if car reval x eq 'minus then cdadr reval x
  49. else cdr reval x) where x=oper . car ut;
  50. n:=length uu;
  51. x:=if listp car uu and null flagp(oper,'tensor) and not boolfn then
  52. <<bool:=t;apply1(fn, cdar uu)>> else
  53. if boolfn and listp cadr uu and null flagp(oper,'tensor) then
  54. <<bool:=t;apply1(fn,cadr uu)>>
  55. else apply1(fn,uu); % this applies to tensors
  56. if flagp(fn,'opfn) then x:=alg_to_symb x;
  57. n:=length x -1;
  58. if not bool then <<
  59. res:= if sym then sym_sign((
  60. if cadr ut then oper . (cadr ut . car x)
  61. else oper . car x) .** 1 .* 1 .+ nil)
  62. else
  63. (if cadr ut then oper . (cadr ut . car x)
  64. else oper . car x) .** 1 .* 1 .+ nil ;
  65. for i:=1:n do
  66. << uu:=cadr x; aconc(res, if sym then car sym_sign(
  67. (if cadr ut then oper . (cadr ut . uu)
  68. else oper . uu) .** 1 .* 1 .+ nil)
  69. else
  70. (if cadr ut then oper . (cadr ut . uu)
  71. else oper . uu) .** 1 .* 1); delqip(uu,x);>>;
  72. >>
  73. else
  74. << res:=if sym then sym_sign((oper . list('list .
  75. for each i in car x collect mk!*sq simp!* i)) .** 1 .* 1 .+ nil)
  76. else
  77. (oper . list('list .
  78. for each i in car x collect mk!*sq simp!* i)) .** 1 .* 1 .+ nil;
  79. for i:=1:n do << uu:=cadr x;
  80. aconc(res, if sym then car sym_sign((oper . list('list .
  81. for each j in uu collect simp!* j)) .** 1 .* 1 .+ nil)
  82. else (oper . list('list .
  83. for each i in uu collect mk!*sq simp!* i)) .** 1 .* 1 );
  84. delqip(uu,x);>>;
  85. >>;
  86. return
  87. if get(oper,'tag) eq 'list then
  88. simp!*('list . for each w in res collect caar w)
  89. else
  90. resimp (multf(!*n2f thesign,res) ./ 1)
  91. end;
  92. %load_package dummyn;
  93. % modifications to dummy.red:
  94. % patch to dummy.red
  95. symbolic procedure dummy_nam u;
  96. % creates the required global vector for dummy.red
  97. % A variant of dummy_names from DUMMY.
  98. % No declaration flag(..,'dummy) here since
  99. % it is done inside 'mk_dummy_ids'
  100. <<g_dvnames := list2vect!*(ordn u,'symbolic);t>>;
  101. % This part redefines some of the dummy procedures
  102. % to make it tolerate the covariant-contravariant indices.
  103. % and tensors with NO indices.
  104. symbolic procedure dv_skelsplit(camb);
  105. begin scalar var_camb,skel, stree, subskels;
  106. integer count, ind, maxind, thesign;
  107. thesign := 1;
  108. var_camb:=if listp camb then
  109. if listp cadr camb and caadr camb = 'list then cadr camb;
  110. if (ind := dummyp(camb)) then
  111. return {1, ind, ('!~dv . {'!*, ind})}
  112. else
  113. if not listp camb or (var_camb and null cddr camb)
  114. then return {1, 0, (camb . nil)};
  115. stree := get(car camb, 'symtree);
  116. if not stree then
  117. <<
  118. stree := for count := 1 : length(if var_camb then cddr camb %%
  119. else cdr camb) collect count; %%
  120. if flagp(car camb, 'symmetric) then
  121. stree := '!+ . stree
  122. else if flagp(car camb, 'antisymmetric) then
  123. stree := '!- . stree
  124. else
  125. stree := '!* . stree
  126. >>;
  127. subskels := mkve(length(if var_camb then cddr camb else cdr camb)); %%
  128. count := 0;
  129. for each arg in (if var_camb then cddr camb else cdr camb) do %%
  130. <<
  131. count := count + 1;
  132. if (ind := dummyp(arg)) then
  133. <<
  134. maxind := max(maxind, ind);
  135. if idp arg then putve(subskels, count, ('!~dv . {'!*, ind}))
  136. else putve(subskels, count, ('!~dva . {'!*, ind}))
  137. >>
  138. else
  139. putve(subskels, count, (arg . nil));
  140. >>;
  141. stree := st_sorttree(stree, subskels, function idcons_ordp);
  142. if stree and (car stree = 0) then return nil;
  143. thesign := car stree;
  144. skel := dv_skelsplit1(cdr stree, subskels);
  145. stree := st_consolidate(cdr skel);
  146. skel := if var_camb then (car camb) . var_camb . car skel %%
  147. else car camb . car skel; %%
  148. return {thesign, maxind, skel . stree};
  149. end;
  150. symbolic procedure dummyp(var);
  151. % takes into account the new features i.e.
  152. % some indices may be !0, !1 ....
  153. % others are covariant indices i.e. (minus !<integer>), (minus a) etc ...
  154. begin scalar varsplit;
  155. integer count, res;
  156. if listp var then
  157. if ( careq_minus var) then var:= cadr var
  158. else return nil;
  159. if numberp(var) or (!*id2num var)
  160. then return nil;
  161. count := 1;
  162. while count <= upbve(g_dvnames) do
  163. <<
  164. if var = venth(g_dvnames, count) then
  165. <<
  166. res := count;
  167. count := upbve(g_dvnames) + 1
  168. >>
  169. else
  170. count := count + 1;
  171. >>;
  172. if res = 0 then
  173. <<
  174. varsplit := ad_splitname(var);
  175. if (car varsplit eq g_dvbase) then
  176. return cdr varsplit
  177. >>
  178. else return res;
  179. end;
  180. symbolic procedure dv_skel2factor1(skel_kern, dvars);
  181. % Take into account of the two sets of generic dummy variables.
  182. % One for the ordinary and contravariant dummy variables, another for
  183. % covariant variables.
  184. % !~dva regenerate COVARIANT dummy variables.
  185. begin scalar dvar,scr;
  186. if null skel_kern then return nil;
  187. return
  188. if listp skel_kern then
  189. <<scr:=dv_skel2factor1(car skel_kern, dvars);
  190. scr:=scr . dv_skel2factor1(cdr skel_kern, dvars)
  191. >>
  192. else
  193. if skel_kern eq '!~dv then
  194. <<
  195. dvar := car dvars;
  196. if cdr dvars then
  197. <<
  198. rplaca(dvars, cadr dvars); rplacd(dvars, cddr dvars);
  199. >>;
  200. dvar
  201. >>
  202. else
  203. if skel_kern eq '!~dva then
  204. <<
  205. dvar := car dvars;
  206. if cdr dvars then
  207. <<
  208. rplaca(dvars, cadr dvars); rplacd(dvars, cddr dvars);
  209. >>;
  210. ('minus . dvar . nil)
  211. >>
  212. else
  213. skel_kern;
  214. end;
  215. % end of patch to dummy
  216. endmodule;
  217. end;