vandermonde.scm 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  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. ;;;; Vandermonde solver, from Zippel, section 13.1
  21. (declare (usual-integrations))
  22. ;;; Simple Vandermonde systems
  23. ;;; Given k_i and w_j to find x_i
  24. ;;; such that Sigma_i (expt k_j i) x_i = w_j
  25. ;;; e.g. x_0 + k_0*x_1 + k_0^2*x_2 + k_0^3*x_3 + ... = w_0
  26. ;;; x_0 + k_1*x_1 + k_1^2*x_2 + k_1^3*x_3 + ... = w_1
  27. ;;; ...
  28. (define (solve-vandermonde-system ks ws succeed fail)
  29. (let ((n (length ws))
  30. (linear-terms
  31. (map (lambda (k) (sparse-linear 1 0 k))
  32. ks)))
  33. (assert (fix:= n (length ks)))
  34. (let ((Q
  35. (fold-left sparse-multiply (sparse-one 1)
  36. linear-terms))
  37. (x (make-vector (length ws) 0)))
  38. (let lp ((i 0))
  39. (if (fix:= i n)
  40. (succeed (vector->list x))
  41. (let ((ki (list-ref ks i))
  42. (x-ki (list-ref linear-terms i))
  43. (except-ki (delete-nth i ks)))
  44. (sparse-divide Q x-ki
  45. (lambda (Qi R)
  46. (assert (null? R))
  47. (let ((d
  48. (sparse-constant-term 1
  49. (roots->poly-value except-ki ki))))
  50. (if (sparse-zero-term? d)
  51. (fail)
  52. (let ((Pi (sparse-normalize Qi d)))
  53. (for-each (lambda (term)
  54. (let ((j (car (sparse-exponents term)))
  55. (c (sparse-coefficient term)))
  56. (vector-set! x j
  57. (+ (* (list-ref ws i) c)
  58. (vector-ref x j)))))
  59. Pi)
  60. (lp (fix:+ i 1)))))))))))))
  61. ;;; Transposed Vandermonde systems
  62. ;;; Given k_i and w_j to find x_i
  63. ;;; such that Sigma_i (expt k_i j) x_i = w_j
  64. ;;; e.g. x_0 + x_1 + x_2 + x_3 + ... = w_0
  65. ;;; k_0*x_0 + k_1*x_1 + k_2*x_2 + k_3*x_3 + ... = w_1
  66. ;;; k_0^2*x_0 + k_1^2*x_1 + k_2^2*x_2 + k_3^2*x_3 + ... = w_2
  67. ;;; ...
  68. (define (solve-vandermonde-t-system ks ws succeed fail)
  69. (let ((n (length ws))
  70. (linear-terms
  71. (map (lambda (k) (sparse-linear 1 0 k))
  72. ks)))
  73. (assert (fix:= n (length ks)))
  74. (let ((Q
  75. (fold-left sparse-multiply (sparse-one 1)
  76. linear-terms))
  77. (x (make-vector (length ws) 0)))
  78. (let lp ((i 0))
  79. (if (fix:= i n)
  80. (succeed (vector->list x))
  81. (let ((ki (list-ref ks i))
  82. (x-ki (list-ref linear-terms i))
  83. (except-ki (delete-nth i ks)))
  84. (sparse-divide Q x-ki
  85. (lambda (Qi R)
  86. (assert (null? R))
  87. (let ((d
  88. (sparse-constant-term 1
  89. (roots->poly-value except-ki ki))))
  90. (if (sparse-zero-term? d)
  91. (fail)
  92. (let ((Pi (sparse-normalize Qi d)))
  93. (for-each (lambda (term)
  94. (let ((j (car (sparse-exponents term)))
  95. (c (sparse-coefficient term)))
  96. (vector-set! x i
  97. (+ (* (list-ref ws j) c)
  98. (vector-ref x i)))))
  99. Pi)
  100. (lp (fix:+ i 1)))))))))))))
  101. ;;; Variant transposed Vandermonde systems
  102. ;;; Given k_i and w_j to find x^i
  103. ;;; such that Sigma_i (expt k_i (+ j 1)) x^i = w^j
  104. ;;; e.g.
  105. ;;; k_0*x_0 + k_1*x_1 + k_2*x_2 + k_3*x_3 + ... = w_0
  106. ;;; k_0^2*x_0 + k_1^2*x_1 + k_2^2*x_2 + k_3^2*x_3 + ... = w_1
  107. ;;; ...
  108. (define (solve-vandermonde-td-system ks ws succeed fail)
  109. (let ((n (length ws))
  110. (linear-terms
  111. (map (lambda (k) (sparse-linear 1 0 k))
  112. ks)))
  113. (assert (fix:= n (length ks)))
  114. (let ((Q
  115. (fold-left sparse-multiply (sparse-one 1)
  116. linear-terms))
  117. (x (make-vector (length ws) 0)))
  118. (let lp ((i 0))
  119. (if (fix:= i n)
  120. (succeed (vector->list x))
  121. (let ((ki (list-ref ks i))
  122. (x-ki (list-ref linear-terms i))
  123. (except-ki (delete-nth i ks)))
  124. (sparse-divide Q x-ki
  125. (lambda (Qi R)
  126. (assert (null? R))
  127. (let ((d
  128. (sparse-constant-term 1
  129. (* ki (roots->poly-value except-ki ki)))))
  130. (if (sparse-zero-term? d)
  131. (fail)
  132. (let ((Pi (sparse-normalize Qi d)))
  133. (for-each (lambda (term)
  134. (let ((j (car (sparse-exponents term)))
  135. (c (sparse-coefficient term)))
  136. (vector-set! x i
  137. (+ (* (list-ref ws j) c)
  138. (vector-ref x i)))))
  139. Pi)
  140. (lp (fix:+ i 1)))))))))))))
  141. (define (roots->poly-value ks z)
  142. (fold-left *
  143. 1
  144. (map (lambda (k)
  145. (- z k))
  146. ks)))
  147. #|
  148. (solve-vandermonde-system '(3 5 7) '(9 11 13)
  149. (lambda (x) x) (lambda () 'foo))
  150. ;Value: (6 1 0)
  151. (solve-vandermonde-t-system '(3 5 7) '(9 11 13)
  152. (lambda (x) x) (lambda () 'foo))
  153. ;Value: (49/2 -23 15/2)
  154. (solve-vandermonde-td-system '(3 5 7) '(9 11 13)
  155. (lambda (x) x) (lambda () 'foo))
  156. ;Value: (49/6 -23/5 15/14)
  157. (solve-vandermonde-td-system '(3 5 0) '(9 11 13)
  158. (lambda (x) x) (lambda () 'foo))
  159. ;Value: foo
  160. |#