scan for appropriate 2nd element to take the mean with when calling vector-find-median on an even length vector (issue #754)

This commit is contained in:
Alex Shinn 2021-06-29 21:09:41 +09:00
parent f3bccf1f7b
commit 73da0a88d4
2 changed files with 16 additions and 4 deletions

View file

@ -158,6 +158,14 @@
((odd? len) (vector-ref vec mid)) ((odd? len) (vector-ref vec mid))
(else (mean (vector-ref vec (- mid 1)) (vector-ref vec mid)))))) (else (mean (vector-ref vec (- mid 1)) (vector-ref vec mid))))))
(define (vector-max less vec lo hi largest)
(cond
((>= lo hi) largest)
((less largest (vector-ref vec lo))
(vector-max less vec (+ lo 1) hi (vector-ref vec lo)))
(else
(vector-max less vec (+ lo 1) hi largest))))
(define (vector-find-median < vec knil . o) (define (vector-find-median < vec knil . o)
(let* ((vec (vector-copy vec)) (let* ((vec (vector-copy vec))
(len (vector-length vec)) (len (vector-length vec))
@ -166,7 +174,9 @@
(cond (cond
((zero? len) knil) ((zero? len) knil)
(else (else
(vector-separate! < vec mid) (let ((mid-elt (vector-select! < vec mid)))
(cond (cond
((odd? len) (vector-ref vec mid)) ((odd? len) mid-elt)
(else (mean (vector-ref vec (- mid 1)) (vector-ref vec mid)))))))) (else
(mean (vector-max < vec 0 (- mid 1) (vector-ref vec (- mid 1)))
mid-elt))))))))

View file

@ -683,4 +683,6 @@
(test 21 (test 21
(let ((v (vector 8 22 19 19 13 9 21 13 3 23))) (let ((v (vector 8 22 19 19 13 9 21 13 3 23)))
(vector-select! < v 3 4 8))) (vector-select! < v 3 4 8)))
(test 17.0
(vector-find-median < '#(18. 11. 20. 15. 16. 9. 24. 15. 21. 20.) 0))
(test-end)))) (test-end))))