Class: Flt::Solver::SecantSolver

Inherits:
Base
  • Object
show all
Defined in:
lib/solver/secant.rb

Overview

Secant method solver Bisect method is used is bracketing found (sign(f(a)) != sign(f(b)))

Example of use:

require 'solver'
include Flt
solver = Solver::SecantSolver.new(Float.context, [0.0, 100.0], Tolerance(3, :decimals)) do |x|
  2*x+11.0
end
puts solver.root
# with a guess:
puts solver.root(5.0)

solver = SecantSolver.new(Float.context, [0.0, 10.0], Tolerance(3, :decimals)) do |x|
  y = 2
  y*exp(x)-10
end
puts solver.root

Instance Attribute Summary

Attributes inherited from Base

#iteration, #reason

Instance Method Summary collapse

Methods inherited from Base

#root, #value

Constructor Details

#initialize(*args, &blk) ⇒ SecantSolver

Returns a new instance of SecantSolver.



24
25
26
27
28
# File 'lib/solver/secant.rb', line 24

def initialize(*args, &blk)
  super
  @half = num(Rational(1,2))
  reset
end

Instance Method Details

#resetObject



30
31
32
33
34
# File 'lib/solver/secant.rb', line 30

def reset
  super
  @a = @b = @fa = @fb = nil
  @bracketing = false
end

#stepObject



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/solver/secant.rb', line 36

def step
  return @guess[1] if @iteration == 0
  bisect = false
  dy = @fx - @l_fx

  if @tol.zero?(dy)
    if @bracketing
      bisect = true
    else
      @ok = false
      return @x
    end
  end

  if !bisect
    next_x = @x - ((@x - @l_x)*@fx)/dy
    bisect = true if @bracketing && (next_x < @a || next_x > @b)
  end
  next_x = (@a + @b)*@half if bisect
  next_fx = eval_f(next_x)

  if @bracketing
    if @context.sign(@fa) == @context.sign(next_fx)
      @a = next_x
      @fa = next_fx
    else
      @b = next_x
      @fb = next_fx
    end
  else
    if @context.sign(next_fx) != @context.sign(@fx)
      @a, @b = @x, next_x
      @a, @b = @b, @a if @a > @b
      @fa = eval_f(@a)
      @fb = eval_f(@b)
      @bracketing = true
    end
  end
  next_x
end

#validateObject



77
78
79
80
81
82
83
84
# File 'lib/solver/secant.rb', line 77

def validate
  @guess = @guess.uniq
  if @guess.size < 2
    return false if @guess.empty?
    @guess << (@guess.first + 1)
  end
  true
end