Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I mask the scan operator in APL?

Tags:

apl

dyalog

Assuming I have an array N ← 0 0 0 1 1 1 0 0 1, how can I apply the scan \ to achieve the array 0 0 0 1 2 3 0 0 1?

+\N gives me 0 0 0 1 2 3 3 3 4 which is not what I want.

+\¨⊆⍨N gives me | 1 2 3 | 1 | which is closer, but then I lose the positions.

Is there a way to carry the original values in the scan and multiply, or perhaps a better way?

like image 628
mazin Avatar asked Dec 31 '22 12:12

mazin


2 Answers

How about m←{s-⌈\(s←+\⍵)×2>/0,⍵}, seems about twice as fast?

      cmpx  'h r' 'm r'
  h r → 1.1E¯5 |   0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
  m r → 4.2E¯6 | -63% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕ 
like image 122
Morten Kromberg Avatar answered Jan 28 '23 16:01

Morten Kromberg


There are a couple of options here. Your original idea can be adapted easily using \.

Alternatively, for a short (but inefficient O(n^2)) solution, ⊥⍨¨,\ works.

For a more efficient but longer solution, I adapted https://aplcart.info/?q=cumulative%20sum#

There's probably something even better but I'm too bad to find it but it's left as an exercise to the reader ;)

      f ← {⍵\∊+\¨⊆⍨⍵}
      g ← ⊥⍨¨,\
      h ← {+\⍵-a\¯2-/0,(a←1,2≠/⍵)/+\¯1↓0,⍵}
      f 0 0 0 1 1 1 0 0 1
0 0 0 1 2 3 0 0 1

      r ← ? 1e3 ⍴ 2        ⍝ random boolean array
      (∧/2≡/f,⍥⊆g,⍥⊆h)r   ⍝ they're all the same
1
      
      ]runtime -c 'f r' 'g r' 'h r'
                                                                
  f r → 3.6E¯5 |    0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕                      
  g r → 7.7E¯5 | +111% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕ 
  h r → 7.3E¯6 |  -80% ⎕⎕⎕⎕                                     
like image 37
rak1507 Avatar answered Jan 28 '23 16:01

rak1507