matrext.red 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. module matrext;
  2. % This module defines additional utility functions for manipulating
  3. % matrices. Coercions to BAG and LIST structures are defined.
  4. symbolic procedure natnumlis u;
  5. % True if U is a list of natural numbers.
  6. % Taken from MATR.RED for bootstrap purpose.
  7. null u or numberp car u and fixp car u and car u>0 and natnumlis cdr u;
  8. symbolic procedure mkidm(u,j);
  9. % This function allows us to RELATE TWO MATRICES by concatanation of
  10. % characters. u AND uj should BOTH be matrices.
  11. % matsm cadr get(mkid!:(u,j),'avalue) ;
  12. mkid(u,j);
  13. flag('(mkidm),'opfn);
  14. flag('(mkidm),'noval);
  15. symbolic procedure baglmat (u,op);
  16. % this procedure maps U into the matrix whose name is OP;
  17. % it cannot REDEFINE the matrix OP.
  18. % This is to avoid accidental redefinition of a previous matrix;
  19. if getrtype op then rederr list(op,"should be an identifier")
  20. else
  21. begin scalar x,y;
  22. if atom op then if not (y:=gettype op) then put(op,'rtype,'matrix)
  23. else typerr(list(y,op),"matrix");
  24. if rdepth list u neq 2 then rederr("depth of list or bag must be 2");
  25. x:=cdr u;
  26. x:= for each j in x collect for each k in cdr j collect k;
  27. put(op,'avalue,list('matrix,'mat . x));
  28. return t end;
  29. flag('(baglmat),'opfn);
  30. symbolic procedure rcoercemat u;
  31. % Transforms a matrix into a bag or list. Argument is a list (mat,idp).
  32. % idp is the name to be given to the line or column vectors.
  33. % The idp-envelope of the bag is the same as the one of the one of the
  34. % subbags$
  35. begin scalar x,prf;
  36. x:=reval car u;
  37. if getrtype x neq 'matrix then rederr list(x,"should be a matrix");
  38. prf:= cadr u;
  39. if car x neq 'mat then typerr(x,"matrix") else
  40. if prf neq 'list then <<prf:=reval prf; simpbagprop list(prf,t)>>;
  41. x:=cdr x;
  42. x:= for each j in x collect (prf . j);
  43. return prf . x end;
  44. put('coercemat,'psopfn,'rcoercemat);
  45. put('rcoercemat,'number!_of!_args,2);
  46. symbolic procedure n!-1zero(n,k)$
  47. if n=0 then nil else
  48. if k=1 then 1 . nzero(n-1) else
  49. if k=n then append(nzero(n-1) , (1 . nil)) else
  50. append(nzero(k-1), (1 . nzero(n-k)))$
  51. symbolic procedure unitmat u$
  52. % It creates unit matrices. The argument is of the form A(2),B(5)....$
  53. begin scalar l,sy,x,aa$
  54. for each s in u do
  55. << if atom s or length (l:= revlis cdr s) neq 1 or not natnumlis l
  56. then errpri2(s,'hold) else
  57. <<aa:=nil;sy:=car s; x:=gettype sy; if not null x then if x eq 'matrix
  58. then lprim list(x,sy,"redefined")
  59. else typerr(list(x,sy),"matrix");
  60. l:=car l; for n:=1:l do aa:=n!-1zero(l,l-n+1) . aa$
  61. put(sy,'rtype,'matrix);
  62. put(sy,'avalue,list('matrix,'mat . aa))>>>>;
  63. end$
  64. put('unitmat,'stat,'rlis);
  65. symbolic procedure submat (u,nl,nc);
  66. % Allows to extract from the matrix M the matrix obtained when
  67. % the row NL and the column NC have been dropped.
  68. % When NL and NC are out of range gives a copy of M;
  69. if getrtype u neq 'matrix then rederr list(u,"should be a matrix")
  70. else
  71. begin scalar x;
  72. x:= matsm u;
  73. if and(nl=0,nc=0) then return x else
  74. if nl neq 0 then x:=remove(x,nl)$
  75. if nc neq 0 then
  76. x:=for each j in x collect remove(j,nc);
  77. return x end;
  78. put('submat,'rtypefn,'getrtypecar);
  79. flag('(submat),'matflg);
  80. symbolic procedure matsubr(m,bgl,nr)$
  81. if getrtype m neq 'matrix then rederr list(m,"should be a matrix")
  82. else
  83. begin scalar x,y,res; integer xl;
  84. % It allows to replace row NR of the matrix M by the bag or list BGL;
  85. y:=reval bgl;
  86. if not baglistp y then typerr(y,"bag or list") else
  87. if nr leq 0 then rederr " THIRD ARG. MUST BE POSITIVE"
  88. else
  89. x:=matsm m$ xl:=length x$
  90. if length( y:=cdr y) neq xl then rederr " MATRIX MISMATCH"$
  91. y:= for each j in y collect simp j;
  92. if nr-xl >0 then rederr " row number is out of range";
  93. while (nr:=nr-1) >0
  94. do <<res:=car x . res$ x:=cdr x >>;
  95. rplaca(x,y) ;
  96. res:=append( reverse res, x) ;
  97. return res end;
  98. put('matsubr,'rtypefn,'getrtypecar);
  99. flag('(matsubr),'matflg);
  100. symbolic procedure matsubc(m,bgl,nc)$
  101. if getrtype m neq 'matrix then rederr list(m,"should be a matrix")
  102. else
  103. begin scalar x,y,res; integer xl;
  104. %It allows to replace column NC of the matrix M by the bag or list BGL
  105. y:=reval bgl;
  106. if not baglistp y then typerr(y,"bag or list") else
  107. if nc leq 0 then rederr " THIRD ARG. MUST BE POSITIVE"
  108. else
  109. x:=tp1 matsm m$ xl:=length x$
  110. if length( y:=cdr y) neq xl then rederr " MATRIX MISMATCH"$
  111. y:= for each j in y collect simp j;
  112. if nc-xl >0 then rederr " column number is out of range";
  113. while (nc:=nc-1) >0
  114. do <<res:=car x . res$ x:=cdr x >>;
  115. rplaca(x,y) ;
  116. res:=tp1 append( reverse res, x) ;
  117. return res end;
  118. put('matsubc,'rtypefn,'getrtypecar);
  119. flag('(matsubc),'matflg);
  120. symbolic procedure rmatextr u$
  121. % This function allows to extract row N from matrix A and
  122. % to place it inside a bag whose name is LN$
  123. begin scalar x,y; integer n,nl;
  124. x:= matsm car u; y:= reval cadr u; n:=reval caddr u;
  125. if not fixp n then
  126. rederr "Arguments are: matrix, vector name, line number" else
  127. if not baglistp list y then simpbagprop list(y, t)$
  128. nl:=length x;
  129. if n<= 0 or n>nl then return nil$
  130. while n>1 do <<x:=cdr x$ n:=n-1>>$
  131. if null x then return nil$
  132. return x:=y . ( for each j in car x collect prepsq j) end$
  133. symbolic procedure rmatextc u$
  134. % This function allows to extract column N from matrix A and
  135. % to place it inside a bag whose name is LN$
  136. begin scalar x,y; integer n,nc;
  137. x:= tp1 matsm car u; y:= reval cadr u; n:=reval caddr u;
  138. if not fixp n then
  139. rederr "Arguments are: matrix, vector name, line number" else
  140. if not baglistp list y then simpbagprop list(y, t)$
  141. nc:=length x;
  142. if n<= 0 or n>nc then return nil$
  143. while n>1 do <<x:=cdr x$ n:=n-1>>$
  144. if null x then return nil$
  145. return x:=y . ( for each j in car x collect prepsq j) end$
  146. put('matextr,'psopfn,'rmatextr);
  147. put('matextc,'psopfn,'rmatextc);
  148. symbolic procedure hconcmat(u,v)$
  149. % Gives the horizontal concatenation of matrices U and V$
  150. hconcmat!:(matsm u,matsm v );
  151. symbolic procedure hconcmat!:(u,v)$
  152. if null u then v else if null v then u else
  153. append(car u,car v) . hconcmat!:(cdr u,cdr v)$
  154. symbolic put('hconcmat,'rtypefn,'getrtypecar);
  155. symbolic flag('(hconcmat),'matflg);
  156. symbolic procedure vconcmat (u,v)$
  157. % Gives the vertical concatenation of matrices U and V$
  158. append(matsm u,matsm v);
  159. put('vconcmat,'rtypefn,'getrtypecar);
  160. flag('(vconcmat),'matflg);
  161. symbolic procedure tprodl(u,v)$
  162. begin scalar aa,ul$
  163. l1: if null u then return aa$
  164. ul:=car u$
  165. ul:=multsm(ul,v)$
  166. aa:=hconcmat!:(aa,ul)$
  167. u:=cdr u$
  168. go to l1$
  169. end$
  170. symbolic procedure tpmat(u,v)$
  171. % Constructs the direct product of two matrices;
  172. if null gettype u then multsm(simp u,matsm v) else
  173. if null gettype v then multsm(simp v,matsm u) else
  174. begin scalar aa,uu,vv$
  175. uu:=matsm u$ vv:=matsm v$
  176. for each x in uu do aa:=append (aa,tprodl(x,vv))$
  177. return aa end;
  178. infix tpmat$
  179. put('tpmat,'rtypefn, 'getrtypecar);
  180. flag('(tpmat),'matflg)$
  181. algebraic procedure hermat (m,hm);
  182. % hm must be an identifier with NO value. Returns the
  183. % Hermitiam Conjugate matrix.
  184. begin scalar ml,ll; %ll:=length M;
  185. m:=tp m;
  186. ml:=coercemat(m,list);
  187. ll:=list(length first ml,length ml);
  188. ml:=for j:=1: first ll collect for k:=1:second ll collect
  189. sub(i=-i,(ml.j).k);
  190. baglmat(ml,hm);
  191. return hm end;
  192. symbolic procedure seteltmat(m,elt,i,j);
  193. % Sets the matrix element (i,j) to elt. Returns the modified matrix.
  194. begin scalar res;res:=matsm m;
  195. rplaca(pnth(nth(res,i),j),simp elt);
  196. return res end;
  197. put('seteltmat,'rtypefn,'getrtypecar);
  198. flag('(seteltmat),'matflg);
  199. symbolic procedure simpgetelt u;
  200. % Gets the matrix element (i,j). Returns the element.
  201. begin scalar mm;
  202. mm:=matsm car u;
  203. return nth(nth(mm,cadr u),caddr u) end;
  204. put('geteltmat, 'simpfn,'simpgetelt);
  205. endmodule;
  206. end;