glmat.red 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. module glmat; % Routines for inverting matrices and finding eigen-values
  2. % and vectors. Methods are the same as in glsolve module.
  3. % Author: Eberhard Schruefer.
  4. % Modification: James Davenport and Fran Burstall.
  5. fluid '(!*cramer !*factor !*gcd !*sqfree !*sub2 kord!*);
  6. global '(!!arbint);
  7. if null !!arbint then !!arbint := 0;
  8. switch cramer;
  9. put('cramer,'simpfg,
  10. '((t (put 'mat 'lnrsolvefn 'clnrsolve)
  11. (put 'mat 'inversefn 'matinv))
  12. (nil (put 'mat 'lnrsolvefn 'lnrsolve)
  13. (put 'mat 'inversefn 'matinverse))));
  14. % algebraic operator arbcomplex;
  15. % Done this way since it's also defined in the solve1 module.
  16. deflist('((arbcomplex simpiden)),'simpfn);
  17. symbolic procedure clnrsolve(u,v);
  18. % Interface to matrix package.
  19. multm(matinv u,v);
  20. symbolic procedure minv u;
  21. matinv matsm u;
  22. put('minv,'rtypefn,'quotematrix);
  23. %put('mateigen,'rtypefn,'quotematrix);
  24. remprop('mateigen,'rtypefn);
  25. symbolic procedure matinv u;
  26. % U is a matrix form. Result is the inverse of matrix u.
  27. begin scalar sgn,x,y,z,!*exp;
  28. integer l,m,lm;
  29. !*exp := t;
  30. z := 1;
  31. lm := length car u;
  32. for each v in u do
  33. <<y := 1;
  34. for each w in v do y := lcm(y,denr w);
  35. m := lm;
  36. x := list(nil . (l := l + 1)) .* negf y .+ nil;
  37. for each j in reverse v do
  38. <<if numr j then
  39. x := list m .* multf(numr j,quotf(y,denr j)) .+ x;
  40. m := m - 1>>;
  41. z := c!:extmult(x,z)>>;
  42. if singularchk lpow z then rerror(matrix,13,"Singular matrix");
  43. sgn := evenp length lpow z;
  44. return for each k in lpow z collect
  45. <<sgn := not sgn;
  46. for each j in lpow z collect mkglimat(k,z,sgn,j)>>
  47. end;
  48. symbolic procedure singularchk u; pairp car lastpair u;
  49. flag('(mateigen),'opfn);
  50. flag('(mateigen),'noval);
  51. symbolic procedure mateigen(u,eival);
  52. % U is a matrix form, eival an indeterminate naming the eigenvalues.
  53. % Result is a list of lists:
  54. % {{eival-eq1,multiplicity1,eigenvector1},....},
  55. % where eival-eq is a polynomial and eigenvector is a matrix.
  56. % How much should we attempt to solve the eigenvalue eq.? sqfr?
  57. % Sqfr is necessary if we want to have the full eigenspace. If there
  58. % are multiple roots another pass through eigenvector calculation
  59. % is needed(done).
  60. % We should actually perform the calculations in the extension
  61. % field generated by the eigenvalue equation(done inside).
  62. begin scalar arbvars,exu,sgn,q,r,s,x,y,z,eivec,!*factor,!*sqfree,
  63. !*exp;
  64. integer l;
  65. !*exp := t;
  66. if not(getrtype u eq 'matrix) then typerr(u,"matrix");
  67. eival := !*a2k eival;
  68. kord!* := eival . kord!*;
  69. exu := mateigen1(matsm u,eival);
  70. q := car exu;
  71. y := cadr exu;
  72. z := caddr exu;
  73. exu := cdddr exu;
  74. !*sqfree := t;
  75. for each j in cdr fctrf numr subs2(lc z ./ 1)
  76. do if null domainp car j and mvar car j eq eival
  77. then s := (if null red car j
  78. then !*k2f mvar car j . (ldeg car j*cdr j)
  79. else j) . s;
  80. for each j in q
  81. do (if x then rplacd(x,cdr x + cdr j)
  82. else s := (y . cdr j) . s)
  83. where x := assoc(y,s) where y := absf reorder car j;
  84. l := length s;
  85. r := 'list .
  86. for each j in s collect
  87. <<if null((cdr j = 1) and (l = 1)) then
  88. <<y := 1;
  89. for each k in exu do
  90. if x := reduce!-mod!-eig(car j,c!:extmult(k,y))
  91. then y := x>>;
  92. arbvars := nil;
  93. for each k in lpow z do
  94. if (y=1) or null(k member lpow y) then
  95. arbvars := (k . makearbcomplex()) . arbvars;
  96. sgn := (y=1) or evenp length lpow y;
  97. eivec := 'mat . for each k in lpow z collect list
  98. if x := assoc(k,arbvars)
  99. then mvar cdr x
  100. else prepsq!* mkgleig(k,y,
  101. sgn := not sgn,arbvars);
  102. list('list,prepsq!*(car j ./ 1),cdr j,eivec)>>;
  103. kord!* := cdr kord!*;
  104. return r
  105. end;
  106. symbolic procedure mateigen1(u,eival);
  107. begin scalar q,x,y,z; integer l,lm,m;
  108. lm := length car u;
  109. z := 1;
  110. u := for each v in u collect
  111. <<y := 1;
  112. for each w in v do y := lcm(y,denr w);
  113. m := lm;
  114. l := l + 1;
  115. x := nil;
  116. for each j in reverse v do
  117. <<if numr j or l = m then
  118. x := list m .* multf(if l = m then
  119. addf(numr j,
  120. negf multf(!*k2f eival,
  121. denr j)) else numr j,
  122. quotf(y,denr j)) .+ x;
  123. m := m - 1>>;
  124. y := z;
  125. z := c!:extmult(if null red x then <<
  126. q := (if p then (car p . (cdr p + 1)) . delete(p,q)
  127. else (lc x . 1) . q) where p = assoc(lc x,q);
  128. !*p2f lpow x>> else x,z);
  129. x>>;
  130. return q . y . z . u
  131. end;
  132. symbolic procedure reduce!-mod!-eig(u,v);
  133. % Reduces exterior product v wrt eigenvalue equation u.
  134. begin scalar x,y;
  135. for each j on v do
  136. if numr(y := reduce!-mod!-eigf(u,lc j)) then
  137. x := lpow j .* y .+ x;
  138. y := 1;
  139. for each j on x do y := lcm(y,denr lc j);
  140. return for each j on reverse x collect
  141. lpow j .* multf(numr lc j,quotf(y,denr lc j))
  142. end;
  143. symbolic procedure reduce!-mod!-eigf(u,v);
  144. (subs2 reduce!-eival!-powers(lpow u . negsq cancel(red u ./ lc u),v))
  145. where !*sub2 = !*sub2;
  146. symbolic procedure reduce!-eival!-powers(v,u);
  147. if domainp u or null(mvar u eq caar v) then u ./ 1
  148. else reduce!-eival!-powers1(v,u ./ 1);
  149. symbolic procedure reduce!-eival!-powers1(v,u);
  150. % Reduces powers with the help of the eigenvalue polynomial.
  151. if domainp numr u or (ldeg numr u<pdeg car v) then u
  152. else if ldeg numr u=pdeg car v then
  153. addsq(multsq(cdr v,lc numr u ./ denr u),
  154. red numr u ./ denr u)
  155. else reduce!-eival!-powers1(v,
  156. addsq(multsq(multpf(mvar numr u .** (ldeg numr u-pdeg car v),
  157. lc numr u) ./ denr u,
  158. cdr v),red numr u ./ denr u));
  159. % Determinant calculation using exterior multiplication.
  160. symbolic procedure detex u;
  161. % U is a matrix form, result is determinant of u.
  162. begin scalar f,x,y,z;
  163. integer m,lm;
  164. z := 1;
  165. u := matsm car u;
  166. lm := length car u;
  167. f := 1;
  168. for each v in u do
  169. <<y := 1;
  170. for each w in v do y := lcm(y,denr w);
  171. f := multf(y,f);
  172. m := lm;
  173. x := nil;
  174. for each j in v do
  175. <<if numr j then
  176. x := list m .* multf(numr j,quotf(y,denr j)) .+ x;
  177. m := m - 1>>;
  178. z := c!:extmult(x,z)>>;
  179. return cancel(lc z ./ f)
  180. end;
  181. % Not supported at algebraic user level since it is in general slower
  182. % than other methods.
  183. % put('detex,'simpfn,'detex);
  184. symbolic procedure mkglimat(u,v,sgn,k);
  185. begin scalar s,x,y;
  186. x := nil ./ 1;
  187. y := lpow v;
  188. for each j on red v do
  189. if s := glmatterm(u,y,j,k)
  190. then x := addsq(cancel(s ./ lc v),x);
  191. return if sgn then negsq x else x
  192. end;
  193. symbolic procedure glmatterm(u,v,w,k);
  194. begin scalar x,y,sgn;
  195. x := lpow w;
  196. a: if null x then return
  197. if pairp car y and (cdar y = k) then lc w else nil;
  198. if car x = u then return nil
  199. else if car x member v then <<x := cdr x;
  200. if y then sgn := not sgn>>
  201. else if y then return nil
  202. else <<y := list car x; x := cdr x>>;
  203. go to a
  204. end;
  205. symbolic procedure mkgleig(u,v,sgn,arbvars);
  206. begin scalar s,x,y,!*gcd;
  207. x := nil ./ 1;
  208. y := lpow v;
  209. !*gcd := t;
  210. for each j on red v do
  211. if s := glsoleig(u,y,j,arbvars)
  212. then x := addsq(cancel(s ./ lc v),x);
  213. return if sgn then negsq x else x
  214. end;
  215. symbolic procedure glsoleig(u,v,w,arbvars);
  216. begin scalar x,y,sgn;
  217. x := lpow w;
  218. a: if null x then return
  219. if null car y then lc w
  220. else multf(cdr assoc(car y,arbvars),
  221. if sgn then negf lc w else lc w);
  222. if car x = u then return nil
  223. else if car x member v then <<x := cdr x;
  224. if y then sgn := not sgn>>
  225. else if y then return nil
  226. else <<y := list car x; x := cdr x>>;
  227. go to a
  228. end;
  229. %**** Support for exterior multiplication ****
  230. % Data structure is lpow ::= list of col.-ind. in exterior product
  231. % | nil . number of eq. for inhomog. terms.
  232. % lc ::= standard form
  233. % Exterior multiplication and p-forms:
  234. % Let V be a vector space of dimension n.
  235. % We call the elements of V 1-forms and build new objects called
  236. % p-forms as follows: define a multiplication on 1-forms ^ such that
  237. % v^w=-w^v
  238. % then the linear span of such objects is the space of 2-forms and has
  239. % dimension n(n-1)/2. Indeed, if v_1,...,v_n is a basis of V then
  240. % v_i^v_j for i<j is a basis for the 2-forms.
  241. % We extend this multiplication (called exterior multiplication)
  242. % to get products of p vectors, linear combinations of which are
  243. % called p-forms: this extension is defined by the rule that v_1^...^v_p
  244. % vanishes whenever some v_i=v_j (for i not j). Thus the effect of
  245. % permuting the order of the vectors in such a product is to multiply
  246. % the product by the sign of the permutation.
  247. % Using this it is not difficult to show:
  248. % Theorem: Vectors v_1,...,v_p are linear independent iff their exterior
  249. % product v_1^...^v_p is non-zero.
  250. %
  251. % For more information see F. Warner "Foundations of Differentiable
  252. % Manifolds and Lie Groups" (Springer) Chapter 2. (Or any other book
  253. % on differential geometry or multilinear algebra
  254. symbolic procedure c!:extmult(u,v);
  255. % Special exterior multiplication routine. Degree of form v is
  256. % arbitrary, u is a one-form.
  257. if null u or null v then nil
  258. else if v = 1 then u %unity
  259. % else (if x then cdr x .* (if car x
  260. % then negf c!:subs2multf(lc u,lc v)
  261. % else c!:subs2multf(lc u,lc v))
  262. % .+ c!:extadd(c!:extmult(!*t2f lt u,red v),
  263. % ^^ this is bogus: .+ may not be valid in this circumstance
  264. % c!:extmult(red u,v))
  265. else (if x then
  266. c!:extadd(cdr x .* (if car x
  267. then negf c!:subs2multf(lc u,lc v)
  268. else c!:subs2multf(lc u,lc v)) .+ nil,
  269. c!:extadd(c!:extmult(!*t2f lt u,red v),
  270. c!:extmult(red u,v)))
  271. else c!:extadd(c!:extmult(!*t2f lt u,red v),
  272. c!:extmult(red u,v)))
  273. where x = c!:ordexn(car lpow u,lpow v);
  274. symbolic procedure c!:subs2multf(u,v);
  275. (if denr x neq 1 then rerror(matrix,14,"Sub error in glnrsolve")
  276. else numr x)
  277. where x = subs2(multf(u,v) ./ 1) where !*sub2 = !*sub2;
  278. symbolic procedure c!:extadd(u,v);
  279. if null u then v
  280. else if null v then u
  281. else if lpow u = lpow v then
  282. (lambda x,y; if null x then y else lpow u .* x .+ y)
  283. (addf(lc u,lc v),c!:extadd(red u,red v))
  284. else if c!:ordexp(lpow u,lpow v) then lt u .+ c!:extadd(red u,v)
  285. else lt v .+ c!:extadd(u,red v);
  286. symbolic procedure c!:ordexp(u,v);
  287. if null u then t
  288. else if car u = car v then c!:ordexp(cdr u,cdr v)
  289. else c!:ordxp(car u,car v);
  290. symbolic procedure c!:ordexn(u,v);
  291. % U is a single index, v a list. Returns nil if u is a member
  292. % of v or a dotted pair of a permutation indicator and the ordered
  293. % list of u merged into v.
  294. begin scalar s,x;
  295. a: if null v then return(s . reverse(u . x))
  296. else if (u = car v) or (pairp u and pairp car v)
  297. then return nil
  298. else if c!:ordxp(u,car v) then
  299. return(s . append(reverse(u . x),v))
  300. else <<x := car v . x;
  301. v := cdr v;
  302. s := not s>>;
  303. go to a
  304. end;
  305. symbolic procedure c!:ordxp(u,v);
  306. if pairp u then if pairp v then cdr u < cdr v
  307. else nil
  308. else if pairp v then t
  309. else u < v;
  310. endmodule;
  311. end;