which column in matlab selforgmap output corresponds to which neuron of the SOM map - matlab

I used selforgmap for pattern recognition. After training finished i calculated the network's output of the whole data and I got a logical matrix.
I want know how selforgmap:
1- numbers the neurons (i mean from 1 to N, while N equals the total number of neurons)
2-
Here is my map
1 O------O
/ /
0 O------O
0 0.5 1 1.5
the output looks like this (after transpose)
1 0 0 0
0 1 0 0
1 0 0 0
1 0 0 0
0 0 1 0
0 1 0 0
0 0 1 0
0 0 1 0
i want know which column in output corresponds to which neuron of the map

Selforgmap in MATLAB starts the numbering from the bottom left. For your example, the neurons are labeled:
3 - 4
/ /
1 2
You can use the
vec2ind(output)
command to associate the output with the neuron to which the corresponding input has been assigned.

Related

Visualize the path on the 2D square

I want to visualize all of the paths on 2D square in matlab.
This code gives me the following figure which consists of a 2D square and randomly distributed of 1 and 0.
https://i.hizliresim.com/Ey4G4D.png
Each 1's must connected with lines from top to bottom.
If there is 1, then there is a way and I have to plot line. Otherwise therre is no way and stop.
Without the boundary elements, there are 3 way for each elements. Each element can go left side, right side or down side.
The top left hand corner's element can go right and down direction.
The top right hand corner's element can go left and down direction.
This is the algorithm of the modelling.
https://i.hizliresim.com/Dy0z0y.jpg
How can I write this code ?
I am waiting your advise :)
Problem analysis
To get an information on the possible paths in your matrix/image you can use the diff function. It calculates the difference between two neighbouring matrix elements along the specified dimension.
The conditions for the existence of a path are:
The difference between the element and its neighbour must be 0
The element itself must be 1
Solution
The following matlab program will create 3 matrices containing the value 1 or true for each element with a path existing to its neighbour.
matrix = logical([1 1 1 1 0; ...
1 1 0 1 1; ...
0 0 0 1 0; ...
0 0 1 1 0])
hasPathtoRight = false(size(matrix));
hasPathtoRight(:,1:end-1) = (diff(matrix,1,2)==0) & (matrix(:,1:end-1)==1)
hasPathtoLeft = false(size(matrix));
hasPathtoLeft(:,2:end) = (diff(matrix,1,2)==0) & (matrix(:,2:end)==1)
hasPathDown = false(size(matrix));
hasPathDown(1:end-1,:) = (diff(matrix,1,1)==0) & (matrix(1:end-1,:)==1)
Result
The result for the example matrix is shown here:
matrix =
1 1 1 1 0
1 1 0 1 1
0 0 0 1 0
0 0 1 1 0
hasPathtoRight =
1 1 1 0 0
1 0 0 1 0
0 0 0 0 0
0 0 1 0 0
hasPathtoLeft =
0 1 1 1 0
0 1 0 0 1
0 0 0 0 0
0 0 0 1 0
hasPathDown =
1 1 0 1 0
0 0 0 1 0
0 0 0 1 0
0 0 0 0 0
You can use these matrices to draw the paths in a graphical display.

Determine matrix boundary without loops

