2021-07-23 19:42:30 +02:00
debug = false ;
if debug
[ top_test_dir , ~ , ~ ] = fileparts ( mfilename ( ' fullpath' ) ) ;
else
top_test_dir = getenv ( ' TOP_TEST_DIR' ) ;
end
addpath ( sprintf ( ' %s/matlab' , top_test_dir ( 1 : end - 6 ) ) )
addpath ( sprintf ( ' %s/tests/solver-test-functions' , top_test_dir ( 1 : end - 6 ) ) )
if ~ debug
% Test Dynare Version
if ~ strcmp ( dynare_version ( ) , getenv ( ' DYNARE_VERSION' ) )
error ( ' Incorrect version of Dynare is being tested' )
end
end
dynare_config ;
NumberOfTests = 0 ;
testFailed = 0 ;
if ~ debug
skipline ( )
disp ( ' *** TESTING: nonlinearsolvers.m ***' ) ;
end
tolf = 1e-6 ;
tolx = 1e-6 ;
maxit = 50 ;
factor = 10 ;
auxstruct = struct ( ) ;
2022-03-11 18:39:40 +01:00
% List of function handles
objfun = { @ rosenbrock ,
@ powell1 ,
@ powell2 ,
@ wood ,
@ helicalvalley ,
@ watson ,
@ chebyquad ,
@ brown ,
@ discreteboundaryvalue ,
@ discreteintegralequation ,
@ trigonometric ,
@ variablydimensioned ,
@ broydentridiagonal ,
@ broydenbanded } ;
% FIXME block_trust_region (mex) or trust_region (matlab) do not work for all n (not sure we can fix that).
% FIXME block_trust_region (mex) and trust_region (matlab) do not behave the same (spurious convergence for powell2 and trigonometric with block_trust_region).
%
% Test mex routine
%
2021-07-23 19:42:30 +02:00
2022-03-11 18:39:40 +01:00
t0 = clock ;
2021-07-23 19:42:30 +02:00
2022-03-11 18:39:40 +01:00
for i = 1 : length ( objfun )
2021-07-23 19:42:30 +02:00
NumberOfTests = NumberOfTests + 1 ;
2022-03-11 18:39:40 +01:00
switch func2str ( objfun { i } )
case ' helicalvalley'
% FIXME block_trust_region is diverging if x(1)<0.
x = helicalvalley ( ) ;
x ( 1 ) = 5 ;
case ' chebyquad'
% Fails with a system of 10 equations.
x = objfun { i } ( nan ( 9 , 1 ) ) ;
case { ' watson' , ' brown' , ' discreteintegralequation' , ' discreteboundaryvalue' , ' chebyquad' , ' trigonometric' , ' variablydimensioned' , ' broydenbanded' , ' broydentridiagonal' }
x = objfun { i } ( nan ( 4 , 1 ) ) ;
otherwise
x = objfun { i } ( ) ;
2021-07-23 19:42:30 +02:00
end
2022-03-11 18:39:40 +01:00
try
2022-03-25 18:09:57 +01:00
[ x , errorflag , exitflag ] = block_trust_region ( objfun { i } , x , tolf , tolx , maxit , factor , false , auxstruct ) ;
2022-03-11 18:39:40 +01:00
if isequal ( func2str ( objfun { i } ) , ' powell2' )
if ~ errorflag
testFailed = testFailed + 1 ;
if debug
dprintf ( ' Nonlinear solver is expected to fail on %s function but did not return an error.' , func2str ( objfun { i } ) )
end
end
else
if errorflag || norm ( objfun { i } ( x ) ) > tolf
testFailed = testFailed + 1 ;
if debug
dprintf ( ' Nonlinear solver (mex) failed on %s function (norm(f(x))=%s).' , func2str ( objfun { i } ) , num2str ( norm ( objfun { i } ( x ) ) ) )
end
end
end
catch
2021-07-23 19:42:30 +02:00
testFailed = testFailed + 1 ;
2022-03-11 18:39:40 +01:00
if debug
dprintf ( ' Nonlinear solver (mex) failed on %s function.' , func2str ( objfun { i } ) )
end
2021-07-23 19:42:30 +02:00
end
end
2022-03-11 18:39:40 +01:00
t1 = clock ; etime ( t1 , t0 )
2021-07-23 19:42:30 +02:00
2022-03-11 18:39:40 +01:00
%
% Test matlab routine
%
2021-07-23 19:42:30 +02:00
2022-03-11 18:39:40 +01:00
for i = 1 : length ( objfun )
2021-07-23 19:42:30 +02:00
NumberOfTests = NumberOfTests + 1 ;
2022-03-11 18:39:40 +01:00
switch func2str ( objfun { i } )
case ' chebyquad'
% Fails with a system of 10 equations.
x = objfun { i } ( nan ( 9 , 1 ) ) ;
case { ' watson' , ' brown' , ' discreteintegralequation' , ' discreteboundaryvalue' , ' trigonometric' , ' variablydimensioned' , ' broydenbanded' , ' broydentridiagonal' }
x = objfun { i } ( nan ( 10 , 1 ) ) ;
otherwise
x = objfun { i } ( ) ;
2021-07-23 19:42:30 +02:00
end
2022-03-11 18:39:40 +01:00
try
[ x , errorflag , info ] = trust_region ( objfun { i } , x , 1 : length ( x ) , 1 : length ( x ) , true , [ ] , tolf , tolx , maxit , factor ) ;
if isequal ( func2str ( objfun { i } ) , ' powell2' )
if ~ errorflag
testFailed = testFailed + 1 ;
if debug
dprintf ( ' Nonlinear solver is expected to fail on %s function but did not return an error.' , func2str ( objfun { i } ) )
end
end
if info ~= 3
testFailed = testFailed + 1 ;
if debug
dprintf ( ' Nonlinear solver is expected to fail on %s function with info==3 but did not the correct value of info.' , func2str ( objfun { i } ) )
end
end
else
if errorflag
testFailed = testFailed + 1 ;
if debug
dprintf ( ' Nonlinear solver failed on %s function (info=%s).' , func2str ( objfun { i } ) , int2str ( info ) )
end
end
end
catch
2021-07-23 19:42:30 +02:00
testFailed = testFailed + 1 ;
2022-03-11 18:39:40 +01:00
if debug
dprintf ( ' Nonlinear solver failed on %s function.' , func2str ( objfun { i } ) )
end
2021-07-23 19:42:30 +02:00
end
end
2022-03-11 18:39:40 +01:00
t2 = clock ; etime ( t2 , t1 )
2021-07-23 19:42:30 +02:00
if ~ debug
cd ( getenv ( ' TOP_TEST_DIR' ) ) ;
else
dprintf ( ' FAILED tests: %i' , testFailed )
end
if isoctave
fid = fopen ( ' nonlinearsolvers.o.trs' , ' w+' ) ;
else
fid = fopen ( ' nonlinearsolvers.m.trs' , ' w+' ) ;
end
if testFailed
2022-03-11 18:39:40 +01:00
fprintf ( fid , ' :test-result: FAIL\n' ) ;
2021-07-23 19:42:30 +02:00
else
2022-03-11 18:39:40 +01:00
fprintf ( fid , ' :test-result: PASS\n' ) ;
2021-07-23 19:42:30 +02:00
end
fprintf ( fid , ' :number-tests: %i\n' , NumberOfTests ) ;
fprintf ( fid , ' :number-failed-tests: %i\n' , testFailed ) ;
fprintf ( fid , ' :list-of-passed-tests: nonlinearsolvers.m\n' ) ;
2022-03-11 18:39:40 +01:00
fprintf ( fid , ' :elapsed-time: %f\n' , etime ( t2 , t0 ) ) ;
2021-07-23 19:42:30 +02:00
fclose ( fid ) ;
if ~ debug
exit ;
end