Alex
Alex

Reputation: 15708

Modify parts of a matrix based on linear equation on row and column numbers

For example:

>> tmp = ones(5,5)

tmp =

     1     1     1     1     1
     1     1     1     1     1
     1     1     1     1     1
     1     1     1     1     1
     1     1     1     1     1

I want a command like:

tmp(colNum - 2*rowNum > 0) = 0

that modifies entries of tmp when the column number is more than twice the row number e.g. it should produce:

tmp =

     1     1     0     0     0
     1     1     1     1     0
     1     1     1     1     1
     1     1     1     1     1
     1     1     1     1     1

As a second example, tmp(colNum - rowNum == 0) = 0 should set the diagonal elements of tmp to be zero.

Upvotes: 1

Views: 40

Answers (2)

Dan
Dan

Reputation: 45752

A possibly more efficient solution is to use bsxfun like so

nRows = 5;
nCols = 5;
bsxfun(@(col,row)~(col - 2*row > 0), 1:nCols, (1:nRows)')

You can generalize this to just accept a function so it becomes

bsxfun(@(col,row)~f(col,row), 1:nCols, (1:nRows)')

And now just replace f with exactly the way you specify the equation in your question i.e.

f = @(colNum, rowNum)(colNum - 2*rowNum > 0)

or

f = @(colNum, rowNum)(colNum - rowNum == 0)

of course it might make more sense to specify your function to accept (row,col) instead of (col,row) as that's how MATLAB indexes

Upvotes: 3

rayryeng
rayryeng

Reputation: 104515

You can use meshgrid to generate a grid of 2D coordinates, then use this to impose any condition you wish. The variant you seek outputs 2 2D matrices where the first matrix gives you the column locations and the second matrix outputs the row locations.

For example, given your situation above:

>> [X,Y] = meshgrid(1:5, 1:5)

X =

     1     2     3     4     5
     1     2     3     4     5
     1     2     3     4     5
     1     2     3     4     5
     1     2     3     4     5


Y =

     1     1     1     1     1
     2     2     2     2     2
     3     3     3     3     3
     4     4     4     4     4
     5     5     5     5     5

You can see that each unique spatial location shared between X and Y give you the desired 2D location as if you were envisioning a 2D grid.

Therefore, you would do something like this for your first situation:

[X,Y] = meshgrid(1:5,1:5); % Generate 2D coordinates
tmp = ones(5); % Generate desired matrix
tmp(X > 2*Y) = 0; % Set desired locations to 0

We get:

>> tmp

tmp =

     1     1     0     0     0
     1     1     1     1     0
     1     1     1     1     1
     1     1     1     1     1
     1     1     1     1     1

Finally for your second example:

[X,Y] = meshgrid(1:5,1:5); % Generate 2D coordinates
tmp = ones(5); % Generate desired matrix
tmp(X == Y) = 0;  % Set desired locations to 0

We get:

>> tmp

tmp =

     0     1     1     1     1
     1     0     1     1     1
     1     1     0     1     1
     1     1     1     0     1
     1     1     1     1     0

Simply put, generate a grid of 2D coordinates, then use those directly to index into your desired matrix using logical / Boolean conditions to set the desired locations to 0.

Upvotes: 2

Related Questions