I'm trying to find a way (idiomatic or otherwise) to transform a matrix that looks like
0 1
0 1
0 1
into 3 individual matrices
0 1
0 0
0 0
0 0
0 1
0 0
0 0
0 0
0 1
so that when I OR all of them together, I get the original. Each of these "sub-matrices" have to have 1 non-zero element only and must have the same shape as the original.
One solution:
Any boolean matrix:
m←4 3⍴?12⍴2
m
0 0 1
0 0 0
1 1 0
0 1 0
Note its shape:
d←⍴m
d
4 3
Ravel the matrix into a vector:
v←,m
v
0 0 1 0 0 0 1 1 0 0 1 0
Generate indices:
i ←⍳⍴v
i
0 1 2 3 4 5 6 7 8 9 10 11
Construct a matrix for each 1 in the original matrix:
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
Verify result:
↑∨/a
0 0 1
0 0 0
1 1 0
0 1 0
There is probably a nice way to do this using scatter point indexing as well, by first generating a 3 dimensional matrix and then specifying the location of the 1s.
Yes there is, using v and d as above:
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
Given a vector A:
+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
Break it down into component matrices as follows:
+(⍴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
How it works
First assign the number of 1s to B:
B←+/,A ⍝ 5
Create an identity matrix as discussed in this post: 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 the original matrix:
,A ⍝ 1 0 1 0 1 0 0 0 0 1 0 1
Use the raveled matrix to expand the identity matrix. That creates a matrix wherein each row is the raveled form of the component matrices:
+(,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
Convert that matrix into a vector of the rows:
+⊂[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
Using the original shape of A (⍴A)
, create the final matrices:
(⍴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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With