Donoho-Tanner Phase Transition Matlab - matlab

I'm trying to create phase-transition plots in Matlab, but don't know how to program the acutal plots. My data is, for example, the following matrix:
0 0 0 0 0 0 0 0 0 0 0 1.0000
0 0 0 0 0 0 0 0 0 0 0 1.0000
0 0 0 0 0 0 0 0 0 0 0 1.0000
0 0 0 0 0 0 0 0 0 0 0 1.0000
0 0 0 0 0 0 0 0 0 0 0.1000 1.0000
0 0 0 0 0 0 0 0 0 0 0.2000 1.0000
0 0 0 0 0 0 0 0 0 0.2000 0.3000 1.0000
0 0 0 0 0 0 0 0 0 0.1000 0.5000 1.0000
0 0 0 0.1000 0 0.4000 0.3000 0.5000 0.7000 1.0000 0.9000 1.0000
0.6000 0.4000 0.8000 0.9000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000
For now, what I want to do is basically plot the rows against the columns and represent the entries as shades, for example with 1 being represented as white and 0 being represented as black. The result should look somehting like this:
Thanks in advance!

use imagesc
colormap(gray)
imagesc(my_data,[0 1])
0 maps to black and 1 maps to white

Related

How to reorder the rows and columns of a matrix multiplying a vector indexed by (i,j)

I am trying to construct a particular matrix A which multiplies a column vector v= [p_0,0; p_0,1; ... p_0,N; p_1,0; ...; p_N,N].
I know the required matrix (B say) if the vector v was rearranged in the order given by sorting by the second index before the first ( i.e if v were [p_0,0; p_1,0; ... p_N,0; p_0,1; ...; p_N,N]), however would like to rearrange the rows and columns of this matrix to obtain A so that it multiplies the correctly ordered v.
Example:
B =
-2.6667 1.0000 0 0 0 0 0 0 0
-0.5000 0 0.5000 0 0 0 0 0 0
0 -1.0000 -0.4706 0 0 0 0 0 0
0 0 0 -2.6667 1.0000 0 0 0 0
0 0 0 -0.5000 0 0.5000 0 0 0
0 0 0 0 -1.0000 -0.4706 0 0 0
0 0 0 0 0 0 -2.6667 1.0000 0
0 0 0 0 0 0 -0.5000 0 0.5000
0 0 0 0 0 0 0 -1.0000 -0.4706
multiplying v in the wrong order
p_0,0
p_1,0
p_2,0
p_0,1
p_1,1
p_2,1
p_0,2
p_1,2
p_2,2
As long as I understood, you want to convert matrix B to the matrix A in the following order:
v1= [p_0,0; p_0,1; ... p_0,N; p_1,0; ...; p_N,N]
v2=[p_0,0; p_1,0; ... p_N,0; p_0,1; ...; p_N,N]
where A*v1 equals to B*v2.
For this, you need swapping of each row of the matrix.
Try this code:
m=length(B); % m is equal to NxN
N=sqrt(m);
A=zeros(m,m);
for i=0:N-1
for j=0:N-1
A(j+i*N+1,:)=B(i+N*j+1,:);
end
end

Add programmatically random values to a matrix using matlab

