Assigning values to a matrix, Right Hand Side is a Function of the Index - matlab

I am trying to assign multiple values simultaneously to a matrix using MATLAB vectorization. In my code, I currently have something like:
y(1,:) = G(x(1:2,:))
y(2,:) = G(x(3:4,:))
and so on..
G is a function which involves relational operators with rows of the input argument as operands.
function g = G(x)
g = x(1,:) | x(2,:)
Is there a way to apply function G to the entire x-array without using a for-loop?
Thanks.

For this type of function it is indeed possible. Define your function so that it works with all rows at the same time:
G = #(x) x(1:2:end,:) | x(2:2:end,:)
and then:
y = G(x);
Example: let
x =
1 1 0 1 0
0 0 0 0 0
1 1 0 0 0
1 0 1 0 1
1 1 1 1 1
1 0 0 1 1
Then y = G(x) gives
y =
1 1 0 1 0
1 1 1 0 1
1 1 1 1 1

Related

Get dynamic rows of matrix based on the ones of another matrix (Matlab)

I am new to Matlab and I need some help.
I want compute Parity Check Matrix and then to encode a codeword using Generator Matrix
My matrix is the following :
1 0 0 0 1 1 1
0 1 0 0 1 1 0
0 0 1 0 1 0 1
0 0 0 1 0 1 1
The codeword is 1 0 1 1.
My code in Matlab is as follow :
printf('Generator Matrix\n');
G = [
1 0 0 0 1 1 1;
0 1 0 0 1 1 0;
0 0 1 0 1 0 1;
0 0 0 1 0 1 1
]
[k,n] = size(G)
P = G(1:k,k+1:n)
PT = P'
printf('Parity Check Matrix\n');
H = cat(2,PT,eye( n-k ))
printf('Encode the following word : \n');
D = [1 0 1 1]
C = xor( G(1,:), G(3,:) , G(4,:) )
My problem is that I want to get dynamically the rows of G Matrix in order to make the xor operation.
Could you help me please ?
Thanks a lot
You only need matrix multiplication modulo 2:
C = mod(D*G, 2);
Alternatively, compute the sum of the rows of G indicated by D, modulo 2:
C = mod(sum(G(D==1,:), 1), 2);

Performing an averaging operation over every n elements in a vector

I have a logical vector in which I would like to iterate over every n-elements. If in any given window at least 50% are 1's, then I change every element to 1, else I keep as is and move to the next window. For example.
n = 4;
input = [0 0 0 1 0 1 1 0 0 0 0 1 0 1 0 1 0 0 0 1];
output = func(input,4);
output = [0 0 0 1 1 1 1 1 0 0 0 1 1 1 1 1 0 0 0 1];
This function is trivial to implement but is it possible to apply a vectorized implementation using logical indexing?. I am trying to build up the intuition of applying this technique.
here's a one liner (that works for your input):
func = #(input,n) input | kron(sum(reshape(input ,n,[]))>=n/2,ones(1,n));
of course, there are cases to solve that this doesnt answer, what if the size of the input is not commensurate in n? etc...
i'm not sure if that's what you meant by vectorization, and I didnt benchmark it vs a for loop...
Here is one way of doing it. Once understood you can compact it in less lines but I'll details the intermediate steps for the sake of clarity.
%% The inputs
n = 4;
input = [0 0 0 1 0 1 1 0 0 0 0 1 0 1 0 1 0 0 0 1];
1) Split your input into blocks of size n (note that your final function will have to check that the number of elements in input is a integer multiple of n)
c = reshape(input,n,[]) ;
Gives you a matrix with your blocks organized in columns:
c =
0 0 0 0 0
0 1 0 1 0
0 1 0 0 0
1 0 1 1 1
2) Perform your test condition on each of the block. For this we'll take advantage that Matlab is working column wise for the sum function:
>> cr = sum(c) >= (n/2)
cr =
0 1 0 1 0
Now you have a logical vector cr containing as many elements as initial blocks. Each value is the result of the test condition over the block. The 0 blocks will be left unchanged, the 1 blocks will be forced to value 1.
3) Force 1 columns/block to value 1:
>> c(:,cr) = 1
c =
0 1 0 1 0
0 1 0 1 0
0 1 0 1 0
1 1 1 1 1
4) Now all is left is to unfold your matrix. You can do it several ways:
res = c(:) ; %% will give you a column vector
OR
>> res = reshape(c,1,[]) %% will give you a line vector
res =
0 0 0 1 1 1 1 1 0 0 0 1 1 1 1 1 0 0 0 1

Finding a binary matrix such that the given hamming weight is constant

