2013-07-16 1 views
4

Я пытаюсь найти способ (идиоматическое или иным образом), чтобы преобразовать матрицу, которая выглядит какAPL: Матричный манипуляционный трюк?

0 1 
0 1 
0 1 

в 3 отдельных матриц

0 1 
0 0 
0 0 

0 0 
0 1 
0 0 

0 0 
0 0 
0 1 

так, что когда я или все вместе, Я получаю оригинал. Каждая из этих «подматриц» должна иметь только один ненулевой элемент и должна иметь ту же форму, что и оригинал.

ответ

3

Одно из решений:

Любая булева матрица:

 m←4 3⍴?12⍴2 
     m 
0 0 1 
0 0 0 
1 1 0 
0 1 0 

Примечание его форма:

d←⍴m 
    d 
4 3 

Равель матрица в вектор:

 v←,m 
     v 
0 0 1 0 0 0 1 1 0 0 1 0 

Генерация индексов:

  i ←⍳⍴v 
      i 
    0 1 2 3 4 5 6 7 8 9 10 11 

Построить матрицу для каждого 1 в исходной матрице:

 a←d∘⍴¨↓(v/i)∘.=i 
     a 
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 1 0 0 0 1 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 1 0 

Проверьте результат:

↑∨/a 
0 0 1 
0 0 0 
1 1 0 
0 1 0 

Существует, вероятно, хороший способ сделать это с помощью индексации точки рассеяния, а также , сначала создавая трехмерную матрицу, а затем определяя местоположение 1s.

Да есть, используя V и D, как указано выше:

 n←+/v 
     b←(n,d)⍴0 
     b[↓⍉(⍳n)⍪d⊤v/⍳⍴v]←1 
     b 
0 0 1 
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 1 0 
0 0 0 

0 0 0 
0 0 0 
0 0 0 
0 1 0 
     ∨⌿b 
0 0 1 
0 0 0 
1 1 0 
0 1 0 
3

Учитывая вектор А:

+A←3 4⍴1 0 1 0 1 0 0 0 0 1 0 1 

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

разбить его на составные матрицы следующим образом:

+(⍴A)∘⍴¨⊂[2](,A)\B B⍴1,(B←+/,A)⍴0 

1 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 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 1 0 0 0 0 0 1 

Как это работает

Сначала назначить количество 1s к B:

B←+/,A   ⍝ 5 

Создать единичную матрицу, как описано в этом посте: The most idiomatic way of creating identity matrix in APL:

B B⍴1,(B←+/,A)⍴0 

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

RAVEL исходной матрицы:

,A    ⍝ 1 0 1 0 1 0 0 0 0 1 0 1 

Используйте расколотую матрицу для расширения матрицы идентичности.Это создает матрицу, где каждая строка представляет собой распущенной вид матриц компонентов:

+(,A)\B B⍴1,(B←+/,A)⍴0 

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

Преобразование этой матрицы в вектор строк:

+⊂[2](,A)\B B⍴1,(B←+/,A)⍴0 

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

Используя оригинальную форму (⍴A), создать конечные матрицы:

(⍴A)∘⍴¨⊂[2](,A)\B B⍴1,(B←+/,A)⍴0 

1 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 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 1 0 0 0 0 0 1 
+0

Очень хорошее решение! Мне нравится этот, потому что он просто перестраивает 1 и 0, а кроме числа 1 не требует целых чисел или индексов.Я думал, что должен быть какой-то способ сделать это таким образом и играть с расширением, но генерация матрицы идентичности мне не пришла. Очень приятно! –

+0

@PaulMansour - Спасибо, Пол! Мне тоже понравилось ваше решение, но я немного в тупике от него, потому что я получаю ошибку валентности с '↓ (v/i) ∘. = I'. Не должно быть аргумента слева от этого? –

+0

Монадическая стрелка вниз известна как «раскол» и делает то же самое, что и [2], превращая матрицу в вектор векторов. Может быть недоступен во всех реализациях APL. –

0

с Dyalog APL версией 16,0 теперь вы можете написать это очень сжато с молчаливым фунцем ион ⍸{[email protected](⊂⍺)≠⍨⍵}⍤0 2⊢. Посмотрите внизу этого сообщения, как получить список матриц.

Try it online!

Как это работает?

Это развилка, где так результаты и из являются левые и правые аргументы {[email protected](⊂⍺)≠⍨⍵}⍤0 2.

дает список индексов, где существует 1s в аргументе

только выхода s неизмененного аргумента

{ ... }⍤0 2 применяет следующий DFN с каждым ранг-0 подматрица левого аргумента (т. е. каждый индекс a 1) в качестве левого аргумента и каждый rank-2 подправа правого аргумента (i . .e вся матрица) в качестве аргумент правой

≠⍨⍵неравных селе из правого аргумента; дает матрицу той же формы, но заполняются нулями

[email protected](⊂⍺) это переворачивает (логический не) бит в положение, обозначенное в левый аргумент

Таким образом, для каждого 1, он создает all-zero layer, где бит в его положении перевернут.


Как получить список матриц вместо:

⍸{[email protected](⊂⍺)≠⍨⍵}¨⊂ дает список желаемых матриц. Try it online!

Это работает идентично, но вместо использования оператора ранга для работы со всем массивом мы используем ¨⊂ для объединения каждого индекса 1 со всей матрицей.

 Смежные вопросы

  • Нет связанных вопросов^_^