matop.red 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. module matop;
  2. COMMENT
  3. #############################
  4. #### ####
  5. #### MATRIX OPERATIONS ####
  6. #### ####
  7. #############################
  8. This module contains operations on dpmats, that correspond to module
  9. operations on the corresponding images resp. cokernels.
  10. END COMMENT;
  11. symbolic procedure matop!=testdpmatlist l;
  12. % Test l to be a list of dpmats embedded into a common free module.
  13. if null l then rederr"Empty DPMAT list"
  14. else begin scalar c,d;
  15. for each x in l do
  16. if not eqcar(x,'dpmat) then typerr(x,"DPMAT");
  17. c:=dpmat_cols car l; d:=dpmat_coldegs car l;
  18. for each x in cdr l do
  19. if not (eqn(c,dpmat_cols x) and equal(d,dpmat_coldegs x)) then
  20. rederr"Matrices don't match in the DPMAT list";
  21. end;
  22. symbolic procedure matappend!* l;
  23. % Appends rows of the dpmats in the dpmat list l.
  24. (begin scalar u,r;
  25. matop!=testdpmatlist l;
  26. cali!=degrees:=dpmat_coldegs car l;
  27. u:=dpmat_list car l; r:=dpmat_rows car l;
  28. for each y in cdr l do
  29. << u:=append(u, for each x in dpmat_list y collect
  30. bas_newnumber(bas_nr x + r,x));
  31. r:=r + dpmat_rows y;
  32. >>;
  33. return dpmat_make(r,dpmat_cols car l,u,cali!=degrees,nil)
  34. end) where cali!=degrees:=cali!=degrees;
  35. put('matappend,'psopfn,'matop!=matappend);
  36. symbolic procedure matop!=matappend l;
  37. % Append the dpmats in the list l.
  38. dpmat_2a matappend!* for each x in l collect dpmat_from_a reval x;
  39. symbolic procedure mat2list!* m;
  40. % Returns the ideal of all elements of m.
  41. if dpmat_cols m = 0 then m
  42. else (begin scalar x;
  43. x:=bas_renumber bas_zerodelete
  44. for i:=1:dpmat_rows m join
  45. for j:=1:dpmat_cols m collect
  46. bas_make(0,dpmat_element(i,j,m));
  47. return dpmat_make(length x,0,x,nil,
  48. if dpmat_cols m=1 then dpmat_gbtag m else nil)
  49. end) where cali!=degrees:=nil;
  50. symbolic procedure matsum!* l;
  51. % Returns the module sum of the dpmat list l.
  52. interreduce!* matappend!* l;
  53. put('matsum,'psopfn,'matop!=matsum);
  54. put('idealsum,'psopfn,'matop!=matsum);
  55. symbolic procedure matop!=matsum l;
  56. % Returns the sum of the ideals/modules in the list l.
  57. dpmat_2a matsum!* for each x in l collect dpmat_from_a reval x;
  58. symbolic procedure matop!=idealprod2(a,b);
  59. if (dpmat_cols a > 0) or (dpmat_cols b > 0 ) then
  60. rederr"IDEALPROD only for ideals"
  61. else (begin scalar x;
  62. x:=bas_renumber
  63. for each a1 in dpmat_list a join
  64. for each b1 in dpmat_list b collect
  65. bas_make(0,dp_prod(bas_dpoly a1,bas_dpoly b1));
  66. return interreduce!* dpmat_make(length x,0,x,nil,nil)
  67. end) where cali!=degrees:=nil;
  68. symbolic procedure idealprod!* l;
  69. % Returns the product of the ideals in the dpmat list l.
  70. if null l then rederr"empty list in IDEALPROD"
  71. else if length l=1 then car l
  72. else begin scalar u;
  73. u:=car l;
  74. for each x in cdr l do u:=matop!=idealprod2(u,x);
  75. return u;
  76. end;
  77. put('idealprod,'psopfn,'matop!=idealprod);
  78. symbolic procedure matop!=idealprod l;
  79. % Returns the product of the ideals in the list l.
  80. dpmat_2a idealprod!* for each x in l collect dpmat_from_a reval x;
  81. symbolic procedure idealpower!*(a,n);
  82. if (dpmat_cols a > 0) or (not fixp n) or (n < 0) then
  83. rederr" Syntax : idealpower(ideal,integer)"
  84. else if (n=0) then dpmat_from_dpoly dp_fi 1
  85. else begin scalar w; w:=a;
  86. for i:=2:n do w:=matop!=idealprod2(w,a);
  87. return w;
  88. end;
  89. symbolic operator idealpower;
  90. symbolic procedure idealpower(m,l);
  91. if !*mode='algebraic then
  92. dpmat_2a idealpower!*(dpmat_from_a reval m,l)
  93. else idealpower!*(m,l);
  94. symbolic procedure matop!=shiftdegs(d,n);
  95. % Shift column degrees d n places.
  96. for each x in d collect ((car x + n) . cdr x);
  97. symbolic procedure directsum!* l;
  98. % Returns the direct sum of the modules in the dpmat list l.
  99. if null l then rederr"Empty DPMAT list"
  100. else (begin scalar r,c,u;
  101. for each x in l do
  102. if not eqcar(x,'dpmat) then typerr(x,"DPMAT")
  103. else if dpmat_cols x=0 then
  104. rederr"DIRECTSUM only for modules";
  105. c:=r:=0; % Actual column resp. row index.
  106. cali!=degrees:=nil;
  107. for each x in l do
  108. << cali!=degrees:=append(cali!=degrees,
  109. matop!=shiftdegs(dpmat_coldegs x,c));
  110. u:=append(u, for each y in dpmat_list x collect
  111. bas_make(bas_nr y + r,dp_times_ei(c,bas_dpoly y)));
  112. r:=r + dpmat_rows x;
  113. c:=c + dpmat_cols x;
  114. >>;
  115. return dpmat_make(r,c,u,cali!=degrees,nil)
  116. end) where cali!=degrees:=cali!=degrees;
  117. put('directsum,'psopfn,'matop!=directsum);
  118. symbolic procedure matop!=directsum l;
  119. % Returns the direct sum of the modules in the list l.
  120. dpmat_2a directsum!* for each x in l collect dpmat_from_a reval x;
  121. symbolic operator deleteunits;
  122. symbolic procedure deleteunits m;
  123. if !*noetherian then m
  124. else if !*mode='algebraic then dpmat_2a deleteunits!* dpmat_from_a m
  125. else deleteunits!* m;
  126. symbolic procedure deleteunits!* m;
  127. % Delete units from the base elements of the ideal m.
  128. if !*noetherian or (dpmat_cols m>0) then m
  129. else dpmat_make(dpmat_rows m,0,
  130. for each x in dpmat_list m collect
  131. bas_factorunits x,nil,dpmat_gbtag m);
  132. symbolic procedure interreduce!* m;
  133. (begin scalar u;
  134. u:=red_interreduce dpmat_list m;
  135. return dpmat_make(length u, dpmat_cols m, bas_renumber u,
  136. cali!=degrees, dpmat_gbtag m)
  137. end) where cali!=degrees:=dpmat_coldegs m;
  138. symbolic operator interreduce;
  139. symbolic procedure interreduce m;
  140. % Interreduce m.
  141. if !*mode='algebraic then
  142. dpmat_2a interreduce!* dpmat_from_a reval m
  143. else interreduce!* m;
  144. symbolic procedure gbasis!* m;
  145. % Produce a minimal Groebner or standard basis of the dpmat m.
  146. if dpmat_gbtag m then m else car groeb_stbasis(m,t,nil,nil);
  147. put('tangentcone,'psopfn,'matop!=tangentcone);
  148. symbolic procedure matop!=tangentcone m;
  149. begin scalar c;
  150. intf_test m; m:=car m; intf_get m;
  151. if not (c:=get(m,'gbasis)) then
  152. put(m,'gbasis,c:=gbasis!* get(m,'basis));
  153. c:=tangentcone!* c;
  154. return dpmat_2a c;
  155. end;
  156. symbolic procedure tangentcone!* m;
  157. % Returns the tangent cone of m, provided the term order has degrees.
  158. % m must be a gbasis.
  159. if null ring_degrees cali!=basering then
  160. rederr"tangent cone only for degree orders defined"
  161. else (begin scalar b;
  162. b:=for each x in dpmat_list m collect
  163. bas_make(bas_nr x,dp_tcpart bas_dpoly x);
  164. return dpmat_make(dpmat_rows m,
  165. dpmat_cols m,b,cali!=degrees,dpmat_gbtag m);
  166. end) where cali!=degrees:=dpmat_coldegs m;
  167. symbolic procedure syzygies1!* bas;
  168. % Returns the (not yet interreduced first) syzygy module of the dpmat
  169. % bas.
  170. begin
  171. if cali_trace() > 0 then
  172. << terpri(); write" Compute syzygies"; terpri() >>;
  173. return third groeb_stbasis(bas,nil,nil,t);
  174. end;
  175. symbolic procedure syzygies!* bas;
  176. % Returns the interreduced syzygy basis.
  177. interreduce!* syzygies1!* bas;
  178. symbolic procedure normalform!*(a,b);
  179. % Returns {a1,r,z} with a1=z*a-r*b where the rows of the dpmat a1 are
  180. % the normalforms of the rows of the dpmat a with respect to the
  181. % dpmat b.
  182. if not(eqn(dpmat_cols a,dpmat_cols b) and
  183. equal(dpmat_coldegs a,dpmat_coldegs b)) then
  184. rederr"dpmats don't match for NORMALFORM"
  185. else (begin scalar a1,z,u,r;
  186. bas_setrelations dpmat_list b;
  187. a1:=for each x in dpmat_list a collect
  188. << u:=red_redpol(dpmat_list b,x);
  189. z:=bas_make(bas_nr x,dp_times_ei(bas_nr x,cdr u)).z;
  190. car u
  191. >>;
  192. r:=bas_getrelations a1; bas_removerelations a1;
  193. bas_removerelations dpmat_list b; z:=reversip z;
  194. a1:=dpmat_make(dpmat_rows a,dpmat_cols a,a1,cali!=degrees,nil);
  195. cali!=degrees:=dpmat_rowdegrees b;
  196. r:=dpmat_make(dpmat_rows a,dpmat_rows b,bas_neworder r,
  197. cali!=degrees,nil);
  198. cali!=degrees:=nil;
  199. z:=dpmat_make(dpmat_rows a,dpmat_rows a,bas_neworder z,nil,nil);
  200. return {a1,r,z};
  201. end) where cali!=degrees:=dpmat_coldegs b;
  202. symbolic procedure matop_pseudomod(a,b); car mod!*(a,b);
  203. symbolic procedure mod!*(a,b);
  204. % Returns the normal form of the dpoly a modulo the dpmat b and the
  205. % corresponding unit produced during pseudo division.
  206. (begin scalar u;
  207. a:=dp_neworder a; % to be on the safe side.
  208. u:=red_redpol(dpmat_list b,bas_make(0,a));
  209. return (bas_dpoly car u) . cdr u;
  210. end) where cali!=degrees:=dpmat_coldegs b;
  211. symbolic operator mod;
  212. symbolic procedure mod(a,b);
  213. % True normal form as s.q. also for matrices.
  214. if !*mode='symbolic then rederr"only for algebraic mode"
  215. else begin scalar u;
  216. b:=dpmat_from_a reval b; a:=reval a;
  217. if eqcar(a,'list) then
  218. if dpmat_cols b>0 then rederr"entries don't match for MOD"
  219. else a:=makelist for each x in cdr a collect
  220. << u:=mod!*(dp_from_a x, b);
  221. {'quotient,dp_2a car u,dp_2a cdr u}
  222. >>
  223. else if eqcar(a,'mat) then
  224. begin a:=dpmat_from_a a;
  225. if dpmat_cols a neq dpmat_cols b then
  226. rederr"entries don't match for MOD";
  227. a:=for each x in dpmat_list a collect mod!*(bas_dpoly x,b);
  228. a:='mat.
  229. for each x in a collect
  230. << u:=dp_2a cdr x;
  231. for i:=1:dpmat_cols b collect
  232. {'quotient,dp_2a dp_comp(i,car x),u}
  233. >>
  234. end
  235. else if dpmat_cols b>0 then rederr"entries don't match for MOD"
  236. else << u:=mod!*(dp_from_a a, b);
  237. a:={'quotient,dp_2a car u,dp_2a cdr u}
  238. >>;
  239. return a;
  240. end;
  241. infix mod;
  242. symbolic operator normalform;
  243. symbolic procedure normalform(a,b);
  244. % Compute a normal form of the rows of a with respect to b :
  245. % first result = third result * a + second result * b.
  246. if !*mode='algebraic then
  247. begin scalar m;
  248. m:= normalform!*(dpmat_from_a reval a,dpmat_from_a reval b);
  249. return {'list,dpmat_2a car m, dpmat_2a cadr m, dpmat_2a caddr m}
  250. end
  251. else normalform!*(a,b);
  252. symbolic procedure eliminate!*(m,vars);
  253. % Returns a (dpmat) basis of the elimination module of the dpmat m
  254. % eliminating variables contained in the var. list vars.
  255. % It sets temporary the standard elimination term order, but doesn't
  256. % affect the ecart, and computes a Groebner basis of m.
  257. % if dpmat_gbtag m and eo(vars) then dpmat_sieve(m,vars,t) else
  258. (begin scalar c,e,bas,v;
  259. c:=cali!=basering; e:=ring_ecart c;
  260. v:=ring_names cali!=basering;
  261. setring!* ring_define(v,eliminationorder!*(v,vars),'revlex,e);
  262. cali!=degrees:=nil; % No degrees for proper result !!
  263. bas:=(bas_sieve(dpmat_list
  264. car groeb_stbasis(dpmat_neworder(m,nil),t,nil,nil), vars)
  265. where !*noetherian=t);
  266. setring!* c; cali!=degrees:=dpmat_coldegs m;
  267. return dpmat_make(length bas,dpmat_cols m,bas_neworder bas,
  268. cali!=degrees,nil);
  269. end)
  270. where cali!=degrees:=cali!=degrees,
  271. cali!=basering:=cali!=basering;
  272. symbolic operator eliminate;
  273. symbolic procedure eliminate(m,l);
  274. % Returns the elimination ideal/module of m with respect to the
  275. % variables in the list l to be eliminated.
  276. if !*mode='algebraic then
  277. begin l:=reval l;
  278. if not eqcar(l,'list) then typerr(l,"variable list");
  279. m:=dpmat_from_a m; l:=cdr l;
  280. return dpmat_2a eliminate!*(m,l);
  281. end
  282. else eliminate!*(m,l);
  283. symbolic procedure matintersect!* l;
  284. if null l then rederr"MATINTERSECT with empty list"
  285. else if length l=1 then car l
  286. else (begin scalar c,u,v,p,size;
  287. matop!=testdpmatlist l;
  288. size:=dpmat_cols car l;
  289. v:=for each x in l collect gensym();
  290. c:=cali!=basering;
  291. setring!* ring_sum(c,
  292. ring_define(v,degreeorder!* v,'lex,for each x in v collect 1));
  293. cali!=degrees:=mo_degneworder dpmat_coldegs car l;
  294. u:=for each x in pair(v,l) collect
  295. dpmat_times_dpoly(dp_from_a car x,dpmat_neworder(cdr x,nil));
  296. p:=dp_fi 1; for each x in v do p:=dp_diff(p,dp_from_a x);
  297. if size=0 then p:=dpmat_from_dpoly p
  298. else p:=dpmat_times_dpoly(p,dpmat_unit(size,cali!=degrees));
  299. p:=gbasis!* matsum!* (p . u);
  300. p:=dpmat_sieve(p,v,t);
  301. setring!* c;
  302. cali!=degrees:=dpmat_coldegs car l;
  303. return dpmat_neworder(p,t);
  304. end)
  305. where cali!=degrees:=cali!=degrees,
  306. cali!=basering:=cali!=basering;
  307. put('matintersect,'psopfn,'matop!=matintersect);
  308. put('idealintersect,'psopfn,'matop!=matintersect);
  309. symbolic procedure matop!=matintersect l;
  310. % Returns the intersection of the submodules of a fixed free module
  311. % in the list l.
  312. dpmat_2a matintersect!* for each x in l collect dpmat_from_a reval x;
  313. % ------- Submodule property and equality test --------------
  314. put('modequalp,'psopfn,'matop!=equalp);
  315. % Test, whether a and b are module equal.
  316. symbolic procedure matop!=equalp u;
  317. if length u neq 2 then rederr"Syntax : MODEQUALP(dpmat,dpmat) "
  318. else begin scalar a,b;
  319. intf_get first u; intf_get second u;
  320. if null(a:=get(first u,'gbasis)) then
  321. put(first u,'gbasis,a:=gbasis!* get(first u,'basis));
  322. if null(b:=get(second u,'gbasis)) then
  323. put(second u,'gbasis,b:=gbasis!* get(second u,'basis));
  324. if modequalp!*(a,b) then return 'yes else return 'no
  325. end;
  326. symbolic procedure modequalp!*(a,b);
  327. submodulep!*(a,b) and submodulep!*(b,a);
  328. put('submodulep,'psopfn,'matop!=submodulep);
  329. % Test, whether a is a submodule of b.
  330. symbolic procedure matop!=submodulep u;
  331. if length u neq 2 then rederr"Syntax : SUBMODULEP(dpmat,dpmat)"
  332. else begin scalar a,b;
  333. intf_get second u;
  334. if null(b:=get(second u,'gbasis)) then
  335. put(second u,'gbasis,b:=gbasis!* get(second u,'basis));
  336. a:=dpmat_from_a reval first u;
  337. if submodulep!*(a,b) then return 'yes else return 'no
  338. end;
  339. symbolic procedure submodulep!*(a,b);
  340. if not(dpmat_cols a=dpmat_cols b
  341. and equal(dpmat_coldegs a,dpmat_coldegs b)) then
  342. rederr"incompatible modules in SUBMODULEP"
  343. else (begin
  344. a:=for each x in dpmat_list a collect bas_dpoly x;
  345. return not listtest(a,b,function matop_pseudomod)
  346. end) where cali!=degrees:=dpmat_coldegs a;
  347. endmodule; % matop
  348. end;