sfto.red 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. % ----------------------------------------------------------------------
  2. % $Id: sfto.red,v 1.8 1999/03/22 15:26:43 dolzmann Exp $
  3. % ----------------------------------------------------------------------
  4. % Copyright (c) 1995-1999 Andreas Dolzmann and Thomas Sturm
  5. % ----------------------------------------------------------------------
  6. % $Log: sfto.red,v $
  7. % Revision 1.8 1999/03/22 15:26:43 dolzmann
  8. % Changed copyright information.
  9. % Added and reformatted comments.
  10. %
  11. % Revision 1.7 1999/01/17 15:33:13 dolzmann
  12. % Added procedure sfto_sqfpartz for computing the square-free part of an
  13. % integer.
  14. %
  15. % Revision 1.6 1999/01/10 12:09:16 dolzmann
  16. % Added procedures sfto_zdeqn, sfto_zdgtn, sfto_zdgen for the decomposition of
  17. % integers.
  18. %
  19. % Revision 1.5 1996/10/08 13:54:59 dolzmann
  20. % Renamed "degree parity decomposition" to "parity decomposition".
  21. % Adapted names of procedures and switches accordingly.
  22. %
  23. % Revision 1.4 1996/09/05 11:17:48 dolzmann
  24. % Added procedure sfto_monfp.
  25. %
  26. % Revision 1.3 1996/07/07 12:56:12 dolzmann
  27. % Fixed a bug in sfto_preducef and sfto_greducef.
  28. %
  29. % Revision 1.2 1996/05/13 13:54:26 dolzmann
  30. % Added procedure sfto_sqrtf.
  31. %
  32. % Revision 1.1 1996/04/30 12:06:46 sturm
  33. % Merged ioto, lto, and sfto into rltools.
  34. %
  35. % Revision 1.2 1996/04/30 09:13:33 sturm
  36. % Added procedure sfto_gcdf implementing the Davenport test.
  37. %
  38. % Revision 1.1 1996/03/22 12:19:17 sturm
  39. % Moved.
  40. %
  41. % Revision 1.5 1996/03/04 17:15:46 sturm
  42. % Added procedure sfto_decdegf.
  43. % Moved sfto_reorder from module ofsf to this module.
  44. %
  45. % Revision 1.4 1996/03/04 13:09:54 dolzmann
  46. % Moved procedures sfto_groebnerf, sfto_preducef, sfto_greducef and
  47. % loading of groebner packages from module ofsfgs to this module.
  48. %
  49. % Revision 1.3 1995/08/30 08:26:45 sturm
  50. % Fixed a bug in procedure sfto_dprpartf.
  51. %
  52. % Revision 1.2 1995/08/30 07:35:19 sturm
  53. % Added procedures sfto_dprpartf and sfto_dprpartf1.
  54. %
  55. % Revision 1.1 1995/05/29 14:47:23 sturm
  56. % Initial check-in.
  57. %
  58. % ----------------------------------------------------------------------
  59. lisp <<
  60. fluid '(sfto_rcsid!* sfto_copyright!*);
  61. sfto_rcsid!* := "$Id: sfto.red,v 1.8 1999/03/22 15:26:43 dolzmann Exp $";
  62. sfto_copyright!* := "Copyright (c) 1995-1999 by A. Dolzmann and T. Sturm"
  63. >>;
  64. module sfto;
  65. % Standard form tools.
  66. load!-package 'groebner;
  67. load!-package 'groebnr2;
  68. fluid '(!*ezgcd !*gcd !*rldavgcd);
  69. switch sfto_yun,sfto_tobey,sfto_musser;
  70. !*sfto_yun := T;
  71. put('sqfpart,'polyfn,'sfto_sqfpartf);
  72. put('tsqsum,'psopfn,'sfto_tsqsum!$);
  73. put('sqfdec,'psopfn,'sfto_sqfdec!$);
  74. put('pdec,'psopfn,'sfto_pdec!$);
  75. put('sfto_yun,'simpfg,
  76. '((T (setq !*sfto_tobey nil) (setq !*sfto_musser nil))));
  77. put('sfto_tobey,'simpfg,
  78. '((T (setq !*sfto_yun nil) (setq !*sfto_musser nil))));
  79. put('sfto_musser,'simpfg,
  80. '((T (setq !*sfto_tobey nil) (setq !*sfto_yun nil))));
  81. procedure sfto_dcontentf(u);
  82. % Standard form tools domain content standard form. [u] is an SF.
  83. % Returns a domain element, which is the content of [u] as a
  84. % multivariate polynomial over the current domain.
  85. sfto_dcontentf1(u,nil);
  86. procedure sfto_dcontentf1(u,g);
  87. % Standard form tools domain content standard form subroutine. [u]
  88. % is a term; [g] is a domain element. Returns the gcd of the
  89. % content of [u] and [g], which is a domain element.
  90. if g = 1 then
  91. g
  92. else if domainp u then
  93. sfto_gcdf(absf u,g)
  94. else
  95. sfto_dcontentf1(red u,sfto_dcontentf1(lc u,g));
  96. procedure sfto_dprpartf(u);
  97. % Standard form tools domain primitive part standard form. [u] is
  98. % an SF. Returns an SF which is the primitive part of [u] as a
  99. % multivariate polynomial over the current domain.
  100. sfto_dprpartf1(u,sfto_dcontentf u);
  101. procedure sfto_dprpartf1(u,c);
  102. % Standard form tools domain primitive part standard form
  103. % subroutine. [u] and [c] are SF's. Returns an SF which is the
  104. % primitive part of [u] as a multivariate polynomial over the
  105. % current domain.
  106. (if minusf w then negf w else w) where w = quotf(u,c);
  107. procedure sfto_sqfpartf(u);
  108. % Standard form tools square-free part. [u] is a non-zero SF.
  109. % Returns an SF which is the square-free part of [u] as a
  110. % multivariate polynomial. The (domain) content is dropped.
  111. begin scalar c,pp;
  112. if domainp u then return 1;
  113. c := sfto_ucontentf u;
  114. pp := quotf(u,c);
  115. return multf(sfto_sqfpartf(c),quotf(pp,sfto_gcdf!*(pp,diff(pp,mvar u))))
  116. end;
  117. procedure sfto_ucontentf(u);
  118. % Standard form tools univariate content standard form. [u] is an
  119. % SF. Returns the content of [u] as a univariate polynomial in its
  120. % [mvar] over the polynomial ring in all other contained variables.
  121. if domainp u then u else sfto_ucontentf1(u,mvar u);
  122. procedure sfto_ucontentf1(u,v);
  123. % Standard form tools univariate content standard form subroutine.
  124. % [v] is a kernel; [u] is an SF with main variable [v]. Returns an
  125. % SF which is the content of [u] as an univariate polynomial in [v]
  126. % over the polynomial ring in all other contained variables.
  127. if domainp u or mvar u neq v then u else
  128. sfto_gcdf!*(lc u,sfto_ucontentf1(red u,v));
  129. procedure sfto_uprpartf(u);
  130. % Standard form tools univariate primitive part. [u] is an SF.
  131. % Returns the primitive part of [u] as a univariate polynomial in
  132. % its [mvar] over the polynomial ring in all other contained
  133. % variables.
  134. quotf(u,sfto_ucontentf u);
  135. procedure sfto_tsqsumf(u);
  136. % Standard form tools trivial square sum standard form. [u] is an
  137. % SF. Returns one of [nil], ['stsq], or ['tsq]. ['stsq] means that
  138. % in the sparse distributive representation of [u] all exponents
  139. % are even and all coefficients are positive. ['tsq] means that all
  140. % exponents are even and all coefficients are positive except for
  141. % that there is no absolute summand.
  142. if domainp u then
  143. (if null u then 'tsq else if not minusf u then 'stsq)
  144. else
  145. evenp ldeg u and sfto_tsqsumf lc u and sfto_tsqsumf red u;
  146. procedure sfto_tsqsum!$(argl);
  147. sfto_tsqsumf(numr simp car argl);
  148. procedure sfto_sqfdecf(u);
  149. % Standard form tools multivariate square-free decomposition
  150. % standard form. [u] is an SF. Returns a (dense) list $((q_1 .
  151. % 1),(q_2 . 2),...,(q_n . n))$ such that $\prod q_i^i = u$ with the
  152. % $q_i$ square-free and pairwise relatively prime. The (integer)
  153. % content of u is dropped. Decomposition is performed by merging
  154. % univariate decompositions. The univariate decomposition method is
  155. % selected by turning on one of the switches [sfto_yun] (default),
  156. % [sfto_tobey], or [sfto_musser].
  157. begin scalar c,pp;
  158. if domainp u then return {1 . 1};
  159. c := sfto_ucontentf u;
  160. pp := quotf(u,c);
  161. return sfto_sqdmerge(sfto_sqfdecf(c),sfto_usqfdecf(pp))
  162. end;
  163. procedure sfto_sqfdec!$(argl);
  164. % Standard form tools square free decomposition. [argl] is an
  165. % argument list. Returns an AM list of AM lists of the form
  166. % $(p_i,m_i)$, where the $p_i$ are polynomials represented as a
  167. % Lisp-prefix-form and the $m_i$ are integers.
  168. begin scalar w;
  169. return 'list . for each x in sfto_sqfdecf numr simp car argl join
  170. if (w := prepf car x) neq 1 then {{'list,w,cdr x}}
  171. end;
  172. procedure sfto_usqfdecf(u);
  173. if !*sfto_yun then
  174. sfto_yun!-usqfdecf u
  175. else if !*sfto_musser then
  176. sfto_musser!-usqfdecf u
  177. else if !*sfto_tobey then
  178. sfto_tobey!-usqfdecf u
  179. else
  180. rederr {"sfto_usqfdecf: select a decomposition method"};
  181. procedure sfto_yun!-usqfdecf(p);
  182. % Standard form tools univariate square-free decomposition after
  183. % Yun. [p] is a an SF that is viewed a univariate Polynomial in its
  184. % [mvar] over the polynomial ring in all other variables; in this
  185. % sense, [p] must be primitive. Returns the square-free
  186. % decomposition of [p] as a (dense) list $((q_1 . 1),(q_2 .
  187. % 2),...,(q_n . n))$ such that $\prod q_i^i = u$ with the $q_i$
  188. % square-free and pairwise relatively prime.
  189. begin scalar !*gcd,x,g,c,d,w,l; integer n;
  190. !*gcd := T;
  191. x := mvar p;
  192. g := sfto_gcdf(p,w := diff(p,x));
  193. c := quotf(p,g);
  194. d := addf(quotf(w,g),negf(diff(c,x)));
  195. repeat <<
  196. p := sfto_gcdf(c,d);
  197. l := (p . (n := n+1)) . l;
  198. c := quotf(c,p);
  199. d := addf(quotf(d,p),negf(diff(c,x)))
  200. >> until domainp c;
  201. return reversip l
  202. end;
  203. procedure sfto_musser!-usqfdecf(u);
  204. % Standard form tools univariate square-free decomposition after
  205. % Musser. [p] is a an SF that is viewed a univariate Polynomial in
  206. % its [mvar] over the polynomial ring in all other variables; in
  207. % this sense, [p] must be primitive. Returns the square-free
  208. % decomposition of [p] as a (dense) list $((q_1 . 1),(q_2 .
  209. % 2),...,(q_n . n))$ such that $\prod q_i^i = u$ with the $q_i$
  210. % square-free and pairwise relatively prime.
  211. begin scalar !*gcd,v,u1,sqfp,sqfp1,l; integer n;
  212. !*gcd := T;
  213. v := mvar u;
  214. u1 := sfto_gcdf(u,diff(u,v));
  215. sqfp := quotf(u,u1);
  216. while degr(u1,v)>0 do <<
  217. sqfp1 := sfto_gcdf(sqfp,u1);
  218. l := (quotf(sqfp,sqfp1) . (n := n+1)) . l;
  219. u1 := quotf(u1,sqfp1);
  220. sqfp := sqfp1
  221. >>;
  222. l := (sqfp . (n := n+1)) . l;
  223. return reversip l
  224. end;
  225. procedure sfto_tobey!-usqfdecf(u);
  226. % Standard form tools univariate square-free decomposition after
  227. % Tobey and Horowitz. [p] is a an SF that is viewed a univariate
  228. % Polynomial in its [mvar] over the polynomial ring in all other
  229. % variables; in this sense, [p] must be primitive. Returns the
  230. % square-free decomposition of [p] as a (dense) list $((q_1 .
  231. % 1),(q_2 . 2),...,(q_n . n))$ such that $\prod q_i^i = u$ with the
  232. % $q_i$ square-free and pairwise relatively prime.
  233. begin scalar !*gcd,v,h,q1,q2,l; integer n;
  234. !*gcd := T;
  235. v := mvar u;
  236. h := sfto_gcdf(u,diff(u,v));
  237. q2 := quotf(u,h);
  238. while degr(u,v)>0 do <<
  239. u := h;
  240. q1 := q2;
  241. h := sfto_gcdf(u,diff(u,v));
  242. q2 := quotf(u,h);
  243. l := (quotf(q1,q2) . (n := n+1)) . l
  244. >>;
  245. return reversip l
  246. end;
  247. procedure sfto_sqdmerge(l1,l2);
  248. % Standard form tools square-free decomposition merge
  249. begin scalar l;
  250. l := l1;
  251. while l1 and l2 do <<
  252. caar l1 := multf(caar l1,caar l2);
  253. l1 := cdr l1;
  254. l2 := cdr l2
  255. >>;
  256. if l2 then l := nconc(l,l2);
  257. return l
  258. end;
  259. procedure sfto_pdecf(u);
  260. % Standard form tools multivariate parity decomposition. [u] is an
  261. % SF. Returns a consed pair $a . d$ such that $a$ is the product of
  262. % all square-free factors with an odd multiplicity in [u] and $d$
  263. % is that of the even multiplicity square-free factors. The
  264. % (integer) content of u is dropped. Decomposition is performed by
  265. % merging univariate decompositions. The univariate decomposition
  266. % method is selected by turning on one of the switches [sfto_yun]
  267. % (default), [sfto_musser].
  268. begin scalar c,dpdc,dpdpp;
  269. if domainp u then return 1 . 1;
  270. c := sfto_ucontentf u;
  271. dpdc := sfto_pdecf c;
  272. dpdpp := sfto_updecf quotf(u,c);
  273. return multf(car dpdc,car dpdpp) . multf(cdr dpdc,cdr dpdpp)
  274. end;
  275. procedure sfto_updecf(u);
  276. if !*sfto_yun then
  277. sfto_yun!-updecf u
  278. else if !*sfto_musser then
  279. sfto_musser!-updecf u
  280. else
  281. rederr {"sfto_updecf: select a decomposition method"};
  282. procedure sfto_yun!-updecf(p);
  283. begin scalar !*gcd,x,g,c,d,w,l,od;
  284. !*gcd := T;
  285. l := 1 . 1;
  286. x := mvar p;
  287. g := sfto_gcdf(p,w := diff(p,x));
  288. c := quotf(p,g);
  289. d := addf(quotf(w,g),negf(diff(c,x)));
  290. repeat <<
  291. od := not od;
  292. p := sfto_gcdf(c,d);
  293. if od then car l := multf(car l,p) else cdr l := multf(cdr l,p);
  294. c := quotf(c,p);
  295. d := addf(quotf(d,p),negf(diff(c,x)))
  296. >> until domainp c;
  297. return l
  298. end;
  299. procedure sfto_musser!-updecf(u);
  300. begin scalar !*gcd,od,v,u1,sqfp,sqfp1,l;
  301. !*gcd := T;
  302. od := T;
  303. l := 1 . 1;
  304. v := mvar u;
  305. u1 := sfto_gcdf(u,diff(u,v));
  306. sqfp := quotf(u,u1);
  307. while degr(u1,v)>0 do <<
  308. sqfp1 := sfto_gcdf(sqfp,u1);
  309. if od then
  310. car l := multf(car l,quotf(sqfp,sqfp1))
  311. else
  312. cdr l := multf(cdr l,quotf(sqfp,sqfp1));
  313. u1 := quotf(u1,sqfp1);
  314. sqfp := sqfp1;
  315. od := not od
  316. >>;
  317. if od then
  318. car l := multf(car l,sqfp)
  319. else
  320. cdr l := multf(cdr l,sqfp);
  321. return l
  322. end;
  323. procedure sfto_pdec!$(argl);
  324. {'list,prepf car w,prepf cdr w}
  325. where w=sfto_pdecf numr simp car argl;
  326. procedure sfto_decdegf(u,k,n);
  327. % Standard form tools decrement degree standard form. [u] is an SF;
  328. % [k] is a variable; [n] is an integer. Returns an SF. Replace each
  329. % occurence of $[k]^d$ by $k^(d/n)$.
  330. reorder sfto_decdegf1(sfto_reorder(u,k),k,n);
  331. procedure sfto_decdegf1(u,k,n);
  332. % Standard form tools decrement degree standard form. [u] is an SF
  333. % with main variable [k]; [k] is a variable; [n] is an integer.
  334. % Returns an SF. Replace each occurence of $[k]^d$ by $k^(d/n)$.
  335. if degr(u,k)=0 then
  336. u
  337. else
  338. mvar u .** (ldeg u / n) .* lc u .+ sfto_decdegf1(red u,k,n);
  339. procedure sfto_reorder(u,v);
  340. % Standard form tools reorder. [u] is an SF; [v] is a kernel.
  341. % Returns the SF [u] reorderd wrt. [{v}].
  342. begin scalar w;
  343. w := setkorder {v};
  344. u := reorder u;
  345. setkorder w;
  346. return u
  347. end;
  348. procedure sfto_groebnerf(l);
  349. % Standard form tools Groebner calculation standard form. [l] is a
  350. % list of SF's. Returns a list of SF's. The returned list is the
  351. % reduced Groebner basis of [l] wrt. the current term order.
  352. begin scalar w;
  353. if null l then return nil;
  354. w := groebnereval {'list . for each sf in l collect prepf sf};
  355. return for each x in cdr w collect
  356. numr simp x
  357. end;
  358. procedure sfto_preducef(f,gl);
  359. % Standard form tools polynomial reduction standard form. [f] is an
  360. % SF and [gl] a list of SF's. Returns the SF [f] reduced wrt. [gl].
  361. if null gl then
  362. f
  363. else if (null cdr gl) and (domainp car gl) then
  364. nil
  365. else
  366. numr simp preduceeval {
  367. prepf f,'list . for each sf in gl collect prepf sf};
  368. procedure sfto_greducef(f,gl);
  369. % Standard form tools polynomial reduction standard form. [f] is an
  370. % SF and [gl] a list of SF's. Returns the SF [f] reduced wrt. a
  371. % Groebner basis of [gl].
  372. if null gl then
  373. f
  374. else if (null cdr gl) and (domainp car gl) then
  375. nil
  376. else
  377. numr simp greduceeval {
  378. prepf f,'list . for each sf in gl collect prepf sf};
  379. procedure sfto_gcdf!*(f,g);
  380. % Standard form tools greatest common divisor of standard forms.
  381. % [f] and [g] are SF's. Returns an SF, the GCD of [f] and [g].
  382. % Compute the GCD of [f] and [g] via [gcdf!*] or [ezgcdf] according
  383. % to Davenport's criterion: If, in one polynomial, the number of
  384. % variables of a degree greater than 2 is greater than 1, then use
  385. % [ezgcd].
  386. sfto_gcdf(f,g) where !*gcd=T;
  387. procedure sfto_gcdf(f,g);
  388. % Standard form tools greatest common divisor of standard forms.
  389. % [f] and [g] are SF's. Returns an SF, the GCD of [f] and [g].
  390. % Compute the GCD of [f] and [g] via [gcdf!*] or [ezgcdf] according
  391. % to Davenport's criterion: If, in one polynomial, the number of
  392. % variables of a degree greater than 2 is greater than 1, then use
  393. % [ezgcd]. For computing the real gcd of [f] ang [g] this
  394. % procedures require, that [!*gcd] is set to [T].
  395. if null !*rldavgcd then
  396. gcdf(f,g)
  397. else if sfto_davp(f,nil) or sfto_davp(g,nil) then
  398. gcdf(f,g) where !*ezgcd=nil
  399. else
  400. ezgcdf(f,g);
  401. procedure sfto_davp(f,badv);
  402. % Standard form tools Davenport predicate. [f] is an SF; [v] is a
  403. % kernel or [nil]. Returns Boolean. [T] means [gcdf] can be used.
  404. if domainp f then
  405. T
  406. else if ldeg f > 2 then
  407. if badv and mvar f neq badv then
  408. nil
  409. else
  410. sfto_davp(lc f,mvar f) and sfto_davp(red f,mvar f)
  411. else
  412. sfto_davp(lc f,badv) and sfto_davp(red f,badv);
  413. procedure sfto_sqrtf(f);
  414. % Standard form tools square root standard form. Returns [nil] or
  415. % an SF $g$, such that $g**2=[f]$.
  416. begin scalar a,c,w,sd,result;
  417. c := sfto_dcontentf(f);
  418. result := fix sqrt c;
  419. if result**2 neq c then
  420. return nil;
  421. sd := sfto_sqfdecf(f);
  422. w := sd;
  423. while sd do <<
  424. a := car sd;
  425. sd := cdr sd;
  426. if not(evenp cdr a) and car a neq 1 then <<
  427. sd := nil;
  428. a := 'break
  429. >> else
  430. result := multf(result,exptf(car a,cdr a / 2 ))
  431. >>;
  432. if a neq 'break and exptf(result,2) = f then
  433. return result
  434. end;
  435. procedure sfto_monfp(sf);
  436. % Standard form tools monomial predicate. [f] is an SF. Returns an
  437. % SF. Check if [sf] is of the form $a x_1 \dots x_n$ for a domain
  438. % element $a$ and kernels $x_i$.
  439. domainp sf or (null red sf and sfto_monfp lc sf);
  440. procedure sfto_sqfpartz(z);
  441. % Standard form tools square free part of an integer. [z] is an
  442. % integer with prime decomposition $p_1^{e_1}\cdots p_n^{e_n}$.
  443. % Returns $\prod \{p_i\}$.
  444. sfto_zdgen(z,0);
  445. procedure sfto_zdeqn(z,n);
  446. % Standard form tools z decomposition equal n. [z] is an integer
  447. % with prime decomposition $p_1^{e_1}\cdots p_n^{e_n}$; [n] is a
  448. % positive integer. Returns $\prod \{p_i:e_i=n\}$.
  449. for each x in zfactor z product
  450. if cdr x = n then car x else 1;
  451. procedure sfto_zdgtn(z,n);
  452. % Standard form tools z decomposition greater than n. [z] is an
  453. % integer with prime decomposition $p_1^{e_1}\cdots p_n^{e_n}$; [n]
  454. % is a positive integer. Returns $\prod \{p_i:e_i>n\}$.
  455. for each x in zfactor z product
  456. if cdr x > n then car x else 1;
  457. procedure sfto_zdgen(z,n);
  458. % Standard form tools z decomposition greater than or equal to n.
  459. % [z] is an integer with prime decomposition $p_1^{e_1}\cdots
  460. % p_n^{e_n}$; [n] is a positive integer. Returns $\prod
  461. % \{p_i:e_i\geq n\}$.
  462. for each x in zfactor z product
  463. if cdr x >= n then car x else 1;
  464. endmodule; % [sfto]
  465. end; % of file