How to resolve the algorithm Continued fraction/Arithmetic/G(matrix ng, continued fraction n1, continued fraction n2) step by step in the Scheme programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Continued fraction/Arithmetic/G(matrix ng, continued fraction n1, continued fraction n2) step by step in the Scheme programming language

Table of Contents

Problem Statement

This task performs the basic mathematical functions on 2 continued fractions. This requires the full version of matrix NG: I may perform perform the following operations: I output a term if the integer parts of

a b

{\displaystyle {\frac {a}{b}}}

and

a

1

b

1

{\displaystyle {\frac {a_{1}}{b_{1}}}}

and

a

2

b

2

{\displaystyle {\frac {a_{2}}{b_{2}}}}

and

a

12

b

12

{\displaystyle {\frac {a_{12}}{b_{12}}}}

are equal. Otherwise I input a term from continued fraction N1 or continued fraction N2. If I need a term from N but N has no more terms I inject

{\displaystyle \infty }

. When I input a term t from continued fraction N1 I change my internal state: When I need a term from exhausted continued fraction N1 I change my internal state: When I input a term t from continued fraction N2 I change my internal state: When I need a term from exhausted continued fraction N2 I change my internal state: When I output a term t I change my internal state: When I need to choose to input from N1 or N2 I act: When performing arithmetic operation on two potentially infinite continued fractions it is possible to generate a rational number. eg

2

{\displaystyle {\sqrt {2}}}

2

{\displaystyle {\sqrt {2}}}

should produce 2. This will require either that I determine that my internal state is approaching infinity, or limiting the number of terms I am willing to input without producing any output.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Continued fraction/Arithmetic/G(matrix ng, continued fraction n1, continued fraction n2) step by step in the Scheme programming language

Source code in the scheme programming language

(cond-expand
  (r7rs)
  (chicken (import (r7rs))))

;;;-------------------------------------------------------------------

