print_func(func:function) = printf('%s = %s\n', func, func.expr())
tester(test:expr):map:dynamic_scope = printf("%s .. %s\n", test, eval(test)):nomap

lambda {
	tester(`math.cross_product([1, 2], [3, 1]))
	tester(`math.cross_product([3, 1], [1, 2]))
	tester(`math.cross_product([1, 2, 3], [-1, 1, 2]))
	tester(`math.cross_product([-1, 1, 2], [1, 2, 3]))
	try {
		tester(`math.cross_product([-1, -3], [2, 2, 3]))
	} except(ValueError) {|e|
		println("expected error occurs: ", e.text)
	}
	try {
		tester(`math.cross_product([-1, -3, 2, 1], [2, 2, 3, 1]))
	} except(ValueError) {|e|
		println("expected error occurs: ", e.text)
	}
	tester(`math.dot_product([-1, -3], [2, 2]))
	tester(`math.dot_product([-1, -3, 3], [2, 2, -1]))
	try {
		tester(`math.dot_product([-1, -3], [2, 2, 3]))
	} except(ValueError) {|e|
		println("expected error occurs: ", e.text)
	}
}()
lambda {
	bezier1(nums[]:number):map = lambda(t:number):map {
		numswk = nums.clone()
		while ((len = numswk.len()) > 1) {
			numswk = for (num1 in numswk.head(len - 1), num2 in numswk.offset(1)):list {
				num1 * (1 - t) + num2 * t
			}
		}
		numswk[0]
	}
	bezier2(nums[]:number):map = {
		a = nums[0]
		b = 3 * nums[1] - 3 * nums[0]
		c = 3 * nums[2] - 6 * nums[1] + 3 * nums[0]
		d = nums[3] - 3 * nums[2] + 3 * nums[1] - nums[0]
		lambda(t:number):map {
			a + b * t + c * t * t + d * t * t * t
		}
	}
	[f_x, f_y] = math.bezier([6, 10, 16, 20], [12, 4, 6, 10])
	[f1_x, f1_y] = bezier1([6, 10, 16, 20], [12, 4, 6, 10])
	[f2_x, f2_y] = bezier2([6, 10, 16, 20], [12, 4, 6, 10])
	print_func(f2_x)
	print_func(f2_y)
	t = interval(0, 1, 10)
	printf("%12s,%12s,%12s, %12s,%12s,%12s\n", "f_x", "f1_x", "f2_x", "f_y", "f1_y", "f2_y")
	printf("%12f,%12f,%12f, %12f,%12f,%12f\n", f_x(t), f1_x(t), f2_x(t), f_y(t), f1_y(t), f2_y(t))
}()
lambda {
	x = [1, 3, 5, 7, 9]
	y = [3, 6, 5.5, 5, 7]
	x_interval = interval(0, 10, 100)
	f = math.least_square(x, y, 1)
	g = math.least_square(x, y, 2, `temp)
	h = math.least_square(x, y, 3, `hoge)
	print_func(f)
	print_func(g)
	print_func(h)
}()
lambda {
	x = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2]
	y = [1.0, 1.9, 3.2, 4.3, 4.8, 6.1, 7.2]
	x_interval = interval(0, 1.2, 100)
	f = math.least_square(x, y, 1)
	print_func(f)
}()