I am new to Matlab and I am trying to create programmatically a square Matrix which may have some random stochastic columns but I can't come up with a working solution. By stochastic column I mean the sum of the column elements which are positive should be equal to 1 (the column non-zero elements should be the same and their sum equal to 1). The position of the non-zero elements is not important in the matrix. PS: some columns could be all-zero elements and some could be with only one non-zero element, in this case 1.
I need your guidance or an example of working code on this guys. Thanks in advance.
Here is an example:
A=
0.2500 0.5000 0 0 0 0 0
0.2500 0.5000 0.3333 0 0 0 0
0 0 0.3333 0.2500 0 0 0.3333
0.2500 0 0 0.2500 0 0.5000 0
0.2500 0 0 0.2500 0 0 0
0 0 0 0.2500 0 0.5000 0.3333
0 0 0.3333 0 0 0 0.3333
% here is my code but it's not doing the work yet
n = 5;
A = zeros(n, 5);
i = 0;
for i = 1:n
if rand < 0.5
i = i + 1;
A(i, :) = rand(1, 5);
end
end
A = A(1:i, :)
First generate a random floating point matrix and threshold as you have done. Once you threshold this, simply sum along each column, then divide every column by the sum. Broadcasting will be useful here so that you avoid having to loop through or replicate the summed values per column over all rows.
Something like this should work:
n = 7;
A = rand(n, n) >= 0.5;
sumA = sum(A, 1);
A = bsxfun(#rdivide, A, sumA);
% Or in MATLAB R2016b and up:
% A = A ./ sumA;
A(isnan(A)) = 0;
The first two lines are self-explanatory. Choose n, then create a n x n square matrix of random 0s and 1s. The third line finds the sum of each column, and the fourth line which is the pièce de resistance is taking the sum of each column and doing an internal replication so that you create a temporary matrix that is the same size as the random matrix, but each column contains the total sum for that column. You then divide element wise and that produces your result. This is achieved with the bsxfun function. The last line of code is very important. Supposing that you have a column where there are no 1s. This means that when it's time to normalize, we will encounter a 0 / 0 error which translates to NaN. The last line of code finds any values that are NaN and sets them to 0.
Alternatively in MATLAB R2016b and up, you can simply do the element-wise division operator ./ and it does the broadcasting already.
Example Run
After running the above code, this is one potential result:
>> A
A =
0.2500 0.5000 0 0.2500 0 0 0
0 0 0.2500 0.2500 1.0000 0 0
0 0 0 0.2500 0 0.2500 0.3333
0.2500 0 0 0.2500 0 0.2500 0
0.2500 0.5000 0.2500 0 0 0.2500 0
0 0 0.2500 0 0 0.2500 0.3333
0.2500 0 0.2500 0 0 0 0.3333
What about all zero columns?
To ensure that the code works for all zero columns, simply make the threshold when you create the random matrix more aggressive. Make it higher, like 0.8 or so. This means that there's a higher chance that you will get a 0 than a 1.
Therefore, I changed the second line of code to:
A = rand(n, n) >= 0.8;
When I did this and ran the code again, this is what I get for one run:
>> A
A =
0 0 0 0.2500 0 0.5000 0
0 0.5000 1.0000 0.2500 0 0.5000 0
0 0 0 0 1.0000 0 1.0000
0 0.5000 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0.2500 0 0 0
0 0 0 0.2500 0 0 0

How to find a set of maximum independent vectors given a matrix?

Given a matrix A, I want to find a set of maximum linearly independent columns ? I have tried use rref(A) in matlab, then find all the pivot, it works well in general matrix. But when the matrix is special, it seems given the wrong answer, for example A =
1.6180 1.0000 1.0000 1.0000 0 1.0000
1.0000 1.6180 1.0000 1.0000 1.0000 0
1.0000 1.0000 1.6180 0 1.0000 1.0000
1.0000 1.0000 0 1.6180 0 0
0 1.0000 1.0000 0 1.6180 0
1.0000 0 1.0000 0 0 1.6180
then the rref(A)=
1.0000 0 0 0 0 0.8730
0 1.0000 0 0 0 -1.6180
0 0 1.0000 0 0 0.7450
0 0 0 1.0000 0 0.4604
0 0 0 0 1.0000 0.5396
0 0 0 0 0 0
this cannot be right. because the rank(A)=4. I have done the search, someone said that rref is not accurate and SVD will help ? but I really don't know how to do it ? Help me with the example matrix A will help me much more. 3Q !

How to revert signed distance function back to binary image?

So I used MATLAB's bwdist function to obtain the distance transform of a binary image. My question is, how do I transform a signed distance matrix back into a binary image?
D = bwdist(BW)
Specifically, is there a transform that can go back from BW -> D?
If D = bwdist(BW), how about BW0 = D<=0?
Consider the first example from the bwdist documentation:
bw = zeros(5,5); bw(2,2) = 1; bw(4,4) = 1
bw =
0 0 0 0 0
0 1 0 0 0
0 0 0 0 0
0 0 0 1 0
0 0 0 0 0
[D,IDX] = bwdist(bw)
D =
1.4142 1.0000 1.4142 2.2361 3.1623
1.0000 0 1.0000 2.0000 2.2361
1.4142 1.0000 1.4142 1.0000 1.4142
2.2361 2.0000 1.0000 0 1.0000
3.1623 2.2361 1.4142 1.0000 1.4142
To get back your binary image, you just want the points in the distance transform that are equal to zero (i.e. on a non-zero pixel in the original bw):
>> bw0 = D<=0
bw0 =
0 0 0 0 0
0 1 0 0 0
0 0 0 0 0
0 0 0 1 0
0 0 0 0 0
>> isequal(bw,bw0)
ans =
1

Plot a disc in Matlab, color varying with angle

I would like to represent some data depending on the angle of measure. I have something like that:
angle=[0 90 180 270 360];
value=[1 2 3 4];
In my case, length(angle)=73
How can I plot a disc in which the color of the radius line varies according to the vector value.
I would like something like imagesc but in a disc.
I unsuccessfully tried using rose, but it is limited to a max of 20 angles.
This is another alternative that does not use 3D graphics, only 2D. It uses the primitive patch command that draws triangles. Here is a result:
function PlotDisc
thetas=(0:5:360)'*pi/180;
% r=(0:0.1:1)';
r = 1;
[x,y]=pol2cart(thetas,r);
colMap = GetColMap();
for i=1:numel(x)-1
X = [0 x(i) x(i+1) 0];
Y = [0 y(i) y(i+1) 0];
col = i / (numel(x)-1) * numel(colMap);
patch(X,Y,col,'EdgeAlpha',0);
end
axis equal
end
function colMap = GetColMap()
colMap = ...
[0.0417 0 0
0.0833 0 0
0.1250 0 0
0.1667 0 0
0.2083 0 0
0.2500 0 0
0.2917 0 0
0.3333 0 0
0.3750 0 0
0.4167 0 0
0.4583 0 0
0.5000 0 0
0.5417 0 0
0.5833 0 0
0.6250 0 0
0.6667 0 0
0.7083 0 0
0.7500 0 0
0.7917 0 0
0.8333 0 0
0.8750 0 0
0.9167 0 0
0.9583 0 0
1.0000 0 0
1.0000 0.0417 0
1.0000 0.0833 0
1.0000 0.1250 0
1.0000 0.1667 0
1.0000 0.2083 0
1.0000 0.2500 0
1.0000 0.2917 0
1.0000 0.3333 0
1.0000 0.3750 0
1.0000 0.4167 0
1.0000 0.4583 0
1.0000 0.5000 0
1.0000 0.5417 0
1.0000 0.5833 0
1.0000 0.6250 0
1.0000 0.6667 0
1.0000 0.7083 0
1.0000 0.7500 0
1.0000 0.7917 0
1.0000 0.8333 0
1.0000 0.8750 0
1.0000 0.9167 0
1.0000 0.9583 0
1.0000 1.0000 0
1.0000 1.0000 0.0625
1.0000 1.0000 0.1250
1.0000 1.0000 0.1875
1.0000 1.0000 0.2500
1.0000 1.0000 0.3125
1.0000 1.0000 0.3750
1.0000 1.0000 0.4375
1.0000 1.0000 0.5000
1.0000 1.0000 0.5625
1.0000 1.0000 0.6250
1.0000 1.0000 0.6875
1.0000 1.0000 0.7500
1.0000 1.0000 0.8125
1.0000 1.0000 0.8750
1.0000 1.0000 0.9375
1.0000 1.0000 1.0000] ;
end
Some time ago I had to plot polar data and looked for something similar. I do not know if it corresponds to your needs but I adapted my solution to your problem, here it is:
theta=(0:360)'*pi/180;
r=(0:0.1:1)';
value=repmat([360 (1:360)],size(r,1),1);
[THETA,R]=meshgrid(theta,r);
[X,Y]=pol2cart(THETA,R);
surf(X,Y,value,'edgecolor','none');
view(0,90);
UPDATE: You are absolutely right Andrey, and I suspect the 3D graphics to take more memory and thus display a lot slower but at the time I did not find any ohter way. Your solution is better, I will use it from now. The only thing I would change is the for loop:
r=1;
dtheta=0.01;
theta=linspace(0,2*pi,100)';
n=numel(theta);
[x,y]=pol2cart(theta,r);
figure;
cmap=colormap(jet);
X=[zeros(1,n-1);x(1:end-1)';x(2:end)';zeros(1,n-1)];
Y=[zeros(1,n-1);y(1:end-1)';y(2:end)';zeros(1,n-1)];
C=numel(cmap)*(1:n-1)/n-1;
patch(X,Y,C,'EdgeAlpha',0);
axis equal;