-2

私は自分の研究をしています。この次の行列を表示するコードを作成するのに問題があります。

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]

行列Cは、行列Aの値の前にゼロがいくつあるかを示す行列です。

そして、私は行列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]

そのため、Aと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]

私は他のフォーラムからこれをフォローしています。

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

あなたの意見は何ですか?

4

1 に答える 1

2

手始めに、あなたの行列Aが最初A = [ 1 2 3 4; 3 2 1 4]A(1)、、A(2)をどのようA(3)に同時に保持するかを理解していませんA(4)

代わりに次のものがあると思います。

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];

これを想定すると、次の方法で目的の結果を得ることができます。

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

これにより、次のようになります。

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

編集#1:

質問の更新に続いて、行列C = [0, 0, 1, 2; 1, 1, 1, 0]の前に挿入する先行ゼロの数を表す別の行列があるB場合は、次の方法で目的の結果を得ることができます。

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))

これにより、次のようになります。

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

編集#2:

質問の2回目の更新に続いて、A行列Cが3次元の場合、これによりコードが非常に複雑になります。for次のように、ループを使用して問題を2Dに減らすのが最も簡単だと思います。

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

Res反復ごとに異なるサイズが必要な場合はRes、セル配列を作成することをお勧めします。

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

PS 2番目の行には、最初の行と同じ量のゼロがないため、
2回目の反復で問題が発生することに注意してください。C = [1, 0, 1, 0; 0, 1, 1, 1]私はあなたがこのような何かを意味したと信じています:C = [1, 1, 1, 0; 0, 1, 1, 1]

編集#3:

ランダム行列を生成するコードは次のとおりです。C各行の合計は、事前定義された整数K(これも任意に選択されます)になります。

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
于 2012-09-06T12:57:58.400 に答える