glsolve.red 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. module glsolve; % Routines for solving a general system of linear
  2. % equations using Cramer's rule, realized through
  3. % exterior multiplication.
  4. % Author: Eberhard Schruefer.
  5. % Modifications by: D. Hartley and R.W. Tucker.
  6. % The number of equations and the number of unknowns are arbitrary.
  7. % I.e. the system can be under- or overdetermined.
  8. fluid '(!*solvesingular vars!*); % !*solveinconsistent
  9. global '(!!arbint assumptions requirements);
  10. symbolic procedure glnrsolve(u,v);
  11. % glnrsolve(u: list of sf's, v: list of kernels)
  12. % -> (xprs: list of sq's, flg: boolean)
  13. % Adapted by D. Hartley and R.W. Tucker from E. Schruefer's glnrsolve.
  14. % The equations u must be ordered with respect to the kernels v
  15. begin scalar sgn,x,y,cnds;
  16. if null u then go to b;
  17. a: x := !*sf2ex(car u,v);
  18. if null x then u := cdr u
  19. else if inconsistency!-chk x then
  20. <<cnds := car u . cnds; x := nil; u := cdr u>>;
  21. if u and null x then go to a;
  22. b:
  23. if null u then % no consistent non-zero equations
  24. if cnds then go to d
  25. else return t . {{nil,nil,1}}; % all equations were zero
  26. if null(u := cdr u) then go to d;
  27. c: if y := subs2chkex extmult(!*sf2ex(car u,v),x)
  28. then if inconsistency!-chk y
  29. then cnds := numr cancel(lc y ./ lc x) . cnds
  30. else <<assumptions :=
  31. 'list . mk!*sq !*f2q lc y .
  32. (pairp assumptions and cdr assumptions);
  33. x := y>>;
  34. if (u := cdr u) then go to c;
  35. d:
  36. for each j in cnds do
  37. requirements := 'list . mk!*sq !*f2q j .
  38. (pairp requirements and cdr requirements);
  39. if cnds then return 'inconsistent . nil;
  40. if setdiff(v,lpow x) and not !*solvesingular then
  41. return 'singular . {};
  42. if null red x then return
  43. t . {{for each j in lpow x collect nil ./ 1,lpow x,1}};
  44. y := lc x; sgn := evenp length lpow x;
  45. u := foreach j in lpow x collect
  46. (if (sgn := not sgn) then negf f else f)
  47. where f = !*ex2sf innprodpex(delete(j,lpow x),red x);
  48. return t . {{foreach f in u collect cancel(f ./ y),lpow x,1}};
  49. end;
  50. symbolic procedure inconsistency!-chk u;
  51. null u or ((nil memq lpow u) and inconsistency!-chk red u);
  52. endmodule;
  53. end;