scripts.red 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. module scripts;
  2. COMMENT
  3. ######################
  4. ## ##
  5. ## ADVANCED ##
  6. ## APPLICATIONS ##
  7. ## ##
  8. ######################
  9. This module contains several additional advanced applications of
  10. standard basis computations, inspired partly by the scripts
  11. distributed with the commutative algebra package MACAULAY
  12. (Bayer/Stillman/Eisenbud).
  13. The following topics are currently covered :
  14. - [BGK]'s heuristic variable optimization
  15. - certain stuff on maps (preimage, ratpreimage)
  16. - ideals of points (in affine and proj. spaces)
  17. - ideals of (affine and proj.) monomial curves
  18. - General Rees rings, associated graded rings, and related
  19. topics (analytic spread, symmetric algebra)
  20. - several short scripts (minimal generators, symbolic powers
  21. of primes, singular locus)
  22. END COMMENT;
  23. %---------- [BGK]'s heuristic variable optimization ----------
  24. symbolic operator varopt;
  25. symbolic procedure varopt m;
  26. if !*mode='algebraic then makelist varopt!* dpmat_from_a m
  27. else varopt!* m;
  28. symbolic procedure varopt!* m;
  29. % Find a heuristically optimal variable order.
  30. begin scalar c; c:=mo_zero();
  31. for each x in dpmat_list m do
  32. for each y in bas_dpoly x do c:=mo_lcm(c,car y);
  33. return
  34. for each x in
  35. sort(mo_2list c,function(lambda(x,y); cdr x>cdr y)) collect
  36. car x;
  37. end;
  38. % ----- Certain stuff on maps -------------
  39. % A ring map is represented as a list
  40. % {preimage_ring, image_ring, subst_list},
  41. % where subst_list is a substitution list {v1=ex1,v2=ex2,...} in
  42. % algebraic prefix form, i.e. looks like (list (equal var image) ...)
  43. symbolic operator preimage;
  44. symbolic procedure preimage(m,map);
  45. % Compute the preimage of an ideal m under a (polynomial) ring map.
  46. if !*mode='algebraic then
  47. begin map:=cdr reval map;
  48. return preimage!*(reval m,
  49. {ring_from_a first map, ring_from_a second map, third map});
  50. end
  51. else preimage!*(m,map);
  52. symbolic procedure preimage!*(m,map);
  53. % m and the result are given and returned in algebraic prefix form.
  54. if not !*noetherian then
  55. rederr"PREIMAGE only for noetherian term orders"
  56. else begin scalar u,oldring,newring,oldnames;
  57. if not eqcar(m,'list) then rederr"PREIMAGE only for ideals";
  58. oldring:=first map; newring:=second map;
  59. oldnames:=ring_names oldring;
  60. setring!* ring_sum(newring,oldring);
  61. u:=bas_renumber for each x in cdr third map collect
  62. << if not member(second x,oldnames) then
  63. typerr(second x,"var. name");
  64. bas_make(0,dp_diff(dp_from_a second x,dp_from_a third x))
  65. >>;
  66. m:=matsum!* {dpmat_from_a m,dpmat_make(length u,0,u,nil,nil)};
  67. m:=dpmat_2a eliminate!*(m,ring_names newring);
  68. setring!* oldring;
  69. return m;
  70. end;
  71. symbolic operator ratpreimage;
  72. symbolic procedure ratpreimage(m,map);
  73. % Compute the preimage of an ideal m under a rational ring map.
  74. if !*mode='algebraic then
  75. begin map:=cdr reval map;
  76. return ratpreimage!*(reval m,
  77. {ring_from_a first map, ring_from_a second map, third map});
  78. end
  79. else ratpreimage!*(m,map);
  80. symbolic procedure ratpreimage!*(m,map);
  81. % m and the result are given and returned in algebraic prefix form.
  82. if not !*noetherian then
  83. rederr"RATPREIMAGE only for noetherian term orders"
  84. else begin scalar u,oldring,newnames,oldnames,f,g,v,g0;
  85. if not eqcar(m,'list) then rederr"RATPREIMAGE only for ideals";
  86. oldring:=first map; v:=gensym();
  87. newnames:=v . ring_names second map;
  88. oldnames:=ring_names oldring; u:=append(oldnames,newnames);
  89. setring!* ring_define(u,nil,'lex,for each x in u collect 1);
  90. g0:=dp_fi 1;
  91. u:=bas_renumber for each x in cdr third map collect
  92. << if not member(second x,oldnames) then
  93. typerr(second x,"var. name");
  94. f:=simp third x; g:=dp_from_a prepf denr f;
  95. f:=dp_from_a prepf numr f; g0:=dp_prod(g,g0);
  96. bas_make(0,dp_diff(dp_prod(g,dp_from_a second x),f))
  97. >>;
  98. u:=bas_make(0,dp_diff(dp_prod(g0,dp_from_a v),dp_fi 1)) . u;
  99. m:=matsum!* {dpmat_from_a m,dpmat_make(length u,0,u,nil,nil)};
  100. m:=dpmat_2a eliminate!*(m,newnames);
  101. setring!* oldring;
  102. return m;
  103. end;
  104. % ---- The ideals of affine resp. proj. points. The old stuff, but the
  105. % ---- algebraic interface now uses the linear algebra approach.
  106. symbolic procedure affine_points1!* m;
  107. begin scalar names;
  108. if length(names:=ring_names cali!=basering) neq length cadr m then
  109. typerr(m,"coordinate matrix");
  110. m:=for each x in cdr m collect
  111. 'list . for each y in pair(names,x) collect
  112. {'plus,car y,{'minus,reval cdr y}};
  113. m:=for each x in m collect dpmat_from_a x;
  114. m:=matintersect!* m;
  115. return m;
  116. end;
  117. symbolic procedure scripts!=ideal u;
  118. 'list . for each x in cali_choose(u,2) collect
  119. {'plus,{'times, car first x,cdr second x},
  120. {'minus,{'times, car second x,cdr first x}}};
  121. symbolic procedure proj_points1!* m;
  122. begin scalar names;
  123. if length(names:=ring_names cali!=basering) neq length cadr m then
  124. typerr(m,"coordinate matrix");
  125. m:=for each x in cdr m collect scripts!=ideal pair(names,x);
  126. m:=for each x in m collect interreduce!* dpmat_from_a x;
  127. m:=matintersect!* m;
  128. return m;
  129. end;
  130. % ----- Affine and proj. monomial curves ------------
  131. symbolic operator affine_monomial_curve;
  132. symbolic procedure affine_monomial_curve(l,R);
  133. % l is a list of integers, R contains length l ring var. names.
  134. % Returns the generators of the monomial curve (t^i : i\in l) in R.
  135. if !*mode='algebraic then
  136. dpmat_2a affine_monomial_curve!*(cdr reval l,cdr reval R)
  137. else affine_monomial_curve!*(l,R);
  138. symbolic procedure affine_monomial_curve!*(l,R);
  139. if not numberlistp l then typerr(l,"number list")
  140. else if length l neq length R then
  141. rederr"number of variables doesn't match"
  142. else begin scalar u,t0,v;
  143. v:=list gensym();
  144. r:=ring_define(r,{l},'revlex,l);
  145. setring!* ring_sum(r,ring_define(v,degreeorder!* v,'lex,'(1)));
  146. t0:=dp_from_a car v;
  147. u:=bas_renumber for each x in pair(l,ring_names r) collect
  148. bas_make(0,dp_diff(dp_from_a cdr x,dp_power(t0,car x)));
  149. u:=dpmat_make(length u,0,u,nil,nil);
  150. u:=(eliminate!*(u,v) where cali!=monset=ring_names cali!=basering);
  151. setring!* r;
  152. return dpmat_neworder(u,dpmat_gbtag u);
  153. end;
  154. symbolic operator proj_monomial_curve;
  155. symbolic procedure proj_monomial_curve(l,R);
  156. % l is a list of integers, R contains length l ring var. names.
  157. % Returns the generators of the monomial curve
  158. % (s^(d-i)*t^i : i\in l) in R where d = max { x : x \in l}
  159. if !*mode='algebraic then
  160. dpmat_2a proj_monomial_curve!*(cdr reval l,cdr reval R)
  161. else proj_monomial_curve!*(l,R);
  162. symbolic procedure proj_monomial_curve!*(l,R);
  163. if not numberlistp l then typerr(l,"number list")
  164. else if length l neq length R then
  165. rederr"number of variables doesn't match"
  166. else begin scalar u,t0,t1,v,d;
  167. t0:=gensym(); t1:=gensym(); v:={t0,t1};
  168. d:=listexpand(function max2,l);
  169. r:=ring_define(r,degreeorder!* r,'revlex,for each x in r collect 1);
  170. setring!* ring_sum(r,ring_define(v,degreeorder!* v,'lex,'(1 1)));
  171. t0:=dp_from_a t0; t1:=dp_from_a t1;
  172. u:=bas_renumber for each x in pair(l,ring_names r) collect
  173. bas_make(0,dp_diff(dp_from_a cdr x,
  174. dp_prod(dp_power(t0,car x),dp_power(t1,d-car x))));
  175. u:=dpmat_make(length u,0,u,nil,nil);
  176. u:=(eliminate!*(u,v) where cali!=monset=ring_names cali!=basering);
  177. setring!* r;
  178. return dpmat_neworder(u,dpmat_gbtag u);
  179. end;
  180. % -- General Rees rings, associated graded rings, and related topics --
  181. symbolic operator blowup;
  182. symbolic procedure blowup(m,n,vars);
  183. % vars is a list of var. names for the ring R
  184. % of the same length as dpmat_list n.
  185. % Returns an ideal J such that (S+R)/J == S/M [ N.t ]
  186. % ( with S = the current ring )
  187. % is the blow up ring of the ideal N over S/M.
  188. % (S+R) is the new current ring.
  189. if !*mode='algebraic then
  190. dpmat_2a blowup!*(dpmat_from_a reval m,dpmat_from_a reval n,
  191. cdr reval vars)
  192. else blowup!*(M,N,vars);
  193. symbolic procedure blowup!*(M,N,vars);
  194. if (dpmat_cols m > 0)or(dpmat_cols n > 0) then
  195. rederr"BLOWUP defined only for ideals"
  196. else if not !*noetherian then
  197. rederr"BLOWUP only for noetherian term orders"
  198. else begin scalar u,s,t0,v,r1;
  199. if length vars neq dpmat_rows n then
  200. rederr {"ring must have",dpmat_rows n,"variables"};
  201. u:=for each x in dpmat_rowdegrees n collect mo_ecart cdr x;
  202. r1:=ring_define(vars,list u,'revlex,u);
  203. s:=ring_sum(cali!=basering,r1); v:=list(gensym());
  204. setring!* ring_sum(s,ring_define(v,degreeorder!* v,'lex,'(1)));
  205. t0:=dp_from_a car v;
  206. n:=for each x in
  207. pair(vars,for each y in dpmat_list n collect bas_dpoly y)
  208. collect dp_diff(dp_from_a car x,
  209. dp_prod(dp_neworder cdr x,t0));
  210. m:=bas_renumber append(bas_neworder dpmat_list m,
  211. for each x in n collect bas_make(0,x));
  212. m:=(eliminate!*(interreduce!* dpmat_make(length m,0,m,nil,nil),v)
  213. where cali!=monset=nil);
  214. setring!* s;
  215. return dpmat_neworder(m,dpmat_gbtag m);
  216. end;
  217. symbolic operator assgrad;
  218. symbolic procedure assgrad(m,n,vars);
  219. % vars is a list of var. names for the ring T
  220. % of the same length as dpmat_list n.
  221. % Returns an ideal J such that (S+T)/J == (R/N + N/N^2 + ... )
  222. % ( with R=S/M and S the current ring )
  223. % is the associated graded ring of the ideal N over R.
  224. % (S+T) is the new current ring.
  225. if !*mode='algebraic then
  226. dpmat_2a assgrad!*(dpmat_from_a reval m,dpmat_from_a reval n,
  227. cdr reval vars)
  228. else assgrad!*(M,N,vars);
  229. symbolic procedure assgrad!*(M,N,vars);
  230. if (dpmat_cols m > 0)or(dpmat_cols n > 0) then
  231. rederr"ASSGRAD defined only for ideals"
  232. else begin scalar u;
  233. u:=blowup!*(m,n,vars);
  234. return matsum!* {u,dpmat_neworder(n,nil)};
  235. end;
  236. symbolic operator analytic_spread;
  237. symbolic procedure analytic_spread m;
  238. % Returns the analytic spread of the ideal m.
  239. if !*mode='algebraic then analytic_spread!* dpmat_from_a reval m
  240. else analytic_spread!* m;
  241. symbolic procedure analytic_spread!* m;
  242. if (dpmat_cols m>0) then rederr"ANALYTIC SPREAD only for ideals"
  243. else (begin scalar r,m1,vars;
  244. r:=ring_names cali!=basering;
  245. vars:=for each x in dpmat_list m collect gensym();
  246. m1:=blowup!*(dpmat_from_dpoly nil,m,vars);
  247. return dim!* gbasis!* matsum!*{m1,dpmat_from_a('list . r)};
  248. end) where cali!=basering=cali!=basering;
  249. symbolic operator sym;
  250. symbolic procedure sym(M,vars);
  251. % vars is a list of var. names for the ring R
  252. % of the same length as dpmat_list M.
  253. % Returns an ideal J such that (S+R)/J == Sym(M)
  254. % ( with S = the current ring )
  255. % is the symmetric algebra of M over S.
  256. % (S+R) is the new current ring.
  257. if !*mode='algebraic then
  258. dpmat_2a sym!*(dpmat_from_a M,cdr reval vars)
  259. else sym!*(m,vars);
  260. symbolic procedure sym!*(m,vars);
  261. % The symmetric algebra of the dpmat m.
  262. if not !*noetherian then
  263. rederr"SYM only for noetherian term orders"
  264. else begin scalar n,u,r1;
  265. if length vars neq dpmat_rows m then
  266. rederr {"ring must have",dpmat_rows m,"variables"};
  267. cali!=degrees:=dpmat_coldegs m;
  268. u:=for each x in dpmat_rowdegrees m collect mo_ecart cdr x;
  269. r1:=ring_define(vars,list u,'revlex,u); n:=syzygies!* m;
  270. setring!* ring_sum(cali!=basering,r1);
  271. return mat2list!* interreduce!*
  272. dpmat_mult(dpmat_neworder(n,nil),
  273. ideal2mat!* dpmat_from_a('list . vars));
  274. end;
  275. % ----- Several short scripts ----------
  276. % ------ Minimal generators of an ideal or module.
  277. symbolic operator minimal_generators;
  278. symbolic procedure minimal_generators m;
  279. if !*mode='algebraic then
  280. dpmat_2a minimal_generators!* dpmat_from_a reval m
  281. else minimal_generators!* m;
  282. symbolic procedure minimal_generators!* m;
  283. car groeb_minimize(m,syzygies!* m);
  284. % ------- Symbolic powers of prime (or unmixed) ideals
  285. symbolic operator symbolic_power;
  286. symbolic procedure symbolic_power(m,d);
  287. if !*mode='algebraic then
  288. dpmat_2a symbolic_power!*(dpmat_from_a m,reval d)
  289. else symbolic_power!*(m,d);
  290. symbolic procedure symbolic_power!*(m,d);
  291. eqhull!* idealpower!*(m,d);
  292. % ---- non zero divisor property -----------
  293. put('nzdp,'psopfn,'scripts!=nzdp);
  294. symbolic procedure scripts!=nzdp m;
  295. if length m neq 2 then rederr"Syntax : nzdp(dpoly,dpmat)"
  296. else begin scalar f,b;
  297. f:=reval car m; intf_get second m;
  298. if null(b:=get(second m,'gbasis)) then
  299. put(second m,'gbasis,b:=gbasis!* get(second m,'basis));
  300. return if nzdp!*(dp_from_a f,b) then 'yes else 'no;
  301. end;
  302. symbolic procedure nzdp!*(f,m);
  303. % Test dpoly f for a non zero divisor on coker m. m must be a gbasis.
  304. submodulep!*(matqquot!*(m,f),m);
  305. endmodule; % scripts
  306. end;