quot.red 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. module quot;
  2. COMMENT
  3. #################
  4. # #
  5. # QUOTIENTS #
  6. # #
  7. #################
  8. This module contains algorithms for different kinds of quotients of
  9. ideals and modules.
  10. END COMMENT;
  11. % -------- Quotient of a module by a polynomial -----------
  12. % Returns m : (f) for a polynomial f.
  13. symbolic operator matquot;
  14. symbolic procedure matquot(m,f);
  15. if !*mode='algebraic then
  16. if eqcar(f,'list) or eqcar(f,'mat) then
  17. rederr("Syntax : matquot(dpmat,dpoly)")
  18. else dpmat_2a matquot!*(dpmat_from_a reval m,dp_from_a reval f)
  19. else matquot!*(m,f);
  20. symbolic procedure matquot!*(m,f);
  21. if dp_unit!? f then m
  22. else if dpmat_cols m=0 then mat2list!* quot!=quot(ideal2mat!* m,f)
  23. else quot!=quot(m,f);
  24. symbolic procedure quot!=quot(m,f);
  25. % Note that, if a is a gbasis, then also b.
  26. begin scalar a,b;
  27. a:=matintersect!* {m,
  28. dpmat_times_dpoly(f,dpmat_unit(dpmat_cols m,dpmat_coldegs m))};
  29. b:=for each x in dpmat_list a collect
  30. bas_make(bas_nr x,car dp_pseudodivmod(bas_dpoly x,f));
  31. return dpmat_make(dpmat_rows a,dpmat_cols a,b,
  32. dpmat_coldegs m,dpmat_gbtag a);
  33. end;
  34. % -------- Quotient of a module by an ideal -----------
  35. % Returns m:n as a module.
  36. symbolic operator idealquotient;
  37. symbolic procedure idealquotient(m,n);
  38. if !*mode='algebraic then
  39. dpmat_2a idealquotient2!*(dpmat_from_a reval m,
  40. dpmat_from_a reval n)
  41. else idealquotient2!*(m,n);
  42. % -------- Quotient of a module by another module -----------
  43. % Returns m:n as an ideal in S. m and n must be submodules of a common
  44. % free module.
  45. symbolic operator modulequotient;
  46. symbolic procedure modulequotient(m,n);
  47. if !*mode='algebraic then
  48. dpmat_2a modulequotient2!*(dpmat_from_a reval m,
  49. dpmat_from_a reval n)
  50. else modulequotient2!*(m,n);
  51. % ---- The annihilator of a module, i.e. Ann coker M := M : F ---
  52. symbolic operator annihilator;
  53. symbolic procedure annihilator m;
  54. if !*mode='algebraic then
  55. dpmat_2a annihilator2!* dpmat_from_a reval m
  56. else annihilator2!* m;
  57. % ---- Quotients as M:N = \intersect { M:f | f \in N } ------
  58. symbolic procedure idealquotient2!*(m,n);
  59. if dpmat_cols n>0 then rederr"Syntax : idealquotient(dpmat,ideal)"
  60. else if dpmat_cols m=0 then modulequotient2!*(m,n)
  61. else if dpmat_cols m=1 then
  62. ideal2mat!* modulequotient2!*(m,ideal2mat!* n)
  63. else matintersect!* for each x in dpmat_list n collect
  64. quot!=quot(m,bas_dpoly x);
  65. symbolic procedure modulequotient2!*(m,n);
  66. (begin scalar c;
  67. if not((c:=dpmat_cols m)=dpmat_cols n) then rederr
  68. "MODULEQUOTIENT only for submodules of a common free module";
  69. if not equal(dpmat_coldegs m,dpmat_coldegs n) then
  70. rederr"matrices don't match for MODULEQUOTIENT";
  71. if (c=0) then << m:=ideal2mat!* m; n:=ideal2mat!* n >>;
  72. cali!=degrees:=dpmat_coldegs m;
  73. n:=for each x in dpmat_list n collect matop_pseudomod(bas_dpoly x,m);
  74. n:=for each x in n join if x then {x};
  75. return if null n then dpmat_from_dpoly dp_fi 1
  76. else matintersect!* for each x in n collect quot!=mquot(m,x);
  77. end) where cali!=degrees:=cali!=degrees;
  78. symbolic procedure quot!=mquot(m,f);
  79. begin scalar a,b;
  80. a:=matintersect!*
  81. {m,dpmat_make(1,dpmat_cols m,list bas_make(1,f),dpmat_coldegs m,t)};
  82. b:=for each x in dpmat_list a collect
  83. bas_make(bas_nr x,car dp_pseudodivmod(bas_dpoly x,f));
  84. return dpmat_make(dpmat_rows a,0,b,nil,nil);
  85. end;
  86. symbolic procedure annihilator2!* m;
  87. if dpmat_cols m=0 then m
  88. else if dpmat_cols m=1 then mat2list!* m
  89. else modulequotient2!*(m,dpmat_unit(dpmat_cols m,dpmat_coldegs m));
  90. % -------- Quotients by the general element method --------
  91. symbolic procedure idealquotient1!*(m,n);
  92. if dpmat_cols n>0 then rederr "second parameter must be an ideal"
  93. else if dpmat_cols m=0 then modulequotient1!*(m,n)
  94. else if dpmat_cols m=1 then
  95. ideal2mat!* modulequotient1!*(m,ideal2mat!* n)
  96. else (begin scalar u1,u2,f,v,r,m1;
  97. v:=list gensym(); r:=cali!=basering;
  98. setring!* ring_sum(r,ring_define(v,degreeorder!* v,'revlex,'(1)));
  99. cali!=degrees:=mo_degneworder dpmat_coldegs m;
  100. n:=for each x in dpmat_list n collect dp_neworder x;
  101. u1:=u2:=dp_from_a car v; f:=car n;
  102. for each x in n do
  103. << f:=dp_sum(f,dp_prod(u1,x)); u1:=dp_prod(u1,u2) >>;
  104. m1:=dpmat_sieve(gbasis!* quot!=quot(dpmat_neworder(m,nil),f),v,t);
  105. setring!* r; cali!=degrees:=dpmat_coldegs m;
  106. return dpmat_neworder(m1,t);
  107. end)
  108. where cali!=degrees:=cali!=degrees,
  109. cali!=basering:=cali!=basering;
  110. symbolic procedure modulequotient1!*(m,n);
  111. (begin scalar c,u1,u2,f,v,r,m1;
  112. if not((c:=dpmat_cols m)=dpmat_cols n) then rederr
  113. "MODULEQUOTIENT only for submodules of a common free module";
  114. if not equal(dpmat_coldegs m,dpmat_coldegs n) then
  115. rederr"matrices don't match for MODULEQUOTIENT";
  116. if (c=0) then << m:=ideal2mat!* m; n:=ideal2mat!* n >>;
  117. cali!=degrees:=dpmat_coldegs m;
  118. n:=for each x in dpmat_list n collect matop_pseudomod(bas_dpoly x,m);
  119. n:=for each x in n join if x then {x};
  120. if null n then return dpmat_from_dpoly dp_fi 1;
  121. v:=list gensym(); r:=cali!=basering;
  122. setring!* ring_sum(r,ring_define(v,degreeorder!* v,'revlex,'(1)));
  123. cali!=degrees:=mo_degneworder cali!=degrees;
  124. u1:=u2:=dp_from_a car v; f:=dp_neworder car n;
  125. for each x in n do
  126. << f:=dp_sum(f,dp_prod(u1,dp_neworder x));
  127. u1:=dp_prod(u1,u2)
  128. >>;
  129. m1:=dpmat_sieve(gbasis!* quot!=mquot(dpmat_neworder(m,nil),f),v,t);
  130. setring!* r; cali!=degrees:=dpmat_coldegs m;
  131. return dpmat_neworder(m1,t);
  132. end)
  133. where cali!=degrees:=cali!=degrees,
  134. cali!=basering:=cali!=basering;
  135. symbolic procedure annihilator1!* m;
  136. if dpmat_cols m=0 then m
  137. else if dpmat_cols m=1 then m
  138. else modulequotient1!*(m,dpmat_unit(dpmat_cols m,dpmat_coldegs m));
  139. % --------------- Stable quotients ------------------------
  140. symbolic operator matqquot;
  141. symbolic procedure matqquot(m,f);
  142. % Stable quotient of dpmat m with respect to a polynomial f, i.e.
  143. % m : <f> = { v \in F | \exists n : f^n*v \in m }
  144. if !*mode='algebraic then
  145. if eqcar(f,'list) or eqcar(f,'mat) then
  146. rederr("Syntax : matquot(dpmat,dpoly)")
  147. else dpmat_2a matqquot!*(dpmat_from_a reval m,dp_from_a reval f)
  148. else matqquot!*(m,f);
  149. symbolic procedure matqquot!*(m,f);
  150. if dp_unit!? f then m
  151. else if dpmat_cols m=0 then
  152. mat2list!* quot!=stabquot(ideal2mat!* m,{f})
  153. else quot!=stabquot(m,{f});
  154. symbolic operator matstabquot;
  155. symbolic procedure matstabquot(m,f);
  156. % Stable quotient of dpmat m with respect to an ideal f.
  157. if !*mode='algebraic then dpmat_2a
  158. matstabquot!*(dpmat_from_a reval m,dpmat_from_a reval f)
  159. else matstabquot!*(m,f);
  160. symbolic procedure matstabquot!*(m,f);
  161. if dpmat_cols f > 0 then rederr "stable quotient only by ideals"
  162. else begin scalar c;
  163. if (c:=dpmat_cols m)=0 then
  164. << f:=for each x in dpmat_list f collect
  165. matop_pseudomod(bas_dpoly x,m);
  166. f:=for each x in f join if x then {x}
  167. >>
  168. else f:=for each x in dpmat_list f collect bas_dpoly x;
  169. if null f then return
  170. if c=0 then dpmat_from_dpoly dp_fi 1
  171. else dpmat_unit(c,dpmat_coldegs m);
  172. if dp_unit!? car f then return m;
  173. if c=0 then return mat2list!* quot!=stabquot(ideal2mat!* m,f)
  174. else return quot!=stabquot(m,f);
  175. end;
  176. symbolic procedure quot!=stabquot(m,f);
  177. % m must be a module.
  178. if dpmat_cols m=0 then rederr"quot_stabquot only for cols>0"
  179. else (begin scalar m1,p,p1,p2,v,v1,v2,c;
  180. v1:=gensym(); v2:=gensym(); v:={v1,v2};
  181. setring!* ring_sum(c:=cali!=basering,
  182. ring_define(v,degreeorder!* v,'lex,'(1 1)));
  183. cali!=degrees:=mo_degneworder dpmat_coldegs m;
  184. p1:=p2:=dp_from_a v1;
  185. f:=for each x in f collect dp_neworder x;
  186. p:=car f;
  187. for each x in cdr f do
  188. << p:=dp_sum(dp_prod(p1,x),p); p1:=dp_prod(p1,p2) >>;
  189. p:=dp_diff(dp_fi 1,dp_prod(dp_from_a v2,p));
  190. % p = 1 - v2 * \sum{f_i * v1^i}
  191. m1:=matsum!* {dpmat_neworder(m,nil),
  192. dpmat_times_dpoly(p,
  193. dpmat_unit(dpmat_cols m,cali!=degrees))};
  194. m1:=dpmat_sieve(gbasis!* m1,v,t);
  195. setring!* c; cali!=degrees:=dpmat_coldegs m;
  196. return dpmat_neworder(m1,t);
  197. end)
  198. where cali!=degrees:=cali!=degrees,
  199. cali!=basering:=cali!=basering;
  200. endmodule; % quot
  201. end;