matsm.red 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. module matsm; % Simplification of matrices.
  2. % Author: Anthony C. Hearn.
  3. % Copyright (c) 1998 Anthony C. Hearn. All rights reserved.
  4. % This module is rife with essential references to RPLAC-based
  5. % functions.
  6. symbolic procedure matsm!*(u,v);
  7. % Matrix expression simplification function.
  8. matsm!*1 matsm u;
  9. % symbolic procedure matsm!*1 u;
  10. % begin scalar sub2;
  11. % sub2 := !*sub2; % Since we need value for each element.
  12. % u := 'mat . for each j in u collect
  13. % for each k in j
  14. % collect <<!*sub2 := sub2; !*q2a subs2 k>>;
  15. % !*sub2 := nil; % Since all substitutions done.
  16. % return u
  17. % end;
  18. symbolic procedure matsm!*1 u;
  19. begin
  20. % We use subs2!* to make sure each element simplified fully.
  21. u := 'mat . for each j in u collect
  22. for each k in j collect !*q2a subs2!* k;
  23. !*sub2 := nil; % Since all substitutions done.
  24. return u
  25. end;
  26. symbolic procedure matsm u;
  27. begin scalar x,y;
  28. for each j in nssimp(u,'matrix) do
  29. <<y := multsm(car j,matsm1 cdr j);
  30. x := if null x then y else addm(x,y)>>;
  31. return x
  32. end;
  33. symbolic procedure matsm1 u;
  34. %returns matrix canonical form for matrix symbol product U;
  35. begin scalar x,y,z; integer n;
  36. a: if null u then return z
  37. else if eqcar(car u,'!*div) then go to d
  38. else if atom car u then go to er
  39. else if caar u eq 'mat then go to c1
  40. else <<x := lispapply(caar u,cdar u); %
  41. if eqcar(x,'mat) then x := matsm x>>; %
  42. b: z := if null z then x
  43. else if null cdr z and null cdar z then multsm(caar z,x)
  44. else multm(x,z);
  45. c: u := cdr u;
  46. go to a;
  47. c1: if not lchk cdar u then rerror(matrix,3,"Matrix mismatch");
  48. x := for each j in cdar u collect
  49. for each k in j collect xsimp k;
  50. go to b;
  51. d: y := matsm cadar u;
  52. if (n := length car y) neq length y
  53. then rerror(matrix,4,"Non square matrix")
  54. else if (z and n neq length z)
  55. then rerror(matrix,5,"Matrix mismatch")
  56. else if cddar u then go to h
  57. else if null cdr y and null cdar y then go to e;
  58. x := subfg!*;
  59. subfg!* := nil;
  60. if null z then z := apply1(get('mat,'inversefn),y)
  61. else if null(x := get('mat,'lnrsolvefn))
  62. then z := multm(apply1(get('mat,'inversefn),y),z)
  63. else z := apply2(get('mat,'lnrsolvefn),y,z);
  64. subfg!* := x;
  65. % Make sure there are no power substitutions.
  66. z := for each j in z collect for each k in j collect
  67. <<!*sub2 := t; subs2 k>>;
  68. go to c;
  69. e: if null caaar y then rerror(matrix,6,"Zero divisor");
  70. y := revpr caar y;
  71. z := if null z then list list y else multsm(y,z);
  72. go to c;
  73. h: if null z then z := generateident n;
  74. go to c;
  75. er: rerror(matrix,7,list("Matrix",car u,"not set"))
  76. end;
  77. symbolic procedure lchk u;
  78. begin integer n;
  79. if null u or atom car u then return nil;
  80. n := length car u;
  81. repeat u := cdr u
  82. until null u or atom car u or length car u neq n;
  83. return null u
  84. end;
  85. symbolic procedure addm(u,v);
  86. % Returns sum of two matrix canonical forms U and V.
  87. % Returns U + 0 as U. Patch by Francis Wright.
  88. if v = '(((nil . 1))) then u else % FJW.
  89. for each j in addm1(u,v,function cons)
  90. collect addm1(car j,cdr j,function addsq);
  91. symbolic procedure addm1(u,v,w);
  92. if null u and null v then nil
  93. else if null u or null v then rerror(matrix,8,"Matrix mismatch")
  94. else apply2(w,car u,car v) . addm1(cdr u,cdr v,w);
  95. symbolic procedure tp u; tp1 matsm u;
  96. put('tp,'rtypefn,'getrtypecar);
  97. symbolic procedure tp1 u;
  98. %returns transpose of the matrix canonical form U;
  99. %U is destroyed in the process;
  100. begin scalar v,w,x,y,z;
  101. v := w := list nil;
  102. while car u do
  103. <<x := u;
  104. y := z := list nil;
  105. while x do
  106. <<z := cdr rplacd(z,list caar x);
  107. x := cdr rplaca(x,cdar x)>>;
  108. w := cdr rplacd(w,list cdr y)>>;
  109. return cdr v
  110. end;
  111. symbolic procedure scalprod(u,v);
  112. %returns scalar product of two lists (vectors) U and V;
  113. if null u and null v then nil ./ 1
  114. else if null u or null v then rerror(matrix,9,"Matrix mismatch")
  115. else addsq(multsq(car u,car v),scalprod(cdr u,cdr v));
  116. symbolic procedure multm(u,v);
  117. %returns matrix product of two matrix canonical forms U and V;
  118. (for each y in u
  119. collect for each k in x collect subs2 scalprod(y,k))
  120. where x = tp1 v;
  121. symbolic procedure multsm(u,v);
  122. %returns product of standard quotient U and matrix standard form V;
  123. if u = (1 ./ 1) then v
  124. else for each j in v collect for each k in j collect multsq(u,k);
  125. % Explicit substitution code for matrices.
  126. symbolic procedure matsub(u,v);
  127. 'mat . for each x in cdr v collect
  128. for each y in x collect subeval1(u,y);
  129. put('matrix,'subfn,'matsub);
  130. endmodule;
  131. end;