numeric.scm 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  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. ;;;; Extensions to Scheme numbers
  21. (declare (usual-integrations))
  22. ;;; Everybody wants to know about these.
  23. (define zero 0)
  24. (define one 1)
  25. (define -one -1)
  26. (define two 2)
  27. (define three 3)
  28. (define pi (* 4 (atan 1 1)))
  29. (define -pi (- pi))
  30. (define pi/6 (/ pi 6))
  31. (define -pi/6 (- pi/6))
  32. (define pi/4 (/ pi 4))
  33. (define -pi/4 (- pi/4))
  34. (define pi/3 (/ pi 3))
  35. (define -pi/3 (- pi/3))
  36. (define pi/2 (/ pi 2))
  37. (define -pi/2 (- pi/2))
  38. (define 2pi (+ pi pi))
  39. (define -2pi (- 2pi))
  40. (define :zero zero)
  41. (define :one one)
  42. (define :-one -one)
  43. (define :two two)
  44. (define :three three)
  45. (define :pi pi)
  46. (define :+pi pi)
  47. (define :-pi -pi)
  48. (define :pi/6 pi/6)
  49. (define :+pi/6 pi/6)
  50. (define :-pi/6 -pi/6)
  51. (define :pi/4 pi/4)
  52. (define :+pi/4 pi/4)
  53. (define :-pi/4 -pi/4)
  54. (define :pi/3 pi/3)
  55. (define :+pi/3 pi/3)
  56. (define :-pi/3 -pi/3)
  57. (define :pi/2 pi/2)
  58. (define :+pi/2 pi/2)
  59. (define :-pi/2 -pi/2)
  60. (define :2pi 2pi)
  61. (define :+2pi 2pi)
  62. (define :-2pi -2pi)
  63. (define *machine-epsilon*
  64. (let loop ((e 1.0))
  65. (if (= 1.0 (+ e 1.0))
  66. (* 2 e)
  67. (loop (/ e 2)))))
  68. (define *sqrt-machine-epsilon*
  69. (sqrt *machine-epsilon*))
  70. (define :euler 0.57721566490153286)
  71. (define :phi (/ (+ 1 (sqrt 5)) 2))
  72. (define (exact-zero? x)
  73. (and (number? x) (exact? x) (= x 0)))
  74. (define (exact-one? x)
  75. (and (number? x) (exact? x) (= x 1)))
  76. (define :ln2 (log 2.0))
  77. (define :ln10 (log 10.0))
  78. (define (log10 x)
  79. (/ (log x) :ln10))
  80. (define (log2 x)
  81. (/ (log x) :ln2))
  82. (define (exp10 x)
  83. (expt 10 x))
  84. (define (exp2 x)
  85. (expt 2 x))
  86. (define :minlog -1000.0)
  87. (define (safelog x)
  88. (if (and (real? x) (> x 0))
  89. (max (log x) :minlog)
  90. (error "Out of range -- SAFELOG" x)))
  91. (define (principal-value cuthigh)
  92. (let ((cutlow (- cuthigh :+2pi)))
  93. (define (the-principal-value x)
  94. (if (and (<= cutlow x) (< x cuthigh))
  95. x
  96. (let ((y (- x (* :+2pi (floor (/ x :+2pi))))))
  97. (if (< y cuthigh)
  98. y
  99. (- y :+2pi)))))
  100. the-principal-value))
  101. (define (principal-value-minus-pi-to-pi x)
  102. (if (or (<= x -pi) (> x +pi))
  103. (let ((y (- x (* +2pi (floor (/ x 2pi))))))
  104. (if (< y +pi)
  105. y
  106. (- y +2pi)))
  107. x))
  108. (define (principal-value-zero-to-2pi x)
  109. (if (or (< x 0.0) (>= x +2pi))
  110. (- x (* +2pi (floor (/ x +2pi))))
  111. x))
  112. (define* ((principal-range period) index)
  113. (let ((t (- index (* period (floor (/ index period))))))
  114. (if (< t (/ period 2.))
  115. t
  116. (- t period))))
  117. (define (one? x) (= x 1)) ; Exactness?
  118. (define (square x) (* x x))
  119. (define (cube x) (* x x x))
  120. (define (negate x) (- x))
  121. (define (invert x) (/ x))
  122. (define (cot x)
  123. (/ 1 (tan x)))
  124. (define (sec x)
  125. (/ 1 (cos x)))
  126. (define (csc x)
  127. (/ 1 (sin x)))
  128. (define (sinh x)
  129. (/ (- (exp x) (exp (- x))) 2))
  130. (define (cosh x)
  131. (/ (+ (exp x) (exp (- x))) 2))
  132. (define (tanh x)
  133. (/ (sinh x) (cosh x)))
  134. (define (sech x)
  135. (/ 1 (cosh x)))
  136. (define (csch x)
  137. (/ 1 (sinh x)))
  138. (define (factorial n)
  139. (define (f n)
  140. (if (= n 0)
  141. 1
  142. (* n (f (- n 1)))))
  143. (assert (and (exact-integer? n) (not (negative? n))))
  144. (f n))
  145. (define (exact-quotient n d)
  146. (let ((qr (integer-divide n d)))
  147. (assert (= 0 (integer-divide-remainder qr)))
  148. (integer-divide-quotient qr)))
  149. (define (binomial-coefficient n m)
  150. (assert (and (exact-integer? n) (exact-integer? m) (<= 0 m n)))
  151. (let ((d (- n m)))
  152. (let ((t (max m d)) (s (min m d)))
  153. (define (lp count prod)
  154. (if (= count t)
  155. (exact-quotient prod (factorial s))
  156. (lp (- count 1) (* count prod))))
  157. (lp n 1))))
  158. (define (stirling-first-kind n k)
  159. ;; (assert (and (int:<= 1 k) (int:<= k n))) ; FBE
  160. (define lp
  161. (linear-memoize
  162. (lambda (n k)
  163. (cond ((int:= n 0)
  164. (if (int:= k 0) 1 0))
  165. (else
  166. (let ((np (int:- n 1)))
  167. (int:+ (lp np (int:- k 1))
  168. (int:* np
  169. (lp np k)))))))
  170. 0))
  171. (lp n k))
  172. #|
  173. (stirling-first-kind 1 1)
  174. ;Value: 1
  175. (stirling-first-kind 2 1)
  176. ;Value: 1
  177. (stirling-first-kind 2 2)
  178. ;Value: 1
  179. (stirling-first-kind 3 1)
  180. ;Value: 2
  181. (stirling-first-kind 3 2)
  182. ;Value: 3
  183. (stirling-first-kind 5 2)
  184. ;Value: 50
  185. (stirling-first-kind 7 3)
  186. ;Value: 1624
  187. |#
  188. (define (stirling-second-kind n k)
  189. ;; (assert (and (int:<= 1 k) (int:<= k n))) ; FBE
  190. (define lp
  191. (linear-memoize
  192. (lambda (n k)
  193. (cond ((int:= k 1) 1)
  194. ((int:= n k) 1)
  195. (else
  196. (let ((np (int:- n 1)))
  197. (int:+ (* k (lp np k))
  198. (lp np (int:- k 1)))))))
  199. 0))
  200. (lp n k))
  201. #|
  202. (stirling-second-kind 5 3)
  203. ;Value: 25
  204. |#
  205. (define (close-enuf? h1 h2 tolerance)
  206. (<= (magnitude (- h1 h2))
  207. (* .5 (max tolerance *machine-epsilon*)
  208. (+ (magnitude h1) (magnitude h2) 2.0))))
  209. #|
  210. ;;; When really paranoid, put in a scale factor
  211. (define (close-enuf? h1 h2 #!optional tolerance scale)
  212. (if (default-object? tolerance)
  213. (set! tolerance *machine-epsilon*))
  214. (if (default-object? scale)
  215. (set! scale 1.0))
  216. (<= (magnitude (- h1 h2))
  217. (* tolerance
  218. (+ (* 0.5
  219. (+ (magnitude h1) (magnitude h2)))
  220. scale))))
  221. |#
  222. #|
  223. ;;; See below for the reason for using
  224. ;;; the more complex addition formula.
  225. (define (sigma f low high)
  226. (let lp ((i low) (sum 0))
  227. (if (fix:> i high)
  228. sum
  229. (lp (fix:+ i 1) (+ sum (f i))))))
  230. |#
  231. (define (sigma f low high)
  232. (let lp ((i low) (sum 0) (c 0))
  233. (if (fix:> i high)
  234. sum
  235. (let* ((y (- (f i) c)) (t (+ sum y)))
  236. (lp (fix:+ i 1) t (- (- t sum) y))))))
  237. #|
  238. ;;; When adding up 1/n large-to-small we
  239. ;;; get a different answer than when adding
  240. ;;; them up small-to-large, which is more
  241. ;;; accurate.
  242. (let lp ((i 1) (sum 0.0))
  243. (if (> i 10000000)
  244. sum
  245. (lp (+ i 1) (+ sum (/ 1.0 i)))))
  246. ;Value: 16.695311365857272
  247. (let lp ((i 10000000) (sum 0.0))
  248. (if (= i 0)
  249. sum
  250. (lp (- i 1) (+ sum (/ 1.0 i)))))
  251. ;Value: 16.695311365859965
  252. (- 16.695311365859965 16.695311365857272)
  253. ;Value: 2.6929569685307797e-12
  254. ;;; Traditional sigma is the inaccurate way.
  255. (sigma (lambda (x) (/ 1.0 x)) 1 10000000)
  256. ;Value: 16.695311365857272
  257. ;;; Kahan's compensated summation formula is
  258. ;;; much better, but slower...
  259. (define (sigma-kahan f low high)
  260. (let lp ((i low) (sum 0) (c 0))
  261. (if (fix:> i high)
  262. sum
  263. (let* ((y (- (f i) c)) (t (+ sum y)))
  264. (lp (fix:+ i 1) t (- (- t sum) y))))))
  265. ;Value: sigma-kahan
  266. (sigma-kahan (lambda (x) (/ 1.0 x)) 1 10000000)
  267. ;Value: 16.69531136585985
  268. (- 16.695311365859965 16.69531136585985)
  269. ;Value: 1.1368683772161603e-13
  270. |#
  271. #|
  272. ;;; Harmonic numbers
  273. (define (Hn n)
  274. (/ (stirling-first-kind (+ n 1) 2)
  275. (factorial n)))
  276. (exact->inexact (Hn 300))
  277. ;Value: 6.282663880299504
  278. (let lp ((i 1) (sum 0.0))
  279. (if (> i 300)
  280. sum
  281. (lp (+ i 1) (+ sum (/ 1.0 i)))))
  282. ;Value: 6.282663880299502
  283. (let lp ((i 300) (sum 0.0))
  284. (if (= i 0)
  285. sum
  286. (lp (- i 1) (+ sum (/ 1.0 i)))))
  287. ;Value: 6.282663880299501
  288. (sigma (lambda (x) (/ 1.0 x)) 1 300)
  289. ;Value: 6.282663880299502
  290. |#
  291. #|
  292. (define (geometric a r n)
  293. (define (sigma-kahan f low high)
  294. (let lp ((i low) (sum 0) (c 0))
  295. (if (fix:> i high)
  296. sum
  297. (let* ((y (- (f i) c)) (t (+ sum y)))
  298. (lp (fix:+ i 1) t (- (- t sum) y))))))
  299. (let lp> ((k 0) (sum 0.0))
  300. (if (> k n)
  301. (write-line `(forward-order ,sum))
  302. (lp> (+ k 1) (+ sum (* a (expt r k))))))
  303. (write-line
  304. `(g:sigma
  305. ,(g:sigma ;generic sigma is naive
  306. (lambda (k)
  307. (exact->inexact (* a (expt r k))))
  308. 0 n)))
  309. (let lp< ((k n) (sum 0.0))
  310. (if (< k 0)
  311. (write-line `(reverse-order ,sum))
  312. (lp< (- k 1) (+ sum (* a (expt r k))))))
  313. (write-line
  314. `(kahan-method
  315. ,(sigma-kahan
  316. (lambda (k)
  317. (exact->inexact (* a (expt r k))))
  318. 0 n)))
  319. (write-line
  320. `(explicit-formula
  321. ,(exact->inexact (/ (* a (- 1 (expt r (+ n 1))))
  322. (- 1 r)))))
  323. 'done)
  324. (geometric 1 0.5001 200)
  325. (forward-order 2.0004000800160022)
  326. (g:sigma 2.0004000800160022)
  327. (reverse-order 2.000400080016003)
  328. (kahan-method 2.000400080016003)
  329. (explicit-formula 2.000400080016003)
  330. ;Value: done
  331. |#
  332. ;;; The following is arbitrary, but chosen to make Euclid's algorithm
  333. ;;; for polynomials over the rationals (defined with pseudo-division)
  334. ;;; have only small fractions.
  335. ;;; FBE
  336. ;; (define make-rational
  337. ;; (access make-rational (->environment '(runtime number))))
  338. #| Wrong
  339. (define (gcd-rational p/q r/s)
  340. (make-rational (gcd (numerator p/q) (numerator r/s))
  341. (lcm (denominator p/q) (denominator r/s))))
  342. |#
  343. (define (gcd-rational p/q r/s)
  344. (gcd (numerator p/q) (numerator r/s)))
  345. ;;; Euclid's algorithm for Exact Complex Numbers
  346. ;;; suggested by William Throwe, to allow simplification
  347. ;;; of rational functions with complex coefficients.
  348. (define (round-complex z)
  349. (make-rectangular (round (real-part z))
  350. (round (imag-part z))))
  351. (define (gcd-complex a b)
  352. (cond ((zero? a) b)
  353. ((zero? b) a)
  354. (else
  355. (let ((q (round-complex (/ a b))))
  356. (gcd-complex b (- a (* q b)))))))
  357. (define (exact-complex? x)
  358. (and (number? x) (exact? x)))
  359. (define (scheme-number-gcd x y)
  360. (cond ((or (inexact? x) (inexact? y)) 1)
  361. ((and (exact-integer? x) (exact-integer? y))
  362. (gcd x y))
  363. ((and (exact-rational? x) (exact-rational? y))
  364. (gcd-rational x y))
  365. ((and (exact-complex? x) (exact-complex? y))
  366. (gcd-complex x y))
  367. (else 1)))
  368. (define *no-rationals-in-divide* #f)
  369. (define (scheme-number-divide n d c)
  370. (if (and *no-rationals-in-divide*
  371. (exact-integer? n)
  372. (exact-integer? d))
  373. (let ((qr (integer-divide n d)))
  374. (c (integer-divide-quotient qr)
  375. (integer-divide-remainder qr)))
  376. (c (/ n d) 0)))
  377. (define (sgn x)
  378. (if (real? x)
  379. (if (negative? x) -1 +1)
  380. ;; This is a kludge, needed so that rational
  381. ;; functions can be canonicalized, even if
  382. ;; coefficients are complex.
  383. (if (negative? (real-part x)) -1 +1)))
  384. ;;; From Hamming, gives roots of quadratic without bad roundoff.
  385. ;;; a*x^2 + b*x + c = 0
  386. (define* (quadratic a b c
  387. ;; continuations for each case
  388. two-roots
  389. #:optional
  390. complex-roots
  391. double-root
  392. linear
  393. no-solution)
  394. (if (zero? a)
  395. (if (zero? b)
  396. (if (default-object? no-solution)
  397. (error "No solution -- QUADRATIC" a b c)
  398. (no-solution a b c))
  399. (if (default-object? linear)
  400. (error "Not QUADRATIC" a b c)
  401. (linear (/ (- c) b))))
  402. (let ((d (- (* b b) (* 4 a c))))
  403. (if (zero? d)
  404. (let ((root (/ b (* -2 a))))
  405. (if (default-object? double-root)
  406. (two-roots root root)
  407. (double-root root)))
  408. (let ((q (* -1/2 (+ b (* (sgn b) (sqrt d))))))
  409. (let ((r1 (/ q a)) (r2 (/ c q)))
  410. (if (or (> d 0)
  411. (default-object? complex-roots))
  412. (two-roots r1 r2)
  413. (complex-roots r1 r2))))))))
  414. ;;; From Numerical Recipes... for real coefficients
  415. ;;; x^3 + a*x^2 + b*x + c = 0
  416. (define (cubic a b c cont)
  417. (let ((q (/ (- (square a) (* 3 b)) 9))
  418. (r (/ (+ (* 2 (cube a)) (* -9 a b) (* 27 c)) 54)))
  419. (let ((aa
  420. (* -1
  421. (sgn r)
  422. (expt (+ (abs r)
  423. (sqrt (- (square r) (cube q))))
  424. 1/3))))
  425. (let ((bb (if (zero? aa) 0 (/ q aa))))
  426. (let ((u (+ aa bb))
  427. (v (* -1/3 a))
  428. (w (* (/ (sqrt 3) 2) (- aa bb))))
  429. (cont (+ u v)
  430. (+ (* -1/2 u) v (* +i w))
  431. (+ (* -1/2 u) v (* -i w))))))))