Question

I am doing my research. I have problem to make code to present this following matrices.

A(:,:,1)=[ 1 2 3 4;
           3 2 1 4]
A(:,:,2)=[ 1 3 4 2;
           4 2 1 3]

C(:,:,1)=[ 0 0 1 2;
           1 1 1 0]
C(:,:,2)=[ 1 0 1 0;
           0 1 1 1]

Matrices C is matrices that show how many zeros before value in matrice A.

And i have this following matrices to present value in matrices A.

value=1, 
B(1)=[1 1 1;
      1 1 1]
value=2,
B(2)=[2 2 2;
      2 2 2]
value=3,
B(3)=[3 3 3;
      4 4 4]
value=4,
B(4)=[4 4 4;
      3 3 3]

So that I will get this following matrices by combining A and C.

Res(:,:,1)=[1 1 1 2 2 2 0 3 3 3 0 0 4 4 4;
            1 1 1 2 2 2 0 4 4 4 0 0 3 3 3;
            0 3 3 3 0 2 2 2 0 1 1 1 4 4 4;
            0 4 4 4 0 2 2 2 0 1 1 1 3 3 3]

Res(:,:,2)=[0 1 1 1 3 3 3 0 4 4 4 2 2 2 0;
            0 1 1 1 4 4 4 0 3 3 3 2 2 2 0;
            4 4 4 0 2 2 2 0 1 1 1 0 3 3 3;
            3 3 3 0 2 2 2 0 1 1 1 0 4 4 4]

I got this following from other forum.

CP = bsxfun(@minus, 3 , sum(C,2));
G = mat2cell(C,ones(size(C,1),1),ones(size(C,2),1),ones(size(C,3),1));
CP = mat2cell(CP,ones(size(CP,1),1),ones(size(CP,2),1),ones(size(CP,3),1));
D = B(A);
E = cellfun(@(x,n) [zeros(size(x,1),n) x], D, G,'UniformOutput',false);
for ii=1:depth;
    E(:,end,ii) = cellfun(@(x,n) [x,zeros(size(x,1),n)],E(:,end,ii),CP(:,:,ii),...
   'UniformOutput',false);
    NewMatrice(:,:,ii)=cell2mat(E(:,:,ii));
end

What is your Opinion?

Was it helpful?

Solution

For starters, I don't understand how your matrix A both holds the first A = [ 1 2 3 4; 3 2 1 4] and A(1), A(2), A(3) and A(4) at the same time.

I suppose that you have the following instead:

A = [1, 2, 3, 4; 3, 2, 1, 4];
B(:, :, 1) = [1, 1, 1; 1, 1, 1];
B(:, :, 2) = [2, 2, 2; 2, 2, 2];
B(:, :, 3) = [3, 3, 3; 4, 4, 4];
B(:, :, 4) = [4, 4, 4; 3, 3, 3];

Assuming this, you can get your desired result in the following way:

Res = cell2mat(arrayfun(@(n)B(:, :, n), A, 'UniformOutput', false));

which yields:

Res =

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

EDIT #1:

Following the update to your question, if you have another matrix C = [0, 0, 1, 2; 1, 1, 1, 0] that represents the number of leading zeros to insert before the B matrices, you can get your desired result in the following way:

my_func = @(n)[zeros(size(B(:, :, A(n)), 1), C(n)), B(:, :, A(n))];
Res = cell2mat(arrayfun(my_func, reshape(1:numel(A), size(A)), 'Uniform', false))

this yields:

Res =

  Columns 1 through 15

     1    1    1    2    2    2    0    3    3    3    0    0    4    4    4
     1    1    1    2    2    2    0    4    4    4    0    0    3    3    3
     0    3    3    3    0    2    2    2    0    1    1    1    4    4    4
     0    4    4    4    0    2    2    2    0    1    1    1    3    3    3

EDIT #2:

Following the second update to your question, if your A and C matrices are 3-dimensional, this adds a lot of complexity to the code. I find it easiest to use a for loop and reduce the problem to 2-D, like so:

for k = 1:size(A, 3)
    A2 = A(:, :, k);
    C2 = C(:, :, k);
    my_func = @(n)[zeros(size(B(:, :, A2(n)), 1), C2(n)), B(:, :, A2(n))];
    Res(:,:,k) = cell2mat(arrayfun(my_func,reshape(1:numel(A2),size(A2)),'Un',0))
end

If you want different sizes for Res in each iteration, I suggest you make Res a cell array, i.e.:

Res{k} = cell2mat(arrayfun(my_func,reshape(1:numel(A2),size(A2)),'Un',0))

P.S.
Notice that for the second iteration you have C = [1, 0, 1, 0; 0, 1, 1, 1] you'll get a problem, because the second row won't have the same amount of zeroes as the first. I believe you meant something like this: C = [1, 1, 1, 0; 0, 1, 1, 1].

EDIT #3:

Here's code to generate a random matrix C, where each row sums up to a predefined integer K (which is also chosen arbitrarily):

K = fix(size(A, 2) * (1 + rand));                         %# Pick a random K
C = rand(size(A));                                        %# Generate a random C
C = ceil(C * K ./ repmat(sum(C, 2), 1, size(A, 2))) - 1;  %# Normalize
C(:, end) = C(:, end) + K - sum(C, 2);                    %# Fix illegal rows
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top