MxN matrix with ones and zeros following a specific rule - matlab

I want to create a MxN matrix as shown below:
[1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1]
I have window size, let's say, 5 and it moves 3 in every row. Is it possible to create such a matrix without using for loops? Or is there any optimum way to do it?

This is a one line solution:
reshape([reshape([ones(5,6);zeros(21,6)], 1,[]), ones(1,5)],[],7).'
note:
The desired matrix can be seen as concatenation of a [6, 5+21] matrix:
1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
and a [1 ,5] matrix:
1 1 1 1 1
that reshaped to a [7 , 23] matrix.
Other solution using repelem + bsxfun + accumarray:
r = repelem (1:7,5);
c= bsxfun(#plus, ((1:5)-3).',3*(1:7));
out = accumarray([r(:) c(:)] ,1)
Indices of rows and columns of 1 s can be generated and accumarray can be used to create the desired matrix.

Related

Simulate obstacles in logical matrix

I'm writing an optimal path planning algorithm for one of my projects, and am a bit stuck on how to generate the map. In order to test my algorithm, I want to generate random maps that the object will pass through with obstacles in the way. To generate the maps I am making a logical array with "1" for wall or obstacle and "0" when there is nothing in the way. I am having some issues placing the obstacles however.
For now, this is what I've written in MATLAB (though I think the core idea can be solved in any language):
% lenx = length in x-direction of map [m]
% leny = length in y-direction of map [m]
% numObs = number of obstacles
% obsLoc = 2D array with the central location(s) of the obstacle(s)
% [x1, y1; x2 y2; ...]
% obsSize = size of the obstacles (all same size) [m]
% assume the obstacles are square.
% res = resolution of the map [cell/m]
%
% Outputs:
% map = 2D logical array which translates into a map
%
%---------------------------------------------------------
function map = createMap(lenx, leny, numObs, obsLoc, obsSize, res)
%Making map of the given size
map = zeros(leny*res, lenx*res);
%Adding walls
map(:,1) = 1;
map(:, lenx*res) = 1;
map(1,:) = 1;
map(leny*res, :) = 1;
%Recalculating obstacle size for this grid
obsSize = obsSize - 1;
%Adding obstacles
for i = 1:1:numObs
map(obsLoc(i,1)*res-obsSize*res:obsLoc(i,1)*res+obsSize*res,...
obsLoc(i,2)*res-obsSize*res:obsLoc(i,2)*res+obsSize*res) = 1;
end
end
The obsSize parameter is representing the dimension of one of the sides of the square obstacle. Here is a sample solution I ran:
>> createMap(10,10,1,[5,5],1,1)
ans =
1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 1
1 0 0 0 1 0 0 0 0 1
1 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 1
1 1 1 1 1 1 1 1 1 1
Looks good! But the issue begins for obstacle sizes and resolutions that are not 1 or 2...
>> createMap(10,10,1,[5,5],0.5,2)
ans =
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
>> createMap(10,10,1,[5,5],3,2)
ans =
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 1
1 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 1
1 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 1
1 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 1
1 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 1
1 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 1
1 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 1
1 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 1
1 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
For the first one, we would expect there to be a 1 somewhere close to the middle, but it's nowhere to be found. In the second one, we'd expect to find 6 ones in each direction (3m * 3cell/m = 6 cell), but we are getting 8 (It's also possible that this is not what my code is calculating, but this is what I'm hoping it does. Neither case is working, and I think it has to do with this line:
Recalculating obstacle size for this grid
obsSize = obsSize - 1;
I'm pretty sure I do have to recalculate the object size so it fits to the grid, but how can I do this for any grid and obstacle? Is there a way to scale that "-1" such that it acts according to the size of the grid/obstacle?
Let me know what you come up with, and if there's any other glaring issues in my code?
Thanks!

Comparison between two rows and change value

i have a matrix 20 rows and 20 columns,
If the value 1 in the row 5 the column take 0
matric=[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ;
0 1 1 1 1 0 1 0 1 0 1 1 1 0 1 0 1 1 1 1;
0 1 1 0 1 0 1 0 0 0 1 0 1 0 1 0 0 1 0 1;
0 1 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 1 0 1;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;];
if (matric(5,:)==1)
matric(1:5,1:end)=0;end
I try to compare the second row and the 5 row
If we have "1" in row 2 and row 5
The row 2 take 0
if (matric(5,:)==matric(2,:)==1)
matric(2,1:end)=0;end
do you have an idea
Thank you
The desired output is:
matric=[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
1 0 1 1 0 0 1 1 1 1 0 1 0 1 1 1 1 0 1 0 ;2row will change
0 1 1 1 1 0 1 0 1 0 1 1 1 0 1 0 1 1 1 1;
0 1 1 0 1 0 1 0 0 0 1 0 1 0 1 0 0 1 0 1;
0 1 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 1 0 1; % 5 row
You can use logical indexing.
I strongly encourage you to read the following references:
Mathworks documentation page: Find Array Elements That Meet a Condition
Loren on the Art of MATLAB blog entry: Logical Indexing – Multiple
Conditions
Use the following lines of code:
Put 0 in all those columns that have a value of 1 in row 5:
matric(:, matric(5, :) == 1) = 0;
Put 0 in all those columns of row 2 that have a value of 1 both in rows 2 and 5:
matric(2, matric(2, :) == matric(5, :)) = 0;
You can use logical indexing to achieve this. Now I must say I am a bit confused by what exactly you want to achieve based on your description, but based on the your code the first statement can be done as follow:
matric(1:5,matric(5,:)==1) = 0;
and the second would look like:
matric(2,matric(5,:)==1 & matric(2,:)==1)=0;

Matrix Exponentiation in Galois Field 2

I am confusing about exponentiation of matrix in Galois Field 2. Assume that I have a matrix that is represented in Galois Field 2 (GF2). I want to take exponentiation of 30. That is,
A^30
In the matlab we have two way to do it.
First, We perform A power 30 and take mod of 2 (Note that A is a double matrix)
A1=mod(A^30,2)
Second way, we convert A to galois matrix and take exponentiation
A=gf(A,2)
A2=A^30
Actually, two way must same result. However, when I check A1 and A2. They have a different result. What is happen in here? Thanks
Let see my A matrix
A =
1 1 0 1 1 1 0 1 0 0 0 1 0 1 0
0 0 0 1 0 1 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 1 0 1 0 0 0 1
1 0 1 1 0 0 0 0 0 0 1 1 1 0 0
1 0 1 0 0 0 0 1 0 0 0 0 0 0 0
0 1 0 1 1 1 1 1 0 1 1 1 1 0 1
0 0 0 1 0 0 0 1 0 0 1 0 0 0 0
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
1 0 0 1 0 1 0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 1 1
1 0 1 0 0 0 0 0 0 0 1 0 0 0 1
0 1 0 0 0 0 0 1 0 0 0 0 0 0 0
1 0 1 1 1 1 1 1 1 0 1 1 1 0 1
0 1 0 0 0 1 0 0 0 1 0 0 0 1 0
1 0 0 1 0 1 0 0 0 1 0 0 0 1 1
Method1:
A1=
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Method 2
A2 =
1 1 0 1 1 1 0 1 0 0 0 1 0 1 0
0 0 0 1 0 1 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 1 0 1 0 0 0 1
1 0 1 1 0 0 0 0 0 0 1 1 1 0 0
1 0 1 0 0 0 0 1 0 0 0 0 0 0 0
0 1 0 1 1 1 1 1 0 1 1 1 1 0 1
0 0 0 1 0 0 0 1 0 0 1 0 0 0 0
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
1 0 0 1 0 1 0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 1 1
1 0 1 0 0 0 0 0 0 0 1 0 0 0 1
0 1 0 0 0 0 0 1 0 0 0 0 0 0 0
1 0 1 1 1 1 1 1 1 0 1 1 1 0 1
0 1 0 0 0 1 0 0 0 1 0 0 0 1 0
1 0 0 1 0 1 0 0 0 1 0 0 0 1 1

error with matrix inverse only when matrix created through script

A=[ 1 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
1 -3 1 0 0 0 0 0 0 1 0 0 0 0 0 0;
0 1 -3 1 0 0 0 0 0 0 1 0 0 0 0 0;
0 0 1 -7.94E+05 7.94E+05 0 0 0 0 0 0 2 0 0 0 0;
0 0 0 +7.94E+05 -7.94E+05 1 0 0 0 0 0 0 2 0 0 0;
0 0 0 0 1 -3 1 0 0 0 0 0 0 1 0 0;
0 0 0 0 0 1 -3 1 0 0 0 0 0 0 1 0;
0 0 0 0 0 0 1 -1 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 1 -1 0 0 0 0 0 0;
0 1 0 0 0 0 0 0 1 -3 1 0 0 0 0 0;
0 0 1 0 0 0 0 0 0 1 -3 1 0 0 0 0;
0 0 0 2 0 0 0 0 0 0 1 -7.94E+05 7.94E+05 0 0 0;
0 0 0 0 2 0 0 0 0 0 0 7.94E+05 -7.94E+05 1 0 0;
0 0 0 0 0 1 0 0 0 0 0 0 1 -3 1 0;
0 0 0 0 0 0 1 0 0 0 0 0 0 1 -3 1;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 -1];
This matrix has an inverse when created manually. But the same matrix when generated through script and inverted gives me "Matrix is close to singular or badly scaled. Results may be inaccurate." error and the inverse generated is not the same as inv(A). I tried using the backslash too. I tried creating the matrix through program using format long, short and bank and continue to face the same problem. What could be my mistake? Thanks in advance.

How to replace elements of a matrix by an another matrix in MATLAB?

How to replace elements of a matrix by an another matrix in MATLAB?
Ex: let say if we have a matrix A, where
A=[1 0 0; 0 1 0; 1 0 1]
I want to replace all ones by
J=[1 0 0; 0 1 0; 0 0 1]
and zeros by
K=[0 0 0; 0 0 0; 0 0 0]
So that I can get 9x9 matrix. So how we will code it in MATLAB
Thanks
Sounds like you might want to take a look at the kronecker tensor product. This is not a general case but the idea should work for what you want
>> kron(A==1,J)+kron(A==0,K)
ans =
1 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0
0 0 0 0 1 0 0 0 0
0 0 0 0 0 1 0 0 0
1 0 0 0 0 0 1 0 0
0 1 0 0 0 0 0 1 0
0 0 1 0 0 0 0 0 1
which, for the example case, would simplify to a simpler command:
>> kron(A,J)
ans =
1 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0
0 0 0 0 1 0 0 0 0
0 0 0 0 0 1 0 0 0
1 0 0 0 0 0 1 0 0
0 1 0 0 0 0 0 1 0
0 0 1 0 0 0 0 0 1
You can do:
A2=imresize(A,size(A).*size(J),'nearest');
J2=repmat(J,size(A));
K2=repmat(K,size(A));
A2(A2==1)=J2(A2==1);
A2(A2==0)=K2(A2==0)