Using MATLAB, I have a matrix such as:
1 1 0
1 0 1
1 1 1
The aim is to represent the zero's as a mine in a minesweeper program and the values around the 0's should reflect how many mines are adjacent to it.
Therefore creating a vector like this:
1 2 0
1 0 2
1 1 1
I have thought to take elements around the zero as a sub matrix and then add 1, but then it will turn 0's into 1's.
How would I program such a task?
I think this can be achieved by simple convolution plus some post-processing on the resultant matrix as follows:
% Defining a 6x6 matrix of zeros and ones
mineMat=randi(2,6,6)-1;
numberOfMines=conv2(double(~mineMat),ones(3,3),'same').*mineMat;
% Result:
mineMat=
1 0 1 1 0 0
0 0 0 1 0 0
1 1 1 1 1 0
1 1 1 1 0 1
0 1 0 0 0 0
0 1 1 0 0 0
numberOfMines=
3 0 3 3 0 0
0 0 0 3 0 0
2 3 2 3 4 0
1 2 2 4 0 4
0 3 0 0 0 0
0 3 3 0 0 0
Parag's answer would be my first option. Another approach is to use blockproc (Image Processing Toolbox):
blockproc(~M, [1 1], #(x)sum(x.data(:)), 'Bordersize', [1 1], 'TrimBorder', 0).*M
Sounds like you are looking to apply a (two dimensional) filter:
M = [1 1 0; 1 0 1; 1 1 1]==0;
F = filter2(ones(3),M);
F(M)=0
The middle line basically does the work (applying the filter) to create the count. The last line ensures that the mines stay at value 0.
Related
I want to find how many edges are there in C1 and C2? I have stored their adjacency matrix like this :
1 2 3 4 5
1 0 1 1 0 0
2 1 0 0 0 1
3 0 0 0 1 0
4 0 0 0 0 1
5 0 0 0 1 0
If I give an input in an array as [1,3,4] O/P should be : 2
You can use your array to select the appropriate rows and columns from your adjacency matrix and then count the number of non-zeros in the result by using nnz
nnz(A([1 3 4], [1 3 4]))
say i have a matrix
A=zeros(10,3);
and a vector
ll=[1 1 1 2 2 2 3 1 3 2]';
and i want to assign the value in each row corresponding to the value in ll for that row to be 1
i.e output would be
A= 1 0 0
1 0 0
1 0 0
0 1 0
0 1 0
0 1 0
0 0 1
1 0 0
0 0 1
0 1 0
how i do it is using a for loop
for ii=1:length(ll)
A(ii,ll(ii)=1;
end
This should do the trick:
ll=[1 1 1 2 2 2 3 1 3 2]';
A=bsxfun(#eq,ll,1:max(ll))
I'm using bsxfun to check when the entry of ll is equal to an element of the row vector [1 2 3] (in this case). If the entry of ll is 1, it will be equal to the entry in the first column of the [1 2 3] vector and will give a 1 in the first column of A and zeros in the rest of the columns of that row.
Just convert to a linear index:
A((ll-1)*size(A,1) + (1:size(A,1)).') = 1;
Let say that I have 1 matrix with numbers (0,1). How can i create new matrix that is the result of a logical operation among the columns?
eg. A =
0 0 0 1 0
1 1 1 1 1
0 1 1 0 0
0 0 0 0 1
1 0 0 1 0
1 1 1 1 1
If all elements of **rows** are equal to 1 - 1, if not - 0.
(like AND operation)
Ans= 0
1
0
0
0
1
Thanks!
To solve your problem this would work -
all(A,2)
If you were looking to set elements based on the columnwise data in A, you would do this -
all(A,1)
More info on all, must serve you well.
this is my matrix that displays a sample network graph
matrix =
0 1 1 1
1 0 1 0
0 0 0 1
1 1 1 0
where its a 4x4 matrix
1) 2) 3) 4)
1) 0 1 1 1
2) 1 0 1 0
3) 0 0 0 1
4) 1 1 1 0
i want to count this 4x4 matrix like
row 1 counts how many 1s i have and adds column 1 number of 1's to it and returns 1)=5 as total 1's in row 1 and col 1 = 5
i want my output to be like
1=5
2=4
3=4
4=5
This must be it -
out = sum([matrix matrix'],2)
Example run -
matrix =
1 1 1 1
1 0 0 0
0 1 0 1
0 0 1 1
out =
6
3
4
5
The above code would count 1s twice when they appear on the diagonal, which if you don't want, use this -
out1 = sum([matrix matrix'],2) - diag(matrix)
Example run -
matrix =
1 1 1 1
1 0 0 0
0 1 0 1
0 0 1 1
out1 =
5
3
4
4
I agree with the answer of Divakar, but once your graph gets larger and larger, you might not want to transpose the entire matrix. I suggest doing the sum first and then transposing afterwards:
sum(matrix,1)'+sum(matrix,2)-diag(matrix);
matrix =
0 1 1 1
1 0 1 0
0 0 0 1
1 1 1 0
degree=sum(matrix,1)'+sum(matrix,2)-diag(matrix)
degree =
5
4
4
5
I'm trying to copy part of a matrix (matrix 1) in matlab to another empty matrix of zeros (matrix 2) so that the section I copy from matrix 1 has the same indices in matrix 2, e.g.
Matrix 1 (mat1):
0 3 0 0 2 4 1 2 6
1 3 4 2 0 0 0 2 0
0 2 6 1 3 6 6 1 1
0 0 0 2 1 3 3 1 0
1 4 5 2 3 3 0 0 1
Matrix 2 (mat2) desired output:
0 0 0 0 0 0 0 0 0
0 0 4 2 0 0 0 0 0
0 0 6 1 3 6 6 0 0
0 0 0 2 1 3 3 0 0
0 0 0 0 0 0 0 0 0
I've tried something like
mat2([2:4],[3:7]) = mat1([2:4],[3:7])
but of course it doesn't work... any ideas of an efficient way to do this? I couldn't find another thread to help with this problem.
Thanks!
It does work. You just need to create mat2 first:
mat2 = zeros(size(mat1));
mat2(2:4, 3:7) = mat1(2:4, 3:7);
Note that you don't need the square brackets on those ranges.
Do this:
mat2 = zeros(size(mat1));
Before copying over.