I have got a 2D matrix. There is some region in the matrix where the elements are non-zero, in particular everywhere around the edge they are zero.
I plot the matrix using image as a colorplot and would like to add the curve that shows the boundary between non-zero values to zero values in the matrix. Is there any neat way to do this without loops?
This looks like a job for convhull :
To illustrate this code i'll take a dummy example :
A=zeros(10);
B=binornd(1,0.5,8,8);
A(2:end-1,2:end-1)=B
A =
0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 1 1 1 1 1 1 0 0
0 0 1 1 0 0 0 0 1 0
0 0 0 1 0 0 0 1 0 0
0 1 0 0 0 0 0 1 0 0
0 0 0 1 1 1 1 1 1 0
0 0 1 0 1 1 1 1 0 0
0 1 0 1 1 1 1 0 1 0
0 0 0 0 0 0 0 0 0 0
1/ Find the locations of all non zero entries :
[row,col]=find(A);
2/ Take the convex hull of these locations
k=convhull(row,col);
3/ Plot the convex hull (I plot the non zero points aswell but in your problem it will be your image points)
plot(row(k),col(k),'r-',row,col,'b*')
Result :
Another option is using the image processing toolbox and the bwperim function. This will work if you know that your area is completely closed (i.e. has no holes in the boundary)
This is an example using a black and white image, and you have 2 options: fill the inner gaps before, or not. You can see in the result the differences.
A = imread('circles.png');
Afill=imfill(A,'holes'); % optional
Abound1=bwperim(Afill);
Abound2=bwperim(A);
imshow([A,Abound, Abound2])
You can plot one on top of the other with:
[x,y]= find(Abound2);
hold on
image(A*255) %// If A is logical, else use just A (not *255)
colormap('gray')
plot(y,x,'r.')
hold off
axis tight
If you have a gray-scale image (or a matrix with a single value in each position (2D matrix), then you can binarize it first by either:
If you know everything outside your object is EXACTLY zero
A=yourA>0;
If you want to separate your object from the background, and the background is not exactly zero by A=im2bw(yourA,level), by choosing your own level, or letting Otsu do it for you with level=graythresh(yourA)

Vector categorization

I am trying to represent an huge vector in terms of pre-defined bins and do 1-k encoding. For example, if my vector is
1.101
3.45
8
9.91
2.47
5.5
6.8
and I have four bins
Bin 1: (0 - 2.5), and its 1-k encoding 1 0 0 0
Bin 2: (2.51 - 5) and its 1-k encoding 0 1 0 0
Bin 3: (5.01 - 7.5) and its 1-k encoding 0 0 1 0
Bin 4 : (7.51 - 10) and its 1-k encoding 0 0 0 1
I want to build a new matrix (7x4) which represents the vector in the following way:
1.101 --> 1 0 0 0
3.45 --> 0 1 0 0
8 --> 0 0 0 1
9.91 --> 0 0 0 1
2.47 --> 1 0 0 0
5.5 --> 0 0 1 0
6.8 --> 0 0 1 0
How can I do this in MATLAB?
Easiest way I can think of is to use histcounts to do a histogram count, but instead of getting the histogram, you want the find the actual bin the value belonged to. You need the third output of histcounts for that. You also need to make sure that the bin edges vary from 0 to 10 in steps of 2.5. Once you have this, simply create a sparse matrix where for the nonzero entries, the rows varies from 1 up to as many values as you have in your vector and the columns are directly using the third output of histcounts. You'll also want to convert to full when you're done.
vec = [1.101; 3.45; 8; 9.91; 2.47; 5.5; 6.8]; %// Your example
[~,~,bin] = histcounts(vec, 0:2.5:10); %// Find which bin each value belongs to
%// Compute the matrix
out = full(sparse((1:numel(vec)).', bin, 1));
We get:
out =
1 0 0 0
0 1 0 0
0 0 0 1
0 0 0 1
1 0 0 0
0 0 1 0
0 0 1 0

MATLAB Add 1's to matrix elements around a specific element

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.

How to make matlab repeat a procedure independently?

I have a matrix like this:
A =
1 1 1 0 1
0 1 1 0 0
0 0 0 0 1
1 0 0 0 0
0 1 0 1 1
I want to replace for example 30% of 1 elements in this matrix with 0 randomly and repeat this procedure independently 10 times for instance, and at the end of the work I must have 10 independent matrices which each one of them should has 30% of 1 elements less than the original matrix.
here's the code I use to do this:
for i=1:10
f=.3;
A_ones=find(A);
n = round(f*length(A_ones));
A_ones_change = randsample(A_ones,n);
A(A_ones_change) = 0;
end
A
But the thing that matlab does with this code is that it takes the original matrix A at the begining and replaces 30% of its 1 elements with 0. But for the second time it takes the resultant matrix from previous step as A (not the original matrix) and replaces 30% of remained 1 elements in that matrix with 0 and does it again and again for 10 times and at the end it gives me only 1 matrix like below:
A =
0 0 0 0 0
1 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
How can I solve this problem and make matlab to do this procedure on 'original matrix A' for each i?
Your original A is changing every time because of the last line in your loop A(A_ones_change) = 0;. Change it to some copy of A (say, A1 = A) you make in the beginning of the loop.