forked from cvxr/TFOCS
-
Notifications
You must be signed in to change notification settings - Fork 0
/
test_smooth.m
142 lines (119 loc) · 3.26 KB
/
test_smooth.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
function varargout = test_smooth( f, N, DOM )
% TEST_SMOOTH Runs diagnostic checks on a TFOCS smooth function object.
% TEST_SMOOTH( F )
% tests whether the function handle F works as a TFOCS smooth
% function object.
%
% Requirements: f = F(X) must return the value of the function at X.
% [f,g] = F(X) must return the value, f, and the gradient, g.
%
% For an example, see SMOOTH_QUAD.M
%
% TEST_SMOOTH( F, N )
% specifies the size of the domain space. If N is a scalar,
% then the domain space is the set of N x 1 vectors.
% If N is a matrix of the form [n1, n2], the the domain
% space is the set of n1 x n2 matrices.
%
% TEST_SMOOTH( ..., DOM )
% specifies the domain of F. DOM can be of the form [a,b]
% which signifies the 1D set (a,b).
%
% OK = TEST_SMOOTH(...)
% returns "true" if all tests are passed, and "false" otherwise.
%
% See also private/tfocs_smooth, smooth_huber
OK = false;
PLOT = true;
error(nargchk(1,3,nargin));
if ~isa(f,'function_handle')
fail('TFOCS smooth function must be a FUNCTION HANDLE');
return;
end
fprintf('== Testing the smooth function %s ==\n', func2str(f) );
FORCE_N = false; % always require a vector input
if nargin < 2 || isempty(N), N = 10;
else FORCE_N = true;
end
if nargin < 3 || isempty(DOM), DOM = [-1,1]; end
a = DOM(1); b = DOM(2);
x = (a+b)/2;
fprintf('Testing scalar inputs... \n');
try
vi = f(x);
catch
fail('TFOCS smooth function failed to return a function value');
return;
end
if isinf(vi)
fail('TFOCS smooth function tester: default domain is invalid. Please specify valid domain');
return;
end
fprintf('\t\t\t\t...passed. \n');
% Now, also ask for the gradient
fprintf('Testing gradient output... \n');
try
[vi,gi] = f(x);
catch
fail('TFOCS smooth function failed to return a derivative value');
return;
end
fprintf('\t\t\t\t...passed. \n');
% Now, try a vector
if isscalar(N)
x = repmat(x,N,1);
else
x = repmat(x,N(1),N(2));
% if a > 0, assume we want a PSD matrix:
if a >= 0
x = ones(N(1),N(2)) + eye(N(1),N(2) );
end
end
fprintf('Testing vector inputs... \n');
try
[vi,gi] = f(x);
catch
fail('TFOCS smooth function failed when supplied a vector input');
return;
end
fprintf('\t\t\t\t...passed. \n');
% 1D example. Does not require function to be vectorized
n = 100; % number of grid points
h = (b-a)/n;
grid = (a+h/2):h:(b-h/2);
v = zeros(size(grid));
g = zeros(size(grid));
first = @(x) x(1);
for i = 1:length(grid)
v(i) = f(grid(i));
if isinf(v(i))
g(i) = v(i);
else
[v(i),gi] = f(grid(i));
g(i) = first(gi);
end
end
if PLOT
figure;
clf;
plot(grid,v,'.-');
hold all
plot(grid,g,'.-');
legend('function','derivative');
% title(func2str(f),'interpreter','none');
line([a,b], 0*[1,1],'color','k' )
if a < 0 && b > 0
line( 0*[1,1], get(gca,'ylim'),'color','k' );
end
end
OK = true;
if nargout > 0
varargout{1} = OK;
end
disp('Test passed succesfully.');
function fail(str)
disp('Test failed. Reason:');
disp(str);
% TFOCS v1.3 by Stephen Becker, Emmanuel Candes, and Michael Grant.
% Copyright 2013 California Institute of Technology and CVX Research.
% See the file LICENSE for full license information.