
(defun arithmetic-geometric-mean (a b)
  (values (/ (+ a b) 2)
          (sqrt (* a b))))

(defun converge (epsilon fun a b)
  (loop
    :while (< epsilon (abs (- a b)))
    :do (multiple-value-setq (a b) (funcall fun a b))
    :finally (return (values a b))))

(format t ";; --> ~{~S~^~%;;     ~}~%" (multiple-value-list
(converge 1d-15
          (lambda (a b)
            (format t ";; ~24,21F ~24,21F~%" a b)
            (arithmetic-geometric-mean a b))
          24d0 6d0)
))


(defun geothmetic-meandian (set)
  (sort (vector (/ (reduce (function +) set :initial-value 0.0d0)
                   (length set))
                (expt (reduce (function *) set  :initial-value 1.0d0)
                      (/ (length set)))
                (aref set (truncate (length set) 2)))
        (function <)))

(defun converge-set (epsilon fun set)
  ;; set is sorted.
  (loop
    :while (< epsilon (abs (- (aref set 0) (aref set (1- (length set))))))
    :do (setf set (funcall fun set))
    :finally (return set)))
    
(format t ";; --> ~{~S~^~%;;     ~}~%" (multiple-value-list
(converge-set
  1d-3
  (lambda (set)
    (format t ";;~{ ~24,21F~}~%" (coerce set 'list))
    (geothmetic-meandian set))
  #(1 1 2 3 5))
))