vdpcom.red 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. module vdpcom;
  2. % Common routines to all vdp mappings.
  3. flag('(vdpprintmax),'share);
  4. vdpprintmax:=5;
  5. % Repeat of smacros defined in vdp2dip.
  6. smacro procedure vdppoly u;cadr cddr u;
  7. smacro procedure vdpzero!? u;null u or null vdppoly u;
  8. smacro procedure vdpevlmon u;cadr u;
  9. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  10. %
  11. % manipulating of exponent vectors
  12. %
  13. symbolic procedure vevnth(a,n);
  14. % Extract nth element from 'a'.
  15. if null a then 0 else if n=1 then car a else vevnth(cdr a,n #- 1);
  16. % Unrolled code for zero test(very often called).
  17. smacro procedure vevzero!? u;
  18. null u or(car u=0 and vevzero!?1 cdr u);
  19. symbolic procedure vevzero!?1 u;
  20. null u or(car u=0 and vevzero!? cdr u);
  21. symbolic procedure veveq(vev1,vev2);
  22. if null vev1 then vevzero!? vev2
  23. else if null vev2 then vevzero!? vev1
  24. else(car vev1=car vev2 and vevequal(cdr vev1,vev2));
  25. symbolic procedure vevmaptozero e;
  26. % Generate an exponent vector with same length as e and zeros only.
  27. vevmaptozero1(e,nil);
  28. symbolic procedure vevmaptozero1(e,vev);
  29. if null e then vev else vevmaptozero1(cdr e,0 .vev);
  30. symbolic procedure vevmtest!?(e1,e2);
  31. % Exponent vector multiple test.'e1' and 'e2' are compatible exponent
  32. % vectors.vevmtest?(e1,e2) returns a boolean expression.
  33. % True if exponent vector 'e1' is a multiple of exponent
  34. % vector 'e2', else false.
  35. if null e2 then t else if null e1 then if vevzero!? e2 then t else nil
  36. else not(car e1 #< car e2)and vevmtest!?(cdr e1,cdr e2);
  37. symbolic procedure vevlcm(e1,e2);
  38. % Exponent vector least common multiple.'e1' and 'e2' are
  39. % exponent vectors.'vevlcm(e1,e2)' computes the least common
  40. % multiple of the exponent vectors 'e1' and 'e2', and returns
  41. % an exponent vector.
  42. begin scalar x;
  43. while e1 and e2 do
  44. <<x:=(if car e1 #> car e2 then car e1 else car e2).x;
  45. e1:=cdr e1;e2:=cdr e2>>;
  46. x:=reversip x;
  47. if e1 then x:=nconc(x,e1)else if e2 then x:=nconc(x,e2);
  48. return x end;
  49. symbolic procedure vevmin(e1,e2);
  50. % Exponent vector minima.
  51. begin scalar x;
  52. while e1 and e2 do
  53. <<x:=(if car e1 #< car e2 then car e1 else car e2).x;
  54. e1:=cdr e1;e2:=cdr e2>>;
  55. while x and 0=car x do x:=cdr x;% Cut trailing zeros.
  56. return reversip x end;
  57. symbolic procedure vevsum(e1,e2);
  58. % Exponent vector sum.'e1' and 'e2' are exponent vectors.
  59. % 'vevsum(e1,e2)' calculates the sum of the exponent vectors
  60. % 'e1' and 'e2' componentwise and returns an exponent vector.
  61. begin scalar x;
  62. while e1 and e2 do
  63. <<x:=(car e1 #+ car e2).x;e1:=cdr e1;e2:=cdr e2>>;
  64. x:=reversip x;
  65. if e1 then x:=nconc(x,e1)else if e2 then x:=nconc(x,e2);
  66. return x end;
  67. symbolic procedure vevtdeg u;
  68. % Calculate the total degree of u.
  69. if null u then 0 else car u #+ vevtdeg cdr u;
  70. symbolic procedure vdptdeg u;
  71. if vdpzero!? u then 0 else
  72. max(vevtdeg vdpevlmon u,vdptdeg vdpred u);
  73. symbolic procedure vevdif(ee1,ee2);
  74. % Exponent vector difference.'e1' and 'e2' are exponent
  75. % vectors.'vevdif(e1,e2)' calculates the difference of the
  76. % exponent vectors componentwise and returns an exponent vector.
  77. begin scalar x,y,break,e1,e2;
  78. e1:=ee1;e2:=ee2;
  79. while e1 and e2 and not break do
  80. <<y:=(car e1 #- car e2);x:=y.x;break:=y #< 0;
  81. e1:=cdr e1;e2:=cdr e2>>;
  82. if break or(e2 and not vevzero!? e2)then
  83. <<print ee1;print ee2;if getd 'backtrace then backtrace();
  84. return rerror(dipoly,5,"Vevdif, difference would be < 0")>>;
  85. return nconc(reversip x,e1)end;
  86. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  87. %
  88. % Numbering of polynomials.
  89. %
  90. symbolic procedure vdpenumerate f;
  91. % 'f' is a temporary result.Prepare it for medium range storage
  92. % and sign a number.
  93. if vdpzero!? f then f else
  94. <<f:=vdpsave f;
  95. if not vdpgetprop( f,'number)then
  96. f:=vdpputprop(f,'number,(pcount!*:=pcount!* #+ 1));f>>;
  97. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  98. %
  99. % SUGAR of polynomials.
  100. %
  101. symbolic procedure gsugar p;
  102. if !*gsugar then
  103. (( s or
  104. <<print{"*** missing sugar",p};backtrace();
  105. s:=vdptdeg p;gsetsugar(p,s);s>>
  106. )where s= if vdpzero!? p then 0 else vdpgetprop(p,'sugar));
  107. symbolic procedure gsetsugar(p,s);
  108. !*gsugar and vdpputprop(p,'sugar,s or vdptdeg p)or p;
  109. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  110. %
  111. % Operations on sets of polynomials.
  112. %
  113. symbolic procedure vdpmember(p1,l);
  114. % Test membership of a polynomial in a list of polys.
  115. if null l then nil else
  116. if vdpequal(p1,car l)then l else vdpmember(p1,cdr l);
  117. symbolic procedure vdpunion(s1,s2);
  118. % 's1' and 's2' are two sets of polynomials;
  119. % union of the sets using vdpMember as crit.
  120. if null s1 then s2 else
  121. if vdpmember(car s1,s2)then vdpunion(cdr s1,s2)
  122. else car s1.vdpunion(cdr s1,s2);
  123. symbolic procedure vdpintersection(s1,s2);
  124. % 's1' and 's2' are two sets of polynomials;
  125. % intersection of the sets using vdpmember as crit.
  126. if null s1 then nil else
  127. if vdpmember(car s1,s2)then car s1.vdpunion(cdr s1,s2)
  128. else vdpunion(cdr s1,s2);
  129. symbolic procedure vdpsetequal!?(s1,s2);
  130. % Tests if 's1' and 's2' have the same polynomials as members.
  131. if not(length s1=length s2)then nil
  132. else vdpsetequal!?1(s1,append(s2,nil));
  133. symbolic procedure vdpsetequal!?1(s1,s2);
  134. % Destroys its second parameter(is therefore copied when called).
  135. if null s1 and null s2 then t else
  136. if null s1 or null s2 then nil else
  137. (if hugo then vdpsetequal!?1(cdr s1,groedeletip(car hugo,s2))
  138. else nil)where hugo=vdpmember(car s1,s2);
  139. symbolic procedure vdpsortedsetequal!?(s1,s2);
  140. % Tests if 's1' and 's2' have the same polynomials as members
  141. % here assuming, that both sets are sorted by the same principles.
  142. if null s1 and null s2 then t else if null s1 or null s2 then nil else
  143. if vdpequal(car s1,car s2)then
  144. vdpsortedsetequal!?(cdr s1,cdr s2)else nil;
  145. symbolic procedure vdpdisjoint!?(s1,s2);
  146. % 's1' and 's2' are two sets of polynomials;
  147. % test that there are no common members.
  148. if null s1 then t else
  149. if vdpmember(car s1,s2)then nil else vdpdisjoint!?(cdr s1,s2);
  150. symbolic procedure vdpsubset!?(s1,s2);
  151. not(length s1 > length s2)and vdpsubset!?1(s1,s2);
  152. symbolic procedure vdpsubset!?1(s1,s2);
  153. % 's1' and 's2' are two sets of polynomials.
  154. % Test if 's1' is subset of 's2'.
  155. if null s1 then t else
  156. if vdpmember(car s1,s2)then vdpsubset!?1(cdr s1,s2)else nil;
  157. symbolic procedure vdpdeletemember(p,l);
  158. % Delete polynomial 'p' from list 'l'.
  159. if null l then nil else
  160. if vdpequal(p,car l)then vdpdeletemember(p,cdr l)
  161. else car l.vdpdeletemember(p,cdr l);
  162. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  163. %
  164. % Sorting of polynomials.
  165. %
  166. symbolic procedure vdplsort pl;
  167. % Distributive polynomial list sort.'pl' is a list of
  168. % distributive polynomials.'vdplsort(pl)' returns the
  169. % sorted distributive polynomial list of pl.
  170. sort(pl,function vdpvevlcomp);
  171. symbolic procedure vdplsortin(p,pl);
  172. % 'p' is a polynomial, 'pl' is a list of polynomials.
  173. % 'p' is inserted into 'pl' at its place determined by vevlcompless?.
  174. % The result is the updated pl.
  175. if null pl then{p}else<<vdplsortin1(p,pl,pl);pl>>;
  176. symbolic procedure vdplsortin1(p,pl,oldpl);
  177. if null pl then cdr oldpl:= p.nil
  178. else if vevcompless!?(vdpevlmon p,vdpevlmon car pl)
  179. then vdplsortin1(p,cdr pl,pl)
  180. else <<cdr pl:=car pl.cdr pl;car pl:=p>>;
  181. symbolic procedure vdplsortinreplacing(po,pl);
  182. % 'po' is a polynomial, 'pl' is a linear list of polynomials(sorted).
  183. % 'po' is inserted into 'pl' at its place determined by 'vevlcompless?'.
  184. % If there is a multiple of the first exponent of a polynomial in 'pl',
  185. % this one is deleted from 'pl'.The result is the updated 'pl'.
  186. % 'opl' is the initial value of 'pl',(initial multiples of 'po' are
  187. % removed);'oopl' a working version of 'opl'.
  188. begin scalar oopl,opl;if pl then go to bb;
  189. aa : return po.nil;
  190. bb : if vevdivides!?(vdpevlmon po,vdpevlmon car pl)then
  191. <<pl:=cdr pl;if null pl then go to aa;go to bb>>;
  192. opl:=pl;
  193. cc : if null pl then
  194. <<oopl:=lastpair opl;cdr oopl:=po.nil;return opl>>;
  195. if not(pl eq opl)and vevdivides!?(vdpevlmon po,vdpevlmon car pl)then
  196. <<if null cdr pl then
  197. <<oopl:=lastpair1 opl;cdr oopl:=nil;pl:=nil>>
  198. else <<car pl:=cadr pl;cdr pl:=cddr pl>>; go to cc>>;
  199. if vevcompless!?(vdpevlmon po,vdpevlmon car pl)then
  200. <<pl:=cdr pl;go to cc>>;
  201. cdr pl:=car pl.cdr pl;car pl:=po;% Insert 'po'.
  202. return opl end;
  203. symbolic procedure lastpair1 opl;
  204. % Determine the last full pair(the 'cdr' non-nil)of the linear list
  205. % 'opl';if the routine is called with 'nil' or cdr='nil',
  206. % return 't'.
  207. if null opl or null cdr opl then t else
  208. <<while cddr opl do opl:=cdr opl;opl>>;
  209. symbolic procedure countlastvar(a,m);
  210. % Count the monomials with the last variable of a vdp-polynomial
  211. % 'a';'m' determines, whether the first('m' is true)non-factor
  212. % of the last variable leads to the result '0';if the polynomial has more
  213. % than 25 elements, return '0' if 'm' is false or if the polynomial has
  214. % more than 25 terms(divisible by the last variable).
  215. begin integer n,nn;a:=vdppoly a;
  216. aa: if atom a then return n;
  217. nn:=nn #+ 1;if nn #> 25 then return 0;n:=n #+ 1;
  218. if countlastvar1 dipevlmon a #< 1 then(if m then return 0 else n:=0);
  219. a:=dipmred a;go to aa end;
  220. symbolic procedure countlastvar1 b;
  221. begin scalar n;n:=1;
  222. aa : if atom b then return 0 else if n=vdplastvar!* then return car b;
  223. b:=cdr b;n:=n #+ 1;go to aa end;
  224. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  225. %
  226. % Property lists for polynomials.
  227. %
  228. symbolic procedure vdpputprop(poly,prop,val);
  229. begin scalar c,p;
  230. if not pairp poly or not pairp(c:=cdr poly)or not pairp(c:=cdr c)
  231. or not pairp(c:=cdr c)or not pairp(c:=cdr c)
  232. then rerror(dipoly,6,
  233. {"vdpputprop given a non-vdp as 1st parameter",poly,prop,val});
  234. p:=assoc(prop,car c);
  235. if p then rplacd(p,val)else rplaca(c,(prop.val).car c);
  236. return poly end;
  237. symbolic procedure vdpgetprop(poly,prop);
  238. if null poly then nil % nil is a legal variant of vdp=0
  239. else if not eqcar(poly,'vdp)
  240. then rerror( dipoly,7,
  241. {"vdpgetprop given a non-vdp as 1st parameter",
  242. poly,prop})
  243. else(if p then cdr p else nil)
  244. where p=assoc(prop,cadr cdddr poly);
  245. symbolic procedure vdpremallprops u;
  246. begin scalar c;
  247. if not(not pairp u or not pairp(c:=cdr u)or not pairp(c:=cdr c)
  248. or not pairp(c:=cdr c)or not pairp(c:=cdr c))
  249. then rplaca(c,nil);return u end;
  250. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  251. %
  252. % Groebner interface to power substitution.
  253. %
  254. fluid'(!*sub2);
  255. symbolic procedure groebsubs2 q;(subs2 q)where !*sub2=t;
  256. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  257. %
  258. % And a special print.
  259. %
  260. symbolic procedure vdpprintshort u;
  261. begin scalar m;
  262. m:=vdpprintmax;vdpprintmax:= 2;vdpprint u;vdpprintmax:=m end;
  263. endmodule;;end;