generate plot matrix from two different matrices in matlab [duplicate] - matlab

This question already has an answer here:
Create a larger matrix in special case [closed]
(1 answer)
Closed 9 years ago.
I have two matrices (5_by_1), say A=[5 rows,1 column] and B=[5 rows, 1 column] if I do plot(A,B), I will create a large matrix C=[5 rows,5 columns] wright?!
Now I would like to create this large matrix without plot it. I want this matrix directly. thank you.
For example A=[1 2 3 4 5 ] and B=[3 4 2 1 4]
c=
0 1 0 0 0
1 0 0 0 1
0 0 1 0 0
0 0 0 1 0

This should work:
a = [1 2 3 4 5];
b = [3 4 2 1 4];
c = flipud(sparse(b,a,1,4,5));
If you want to see the full c:
full(c)
or if you have a bigger version:
c = flipud(sparse(b,a,1,max(b),max(a)));
The flipud command is to flip the matrix upside down.
Hope this helps =)
EDIT:
"Shift" the matrices, so that your lowest value is in (1,1) (before you flip it). The structure will be correct, but the origin won't be easy to spot.
a_1 = floor(a - min(a)) + 1; % floor if you don't have integers.
b_1 = floor(b - min(b)) + 1;
c = flipud(sparse(b_1,a_1,1,max(b_1),max(a_1)));

Related

Matlab how to distribute a matrix elements randomly

hi everyone how to make a matrix randomly distributed to another matrix n,
m = [ 1 1 3 3 3 4 4 6 6 7 7 7];
n = zeros(3,10);
the same value must in the sequence, ex : 4 4 4, 7 7 7.result reqiured can be something like {or other combinations):
distributed_matrix =
0 1 1 0 7 7 7 0 0 0
0 0 3 3 3 4 4 0 0 0
6 6 6 0 0 0 0 0 0 0
thank you...
If you do not impose any constraint on the order at which the elements of m are distributed, then randsample might help:
ridx = randsample( numel(n), numel(m) ); %// sample new idices for elelemtns
n(ridx) = m;
Looking into the additional constraints, things get a bit more messy.
For identifying the sequences and their extent in m, you can:
idx = [1 find(diff(m)~=0)+1];
extent = diff([idx numel(m)+1]); %// length of each sequence
vals = m(idx); %// value of each sequence
Once you have the sequqnces and their length you can randomly shuffle them and then distribute along the lines...
If I understand your question correctly, the possible solution is
m = [ 1 1 3 3 3 4 4 6 6 7 7 7];
n = zeros(3,10);
p= randperm(numel(n)); % generate the random permutation
n(p(1:length(m)))= m % assign the elments of m to the elements with indices taken
% from the first length(m) numbers of random permutation

How to fill the matrix with 0 in matlab [duplicate]

This question already has answers here:
How can I put margins in an image?
(4 answers)
Closed 7 years ago.
Suppose I have a matrix [1 2;3 4], but I need [0 0 0 0;0 1 2 0;0 3 4 0;0 0 0 0], I now how to do it, but is there a function can solve it within one line?
If you have the image processing toolbox, use padarray:
>> A = [1 2; 3 4];
>> B = padarray(A, [1 1])
B =
0 0 0 0
0 1 2 0
0 3 4 0
0 0 0 0
The first input is the matrix you want to pad, and the second input is how many zeroes along the border in each dimension you want to see. You want a 1 element zero border both horizontally and vertically, and so [1 1] is what is required.
However, I'm confused as to why you want this to be in "one-line". If you want a one element border surrounding the original matrix, what's wrong with having multiple lines?
A = [1 2; 3 4];
B = zeros(size(A) + 2);
B(2:end-1,2:end-1) = A;
This is three lines of code, including the definition of your original matrix, but each line is quite clear. You define a new matrix that has 2 more rows and 2 more columns that the original, because you want a 1 element zero boundary around the original matrix, then just place it in the middle.

Matlab: Using a matrix as a mask to perform elementwise operations

In Matlab, I have two matrices: one with integers,x, and one with booleans, y:
x =
2 4 2
3 3 1
4 1 5
y =
0 0 1
1 1 0
1 0 1
What I now want to do is to assign some elements of x to 5, and I want to use y as a mask to determine which elements should be set to 5. So elements with a corresponding value of 0 in y should remain as they are in x, but those with a corresponding value of 1 in y should be set to 5. Therefore, the output should be:
2 4 5
5 5 1
5 1 5
I have tried the following:
x(y) = 5
Which gives me the error:
Subscript indices must either be real positive integers or logicals.
And I have also tried:
y(x) = 5
Which gives me the following:
5 5 1
5 1 0
5 0 1
Can somebody please explain what is going on here, and what I need to do to get my desired result?
The error you've got is due to the fact that, apparently, y is of type double while, in this case, it should be of type logical
You could try:
x(logical(y))=5
Hope this helps
Its not a fancy solution but will solve your problem
>> x = [ 2 4 2;3 3 1;4 1 5];
y = logical([ 0 0 1;1 1 0;1 0 1]);
f = x(:);
f(y(:)) = 5;
x = reshape(f,size(x))
x =
2 4 5
5 5 1
5 1 5
>>
x(find(y)) = 5; should work fine.

