Search code examples
j

How do I negate a selector in J lang?


I am playing with selection. Let's look at the initial example:

rarg=. 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
   _1 (<(<0 1),(<0 1)) } ( 4 4 $ rarg)
_1 _1  2  3
_1 _1  6  7
 8  9 10 11
12 13 14 15

Here I want to overwrite block {rows=0,1; columns=0,1}. I can use instead of -1 the block :

   (2 2 $ _1 _2 _3 _4) (<(<0 1),(<0 1)) } ( 4 4 $ rarg)
_1 _2  2  3
_3 _4  6  7
 8  9 10 11
12 13 14 15

If I negate rows and columns choice in selector I end-up with the expected:

   _1 (<(<<0 1),(<<0 1)) } ( 4 4 $ rarg)
 0  1  2  3
 4  5  6  7
 8  9 _1 _1
12 13 _1 _1

So far so good. But let's assume I want to "negate" the selector (<(<0 1),(<0 1)) and have something like this:

   _1 NEGATED_SEL } ( 4 4 $ rarg)
0   1  _1  _1
4   5  _1  _1
_1 _1  _1  _1
_1 _1  _1  _1
  1. Is there a way to achieve that using the above selector?
  2. If yes, what if I would like to specify not -1 but arbitrary values? Thanks a lot in advance!

Solution

  • The "correct" way would be using exclude (<):

    (<< 0 1) { i. 4 4
    0 1 2 3
    4 5 6 7
    (<<< 0 1) { i. 4 4
     8  9 10 11
    12 13 14 15
    

    But, as @Dan_Bron mentioned, this is not permitted by } as the selection would not be rectangular.

    You can still use exclude if you first unravel and then re-ravel your input.

    sel =: <(<<0 1),(<<0 1)
    r =: i. 4 4
    
    sel { r
     10 11
     14 15
    
    _1 sel } r
      0  1  2  3
      4  5  6  7
      8  9 _1 _1
     12 13 _1 _1
    
    new =: -i. 12
    
    ($r) $ new (<<<,sel { r) } ,r
       0  _1 _2 _3
      _4  _5 _6 _7
      _8  _9 10 11
     _10 _11 14 15
    

    For a general input m, you could convert the selection to indices by sel { i. $m:

    ($m) $ new (<<<,sel { i.$m) } , m