Building Abstractions with Data - Introduction to Data Abstraction - Extended Exercise: Interval Arithmetic - width of an interval, addiction, multiplication, division
Structure and Interpretation of Computer Programs: JavaScript Edition(Harold Abelson(著)、Gerald Jay Sussman(著)、Julie Sussman(著)、The MIT Press)のChapter 2(Building Abstractions with Data)、2.1(Introduction to Data Abstraction)、2.1.4(Extended Exercise: Interval Arithmetic)、Exercise 2.9の解答を求めてみる。
和について。
x1、x2を任意のintervalとする。
x1のwidthとx2のwidthの和。
- (x1_upper-x1_lower) / 2 + (x2_upper-x2_lower) / 2
- ((x1_upper + x2_upper) - (x1_lower+x2_lower)) / 2
これはx1とx2の和のwidthと等しい。
積について。
x=[1, 3], y=[1, 5]
に対して、xのwidthは
(3-1)/2=1
yのwidthは
(5-1)/2=2
xのwidthとyのwidthの積は2。
xとyの積をzとすると、
z=[1, 15]
でzのwidthは
(15-1)/2=7
よって、widthの積と積のwidthは異なる。
除算について。
x、yは積の場合と同様とする。
x_width/y_width=1/2
x/y=[1, 3] * [1/5, 1]=[1/5, 3]
このwidthは
(3-1/5)/2=7/5
実際にプログラムを実行してみる。
コード
function pair(x, y) {
return [x, y];
}
function head(z) {
return z[0];
}
function tail(z) {
return z[1];
}
function half(x) {
return x / 2;
}
function make_interval(x, y) {
return pair(x, y);
}
function upper_bound(interval) {
return tail(interval);
}
function lower_bound(interval) {
return head(interval);
}
function width_interval(interval) {
return half(upper_bound(interval) - lower_bound(interval));
}
function add_interval(x, y) {
return make_interval(
lower_bound(x) + lower_bound(y),
upper_bound(x) + upper_bound(y)
)
}
function mul_interval(x, y) {
const p1 = lower_bound(x) * lower_bound(y);
const p2 = lower_bound(x) * upper_bound(y);
const p3 = upper_bound(x) * lower_bound(y);
const p4 = upper_bound(x) * upper_bound(y);
return make_interval(
Math.min(p1, p2, p3, p4),
Math.max(p1, p2, p3, p4)
);
}
function div_interval(x, y) {
return mul_interval(
x,
make_interval(
1 / upper_bound(y),
1 / lower_bound(y)
)
)
}
const x = make_interval(1, 3);
const y = make_interval(1, 5);
const x_width = width_interval(x);
const y_width = width_interval(y);
console.log(`x = ${x}, y= ${y}`)
console.log(`x_width = ${x_width}, y_width = ${y_width}`);
console.log('addition');
console.log(`${x_width + y_width}, ${width_interval(add_interval(x, y))}`);
console.log('multiplication');
console.log(`${x_width * y_width}, ${width_interval(mul_interval(x, y))}`);
console.log('division');
console.log(`${x_width / y_width}, ${width_interval(div_interval(x, y))}`);
入出力結果(Terminal, Zsh)
% node answer2.9.js
x = 1,3, y= 1,5
x_width = 1, y_width = 2
addition
3, 3
multiplication
2, 7
division
0.5, 1.4
%