Identify adjacent superpixels iteratively

Let A be:
1 1 1 1 1 1
1 2 2 3 3 3
4 4 2 2 3 4
4 4 4 4 4 4
4 4 5 5 6 6
5 5 5 5 5 6
I need to identify a particular superpixel's adjacent pixels,
e.g.
The 1st adjacency of 2 is 1, 3, 4
The 2nd adjacency of 2 is 5, 6
The 3rd adjacency of 2 is ...
What is the FASTEST way to do it?
Assume you have a function adj(value), that has the code from your previous question.
sidenote: you probably would like that adj() function not to return the value of the pixel you are analyzing. you can make that easily.
you could do:
img=[your stuff];
imgaux=img;
ii=1;
val=2; %whatever value you want
while numel(unique(imgaux))>1 % Stop if the whole image is a single superpixel
adjacent{ii}=adj(val);
% expand the superpixel to the ii order of adjacency
for jj=1:size(adjacent{ii},1)
imgaux(imgaux==adjacent{ii}(jj))==val;
end
ii=ii+1;
end
Now size(adjacent,2) will be the amount of adjacency levels for that superpixel.
I am guessing this code is optimizable, I welcome any try for it!
Following Dan's suggestion on the comments, here is a possible implementation:
% Parameters
pixVal = 2;
adj = {};
prevMask = A == pixVal;
for ii = 1:length(A)
currMask = imdilate(prevMask, ones(2 * ii + 1));
adj{ii} = setdiff(unique(A(currMask & ~prevMask))', [adj{:}]);
if isempty(adj{ii})
break
end
prevMask = currMask;
end
Where pixVal is the pixel you want to look at.
Result:
>> adj{:}
ans =
1 3 4
ans =
5 6
ans =
Empty matrix: 1-by-0
Here's another approach reusing the code from your previous question:
%// create adjacency matrix
%// Includes code from #LuisMendo's answer
% // Data:
A = [ 1 1 1 1 1 1
1 2 2 3 3 3
4 4 2 2 3 4
4 4 4 4 4 4
4 4 5 5 6 6
5 5 5 5 5 6 ];
adj = [0 1 0; 1 0 1; 0 1 0]; %// define adjacency. [1 1 1;1 0 1;1 1 1] to include diagonals
nodes=unique(A);
J=zeros(numel(nodes));
for value=nodes.'
mask = conv2(double(A==value), adj, 'same')>0; %// from Luis' code
result = unique(A(mask)); %// from Luis' code
J(value,result)=1;
J(value,value)=0;
end
J is now the adjacency matrix for your matrix A and this becomes a graph problem. From here you would use the appropriate algorithm to find the shortest path. Path length of 1 is your "1st adjacency", path length of 2 is "2nd adjacency" and so on.
Dijkstra to find shortest path from a single node
Floyd-Warshall to find shortest paths from all the nodes
Breadth-first search for a single node, plus you can generate a handy tree
Update
I decided to play around with a custom Breadth-First Traversal to use in this case, and it's a good thing I did. It exposed some glaring errors in my pseudocode, which has been corrected above with working Matlab code.
Using your sample data, the code above generates the following adjacency matrix:
J =
0 1 1 1 0 0
1 0 1 1 0 0
1 1 0 1 0 0
1 1 1 0 1 1
0 0 0 1 0 1
0 0 0 1 1 0
We can then perform a depth-first traversal of the graph, putting each level of the breadth-first tree in a row of a cell array so that D{1} lists the nodes that have a distance of 1, D{2} has a distance of 2, etc.
function D = BFD(A, s)
%// BFD - Breadth-First Depth
%// Find the depth of all nodes connected to node s
%// in graph A (represented by an adjacency matrix)
A=logical(A); %// all distances are 1
r=A(s,:); %// newly visited nodes at the current depth
v=r; %// previously visited nodes
v(s)=1; %// we've visited the start node
D={}; %// returned Depth list
while any(r)
D(end+1,:)=find(r);
r=any(A(r,:))&~v;
v=r|v;
end
end
For a start node of 2, the output is:
>> D=BFD(J,2)
D =
{
[1,1] =
1 3 4
[2,1] =
5 6
}

How to add boundary to a matrix

I am quite new to MATLAB. I would like to know how can I transfer the matrix A to matrix B as shown below?
A = 1 2
3 4
5 6
B=0 0 0 0
1 1 2 1
1 3 4 1
1 5 6 1
0 0 0 0
Essentially I would like to add a boundary to A.
Thank you!
padarray implementation -
%// pad ones on left-right and then pad zeros on top-bottom
B = padarray(padarray(A,[0 1],1),[1 0],0)
If I understand your question correctly, you wish to insert a 1 element boundary surrounding the matrix. In that case, try something like this:
A = [1 2; 3 4; 5 6];
[rows,cols] = size(A);
B = zeros(rows+2, cols+2);
B(2:end-1,[1 end]) = 1;
B(2:end-1,2:end-1) = A;
However, you can also use padarray like what #Divakar has suggested. Much more elegant!