Matlab Convolution Array with vector row by row - Galois Field(2) - arrays

Let's say I have array A(n,k) and vector b(1,4). Matrix and vector's context are on Galois Field (2).
Is there any way to convolute each row of A with vector b without for loop?
For example if A is of size (4,5) then the command should do the following:
conv(A(1,:),b)
conv(A(2,:),b)
conv(A(3,:),b)
conv(A(4,:),b)
Any ideas?

You can first convert A to a cell array and then use cellfun to apply your function to every element of the cell array, such as:
cellA = num2cell(A, 2) % creates a cell array where each element is a row of A
result = cellfun(#(row)(conv(row, b)), cellA);
Here #(row)(conv(row, b)) is an anonymous function that takes one element of the cell array and applies your conv function to it and your b vector

Related

Sub2ind with three dimension - access all of dimension

Say A is a 3x4x5 array. I am given a vector a, say of dimension 2 and b of dimension 2. If I do A(a,b,:) it will give 5 matrices of dimensions 2x2. I instead want the piecewise vectors (without writing a for loop).
So, I want the two vectors of A which are given by (a's first element and b's first element) and (a's second element and b's second element)
How do I do this without a for loop? If A were two dimensions I could do this using sub2ind. I don't know how to access the entire vectors.
You can use sub2ind to find the linear index to the first element of each output vector: ind = sub2ind(size(A),a,b). To get the whole vectors, you can't do A(ind,:), because the : has to be the 3rd dimension. However, what you can do is reshape A to be 2D, collapsing the first two dimensions into one. We have a linear index to the vectors we want, that will correctly index the first dimension of this reshaped A:
% input:
A = rand(3,4,5);
a = [2,3];
b = [1,2];
% expected:
B = [squeeze(A(a(1),b(1),:)).';squeeze(A(a(2),b(2),:)).']
% solution:
ind = sub2ind(size(A),a,b);
C = reshape(A,[],size(A,3));
C = C(ind,:)
assert(isequal(B,C))
You can change a and b to be 3d arrays just like A and then the sub2ind should be able to index the whole matrix. Like this:
Edit: Someone pointed out a bug. I have changed it so that a correction gets added. The problem was that ind1, which should have had the index number for each desired element of A was only indexing the first "plane" of A. The fix is that for each additional "plane" in the z direction, the total number of elements in A in the previous "planes" must be added to the index.
A=rand(3,4,5);
a=[2,3];
b=[1,2];
a=repmat(a,1,1,size(A,3));
b=repmat(b,1,1,size(A,3));
ind1=sub2ind(size(A),a,b);
correction=(size(A,1)*size(A,2))*(0:size(A,3)-1);
correction=permute(correction,[3 1 2]);
ind1=ind1+repmat(correction,1,2,1);
out=A(ind1)

Targeting specific elements of cell arrays (Matlab)

I currently have a cell array consisting of 7x1 vectors. I need to extract the first element (1,1) of each vector from each cell and store these values in a new array. This is what I currently have:
for j = 1:numel(xvalues)
cellj = xvalues{j};
a = cellj(1:1);
avalues(1:j) = a;
end
However, I am just generating a cell array with the first element of the last cell, repeating.
How can I fix this?
You can also use cellfun to apply a function to each element in a cell array. So to extract the first element of each vector the following should work.
avalues = cellfun(#(x) x(1),xvalues);
Cellfun loops through each element in the cell array and passes it in to the anonymous function via #(x). We then process x by taking the first element x(1).
In cases such as yours, where the cell contents are matrices of the same size, and assuming your inputs are small enough (meaning that neither memory nor runtime are imminent issues) you can convert the cell array into a numeric matrix and select a vector along the relevant dimension:
function out = q48740494
%% Generate some data:
c = squeeze(num2cell(randi(20,7,1,20),[1,2]));
% c = 20×1 cell array of {7x1 double}
%% Convert this into a numeric array and output:
out = cell2mat(c.'); out = out(1,:);
% BONUS: another version of the line above.
% out = subsref(cell2mat(c.'), substruct('()', {1,1:numel(c)}) ) ;

Save unlimited matrix from cell arrays

I get a cell array which contains 103 cells of different dimensions. Each cell of my cell array represents a matrix and it can be displayed as an image. How can I extract each cell (ie each matrix) in a for loop?
I know how to do that one by one but not for the whole cell :
image1 = cellArray{1}; % extract matrix 1 (on 103) from the cell array #1
image2 = cellArray{2}; % and so on
Thanks for your help
The easiest way to loop through your cell array and apply to same function to every cell is to use cellfun. If your function returns a scalar e.g.
f = #(x)max(:)
then it's as simple as
cellfun(f, cellArray)
Note that f above is an anonymous function (or rather a function handle to an anonymous function), but more likely your function will be in its own m-file in which case you need to use the # operator:
cellfun(#f, cellArray)
Lastly, if your output is not a scalar then call
cellfun(#f, cellArray, 'uni' 0)

How can I check whether an element is in a nested cell array?

How can I check whether an element is in a nested cell array?
ex:
A = {{4 5 6};{6 7 8}};
b = 5;
The function
ismember(b,A{1})
does not work.
Is there any solution better than for-loop?
Because each element is a cell, you don't have a choice but to use cellfun combined with ismember, which is the same as using a loop in any case. Your cells are specifically two-deep (per Andrew Janke). Each cell element in your cell array is another cell array of individual elements, so there is no vectorized solution that can help you out of this.
Assuming that each cell is just a 1-D cell array of individual elements, you would thus do:
A = {{4 5 6};{6 7 8}};
b = 5;
out = cellfun(#(x) ismember(b, cell2mat(x)), A);
Which gives us:
out =
1
0
This checks to see if the value b is in each of the nested cell arrays. If it is your intention to simply check for its existence over the entire nested cell array, use any on the output, and so:
out = any(cellfun(#(x) ismember(b, cell2mat(x)), A));
Because each cell element is a cell array of individual elements, I converted these to a numerical vector by cell2mat before invoking ismember.

How to remove a row from a matrix inside a cell array

I have a cell array (A) with size of 400 x 1 and each cell of this array includes a matrix with size 9 x 4. As such, it looks like this:
A={[9x4 double];[9x4 double];...;[9x4 double]};
Now, I want to remove the zero rows from these sub matrices and then obtain a new A cell array called A_new where its sub matrices don't have any zero rows like this:
A_new={[5x4 double];[7x4 double];...;[4x4 double]};
By my below code, I can find the index of rows which are not zero but I couldn't create my cell array like I mentioned above. This is my written code and for the bold part, I have a problem and I couldn't solve it.
for i=1:A_Length
[row,col]=find(A{i,1});
out=[row col];
NNZ_row=unique(row);
Length_NNZ= length(NNZ_row);
for j=1:Length_NNZ
**A_NonZero{i,1}= ??????????**
end
end
What I would do is take each cell, then use all on the opposite of the matrix over all of the columns in each row to determine which rows contain all zeroes. Once you do this, use these locations and remove those rows from this matrix and save this to your new matrix.
As such, do this:
A_new = cell(1,numel(A));
for i=1:numel(A)
mat = A{i};
ind = all(~mat, 2);
A_new{i} = mat(~ind,:);
end
The first line of code creates a new cell array that is the same size as A. Next, for each element in A, extract the matrix at each cell location, use all on the opposite of this matrix to find those elements that we need to keep, then save this new matrix into the corresponding location in A_new.
If you want to do this in a single line of code, use cellfun:
A_new = cellfun(#(x) x(~all(~x,2),:), A, 'uni', 0);
The first argument to cellfun is an anonymous function that performs what the for loop was doing. We find those rows that contain all zeroes and use those to remove the rows in each matrix in the cell array. The second argument is the matrix we want to operate on, which is A. The 'uni' and 0 flags are important because the outputs are not single values but matrices, and so the output of this function will be a cell array that is the same size as A where each element is the matrix for those corresponding locations in A with the zero rows removed.
You should use a combination of cellfun and any:
A_new = cellfun(#(x) x(any(x~=0,2),:), A, 'UniformOutput', false);
should do the trick.

Resources