Skip to content

Instantly share code, notes, and snippets.

@estebanz01
Last active March 4, 2019 20:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save estebanz01/85e4a5f2548921d2de342a1daf51dc0c to your computer and use it in GitHub Desktop.
Save estebanz01/85e4a5f2548921d2de342a1daf51dc0c to your computer and use it in GitHub Desktop.
Ruby snippet that tries to compute and find the root for a function using the Newton-Raphson method.
#!/usr/env ruby
def derivative_of(f:, x:)
h = 1e-14 # 1 * 10^-14 this is the smallest number ruby can handle in calculations before defaulting result to zero.
(f.call(x + h) - f.call(x)) / h # This is a naive approach to calculate limit of f(x) in x.
end
# Newton's Method, where we calculate f(x), f'(x) and calculate error.
def find_root(f:, seed:, iterations: nil, error_level: nil)
if iterations.nil? && error_level.nil?
throw 'Iterations and error level not defined. Please specify at least one'
end
x = nil # Root
x0 = seed # Initial value
i = 0 # Number of iterations made
loop do
break if !iterations.nil? && i >= iterations # Leave if we have reached the number of iterations.
x = x0 - (f.call(x0) / derivative_of(f: f, x: x0))
if x.nan?
x = nil
break
end
break if x == 0 || (x - x0).abs <= error_level
i = i+1 # Iteration finished
x0 = x # Swap the x0 value
end
x # Result
rescue Math::DomainError
x = nil
end
# Example # 1
# F(x) = (e ^ x) * ln(x)
# Exact root is defined at 1
f = lambda { |x| Math.exp(x) * Math.log(x) } # f(x) = (e^x) * ln(x) defined in R
root = find_root(f: f, seed: 2, error_level: 0.00000001)
if root.nil?
puts 'Computed root of F(x) cannot be found or do not exist.'
else
puts "Computed root of F(x) = (e^x)ln(x) is #{root}. Exact root is 1.0."
end
# Example # 2
# F(x) = (x ^ 5) * tanh(x^3)
# Exact root is defined at 0
f = lambda { |x| (x ** 5) * Math.tanh(x ** 3) } # f(x) = (x^5) * tanh(x^3) defined in R
root = find_root(f: f, seed: 2, error_level: 0.00000001)
if root.nil?
puts 'Computed root of F(x) cannot be found or do not exist.'
else
puts "Computed root of F(x) = (x^5)tanh(x^3) is #{root}. Exact root is 0.0."
end
# Example # 3
# F(x) = (x ^ 2) + 2
# Exact root is not defined
f = lambda { |x| (x ** 2) + 2 } # f(x) = x^2 + 2 defined in R
root = find_root(f: f, seed: 2, error_level: 0.00000001)
if root.nil?
puts 'Computed root of F(x) = x^2 + 2 cannot be found or do not exist.'
else
puts "Root of F(x) is #{root}."
end
# Example # 4
# F(x) = ln^x(x) + 1
# Exact root is not defined
f = lambda { |x| (Math.log(x) ** x) + 1 } # f(x) = ln^x(x) + 1 defined in R
root = find_root(f: f, seed: 2, error_level: 0.00000001)
if root.nil?
puts 'Computed root of F(x) = ln^x(x) + 1 cannot be found or do not exist.'
else
puts "Computed root of F(x) is #{root}."
end
# Example # 5
# F(x) = (x - 1) / (x + 1)
# Exact root is defined at 1
f = lambda { |x| (x - 1) * (x + 1) } # f(x) = (x - 1) * (x + 1) defined in R
root = find_root(f: f, seed: 2, error_level: 0.00000001)
if root.nil?
puts 'Computed root of F(x) cannot be found or do not exist.'
else
puts "Computed root of F(x) = (x - 1)(x + 1) is #{root}. Exact root is 1.0"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment