dpmat.red 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. module dpmat;
  2. COMMENT
  3. #####################
  4. ### ###
  5. ### MATRICES ###
  6. ### ###
  7. #####################
  8. This module introduces special dpoly matrices with its own matrix
  9. syntax.
  10. Informal syntax :
  11. <matrix> ::= list('DPMAT,#rows,#cols,baslist,column_degrees,gb-tag)
  12. Dpmat's are the central data structure exploited in the modules of
  13. this package. Each such matrix describes a map
  14. f : R^rows --> R^cols,
  15. that gives rise for the definition of two modules,
  16. im f = the submodule of R^cols generated by the rows
  17. of the matrix
  18. and coker f = R^cols/im f.
  19. Conceptually dpmat's are identified with im f.
  20. END COMMENT;
  21. % ------------- Reference operators ----------------
  22. symbolic procedure dpmat_rows m; cadr m;
  23. symbolic procedure dpmat_cols m; caddr m;
  24. symbolic procedure dpmat_list m; cadddr m;
  25. symbolic procedure dpmat_coldegs m; nth(m,5);
  26. symbolic procedure dpmat_gbtag m; nth(m,6);
  27. % ------------- Elementary operations --------------
  28. symbolic procedure dpmat_rowdegrees m;
  29. % Returns the row degrees of the dpmat m as an assoc. list.
  30. (for each x in dpmat_list m join
  31. if (bas_nr x > 0) and bas_dpoly x then
  32. {(bas_nr x).(mo_getdegree(dp_lmon bas_dpoly x,l))})
  33. where l=dpmat_coldegs m;
  34. symbolic procedure dpmat_make(r,c,bas,degs,gbtag);
  35. list('dpmat,r,c,bas,degs,gbtag);
  36. symbolic procedure dpmat_element(r,c,mmat);
  37. % Returns mmat[r,c].
  38. dp_neworder
  39. dp_comp(c, bas_dpoly bas_getelement(r,dpmat_list mmat));
  40. symbolic procedure dpmat_print m; mathprint dpmat_2a m;
  41. symbolic procedure getleadterms!* m;
  42. % Returns the dpmat with the leading terms of m.
  43. (begin scalar b;
  44. b:=for each x in dpmat_list m collect
  45. bas_make(bas_nr x,list(car bas_dpoly x));
  46. return dpmat_make(dpmat_rows m,dpmat_cols m,b,cali!=degrees,t);
  47. end) where cali!=degrees:=dpmat_coldegs m;
  48. % -------- Symbolic mode file transfer --------------
  49. symbolic procedure savemat!*(m,name);
  50. % Save the dpmat m under the name <name>.
  51. begin scalar nat,c;
  52. if not (stringp name or idp name) then typerr(name,"file name");
  53. if not eqcar(m,'dpmat) then typerr(m,"dpmat");
  54. nat:=!*nat; !*nat:=nil;
  55. write"Saving as ",name;
  56. out name$
  57. write"algebraic(setring "$
  58. % mathprint prints lists without terminator, but matrices with
  59. % terminator.
  60. mathprint ring_2a cali!=basering$ write")$"$
  61. write"algebraic(<<basis :="$ dpmat_print m$
  62. if dpmat_cols m=0 then write"$"$ write">>)$"$
  63. if (c:=dpmat_coldegs m) then
  64. << write"algebraic(degrees:="$
  65. mathprint moid_2a for each x in c collect cdr x$ write")$"$
  66. >>;
  67. write"end$"$ terpri()$
  68. shut name; terpri(); !*nat:=nat;
  69. end;
  70. symbolic procedure initmat!* name;
  71. % Initialize a dpmat from <name>.
  72. if not (stringp name or idp name) then typerr(name,"file name")
  73. else begin scalar m,c; integer i;
  74. write"Initializing ",name; terpri();
  75. in name$ m:=reval 'basis; cali!=degrees:=nil;
  76. if eqcar(m,'list) then
  77. << m:=bas_from_a m; m:=dpmat_make(length m,0,m,nil,nil)>>
  78. else if eqcar(m,'mat) then
  79. << c:=moid_from_a reval 'degrees; i:=0;
  80. cali!=degrees:=for each x in c collect <<i:=i+1; i . x >>;
  81. m:=dpmat_from_a m;
  82. >>
  83. else typerr(m,"basis or matrix");
  84. dpmat_print m;
  85. return m;
  86. end;
  87. % ---- Algebraic mode file transfer ---------
  88. symbolic operator savemat;
  89. symbolic procedure savemat(m,name);
  90. if !*mode='algebraic then savemat!*(dpmat_from_a m,name)
  91. else savemat!*(m,name);
  92. symbolic operator initmat;
  93. symbolic procedure initmat name;
  94. if !*mode='algebraic then dpmat_2a initmat!* name
  95. else initmat!* name;
  96. % --------------- Arithmetics for dpmat's ----------------------
  97. symbolic procedure dpmat!=dpsubst(a,b);
  98. % Substitute in the dpoly a each e_i by b_i from the base list b.
  99. begin scalar v;
  100. for each x in b do
  101. v:=dp_sum(v,dp_prod(dp_comp(bas_nr x,a),bas_dpoly x));
  102. return v;
  103. end;
  104. symbolic procedure dpmat_mult(a,b);
  105. % Returns a * b.
  106. if not eqn(dpmat_cols a,dpmat_rows b) then
  107. rerror('dpmat,1," matrices don't match for MATMULT")
  108. else dpmat_make( dpmat_rows a, dpmat_cols b,
  109. for each x in dpmat_list a collect
  110. bas_make(bas_nr x,
  111. dpmat!=dpsubst(bas_dpoly x,dpmat_list b)),
  112. cali!=degrees,nil)
  113. where cali!=degrees:=dpmat_coldegs b;
  114. symbolic procedure dpmat_times_dpoly(f,m);
  115. % Returns f * m for the dpoly f and the dpmat m.
  116. dpmat_make(dpmat_rows m,dpmat_cols m,
  117. for each x in dpmat_list m collect
  118. bas_make1(bas_nr x, dp_prod(f,bas_dpoly x),
  119. dp_prod(f,bas_rep x)),
  120. cali!=degrees,nil) where cali!=degrees:=dpmat_coldegs m;
  121. symbolic procedure dpmat_neg a;
  122. % Returns - a.
  123. dpmat_make(
  124. dpmat_rows a,
  125. dpmat_cols a,
  126. for each x in dpmat_list a collect
  127. bas_make1(bas_nr x,dp_neg bas_dpoly x, dp_neg bas_rep x),
  128. cali!=degrees,dpmat_gbtag a)
  129. where cali!=degrees:=dpmat_coldegs a;
  130. symbolic procedure dpmat_diff(a,b);
  131. % Returns a - b.
  132. dpmat_sum(a,dpmat_neg b);
  133. symbolic procedure dpmat_sum(a,b);
  134. % Returns a + b.
  135. if not (eqn(dpmat_rows a,dpmat_rows b)
  136. and eqn(dpmat_cols a, dpmat_cols b)
  137. and equal(dpmat_coldegs a,dpmat_coldegs b)) then
  138. rerror('dpmat,2,"matrices don't match for MATSUM")
  139. else (begin scalar u,v,w;
  140. u:=dpmat_list a; v:=dpmat_list b;
  141. w:=for i:=1:dpmat_rows a collect
  142. (bas_make1(i,dp_sum(bas_dpoly x,bas_dpoly y),
  143. dp_sum(bas_rep x,bas_rep y))
  144. where y= bas_getelement(i,v),
  145. x= bas_getelement(i,u));
  146. return dpmat_make(dpmat_rows a,dpmat_cols a,w,cali!=degrees,
  147. nil);
  148. end) where cali!=degrees:=dpmat_coldegs a;
  149. symbolic procedure dpmat_from_dpoly p;
  150. if null p then dpmat_make(0,0,nil,nil,t)
  151. else dpmat_make(1,0,list bas_make(1,p),nil,t);
  152. symbolic procedure dpmat_unit(n,degs);
  153. % Returns the unit dpmat of size n.
  154. dpmat_make(n,n, for i:=1:n collect bas_make(i,dp_from_ei i),degs,t);
  155. symbolic procedure dpmat_unitideal!? m;
  156. (dpmat_cols m = 0) and null matop_pseudomod(dp_fi 1,m);
  157. symbolic procedure dpmat_transpose m;
  158. % Returns transposed m with consistent column degrees.
  159. if (dpmat_cols m = 0) then dpmat!=transpose ideal2mat!* m
  160. else dpmat!=transpose m;
  161. symbolic procedure dpmat!=transpose m;
  162. (begin scalar b,p,q;
  163. cali!=degrees:=
  164. for each x in dpmat_rowdegrees m collect
  165. (car x).(mo_neg cdr x);
  166. for i:=1:dpmat_cols m do
  167. << p:=nil;
  168. for j:=1:dpmat_rows m do
  169. << q:=dpmat_element(j,i,m);
  170. if q then p:=dp_sum(p,dp_times_ei(j,q))
  171. >>;
  172. if p then b:=bas_make(i,p) . b;
  173. >>;
  174. return dpmat_make(dpmat_cols m,dpmat_rows m,reverse b,
  175. cali!=degrees,nil);
  176. end) where cali!=degrees:=cali!=degrees;
  177. symbolic procedure ideal2mat!* u;
  178. % Returns u as column vector if dpmat_cols u = 0.
  179. if dpmat_cols u neq 0 then
  180. rerror('dpmat,4,"IDEAL2MAT only for ideal bases")
  181. else dpmat_make(dpmat_rows u,1,
  182. for each x in dpmat_list u collect
  183. bas_make(bas_nr x,dp_times_ei(1,bas_dpoly x)),
  184. nil,dpmat_gbtag u) where cali!=degrees:=nil;
  185. symbolic procedure dpmat_renumber old;
  186. % Renumber dpmat_list old.
  187. % Returns (new . change) with new = change * old.
  188. if null dpmat_list old then (old . dpmat_unit(dpmat_rows old,nil))
  189. else (begin scalar i,u,v,w;
  190. cali!=degrees:=dpmat_rowdegrees old;
  191. i:=0; u:=dpmat_list old;
  192. while u do
  193. <<i:=i+1; v:=bas_newnumber(i,car u) . v;
  194. w:=bas_make(i,dp_from_ei bas_nr car u) . w ; u:=cdr u>>;
  195. return dpmat_make(i,dpmat_cols old,
  196. reverse v,dpmat_coldegs old,dpmat_gbtag old) .
  197. dpmat_make(i,dpmat_rows old,reverse w,cali!=degrees,t);
  198. end) where cali!=degrees:=cali!=degrees;
  199. symbolic procedure mathomogenize!*(m,var);
  200. % Returns m with homogenized rows using the var. name var.
  201. dpmat_make(dpmat_rows m, dpmat_cols m,
  202. bas_homogenize(dpmat_list m,var), cali!=degrees,nil)
  203. where cali!=degrees:=dpmat_coldegs m;
  204. symbolic operator mathomogenize;
  205. symbolic procedure mathomogenize(m,v);
  206. % Returns the homogenized matrix of m with respect to the variable v.
  207. if !*mode='algebraic then
  208. dpmat_2a mathomogenize!*(dpmat_from_a reval m,v)
  209. else matdehomogenize!*(m,v);
  210. symbolic procedure matdehomogenize!*(m,var);
  211. % Returns m with var. name var set equal to one.
  212. dpmat_make(dpmat_rows m, dpmat_cols m,
  213. bas_dehomogenize(dpmat_list m,var), cali!=degrees,nil)
  214. where cali!=degrees:=dpmat_coldegs m;
  215. symbolic procedure dpmat_sieve(m,vars,gbtag);
  216. % Apply bas_sieve to dpmat_list m. The gbtag slot allows to set the
  217. % gbtag of the result.
  218. dpmat_make(length x,dpmat_cols m,x,cali!=degrees,gbtag)
  219. where x=bas_sieve(dpmat_list m,vars)
  220. where cali!=degrees:=dpmat_coldegs m;
  221. symbolic procedure dpmat_neworder(m,gbtag);
  222. % Apply bas_neworder to dpmat_list m with current cali!=degrees.
  223. % The gbtag sets the gbtag part of the result.
  224. dpmat_make(dpmat_rows m,dpmat_cols m,
  225. bas_neworder dpmat_list m,cali!=degrees,gbtag);
  226. symbolic procedure dpmat_zero!? m;
  227. % Test whether m is a zero dpmat.
  228. bas_zero!? dpmat_list m;
  229. symbolic procedure dpmat_project(m,k);
  230. % Project the dpmat m onto its first k components.
  231. dpmat_make(dpmat_rows m,k,
  232. for each x in dpmat_list m collect
  233. bas_make(bas_nr x,dp_project(bas_dpoly x,k)),
  234. dpmat_coldegs m,nil);
  235. % ---------- Interface to algebraic mode
  236. symbolic procedure dpmat_2a m;
  237. % Convert the dpmat m to a matrix (c>0) or a polynomial list (c=0) in
  238. % algebraic (pseudo)prefix form.
  239. if dpmat_cols m=0 then bas_2a dpmat_list m
  240. else 'mat .
  241. if dpmat_rows m=0 then list for j:=1:dpmat_cols m collect 0
  242. else for i:=1:dpmat_rows m collect
  243. for j:=1:dpmat_cols m collect
  244. dp_2a dpmat_element(i,j,m);
  245. symbolic procedure dpmat_from_a m;
  246. % Convert an algebraic polynomial list or matrix expression into a
  247. % dpmat with respect to the current setting of cali!=degrees.
  248. if eqcar(m,'mat) then
  249. begin integer i; scalar u,p; m:=cdr m;
  250. for each x in m do
  251. << i:=1; p:=nil;
  252. for each y in x do
  253. << p:=dp_sum(p,dp_times_ei(i,dp_from_a reval y)); i:=i+1 >>;
  254. u:=bas_make(0,p).u
  255. >>;
  256. return dpmat_make(length m,length car m,
  257. bas_renumber reversip u, cali!=degrees,nil);
  258. end
  259. else if eqcar(m,'list) then
  260. ((begin scalar x; x:=bas_from_a reval m;
  261. return dpmat_make(length x,0,x,nil,nil)
  262. end) where cali!=degrees:=nil)
  263. else typerr(m,"polynomial list or matrix");
  264. % ---- Substitution in dpmats --------------
  265. symbolic procedure dpmat_sub(a,m);
  266. % a=list of (var . alg. prefix form) to be substituted into the dpmat
  267. % m.
  268. dpmat_from_a subeval1(a,dpmat_2a m)
  269. where cali!=degrees:=dpmat_coldegs m;
  270. % ------------- Determinant ------------------------
  271. symbolic procedure dpmat_det m;
  272. % Returns the determinant of the dpmat m.
  273. if dpmat_rows m neq dpmat_cols m then rederr "non-square matrix"
  274. else dp_from_a prepf numr detq matsm dpmat_2a m;
  275. endmodule; % dpmat
  276. end;