
Here is a short example showing the power of Compressed Sensing. I modified a small program written by Emmanuel Candes from his short course at IMA ("The role of probability in compressive sampling", Talks(A/V) (ram)).
Before you continue on, you need to have Matlab and SeDuMi installed on your system. Let us imagine you have a function f that is unknown to you but for which you know it is sparsely composed of sine functions. Let us imagine for the sake of argument that:
f(x)=2*sin(x)+sin(2x)+21*sin(300x)
The normal way of finding what this decomposition is by computing the scalar product of this function f with sines and cosines with as large as possible of frequency content (in order to capture the high frequency content of this function). This is done iteratively because one doesn't know in advance that a frequency of 300 is part of the solution. But in effect, one is solving a least square problem.
With Compressed Sensing, we know that if we are to measure this function with an incoherent basis to sines and cosines, we are likely to find the decomposition using the L1 minimization. We know that diracs and sines are incoherent (please note we are not using random projections), so we evaluate the scalar product of f with several diracs functions centered at say 18 different locations. In effect, we query for the value of f(x) at the following points x -chosen at random by hand- : 1, 4, 6, 12, 54, 69, 75, 80, 89, 132, 133, 152, 178, 230, 300, 340, 356, 400
We then use these values to solve for the coefficients of the sine series expansion of f(x) by doing an L1 minimization using SeDuMi:
clear
% size of signal
n = 512;
x0 = zeros(n,1);
% function is f(x)=2*sin(x)+sin(2x)+21*sin(300x)
x0(1)=2;
x0(2)=1;
x0(300)=21;
% evaluating f at all sample points xx
% f(1), f(4), f(6).....f(340) f(356) f(400)
xx=[1 4 6 12 54 69 75 80 89 132 133 152 178 230 300 340 356 400];
% C is measurement matrix
for i=1:n
C(:,i)=sin(i*xx)';
end
b = C*x0;
% b is the result of evaluating f at all sample points xx
% f(1), f(4), f(6).....f(340) f(356) f(400)
% C is the measurement matrix
% let us solve for x and see if it is close to x0
% solve l1-minimization using SeDuMi
cvx_begin
variable x(n);
minimize(norm(x,1));
subject to
C*x == b;
cvx_end
figure(1)
plot(abs(x-x0),'o')
title('Error between solution solution found by L1 and actual solution')
figure(2)
plot(x,'*')
hold
plot(x0,'o')
title('Solution found for x using L1 minimization')
With only 20 function evaluations we have a near exact reconstruction. You may want to try the the L2 norm (or least-square) by replacing:
minimize(norm(x,1));
by
minimize(norm(x,2));and then change the number of function evaluations needed to reach the same result. With 200 functions evaluations, the error between the reconstructed solution and the actual solution is several orders of magnitude larger than the L1 technique with 20 functions evaluations.
Pretty neat uh ?
If you think this blog provides a service, please support it by ordering through the Amazon - Nuit Blanche Reference Store


