#!/usr/bin/env ruby
# Ruby/GSL implementation of GSL "multiroot/test.c"
require("rbgsl")
require("./gsl_test2.rb")
include GSL::Test
include Math
GC.disable
def test_fdf(desc, fdf, initpt, factor, type)
n = fdf.n
x = eval("#{initpt}")
if factor != 1.0
x = x.scale(factor)
end
s = GSL::MultiRoot::FdfSolver.alloc(type, n)
s.set(fdf, x)
iter = 0
begin
iter += 1
status = s.iterate
status = GSL::MultiRoot.test_residual(s.f, 0.0000001)
end while status == GSL::CONTINUE and iter < 1000
jac, stat = GSL::MultiRoot.fdjacobian(fdf, s.x, s.f, GSL::SQRT_DBL_EPSILON)
r = 0.0
sum = 0.0
for i in 0...n
for j in 0...n
u = jac[i][j]
su = s.jac[i][j]
r = (u - su).abs/(1e-6 + 1e-6 * u.abs)
sum += r
if (u - su).abs > (1e-6 + 1e-6 * u.abs)
printf("broken jacobian %g\n", r)
end
end
printf("avg r = %g\n", sum/(n*n))
end
residual = 0.0
for i in 0...n
residual += s.f[i].abs
end
GSL::Test::test(status, "#{type} on #{desc} (#{factor}), #{iter} iterations, residual = #{residual}")
end
def test_f(desc, fdf, initpt, factor, type)
n = fdf.n
x = eval("#{initpt}")
x = x.scale(factor)
function = GSL::MultiRoot::Function.alloc(fdf.f, fdf.n)
s = GSL::MultiRoot::FSolver.alloc(type, n)
s.set(function, x)
iter = 0
begin
iter += 1
status = s.iterate
status = GSL::MultiRoot.test_residual(s.f, 0.0000001)
end while status == GSL::CONTINUE and iter < 1000
residual = 0.0
for i in 0...n
residual += s.f[i].abs
end
GSL::Test::test(status, "#{type} on #{desc} (#{factor}), #{iter} iterations, residual = #{residual}")
end
def roth_initpt
return GSL::Vector.alloc(4.5, 3.5)
end
def wood_initpt
return GSL::Vector.alloc(-3.0, -1.0, -3.0, -1.0)
end
def rosenbrock_initpt
GSL::Vector.alloc(-1.2, 1.0)
end
roth_f = Proc.new { |x, f|
u = x[0]
v = x[1]
f[0] = -13.0 + u + ((5.0 - v)*v - 2.0)*v;
f[1] = -29.0 + u + ((v + 1.0)*v - 14.0)*v;
}
roth_df = Proc.new { |x, df|
x1 = x[1]
df.set(0, 0, 1.0)
df.set(0, 1, -3 * x1 * x1 + 10 * x1 - 2)
df.set(1, 0, 1.0)
df.set(1, 1, 3 * x1 * x1 + 2 * x1 - 14)
}
rosenbrock_f = Proc.new { |x, f|
x0 = x[0]; x1 = x[1]
y0 = 1.0 - x0
y1 = 10*(x1 - x0*x0)
f[0] = y0
f[1] = y1
GSL::SUCCESS
}
rosenbrock_df = Proc.new { |x, df|
x0 = x[0]
df00 = -1.0
df01 = 0.0
df10 = -20*x0
df11 = 10
df.set(0, 0, df00)
df.set(0, 1, df01)
df.set(1, 0, df10)
df.set(1, 1, df11)
GSL::SUCCESS
}
roth = GSL::MultiRoot::Function_fdf.alloc(roth_f, roth_df, 2)
rosenbrock = GSL::MultiRoot::Function_fdf.alloc(rosenbrock_f, rosenbrock_df, 2)
fsolvers = ["dnewton", "broyden", "hybrid", "hybrids"]
fsolvers.each do |type|
test_f("Roth", roth, "roth_initpt", 1.0, type)
test_f("Rosenbrock", rosenbrock, "rosenbrock_initpt", 1.0, type)
end
exit
f = 1.0
fdfsolvers = ["newton", "gnewton", "hybridj", "hybridsj"]
fdfsolvers.each do |type|
test_fdf("Roth", roth, "roth_initpt", f, type)
end
syntax highlighted by Code2HTML, v. 0.9.1