(define-library (cf)

  (export make-cf
          cf?
          *cf-max-terms*
          cf->string
          number->cf
          ng8->procedure)

  (import (scheme base)
          (scheme case-lambda))

  (begin

    (define-record-type <cf>
      (%%make-cf terminated? ;; No more terms?
                 m           ;; No. of terms memoized.
                 memo        ;; Memoized terms.
                 gen)        ;; Term-generating thunk.
      cf?
      (terminated? cf-terminated? set-cf-terminated?!)
      (m cf-m set-cf-m!)
      (memo cf-memo set-cf-memo!)
      (gen cf-gen set-cf-gen!))

    (define (make-cf gen)             ; Make a new continued fraction.
      (%%make-cf #f 0 (make-vector 32) gen))

    (define (cf-ref cf i)  ; Get the ith term, or #f if there is none.
      (define (get-more-terms! needed)
        (do () ((or (cf-terminated? cf) (= (cf-m cf) needed)))
          (let ((term ((cf-gen cf))))
            (if term
                (begin
                  (vector-set! (cf-memo cf) (cf-m cf) term)
                  (set-cf-m! cf (+ (cf-m cf) 1)))
                (set-cf-terminated?! cf #t)))))
      (define (update! needed)
        (cond ((cf-terminated? cf) (begin))
              ((<= needed (cf-m cf)) (begin))
              ((<= needed (vector-length (cf-memo cf)))
               (get-more-terms! needed))
              (else ;; Increase the storage space for memoization.
               (let* ((n1 (+ needed needed))
                      (memo1 (make-vector n1)))
                 (vector-copy! memo1 0 (cf-memo cf) 0 (cf-m cf))
                 (set-cf-memo! cf memo1))
               (get-more-terms! needed))))
      (update! (+ i 1))
      (and (< i (cf-m cf))
           (vector-ref (cf-memo cf) i)))

    (define *cf-max-terms*  ; Default term-count limit for cf->string.
      (make-parameter 20))

    (define cf->string       ; Make a string for a continued fraction.
      (case-lambda
        ((cf) (cf->string cf (*cf-max-terms*)))
        ((cf max-terms)
         (let loop ((i 0)
                    (s "["))
           (let ((term (cf-ref cf i)))
             (cond ((not term) (string-append s "]"))
                   ((= i max-terms) (string-append s ",...]"))
                   (else
                    (let ((separator (case i
                                       ((0) "")
                                       ((1) ";")
                                       (else ",")))
                          (term-str (number->string term)))
                      (loop (+ i 1) (string-append s separator
                                                   term-str))))))))))

    (define (number->cf num) ; Convert a number to a continued fraction.
      (let ((num (exact num)))
        (let ((n (numerator num))
              (d (denominator num)))
          (make-cf
           (lambda ()
             (and (not (zero? d))
                  (let-values (((q r) (floor/ n d)))
                    (set! n d)
                    (set! d r)
                    q)))))))

    (define (%%divide a b)
      (if (zero? b)
          (values #f #f)
          (floor/ a b)))

    (define (ng8->procedure ng8)

      ;; Thresholds chosen merely for demonstration.
      (define number-that-is-too-big (expt 2 512))
      (define practically-infinite (expt 2 64))

      (define too-big?  ; Stop computing if a no. reaches a threshold.
        (lambda (values)
          (cond ((null? values) #f)
                ((>= (abs (car values))
                     (abs number-that-is-too-big)) #t)
                (else (too-big? (cdr values))))))

      (define (treat-as-infinite? term)
        (>= (abs term) (abs practically-infinite)))

      (lambda (x y)

        (define (make-source cf)
          (let ((i 0))
            (lambda ()
              (let ((term (cf-ref cf i)))
                (set! i (+ i 1))
                term))))

        (define no-terms-source (lambda () #f))

        (define ng ng8)
        (define xsource (make-source x))
        (define ysource (make-source y))

        ;; The procedures "main", "compare-quotients",
        ;; "absorb-x-term", and "absorb-y-term" form a mutually
        ;; tail-recursive set. In standard Scheme, such an arrangement
        ;; requires no special notations, and WILL NOT blow up the
        ;; stack.

        (define (main)          ; "main" is the term-generating thunk.
          (define-values (a12 a1 a2 a b12 b1 b2 b)
            (apply values ng))
          (define bz? (zero? b))
          (define b1z? (zero? b1))
          (define b2z? (zero? b2))
          (define b12z? (zero? b12))
          (cond
           ((and bz? b1z? b2z? b12z?) #f)
           ((and bz? b2z?) (absorb-x-term))
           ((or bz? b2z?) (absorb-y-term))
           (b1z? (absorb-x-term))
           (else
            (let-values (((q  r)  (%%divide a b))
                         ((q1 r1) (%%divide a1 b1))
                         ((q2 r2) (%%divide a2 b2))
                         ((q12 r12) (%%divide a12 b12)))
              (if (and (not b12z?) (= q q1 q2 q12))
                  (output-a-term q b12 b1 b2 b r12 r1 r2 r)
                  (compare-quotients a2 a1 a b2 b1 b))))))

        (define (compare-quotients a2 a1 a b2 b1 b)
          (let ((n (* a b1 b2))
                (n1 (* a1 b b2))
                (n2 (* a2 b b1)))
            (if (> (abs (- n1 n)) (abs (- n2 n)))
                (absorb-x-term)
                (absorb-y-term))))

        (define (absorb-x-term)
          (define-values (a12 a1 a2 a b12 b1 b2 b)
            (apply values ng))
          (define term (xsource))
          (if term
              (let ((new-ng (list (+ a2 (* a12 term))
                                  (+ a  (* a1  term))
                                  a12 a1
                                  (+ b2 (* b12 term))
                                  (+ b  (* b1  term))
                                  b12 b1)))
                (if (not (too-big? new-ng))
                    (set! ng new-ng)
                    (begin 
                      ;; Replace the x source with one that returns no
                      ;; terms.
                      (set! xsource no-terms-source)
                      (set! ng (list a12 a1 a12 a1 b12 b1 b12 b1)))))
              (set! ng (list a12 a1 a12 a1 b12 b1 b12 b1)))
          (main))

        (define (absorb-y-term)
          (define-values (a12 a1 a2 a b12 b1 b2 b)
            (apply values ng))
          (define term (ysource))
          (if term
              (let ((new-ng (list (+ a1 (* a12 term)) a12
                                  (+ a  (* a2  term)) a2
                                  (+ b1 (* b12 term)) b12
                                  (+ b  (* b2  term)) b2)))
                (if (not (too-big? new-ng))
                    (set! ng new-ng)
                    (begin
                      ;; Replace the y source with one that returns no
                      ;; terms.
                      (set! ysource no-terms-source)
                      (set! ng (list a12 a12 a2 a2 b12 b12 b2 b2)))))
              (set! ng (list a12 a12 a2 a2 b12 b12 b2 b2)))
          (main))

        (define (output-a-term q b12 b1 b2 b r12 r1 r2 r)
          (let ((new-ng (list b12 b1 b2 b r12 r1 r2 r))
                (term (and (not (treat-as-infinite? q)) q)))
            (set! ng new-ng)
            term))

        (make-cf main))) ;; end procedure ng8->procedure

    )) ;; end library (cf)

;;;-------------------------------------------------------------------

(import (scheme base))
(import (scheme case-lambda))
(import (scheme write))
(import (cf))

(define golden-ratio (make-cf (lambda () 1)))
(define silver-ratio (make-cf (lambda () 2)))
(define sqrt2 (make-cf (let ((next-term 1))
                         (lambda ()
                           (let ((term next-term))
                             (set! next-term 2)
                             term)))))
(define frac13/11 (number->cf 13/11))
(define frac22/7 (number->cf 22/7))
(define one (number->cf 1))
(define two (number->cf 2))
(define three (number->cf 3))
(define four (number->cf 4))

(define cf+ (ng8->procedure '(0 1 1 0 0 0 0 1)))
(define cf- (ng8->procedure '(0 1 -1 0 0 0 0 1)))
(define cf* (ng8->procedure '(1 0 0 0 0 0 0 1)))
(define cf/ (ng8->procedure '(0 1 0 0 0 0 1 0)))

(define show
  (case-lambda
    ((expression cf note)
     (display expression)
     (display " =>  ")
     (display (cf->string cf))
     (display note)
     (newline))
    ((expression cf)
     (show expression cf ""))))

(show "      golden ratio" golden-ratio)
(show "      silver ratio" silver-ratio)
(show "           sqrt(2)" sqrt2)
(show "             13/11" frac13/11)
(show "              22/7" frac22/7)
(show "                 1" one)
(show "                 2" two)
(show "                 3" three)
(show "                 4" four)
(show " (1 + 1/sqrt(2))/2" (cf/ (cf+ one (cf/ one sqrt2)) two)
      "  method 1")
(show " (1 + 1/sqrt(2))/2" ((ng8->procedure '(1 0 0 1 0 0 0 8))
                            silver-ratio silver-ratio)
      "  method 2")
(show " (1 + 1/sqrt(2))/2" (cf/ (cf/ (cf/ silver-ratio sqrt2)
                                     sqrt2)
                                sqrt2)
      "  method 3")
(show " sqrt(2) + sqrt(2)" (cf+ sqrt2 sqrt2))
(show " sqrt(2) - sqrt(2)" (cf- sqrt2 sqrt2))
(show " sqrt(2) * sqrt(2)" (cf* sqrt2 sqrt2))
(show " sqrt(2) / sqrt(2)" (cf/ sqrt2 sqrt2))

;;;-------------------------------------------------------------------


  

You may also check:How to resolve the algorithm Recaman's sequence step by step in the EasyLang programming language
You may also check:How to resolve the algorithm Iterated digits squaring step by step in the Python programming language
You may also check:How to resolve the algorithm 99 bottles of beer step by step in the Inform 6 programming language
You may also check:How to resolve the algorithm Comments step by step in the SETL programming language
You may also check:How to resolve the algorithm Ray-casting algorithm step by step in the CoffeeScript programming language