--- /dev/null
+(ns sicp.ch2_1_extended
+ (:use [sicp utils ex2_7]
+ [clojure.test]))
+
+;; 2.1.4 - interval arithmetic
+;;(declare make-interval lower-bound upper-bound)
+
+(defn add-interval [x y]
+ (make-interval (+ (lower-bound x) (lower-bound y))
+ (+ (upper-bound x) (upper-bound y))))
+
+(defn mul-interval [x y]
+ (let [p1 (* (lower-bound x) (lower-bound y))
+ p2 (* (lower-bound x) (upper-bound y))
+ p3 (* (upper-bound x) (lower-bound y))
+ p4 (* (upper-bound x) (upper-bound y))]
+ (make-interval (min p1 p2 p3 p4)
+ (max p1 p2 p3 p4))))
+
+(defn div-interval [x y]
+ (mul-interval x
+ (make-interval (/ 1.0 (upper-bound y))
+ (/ 1.0 (lower-bound y)))))
+
+
--- /dev/null
+(ns sicp.ex2_10
+ (:use [sicp utils ch2_1_extended ex2_7]
+ [clojure.test]))
+
+(defn new-div-interval [x y]
+ (let [l (lower-bound y)
+ u (upper-bound y)]
+ (if (or (and (pos? l)
+ (neg? u))
+ (and (pos? u)
+ (neg? l)))
+ (error "Division by a range spanning 0")
+ (div-interval x y))))
\ No newline at end of file
--- /dev/null
+(ns sicp.ex2_11
+ (:use [sicp utils ch2_1_extended ex2_7]
+ [clojure.test]))
+
+;; let [l1, u2] be lower and upper bound of range x
+;; and [l2, u2] that of range y.
+
+;; based on the signs of l1, u1, l2, u2, we have 16 combinations
+
+;; l1 :u1 :l2 :u2
+;; + + + +
+;; + + + -
+;; + + - +
+;; + + - -
+;; + - + +
+;; + - + -
+;; + - - +
+;; + - - -
+;; - + + +
+;; - + + -
+;; - + - +
+;; - + - -
+;; - - + +
+;; - - + -
+;; - - - +
+;; - - - -
+
+;; Now, if lower bound is +ve and upper is -ve, then it is invalid. So,
+;; l1 :u1 :l2 :u2
+;; + + + +
+;; + + + - => invalid
+;; + + - +
+;; + + - -
+;; + - + + => invalid
+;; + - + - => invalid
+;; + - - + => invalid
+;; + - - - => invalid
+;; - + + +
+;; - + + - => invalid
+;; - + - +
+;; - + - -
+;; - - + +
+;; - - + - => invalid
+;; - - - +
+;; - - - -
+
+
+;; too boring a problem. Skipping the rest of it.
--- /dev/null
+(ns sicp.ex2_7
+ (:use [sicp utils ch2_1_extended]
+ [clojure.test]))
+
+(defn make-interval [x y]
+ (list x y))
+
+(defn upper-bound [i]
+ (first i))
+
+(defn lower-bound [i]
+ (first (rest i)))
--- /dev/null
+(ns sicp.ex2_8
+ (:use [sicp utils ch2_1_extended ex2_7]
+ [clojure.test]))
+
+;; sub-interval
+(defn sub-interval [x y]
+ (make-interval (- (lower-bound x) (upper-bound y))
+ (- (upper-bound x) (lower-bound y))))
+
+;; subtraction of an interval can be seen as addition of a
+;; negative range. Intuitively, if you plot a range in a 2-D graph,
+;; negative of a range, say [a1, a2] for say a1 and a2 positive
+;; is [-a2, -a1]. i.e. the reflection of the range w.r.t the x=0
+;; axis. In this new light, we are adding two ranges [-a2,-a2] and [b1,b2]
+;; and hence the above answer.
\ No newline at end of file
--- /dev/null
+(ns sicp.ex2_9
+ (:use [sicp utils ch2_1_extended ex2_7]
+ [clojure.test]))
+
+;; let us say, width of an interval [x,y] = d = (y-x)/2.
+;; add_interval [x,y] = [l1+l2, u1+u2]
+;; width of sum = (u1+u2 - (l1+l2))/2
+;; = (u1-l1 + u2 - l2)/2
+;; = d1 + d2
+;;
+;; sub_interval [x,y] = [l1-u2, u1-l2]
+;; width of diff = (u1-l2 - (l1-u2))/2
+;; = (u1 - l2 - l1 + u2) / 2
+;; = ((u1 - l1) + (u2 - l2))/2
+;; = d1 + d2
+
+;; Now, intuitively multiplication (and division), scales a range
+;; up or down. Since mul-range was essentially non-linear (is that the
+;; right term? ) because of the min/max calculations, these depend on
+;; absolute values of the range rather than the width.
+;; eg: [2 3] [3 4]. Width (d1, d2) => (1,1)
+;; mul-interval => [6 12]
+
+;; same with division as well.