создание диагональной матрицы с выбранными элементами

У меня есть матрица 4x5 с именем A, из которой я хочу выбрать случайным образом 3 строки, затем 4 случайных столбца, а затем выбрать те элементы, которые совпадают в этих выбранных строках и столбцах, чтобы у меня было 12 выбранных элементов. Затем я хочу создать диагональную матрицу называется B, в котором будут записи либо 1, либо 0, так что умножение этой матрицы B на измененную матрицу A (20x1) даст мне эти выбранные 12 элементов A.

Как я могу создать эту матрицу B? Вот мой код:

A=1:20;
A=reshape(A,4,5);
Mr=4;
Ma=3;
Na=4;
Nr=5;
M=Ma*Mr;
[S1,S2]=size(A);
N=S1*S2;
y2=zeros(size(A));
k1=randperm(S1);
k1=k1(1:Ma);
k2=randperm(S2);
k2=k2(1:Mr);
y2(k1,k2)=A(k1,k2);

person Nanor    schedule 30.10.2015    source источник
comment
@Adriaan yapp извините, что отредактировал.   -  person Nanor    schedule 30.10.2015
comment
У вас не может быть диагональной матрицы, которая решит эту проблему. Вы можете заполнить определенные значения B, чтобы добиться желаемого с помощью умножения, но оно, конечно, не будет диагональным. Умножение диагональной матрицы на вектор просто вернет масштабированные компоненты этого вектора... если только вы не намерены заменить те значения, которые не выбраны, на 0 в конечном векторе. Пожалуйста, уточните, действительно ли вы имеете в виду диагональную матрицу.   -  person rayryeng    schedule 30.10.2015
comment
@rayryeng Я думаю, он имеет в виду, что диагональная матрица будет иметь 0 для значений, которые она не должна возвращать, и 1 для значений, которые она должна возвращать. Результатом A*B будет вектор из 20 элементов с 12 ненулевыми значениями из-за 1 в B. Извините, что, вероятно, вам не поможет, но диагональная матрица решит проблему, хотя я не знаю, почему B не может быть векторным и поэлементным умножением.   -  person IKavanagh    schedule 30.10.2015
comment
@IKavanagh, это правда, поэтому я в замешательстве ... и поэтому я еще не написал ответ.   -  person rayryeng    schedule 30.10.2015
comment
@rayryeng Я только что написал один. Пытаюсь выучить bsxfun, и мне показалось, что это хорошее место, чтобы его применить!   -  person IKavanagh    schedule 30.10.2015
comment
@rayryeng Я думаю, вы не поняли, что я имею в виду. В моем коде y2 дает выбранные 12 элементов A. Теперь мне нужна диагональная матрица B (которая будет иметь размер 12x20) с элементами 0 и 1, чтобы B * A (: ) даст мне матрицу 12x1, которая является теми же элементами y2, которые не равны нулю.   -  person Nanor    schedule 30.10.2015
comment
Итак, что вы хотите, это B, где y3 = A*B и y3 = y2(y2 ~= 0)? Этот вопрос очень неясен. Почти уверен, что B не может быть диагональным для приведенного вами примера.   -  person Matt    schedule 30.10.2015
comment
@Matt Пожалуйста, запустите код, который я предоставил, и сравните матрицы A и y2! что элементы в y2, которые не равны нулю, — это те элементы, которые я выбрал случайным образом из A (12 элементов). Теперь мне нужна эта диагональная матрица B с элементами 0 или 1, чтобы B * A (:) также дал мне эти 12 элементов   -  person Nanor    schedule 30.10.2015
comment
idx = reshape(y2 ~= 0, numel(y2), []). Затем A(idx) даст вам то, что вы хотите. Диагональ не нужна. Я запустил твой код. Ваше желание B бесполезно. Есть лучшие способы сделать это.   -  person Matt    schedule 30.10.2015
comment
@Matt Мне нужна эта диагональная матрица B, потому что она используется в остальной части моего основного кода. Я должен его сгенерировать!   -  person Nanor    schedule 30.10.2015
comment
Для справки mathworld.wolfram.com/DiagonalMatrix.html то, что вы просите, НЕ является диагональю матрица.   -  person Matt    schedule 30.10.2015


Ответы (2)


Немного сложно понять, чего вы хотите, и ваш код не очень помогает, но я думаю, что у меня есть решение для вас.

Я создаю матрицу (вектор) нулей того же размера, что и A, а затем использую bsxfun чтобы определить индексы в этом векторе (который будет диагональю B), которые должны быть 1.

>> A = reshape(1:20, 4, 5);
>> R = [1 2 3]; % Random rows
>> C = [2 3 4 5]; % Random columns
>> B = zeros(size(A));
>> B(bsxfun(@plus, C, size(A, 1)*(R-1).')) = 1;
>> B = diag(B(:));
>> V = B*A(:);
>> V = V(V ~= 0)
V =
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13

Примечание: нет необходимости в B = diag(B(:));, мы могли бы просто использовать поэлементное умножение в Matlab.

>> V = B(:).*A(:);
>> V = V(V ~= 0)

Примечание. Это может быть слишком сложным или очень плохо составленным, и, вероятно, есть лучший способ сделать это. Это моя первая реальная попытка самостоятельно использовать bsxfun.

person IKavanagh    schedule 30.10.2015
comment
Добро пожаловать в мир bsxfun. Ваши братья ждут вас, и Дивакар станет нашим номером один! - person rayryeng; 30.10.2015
comment
bsxfun это так весело! - person IKavanagh; 30.10.2015
comment
ребята, я не понял, о чем речь, но мне не нужен вывод выбранных 12 элементов. На самом деле мне нужна эта диагональная матрица B. А также здесь я написал образец матрицы A. В действительности моя матрица имеет размер 512x512, поэтому создание этой матрицы B будет невозможно, и я думаю, что мне следует использовать разреженную функцию. Я прав? - person Nanor; 30.10.2015
comment
@Nanor Я действительно сбит с толку. Зачем нужна диагональная матрица? Нельзя ли использовать поэлементное умножение? - person IKavanagh; 30.10.2015
comment
@IKavanagh, потому что эта диагональная матрица B также используется в другой части моего основного кода. Так что она мне нужна. - person Nanor; 30.10.2015

Вот хак, но поскольку вы создаете y2, вы можете просто использовать его вместо создания бесполезной матрицы B. Ответ bsxfun намного лучше.

A=1:20;
A=reshape(A,4,5);
Mr=4;
Ma=3;
Na=4;
Nr=5;
M=Ma*Mr;
[S1,S2]=size(A);
N=S1*S2;
y2=zeros(size(A));
k1=randperm(S1);
k1=k1(1:Ma);
k2=randperm(S2);
k2=k2(1:Mr);
y2(k1,k2)=A(k1,k2);
idx = reshape(y2 ~= 0, numel(y2), []);
B = diag(idx);
% "diagonal" matrix 12x20
B = B(all(B==0,2),:) = [];
output = B * A(:)

выход =

 1
 3
 4
 9
11
12
13
15
16
17
19
20

у2 из примера.

y2 =

 1     0     9    13    17
 0     0     0     0     0
 3     0    11    15    19
 4     0    12    16    20
person Matt    schedule 30.10.2015