Логическая индексация с использованием маски работает в NumPy, а не в Matlab - PullRequest
0 голосов
/ 30 сентября 2018

Я пытаюсь воспроизвести следующий код Python в MATLAB, используя разреженную матрицу.

>>> print(M)
[[0 0 0 0 0]
 [0 1 1 1 0]
 [0 1 0 1 0]
 [0 1 1 1 0]
 [0 0 0 0 0]]
>>> im2var = np.arange(5 * 5).reshape((5, 5))
>>> A = np.zeros((25, 25), dtype=int)
>>> A[im2var[M == 1], im2var[M == 1]] = 1
>>> print(A)
[[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]]

Это то, что я написал в MATLAB

M = [
    0 0 0 0 0;
    0 1 1 1 0;
    0 1 0 1 0;
    0 1 1 1 0;
    0 0 0 0 0
];

im2var = reshape(1:25, [5 5]);
A = zeros(25, 25);
A(im2var(M == 1), im2var(M == 1)) = 1;
num2str(A)

Когда яЗапустив скрипт MATLAB, я получаю следующую матрицу, которая явно отличается от вывода Numpy.

ans =

  25x73 char array

    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  1  1  1  0  0  1  0  1  0  0  1  1  1  0  0  0  0  0  0'
    '0  0  0  0  0  0  1  1  1  0  0  1  0  1  0  0  1  1  1  0  0  0  0  0  0'
    '0  0  0  0  0  0  1  1  1  0  0  1  0  1  0  0  1  1  1  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  1  1  1  0  0  1  0  1  0  0  1  1  1  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  1  1  1  0  0  1  0  1  0  0  1  1  1  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  1  1  1  0  0  1  0  1  0  0  1  1  1  0  0  0  0  0  0'
    '0  0  0  0  0  0  1  1  1  0  0  1  0  1  0  0  1  1  1  0  0  0  0  0  0'
    '0  0  0  0  0  0  1  1  1  0  0  1  0  1  0  0  1  1  1  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'

Спасибо за любую помощь!

РЕДАКТИРОВАТЬ: Я также хотел бы выполнить следующееэффект, но текущий ответ, кажется, не работает для двух наборов индексов.

В Python:

>>> Mp = np.roll(M, 1, axis=1)
>>> A[im2var[M==1], im2var[Mp==1]] = -1
>>> print(A[5:15,5:15])
[[ 0  0  0  0  0  0  0  0  0  0]
 [ 0  1 -1  0  0  0  0  0  0  0]
 [ 0  0  1 -1  0  0  0  0  0  0]
 [ 0  0  0  1 -1  0  0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0  0]
 [ 0  0  0  0  0  0  1 -1  0  0]
 [ 0  0  0  0  0  0  0  0  0  0]
 [ 0  0  0  0  0  0  0  0  1 -1]
 [ 0  0  0  0  0  0  0  0  0  0]]

Используя предложение текущего ответа, я написал следующий код.

M = [
    0 0 0 0 0;
    0 1 1 1 0;
    0 1 0 1 0;
    0 1 1 1 0;
    0 0 0 0 0
];

Mp = circshift(M, 1, 2);

ind = find(M);
indp = find(Mp);

A = zeros(25, 25);
A(sub2ind(size(A), ind, ind)) = 1;
A(sub2ind(size(A), ind, indp)) = -1;

num2str(A)

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

ans =

  25x73 char array

    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  1  0  0  0  0 -1  0  0  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  1  0  0  0  0 -1  0  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  1  0  0  0  0 -1  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  1  0  0  0  0 -1  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  1  0  0  0  0 -1  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  1  0  0  0  0 -1  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  1  0  0  0  0 -1  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  1  0  0  0  0 -1  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'

РЕДАКТИРОВАТЬ 2:

Согласно отредактированному ответу,Я попробовал следующий код.

M = [
    0 0 0 0 0;
    0 1 1 1 0;
    0 1 0 1 0;
    0 1 1 1 0;
    0 0 0 0 0
];

Mp = circshift(M, 1, 2);

ind = find(M);
indp = find(Mp.');

A = zeros(25, 25);
A(sub2ind(size(A), ind, ind)) = 1;
A(sub2ind(size(A), ind, indp)) = -1;

num2str(A(5:14, 5:14))

, но он по-прежнему не дает того же результата, что и код Python в EDIT 1.

ans =

  10x28 char array

    '0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0'
    '0  0  1 -1  0  0  0  0  0  0'
    '0  0  0  1 -1  0  0  0  0  0'
    '0  0  0  0  1 -1  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  1 -1  0'
    '0  0  0  0  0  0  0  0  0  0'
    '0  0  0  0  0  0  0  0  0  1'

1 Ответ

0 голосов
/ 30 сентября 2018

В MATLAB вы получаете соответствующие подписки на строки и столбцы A, возвращаемые im2var(M == 1) ваших целевых мест для них.Поочередно это можно сделать с помощью find(M.') без инициализации im2var или просто find(M), поскольку M равно transpose(M) в вашем случае.find(M) возвращает линейные индексы, где M не равен нулю, но линейные индексы M такие же, как индексы строк и столбцов A.Вы не можете напрямую использовать эти индексы строк и столбцов, и вам необходимо преобразовать их в линейные индексы, а затем продолжить, т.е.основной порядок строк.

...