31 comments:
Is the effect as impressive when noise is added?
I did
b = C*(x0+epsilon*randn(size(x0)));
and for epsilon = 0.001, it broke the algorithm down. This makes sense because the resulting vector is no longer sparse in the dictionary chosen; however, this situation happens in practice all the time. Any way to combat this theoretically or algorithmically?
Hello Anonymous,
Yes, it has to break down. The example is featured to show
- that you don't need to have a random projection to find a solution to compressed sensing.
- It is also there to show that how profoundly it would be different to solve an integral or a PDE using this type of technique instead of using a weak formulation (L2 based) as we have been accustomed to do for the past two hundred years.
- I also wanted to illustrate the issue of coherence. In this case, the noise is coherent with the diracs, so the sines cannot make a difference between the signal you want (diracs) and the noise.
I agree with you: noise happens all the time. But in most real cases, you don't have diracs but rather gaussians or wavelet like functions. One really is then looking for families of function that are incoherent with the gaussians or wavelets and coherent with the noise. Noiselets seem to fit that bill.
http://nuit-blanche.blogspot.com/search?q=noiselet
R. Coifman, F. Geshwind, and Y. Meyer. Noiselets. Appl. Comp. Harmonic Analysis, 10:27–44, 2001
Evidently, if the signal is made of gaussians or wavelets, random projections are ok. Random basis are indeed incoherent with the signal to be studied but are coherent with the noise. Results of Donoho, Candes and others show the ability to retrieve the signal of interest under random projections when noise is present.
Igor.
Interesting staff.
Two questions:
Where is the spot above 400 comes from? The highest frequency should be 300, isn't it? I try adding different frequency components to y, if the highest frequency in y is less than a certain value, this unexpected spot gone, otherwise, this spot will always be here. Look similar to the frequency alias when sampling a signal at a rate that is less than its Nyquist-rate.
Also, this algorithm seems to be sensitive to the frequency, I replace sin(2*x) with sin(2.01*x) in y, this algorithm fails to detect this frequency component. Any explain to this?
Thanks.
Jing,
I know I am answering this very late but for the second part of your question, please note that you cannot find a frequency that is not in the dictionnary in the first place. All frequencies are integer from 1 to 512 and do not include 2.01, so it cannot find it.
I think the answer to the first part of your question is similar.
Igor.
??? Undefined function or variable "cvx_begin".
Error in ==> how_to_wow_your_friends_CS at 22
cvx_begin
I am using MATLAB 7.0 and the sedumi is installed
Hello Anonymous,
Even though sedumi is installed, are you sure it works, or that it is in your path ? It looks to me like a sedumi specific error, you might want to contact them directly.
So that you know, I am going to try to make that example sedumi agnostic in the future since we now have at least in-house solvers ( http://igorcarron.googlepages.com/cscodes#sp )
Igor.
How can I use this 'example' if I have a 32 bit pc (which is suppose to avoid me for using Sedumi and so the optimiztion L1, L2, etc?
thanks,
Juan C.
Juan,
Sedumi works in 32 bit. You just need to use Sedumi 1.1.
Cheers,
Igor.
This example is somewhat confusing for me.
Your "measurement matrix" should actually be a bunch of diracs, which are multiplied by f(x) in order to derive b, right? You just didn't show this part.
You then replaced this "measurement matrix" with a new matrix C that contains sine waves (your basis vectors) and used this to derive the coefficients of f(x) in the basis of sine waves. Let's call C the "new matrix".
How did you know which sine waves to include in your new matrix C? Why does having a dirac(4) in your measurement matrix mean that you have to have a sine(4x) in your new matrix? I didn't know there was a relationship between dirac(4) in the time domain and dirac(4) in the frequency domain. Am I missing something?
hello Anonymous,
Generally, in CS, the system of equations is:
y = \phi * \psi * alpha
I am making the assumption that the unknown function f is really a composition of several sine functions that are listed in the \psi matrix or:
f = \psi * alpha
In other words, when alpha is sparse, f is sparse in the family of sine functions.
\phi is a dictionary of incoherent functions (incoherent with respect to sines). It is made up of diracs centered on integer points of the w-axis.
The matrix C you are refering to is just \phi * \psi
Elements of C are really the inner products of sin(w_j * x) and dirac(w - w_i).
y = C * alpha
and
f(x) = sum(alpha_j * sin(w_j * x))
alpha (made of alpha_j) is the list of coefficients (sparse) representing the frequency content of function f.
Hope this helps, let me know if this is not clear.
Cheers,
Igor.
Is it possible to equivalently look at the problem as that of measuring a signal that consists of impulses at different time instances? Then, C, the measurement matrix is equivalent to the Fourier measurement matrix, thus measuring the signal at random modulations. The solution of ell-1 minimization would then be the original signal, which is sparse in time.
Sure it could.
Igor.
Hello Igore,
measurement matrix(C) don't satisfies RIP condition :
n = 512;
x0 = zeros(n,1);
x0(1)=2;
x0(2)=1;
x0(300)=21;
xx=[1 4 6 12 54 69 75 80 89 132 133 152 178 230 300 340 356 400];
for i=1:n
C(:,i)=sin(i*xx)';
end
b = C*x0;
>> norm(x0)
ans =
21.1187
>> norm(b)
ans =
60.1531
why?,
thanks.
Regarding the cvx_begin error above...
I had this problem too. You need to install CVX:
http://www.stanford.edu/~boyd/cvx/download.html
This is not part of SeDuMi - I guess you need both installed?
It's working for me now. I use Matlab 7.8 on a macbook pro. Once again, it only started working once I installed SeDuMi and CVX.
Cheers!
I don't know if it is too late to ask question. If I replace x0(2)=1 by x0(5)=10, it does not work. I also tried adding a fourth frequency component and it failed. Why?
With x0(5) in there, if I specify a sampling point at 30, making the xx array 19 elements long, it works again.
Bhaskar,
If you increase the number of samples, you will likely have convergence most of the time. 18 samples is kind of minimum but with 50 you should always be able to recover the solution.
Hope this helps,
Igor.
Hi igor. I tryed to use your algorithm and i found a matlab error, can you help me?
?? Error: File: C:\matlabR12\work\how_to_wow_your_friends_CS.m Line: 23 Column: 18
Missing operator, comma, or semicolon.
Regards
Mark
Mark,
Please make sure you are doing the right cut and paste. Sometimes, the procedure of cutting and pasting bring extra characters invisible to the eye.
Cheers,
Igor.
Thanks Igor.
It is not working on my MLab, I typed line by line and nothing. Is that possible you send me yoir .m file?
Regards Mark
Thank you James!
Hopefully my question is not too later. This is a fantastic program. I modified the program a bit:
change sin(i*xx) to sin(pi*1*xx)
And the program cannot find the right answer. Can you explain it?
hello igor
can you tell me how can i use CS on images?
Think of an imgae as a matrix, decompose tha matrix as a series of vectors (i.e. Concatenate these vectors into one large vector) and tada yo have linear system of equation
Ax = b.
yeah i have already done that. but i want to do it without braking image into vectors. like if i take dct2 of an image and then multiply with sensing matrix, then how can i reconstruct it?
regarda abiha!
If you take the DCT2 you have already transformed your image, so i am not sure i understand. Have you looked through any of he courses listed below:
http://nuit-blanche.blogspot.com/p/teaching-compressed-sensing.html
Igor.
if the image is not sparse in time domain and it is sparse in some other domain, like i supposed that if i take dct2 and get the sparse image, then multiply with sensing matrix, recover and then take idct2.. but the problem is that how can i recover a matrix instead of a vector? and how can i define a sending matrix for a matrix?
i hope i have made it clear...
waiting for reply..
The least you could do is acknowledge that you have read the web page I mentioned earlier, have you ?
not the one you have mentioned,but i have read about compressive sensing from other sites.
Not the right ones obviously. Please read and find in the link the answer to your question. If you cannot find please come back and let me know what you have read and point to me exactly what is it you don't understand.
Cheers,
Igor.
Post a Comment