Filter function for k elements larger than A - matlab

In R/Bioconductor's genefilter package, there is a nice function called kOverA (page 18 in this manual).
It's just a filter method that, given a numerical matrix, removes the rows of that matrix that do not have k-elements that are greater than or equal to A-value.
How can I do the same thing in MATLAB?
Examples (simplified. In R, kOverA returns a function, so the actual syntax is a bit different but this is the functionality that I want):
m = [1 0 0 0 0 0 1 1 1 0
0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 1 1
0 1 0 1 0 1 0 1 0 1];
kOverA(m, A=1, k=0) → m
kOverA(m, A=2, k=1) → empty
kOverA(m, A=1, k=1) → [1 0 0 0 0 0 1 1 1 0
1 1 1 1 1 1 1 1 1 1
0 1 0 1 0 1 0 1 0 1]
kOverA(m, A=1, k=4) → [1 0 0 0 0 0 1 1 1 0
1 1 1 1 1 1 1 1 1 1
0 1 0 1 0 1 0 1 0 1]
kOverA(m, A=1, k=5) → [1 1 1 1 1 1 1 1 1 1
0 1 0 1 0 1 0 1 0 1]

Requires relational operator >=, sum and logical indexing and this is it.
out = m(sum(m>=A,2) >= k,:);

Related

What matlab command, or combination of commands (using 25 characters or less), could be used to create the following matrix?

