require 'bigdecimal'
class ExtrFinder
def initialize(f,a,b,eps, fprime)
@f = f
@a = a
@b = b
@eps = eps
@fprime = fprime
@nres = 0
@itern = 0
@x1 = 0
end
def dixitom
@iter = 0
while (@b - @a) > 2 * @eps
@iter +=1
@c = (@a + @b)/BigDecimal("2.0")
if @f.call(@a) * @f.call(@c) > 0
@a = @c
else
@b = @c
end
end
end
def newton(x0)
@x1 = x0 - @f.call(x0)/@fprime.call(x0)
#print x0, "\n"
if @f.call(@x1) * @f.call(@x1 + @eps * self.sign(@f.call(@x1) - @f.call(x0))) < 0
#print @itern, "\n"
@nres = @x1 + self.sign(@f.call(@x1) - @f.call(x0))/2
else @itern += 1
self.newton(@x1)
end
end
def sign(x)
#print "x in sign: ", x, "\n"
#print "sign: ", x/x.abs, "\n"
if x > 0
return 1
else return -1
end
end
def printresultd(re)
print "dih: ", "iter: ", @iter," zer: " , ( (@a + @b)/2.0 ).round(3), " delta: ", ( (@a + @b)/2.0 - re ).round(3).abs, "\n"
end
def printresultn(re)
print "newton: ", "iter: ", @itern," zer: " ,( @x1 ).round(3) , " delta: ", ( @x1 - re ).round(3).abs,"\n"
end
end
#func = Proc.new {|x| (x - 1)*(x - 2)*(x - 3)}
func = Proc.new {|x| 2*x*x*x + 4*x*x + -6*x - 1}
#fprime = Proc.new {|x| 3 * x * x - 12 * x + 11}
fprime = Proc.new {|x| 6 * x * x + 8 * x - 6}
counter = ExtrFinder.new(func, BigDecimal("-3.5"), BigDecimal("-1"), BigDecimal("0.1"),fprime)
counter.dixitom
counter.printresultd(-2.99573)
counter = ExtrFinder.new(func, BigDecimal("-2.0"), BigDecimal("0.5"), BigDecimal("0.1"),fprime)
counter.dixitom
counter.printresultd(-0.15237)
counter = ExtrFinder.new(func, BigDecimal("0.0"), BigDecimal("2.5"), BigDecimal("0.1"),fprime)
counter.dixitom
counter.printresultd(1.1096)
counter = ExtrFinder.new(func, BigDecimal("-4"), BigDecimal("-1"), BigDecimal("0.1"),fprime)
counter.newton(BigDecimal("-2.0"))
counter.printresultn(-2.99573)
counter = ExtrFinder.new(func, BigDecimal("-2.0"), BigDecimal("0.5"), BigDecimal("0.1"),fprime)
counter.newton(BigDecimal("-1.0"))
counter.printresultn(-0.15237)
counter = ExtrFinder.new(func, BigDecimal("0.0"), BigDecimal("2.5"), BigDecimal("0.1"),fprime)
counter.newton(BigDecimal("2.0"))
counter.printresultn(1.1096)
=begin
counter = ExtrFinder.new(func, BigDecimal("0.5"), BigDecimal("1.5"), BigDecimal("0.01"),fprime)
counter.dixitom
counter.printresultd
counter = ExtrFinder.new(func, BigDecimal("1.5"), BigDecimal("2.5"), BigDecimal("0.01"),fprime)
counter.dixitom
counter.printresultd
counter = ExtrFinder.new(func, BigDecimal("2.5"), BigDecimal("3.5"), BigDecimal("0.01"),fprime)
counter.dixitom
counter.printresultd
counter = ExtrFinder.new(func, BigDecimal("0.5"), BigDecimal("1.5"), BigDecimal("0.01"),fprime)
counter.newton(BigDecimal("1.3"))
counter.printresultn
counter = ExtrFinder.new(func, BigDecimal("1.5"), BigDecimal("2.5"), BigDecimal("0.01"),fprime)
counter.newton(BigDecimal("2.3"))
counter.printresultn
counter = ExtrFinder.new(func, BigDecimal("2.5"), BigDecimal("3.5"), BigDecimal("0.01"),fprime)
counter.newton(BigDecimal("3.3"))
counter.printresultn
=end