| |
| | (ns e2-7-8-9-10-11
(:use [clojure.contrib.test-is :only (deftest is run-tests)])
(:use [util.util :only (avg)])
(:use [util.interval :only (make-interval lower-bound upper-bound mul-interval add-interval div-interval)])
(:use [clojure.contrib.generic.math-functions :only ()]))
| | (defn sub-interval [a b]
(let [l (- (lower-bound a) (lower-bound b))
u (- (upper-bound a) (upper-bound b))]
(make-interval (min l u) (max l u))))
| | (deftest sub-interval-test
; 1. ----|---\----|---\-------
; a0 a1 b0 b1
(is (= (sub-interval (make-interval 1 3) (make-interval 2 5)) (make-interval -2 -1)))
; 2. ---\--------\-|--------|-
; a1 b1 a0 b0
(is (= (sub-interval (make-interval 4 6) (make-interval 1 3)) (make-interval 3 3)))
; 3. ---|--------|-\--------\-
; a0 b0 a1 b1
(is (= (sub-interval (make-interval 1 3) (make-interval 4 6)) (make-interval -3 -3)))
; 4. ---\----|---\----|-------
; a1 a0 b1 b0
(is (= (sub-interval (make-interval 2 5) (make-interval 1 3)) (make-interval 1 2))))
| | (defn radius-interval [z]
(avg (upper-bound z) (lower-bound z)))
Takes an operation on intervals, an op on numbers and two intervals. Returns true if the result is proportional
to the input values, false otherwise.
| | (defn proportional?
[fint f a b]
(let [result (fint a b)]
(= (radius-interval result) (f (radius-interval a) (radius-interval b)))))
| | (deftest addition-subtraction-test
(is (proportional? sub-interval - (make-interval 1 6) (make-interval 3 15)))
(is (proportional? sub-interval - (make-interval -1 6) (make-interval -6 -5)))
(is (proportional? add-interval + (make-interval 1 6) (make-interval 3 15)))
(is (proportional? add-interval + (make-interval -1 6) (make-interval -6 -5)))
(is (not (proportional? mul-interval * (make-interval 1 6) (make-interval 3 15))))
(is (not (proportional? mul-interval * (make-interval -1 6) (make-interval -6 -5))))
(is (not (proportional? div-interval / (make-interval 1 6) (make-interval 3 15))))
(is (not (proportional? div-interval / (make-interval -1 6) (make-interval -6 -5)))))
| | (defn contains-interval [a n]
(if (or (> (lower-bound a) n) (< (upper-bound a) n))
false
true))
| | (defn div-interval-mod [a b]
(if (contains-interval b 0) (println "Cannot divide by interval containing a zero!" b)
(mul-interval a
(make-interval (/ 1 (upper-bound b))
(/ 1 (lower-bound b))))))
| | (defn mul-interval-2 [a b]
(let [la (lower-bound a)
ua (upper-bound a)
lb (lower-bound b)
ub (upper-bound b)]
; 1.
; --*--|---\----|---\-------
; 0 la lb ua ub
(cond (and (pos? la) (pos? lb))
(make-interval (* la lb) (* ua ub))
; 2.
; -----|---\----|---\---*---
; la lb ua ub 0
(and (neg? ua) (neg? ub))
(make-interval (* ua ub) (* la lb))
; 3.
; -\--------\-*-|--------|-
; lb ub 0 la ua
(and (pos? la) (neg? ub))
(make-interval (* ua lb) (* la ub))
; 4. opposite of 3
; -|--------|-*-\--------\-
; la ua 0 lb ub
(and (pos? lb) (neg? ua))
(make-interval (* la ub) (* lb ua))
; 5.
; -\--------\--|----*---|---
; lb ub la 0 ua
(and (neg? la) (pos? ua) (neg? ub))
(make-interval (* ua lb) (* la lb))
; 6. opposite of 5
; -|--------|--\----*---\---
; la ua lb 0 ub
(and (neg? lb) (pos? ub) (neg? ua))
(make-interval (* ub la) (* la lb))
; 7.
; -\---*----\--|--------|---
; lb 0 ub la ua
(and (neg? lb) (pos? ub) (pos? la))
(make-interval (* lb ua) (* ub ua))
; 8. opposite of 7
; -|---*----|--\--------\---
; la 0 ua lb ub
(and (neg? la) (pos? ua) (pos? lb))
(make-interval (* la ub) (* ua ub))
; 9. the last one where two multiplications are required
; ----|--\--*--|---\---------
; la lb 0 ua ub
:else
(make-interval (min (* la ub) (* lb ua)) (max (* la lb) (* ua ub))))))
| |