solve.red 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022
  1. COMMENT SOLVE MODULE;
  2. %******************* Global Declarations ***************************;
  3. SYMBOLIC;
  4. FLAG('(!*SOLVEWRITE), 'SHARE);
  5. ARRAY !!CF(12), !!INTERVAL(10,2), !!EXACT(10);
  6. GLOBAL '(!!HIPOW !!GCD !*SOLVESINGULAR SM!* MP!* !*ALLBRANCH
  7. !*SOLVEWRITE !!ARBINT !*SOLVEINTERVAL !!INTERVALARRAY);
  8. !*SOLVESINGULAR := T; % Solves consistent, singular eqns (0=0) if T;
  9. !*ALLBRANCH := T; % Returns all branches of solutions if T;
  10. !*SOLVEWRITE := T; % Prints solutions if T;
  11. %!*SOLVEINTERVAL = NIL;% Attempts to isolate insoluble, real roots if T;
  12. !!INTERVALARRAY := '!!INTERVAL; % Value is the name of an array used to
  13. % pass args to RealRoot routines;
  14. !!ARBINT := 0; % Index for arbitrary constants;
  15. % !!HIPOW : SOLVECOEFF returns highest power of its arg in this
  16. % !!GCD : SOLVECOEFF returns GCD of powers of its arg in this
  17. % !!CF : Array of coeffs from SOLVECOEFF
  18. %
  19. % SM!* : List of solutions
  20. % MP!* : List of multiplicities;
  21. ALGEBRAIC MATRIX SOLN, MULTIPLICITY;
  22. %******************* Utility Functions *****************************;
  23. SYMBOLIC PROCEDURE RPLACX U;
  24. BEGIN SCALAR CARU;
  25. CARU := CAR U;
  26. RETURN RPLACD(RPLACA(U,CDR U),CARU)
  27. END;
  28. SYMBOLIC PROCEDURE UNIVARIATEP F;
  29. % F is a standard form. Non-nil iff F is univariate or a constant;
  30. DOMAINP F OR
  31. (DOMAINP LC F AND (DOMAINP RED F OR
  32. ((MVAR F = MVAR RED F) AND UNIVARIATEP RED F) ));
  33. SYMBOLIC SMACRO PROCEDURE SUBTRSQ(U,V);
  34. ADDSQ(U, NEGSQ V);
  35. SYMBOLIC SMACRO PROCEDURE VARLIS U;
  36. %U is an r-polynomial.
  37. %value is an ordered list of variables in U;
  38. VARLIS1(U,NIL);
  39. SYMBOLIC SMACRO PROCEDURE LFCTR U;
  40. COMMENT RETURNS LEFTFACTOR OF A PAIR. USED BY
  41. SUMFACTORS IN IEQN.RED;
  42. CAAR U;
  43. SYMBOLIC OPERATOR LCMD;
  44. SYMBOLIC PROCEDURE LCMD(C,D);
  45. COMMENT C and D are prefix rational numbers. Returns
  46. integer least-common-multiple of their denominators;
  47. LCM(DENR SIMP!* C, DENR SIMP!* D);
  48. SYMBOLIC PROCEDURE VARLIS1(U,V);
  49. IF DOMAINP U THEN V
  50. ELSE VARLIS1(CDR U,VARLIS1(CDAR U,ORDAS(CAAAR U,V)));
  51. SYMBOLIC PROCEDURE ORDAS(A,L);
  52. IF NULL L THEN LIST A
  53. ELSE IF A=CAR L THEN L
  54. ELSE IF ORDP(A,CAR L) THEN A . L
  55. ELSE CAR L . ORDAS(A,CDR L);
  56. SYMBOLIC PROCEDURE RATNUMP X;
  57. COMMENT Returns T iff any prefix expression X is a rational
  58. number;
  59. ATOM NUMR(X:=SIMP!* X) AND ATOM DENR X;
  60. FLAG ('(RATNUMP), 'DIRECT);
  61. SYMBOLIC PROCEDURE KARGLIS(KNAME, KLIS);
  62. COMMENT KNAME evaluates to an atom and KLIS to a list of
  63. kernels. Returns the list of kernels named KNAME in KLIS;
  64. IF NULL KLIS THEN NIL
  65. ELSE UNION(KARG1(KNAME, CAR KLIS), KARGLIS(KNAME,CDR KLIS));
  66. SYMBOLIC PROCEDURE KARG1(KNAME, KRN);
  67. COMMENT KNAME evaluates to an atom and KRN to a kernel.
  68. Returns a list of kernels named KNAME in KRN;
  69. IF ATOM KRN THEN NIL
  70. ELSE IF CAR KRN=KNAME THEN UNION(KARGLIS(KNAME,CDR KRN),
  71. LIST(KRN))
  72. ELSE KARGLIS(KNAME, CDR KRN);
  73. SYMBOLIC PROCEDURE ALLKERN ELST;
  74. COMMENT Returns list of all top-level kernels in the list of
  75. standard forms ELST;
  76. IF NULL ELST THEN NIL
  77. ELSE UNION(VARLIS CAR ELST, ALLKERN CDR ELST);
  78. SYMBOLIC OPERATOR FREEOFKERN;
  79. SYMBOLIC PROCEDURE FREEOFKERN(X,U);
  80. COMMENT Returns T iff any expression U is free of kernel X;
  81. IF ATOM X THEN FREEOF(U,X)
  82. ELSE FREEOF(SUBST('!!DUM,X,U),'!!DUM);
  83. FLAG('(FREEOFKERN),'DIRECT);
  84. SYMBOLIC PROCEDURE TOPKERN(EX, X);
  85. BEGIN COMMENT Returns list of toplevel kernels in the
  86. standard form EX that contain the kernel X;
  87. SCALAR ALLK, WITHX;
  88. ALLK := VARLIS EX;
  89. WHILE ALLK DO<<
  90. IF NOT FREEOFKERN(X,CAR ALLK) THEN WITHX:=CAR ALLK.WITHX;
  91. ALLK:=CDR ALLK>>;
  92. RETURN WITHX
  93. END;
  94. SYMBOLIC PROCEDURE COEFLIS(EX);
  95. % EX is a standard form.
  96. % Returns a list of the coefficients of the main variable
  97. % in ex in the form ((expon.coeff) (expon.coeff) ... ),
  98. % where the expon's occur in increasing order, and entries
  99. % do not occur of zero coefficients;
  100. BEGIN
  101. SCALAR X, ANS, OLDKORD, VAR;
  102. X := EX;
  103. IF DOMAINP(X) THEN
  104. RETURN (0 . X);
  105. VAR := MVAR(EX);
  106. WHILE (NOT DOMAINP(X)) AND MVAR(X)=VAR DO <<
  107. ANS := (LDEG(X) . LC(X)) . ANS;
  108. X := RED(X) >>;
  109. IF X THEN
  110. ANS := (0 . X) . ANS;
  111. RETURN ANS
  112. END;
  113. %******************* Temporary Factoring Routine *******************;
  114. % The following square free factoring routine, based on the Reduce
  115. % function SQFRF, will eventually be replaced by the Norman-Moore
  116. % complete factorization technique.;
  117. FLUID '(!*GCD);
  118. SYMBOLIC PROCEDURE FACTLIS(EX, KLIST);
  119. % EX is a standard form.
  120. % KLIST is a list of kernels.
  121. % Returns a list of square free factors containing the elements of
  122. % KLIST in the form ((integer exponent . standard form factor) ...).;
  123. % Factors constant with respect to KLIST are discarded;
  124. BEGIN
  125. SCALAR FIRST, ANS, OLDGCD, OLDKORD; INTEGER EXPON;
  126. OLDGCD := !*GCD;
  127. !*GCD := T; % Must be on for SQFRF;
  128. OLDKORD := SETKORDER(KLIST);
  129. EX := REORDER(EX);
  130. WHILE (NOT DOMAINP(EX)) AND (MVAR(EX) MEMBER KLIST) DO <<
  131. FIRST := PP(EX);
  132. IF NOT DOMAINP(FIRST) THEN <<
  133. % Non-zero roots;
  134. EX := QUOTF(EX, FIRST);
  135. FIRST := SQFRF(FIRST);
  136. FOR EACH X IN FIRST DO
  137. IF NOT DOMAINP X THEN
  138. ANS := RPLACX X . ANS >>
  139. ELSE <<
  140. % Zero root (possibly multiple);
  141. ANS := (LDEG(EX) . !*K2F(MVAR(EX))) . ANS;
  142. EX := QUOTF(EX, !*P2F(LPOW(EX))) >> >>;
  143. % Restore the state of the world;
  144. SETKORDER(OLDKORD);
  145. !*GCD := OLDGCD;
  146. RETURN ANS
  147. END;
  148. %******************* SOLVE Statement ******************************;
  149. SYMBOLIC PROCEDURE SIMPSOLVE ARGLIST;
  150. BEGIN
  151. INTEGER NARGS;
  152. NARGS := LENGTH(ARGLIST);
  153. RETURN !*F2Q IF NARGS=1 THEN SOLVE0(CAR ARGLIST,NIL)
  154. ELSE IF NARGS=2
  155. THEN SOLVE0(CAR ARGLIST, CADR ARGLIST)
  156. ELSE SOLVE0(CAR ARGLIST,'LST . CDR ARGLIST)
  157. END;
  158. PUT ('SOLVE,'SIMPFN,'SIMPSOLVE);
  159. %******************* Fundamental SOLVE Procedures ******************;
  160. SYMBOLIC PROCEDURE SOLVE0(ELST, XLST);
  161. BEGIN COMMENT ELST is any prefix expression, including the
  162. kernel named LST with any number of arguments. XLST is
  163. a kernel, perhaps named LST with any number of arguments.
  164. Solves eqns in ELST for vars in XLST, putting solutions
  165. and multiplicities in SOLN and MULTIPLICITIES.
  166. Prints SOLN if !*SOLVEWRITE is non-nil.
  167. Returns number of rows in global matrix SOLN;
  168. SCALAR FLST, VARS, NONLIN; INTEGER NEQN, I;
  169. %/ MAYBELOADMATR();
  170. ALGEBRAIC CLEAR SOLN, MULTIPLICITY;
  171. SM!* := MP!* := NIL;
  172. IF NOT ATOM ELST AND CAR ELST='LST THEN ELST:=CDR ELST
  173. ELSE ELST:=LIST ELST;
  174. NEQN:=0;
  175. WHILE ELST DO <<FLST:= NUMR SIMP!* CAR ELST . FLST;
  176. NEQN:=NEQN+1; ELST:= CDR ELST >>;
  177. % Note that ELST and XLST are reversed from the order entered;
  178. IF NULL XLST THEN <<VARS := ALLKERN FLST;
  179. WRITE "UNKNOWNS:";
  180. MAPCAR(REVERSE VARS, FUNCTION MATHPRINT);
  181. TERPRI()>>
  182. ELSE<<IF ATOM XLST OR NOT(CAR XLST='LST)THEN XLST:=LIST(XLST)
  183. ELSE XLST:=CDR XLST;
  184. WHILE XLST DO<<
  185. VARS:=MVAR !*A2F CAR XLST.VARS;
  186. XLST:= CDR XLST>>>>;
  187. IF NOT(NEQN=LENGTH VARS) THEN REDERR
  188. "SOLVE CALLED WITH UNEQUAL NUMBER OF EXPRESSIONS AND UNKNOWNS";
  189. IF NEQN=1 THEN
  190. IF NULL (FLST:=CAR FLST) THEN
  191. IF !*SOLVESINGULAR THEN <<!!ARBINT:=!!ARBINT+1;
  192. CONSSMMP(SIMP!* LIST('ARBCOMPLEX,!!ARBINT), 1) >>
  193. ELSE RETURN 0
  194. ELSE <<VARS:=CAR VARS;
  195. SOLVE1(FLST./1, VARS, 1) >>
  196. COMMENT More than one equation;
  197. ELSE <<
  198. SM!* := TP1(SOLVESYS(FLST, VARS));
  199. MP!* := LIST(LIST(MK!*SQ(!*F2Q(1)))) >>;
  200. SM!* := MAPC2(SM!*, FUNCTION MK!*SQ);
  201. PUT('MULTIPLICITY, 'MATRIX, 'MAT . MP!*);
  202. PUT('SOLN, 'MATRIX, 'MAT . SM!*);
  203. IF !*SOLVEWRITE THEN
  204. MATPRI(SM!*, 'SOLN);
  205. RETURN LENGTH SM!*
  206. END;
  207. SYMBOLIC PROCEDURE CONSSMMP(S, M);
  208. BEGIN COMMENT S is a standard quotient and M is an integer.
  209. Conses (S) to global variable SM!* and (M) to global
  210. variable MP!*;
  211. SM!* := LIST(S) . SM!*;
  212. MP!* := LIST(MK!*SQ(M./1)) . MP!*
  213. END;
  214. SYMBOLIC PROCEDURE SOLVEF(F, V);
  215. % F is a standard form, V is a kernel. Returns a list of
  216. % pairs, each of which car is a standard quotient and cdr an
  217. % integer. If the integer is positive, the SQ is a zero of
  218. % F with multiplicity equal to the integer. Otherwise it is
  219. % an insoluble factor, with multiplicity the absolute value of
  220. % the integer;
  221. BEGIN SCALAR OLDSOLVEWRITE, ANS;
  222. OLDSOLVEWRITE := !*SOLVEWRITE;
  223. !*SOLVEWRITE := NIL;
  224. SOLVE0(MK!*SQ(!*F2Q(F)), V);
  225. ANS := PAIR(MAPCAR(SM!*, FUNCTION LAMBDA(X); SIMP!*(CAR(X))),
  226. MAPCAR(MP!*, FUNCTION CAR) );
  227. !*SOLVEWRITE := OLDSOLVEWRITE;
  228. RETURN ANS
  229. END;
  230. %******************* Procedures for solving a single eqn ***********;
  231. SYMBOLIC PROCEDURE SOLVE1 (EX, X, MUL);
  232. BEGIN COMMENT Factors standard quotient EX with respect to
  233. toplevel occurrences of X and kernels containing variable
  234. X. Factors containing more than one such kernel
  235. are appended to SM!*, with a negative multiplicity
  236. indicating unsolvability, and SOLVE2 is applied
  237. to the other factors. Integer MUL is the multiplicity
  238. passed from any previous factorizations. Returns NIL;
  239. SCALAR E1, X1, TKLIST; INTEGER MU;
  240. EX := NUMR EX;
  241. TKLIST := TOPKERN(EX,X);
  242. IF NULL TKLIST THEN RETURN NIL;
  243. EX := FACTLIS(EX, TKLIST);
  244. WHILE EX DO <<
  245. E1 := CDAR(EX);
  246. X1 := TOPKERN(E1, X);
  247. MU := MUL*CAAR EX;
  248. IF X1 THEN
  249. IF NULL CDR X1 THEN
  250. SOLVE2(E1,CAR X1,X,MU)
  251. ELSE IF SMEMQ('SOL,
  252. (X1:=SIMP!* LIST('SOL,MK!*SQ(E1./1), X))) THEN
  253. CONSSMMP(E1./1, -MU)
  254. ELSE
  255. SOLVE1(X1,X,MU);
  256. EX := CDR(EX) >>
  257. END;
  258. SYMBOLIC PROCEDURE SOLVE2(E1, X1, X, MU);
  259. BEGIN COMMENT E1 is a standard form, MU is an
  260. integer, X1 and X are kernels. Uses roots of unity, known
  261. inverses, together with quadratic, cubic and quartic
  262. formulas, treating other cases as unsolvable. Returns NIL;
  263. SCALAR B, C, D, F; INTEGER N;
  264. F:= ERRORSET(SOLVECOEFF(E1, X1),NIL,NIL);
  265. N:= !!GCD;
  266. COMMENT Test for single power of X1;
  267. IF ATOM(F) THEN CONSSMMP(E1./1, -MU)
  268. ELSE IF (F:=CAR F)=-1 THEN <<
  269. B:= LIST('EXPT, MK!*SQ QUOTSQ(NEGSQ SIMP!* GETELV(LIST('!!CF,0)),
  270. SIMP!* GETELV(LIST('!!CF,1))), MK!*SQ(1 ./!!GCD));
  271. FOR K := 0:N-1 DO <<
  272. SETELV(LIST('!!CF,1), SIMP!* LIST('TIMES,B,
  273. MKEXP LIST('QUOTIENT,LIST('TIMES,K,2,'PI),N)));
  274. COMMENT x = b;
  275. IF X1=X THEN CONSSMMP(GETELV(LIST('!!CF, 1)), MU)
  276. COMMENT LOG(x) = b;
  277. ELSE IF CAR X1 = 'LOG THEN SOLVE1
  278. (SUBTRSQ(SIMP!* CADR X1,SIMP!* LIST('EXPT,'E,MK!*SQ
  279. GETELV(LIST('!!CF, 1)))),X,MU)
  280. ELSE IF CAR X1 = 'EXPT THEN
  281. COMMENT c**(...) = b;
  282. IF FREEOF(CADR X1,X) THEN <<
  283. IF !*ALLBRANCH THEN <<!!ARBINT:=!!ARBINT+1;
  284. C:=LIST('TIMES,2,'I,'PI,LIST('ARBINT,!!ARBINT)) >>
  285. ELSE C:=0;
  286. SOLVE1(SUBTRSQ(SIMP!* CADDR X1,QUOTSQ(ADDSQ(
  287. SIMP!* LIST('LOG,MK!*SQ GETELV(LIST('!!CF, 1))),SIMP!* C),
  288. SIMP!* LIST('LOG,CADR X1))),X,MU) >>
  289. ELSE IF FREEOF(CADDR X1,X) THEN
  290. COMMENT (...)**(m/n) = b;
  291. IF RATNUMP CADDR X1 THEN SOLVE1(SUBTRSQ(
  292. EXPTSQ(SIMP!* CADR X1,NUMR SIMP!* CADDR X1),
  293. SIMP!* LIST('EXPT,MK!*SQ GETELV(LIST('!!CF, 1)),MK!*SQ(DENR
  294. SIMP!* CADDR X1./1))),X,MU)
  295. COMMENT (...)**c = b;
  296. ELSE <<
  297. IF !*ALLBRANCH THEN <<!!ARBINT:=!!ARBINT+1;
  298. C:=MKEXP LIST('TIMES,LIST
  299. ('ARBREAL,!!ARBINT)) >>
  300. ELSE C:=1;
  301. SOLVE1(SUBTRSQ(SIMP!* CADR X1,MULTSQ(SIMP!*
  302. LIST('EXPT,MK!*SQ GETELV(LIST('!!CF, 1)), MK!*SQ INVSQ
  303. SIMP!* CADDR X1),SIMP!* C)), X, MU) >>
  304. COMMENT (...)**(...) = b : transcendental;
  305. ELSE CONSSMMP(SUBTRSQ(SIMP!* X1,GETELV(LIST('!!CF, 1))), -MU)
  306. COMMENT SIN(...) = b;
  307. ELSE IF CAR X1='SIN THEN<<
  308. IF !*ALLBRANCH THEN <<
  309. !!ARBINT:=!!ARBINT+1;
  310. F:=LIST('TIMES,2,'PI,LIST('ARBINT,!!ARBINT)) >>
  311. ELSE
  312. F:=0;
  313. C:=SIMP!* CADR X1;
  314. D:=LIST('ASIN,MK!*SQ GETELV(LIST('!!CF, 1)));
  315. SOLVE1(SUBTRSQ(C,SIMP!* LIST('PLUS,D,F)),X,MU);
  316. IF !*ALLBRANCH THEN SOLVE1(SUBTRSQ(C,SIMP!* LIST
  317. ('PLUS,'PI,MK!*SQ
  318. SUBTRSQ(SIMP!* F,SIMP!* D))), X, MU) >>
  319. COMMENT COS(...) = b;
  320. ELSE IF CAR X1='COS THEN<<
  321. IF !*ALLBRANCH THEN<<!!ARBINT:=!!ARBINT+1;
  322. C:=LIST('TIMES,2,'PI,LIST('ARBINT,!!ARBINT))>>
  323. ELSE C:=0;
  324. C:=SUBTRSQ(SIMP!* CADR X1,SIMP!* C);
  325. D:=SIMP!* LIST('ACOS,MK!*SQ GETELV(LIST('!!CF,1)));
  326. SOLVE1(SUBTRSQ(C,D), X, MU);
  327. IF !*ALLBRANCH THEN SOLVE1(ADDSQ(C,D), X, MU) >>
  328. COMMENT Unknown inverse;
  329. ELSE IF NULL(F:=GET(CAR X1,'INVERSE))THEN
  330. CONSSMMP(SUBTRSQ(SIMP!* X1,GETELV(LIST('!!CF,1))), -MU)
  331. COMMENT Other, known inverse;
  332. ELSE SOLVE1(SUBTRSQ(SIMP!* CADR X1,SIMP!*
  333. LIST(F,MK!*SQ GETELV(LIST('!!CF,1)))), X, MU)>> >>
  334. COMMENT Test for 2 powers of X1;
  335. ELSE IF F>=0 THEN <<
  336. D:= SIMP!* GETELV(LIST('!!CF,2));
  337. C := QUOTSQ(SIMP!* GETELV(LIST('!!CF,0)),D);
  338. D := QUOTSQ(SIMP!* GETELV(LIST('!!CF,1)),MULTSQ((2 ./1),D));
  339. C:=SIMP!* LIST('EXPT, MK!*SQ SUBTRSQ(EXPTSQ(D,2),C),
  340. MK!*SQ(1 ./2));
  341. D := ADDSQ(D, EXPTSQ(SIMP!* X1, N));
  342. SOLVE1(SUBTRSQ(D,C), X, MU);
  343. SOLVE1(ADDSQ(D,C), X, MU) >>
  344. ELSE SOLVE22(E1,X1,X,MU)
  345. END;
  346. SYMBOLIC PROCEDURE SOLVE22(E1,X1,X,MU);
  347. BEGIN SCALAR B,C,D,F; INTEGER N;
  348. COMMENT Test for reciprocal equation, cubic, or quartic;
  349. F:=(!!HIPOW+1)/2; D:=EXPTSQ(SIMP!* X1,N);
  350. IF (FOR J:=0:F DO IF NOT(GETELV(LIST('!!CF,J))
  351. =GETELV(LIST('!!CF,!!HIPOW-J)) )
  352. THEN RETURN T)
  353. THEN IF (FOR J:=0:F DO IF NUMR ADDSQ(SIMP!*
  354. GETELV(LIST('!!CF,J)), SIMP!* GETELV(LIST('!!CF,!!HIPOW-J)))
  355. THEN RETURN T)
  356. THEN IF !!HIPOW=3 THEN SOLVECUBIC(D,X,MU,T)
  357. ELSE IF !!HIPOW=4 THEN SOLVEQUARTIC(D,X,MU)
  358. ELSE IF !*SOLVEINTERVAL AND UNIVARIATEP E1 THEN
  359. SOLVEINTERVAL(E1,MU)
  360. ELSE CONSSMMP(E1./1, -MU)
  361. COMMENT Antisymmetric reciprocal equation;
  362. ELSE << C:=ADDSQ(D,(-1 ./1));
  363. SOLVE1(C, X, MU);
  364. E1:= QUOTSQ(E1./1, C);
  365. IF F+F = !!HIPOW THEN <<C:=ADDSQ(D,(1 ./1));
  366. SOLVE1(C, X, MU);
  367. E1:= QUOTSQ(E1, C) >>;
  368. SOLVE1(E1, X, MU) >>
  369. COMMENT Symmetric reciprocal equation;
  370. ELSE IF F+F=!!HIPOW+1 THEN <<
  371. C:=ADDSQ(D, 1 ./1);
  372. SOLVE1(C,X,MU);
  373. SOLVE1(QUOTSQ(E1./1, C), X, MU) >>
  374. ELSE <<
  375. B:=SM!*;
  376. SETELV(LIST('!!CF, 0), SIMP!* 2);
  377. SETELV(LIST('!!CF, 1), SIMP!* '!!X);
  378. C:=ADDSQ(MULTSQ(SIMP!* GETELV(LIST('!!CF,F+1)),
  379. GETELV(LIST('!!CF,1))),
  380. SIMP!* GETELV(LIST('!!CF,F)));
  381. FOR J:=2:F DO <<
  382. SETELV(LIST('!!CF, J),
  383. SUBTRSQ(MULTSQ(GETELV(LIST('!!CF,1)),
  384. GETELV(LIST('!!CF,J-1))),
  385. GETELV(LIST('!!CF,J-2))));
  386. C:=ADDSQ(C,MULTSQ(GETELV(LIST('!!CF,J)),
  387. SIMP!* GETELV(LIST('!!CF,F+J)) )) >>;
  388. SOLVE1(C,'!!X,MU); C:=F:=NIL;
  389. WHILE NOT(SM!*=B) DO <<
  390. C:=CAR SM!* . C;
  391. F:=CAR MP!* . F;
  392. SM!*:=CDR SM!*;
  393. MP!*:=CDR MP!* >>;
  394. WHILE C DO <<
  395. SOLVE1(ADDSQ(1 ./1,MULTSQ(D,SUBTRSQ(D,CAAR C))),
  396. X, !*A2F CAAR F*MU);
  397. C:=CDR C >> >>
  398. END;
  399. SYMBOLIC PROCEDURE MKEXP U;
  400. (LAMBDA X;
  401. LIST('PLUS,LIST('COS,X),LIST('TIMES,'I,LIST('SIN,X))))
  402. REVAL U;
  403. SYMBOLIC PROCEDURE SOLVECOEFF(EX, VAR);
  404. % EX is a standard form.
  405. % VAR is a kernel.
  406. % Puts the coefficients (as prefix standard quotients) of
  407. % VAR in EX into the elements of !!CF, with index equal
  408. % to the exponent divided by the GCD of all the
  409. % exponents. This GCD is put into !!GCD, and the
  410. % highest power divided by the GCD is put into
  411. % !!HIPOW.
  412. % Returns the lowest power if the highest is equal to 2;
  413. % -1 if the highest power is less than 2, or -1 if
  414. % the highest power is greater than 2.
  415. % This bizarre behaviour stems from the rewriting of the
  416. % Reduce COEFF function originally used by SOLVE.
  417. % Hopefully this will be rewritten someday without
  418. % the kludginess.
  419. % Note that !!CF (an array), !!GCD, and !!HIPOW are globals.;
  420. BEGIN
  421. SCALAR CLIST, X, OLDKORD;
  422. OLDKORD := SETKORDER(LIST(VAR));
  423. CLIST := REORDER (EX);
  424. SETKORDER(OLDKORD);
  425. !!HIPOW := LDEG(CLIST);
  426. CLIST := COEFLIS(CLIST);
  427. !!GCD := 0;
  428. X := CLIST;
  429. WHILE X DO <<
  430. !!GCD := GCDN(CAAR(X), !!GCD);
  431. X := CDR(X) >>;
  432. X := CLIST;
  433. FOR I := 0:(CAR(DIMENSION('!!CF))-1) DO
  434. SETELV(LIST('!!CF, I), NIL);
  435. WHILE X DO <<
  436. SETELV(LIST('!!CF, CAAR(X)/!!GCD), MK!*SQ(CDAR(X) ./ 1));
  437. X := CDR(X) >>;
  438. !!HIPOW := !!HIPOW/!!GCD;
  439. IF !!HIPOW=2 THEN
  440. RETURN CAAR(CLIST)/!!GCD
  441. ELSE IF !!HIPOW<2 THEN
  442. RETURN -1
  443. ELSE
  444. RETURN -2
  445. END;
  446. SYMBOLIC PROCEDURE SOLVEINTERVAL(EX, MUL);
  447. % EX is a standard form, MUL is an integer. Isolates
  448. % insoluble, real roots of EX in rational intervals,
  449. % stuffing result in the form INTERVL(Lowlim,Highlim)
  450. % into SM!* with multiplicity MUL put into MP!*.;
  451. BEGIN INTEGER I;
  452. REALROOT(PREPF EX,PREPSQ !*K2Q MVAR EX,!!INTERVALARRAY,'!!EXACT);
  453. FOR I := 1:GETELV LIST('!!EXACT,0) DO
  454. CONSSMMP(SIMP!* GETELV LIST('!!EXACT,I), MUL);
  455. FOR I := 1:GETELV LIST(!!INTERVALARRAY,0,0) DO
  456. CONSSMMP(SIMP!* LIST('INTERVL,
  457. GETELV LIST(!!INTERVALARRAY,I,1),
  458. GETELV LIST(!!INTERVALARRAY,I,2) ),
  459. MUL)
  460. END;
  461. SYMBOLIC PROCEDURE REALROOT(U,V,W,X);
  462. REDERR("Real root finding not yet implemented");
  463. %***************** Procedures for solving Cubic and Quartic eqns ***;
  464. SYMBOLIC PROCEDURE SOLVECUBIC(X1, X, MU, CUBE3) ;
  465. BEGIN COMMENT Solves !!CF(3)*X1**3 + !!CF(2)*X1**2 ...
  466. X1 and X are
  467. kernels, M and MU are integers, CUBE3 is T or NIL.
  468. Returns NIL;
  469. SCALAR A,B,C,D;
  470. D:=SIMP!* GETELV(LIST('!!CF,3));
  471. C:=QUOTSQ(SIMP!* GETELV(LIST('!!CF,2)),D);
  472. B:=QUOTSQ(SIMP!* GETELV(LIST('!!CF,1)),D);
  473. A:=QUOTSQ(SIMP!* GETELV(LIST('!!CF,0)),D);
  474. A:=MULTSQ(ADDSQ(MULTSQ((9 ./1),MULTSQ(C,B)), ADDSQ(MULTSQ
  475. ((-27 ./1),A),MULTSQ((-2 ./1),EXPTSQ(C,3)))),(1 ./54));
  476. B := MULTSQ((-1 ./9),ADDSQ(EXPTSQ(C,2),MULTSQ((-3 ./1),B)));
  477. D := SIMP!* LIST('EXPT, MK!*SQ ADDSQ(EXPTSQ(B,3),
  478. EXPTSQ(A,2)), MK!*SQ(1 ./2));
  479. D := SIMP!* LIST('EXPT, MK!*SQ ADDSQ(A,D),MK!*SQ(1 ./3));
  480. A := NEGSQ QUOTSQ(B,D);
  481. B := ADDSQ(D, A);
  482. C := ADDSQ(X1, MULTSQ(C,(1 ./3)));
  483. SOLVE1(SUBTRSQ(C,B), X, MU);
  484. IF CUBE3 THEN <<C := ADDSQ(MULTSQ(B,(1 ./2)), C);
  485. D := MULTSQ(SIMP!* LIST('EXPT,MK!*SQ(-3 ./4),MK!*SQ
  486. (1 ./2)), SUBTRSQ(D,A));
  487. SOLVE1(ADDSQ(C,D), X, MU);
  488. SOLVE1(SUBTRSQ(C,D), X, MU)>>
  489. END;
  490. SYMBOLIC PROCEDURE SOLVEQUARTIC(X1,X,MU) ;
  491. BEGIN COMMENT Solves !!CF(4)*X1**4 + !!CF(3)*X1**3 + ....
  492. X1 is a standard quotient, X is a kernel, MU is an integer,
  493. CUBE3 is T or NIL. Returns NIL;
  494. SCALAR A,B,C,D,F;
  495. F:=SIMP!* GETELV(LIST('!!CF,4));
  496. A:=QUOTSQ(SIMP!* GETELV(LIST('!!CF,0)),F);
  497. B:=QUOTSQ(SIMP!* GETELV(LIST('!!CF,1)),F);
  498. C:=QUOTSQ(SIMP!* GETELV(LIST('!!CF,2)),F);
  499. D:=QUOTSQ(SIMP!* GETELV(LIST('!!CF,3)),F);
  500. F := ADDSQ(EXPTSQ(D,2), MULTSQ((-4 ./1),C));
  501. SETELV(LIST('!!CF, 0), MK!*SQ NEGSQ ADDSQ(EXPTSQ(B,2),MULTSQ(A,F)));
  502. SETELV(LIST('!!CF, 1), MK!*SQ ADDSQ(MULTSQ(B,D),MULTSQ((-4 ./1),A)));
  503. SETELV(LIST('!!CF, 2), MK!*SQ NEGSQ C);
  504. SETELV(LIST('!!CF, 3), 1);
  505. SOLVECUBIC(SIMP!* X, X, MU, NIL);
  506. B := CAAR SM!*;
  507. SM!* := CDR SM!*;
  508. MP!*:= CDR MP!*;
  509. A := SIMP!* LIST('EXPT, MK!*SQ ADDSQ(EXPTSQ(B,2),MULTSQ(A,
  510. (-4 ./1))), MK!*SQ(1 ./2));
  511. F := SIMP!* LIST('EXPT, MK!*SQ ADDSQ(F,MULTSQ(B,(4 ./1))),
  512. MK!*SQ(1 ./2));
  513. SOLVE1(ADDSQ(EXPTSQ(X1,2),MULTSQ((1 ./2),ADDSQ(MULTSQ(X1,ADDSQ
  514. (D,F)), ADDSQ(B,A)))), X, MU);
  515. SOLVE1(ADDSQ(EXPTSQ(X1,2),MULTSQ((1 ./2),ADDSQ(MULTSQ(X1,
  516. SUBTRSQ(D,F)), SUBTRSQ(B,A)))), X, MU);
  517. END;
  518. %******************* Procedures for solving a system of eqns *******;
  519. SYMBOLIC PROCEDURE SOLVESYS(EXLIST,VARLIST);
  520. % EXLIST is a list of standard forms.
  521. % VARLIST is a list of kernels.
  522. % If EXLIST and VARLIST are of the same length and the
  523. % elements of VARLIST are linear in the elements of
  524. % exlist, and further the system of linear eqns so
  525. % defined is non-singular, then SOLVESYS returns a
  526. % list of standard quotients which are solutions of
  527. % the system, ordered as in VARLIST.
  528. % Otherwise an error results.;
  529. BEGIN
  530. SCALAR MTRX, RHS; % Coeffs and right side of system;
  531. SCALAR ROW, OLDKORD;
  532. IF LENGTH(EXLIST) NEQ LENGTH(VARLIST) THEN
  533. REDERR "SOLVESYS given unequal number of eqns & unknowns";
  534. OLDKORD := SETKORDER(VARLIST);
  535. EXLIST := MAPCAR(EXLIST, 'REORDER);
  536. FOR EACH EX IN EXLIST DO <<
  537. ROW := NIL;
  538. FOR EACH VAR IN VARLIST DO<<
  539. IF NOT DOMAINP(EX) AND
  540. (MVAR(EX)=VAR AND LDEG(EX)>1
  541. OR (NOT FREEOFKERN(VAR, LC(EX)))
  542. OR (NOT FREEOFKERN(VAR, RED(EX))) ) THEN
  543. REDERR
  544. "SOLVE given system of non linear-fractional equations";
  545. IF NOT DOMAINP(EX) AND MVAR(EX)=VAR THEN <<
  546. ROW := !*F2Q(LC(EX)) . ROW;
  547. EX := RED(EX) >>
  548. ELSE
  549. ROW := !*F2Q(NIL) . ROW >>;
  550. RHS := LIST(!*F2Q(NEGF(EX))) . RHS;
  551. MTRX := ROW . MTRX >>;
  552. SETKORDER(OLDKORD);
  553. RETURN SOLVELNRSOLVE(MTRX, RHS)
  554. END;
  555. SYMBOLIC PROCEDURE SOLVELNRSOLVE(U,V);
  556. % U is a matrix canonical form, V a compatible matrix form.
  557. % Result is the solution,y, to the matrix equation U*y=V.
  558. % If !*SOLVESINGULAR is non-nil, introduces arbitrary constants
  559. % if necessary. Returns an error if the system represented is
  560. % inconsistent or if !*SOLVESINGULAR is nil and U is singular.;
  561. BEGIN INTEGER N, K; SCALAR X,!*S!*, PERM;
  562. X := !*EXP; !*EXP := T; N := LENGTH U; PERM := INDEXLIS(1, N);
  563. U := CAR NORMMAT AUGMENT(U,V);
  564. IF NOT !*SOLVESINGULAR THEN
  565. U := BAREISS U
  566. ELSE <<
  567. U := SOLVEBAREISS(U, PERM);
  568. IF U THEN
  569. U := INSERTARBCONSTS(CDR(U),
  570. CAR(U)+1,
  571. FUNCTION MAKEARBCOMPLEX) >>;
  572. !*S!* := BACKSUB(U,N);
  573. U := MAPC2(RHSIDE(CAR !*S!*,N),
  574. FUNCTION (LAMBDA J; CANCEL(J . CDR !*S!*)));
  575. !*EXP := X;
  576. RETURN PERMUTE(U, PERM);
  577. END;
  578. SYMBOLIC PROCEDURE SOLVEBAREISS(U, PERM);
  579. %The 2-step integer preserving elimination method of Bareiss
  580. %based on the implementation of Lipson;
  581. %This is based on the Bareiss function in the Reduce matrix package,
  582. %modified to reduce singular matrices. If PERM is nil, behaves
  583. %as BAREISS, except a pair is returned for non-singular U, whose
  584. %cdr is the triangularized U. The car is the rank of U, which in
  585. %this case is always LENGTH(U).
  586. %Otherwise PERM is a list of the integers 1,2...length(U).
  587. %As columns are interchanged, then so are the elements of PERM.
  588. %In this case a pair is returned whose car is the rank of U and
  589. %whose cdr is the triangularized U. Note that, just as in BAREISS, the
  590. %lower triangular portion of the returned matrix standard form is only
  591. %implicitly all nils--the requisite RPLACAs are not performed. Also,
  592. %if PERM is non-nil and the rank,r, of U is less than the order of U,
  593. %only the first r rows of the upper triangular portion are explicitly
  594. %set. The all nil rows are only implicitly all nils.
  595. %U is a list of lists of standard forms (a matrix standard form)
  596. %corresponding to the appropriate augmented matrix.
  597. %If the value of procedure is NIL then U is singular, otherwise the
  598. %value is the triangularized form of U (in the same form);
  599. BEGIN SCALAR AA,C0,CI1,CI2,IK1,IJ,KK1,KJ,K1J,K1K1,
  600. UI,U1,X,K1COL,KIJ,FLG;
  601. INTEGER K,K1,COL,MAXCOL;
  602. %U1 points to K-1th row of U
  603. %UI points to Ith row of U
  604. %IJ points to U(I,J)
  605. %K1J points to U(K-1,J)
  606. %KJ points to U(K,J)
  607. %IK1 points to U(I,K-1)
  608. %KK1 points to U(K,K-1)
  609. %K1K1 points to U(K-1,K-1)
  610. %M in comments is number of rows in U
  611. %N in comments is number of columns in U;
  612. MAXCOL := LENGTH(U);
  613. AA:= 1;
  614. K:= 2;
  615. K1:=1;
  616. U1:=U;
  617. GO TO PIVOT;
  618. AGN: U1 := CDR U1;
  619. IF NULL CDR U1 OR NULL CDDR U1 THEN
  620. IF PERM AND CDR(U1) AND
  621. NULL(CAR(IJ := PNTH(NTH(U, MAXCOL), MAXCOL))) THEN <<
  622. MAPC(CDR(IJ), FUNCTION LAMBDA(X);
  623. IF X THEN RETURN NIL);
  624. RETURN (MAXCOL-1).U >>
  625. ELSE
  626. RETURN MAXCOL.U;
  627. AA:=NTH(CAR U1,K); %AA := U(K,K);
  628. K:=K+2;
  629. K1:=K-1;
  630. U1:=CDR U1;
  631. PIVOT: %pivot algorithm;
  632. COL := K1;
  633. K1J:= K1K1 := PNTH(CAR U1,K1);
  634. PIV1: K1COL := PNTH(CAR(U1), COL);
  635. IF CAR K1COL THEN GO TO L2;
  636. UI:= CDR U1; %I := K;
  637. L: IF NULL UI THEN
  638. IF PERM THEN
  639. IF COL>=MAXCOL THEN
  640. RETURN (K1-1).U
  641. ELSE <<
  642. COL := COL+1;
  643. GO TO PIV1 >>
  644. ELSE
  645. RETURN NIL
  646. ELSE IF NULL CAR(IJ := PNTH(CAR UI,COL))
  647. THEN GO TO L1;
  648. L0: IF NULL IJ THEN GO TO L2;
  649. X := CAR IJ;
  650. RPLACA(IJ,NEGF CAR K1COL);
  651. RPLACA(K1COL,X);
  652. IJ:= CDR IJ;
  653. K1COL:= CDR K1COL;
  654. GO TO L0;
  655. L1: UI:= CDR UI;
  656. GO TO L;
  657. L2: SWAPCOLUMNS(U, K1, COL, PERM);
  658. COL := K;
  659. PIV2: UI:= CDR U1; %I:= K;
  660. L21: IF NULL UI THEN
  661. IF PERM THEN
  662. IF COL>=MAXCOL THEN <<
  663. FLG := T;
  664. WHILE FLG AND U1 DO <<
  665. IK1 := PNTH(CAR(U1), K1);
  666. IJ := PNTH(IK1, MAXCOL-K1+2);
  667. KIJ := PNTH(K1K1, MAXCOL-K1+2);
  668. WHILE FLG AND IJ DO
  669. IF ADDF(MULTF(CAR(K1K1), CAR(IJ)),
  670. MULTF(CAR(IK1), NEGF(CAR(KIJ))) )
  671. THEN FLG := NIL
  672. ELSE IJ := CDR(IJ);
  673. U1 := CDR(U1) >>;
  674. IF FLG THEN
  675. RETURN (K-1).U
  676. ELSE
  677. RETURN NIL >>
  678. ELSE <<
  679. COL := COL+1;
  680. GO TO PIV2 >>
  681. ELSE
  682. RETURN NIL;
  683. IJ:= PNTH(CAR UI,K1);
  684. C0:= ADDF(MULTF(CAR K1K1,NTH(IJ, COL-K+2)),
  685. MULTF(NTH(K1K1, COL-K+2),NEGF CAR IJ));
  686. IF C0 THEN GO TO L3;
  687. UI:= CDR UI; %I:= I+1;
  688. GO TO L21;
  689. L3: SWAPCOLUMNS(U, K, COL, PERM);
  690. C0:= QUOTF!*(C0,AA);
  691. KK1 := KJ := PNTH(CADR U1,K1); %KK1 := U(K,K-1);
  692. IF CDR U1 AND NULL CDDR U1 THEN GO TO EV0
  693. ELSE IF UI EQ CDR U1 THEN GO TO COMP;
  694. L31: IF NULL IJ THEN GO TO COMP; %IF I>N THEN GO TO COMP;
  695. X:= CAR IJ;
  696. RPLACA(IJ,NEGF CAR KJ);
  697. RPLACA(KJ,X);
  698. IJ:= CDR IJ;
  699. KJ:= CDR KJ;
  700. GO TO L31;
  701. %pivoting complete;
  702. COMP:
  703. IF NULL CDR U1 THEN GO TO EV;
  704. UI:= CDDR U1; %I:= K+1;
  705. COMP1:
  706. IF NULL UI THEN GO TO EV; %IF I>M THEN GO TO EV;
  707. IK1:= PNTH(CAR UI,K1);
  708. CI1:= QUOTF!*(ADDF(MULTF(CADR K1K1,CAR IK1),
  709. MULTF(CAR K1K1,NEGF CADR IK1)),
  710. AA);
  711. CI2:= QUOTF!*(ADDF(MULTF(CAR KK1,CADR IK1),
  712. MULTF(CADR KK1,NEGF CAR IK1)),
  713. AA);
  714. IF NULL CDDR K1K1 THEN GO TO COMP3;%IF J>N THEN GO TO COMP3;
  715. IJ:= CDDR IK1; %J:= K+1;
  716. KJ:= CDDR KK1;
  717. K1J:= CDDR K1K1;
  718. COMP2:
  719. IF NULL IJ THEN GO TO COMP3;
  720. RPLACA(IJ,QUOTF!*(ADDF(MULTF(CAR IJ,C0),
  721. ADDF(MULTF(CAR KJ,CI1),
  722. MULTF(CAR K1J,CI2))),
  723. AA));
  724. IJ:= CDR IJ;
  725. KJ:= CDR KJ;
  726. K1J:= CDR K1J;
  727. GO TO COMP2;
  728. COMP3:
  729. UI:= CDR UI;
  730. GO TO COMP1;
  731. EV0:IF NULL C0 THEN RETURN;
  732. EV: KJ := CDR KK1;
  733. X := CDDR K1K1; %X := U(K-1,K+1);
  734. RPLACA(KJ,C0);
  735. EV1:KJ:= CDR KJ;
  736. IF NULL KJ THEN GO TO AGN;
  737. RPLACA(KJ,QUOTF!*(ADDF(MULTF(CAR K1K1,CAR KJ),
  738. MULTF(CAR KK1,NEGF CAR X)),
  739. AA));
  740. X := CDR X;
  741. GO TO EV1
  742. END;
  743. SYMBOLIC PROCEDURE SWAPCOLUMNS(MATRX, COL1, COL2, PERM);
  744. IF COL1=COL2 THEN
  745. MATRX
  746. ELSE <<
  747. SWAPELEMENTS(PERM, COL1, COL2);
  748. FOR EACH U IN MATRX DO
  749. SWAPELEMENTS(U, COL1, COL2);
  750. MATRX >>;
  751. SYMBOLIC PROCEDURE SWAPELEMENTS(LST, I, J);
  752. % Swaps the Ith and Jth elements of the list LST al la
  753. % RPLACA and returns nil.;
  754. BEGIN SCALAR TEMP;
  755. IF I>J THEN <<
  756. TEMP := I;
  757. I := J;
  758. J := TEMP >>;
  759. LST := PNTH(LST, I);
  760. I := J-I+1;
  761. TEMP := NTH(LST, I);
  762. RPLACA(PNTH(LST, I), CAR(LST));
  763. RPLACA(LST, TEMP)
  764. END;
  765. SYMBOLIC PROCEDURE INDEXLIS(M, N);
  766. % M,N are integers. Returns the list (M M+1 M+2 ... N-1 N);
  767. IF M<=N THEN M . INDEXLIS(M+1,N);
  768. SYMBOLIC PROCEDURE INSERTARBCONSTS(M, ZEROROW, ARBFN);
  769. % M is a matrix standard form, representing a
  770. % matrix which has been row reduced. All elements below
  771. % the principal diagonal are implicitly nil, as are all
  772. % elements in row ZEROROW and below. It is such a form
  773. % as is returned by SOLVEBAREISS with a non-nil second
  774. % argument. It inserts approriate arbitrary constants in
  775. % the inhomogeneous portion, and 1's on the main diagonal
  776. % except for the last row, which gets the new determinant
  777. % of the square submatrix. Calls ARBFN to generate arbitrary
  778. % constants.;
  779. BEGIN SCALAR U, V, NEWDET; INTEGER N;
  780. N := LENGTH(M);
  781. IF ZEROROW<=N THEN <<
  782. NEWDET := 1;
  783. U := M;
  784. FOR I := 1:(ZEROROW-1) DO <<
  785. NEWDET := MULTF(NEWDET, NTH(CAR(U), I));
  786. U := CDR(U) >>;
  787. FOR I := ZEROROW:(N-1) DO <<
  788. V := PNTH(CAR(U), I);
  789. RPLACA(V, 1);
  790. V := CDR(V);
  791. FOR J := I+1:N DO <<
  792. RPLACA(V, NIL);
  793. V := CDR(V) >>;
  794. WHILE V DO <<
  795. RPLACA(V, !*K2F EVAL LIST ARBFN);
  796. V := CDR(V) >>;
  797. U := CDR(U) >>;
  798. V := PNTH(CAR(U), N);
  799. RPLACA(V, NEWDET);
  800. V := CDR(V);
  801. WHILE V DO <<
  802. RPLACA(V, MULTF(NEWDET, !*K2F EVAL LIST ARBFN));
  803. V := CDR(V) >> >>;
  804. RETURN M
  805. END;
  806. SYMBOLIC PROCEDURE PERMUTE(U, V);
  807. % U is a list. V is a list of the numbers 1,2,...LENGTH(U), permuted;
  808. % Returns a constructed list of the elements of U permuted by V.;
  809. IF V THEN NCONC(LIST(NTH(U,CAR(V))), PERMUTE(U, CDR(V)));
  810. SYMBOLIC PROCEDURE MAKEARBCOMPLEX();
  811. BEGIN SCALAR ANS;
  812. ANS := NUMR(SIMP!*(LIST('ARBCOMPLEX, !!ARBINT)));
  813. !!ARBINT := !!ARBINT+1;
  814. RETURN ANS
  815. END;
  816. %******** Algebraic Let Statements and related declarations ********;
  817. PUT('ASIN, 'INVERSE, 'SIN);
  818. PUT('ACOS, 'INVERSE, 'COS);
  819. ALGEBRAIC <<
  820. OPERATOR SOL, INTERVL, ARBCOMPLEX, ARBREAL, ARBINT, LST;
  821. COMMENT Supply missing argument and simplify 1/4 roots of unity;
  822. LET E**(I*PI/2) = I,
  823. E**(I*PI) = -1,
  824. E**(3*I*PI/2)=-I;
  825. FOR ALL N SUCH THAT FIXP N
  826. LET COS((N*PI)/2)= 0;
  827. LET COS(PI/2)=0;
  828. FOR ALL N SUCH THAT FIXP N
  829. LET SIN((N*PI)/2)=
  830. IF REMAINDER(ABS N,4)<2 THEN 1 ELSE -1;
  831. LET SIN(PI/2)=1;
  832. FOR ALL N SUCH THAT FIXP N
  833. LET COS((N*PI)/3)=
  834. (IF N=4 OR REMAINDER(ABS N+2,6)>3 THEN -1 ELSE 1)/2;
  835. LET COS(PI/3)=1/2;
  836. FOR ALL N SUCH THAT FIXP N
  837. LET SIN((N*PI)/3)=
  838. (IF REMAINDER(ABS N,6)<3 THEN 1 ELSE -1)*SQRT(3)/2;
  839. LET SIN(PI/3)=SQRT(3)/2;
  840. FOR ALL N SUCH THAT FIXP N
  841. LET COS((N*PI)/4)=
  842. (IF REMAINDER(ABS N+2,8)<4 THEN 1 ELSE -1)*SQRT(2)/2;
  843. LET COS(PI/4)=SQRT 2/2;
  844. FOR ALL N SUCH THAT FIXP N
  845. LET SIN((N*PI)/4)=
  846. (IF REMAINDER(ABS N,8)<4 THEN 1 ELSE -1)*SQRT(2)/2;
  847. LET SIN(PI/4)=SQRT(2)/2;
  848. FOR ALL N SUCH THAT FIXP N
  849. LET COS((N*PI)/6)=
  850. (IF REMAINDER(ABS N+2,12)<6 THEN 1 ELSE -1)*SQRT(3)/2;
  851. LET COS(PI/6)=SQRT 3/2;
  852. FOR ALL N SUCH THAT FIXP N
  853. LET SIN((N*PI)/6)=
  854. (IF REMAINDER(ABS N,12)<6 THEN 1 ELSE -1)/2;
  855. LET SIN(PI/6)=1/2;
  856. COMMENT Rules for reducing the number of distinct kernels in an
  857. equation;
  858. FOR ALL A,B,X SUCH THAT RATNUMP C AND RATNUMP D LET
  859. SOL(A**C-B**D, X) = A**(C*LCMD(C,D)) - B**(D*LCMD(C,D));
  860. FOR ALL A,B,C,D,X SUCH THAT FREEOFKERN(X,A) AND FREEOFKERN(X,C) LET
  861. SOL(A**B-C**D, X) = E**(B*LOG A - D*LOG C);
  862. FOR ALL A,B,C,D,X SUCH THAT FREEOFKERN(X,A) AND FREEOFKERN(X,C) LET
  863. SOL(A*LOG B + C*LOG D, X) = B**A*D**C - 1,
  864. SOL(A*LOG B - C*LOG D, X) = B**A - D**C;
  865. FOR ALL A,B,C,D,F,X SUCH THAT FREEOFKERN(X,A) AND FREEOFKERN(X,C) LET
  866. SOL(A*LOG B + C*LOG D + F, X) = SOL(LOG(B**A*D**C) + F, X),
  867. SOL(A*LOG B + C*LOG D - F, X) = SOL(LOG(B**A*D**C) - F, X),
  868. SOL(A*LOG B - C*LOG D + F, X) = SOL(LOG(B**A/D**C) + F, X),
  869. SOL(A*LOG B - C*LOG D - F, X) = SOL(LOG(B**A/D**C) - F, X);
  870. FOR ALL A,B,D,F,X SUCH THAT FREEOFKERN(X,A) LET
  871. SOL(A*LOG B + LOG D + F, X) = SOL(LOG(B**A*D) + F, X),
  872. SOL(A*LOG B + LOG D - F, X) = SOL(LOG(B**A*D) - F, X),
  873. SOL(A*LOG B - LOG D + F, X) = SOL(LOG(B**A/D) + F, X),
  874. SOL(A*LOG B - LOG D - F, X) = SOL(LOG(B**A/D) - F, X),
  875. SOL(LOG D - A*LOG B + F, X) = SOL(LOG(D/B**A) + F, X),
  876. SOL(LOG D - A*LOG B - F, X) = SOL(LOG(D/B**A) - F, X);
  877. FOR ALL A,B,D,X SUCH THAT FREEOFKERN(X,A) LET
  878. SOL(A*LOG B + LOG D, X) = B**A*D - 1,
  879. SOL(A*LOG B - LOG D, X) = B**A - D,
  880. SOL(LOG D - A*LOG B, X) = D - B**A;
  881. FOR ALL A,B,C,X LET
  882. SOL(LOG A + LOG B + C, X) = SOL(LOG(A*B) + C, X),
  883. SOL(LOG A - LOG B + C, X) = SOL(LOG(A/B) + C, X),
  884. SOL(LOG A + LOG B - C, X) = SOL(LOG(A*B) - C, X),
  885. SOL(LOG A - LOG B - C, X) = SOL(LOG(A/B) - C, X);
  886. FOR ALL A,C,X SUCH THAT FREEOFKERN(X,C) LET
  887. SOL(LOG A + C, X) = A - E**C,
  888. SOL(LOG A - C, X) = A - E**(-C);
  889. FOR ALL A,B,X LET
  890. SOL(LOG A + LOG B, X) = A*B - 1,
  891. SOL(LOG A - LOG B, X) = A - B,
  892. SOL(COS A - SIN B, X) = SOL(COS A - COS(PI/2-B), X),
  893. SOL(SIN A + COS B, X) = SOL(SIN A - SIN(B-PI/2), X),
  894. SOL(SIN A - COS B, X) = SOL(SIN A - SIN(PI/2-B), X),
  895. SOL(SIN A + SIN B, X) = SOL(SIN A - SIN(-B), X),
  896. SOL(SIN A - SIN B, X) = IF !*ALLBRANCH THEN SIN((A-B)/2)*
  897. COS((A+B)/2) ELSE A-B,
  898. SOL(COS A + COS B, X) = IF !*ALLBRANCH THEN COS((A+B)/2)*
  899. COS((A-B)/2) ELSE A+B,
  900. SOL(COS A - COS B, X) = IF !*ALLBRANCH THEN SIN((A+B)/2)*
  901. SIN((A-B)/2) ELSE A-B,
  902. SOL(ASIN A - ASIN B, X) = A-B,
  903. SOL(ASIN A + ASIN B, X) = A+B,
  904. SOL(ACOS A - ACOS B, X) = A-B,
  905. SOL(ACOS A + ACOS B, X) = A+B;
  906. LET COS(PI/2)=0>>;
  907. END;