2
votes

Beginner at Matlab. Let's say I have a matrix

A = [ 2,3,4;
      6,9,1;
      7,8,3;
      2,2,2 ]

I want to manipulate each column into a new column (of potentially different size) and then I want to have the whole new matrix. As an example, suppose I want to get rid of every number less than 4 and raise every other number to the fourth power. This is much simpler than what I'm actually trying to do so don't read too much into those specifics.

If I were to do it for a specific column, say the first one, I would do

newcolumn=[];
for r=1:4
    if A(r,1)<4
        newcolumn=newcolumn
    else
        newcolumn=vertcat(newcolumn,(A(r,1))^4))
    end
end

Is it possible to do a double for loop to create the whole matrix?

Thanks

2
What should happen if the number of elements less than 4 in each column are unequal? I hope you realize that we cannot just remove it since the number of elements in each row should be equal and same applies for column, if you want it to be a matrix. In your example, if I remove elements less than 4, then A will be a vector=[6 7 9 8 4]. Now how to arrange it in a new matrix? - Autonomous

2 Answers

1
votes

So if you want the columns to no longer be of the same size then you will have to use a cell array or pad you numerical matrix with some defualt value, probably NaN. Also you don't need a double loop because your loop above is unecessary:

newcolumn=[];
for r=1:4
    if A(r,1)<4
        newcolumn=newcolumn
    else
        newcolumn=vertcat(newcolumn,(A(r,1))^4))
    end
end

is equivalent to

newcolumn = A(A(:,1) < 4, 1).^4;

so now you just need to loop along the columns:

jaggedArray{1,size(A,2)} = []; %// Pre-allocate your array (NB for efficiency in Matlab!)
for col = 1:size(A,2)
    jaggedArray{col} = A(A(:,col) < 4, col).^4;
end
0
votes

If the result has a different number of elements for each row, you can use a cell array to store it.

Two possible approaches:

  1. Using arrayfun (which is equivalent to a for loop):

    B = arrayfun(@(n) A(n,A(n,:)>=4).^4, 1:size(A,1), 'uniformoutput', false);
    

    This takes every number n from 1 up to the number of rows size(A,1), and applies to it the anonymous function @(n) A(n,A(n,:)>=4).^4, which does what you want. It then puts the result into B{n}. The option 'uniformoutput', false indicates that the results are not scalars, so a cell array is created to store them.

  2. Using cellfun: If the function you want to apply to each row is complicated, instead of using an anonymous function you may define it normally in a file, say foo.m. In this case it's easier if your function accepts a row (not the number n) as input:

    %// File foo.m
    function y = foo(x) %// x is a row, y is a row of possibly different size
    y = x(x>=4).^4;
    

    You then split A into a cell array of its rows

    Acell = mat2cell(A, ones(1,size(A,1)), size(A,2));
    

    and then call cellfun with a function handle to your function:

    B = cellfun(@foo, Acell, 'uniformoutput', false);
    

I know all this may be a little beyond Matlab beginner's knowledge, but that's the point of the answer :-)