From: Michael Orlitzky Date: Wed, 13 Mar 2013 18:04:55 +0000 (-0400) Subject: Add extended_powell functions and their tests. X-Git-Url: http://gitweb.michael.orlitzky.com/?p=octave.git;a=commitdiff_plain;h=30c26967dbc89131a09979fa8937eac0ef7a73b4 Add extended_powell functions and their tests. --- diff --git a/optimization/test_functions/extended_powell1.m b/optimization/test_functions/extended_powell1.m new file mode 100644 index 0000000..2b1da25 --- /dev/null +++ b/optimization/test_functions/extended_powell1.m @@ -0,0 +1,33 @@ +function f = extended_powell1(x) + ## + ## The extended Powell function. See Dennis & Schnabel, Appendix B, + ## problem #2. + ## + ## This function has a minimum at x=(0,0,...,0) with f(x) == 0. The + ## suggested starting point is x0=(3, -1, 0, 1,..., 3, -1, 0, 1). + ## Since the number of arguments is variable, we take a vector + ## instead of its individual components. + ## + n = length(x); + + if (odd(n)) + ## 'm' below must be an integer. + f = NA; + return; + end + + m = n / 4; + f = 0; + + % The extended Powell is simply a sum of Powell + % applications. + for k = [ 1 : m ] + y1 = x(4*k - 3); + y2 = x(4*k - 2); + y3 = x(4*k - 1); + y4 = x(4*k); + + f_k = powell(y1,y2,y3,y4); + f = f + f_k; + end +end diff --git a/optimization/test_functions/extended_powell_gradient1.m b/optimization/test_functions/extended_powell_gradient1.m new file mode 100644 index 0000000..7cc7aab --- /dev/null +++ b/optimization/test_functions/extended_powell_gradient1.m @@ -0,0 +1,35 @@ +function g = extended_powell_gradient1(x) + ## + ## The gradient of the extended Powell function. See + ## extended_powell1.m for more information. + ## + ## Since the number of arguments is variable, we take a vector + ## instead of its individual components. + ## + n = length(x); + + if (odd(n)) + ## 'm' below must be an integer. + g = NA; + return; + end + + m = n / 4; + g = zeros(n, 1); + + % The extended Powell is simply a sum of Powell + % applications. + for k = [ 1 : m ] + y1 = x(4*k - 3); + y2 = x(4*k - 2); + y3 = x(4*k - 1); + y4 = x(4*k); + + g_k = powell_gradient(y1, y2, y3, y4); + + for i = [ 1 : 4 ] + g(4*(k-1) + i) = g(4*(k-1) + i) + g_k(i); + end + + end +end diff --git a/optimization/test_functions/extended_powell_hessian1.m b/optimization/test_functions/extended_powell_hessian1.m new file mode 100644 index 0000000..972e690 --- /dev/null +++ b/optimization/test_functions/extended_powell_hessian1.m @@ -0,0 +1,38 @@ +function H = extended_powell_hessian1(x) + ## + ## The Hessian of the extended Powell function. See + ## extended_powell1.m for more information. + ## + ## Since the number of arguments is variable, we take a vector + ## instead of its individual components. + ## + n = length(x); + + if (odd(n)) + ## 'm' below must be an integer. + H = NA; + return; + end + + m = n / 4; + H = zeros(n, n); + + % The extended Powell is simply a sum of Powell + % applications. + for k = [ 1 : m ] + y1 = x(4*k - 3); + y2 = x(4*k - 2); + y3 = x(4*k - 1); + y4 = x(4*k); + + H_k = powell_hessian(y1, y2, y3, y4); + + for i = [ 1 : 4 ] + for j = [ 1 : 4 ] + H(4*(k-1) + i, 4*(k-1) + j) = ... + H(4*(k-1) + i, 4*(k-1) + j) + H_k(i,j); + end + end + + end +end diff --git a/tests/extended_powell1_tests.m b/tests/extended_powell1_tests.m new file mode 100644 index 0000000..990eae6 --- /dev/null +++ b/tests/extended_powell1_tests.m @@ -0,0 +1,14 @@ +## Test the optimal point. + +for m = [ 1 : 10 ] + x = repmat([0;0;0;0], m, 1); + + msg = sprintf("extended_powell1([0;0;0;0...]) == 0 (m = %d)", m); + unit_test_equals(msg, 0, extended_powell1(x)); +end + +## It should fail with the wrong number of coordinates. +f = extended_powell1([1]); +unit_test_equals("extended_powell1 fails when length(x) is odd", ... + true, ... + isna(f)); diff --git a/tests/extended_powell_gradient1_tests.m b/tests/extended_powell_gradient1_tests.m new file mode 100644 index 0000000..5be0a6d --- /dev/null +++ b/tests/extended_powell_gradient1_tests.m @@ -0,0 +1,13 @@ +## The gradient should be zero at the optimal point. + +for m = [ 1 : 10 ] + x = repmat([0;0;0;0], m, 1); + + msg = sprintf("extended_powell_gradient1([0;0;0;0;...]) == 0 (m = %d)", m); + unit_test_equals(msg, 0, extended_powell_gradient1(x)); +end + +## It should fail with the wrong number of coordinates. +g = extended_powell_gradient1([1;2;3]); +msg = "extended_powell_gradient1 fails when length(x) is odd"; +unit_test_equals(msg, true, isna(g)); diff --git a/tests/extended_powell_hessian1_tests.m b/tests/extended_powell_hessian1_tests.m new file mode 100644 index 0000000..6b65533 --- /dev/null +++ b/tests/extended_powell_hessian1_tests.m @@ -0,0 +1,9 @@ +## When m=1 we should agree with powell_hessian1(). + +x = [4;5;6;7]; +f1 = powell_hessian1(x); +f2 = extended_powell_hessian1(x); + +unit_test_equals("(extended_)powell_hessian1 agree for m=1", ... + true, ... + f1 == f2);