I was implementing image denoising based on TV minimisation. So the code goes like:
cvx_begin
variable xrec(n,m)
minimise (norm(xrec-A))
subject to
tvTest(xrec)<=780;
cvx_end
Here A is the noisy image. (n,m) is the size of the image, and tvTest is a function that evaluates the total variation of the image:
function [s] = tvTest(img)
%% Computes the total variation of the image.
[ux, uy] = gradient(img); % ux <- x-gradient of the image
% uy <- y-gradient of the image
ds = sqrt(abs(ux).^2 + abs(uy).^2); % Square of both ux and uy
s = sum(ds(:)); % Total Variation of the image;
end
The code gives error:
Error using zeros CLASSNAME input must be a valid numeric or logical class name.
Error in gradient (line 56) g = zeros(size(f),class(f)); % case of singleton dimension
I understand that it is not able to apply the gradient on xrec. But then what could be the solution. Can’t I use a function on xrec?
Given that tvTest is called with a CVX variable argument img', all the operations on img within that function must satisfy CVX’s rules. In particular, the MATLAB function gradient is not supported by CVX; therefore it can not be applied to the argument img.
However, I believe gradient is just performing numerical differentiation, so you could implement it yourself, and it should result in an x,y vector of affine CVX expressions. (Note that unfortunately, diff is not supported by CVX either). Then ds can be computed using norm, which can be applied to affine CVX expressions. You can not compute ds as you have done, because although convex, it violates CVX’s rules (that’s why you use norm instead).