/benchmarks.larceny/src/simplex.scm

https://github.com/ih/ikarus.dev · Scheme · 188 lines · 181 code · 5 blank · 2 comment · 0 complexity · fc4eadf80466315dd1e2bb4be544adcd MD5 · raw file

  1. ;;; SIMPLEX -- Simplex algorithm.
  2. (define (matrix-rows a) (vector-length a))
  3. (define (matrix-columns a) (FLOATvector-length (vector-ref a 0)))
  4. (define (matrix-ref a i j) (FLOATvector-ref (vector-ref a i) j))
  5. (define (matrix-set! a i j x) (FLOATvector-set! (vector-ref a i) j x))
  6. (define (fuck-up)
  7. (fatal-error "This shouldn't happen"))
  8. (define (simplex a m1 m2 m3)
  9. (define *epsilon* 1e-6)
  10. ;(define *epsilon* 0.000001)
  11. (if (not (and (>= m1 0)
  12. (>= m2 0)
  13. (>= m3 0)
  14. (= (matrix-rows a) (+ m1 m2 m3 2))))
  15. (fuck-up))
  16. (let* ((m12 (+ m1 m2 1))
  17. (m (- (matrix-rows a) 2))
  18. (n (- (matrix-columns a) 1))
  19. (l1 (make-vector n))
  20. (l2 (make-vector m))
  21. (l3 (make-vector m2))
  22. (nl1 n)
  23. (iposv (make-vector m))
  24. (izrov (make-vector n))
  25. (ip 0)
  26. (kp 0)
  27. (bmax 0.0)
  28. (one? #f)
  29. (pass2? #t))
  30. (define (simp1 mm abs?)
  31. (set! kp (vector-ref l1 0))
  32. (set! bmax (matrix-ref a mm kp))
  33. (do ((k 1 (+ k 1))) ((>= k nl1))
  34. (if (FLOATpositive?
  35. (if abs?
  36. (FLOAT- (FLOATabs (matrix-ref a mm (vector-ref l1 k)))
  37. (FLOATabs bmax))
  38. (FLOAT- (matrix-ref a mm (vector-ref l1 k)) bmax)))
  39. (begin
  40. (set! kp (vector-ref l1 k))
  41. (set! bmax (matrix-ref a mm (vector-ref l1 k)))))))
  42. (define (simp2)
  43. (set! ip 0)
  44. (let ((q1 0.0)
  45. (flag? #f))
  46. (do ((i 0 (+ i 1))) ((= i m))
  47. (if flag?
  48. (if (FLOAT< (matrix-ref a (vector-ref l2 i) kp) (FLOAT- *epsilon*))
  49. (begin
  50. (let ((q (FLOAT/ (FLOAT- (matrix-ref a (vector-ref l2 i) 0))
  51. (matrix-ref a (vector-ref l2 i) kp))))
  52. (cond
  53. ((FLOAT< q q1)
  54. (set! ip (vector-ref l2 i))
  55. (set! q1 q))
  56. ((FLOAT= q q1)
  57. (let ((qp 0.0)
  58. (q0 0.0))
  59. (let loop ((k 1))
  60. (if (<= k n)
  61. (begin
  62. (set! qp (FLOAT/ (FLOAT- (matrix-ref a ip k))
  63. (matrix-ref a ip kp)))
  64. (set! q0 (FLOAT/ (FLOAT-
  65. (matrix-ref a (vector-ref l2 i) k))
  66. (matrix-ref a (vector-ref l2 i) kp)))
  67. (if (FLOAT= q0 qp)
  68. (loop (+ k 1))))))
  69. (if (FLOAT< q0 qp)
  70. (set! ip (vector-ref l2 i)))))))))
  71. (if (FLOAT< (matrix-ref a (vector-ref l2 i) kp) (FLOAT- *epsilon*))
  72. (begin
  73. (set! q1 (FLOAT/ (FLOAT- (matrix-ref a (vector-ref l2 i) 0))
  74. (matrix-ref a (vector-ref l2 i) kp)))
  75. (set! ip (vector-ref l2 i))
  76. (set! flag? #t)))))))
  77. (define (simp3 one?)
  78. (let ((piv (FLOAT/ (matrix-ref a ip kp))))
  79. (do ((ii 0 (+ ii 1))) ((= ii (+ m (if one? 2 1))))
  80. (if (not (= ii ip))
  81. (begin
  82. (matrix-set! a ii kp (FLOAT* piv (matrix-ref a ii kp)))
  83. (do ((kk 0 (+ kk 1))) ((= kk (+ n 1)))
  84. (if (not (= kk kp))
  85. (matrix-set! a ii kk (FLOAT- (matrix-ref a ii kk)
  86. (FLOAT* (matrix-ref a ip kk)
  87. (matrix-ref a ii kp)))))))))
  88. (do ((kk 0 (+ kk 1))) ((= kk (+ n 1)))
  89. (if (not (= kk kp))
  90. (matrix-set! a ip kk (FLOAT* (FLOAT- piv) (matrix-ref a ip kk)))))
  91. (matrix-set! a ip kp piv)))
  92. (do ((k 0 (+ k 1))) ((= k n))
  93. (vector-set! l1 k (+ k 1))
  94. (vector-set! izrov k k))
  95. (do ((i 0 (+ i 1))) ((= i m))
  96. (if (FLOATnegative? (matrix-ref a (+ i 1) 0))
  97. (fuck-up))
  98. (vector-set! l2 i (+ i 1))
  99. (vector-set! iposv i (+ n i)))
  100. (do ((i 0 (+ i 1))) ((= i m2)) (vector-set! l3 i #t))
  101. (if (positive? (+ m2 m3))
  102. (begin
  103. (do ((k 0 (+ k 1))) ((= k (+ n 1)))
  104. (do ((i (+ m1 1) (+ i 1)) (sum 0.0 (FLOAT+ sum (matrix-ref a i k))))
  105. ((> i m) (matrix-set! a (+ m 1) k (FLOAT- sum)))))
  106. (let loop ()
  107. (simp1 (+ m 1) #f)
  108. (cond
  109. ((FLOAT<= bmax *epsilon*)
  110. (cond ((FLOAT< (matrix-ref a (+ m 1) 0) (FLOAT- *epsilon*))
  111. (set! pass2? #f))
  112. ((FLOAT<= (matrix-ref a (+ m 1) 0) *epsilon*)
  113. (let loop ((ip1 m12))
  114. (if (<= ip1 m)
  115. (cond ((= (vector-ref iposv (- ip1 1)) (+ ip n -1))
  116. (simp1 ip1 #t)
  117. (cond ((FLOATpositive? bmax)
  118. (set! ip ip1)
  119. (set! one? #t))
  120. (else
  121. (loop (+ ip1 1)))))
  122. (else
  123. (loop (+ ip1 1))))
  124. (do ((i (+ m1 1) (+ i 1))) ((>= i m12))
  125. (if (vector-ref l3 (- i (+ m1 1)))
  126. (do ((k 0 (+ k 1))) ((= k (+ n 1)))
  127. (matrix-set! a i k (FLOAT- (matrix-ref a i k)))))))))
  128. (else (simp2) (if (zero? ip) (set! pass2? #f) (set! one? #t)))))
  129. (else (simp2) (if (zero? ip) (set! pass2? #f) (set! one? #t))))
  130. (if one?
  131. (begin
  132. (set! one? #f)
  133. (simp3 #t)
  134. (cond
  135. ((>= (vector-ref iposv (- ip 1)) (+ n m12 -1))
  136. (let loop ((k 0))
  137. (cond
  138. ((and (< k nl1) (not (= kp (vector-ref l1 k))))
  139. (loop (+ k 1)))
  140. (else
  141. (set! nl1 (- nl1 1))
  142. (do ((is k (+ is 1))) ((>= is nl1))
  143. (vector-set! l1 is (vector-ref l1 (+ is 1))))
  144. (matrix-set! a (+ m 1) kp (FLOAT+ (matrix-ref a (+ m 1) kp) 1.0))
  145. (do ((i 0 (+ i 1))) ((= i (+ m 2)))
  146. (matrix-set! a i kp (FLOAT- (matrix-ref a i kp))))))))
  147. ((and (>= (vector-ref iposv (- ip 1)) (+ n m1))
  148. (vector-ref l3 (- (vector-ref iposv (- ip 1)) (+ m1 n))))
  149. (vector-set! l3 (- (vector-ref iposv (- ip 1)) (+ m1 n)) #f)
  150. (matrix-set! a (+ m 1) kp (FLOAT+ (matrix-ref a (+ m 1) kp) 1.0))
  151. (do ((i 0 (+ i 1))) ((= i (+ m 2)))
  152. (matrix-set! a i kp (FLOAT- (matrix-ref a i kp))))))
  153. (let ((t (vector-ref izrov (- kp 1))))
  154. (vector-set! izrov (- kp 1) (vector-ref iposv (- ip 1)))
  155. (vector-set! iposv (- ip 1) t))
  156. (loop))))))
  157. (and pass2?
  158. (let loop ()
  159. (simp1 0 #f)
  160. (cond
  161. ((FLOATpositive? bmax)
  162. (simp2)
  163. (cond ((zero? ip) #t)
  164. (else (simp3 #f)
  165. (let ((t (vector-ref izrov (- kp 1))))
  166. (vector-set! izrov (- kp 1) (vector-ref iposv (- ip 1)))
  167. (vector-set! iposv (- ip 1) t))
  168. (loop))))
  169. (else (list iposv izrov)))))))
  170. (define (test)
  171. (simplex (vector (FLOATvector 0.0 1.0 1.0 3.0 -0.5)
  172. (FLOATvector 740.0 -1.0 0.0 -2.0 0.0)
  173. (FLOATvector 0.0 0.0 -2.0 0.0 7.0)
  174. (FLOATvector 0.5 0.0 -1.0 1.0 -2.0)
  175. (FLOATvector 9.0 -1.0 -1.0 -1.0 -1.0)
  176. (FLOATvector 0.0 0.0 0.0 0.0 0.0))
  177. 2 1 1))
  178. (define (main . args)
  179. (run-benchmark
  180. "simplex"
  181. simplex-iters
  182. (lambda (result) (equal? result '(#(4 1 3 2) #(0 5 7 6))))
  183. (lambda () (lambda () (test)))))