(define (partly-apply-general hf nums dens) (let ((a (first hf)) (b (second hf)) (c (third hf)) (d (fourth hf))) (if (empty-stream? nums) (values (list a a c c) nums dens) (let ((num (head nums)) (den (head dens))) (values (list (+ (* a den) (* b num)) a (+ (* c den) (* d num)) c) (tail nums) (tail dens)))))) (define (print-hf-general hf nums dens) (call-with-values (lambda () (partly-evaluate hf)) (lambda (term hf*) (if (not term) (call-with-values (lambda () (partly-apply-general hf nums dens)) print-hf-general) (begin (display term) ;; take reciprocal and multiply by 10 (let ((a (first hf*)) (b (second hf*)) (c (third hf*)) (d (fourth hf*))) (print-hf-general (list (* c 10) (* d 10) a b) nums dens)))))))For example, we can compute pi from this generalized continued fraction:
(print-hf-general (list 0 4 1 0) ;; [1 1 4 9 16 25 ...] (cons-stream 1 (let squares ((i 1)) (cons-stream (* i i) (squares (1+ i))))) ;; [1 3 5 7 9 11 ...] (let odds ((j 1)) (cons-stream j (odds (+ j 2))))) 314159265358979323846264338327950^G ; Quit!A bi-homographic function is a function of the form:
(define (bi-homographic a b c d e f g h) (lambda (x y) (/ (+ (* a x y) (* b x) (* c y) d) (+ (* e x y) (* f x) (* g y) h))))Like a homographic function, you can partly evaluate a bi-homographic function and generate a continued fraction. You can also partly apply a bi-homographic function to a pair of continued fractions. When you do this, you have a choice of which continued fraction to be the object of the partial application. There's about twice as much nasty math involved, but the gist is that a bi-homographic function takes two continued fractions as arguments and produces one continued fraction as a result.
It turns out that addition, subtraction, multiplication and division are bi-homographic functions, so one can incrementally compute sums and products of continued fractions.