What matlab command, or combination of commands (using 25 characters or less), could be used to create the following matrix?
1 0 0 0 0 1 0 0 0 0
1 1 0 0 0 1 1 0 0 0
1 1 1 0 0 1 1 1 0 0
1 1 1 1 0 1 1 1 1 0
1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 1 0 0 0 0
1 1 0 0 0 1 1 0 0 0
1 1 1 0 0 1 1 1 0 0
1 1 1 1 0 1 1 1 1 0
1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 1 0 0 0 0
1 1 0 0 0 1 1 0 0 0
1 1 1 0 0 1 1 1 0 0
1 1 1 1 0 1 1 1 1 0
1 1 1 1 1 1 1 1 1 1
Hint: Look for a lower triangluar matrix that is repeated many times. First try to produce that lower triangular matrix with as few characters as possible.
You can use the following code:
A = ones(5); % create 5x5 matrix with all elements 1
B = tril(A); % return the lower triangle matrix of A
C = repmat(B, 3, 2); % repeat the matrix B, 3 times in a row and 2 times in a cloumn as you want.
In more details:
A = ones(5);
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
B = tril(A);
1 0 0 0 0
1 1 0 0 0
1 1 1 0 0
1 1 1 1 0
1 1 1 1 1
C = repmat(B, 3, 2);
1 0 0 0 0 1 0 0 0 0
1 1 0 0 0 1 1 0 0 0
1 1 1 0 0 1 1 1 0 0
1 1 1 1 0 1 1 1 1 0
1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 1 0 0 0 0
1 1 0 0 0 1 1 0 0 0
1 1 1 0 0 1 1 1 0 0
1 1 1 1 0 1 1 1 1 0
1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 1 0 0 0 0
1 1 0 0 0 1 1 0 0 0
1 1 1 0 0 1 1 1 0 0
1 1 1 1 0 1 1 1 1 0
1 1 1 1 1 1 1 1 1 1
A solution using rempat and implicit expansion:
repmat(1:5<(2:6)',3,2)

solving binary linear equation in matlab

Consider a binary linear equation of form x*A = b. I want to solve for x, the efficiency way is by avoiding using x = b*inv(A) and instead using x= b/A.But with this command results are not in binary form. I tried the command x = mod(b/A ,2)but still result was not in binary. How to fix this?
example
`
x = 1 0 1 1 0 0 0 1 1 0`
and matrix A is
`0 1 0 1 0 0 1 1 1 1
0 1 1 1 1 1 1 1 0 1
0 0 1 0 1 1 0 1 1 1
1 0 0 1 1 1 1 1 1 1
1 1 0 0 1 1 0 0 0 0
0 1 1 1 0 1 1 0 1 0
0 0 1 1 0 0 0 1 0 0
1 1 1 1 0 1 0 1 1 1
1 0 1 0 1 1 1 0 1 1
1 1 1 0 0 0 1 1 0 0`
which is full rank.
then
>> b = mod (x*A,2)
b =
1 0 1 1 1 0 1 0 1 1
To find x, am getting
>> k = b / A
k =
Columns 1 through 6
1.3750 -0.5000 -0.7500 -0.7500 0.8750 -0.5000
Columns 7 through 10
1.8750 -0.5000 2.1250 -0.7500
or if am using modulus 2, the result is
>> k = mod (b / A,2)
k =
Columns 1 through 6
1.3750 1.5000 1.2500 1.2500 0.8750 1.5000
Columns 7 through 10
1.8750 1.5000 0.1250 1.2500
So ,how can I get x in the same binary form? and by the way matrices are all in class double not galois field
This example at Mathworks shows how to perform boolean matrix inversion with MATLAB and I believe answers your question.
I have not quite gotten it working perfectly, but I believe you need to use a combination of mod() and logical() for example:
A=logical(A);
b=(mod(x*A,2));
inverseA= ~A;
k=mod(b*inverseA,2)
this gives
k=[1 1 0 0 1 1 0 1 0 0]
which is not x, but i think if you play around with the logical function and logical operations in conjunction with mod() you should be able to get it to work
To solvexin binary form, matrix A should be in galois field.
consider the following example;
>> x = randi ([0 1],1,10)
x =
1 1 0 1 1 1 0 1 1 1
>> A = gf (randi([0 1],10,10))
A = GF(2) array.
Array elements =
Columns 1 through 6
1 1 1 0 0 1
1 0 1 0 1 0
1 0 1 1 0 1
0 0 0 0 0 1
1 1 1 0 1 1
0 1 0 1 0 1
0 0 0 1 1 1
0 1 0 0 1 0
0 0 1 0 1 0
0 0 1 0 0 1
Columns 7 through 10
1 1 0 0
1 0 1 1
1 1 0 0
0 0 1 0
1 1 1 1
0 1 1 1
1 0 1 0
1 1 1 0
1 0 0 0
1 1 1 0
then,
>> b = x*A
b = GF(2) array.
Array elements =
Columns 1 through 6
1 0 1 1 0 1
Columns 7 through 10
0 1 0 1
>> x_solved = b*inv (A)
x_solved = GF(2) array.
Array elements =
Columns 1 through 6
1 1 0 1 1 1
Columns 7 through 10
0 1 1 1
As you can see x_solved is the same as the original x. Therefore you should convert matrix A to galois field by just running a codeA = gf(A).

distribute matrix values of a binary image

I need to take the tril below and distribute the values equally so it ends up like a modified checkerboard.
x=ones(1186,686);
x2=tril(x);
A sample simplified matrix of what I need to have happen is below:
1 1 1 1 1 1
1 1 1 1 1 1
0 1 1 1 1 1
0 0 1 1 1 1
0 0 0 1 1 1
0 0 0 0 1 1
0 0 0 0 0 1
0 0 0 0 0 0
0 0 0 0 0 0
The matrix above needs to be changed into:
1 1 1 1 1 1
1 1 1 1 1 1
1 0 1 1 1 1
1 0 1 0 1 1
1 0 1 0 1 0
1 0 1 0 0 0
1 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
I've tried looking for built in MATLAB functions that would evenly distribute the zeros values across the board, but have not found anything that works. In terms of the output, where the ones and zeros appear is somewhat irrelevant. They just need to be distributed as evenly as possible within the matrix. For example the 3rd line of the modified matrix could = 1 1 1 0 1 1 or the like.
Would be be possible to achieve this effect a different way than starting with the tril that I'm not seeing?
For Beaker and anyone that wants to comment on how I could have better asked my original question.
This is the result of what I wanted. It's not exactly what I had described, but it achieves the same function I'm after. It's Completely different direction. I'm doing image analysis of the mixing and segregation of particles. Having contrived images like this allows me to determine if my mixing algorithm is producing the results I'm expecting. I can use the interleaving code you gave to continue making new and interesting patterns (not shown).
img=checkerboard(1,1186,686);
img_bw=im2bw(img);
img_mix=triu(img_bw,-500);
img_neg=imcomplement(img_mix);
imshow(img_neg)
I think this might be what you're after. Note that I borrowed the interleave-by-reshape trick from this blog post. (I also used triu instead of tril since it matched your example.)
x=ones(12,10);
x2=triu(x);
[rows,cols]=size(x2);
a = x2(:,1:cols/2);
b = x2(:,end:-1:(cols/2)+1);
% interlave two same sized matrices by column
a = a.';
b = b.';
col_interleave = reshape([b(:) a(:)]',2*size(a,1), []).'
Output is:
col_interleave =
1 1 1 1 1 1 1 1 1 1
1 0 1 1 1 1 1 1 1 1
1 0 1 0 1 1 1 1 1 1
1 0 1 0 1 0 1 1 1 1
1 0 1 0 1 0 1 0 1 1
1 0 1 0 1 0 1 0 1 0
1 0 1 0 1 0 1 0 0 0
1 0 1 0 1 0 0 0 0 0
1 0 1 0 0 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
0 0 0 0 0 0 0 0 0 0

Matlab how to bitwise-AND of a vector and a matrix?

I want to find out the index of the matrix column in which the vector appears. My idea is to do AND of the vector over matrix and only the column that is the same will be 1 in the new vecotr. But I don't know how to do this. Below is example:
H =
0 0 0 0 1 1 1 1 1 1 1 1 0 0 0
0 1 1 1 0 0 0 1 1 1 1 0 1 0 0
1 0 1 1 0 1 1 0 0 1 1 0 0 1 0
1 1 0 1 1 0 1 0 1 0 1 0 0 0 1
S =
0 1 0 1
From that I want to get 2 as second column or even better vector
0 1 0 0 0 0 ... 0
Since there is error in second column.
How can I do this in Matlab or even better Octave?
Not really sure how you tried to approach the problem. But with repmat or bsxfun it is as simple as this:
all(bsxfun(#eq,H,S'))
How about
result = sum(H==repmat(S(:),[1 size(H,2)]))==4;
I found out the function
ismember(H', S, "rows")
works exactly as I want. Your answers are all good too, thanks.
That's pretty easy with broadcasting. The following will require Octave 3.6.0 or later but you can use bsxfun if you have a previous version:
octave-cli-3.8.1> h = logical ([
0 0 0 0 1 1 1 1 1 1 1 1 0 0 0
0 1 1 1 0 0 0 1 1 1 1 0 1 0 0
1 0 1 1 0 1 1 0 0 1 1 0 0 1 0
1 1 0 1 1 0 1 0 1 0 1 0 0 0 1]);
octave-cli-3.8.1> s = logical ([0 1 0 1]');
octave-cli-3.8.1> all (h == s)
ans =
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
From here, it's all a matter of using find to get the column numbers. It will even work if it matches more than 1 column:
octave-cli-3.8.1> find (all (h == s))
ans = 2

Grouping logical data in Matlab

I have a matrix that contains data of 0 & 1. I want to find groups of ones (not a specific size) in that matrix. Is it possible somehow?
Thanks in advance!
If you mean that you want to find all the "connected components in the matrix, say BW, simply use:
BW = logical([1 1 1 0 0 0 0 0
1 1 1 0 1 1 0 0
1 1 1 0 1 1 0 0
1 1 1 0 0 0 1 0
1 1 1 0 0 0 1 0
1 1 1 0 0 0 1 0
1 1 1 0 0 1 1 0
1 1 1 0 0 0 0 0]);
L = bwlabel(BW,4) %Result
This would yeild:
L =
1 1 1 0 0 0 0 0
1 1 1 0 2 2 0 0
1 1 1 0 2 2 0 0
1 1 1 0 0 0 3 0
1 1 1 0 0 0 3 0
1 1 1 0 0 0 3 0
1 1 1 0 0 3 3 0
1 1 1 0 0 0 0 0
Now if you want to find the size of various groups:
for ii=1:max(L(:))
length_vector(ii)=length(find(L==ii));
end
length_vector
This gives you:
length_vector =
24 4 5