59 lines
1.1 KiB
Ruby
59 lines
1.1 KiB
Ruby
def leftrect(f, left, right)
|
|
f.call(left)
|
|
end
|
|
|
|
def midrect(f, left, right)
|
|
f.call((left+right)/2.0)
|
|
end
|
|
|
|
def rightrect(f, left, right)
|
|
f.call(right)
|
|
end
|
|
|
|
def trapezium(f, left, right)
|
|
(f.call(left) + f.call(right)) / 2.0
|
|
end
|
|
|
|
def simpson(f, left, right)
|
|
(f.call(left) + 4*f.call((left+right)/2.0) + f.call(right)) / 6.0
|
|
end
|
|
|
|
def integrate(f, a, b, steps, method)
|
|
delta = 1.0 * (b - a) / steps
|
|
total = 0.0
|
|
steps.times do |i|
|
|
left = a + i*delta
|
|
right = left + delta
|
|
total += delta * send(method, f, left, right)
|
|
end
|
|
total
|
|
end
|
|
|
|
def square(x)
|
|
x**2
|
|
end
|
|
|
|
def def_int(f, a, b)
|
|
l = case f.to_s
|
|
when /sin>/
|
|
lambda {|x| -Math.cos(x)}
|
|
when /square>/
|
|
lambda {|x| (x**3)/3.0}
|
|
end
|
|
l.call(b) - l.call(a)
|
|
end
|
|
|
|
a = 0
|
|
b = Math::PI
|
|
steps = 10
|
|
|
|
for func in [method(:square), Math.method(:sin)]
|
|
puts "integral of #{func} from #{a} to #{b} in #{steps} steps"
|
|
actual = def_int(func, a, b)
|
|
for method in [:leftrect, :midrect, :rightrect, :trapezium, :simpson]
|
|
int = integrate(func, a, b, steps, method)
|
|
diff = (int - actual) * 100.0 / actual
|
|
printf " %-10s %s\t(%.1f%%)\n", method, int, diff
|
|
end
|
|
end
|