Расширение матрицы по диагонали с помощью Matlab

#arrays #matlab #matrix

#массивы #matlab #матрица

Вопрос:

У меня есть матрица B , и я хочу получить матрицу C размерности (L k)*m by L*n . L и k являются входными значениями. B0 , B1 , ... , Bk имеет размер m на n .

введите описание изображения здесь

Например :

Если у меня есть матрица B = [1 1 ; 1 1 ; 1 1] с B0 = [1 1] , B1 = [1 1] и B2 = [1 1] , и каждое B0 , B1 , B2 из измерений 1 2 с k = 2 помощью и L = 4 .

Затем C полученная матрица задается C = [1 1 0 0 0 0 0 0 ; 1 1 1 1 0 0 0 0 ; 1 1 1 1 1 1 0 0 ; 0 0 1 1 1 1 1 1 ; 0 0 0 0 1 1 1 1 ; 0 0 0 0 0 0 1 1] и имеет размерность 6 by 8 .

введите описание изображения здесь

Я хотел бы обобщить свою программу для матрицы любого размера B .

Моя программа решает проблему для B = [1 1 ; 1 1 ; 1 1] с m = 1 , n = 2 , k = 2 и L = 4 .

Мой код :

 clc;
clear;

k = 2;                    
L = 4;                   

B = [1 1 ; 1 1 ; 1 1];    
B0 = [1 1];
B1 = [1 1];
B2 = [1 1];
m = size(B0,1);
n = size(B0,2);

c = [B ; zeros(size(B))];
C = zeros((L k)*m,L*n);

for i = 1:L
    
    C(:,2*i-1:2*i) = circshift(c,i-1,1);
    
end
 

Результат : C =

 1   1   0   0   0   0   0   0
1   1   1   1   0   0   0   0
1   1   1   1   1   1   0   0
0   0   1   1   1   1   1   1
0   0   0   0   1   1   1   1
0   0   0   0   0   0   1   1
 

У меня возникают трудности с обобщением для любой заданной матрицы B и для любого значения k и L .

Есть предложения?

Ответ №1:

 B = [1 2 3; 4 5 6; 7 8 9; 100 110 120; 130 140 150; 160 170 180];  % input
L = 4;                                                             % input
k = 2;                                                             % input
m = size(B,1)/(k 1);              % obtain m
n = size(B,2);                    % obtain n
C = zeros((L-1)*m 1, (L-1)*n 1);  % initiallize result
C(1:((L-1)*m 1)*n m:end) = 1;     % each 1 marks the upper-left corner for a copy of B
C = conv2(C, B);                  % insert copies of B, extending size
 

В предпоследней строке используется линейное индексирование. В последней строке применяется двумерная свертка. Результат в этом примере

 B =
     1     2     3
     4     5     6
     7     8     9
   100   110   120
   130   140   150
   160   170   180

C =
     1     2     3     0     0     0     0     0     0     0     0     0
     4     5     6     0     0     0     0     0     0     0     0     0
     7     8     9     1     2     3     0     0     0     0     0     0
   100   110   120     4     5     6     0     0     0     0     0     0
   130   140   150     7     8     9     1     2     3     0     0     0
   160   170   180   100   110   120     4     5     6     0     0     0
     0     0     0   130   140   150     7     8     9     1     2     3
     0     0     0   160   170   180   100   110   120     4     5     6
     0     0     0     0     0     0   130   140   150     7     8     9
     0     0     0     0     0     0   160   170   180   100   110   120
     0     0     0     0     0     0     0     0     0   130   140   150
     0     0     0     0     0     0     0     0     0   160   170   180
 

Комментарии:

1. Это именно то, что я хочу. Спасибо @Luis Mendo.

2. Привет, Луис, я предложил небольшую модификацию, чтобы учесть случай, когда size(B,1)/(k 1) не выводится целое число. В конечном итоге вы можете добавить эту опцию в свой ответ, чтобы я мог удалить свое предложение.

3. @obchardon Нет, я думаю, что лучше оставить свой ответ. Кроме того, он использует другой подход ( sparse ) для создания матрицы 0-1

Ответ №2:

В дополнение к ответу @LuisMendo:

Если size(B,1)/(k 1) не выдать целое число, то его решение может потерпеть неудачу.

Я бы предложил создать C матрицу с sparse() :

 n = size(B,2)
C = full(sparse(1:k:k*L,1:n:n*L,1))
 

Таким образом, весь код становится:

 B = ones(7,3);                       % An input matrix that will produce an error with the linear indexing solution. 
L = 6;                               % number of repetition
k = 2;                               % row-shift
n = size(B,2);                       % obtain n
C = full(sparse(1:k:k*L,1:n:n*L,1)); % Create C using full(sparse())
C = conv2(C, B)                      % insert copies of B, extending size
 

(все кредиты принадлежат ЛуизМендо за идею)

Ответ №3:

Это решение, используемое в ответе @ sparse obchardon, но, в отличие от ответа @LuisMendo, не используется conv2 . Индексы блоков вычисляются и используются sparse для формирования желаемой матрицы.

     [row col] = find(true(size(B)));
    ROW = row   (0:L-1)*k;
    COL = col   (0:L-1)*size(B,2);
    C = sparse (ROW, COL, repmat (B, 1, L));
 

Комментарии:

1. Простейшее решение! Очень приятно