edsaux.red 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. module edsaux;
  2. % Miscellaneous support functions
  3. % Author: David Hartley
  4. fluid '(!*edsverbose !*edsdebug);
  5. % Operations on eds
  6. % Storing these kernel lists seems to have <1% effect on speed.
  7. symbolic procedure indkrns s;
  8. % s:eds -> indkrns:list of lpow pf
  9. % independent kernels - leading basis forms in eds_ind s
  10. % geteds(s,'indkrns) or
  11. % puteds(s,'indkrns,
  12. foreach f in eds_ind s join
  13. if tc(f := trterm f) = (1 ./ 1) then {tpow f}; %);
  14. symbolic procedure depkrns s;
  15. % s:eds -> depkrns:list of lpow pf
  16. % dependent kernels - a basis for edscob s/eds_ind s
  17. % OK?
  18. % geteds(s,'depkrns) or
  19. % puteds(s,'depkrns,
  20. foreach f in eds_sys s join
  21. if lc f = (1 ./ 1) and degreepf f = 1 then {lpow f}; %);
  22. symbolic procedure prlkrns s;
  23. % s:eds -> prlkrns:list of lpow pf
  24. % principal kernels - a basis for the non-linear part of s
  25. % geteds(s,'prlkrns) or
  26. % puteds(s,'prlkrns,
  27. setdiff(edscob s,append(indkrns s,depkrns s)); %);
  28. symbolic procedure remkrns s;
  29. % s:eds -> remkrns:nil
  30. foreach p in {'indkrns,'depkrns,'prlkrns} do rempropeds(s,p);
  31. % Operations on sys
  32. symbolic procedure degreepart(s,d);
  33. % s:sys, d:int -> degreepart:sys
  34. foreach f in s join if degreepf f = d then {f};
  35. symbolic procedure scalarpart s;
  36. % s:sys -> scalarpart:sys
  37. degreepart(s,0);
  38. symbolic procedure pfaffpart s;
  39. % s:sys -> pfaffpart:sys
  40. degreepart(s,1);
  41. symbolic procedure nonpfaffpart s;
  42. % s:sys -> nonpfaffpart:sys
  43. foreach f in s join if degreepf f neq 1 then {f};
  44. symbolic procedure solvedpart s;
  45. % s:sys -> solvedpart:sys
  46. foreach f in s join if f and lc f = (1 ./ 1) then {f};
  47. symbolic procedure lpows s;
  48. % s:list of pf -> lpows:list of lpow pf
  49. % returns the leading kernels in s
  50. foreach f in s collect lpow f;
  51. symbolic procedure singleterms s;
  52. % s:list of pf -> singleterms:bool
  53. % true if each form in s is a single term
  54. null s or null red car s and singleterms cdr s;
  55. symbolic procedure !*a2sys u;
  56. % u:prefix list -> !*a2sys:list of pf
  57. if rlistp u then
  58. foreach f in cdr indexexpandeval{u} collect xpartitop f
  59. else typerr(u,'list);
  60. symbolic procedure !*sys2a u;
  61. % u:list of pf -> !*sys2a:prefix list
  62. makelist foreach f in u collect !*pf2a f;
  63. symbolic procedure !*sys2a1(u,v);
  64. % u:list of pf -> !*sys2a:prefix list
  65. % !*sys2a with choice of !*sq or true prefix
  66. makelist foreach f in u collect !*pf2a1(f,v);
  67. % Operations on pf
  68. symbolic procedure xpows f;
  69. % f:pf -> xpows:list of lpow pf
  70. if f then lpow f . xpows red f;
  71. symbolic procedure xcoeffs f;
  72. % f:pf -> xcoeffs:list of sq
  73. if f then lc f . xcoeffs red f;
  74. symbolic procedure degreepf f;
  75. % f:pf -> degreepf:int
  76. % assumes f homogeneous
  77. % could replace with xdegree from XIDEAL2
  78. if null f then 0
  79. else (if null x then 0
  80. else if fixp x then x
  81. else rerror('eds,130,"Non-integral degree not allowed in EDS"))
  82. where x = deg!*form lpow f;
  83. symbolic procedure xreorder f;
  84. % f:pf -> xreorder:pf
  85. if f then
  86. addpf(multpfsq(xpartitop lpow f,reordsq lc f),
  87. xreorder red f);
  88. symbolic procedure xreorder!* f;
  89. % f:pf -> xreorder!*:pf
  90. % Like xreorder when it is known that only the order between terms
  91. % has changed (and not within terms).
  92. if f and red f then
  93. addpf(lt f .+ nil,xreorder!* red f)
  94. else f;
  95. symbolic procedure xrepartit f;
  96. % f:pf -> xrepartit:pf
  97. if f then
  98. addpf(wedgepf(xpartitsq subs2 resimp lc f,xpartitop lpow f),
  99. xrepartit red f);
  100. symbolic procedure xrepartit!* f;
  101. % f:pf -> xrepartit!*:pf
  102. % Like xrepartit when xvars!* hasn't changed.
  103. if f then
  104. addpf(multpfsq(xpartitop lpow f,subs2 resimp lc f),
  105. xrepartit!* red f);
  106. symbolic procedure trterm f;
  107. % f:pf -> trterm:lt pf
  108. % the trailing term in f
  109. if null red f then lt f else trterm red f;
  110. symbolic procedure linearpart(f,p);
  111. % f:pf, p:list of 1-form kernel -> linearpart:pf
  112. % result is the part of f of degree 1 in p
  113. if null f then nil
  114. else if length intersection(wedgefax lpow f,p) = 1 then
  115. lt f .+ linearpart(red f,p)
  116. else linearpart(red f,p);
  117. symbolic procedure inhomogeneouspart(f,p);
  118. % f:pf, p:list of 1-form kernel -> inhomogeneouspart:pf
  119. % result is the part of f of degree 0 in p
  120. if null f then nil
  121. else if length intersection(wedgefax lpow f,p) = 0 then
  122. lt f .+ inhomogeneouspart(red f,p)
  123. else inhomogeneouspart(red f,p);
  124. symbolic procedure xcoeff(f,c);
  125. % f:pf, c:pffax -> xcoeff:pf
  126. if null f then nil
  127. else
  128. begin scalar q,s;
  129. q := xdiv(c,wedgefax lpow f);
  130. if null q then return xcoeff(red f,c);
  131. q := mknwedge q;
  132. if append(q,c) = lpow f then s := 1 % an easy case
  133. else s := numr lc wedgepf(!*k2pf q,!*k2pf mknwedge c);
  134. return q .* (if s = 1 then lc f else negsq lc f)
  135. .+ xcoeff(red f,c);
  136. end;
  137. symbolic procedure xvarspf f;
  138. % f:pf -> xvarspf:list of kernel
  139. if null f then nil
  140. else
  141. union(foreach k in
  142. append(wedgefax lpow f,
  143. append(kernels numr lc f,
  144. kernels denr lc f)) join if xvarp k then {k},
  145. xvarspf red f);
  146. symbolic procedure kernelspf f;
  147. % f:pf -> kernelspf:list of kernel
  148. % breaks up wedge products
  149. if null f then nil
  150. else
  151. union(append(wedgefax lpow f,
  152. append(kernels numr lc f,
  153. kernels denr lc f)),
  154. kernelspf red f);
  155. symbolic procedure mkform!*(u,p);
  156. % u:prefix, p:prefix (usually int) -> mkform!*:prefix
  157. % putform with u returned, and covariant flag removed
  158. begin
  159. putform(u,p);
  160. return u;
  161. end;
  162. % Operations on lists
  163. symbolic procedure purge u;
  164. % u:list -> purge:list
  165. % remove repeated elements from u, leaving last occurence only
  166. if null u then nil
  167. else if car u member cdr u then purge cdr u
  168. else car u . purge cdr u;
  169. symbolic procedure rightunion(u,v);
  170. % u,v:list -> rightunion:list
  171. % Like union, but appends v to right. Ordering of u and v preserved
  172. % (last occurence of each element in v used).
  173. append(u,foreach x on v join
  174. if not(car x member u) and not(car x member cdr x) then {car x});
  175. symbolic procedure sublisq(u,v);
  176. % u:a-list, v:any -> sublisq:any
  177. % like sublis, but leaves structure untouched where possible
  178. if null u or null v then v
  179. else
  180. begin scalar x,y;
  181. if (x := atsoc(v,u)) then return cdr x;
  182. if atom v then return v;
  183. y := sublisq(u,car v) . sublisq(u,cdr v);
  184. return if y = v then v else y;
  185. end;
  186. symbolic procedure ordcomb(u,n);
  187. % u:list, n:int -> ordcomb:list of list
  188. % List of all combinations of n distinct elements from u.
  189. % Order of u is preserved: ordcomb(u,1) = mapcar(u,'list)
  190. % which is not true for comb, from which this is copied.
  191. begin scalar v; integer m;
  192. if n=0 then return {{}}
  193. else if (m:=length u-n)<0 then return {}
  194. else for i := 1:m do
  195. <<v := nconc!*(v,mapcons(ordcomb(cdr u,n-1),car u));
  196. u := cdr u>>;
  197. return nconc!*(v,{u})
  198. end;
  199. symbolic procedure updkordl u;
  200. % u:list of kernel -> updkordl:list of kernel
  201. % list version of updkorder
  202. % kernels in u will have highest precedence, order of
  203. % other kernels unchanged
  204. begin scalar v,w;
  205. v := kord!*;
  206. w := append(u,setdiff(v,u));
  207. if v=w then return v;
  208. kord!* := w;
  209. alglist!* := nil . nil; % Since kernel order has changed.
  210. return v
  211. end;
  212. symbolic procedure allequal u;
  213. % u:list of any -> allequal:bool
  214. % t if all elements of u are equal
  215. if length u < 2 then t
  216. else car u = cadr u and allequal cdr u;
  217. symbolic procedure allexact u;
  218. % u:list of kernel -> allexact:bool
  219. % t if all elements of u are exact pforms
  220. if null u then t
  221. else exact car u and allexact cdr u;
  222. symbolic procedure coords u;
  223. % u:list of kernel -> coords:list of kernel
  224. % kernels in u are 1-forms, returns coordinates involved
  225. % THIS SHOULD GO
  226. foreach k in u join if exact k then {cadr k};
  227. symbolic procedure zippf(pfl,sql);
  228. % pfl:list of pf, sql:list of sq
  229. % -> zippf:pf
  230. % Multiply elements of pfl by corresponding elements of sql, and add
  231. % results together. If trailing nulls on pfl or sql can be omitted.
  232. if null pfl or null sql then nil
  233. else if numr car sql and car pfl then
  234. addpf(multpfsq(car pfl,car sql),zippf(cdr pfl,cdr sql))
  235. else
  236. zippf(cdr pfl,cdr sql);
  237. % EDS tracing and debugging
  238. symbolic procedure errdhh u;
  239. % Special error call for errors that shouldn't happen
  240. rerror(eds,999,"Internal EDS error -- please contact David Hartley
  241. *****" . if atom u then {u} else u);
  242. symbolic procedure edsverbose(msg,v,type);
  243. % msg:atom or list, v:various, type:id|nil
  244. % -> edsverbose:nil
  245. % type gives the type of v, one of
  246. % nil - v is empty
  247. % 'sf - v is a list of sf
  248. % 'sq - v is a list of sq
  249. % 'sys - v is a list of pf
  250. % 'cob - v is a list of kernel
  251. % 'map - v is a map (list of kernel.prefix)
  252. % 'xform - v is an xform (list of kernel.pf)
  253. % 'prefix- v is prefix
  254. if !*edsverbose or !*edsdebug then
  255. begin
  256. if atom msg then msg := {msg};
  257. lpri msg; terpri();
  258. if null type then nil
  259. else if type = 'sf then
  260. foreach f in v do edsmathprint prepf f
  261. else if type = 'sq then
  262. foreach f in v do edsmathprint prepsq f
  263. else if type = 'sys then
  264. foreach f in v do edsmathprint preppf f
  265. else if type = 'cob then
  266. edsmathprint makelist v
  267. else if type = 'map then
  268. foreach p in v do edsmathprint {'equal,car p,cdr p}
  269. else if type = 'rmap then
  270. << foreach p in car v do edsmathprint {'equal,car p,cdr p};
  271. foreach p in cadr v do edsmathprint {'neq,p,0} >>
  272. else if type = 'xform then
  273. foreach p in v do edsmathprint {'equal,car p,preppf cdr p}
  274. else if type = 'prefix then
  275. edsmathprint v
  276. else errdhh{"Unrecognised type",type,"in edsverbose"};
  277. end;
  278. symbolic procedure edsdebug(msg,v,type);
  279. % msg:string, v:various, type:id|nil
  280. % -> edsdebug:nil
  281. % Like edsverbose, just for debugging.
  282. if !*edsdebug then edsverbose(msg,v,type);
  283. symbolic procedure edsmathprint f;
  284. % f:prefix -> nil
  285. % Similar to mathprint, except going in at writepri,
  286. % so TRI package picks it up too.
  287. <<writepri(mkquote f,'only); terpri!* t; >>;
  288. endmodule;
  289. end;