Given a square binary matrix. I want to get all possible binary matrices which are at d Hamming distance apart.
Suppose
A=[1 0 1;
0 1 1;
1 1 0].
Then a matrix which is one (d) Hamming distance apart is
[0 0 1;
0 1 1;
1 1 0].
Any help in Matlab base coding?
I am hoping that I got the definition of hamming weight right in the given context. Based on that hope/assumption, this might be what you were after -
combs = dec2base(0:2^9-1,2,9)-'0'; %//'# Find all combinations
combs_3d = reshape(combs',3,3,[]); %//'# Reshape into a 3D array
%// Calculate the hamming weights between A and all combinations.
%// Choose the ones with hamming weights equal to `1`
out = combs_3d(:,:,sum(sum(abs(bsxfun(#minus,A,combs_3d)),2),1)==1)
Thus, each 3D slice of out would give you such a 3 x 3 matrix with 1 hamming weight between them and A.
It looks like you have 9 such matrices -
out(:,:,1) =
0 0 1
0 1 1
1 1 0
out(:,:,2) =
1 0 1
0 1 1
0 1 0
out(:,:,3) =
1 0 1
0 0 1
1 1 0
out(:,:,4) =
1 0 1
0 1 1
1 0 0
out(:,:,5) =
1 0 0
0 1 1
1 1 0
out(:,:,6) =
1 0 1
0 1 0
1 1 0
out(:,:,7) =
1 0 1
0 1 1
1 1 1
out(:,:,8) =
1 1 1
0 1 1
1 1 0
out(:,:,9) =
1 0 1
1 1 1
1 1 0
Edit
For big n, you need to use loops it seems -
n = size(A,1);
nsq = n^2;
A_col = A(:).';
out = zeros(n,n,nsq);
count = 1;
for k1 = 0:2^nsq-1
match1 = dec2bin(k1,nsq)-'0';
if sum(abs(match1-A_col))==1
out(:,:,count) = reshape(match1,n,n);
count = count + 1;
end
end

Combination, Subset, MATLAB

I use combnk to generate a list of combinations. But, the result shape is not my required data. I want for example for combnk(1:3,2):
1 1 0
0 1 1
1 0 1
not
1 2
1 3
2 3
How can i do it? How can i change the combnk in optimal way to give results?
Don't you mean you want
1 1 0
1 0 1
0 1 1
instead of
1 2
1 3
2 3
So that each row is a logical selection vector for the original vector v?
You can get this with the following:
v = 1:3;
k = 2;
tmp = combnk(v,k);
M = size(tmp,1);
output = false(M,numel(v));
output(sub2ind(size(output),repmat((1:M)',1,k),tmp))=true;
result:
output =
1 1 0
1 0 1
0 1 1
Another solution:
c = combnk(1:3,2);
r = repmat(1:size(c,1), [1 size(c,2)]);
output = full(sparse(r,c(:),1))
result:
output =
1 1 0
1 0 1
0 1 1

Is there any function in MATLAB for changing the form of a matrix?

I have to get the unknown matrix by changing the form of a known matrix considering the following rules:
H = [-P'|I] %'
G = [I|P]
where
H is a known matrix
G is an unknown matrix which has to be calculated
I is the identity matrix
So for example, if we had a matrix,
H = [1 1 1 1 0 0;
0 0 1 1 0 1;
1 0 0 1 1 0]
its form has to be changed to
H = [1 1 1 1 0 0;
0 1 1 0 1 0;
1 1 0 0 0 1]
So
-P' = [1 1 1;
0 1 0;
1 1 0]
and in case of binary matrices -P = P.
Therefore
G = [1 0 0 1 1 1;
0 1 0 0 1 0;
0 0 1 1 1 0]
I know how to solve it on paper by performing basic row operations but haven't figured out how to solve it using MATLAB yet.
What is the method for solving the given problem?
If the order of columns in -P' doesn't matter, here's one solution using the function ISMEMBER:
>> H = [1 1 1 1 0 0; 0 0 1 1 0 1; 1 0 0 1 1 0]; %# From above
>> pColumns = ~ismember(H',eye(3),'rows') %'# Find indices of columns that
%# are not equal to rows
pColumns = %# of the identity matrix
1
0
1
1
0
0
>> P = -H(:,pColumns)' %'# Find P
P =
-1 0 -1
-1 -1 0
-1 -1 -1
>> G = logical([eye(3) P]) %# Create the binary matrix G
G =
1 0 0 1 0 1
0 1 0 1 1 0
0 0 1 1 1 1
NOTE: This solution will work properly for integer or binary values in H. If H has floating-point values, you will likely run into an issue with floating-point comparisons when using ISMEMBER (see here and here for more discussion of this issue).