Exercise 2.7
#lang racket
(define (make-interval a b) (cons a b))
(define (upper-bound interval) (cdr interval))
(define (lower-bound interval) (car interval))
Exercise 2.8
#lang racket
(define (sub-interval x y)
(make-interval
(- (lower-bound x) (upper-bound y))
(- (upper-bound x) (lower-bound y))))
Exercise 2.9
#lang racket
;something like that
(a b) + (c d) = (a+c b+d)
width(ab) = (b-a)/2
width(cd) = (d-c)/2
width(add) = [(b+d)-(a+c)]/2 = [(b-a)+(d-c)]/2
width(add) = width(ab) + width(cd)
;multiplication or division is not true
;interval arithmethic is complicated and uncertain
;especially div
Exercise 2.10
#lang racket
(define (div-interval x y)
(if (and (>= (upper-bound y) 0) (<= (lower-bound y) 0))
(error "Denominator spans zero" y)
(mul-interval
x
(make-interval (/1.0 (upper-bound y))
(/1.0 (lower-bound y))))))
Exercise 2.11
#lang racket
(define (mul-interval x y)
(let ((upper-x (upper-bound x))
(lower-x (lower-bound x))
(upper-y (upper-bound y))
(lower-y (lower-bound y)))
(cond ((and (>= upper-x 0) (>= lower-x 0)
(>= upper-y 0) (>= lower-y 0))
(make-interval (* lower-x lower-y) (* upper-x upper-y)));x++,y++
((and (>= upper-x 0) (>= lower-x 0)
(>= upper-y 0) (< lower-y 0))
(make-interval (* upper-x lower-y) (* upper-x upper-y)));x++,y+-
((and (>= upper-x 0) (>= lower-x 0)
(< upper-y 0) (< lower-y 0))
(make-interval (* upper-x lower-y) (* lower-x upper-y)));x++,y--
((and (>= upper-x 0) (< lower-x 0)
(>= upper-y 0) (>= lower-y 0))
(make-interval (* upper-y lower-x) (* upper-x upper-y)));x+-,y++
((and (>= upper-x 0) (< lower-x 0)
(>= upper-y 0) (< lower-y 0))
;x+-,y+- need to do some special
(let ((p1 (* lower-x lower-y))
(p2 (* lower-x upper-y))
(p3 (* upper-x upper-y))
(p4 (* upper-x lower-y)))
(make-interval (min p1 p2 p3 p4) (max p1 p2 p3 p4))))
((and (>= upper-x 0) (< lower-x 0)
(< upper-y 0) (< lower-y 0))
(make-interval (* upper-x lower-y) (* lower-x lower-y)));x+-,y--
((and (< upper-x 0) (< lower-x 0)
(>= upper-y 0) (>= lower-y 0))
(make-interval (* upper-y lower-x) (* lower-y upper-x)));x--,y++
((and (< upper-x 0) (< lower-x 0)
(>= upper-y 0) (< lower-y 0))
(make-interval (* upper-y lower-x) (* lower-x lower-y)));x--,y+-
((and (< upper-x 0) (< lower-x 0)
(< upper-y 0) (< lower-y 0))
(make-interval (* upper-x upper-y) (* lower-x lower-y)));x--,y--
(else
(error "no this condition")))))
Exercise 2.12
#lang racket
;transfer center width to lower and upper
(define (make-center-width c w)
(make-interval (- c w) (+ c w)))
;selector width
(define (width i)
(/ (- (upper-bound i) (lower-bound i)) 2))
;selector center
(define (center i)
(/ (+ (lower-bound i) (upper-bound i)) 2))
;transfer percent to width,then call make-center-width
(define (make-center-percent c p)
(let ((w (* c (/ p 100))))
(make-interval (- c w) (+ c w))))
;selector percent
(define (percent i)
(* 100 (/ (width i) (center i))))
Exercise 2.13-2.14
#lang racket
(define (par1 r1 r2)
(div-interval (mul-interval r1 r2)
(add-interval r1 r2)))
(define (par2 r1 r2)
(let ((one (add-interval (div-interval one r1)
(div-interval one r2))))))
;because the interval arithmetic r1/r1 is not 1.
;so they can't be written in two algebraically equivalent ways:
;(1/(1/R1)+(1/R2))*R1R2 = R1R2/(R2*R1/R1+R1*R2/R2)<>R1R2/(R1+R2)
Exercise 2.15-2.16
#lang racket
;I think Eva Lu Ator is right,
;by reducing the repeatability can make the tighter error bounds.
;but i can't give the precise answer,just feel
Summarize
- 区间运算很复杂,一方面在于其边界条件考虑起来比较麻烦,另一个原因就是它的不确定性,没法保证区间除法产生固定的区间值。
- Don't repeat yourself,充分利用已有的方法,在已有的方法上堆砌新的方法。
- 题目很变态,累了就歇会~~