#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. Простейшее решение! Очень приятно