pcf.scm 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482
  1. #| -*-Scheme-*-
  2. Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
  3. 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
  4. 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Massachusetts
  5. Institute of Technology
  6. This file is part of MIT/GNU Scheme.
  7. MIT/GNU Scheme is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or (at
  10. your option) any later version.
  11. MIT/GNU Scheme is distributed in the hope that it will be useful, but
  12. WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. General Public License for more details.
  15. You should have received a copy of the GNU General Public License
  16. along with MIT/GNU Scheme; if not, write to the Free Software
  17. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
  18. USA.
  19. |#
  20. ;;;; Multivariate Polynomial Functions -- GJS
  21. ;;; Polynomial functions are used to implement rational functions.
  22. ;;; These are used for simplification to Rational Canonical Form.
  23. ;;; Multivariate polynomial functions are not expressions in named
  24. ;;; indeterminates. In fact, they are true functions -- they take
  25. ;;; arguments by position, without any presumed name for each
  26. ;;; argument.
  27. (declare (usual-integrations))
  28. ;;; The following procedures are mapped for coefficient arithmetic.
  29. ;;; Other implementation of coefficient arithmetic may be constructed
  30. ;;; by modifying this map.
  31. (define-integrable base? number?)
  32. (define-integrable base/zero :zero)
  33. (define-integrable base/one :one)
  34. (define-integrable base/zero? zero?)
  35. (define-integrable base/one? one?)
  36. (define-integrable base/negative? negative?)
  37. (define-integrable base/negate -)
  38. (define-integrable base/abs magnitude)
  39. (define-integrable base/equal? =)
  40. (define-integrable base/add +)
  41. (define-integrable base/mul *)
  42. (define-integrable base/sub -)
  43. (define-integrable base/div scheme-number-divide)
  44. (define-integrable base/gcd scheme-number-gcd)
  45. (define-integrable base/expt expt)
  46. (define-integrable poly/zero base/zero)
  47. (define-integrable poly/one base/one)
  48. (define-integrable (poly/zero? p)
  49. (and (base? p) (base/zero? p)))
  50. (define-integrable (poly/one? p)
  51. (and (base? p) (base/one? p)))
  52. (define (poly/make-identity arity)
  53. (poly/make-from-dense arity (list base/one base/zero)))
  54. (define (poly/make-constant arity c)
  55. (if (not (fix:< (poly/arity c) arity))
  56. (error "Bad constant -- POLY/MAKE-CONSTANT" arity c))
  57. (poly/make-from-dense arity (list c)))
  58. (define (poly/make-c*x^n arity c n)
  59. (poly/make-from-sparse arity (list (cons n c))))
  60. (define (poly/identity? p)
  61. (if (base? p)
  62. #f
  63. (poly/equal? p poly/identity)))
  64. (define (poly/monic? p)
  65. (if (base? p)
  66. (base/one? p)
  67. (poly/monic? (poly/leading-coefficient p))))
  68. (define (poly/negative? p)
  69. (if (base? p)
  70. (and (real? p) (negative? p))
  71. (poly/negative? (poly/leading-coefficient p))))
  72. (define (poly/equal? p1 p2)
  73. (cond ((and (base? p1) (base? p2)) (base/equal? p1 p2))
  74. ((or (base? p1) (base? p2)) #f)
  75. (else
  76. (let ((arity (poly/check-same-arity p1 p2)))
  77. (and (fix:= (poly/degree p1) (poly/degree p2))
  78. (poly/equal? (poly/leading-coefficient p1)
  79. (poly/leading-coefficient p2))
  80. (poly/equal? (poly/except-leading-term arity p1)
  81. (poly/except-leading-term arity p2)))))))
  82. (define (poly/extend n p)
  83. ;; Interpolates a variable at position n in polynomial p.
  84. (let* ((arity (poly/arity p))
  85. (narity (if (fix:> n arity) (fix:+ n 1) (fix:+ arity 1))))
  86. (if (fix:= n 0)
  87. (poly/adjoin (fix:+ arity 1) 0 p poly/zero)
  88. (let lp ((p p))
  89. (cond ((poly/zero? p) p)
  90. (else
  91. (poly/adjoin narity
  92. (poly/degree p)
  93. (poly/extend (fix:- n 1)
  94. (poly/leading-coefficient p))
  95. (lp (poly/except-leading-term arity p)))))))))
  96. (define (poly/contract n p)
  97. (if (poly/contractable? n p)
  98. (let ((arity (poly/arity p)))
  99. (if (fix:= n 0)
  100. (poly/trailing-coefficient p)
  101. (let lp ((p p))
  102. (cond ((poly/zero? p) p)
  103. (else
  104. (poly/adjoin (fix:- arity 1)
  105. (poly/degree p)
  106. (poly/contract (fix:- n 1)
  107. (poly/leading-coefficient p))
  108. (lp
  109. (poly/except-leading-term arity p))))))))
  110. (error "Poly not contractable" n p)))
  111. (define (poly/contractable? n p)
  112. (or (base? p)
  113. (if (fix:= n 0)
  114. (fix:= (poly/degree p) 0)
  115. (and (fix:< n (poly/arity p))
  116. (let lp ((p p))
  117. (cond ((poly/zero? p) #t)
  118. ((poly/contractable? (fix:- n 1)
  119. (poly/leading-coefficient p))
  120. (poly/contractable? n
  121. (poly/except-leading-term (poly/arity p) p)))
  122. (else #f)))))))
  123. (define (poly/make-vars arity)
  124. (if (fix:= arity 0)
  125. '()
  126. (let lp1 ((n 1) (l (list poly/identity)))
  127. (if (fix:= n arity)
  128. l
  129. (lp1 (fix:+ n 1)
  130. (cons (poly/make-identity (fix:+ n 1))
  131. (map (lambda (c)
  132. (poly/extend 0 c))
  133. l)))))))
  134. ;;; Functions can only be combined if they have the same arity.
  135. (define (poly/check-same-arity p1 p2)
  136. (cond ((base? p1) (poly/arity p2))
  137. ((base? p2) (poly/arity p1))
  138. ((fix:= (poly/arity p1) (poly/arity p2))
  139. (poly/arity p1))
  140. (else (error "Unequal arities -- POLY" p1 p2))))
  141. (define (poly/add p1 p2)
  142. (cond ((and (base? p1) (base? p2)) (base/add p1 p2))
  143. ((poly/zero? p1) p2)
  144. ((poly/zero? p2) p1)
  145. (else
  146. (let ((degree1 (poly/degree p1))
  147. (degree2 (poly/degree p2))
  148. (arity (poly/check-same-arity p1 p2)))
  149. (cond ((fix:= degree1 degree2)
  150. (let ((c (poly/add (poly/leading-coefficient p1)
  151. (poly/leading-coefficient p2)))
  152. (s (poly/add (poly/except-leading-term arity p1)
  153. (poly/except-leading-term arity p2))))
  154. (if (poly/zero? c)
  155. s
  156. (poly/adjoin arity degree1 c s))))
  157. ((fix:> degree1 degree2)
  158. (poly/adjoin arity degree1
  159. (poly/leading-coefficient p1)
  160. (poly/add (poly/except-leading-term arity p1)
  161. p2)))
  162. (else ;(fix:< degree1 degree2)
  163. (poly/adjoin arity degree2
  164. (poly/leading-coefficient p2)
  165. (poly/add p1
  166. (poly/except-leading-term arity p2)))))))))
  167. (define (poly/sub p1 p2)
  168. (cond ((and (base? p1) (base? p2)) (base/sub p1 p2))
  169. ((poly/zero? p1) (poly/negate p2))
  170. ((poly/zero? p2) p1)
  171. (else
  172. (let ((degree1 (poly/degree p1))
  173. (degree2 (poly/degree p2))
  174. (arity (poly/check-same-arity p1 p2)))
  175. (cond ((fix:= degree1 degree2)
  176. (let ((c (poly/sub (poly/leading-coefficient p1)
  177. (poly/leading-coefficient p2)))
  178. (s (poly/sub (poly/except-leading-term arity p1)
  179. (poly/except-leading-term arity p2))))
  180. (if (poly/zero? c)
  181. s
  182. (poly/adjoin arity degree1 c s))))
  183. ((fix:> degree1 degree2)
  184. (poly/adjoin arity degree1
  185. (poly/leading-coefficient p1)
  186. (poly/sub (poly/except-leading-term arity p1)
  187. p2)))
  188. (else ;(fix:< degree1 degree2)
  189. (poly/adjoin arity degree2
  190. (poly/negate (poly/leading-coefficient p2))
  191. (poly/sub p1
  192. (poly/except-leading-term arity p2)))))))))
  193. (define (poly/negate p)
  194. (let ((arity (poly/arity p)))
  195. (cond ((base? p) (base/negate p))
  196. (else (poly/adjoin arity (poly/degree p)
  197. (poly/negate (poly/leading-coefficient p))
  198. (poly/negate (poly/except-leading-term arity p)))))))
  199. (define (poly/mul p1 p2)
  200. (cond ((and (base? p1) (base? p2)) (base/mul p1 p2))
  201. ((poly/zero? p1) p1)
  202. ((poly/zero? p2) p2)
  203. ((poly/one? p1) p2)
  204. ((poly/one? p2) p1)
  205. (else
  206. (let ((arity (poly/check-same-arity p1 p2))
  207. (d (poly/degree p1))
  208. (c (poly/leading-coefficient p1)))
  209. (poly/add (let loop ((p p2))
  210. (if (poly/zero? p)
  211. p
  212. (poly/adjoin arity
  213. (fix:+ d (poly/degree p))
  214. (poly/mul c (poly/leading-coefficient p))
  215. (loop (poly/except-leading-term arity p)))))
  216. (poly/mul (poly/except-leading-term arity p1)
  217. p2))))))
  218. (define (poly/scale-1 arity p coeff)
  219. (let loop ((p p))
  220. (if (poly/zero? p)
  221. p
  222. (poly/adjoin arity (poly/degree p)
  223. (poly/mul (poly/leading-coefficient p) coeff)
  224. (loop (poly/except-leading-term arity p))))))
  225. (define (poly/scale p coeff)
  226. (poly/scale-1 (poly/arity p) p coeff))
  227. (define (poly/square p)
  228. (poly/mul p p))
  229. (define (poly/expt base exponent)
  230. (define (expt-iter x count answer)
  231. (if (int:zero? count)
  232. answer
  233. (if (even? count)
  234. (expt-iter (poly/square x) (int:quotient count 2) answer)
  235. (expt-iter x (int:- count 1) (poly/mul x answer)))))
  236. (cond ((base? base) (base/expt base exponent))
  237. ((not (exact-integer? exponent))
  238. (error "Can only raise a PCF to an exact integer power" base exponent))
  239. ((negative? exponent)
  240. (error "No inverse (POLY/EXPT):" base exponent))
  241. ((poly/one? base) base)
  242. ((poly/zero? base)
  243. (if (int:zero? exponent)
  244. (error "0^0 -- POLY/EXPT"))
  245. base)
  246. ((int:zero? exponent) poly/one)
  247. (else
  248. (expt-iter base exponent poly/one))))
  249. ;;; Division over a field.
  250. ;;; The following procedure takes two polynomials and calls its
  251. ;;; continuation with the quotient and the remainder polynomials.
  252. ;;;
  253. ;;; s^3 + 3s^2 + 4s + 5 3
  254. ;;; --------------------- = s^2 + 2s + 2 + -------
  255. ;;; s + 1 s + 1
  256. ;;;
  257. ;;; For multivariate polynomials this only makes sense as
  258. ;;; poly/quotient defined below, because the coefficient ring is not
  259. ;;; a field, but a unique factorization domain (UFD).
  260. (define (poly/div u v cont)
  261. ;; cont = (lambda (q r)
  262. ;; (assert (poly/equal? u (poly/add (poly/mul q v) r))))
  263. (if (poly/zero? v)
  264. (error "Divide by zero (POLY/DIV):" u v))
  265. (cond ((and (base? u) (base? v)) (base/div u v cont))
  266. ((or (poly/zero? u) (poly/one? v))
  267. (cont u poly/zero))
  268. (else
  269. (let ((arity (poly/check-same-arity u v)))
  270. (let lp ((u u) (cont cont))
  271. (if (fix:< (poly/degree u) (poly/degree v))
  272. (cont poly/zero u)
  273. (let ((lead-q-degree
  274. (fix:- (poly/degree u) (poly/degree v)))
  275. (lead-q-coeff
  276. (poly/quotient (poly/leading-coefficient u)
  277. (poly/leading-coefficient v))))
  278. (let ((qt (poly/make-c*x^n arity
  279. lead-q-coeff
  280. lead-q-degree)))
  281. (lp (poly/sub u (poly/mul qt v))
  282. (lambda (sq sr)
  283. (cont (poly/add qt sq) sr)))))))))))
  284. ;;; This exact quotient is only defined when the remainder is zero.
  285. ;;; Thus for polynomials over the integers or for polynomials with
  286. ;;; polynomial coefficients we must have only exact quotients in
  287. ;;; the coeff/div. So must check that the remainder is zero.
  288. ;;; For polynomials over the rationals, we may use rat:/.
  289. (define (poly/quotient u v)
  290. (poly/div u v
  291. (lambda (q r)
  292. (if (poly/zero? r)
  293. q
  294. (error "Inexact division (POLY/QUOTIENT):" u v)))))
  295. (define (poly/not-divisible? n d)
  296. (poly/div n d (lambda (p r) (not (poly/zero? r)))))
  297. ;;; Sometimes we want to exactly divide by a coefficient object.
  298. (define (map-poly-terms proc p)
  299. (let ((arity (poly/arity p)))
  300. (let lp ((p p))
  301. (if (poly/zero? p)
  302. p
  303. (poly/adjoin arity
  304. (poly/degree p)
  305. (proc (poly/leading-coefficient p))
  306. (lp (poly/except-leading-term arity p)))))))
  307. (define (poly/normalize p c)
  308. (cond ((poly/zero? c)
  309. (error "Divide by zero (POLY/NORMALIZE):" p c))
  310. ((poly/one? c) p)
  311. ((base? c)
  312. (base/div base/one c
  313. (lambda (q r)
  314. (poly/scale p q))))
  315. (else
  316. (map-poly-terms (lambda (pc) (poly/quotient pc c))
  317. p))))
  318. ;;; Pseudo division produces only a remainder--no quotient.
  319. ;;; This can be used to generalize Euclid's algorithm for polynomials
  320. ;;; over a unique factorization domain (UFD).
  321. ;;; This implementation differs from Knuth's Algorithm R in that
  322. ;;; Knuth's contributes to the integerizing factor, making it
  323. ;;; l(v)^(m-n+1), even though no factor of l(v) is needed if a u_j is
  324. ;;; zero for some n<j<m. This matters a great deal in the
  325. ;;; multivariate case.
  326. ;;; Sussman's code -- good for Euclid Algorithm
  327. (define (poly/pseudo-remainder u v cont)
  328. ;; cont = (lambda (r d) #| l(v)^d*u = v*q + r|# )
  329. (if (poly/zero? v)
  330. (error "Divide by zero (POLY/PSEUDO-REMAINDER):" u v))
  331. (let* ((arity (poly/check-same-arity u v))
  332. (cvn (poly/make-constant arity
  333. (poly/leading-coefficient v)))
  334. (n (poly/degree v)))
  335. (let lp ((u u) (d -1))
  336. ;;(write-line u)
  337. (let ((m (poly/degree u))
  338. (cum (poly/leading-coefficient u)))
  339. (if (fix:< m n)
  340. (cont u d)
  341. (lp (poly/sub (poly/mul u cvn)
  342. (poly/mul (poly/make-c*x^n arity
  343. cum
  344. (fix:- m n))
  345. v))
  346. (fix:+ d 1)))))))
  347. ;;; The following helpers are used in GCD routines
  348. ;;; The content of a polynomial is the GCD of its coefficients.
  349. ;;; The content of a polynomial has the arity of its coefficients.
  350. (define (poly/content-maker poly/gcd)
  351. (define (poly/content u win lose)
  352. (let ((coeffs (poly/coefficients u)))
  353. (if (null? coeffs)
  354. (win poly/zero)
  355. (let lp ((c0 (car coeffs)) (cs (cdr coeffs)))
  356. (if (null? cs)
  357. (win c0)
  358. (poly/gcd c0 (car cs)
  359. (lambda (g1)
  360. (if (poly/one? g1)
  361. (win g1)
  362. (lp g1 (cdr cs))))
  363. lose))))))
  364. poly/content)
  365. ;;; The primitive-part of a polynomial is the polynomial with the
  366. ;;; content removed.
  367. (define (poly/primitive-part-maker poly/gcd)
  368. (let ((poly/content (poly/content-maker poly/gcd)))
  369. (define (poly/primitive-part p win lose)
  370. (if (or (poly/zero? p) (poly/one? p))
  371. (win p)
  372. (poly/content p
  373. (lambda (c)
  374. (win
  375. (cond ((poly/negative? p)
  376. (if (poly/one? c)
  377. (poly/negate p)
  378. (poly/normalize p (poly/negate c))))
  379. ((poly/one? c) p)
  380. (else
  381. (poly/normalize p c)))))
  382. lose)))
  383. poly/primitive-part))
  384. #|
  385. ;;; Distillation method (Zippel Section 8.2) is often very bad.
  386. (define (poly/content-maker poly/gcd)
  387. (define (poly/content u)
  388. (let ((coeffs (poly/coefficients u)))
  389. (if (null? coeffs)
  390. poly/zero
  391. (let lp ((coeffs coeffs))
  392. (let ((n (length coeffs)))
  393. (if (fix:= n 1)
  394. (car coeffs)
  395. (let ((n/2 (quotient n 2)))
  396. (let ((ps (poly/random-linear-combination
  397. (list-head coeffs n/2)))
  398. (qs (poly/random-linear-combination
  399. (list-tail coeffs n/2))))
  400. (let ((g (poly/gcd ps qs)))
  401. (if (poly/one? g)
  402. g
  403. (lp
  404. (cons g
  405. (filter (lambda (c)
  406. (poly/not-divisible? c g))
  407. coeffs)))))))))))))
  408. poly/content)
  409. (define poly/random-linear-combination
  410. (let* ((number-of-primes 100)
  411. (prime-table
  412. (make-initialized-vector number-of-primes
  413. (lambda (i) (stream-ref prime-numbers-stream i)))))
  414. (lambda (polys)
  415. (fold-left poly/add (car polys)
  416. (map (lambda (p)
  417. (poly/mul
  418. (vector-ref prime-table
  419. (random number-of-primes))
  420. p))
  421. (cdr polys))))))
  422. |#
  423. ;;; Euclidean GCD
  424. ;;; This implementation differs from Knuth's Algorithm E in that it
  425. ;;; is rotated to look more like Euclidean integer gcd.
  426. (define (poly/gcd/euclid u v win lose)
  427. (let ((poly/content
  428. (poly/content-maker poly/gcd/euclid))
  429. (poly/primitive-part
  430. (poly/primitive-part-maker poly/gcd/euclid)))
  431. (define (pgcd ppu ppv win lose)
  432. (if euclid-wallp? (pp (list ppu ppv)))
  433. (cond ((poly/zero? ppv) (win ppu))
  434. ((fix:zero? (poly/degree ppv)) (win poly/one))
  435. ((allocated-time-expired?) (lose))
  436. (else
  437. (poly/pseudo-remainder ppu ppv
  438. (lambda (r delta)
  439. (poly/primitive-part r
  440. (lambda (ppr)
  441. (pgcd ppv ppr win lose))
  442. lose))))))
  443. (cond ((poly/zero? u) (win v)) ((poly/zero? v) (win u))
  444. ((poly/one? u) (win u)) ((poly/one? v) (win v))
  445. ((base? u)
  446. (if (base? v)
  447. (win (base/gcd u v))
  448. (poly/content v
  449. (lambda (vc)
  450. (poly/gcd/euclid u vc win lose))
  451. lose)))
  452. ((base? v)
  453. (poly/content u
  454. (lambda (uc)
  455. (poly/gcd/euclid uc v win lose))
  456. lose))
  457. (else
  458. (let ((arity (poly/check-same-arity u v))
  459. (win (lambda (g) (win (poly/abs g)))))
  460. (poly/content u
  461. (lambda (uc)
  462. (poly/content v
  463. (lambda (vc)
  464. (if (poly/one? uc)
  465. (if (poly/one? vc)
  466. (pgcd u v win lose)
  467. (pgcd u (poly/normalize v vc) win lose))
  468. (if (poly/one? vc)
  469. (pgcd (poly/normalize u uc) v win lose)
  470. (poly/gcd/euclid uc vc
  471. (lambda (c)
  472. (if (poly/one? c)
  473. (pgcd (poly/normalize u uc)
  474. (poly/normalize v vc)
  475. win lose)
  476. (pgcd (poly/normalize u uc)
  477. (poly/normalize v vc)
  478. (lambda (g)
  479. (win (poly/scale-1 arity g c)))
  480. lose)))
  481. lose))))
  482. lose))
  483. lose))))))
  484. (define euclid-wallp? false)
  485. (define (poly/gcd-euclid u v)
  486. (poly/gcd/euclid u v (lambda (g) g) (lambda () #f)))
  487. ;;; Algorithm C... Collins's GCD algorithm.
  488. ;;; I have not found this worthwhile--GJS.
  489. ;;; Thus, I have not updated it to use the
  490. ;;; success and failure continuations needed.
  491. (define (poly/gcd-collins u v)
  492. (let ((poly/content
  493. (poly/content-maker poly/gcd-collins))
  494. (poly/primitive-part
  495. (poly/primitive-part-maker poly/gcd-collins)))
  496. (define (pgcd u v oc)
  497. (if collins-wallp? (pp (list u v)))
  498. (cond ((poly/zero? v) u)
  499. ((fix:zero? (poly/degree v)) poly/one)
  500. (else
  501. (poly/pseudo-remainder u v
  502. (lambda (r delta)
  503. (pgcd v
  504. (poly/normalize r
  505. (poly/expt (poly/leading-coefficient u)
  506. oc))
  507. delta))))))
  508. (define (ppgcd u v)
  509. (cond ((poly/one? u) u)
  510. ((poly/one? v) v)
  511. ((and (base? u) (base? v)) (base/gcd u v))
  512. ((fix:>= (poly/degree u) (poly/degree v))
  513. (poly/primitive-part (pgcd u v 0)))
  514. (else
  515. (poly/primitive-part (pgcd v u 0)))))
  516. (cond ((poly/zero? u) v)
  517. ((poly/zero? v) u)
  518. ((poly/one? u) u)
  519. ((poly/one? v) v)
  520. ((base? u)
  521. (if (base? v)
  522. (base/gcd u v)
  523. (poly/gcd-collins u (poly/content v))))
  524. ((base? v)
  525. (poly/gcd-collins (poly/content u) v))
  526. (else
  527. (let ((arity (poly/check-same-arity u v))
  528. (uc (poly/content u))
  529. (vc (poly/content v)))
  530. (let ((ans
  531. (if (poly/one? uc)
  532. (if (poly/one? vc)
  533. (ppgcd u v)
  534. (ppgcd u (poly/normalize v vc)))
  535. (if (poly/one? vc)
  536. (ppgcd (poly/normalize u uc) v)
  537. (let ((c (poly/gcd-collins uc vc)))
  538. (if (poly/one? c)
  539. (ppgcd (poly/normalize u uc)
  540. (poly/normalize v vc))
  541. (poly/scale-1 arity
  542. (ppgcd (poly/normalize u uc)
  543. (poly/normalize v vc))
  544. c)))))))
  545. (poly/abs ans)))))))
  546. (define collins-wallp? false)
  547. #|
  548. ;;; Test examples
  549. (define x-1 (poly/make-from-dense 1 '(1 -1)))
  550. (define x+1 (poly/make-from-dense 1 '(1 1)))
  551. (poly/gcd-euclid (poly/mul (poly/mul x-1 x-1) x+1)
  552. (poly/mul (poly/mul x+1 x+1) x-1))
  553. ;Value: (*dense* 1 1 0 -1)
  554. (poly/gcd-euclid (poly/mul (poly/mul x+1 x+1) x-1)
  555. (poly/mul (poly/mul x-1 x-1) x+1))
  556. ;Value: (*dense* 1 1 0 -1)
  557. (define k1 (poly/make-from-dense 1 '(1 0 1 0 -3 -3 8 2 -5)))
  558. (define k2 (poly/make-from-dense 1 '(3 0 5 0 -4 -9 21)))
  559. (poly/gcd-euclid k1 k2)
  560. ;Value: 1
  561. (poly/gcd-collins (poly/mul (poly/mul x-1 x-1) x+1)
  562. (poly/mul (poly/mul x+1 x+1) x-1))
  563. ;Value: (*dense* 1 1 0 -1)
  564. (poly/gcd-euclid k1 k2)
  565. ;;; With euclid-wallp? = #t
  566. ((*dense* 1 0 1 0 -3 -3 8 2 -5) (*dense* 3 0 5 0 -4 -9 21))
  567. ((*dense* 3 0 5 0 -4 -9 21) (*dense* 5 0 -1 0 3))
  568. ((*dense* 5 0 -1 0 3) (*dense* 13 25 -49))
  569. ((*dense* 13 25 -49) (*dense* 4663 -6150))
  570. ((*dense* 4663 -6150) (*dense* 1))
  571. ;Value: 1
  572. (poly/gcd-collins k1 k2)
  573. ;;; With collins-wallp? = #t
  574. ((*dense* 1 0 1 0 -3 -3 8 2 -5) (*dense* 3 0 5 0 -4 -9 21) 1)
  575. ((*dense* 3 0 5 0 -4 -9 21) (*dense* -5 0 1 0 -3) 9)
  576. ((*dense* -5 0 1 0 -3) (*dense* -13 -25 49) 25)
  577. ((*dense* -13 -25 49) (*dense* -9326 12300) -2197)
  578. ((*dense* -9326 12300) (*dense* 260708) 86974276)
  579. ;Value: 1
  580. (define p1 (poly/make-from-dense 1 '(1 1 1)))
  581. (define p2 (poly/make-from-dense 1 '(3 2)))
  582. (define p3 (poly/make-from-dense 1 '(5 3 2)))
  583. (define p4 (poly/mul (poly/expt p1 3) (poly/mul p2 p3)))
  584. (define p5 (poly/mul p1 (poly/expt p3 2)))
  585. (poly/gcd-euclid p4 p5)
  586. ((*dense* 1 15 64 159 259 307 267 172 79 24 4) (*dense* 1 25 55 84 71 45 16 4))
  587. ((*dense* 1 25 55 84 71 45 16 4) (*dense* 1 3015 5234 6686 3835 1616 164))
  588. ((*dense* 1 3015 5234 6686 3835 1616 164) (*dense* 1 5 8 10 5 2))
  589. ((*dense* 1 5 8 10 5 2) (*dense* 1))
  590. ;Value: (*dense* 1 5 8 10 5 2)
  591. (poly/gcd-collins p4 p5)
  592. ((*dense* 1 15 64 159 259 307 267 172 79 24 4) (*dense* 1 25 55 84 71 45 16 4) 1)
  593. ((*dense* 1 25 55 84 71 45 16 4)
  594. (*dense* 1 1884375 3271250 4178750 2396875 1010000 102500)
  595. 390625)
  596. ((*dense* 1 1884375 3271250 4178750 2396875 1010000 102500)
  597. (*dense* 1 76562500 122500000 153125000 76562500 30625000)
  598. 3550869140625)
  599. ((*dense* 1 76562500 122500000 153125000 76562500 30625000)
  600. (*dense* 1)
  601. 5861816406250000)
  602. ;Value: (*dense* 1 5 8 10 5 2)
  603. (poly/mul p1 p3)
  604. ;Value: (*dense* 1 5 8 10 5 2)
  605. (define p6 (poly/mul (poly/expt p1 2) (poly/expt p3 2)))
  606. (poly/gcd-collins p4 p6)
  607. ;Value: (*dense* 1 5 13 23 23 17 7 2)
  608. (poly/gcd-euclid p4 p6)
  609. ;Value: (*dense* 1 5 13 23 23 17 7 2)
  610. |#
  611. ;;; GCD memoizer. A hairy attempt to speed up the gcd. Ultimately
  612. ;;; this failed and we went to a sparse interpolation gcd.
  613. (define (gcd-memoizer poly/gcd)
  614. (let ((table
  615. ((weak-hash-table/constructor unordered-poly-hash
  616. unordered-pair-equal?))))
  617. (define (the-memoized-gcd p1 p2)
  618. (if *gcd-memoizer-enabled*
  619. (let ((x (cons p1 p2)))
  620. (let ((seen (hash-table/get table x *not-seen*)))
  621. (if (not (eq? seen *not-seen*))
  622. (begin (*gcd-hit* (fix:+ (*gcd-hit*) 1))
  623. seen)
  624. (let ((ans (poly/gcd p1 p2)))
  625. (*gcd-miss* (fix:+ (*gcd-miss*) 1))
  626. (hash-table/put! table x ans)
  627. ans))))
  628. (poly/gcd p1 p2)))
  629. the-memoized-gcd))
  630. (define *gcd-memoizer-enabled* #f)
  631. ;;; FBE: make a parameter
  632. (define *gcd-hit* (make-parameter 0))
  633. (define *gcd-miss* (make-parameter 0))
  634. (define (unordered-pair-equal? a1 a2)
  635. (and (pair? a1)
  636. (pair? a2)
  637. (or (and (equal? (car a1) (car a2))
  638. (equal? (cdr a1) (cdr a2)))
  639. (and (equal? (car a1) (cdr a2))
  640. (equal? (cdr a1) (car a2))))))
  641. (define (unordered-poly-hash a modulus)
  642. (let ((arity (poly/check-same-arity (car a) (cdr a))))
  643. (let ((args (vector-ref hash-args-vector arity)))
  644. (let ((v (* (poly/horner (car a) args)
  645. (poly/horner (cdr a) args))))
  646. (modulo (* (numerator v) (denominator v))
  647. modulus)))))
  648. (define n-random-primes 100)
  649. (define skip-initial-primes 100)
  650. (define prime-numbers-vector
  651. (make-initialized-vector n-random-primes
  652. (lambda (i)
  653. (stream-ref prime-numbers-stream
  654. (fix:+ i skip-initial-primes)))))
  655. (define hash-args-vector
  656. (make-initialized-vector n-random-primes
  657. (lambda (i)
  658. (make-initialized-list i
  659. (lambda (j)
  660. (vector-ref prime-numbers-vector
  661. (random (min (* 2 i) n-random-primes))))))))
  662. ;;; (define poly/gcd-memoized (gcd-memoizer poly/gcd-euclid))
  663. ;;; (define poly/gcd-memoized (gcd-memoizer poly/gcd-collins))
  664. ;;; The following returns the derivative of a polynomial with respect
  665. ;;; to a given variable index. Variable 1 is the principal variable.
  666. ;;; For example:
  667. ;;;(->expression
  668. ;;; (poly/derivative-partial
  669. ;;; (->poly '(+ (* x y z) (* x x z) (* y y))
  670. ;;; '(x y z))
  671. ;;; 2)
  672. ;;; '(x y z))
  673. ;;;Value: (+ (* z x) (* 2 y))
  674. (define (poly/derivative-partial p varnum)
  675. (cond ((base? p) poly/zero)
  676. ((fix:< varnum 1) poly/zero)
  677. ((fix:= varnum 1) (poly/derivative-principal p))
  678. (else
  679. (let ((arity (poly/arity p)))
  680. (if (fix:> varnum arity)
  681. (error "Bad varnum -- POLY/DERIVATIVE-PARTIAL"
  682. p varnum))
  683. (let lp ((p p))
  684. (if (poly/zero? p)
  685. poly/zero
  686. (let ((c (poly/leading-coefficient p)))
  687. (let ((d (poly/derivative-partial c
  688. (fix:- varnum
  689. (fix:- arity
  690. (poly/arity c))))))
  691. (if (poly/zero? d)
  692. (lp (poly/except-leading-term arity p))
  693. (poly/adjoin arity
  694. (poly/degree p)
  695. d
  696. (lp (poly/except-leading-term arity p))))))))))))
  697. (define (poly/partial-derivative p varnums) ;compatibility
  698. (assert (fix:= (length varnums) 1))
  699. (poly/derivative-partial p (fix:+ (car varnums) 1)))
  700. (define (poly/derivative-principal p)
  701. (if (base? p)
  702. poly/zero
  703. (let ((arity (poly/arity p)))
  704. (let lp ((p p))
  705. (if (base? p)
  706. poly/zero
  707. (let ((deg (poly/degree p)))
  708. (if (fix:zero? deg)
  709. poly/zero
  710. (poly/adjoin arity
  711. (fix:- deg 1)
  712. (poly/mul deg (poly/leading-coefficient p))
  713. (lp (poly/except-leading-term arity p))))))))))
  714. ;;; Evaluation of polynomials by Horner's rule is one key to their
  715. ;;; effective use. The following is useful for univariate
  716. ;;; polynomials.
  717. (define (poly/horner-univariate p x)
  718. (poly/hh p x (lambda (x) x)))
  719. (define (poly/horner p args)
  720. (if (base? p)
  721. p
  722. (let ((arity (poly/arity p)))
  723. (if (not (fix:= arity (length args)))
  724. (error "Wrong number of args -- POLY/HORNER" p args))
  725. (let lp ((p p) (args args))
  726. (if (base? p)
  727. p
  728. (let ((arity (poly/arity p))
  729. (nargs (length args)))
  730. (let ((args (list-tail args (fix:- nargs arity))))
  731. (poly/hh p
  732. (car args)
  733. (lambda (c) (lp c (cdr args)))))))))))
  734. ;;; POLY/HORNER-HELPER is used to evaluate a polynomial for a
  735. ;;; particular value of the indeterminate. In general, the
  736. ;;; coefficients of the polynomial will themselves be polynomials,
  737. ;;; which must be evaluated with values for their indeterminates. The
  738. ;;; EVAL-COEFF argument will be used in the process of lifting this
  739. ;;; system to multivariate polynomials. It will encapsulate the
  740. ;;; process of evaluating the coefficients of the current polynomial
  741. ;;; on the rest of the polynomial arguments.
  742. (define (poly/horner-helper add mul raise)
  743. (lambda (p x eval-coeff)
  744. (if (base? p)
  745. p
  746. (let ((arity (poly/arity p)))
  747. (let lp ((restp (poly/except-leading-term arity p))
  748. (coeff-value (eval-coeff (poly/leading-coefficient p)))
  749. (degree (poly/degree p)))
  750. (if (poly/zero? restp)
  751. (mul coeff-value (raise x degree))
  752. (let ((next-degree (poly/degree restp))
  753. (next-coeff (poly/leading-coefficient restp)))
  754. (lp (poly/except-leading-term arity restp)
  755. (add (mul coeff-value
  756. (raise x
  757. (fix:- degree
  758. next-degree)))
  759. (eval-coeff next-coeff))
  760. next-degree))))))))
  761. (define poly/hh (poly/horner-helper poly/add poly/mul poly/expt))
  762. ;;; Given polynomial P(x), substitute x = r*y and compute the resulting
  763. ;;; polynomial Q(y) = P(y*r). When a multivariate polynomial is
  764. ;;; scaled, each factor must have the same arity as the given
  765. ;;; polynomial... or a base constant.
  766. (define (poly/arg-scale p factors)
  767. (poly/horner p
  768. (map poly/mul
  769. (list-head factors (poly/arity p))
  770. (poly/make-vars (poly/arity p)))))
  771. ;;; Given polynomial P(x), substitute x = y+h and compute the resulting
  772. ;;; polynomial Q(y) = P(y+h). When a multivariate polynomial is
  773. ;;; shifted, each shift must have the same arity as the given
  774. ;;; polynomial... or a base constant.
  775. (define (poly/arg-shift p shifts)
  776. (poly/horner p
  777. (map poly/add
  778. (list-head shifts (poly/arity p))
  779. (poly/make-vars (poly/arity p)))))
  780. (define (poly/abs ans)
  781. (if (base? ans)
  782. (base/abs ans)
  783. (if (poly/negative? ans)
  784. (poly/negate ans)
  785. ans)))
  786. (define (poly/leading-base-coefficient p)
  787. (if (base? p)
  788. p
  789. (poly/leading-base-coefficient (poly/leading-coefficient p))))
  790. ;;; This Horner's rule evaluator is restricted to
  791. ;;; numerical coefficients and univariate polynomials.
  792. ;;; It returns, by calling a continuation procedure,
  793. ;;; a value, two derivatives, and an estimate of the
  794. ;;; roundoff error incurred in computing that value.
  795. #|
  796. ;;; The recurrences used are from Kahan's 18 Nov 1986 paper
  797. ;;; "Roundoff in Polynomial Evaluation", generalized for
  798. ;;; sparse representations and another derivative by GJS.
  799. ;;; For p = A(z), q = A'(z), r = A''(z), and e = error in A(x),
  800. p_{j+n} = z^n p_j + a_{j+n}
  801. e_{j+n} = |z|^n ( e_j + (n-1) p_j ) + |p_{j+n}|
  802. q_{j+n} = z^n q_j + n z^{n-1} p_j
  803. r_{j+n} = z^n r_j + n z^{n-1} q_j + 1/2 n (n-1) z^{n-2} p_j
  804. |#
  805. (define (poly/horner-with-error a z cont)
  806. ;; cont = (lambda (p q r e) ...)
  807. (if (base? a)
  808. a
  809. (let ((arity (poly/arity a))
  810. (az (magnitude z)))
  811. (if (not (fix:= arity 1))
  812. (error "Wrong arity poly -- POLY/HORNER-WITH-ERROR" a z))
  813. (let lp ((degree (poly/degree a))
  814. (p (poly/leading-coefficient a))
  815. (q 0)
  816. (r 0)
  817. (e (* 1/2 (magnitude (poly/leading-coefficient a))))
  818. (a (poly/except-leading-term arity a)) )
  819. (let* ((next-degree (poly/degree a))
  820. (n (if (base? a) degree (fix:- degree next-degree))))
  821. (define (finish np nq nr ne)
  822. (if (base? a)
  823. (cont np nq (* 2 nr)
  824. (* *machine-epsilon* (+ (- ne (magnitude np)) ne)))
  825. (lp next-degree np nq nr ne
  826. (poly/except-leading-term arity a))))
  827. (cond ((fix:= n 1)
  828. (let* ((np (+ (* z p) (poly/leading-coefficient a)))
  829. (nq (+ (* z q) p))
  830. (nr (+ (* z r) q))
  831. (ne (+ (* az e) (magnitude np))))
  832. (finish np nq nr ne)))
  833. ((fix:= n 2)
  834. (let* ((z^n (* z z))
  835. (az^n (magnitude z^n))
  836. (np (+ (* z^n p) (poly/leading-coefficient a)))
  837. (nq (+ (* z^n q) (* 2 (* z p))))
  838. (nr (+ (* z^n r) (* 2 z q) p))
  839. (ne (+ (* az^n (+ e p)) (magnitude np))))
  840. (finish np nq nr ne)))
  841. (else
  842. (let* ((z^n-2 (expt z (fix:- n 2)))
  843. (z^n-1 (* z^n-2 z))
  844. (z^n (* z^n-1 z))
  845. (az^n (magnitude z^n))
  846. (np (+ (* z^n p)
  847. (poly/leading-coefficient a)))
  848. (nq (+ (* z^n q)
  849. (* n (* z^n-1 p))))
  850. (nr (+ (* z^n r)
  851. (* n z^n-1 q)
  852. (* 1/2 n (fix:- n 1) z^n-2 p)))
  853. (ne (+ (* az^n (+ e (* (fix:- n 1) p)))
  854. (magnitude np))))
  855. (finish np nq nr ne)))))))))
  856. ;;; The representations of polynomials may be either sparse or dense.
  857. (define (pcf? p)
  858. (or (base? p)
  859. (explicit-pcf? p)))
  860. (define (explicit-pcf? p)
  861. (and (pair? p)
  862. (or (eq? (car p) '*sparse*)
  863. (eq? (car p) '*dense*))))
  864. (define (poly/type p)
  865. (if (base? p)
  866. '*dense*
  867. (car p)))
  868. (define (poly/arity p)
  869. (if (base? p)
  870. 0
  871. (cadr p)))
  872. (define (poly/termlist p)
  873. (cond ((poly/zero? p) '())
  874. ((base? p) (list p)) ;a dense object
  875. (else (cddr p))))
  876. (define (poly/sparse? p)
  877. (and (pair? p) (eq? (car p) '*sparse*)))
  878. (define (poly/make-from-sparse arity termlist)
  879. (cond ((null? termlist) poly/zero)
  880. ((and (null? (cdr termlist))
  881. (fix:= (caar termlist) 0) ;but degree of a zero is -1!
  882. (base? (cdar termlist)))
  883. (cdar termlist))
  884. (else
  885. (cons '*sparse*
  886. (cons arity termlist)))))
  887. (define (poly/dense? p)
  888. (or (base? p)
  889. (and (pair? p) (eq? (car p) '*dense*))))
  890. (define (poly/make-from-dense arity termlist)
  891. (cond ((null? termlist) poly/zero)
  892. ((and (null? (cdr termlist))
  893. (base? (car termlist)))
  894. (car termlist))
  895. (else
  896. (cons '*dense*
  897. (cons arity termlist)))))
  898. (define poly/make poly/make-from-dense)
  899. (define (poly/degree p)
  900. (case (poly/type p)
  901. ((*sparse*)
  902. (poly/sparse/degree (poly/termlist p)))
  903. ((*dense*)
  904. (poly/dense/degree (poly/termlist p)))
  905. (else
  906. (error "Bad type -- POLY/DEGREE" p))))
  907. (define (poly/leading-coefficient p)
  908. (case (poly/type p)
  909. ((*sparse*)
  910. (poly/sparse/leading-coefficient (poly/termlist p)))
  911. ((*dense*)
  912. (poly/dense/leading-coefficient (poly/termlist p)))
  913. (else
  914. (error "Bad type -- POLY/LEADING-COEFFICIENT" p))))
  915. (define (poly/except-leading-term arity p)
  916. (case (poly/type p)
  917. ((*sparse*)
  918. (poly/make-from-sparse arity
  919. (poly/sparse/except-leading-term (poly/termlist p))))
  920. ((*dense*)
  921. (poly/make-from-dense arity
  922. (poly/dense/except-leading-term (poly/termlist p))))
  923. (else
  924. (error "Bad type -- POLY/EXCEPT-LEADING-TERM" p))))
  925. (define *dense-break-even* 2)
  926. (define (poly/adjoin arity n c p)
  927. ;; n=exponent, c=coefficient, p=polynomial
  928. (case (poly/type p)
  929. ((*sparse*)
  930. (let ((terms (poly/termlist p)))
  931. (if (fix:> (fix:- n (fix:- (length terms) 1))
  932. *dense-break-even*)
  933. (poly/make-from-sparse arity
  934. (poly/sparse/adjoin n c terms))
  935. (poly/make-from-dense arity
  936. (poly/dense/adjoin n c
  937. (sparse->dense terms))))))
  938. ((*dense*)
  939. (let ((terms (poly/termlist p)))
  940. (if (fix:> (fix:- n (fix:- (length terms) 1))
  941. *dense-break-even*)
  942. (poly/make-from-sparse arity
  943. (poly/sparse/adjoin n c
  944. (dense->sparse terms)))
  945. (poly/make-from-dense arity
  946. (poly/dense/adjoin n c terms)))))
  947. (else
  948. (error "Bad type -- POLY/ADJOIN" n c p))))
  949. (define (poly/coefficient p n)
  950. (case (poly/type p)
  951. ((*sparse*)
  952. (poly/sparse/coefficient (poly/termlist p) n))
  953. ((*dense*)
  954. (poly/dense/coefficient (poly/termlist p) n))
  955. (else
  956. (error "Bad type -- POLY/COEFFICIENT" p n))))
  957. (define (poly/coefficients p)
  958. (case (poly/type p)
  959. ((*sparse*)
  960. (poly/sparse/coefficients (poly/termlist p)))
  961. ((*dense*)
  962. (poly/dense/coefficients (poly/termlist p)))
  963. (else
  964. (error "Bad type -- POLY/COEFFICIENTS" p))))
  965. ;;; Returns a sorted numerical set of numbers (see sets.scm)
  966. (define (poly/base-coefficients p)
  967. (let lp ((cs (poly/coefficients p)) (ans (empty-set numbers)))
  968. (cond ((null? cs) ans)
  969. ((base? (car cs))
  970. (lp (cdr cs)
  971. ((adjoin-set numbers) (car cs) ans)))
  972. (else
  973. (lp (cdr cs)
  974. ((union-sets numbers)
  975. (poly/base-coefficients (car cs))
  976. ans))))))
  977. (define (poly/principal-reverse p)
  978. (let ((arity (poly/arity p)))
  979. (case (poly/type p)
  980. ((*sparse*)
  981. (poly/make-from-sparse arity
  982. (poly/sparse/principal-reverse (poly/termlist p))))
  983. ((*dense*)
  984. (poly/make-from-dense arity
  985. (poly/dense/principal-reverse (poly/termlist p))))
  986. (else
  987. (error "Bad type -- POLY/PRINCIPAL-REVERSE" p)))))
  988. (define (poly/->dense p)
  989. (let ((arity (poly/arity p)))
  990. (case (poly/type p)
  991. ((*sparse*)
  992. (poly/make-from-dense arity
  993. (sparse->dense (poly/termlist p))))
  994. ((*dense*) p)
  995. (else
  996. (error "Bad type -- POLY/->DENSE" p)))))
  997. (define (poly/->sparse p)
  998. (let ((arity (poly/arity p)))
  999. (case (poly/type p)
  1000. ((*sparse*) p)
  1001. ((*dense*)
  1002. (poly/make-from-sparse arity
  1003. (dense->sparse (poly/termlist p))))
  1004. (else
  1005. (error "Bad type -- POLY/->DENSE" p)))))
  1006. (define (poly/lowest-order p)
  1007. (cond ((base? p) 0)
  1008. (else
  1009. (case (poly/type p)
  1010. ((*sparse*)
  1011. (poly/sparse/lowest-order (poly/termlist p)))
  1012. ((*dense*)
  1013. (poly/dense/lowest-order (poly/termlist p)))
  1014. (else
  1015. (error "Bad type -- POLY/LOWEST-ORDER" p))))))
  1016. (define (poly/trailing-coefficient p)
  1017. (cond ((base? p) p)
  1018. (else
  1019. (case (poly/type p)
  1020. ((*sparse*)
  1021. (poly/sparse/trailing-coefficient (poly/termlist p)))
  1022. ((*dense*)
  1023. (poly/dense/trailing-coefficient (poly/termlist p)))
  1024. (else
  1025. (error "Bad type -- POLY/TRAILING-COEFFICIENT" p))))))
  1026. ;;; Poly raw representations operate on termlists.
  1027. (define poly/sparse/zero '())
  1028. (define poly/sparse/zero? null?)
  1029. (define poly/sparse/one
  1030. (list (cons 0 base/one)))
  1031. (define poly/sparse/identity
  1032. (list (cons 1 base/one)))
  1033. (define (poly/sparse/degree p)
  1034. (if (null? p) -1 (caar p)))
  1035. (define (poly/sparse/leading-coefficient p)
  1036. (if (null? p) base/zero (cdar p)))
  1037. (define (poly/sparse/except-leading-term p)
  1038. (cdr p))
  1039. (define (poly/sparse/adjoin d c p)
  1040. (cons (cons d c) p))
  1041. (define (poly/sparse/coefficients p)
  1042. (map cdr p))
  1043. (define (poly/sparse/coefficient p d)
  1044. (if (not (and (fix:fixnum? d) (fix:>= d 0)))
  1045. (error ":wrong-type-argument" d "nonnegative fixnum"
  1046. 'POLY/SPARSE/COEFFICIENT))
  1047. (let lp ((terms p))
  1048. (cond ((null? terms) base/zero)
  1049. ((fix:= (caar terms) d) (cdar terms))
  1050. ((fix:< (caar terms) d) base/zero)
  1051. (else (lp (cdr terms))))))
  1052. (define (poly/sparse/principal-reverse p)
  1053. (if (null? p)
  1054. '()
  1055. (let ((degree (caar p)))
  1056. (let loop ((p p) (result '()))
  1057. (if (null? p)
  1058. result
  1059. (loop (cdr p)
  1060. (cons (cons (fix:- degree (caar p)) (cdar p))
  1061. result)))))))
  1062. (define (poly/sparse/lowest-order p)
  1063. (caar (last-pair p)))
  1064. (define (poly/sparse/trailing-coefficient p)
  1065. (cdar (last-pair p)))
  1066. (define poly/dense/zero '())
  1067. (define poly/dense/zero? null?)
  1068. (define poly/dense/one
  1069. (list base/one))
  1070. (define poly/dense/identity
  1071. (list base/one base/zero))
  1072. (define (poly/dense/degree p)
  1073. (fix:- (length p) 1))
  1074. (define (poly/dense/leading-coefficient p)
  1075. (if (null? p) base/zero (car p)))
  1076. (define (poly/dense/except-leading-term p)
  1077. (cond ((null? (cdr p))
  1078. (cdr p))
  1079. ((poly/zero? (cadr p))
  1080. (poly/dense/except-leading-term (cdr p)))
  1081. (else
  1082. (cdr p))))
  1083. (define (poly/dense/adjoin d c p)
  1084. (let ((d* (length p)))
  1085. (cond ((fix:= d d*)
  1086. (cons c p))
  1087. ((fix:> d d*)
  1088. (let loop ((d* (fix:+ d* 1)) (p (cons base/zero p)))
  1089. (if (fix:= d d*)
  1090. (cons c p)
  1091. (loop (fix:+ d* 1) (cons base/zero p)))))
  1092. (else
  1093. (error "Term not in order (POLY/ADJOIN):" d c p)))))
  1094. (define (poly/dense/coefficients p)
  1095. (let loop ((p p))
  1096. (cond ((null? p) '())
  1097. ((poly/zero? (car p)) (loop (cdr p)))
  1098. (else (cons (car p) (loop (cdr p)))))))
  1099. (define (poly/dense/coefficient p d)
  1100. (if (not (and (fix:fixnum? d) (fix:>= d 0)))
  1101. (error ":wrong-type-argument" d "nonnegative fixnum"
  1102. 'POLY/DENSE/COEFFICIENT))
  1103. (list-ref p (fix:- (fix:- (length p) 1) d)))
  1104. (define (poly/dense/principal-reverse p)
  1105. (let loop ((p (reverse p)))
  1106. (if (and (not (null? p))
  1107. (base? (car p))
  1108. (base/zero? (car p)))
  1109. (loop (cdr p))
  1110. p)))
  1111. (define (poly/dense/lowest-order p)
  1112. (let lp ((i 0) (l (reverse p)))
  1113. (cond ((null? l)
  1114. (error "Should not get here -- POLY/DENSE/LOWEST-ORDER" p))
  1115. ((poly/zero? (car l))
  1116. (lp (fix:+ i 1) (cdr l)))
  1117. (else i))))
  1118. (define (poly/dense/trailing-coefficient p)
  1119. (let lp ((i 0) (l (reverse p)))
  1120. (cond ((null? l)
  1121. (error "Should not get here -- POLY/DENSE/TRAILING-COEFFICIENT" p))
  1122. ((poly/zero? (car l))
  1123. (lp (fix:+ i 1) (cdr l)))
  1124. (else (car l)))))
  1125. (define (dense->sparse lst)
  1126. (let lp ((lst lst) (degree (poly/dense/degree lst)))
  1127. (if (null? lst)
  1128. poly/sparse/zero
  1129. (let ((coeff (car lst))
  1130. (terms (cdr lst)))
  1131. (if (and (base? coeff) (base/zero? coeff))
  1132. (lp terms (fix:- degree 1))
  1133. (poly/sparse/adjoin degree
  1134. coeff
  1135. (lp terms (fix:- degree 1))))))))
  1136. (define (sparse->dense lst)
  1137. (if (poly/sparse/zero? lst)
  1138. poly/dense/zero
  1139. (let lp ((lst lst))
  1140. (let ((degree (poly/sparse/degree lst))
  1141. (coeff (poly/sparse/leading-coefficient lst))
  1142. (rest (poly/sparse/except-leading-term lst)))
  1143. (cons coeff
  1144. (if (poly/sparse/zero? rest)
  1145. (make-list degree base/zero)
  1146. (let make-zeros ((degree (fix:- degree 1)))
  1147. (if (fix:= degree (poly/sparse/degree rest))
  1148. (lp rest)
  1149. (cons base/zero
  1150. (make-zeros (fix:- degree 1)))))))))))
  1151. (define poly/identity (poly/make-identity 1))
  1152. ;;; Export stuff happens here:
  1153. (define poly:arity poly/arity)
  1154. (define poly:degree poly/degree)
  1155. (define poly:zero? poly/zero?)
  1156. (define poly:one? poly/one?)
  1157. (define poly:negate poly/negate)
  1158. (define poly:square poly/square)
  1159. (define poly:derivative poly/derivative-principal)
  1160. (define poly:= poly/equal?)
  1161. (define poly:+ poly/add)
  1162. (define poly:- poly/sub)
  1163. (define poly:* poly/mul)
  1164. (define poly:expt poly/expt)
  1165. (define poly:divide poly/div)
  1166. (define poly:pseudo-remainder poly/pseudo-remainder)
  1167. (define poly:quotient poly/quotient)
  1168. (define poly:partial-derivative poly/partial-derivative)
  1169. (define poly:arg-shift poly/arg-shift)
  1170. (define poly:arg-scale poly/arg-scale)
  1171. (define poly:apply poly/horner)
  1172. (define poly:zero poly/zero)
  1173. (define poly:one poly/one)
  1174. (define poly:identity poly/identity)
  1175. (define poly:horners-rule-with-error poly/horner-with-error)
  1176. (define (poly:value p . args) (poly/horner p args))
  1177. (define (poly:principal-value p x) (poly/horner p (list x)))
  1178. (define poly:principal-reverse poly/principal-reverse)
  1179. (define poly:scale poly/scale)
  1180. (define poly:normalize-by poly/normalize)
  1181. (define poly:lowest-order poly/lowest-order)
  1182. (define poly:trailing-coefficient poly/trailing-coefficient)
  1183. (define poly:leading-coefficient poly/leading-coefficient)
  1184. (define poly:except-leading-term poly/except-leading-term)
  1185. (define poly:leading-base-coefficient poly/leading-base-coefficient)
  1186. (define poly:extend poly/extend)
  1187. (define poly:contract poly/contract)
  1188. (define poly:contractable? poly/contractable?)
  1189. (define poly:new-variables poly/make-vars)
  1190. #|
  1191. ;;; Now set in pcf-fpf.scm to work with sparse stuff
  1192. (define (poly:gcd x y) (poly/gcd-memoized x y))
  1193. |#
  1194. ;;; Old style stuff, such as POLY/HERMITE needs polys in reversed
  1195. ;;; dense form.
  1196. (define (poly:dense-> a_0-a_n)
  1197. (poly/make-from-dense 1 (reverse a_0-a_n)))
  1198. (define (poly:->dense poly)
  1199. (let ((p (poly/->dense poly)))
  1200. (if (base? p)
  1201. (list p)
  1202. (reverse (poly/termlist p)))))
  1203. ;;; For simplifier
  1204. (define (pcf:->expression p vars)
  1205. (if (base? p)
  1206. p
  1207. (let ((arity (poly/arity p)))
  1208. (if (not (fix:= arity (length vars)))
  1209. (error "Poly arity not = vars supplied -- PCF:->EXPRESSION"
  1210. p vars))
  1211. (let ((hh (poly/horner-helper symb:+ symb:* symb:expt)))
  1212. (let lp ((p p) (args vars))
  1213. (if (base? p)
  1214. p
  1215. (let ((arity (poly/arity p))
  1216. (nargs (length args)))
  1217. (let ((args (list-tail args (fix:- nargs arity))))
  1218. (hh p (car args)
  1219. (lambda (c)
  1220. (lp c (cdr args))))))))))))
  1221. (define* (pcf:expression-> expr cont #:optional less?)
  1222. ;; cont = (lambda (poly vars) ... )
  1223. (let ((evars
  1224. (sort (list-difference (variables-in expr)
  1225. pcf:operators-known)
  1226. (if (default-object? less?) variable<? less?))))
  1227. (cont ((expression-walker
  1228. (pair-up evars
  1229. (poly:new-variables (length evars))
  1230. pcf:operator-table))
  1231. expr)
  1232. evars)))
  1233. (define (poly:->lambda p)
  1234. (let* ((n (poly/arity p))
  1235. (vars (generate-list-of-symbols 'x n))
  1236. (exp (pcf:->expression p vars)))
  1237. `(lambda ,vars ,exp)))
  1238. (define +$poly
  1239. (accumulation poly/add poly/zero))
  1240. (define -$poly
  1241. (inverse-accumulation poly/sub poly/add poly/negate poly/zero))
  1242. (define *$poly
  1243. (accumulation poly/mul poly/one))
  1244. (define pcf:operator-table
  1245. `((+ ,+$poly)
  1246. (- ,-$poly)
  1247. (* ,*$poly)
  1248. (negate ,poly:negate)
  1249. (expt ,poly:expt)
  1250. (square ,poly:square)
  1251. (gcd ,(lambda (x y) (poly:gcd x y)))))
  1252. (define pcf:operators-known
  1253. (map car pcf:operator-table))