4 Custom Continued Fractions
(require continued-fractions/create) | |
package: continued-fractions |
4.1 Creation Concepts
4.1.1 Creation Introduction
There are two standard types of continued fractions. Simple continued fractions are of the form a0 + 1/(a1 + 1/(a2 + ...)). General continued fractions are of the form d0 + n0/(d1 + n1/(d2 + ...)). This library offers some procedures, sequence utilities, and sequences to help you make your own continued fractions.
4.1.2 Creation Caveats
As mentioned in the main introduction, continued fractions in this library generally only allow the first non-zero term to be negative. Short of enumerating all the terms of a sequence, there is no way to guarantee this. Thus, hand-crafted continued fractions for exploratory purposes may violate some assumptions of this library.
This library operates under the additional assumption that all generated terms of continued fractions are exact integers. One may always transform an arbitrary continued fraction with rational terms to one with integer terms. For instance, in the continued fraction 1 + (3/2)/(1 + ...) the denominator of 2 can be eliminated by multiplying this portion of the continued fraction by 2/2, giving 1 + 3/(2 + (2* ...)).
4.2 Provided Sequences
The forms provided by racket/sequence are recommended but not provided. In particular, many continued fractions have initial terms that do not follow a pattern, while subsequent terms do, so sequence-append is helpful. Additionally, some specific sequences are given.
4.2.1 Sequence Utilities
procedure
(sequence-map* p s ...) → sequence?
p : procedure? s : sequence?
> (require racket/sequence)
> (let ((S (sequence-map* + (in-naturals 0) (in-naturals 0) (in-range 5)))) (sequence->list S)) '(0 3 6 9 12)
procedure
(every-other s) → sequence?
s : sequence?
> (sequence->list (every-other (in-range 10))) '(0 2 4 6 8)
procedure
(interleave s ...) → sequence?
s : sequence?
> (sequence->list (interleave (in-range 0 10) (in-range 10 15) (in-range 100 103))) '(0 10 100 1 11 101 2 12 102 3 13 4 14 5 6 7 8 9)
4.2.2 Specific Sequences
procedure
(endless-values v) → sequence?
v : any/c
procedure
v : (and/c exact-integer? even?)
procedure
v : (and/c exact-integer? odd?)
procedure
(in-squares v) → sequence?
v : number?
> (for/list ((s (in-squares 9)) (i (in-range 10))) s) '(9 16 25 36 49 64 81 100 121 144)
> (for/list ((s (in-squares 8)) (i (in-range 10))) s) '(9 16 25 36 49 64 81 100 121 144)
procedure
(in-triangle v) → sequence?
v : number?
procedure
(in-double-triangle v) → sequence?
v : number?
> (for/list ((t (in-triangle 0)) (i (in-range 10))) t) '(0 1 3 6 10 15 21 28 36 45)
> (equal? (for/list ((t (in-triangle 0)) (i (in-range 10))) (* 2 t)) (for/list ((t (in-double-triangle 0)) (i (in-range 10))) t)) #t
procedure
(in-common-difference init base-sequence [ #:strip-until strip]) → sequence? init : (and/c exact? integer?) base-sequence : sequence? strip : (or/c #f (and/c exact? integer?)) = #f
> (sequence->list (in-common-difference 0 (in-range 10))) '(0 0 1 3 6 10 15 21 28 36 45)
> (for/list ((t (in-common-difference 0 (in-common-difference 1 (in-common-difference 6 (endless-values 6))))) (i (in-range 10))) t) '(0 1 8 27 64 125 216 343 512 729)
4.3 Continued Fraction Creation
4.3.1 Continued Fraction Procedures
procedure
(sequence->simple-continued-fraction s [ #:force count]) → continued-fraction? s : sequence?
count :
(or/c #f (and/c exact? positive? integer?)) = #f
procedure
(sequences->general-continued-fraction d n [ #:force count]) → continued-fraction? d : sequence? n : sequence?
count :
(or/c #f (and/c exact? positive? integer?)) = #f
4.3.2 Forcing
Well-behaved continued fractions have terms which are always positive or always negative. Unfortunately this is not always the case. Sometimes there is a crossover where some terms switch from being positive to being negative. A sequence provided may at some point emit a zero at a known location. Such terms can cause havoc with continued fraction arithmetic. For that reason, the #:force keyword is provided. It allows the user to internally force the consumption of the specified number of terms before any arithmetic or other output is attempted. This overrides any precision or consume-limit parameters.
As an example, the continued fraction (-3 -2 -1 0 1 2 3 ...) is equivalant to (-3 -2 0 2 3 ...) which is eventually just (0 4 5 6 ...). Since internal algorithms assume that no zeros will appear, emission of a term from a continued fraction sequence may occur prematurely if #:force is not used.
> (define bad-cf (sequence->simple-continued-fraction (in-range -5 15))) > (sequence->list bad-cf) '(-6 1 3 3 0 -4 1 3 5 6 7 8 9 10 11 12 13 14)
> (define good-cf (sequence->simple-continued-fraction (in-range -5 15) #:force 11)) > (sequence->list good-cf) '(0 6 7 8 9 10 11 12 13 14)
; The overall accuracy of arithmetic is not affected: ; these are both valid representations of the same rational.
> (= (cf-terms->rational (sequence->list bad-cf)) (cf-terms->rational (sequence->list good-cf))) #t
> (for/list ((t (base-emit bad-cf 10)) (i (in-range 20))) t) '(-5 -2 536 2 8 5 6 2 5 7 6 5 8 9 0 6 5 1 0 5)
> (for/list ((t (base-emit good-cf 10)) (i (in-range 20))) t) '(0 1 6 2 8 5 6 2 5 7 6 5 8 9 0 6 5 1 0 5)