#!/usr/bin/env ruby
# Ruby/GSL implementation of GSL "multimin/test.c"
require("rbgsl")
require("./gsl_test2.rb")
include GSL::Test
include Math
def test_fdf(desc, f, initpt, type)
x = eval("#{initpt}")
step_size = 0.1*Blas.dnrm2(x)
s = GSL::MultiMin::FdfMinimizer.alloc(type, f.n)
s.set(f, x, step_size, 0.1)
iter = 0
begin
iter += 1
status = s.iterate
status = GSL::MultiMin.test_gradient(s.gradient, 1e-3)
end while iter < 5000 and status == GSL::CONTINUE
status |= s.f.abs > 1e-5 ? 1 : 0
GSL::Test::test(status, "#{s.name}, on #{desc}: #{iter} iterations, f(x)=#{s.f}")
end
def test_f(desc, f, initpt)
x = eval("#{initpt}")
step_size = GSL::Vector.alloc(f.n)
for i in 0...f.n
step_size[i] = 1
end
s = GSL::MultiMin::FMinimizer.alloc("nmsimplex", f.n)
s.set(f, x, step_size)
iter = 0
begin
status = s.iterate
status = GSL::MultiMin.test_size(s.size, 1e-3)
end while iter < 5000 and status == GSL::CONTINUE
status |= s.fval.abs > 1e-5 ? 1 : 0
GSL::Test::test(status, "#{s.name}, on #{desc}: #{iter} iterations, f(x)=#{s.fval}")
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
return GSL::Vector.alloc(-1.2, 1.0)
end
Roth_f = Proc.new { |x|
u = x[0]
v = x[1]
a = -13.0 + u + ((5.0 - v)*v - 2.0)*v;
b = -29.0 + u + ((v + 1.0)*v - 14.0)*v;
a * a + b * b;
}
Roth_df = Proc.new { |x, df|
u = x[0]
v = x[1]
a = -13.0 + u + ((5.0 - v)*v - 2.0)*v
b = -29.0 + u + ((v + 1.0)*v - 14.0)*v
c = -2 + v * (10 - 3 * v)
d = -14 + v * (2 + 3 * v)
df[0] = 2 * a + 2 * b
df[1] = 2 * a * c + 2 * b * d
}
Wood_f = Proc.new { |x|
u1 = x[0]; u2 = x[1]; u3 = x[2]; u4 = x[3]
t1 = u1*u1 - u2
t2 = u3*u3 - u4
100 * t1 * t1 + (1 - u1) * (1 - u1) + 90 * t2 * t2 + (1 - u3) * (1 - u3) + 10.1 * ( (1 - u2) * (1 - u2) + (1 - u4) * (1 - u4) ) + 19.8 * (1 - u2) * (1 - u4)
}
Wood_df = Proc.new { |x, df|
u1 = x[0]; u2 = x[1]; u3 = x[2]; u4 = x[3]
t1 = u1*u1 - u2
t2 = u3*u3 - u4
df[0] = 400 * u1 * t1 - 2 * (1 - u1)
df[1] = -200 * t1 - 20.2 * (1 - u2) - 19.8 * (1 - u4)
df[2] = 360 * u3 * t2 - 2 * (1 - u3)
df[3] = -180 * t2 - 20.2 * (1 - u4) - 19.8 * (1 - u2)
}
Rosenbrock_f = Proc.new { |x|
u = x[0]; v = x[1]
a = u - 1
b = u*u - v
a*a + 10.0*b*b
}
Rosenbrock_df = Proc.new { |x, df|
u = x[0]; v = x[1]
a = u - 1
b = u*u - v
df[0] = 2 * (u - 1) + 40 * u * b
df[1] = -20 * b
}
if GSL::GSL_VERSION >= "1.8.90"
fdfminimizers = ["steepest_descent", "conjugate_pr", "conjugate_fr",
"vector_bfgs", "vector_bfgs2"]
else
fdfminimizers = ["steepest_descent", "conjugate_pr", "conjugate_fr",
"vector_bfgs"]
end
Rothdf = GSL::MultiMin::Function_fdf.alloc(Roth_f, Roth_df, 2)
Wooddf = GSL::MultiMin::Function_fdf.alloc(Wood_f, Wood_df, 4)
Rosenbrockdf = GSL::MultiMin::Function_fdf.alloc(Rosenbrock_f, Rosenbrock_df, 2)
fdfminimizers.each do |t|
test_fdf("Roth", Rothdf, "roth_initpt", t)
test_fdf("Wood", Wooddf, "wood_initpt", t)
test_fdf("Rosenbrock", Rosenbrockdf, "rosenbrock_initpt", t)
end
rothf = GSL::MultiMin::Function.alloc(Roth_f, 2)
test_f("Roth", rothf, "roth_initpt")
woodf = GSL::MultiMin::Function.alloc(Wood_f, 4)
test_f("Wood", woodf, "wood_initpt")
rosenbrockf = GSL::MultiMin::Function.alloc(Rosenbrock_f, 2)
test_f("Rosenbrock", rosenbrockf, "rosenbrock_initpt")
syntax highlighted by Code2HTML, v. 0.9.1