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