Index-of function with structured left-argument
The ISO spec doesn't address what the index-of function should do when the left argument is not a scalar or a one-dimensional array. GNU APL extends this, but I don't really understand in what way. How am I to interpret the output from this? * (2 2 ⍴ 104 105 106 107) ⍳ (3 4 ⍴ 100+⍳100)* ┏→━━┓ ↓┏⊖┓ ┏⊖┓ ┏⊖┓ ┏⊖┓ ┃ ┃┃0┃ ┃0┃ ┃0┃ ┃0┃ ┃ ┃┗━┛ ┗━┛ ┗━┛ ┗━┛ ┃ ┃┏→━━┓ ┏→━━┓ ┏→━━┓ ┏→━━┓┃ ┃┃0 0┃ ┃0 1┃ ┃1 0┃ ┃1 1┃┃ ┃┗━━━┛ ┗━━━┛ ┗━━━┛ ┗━━━┛┃ ┃┏⊖┓ ┏⊖┓ ┏⊖┓ ┏⊖┓ ┃ ┃┃0┃ ┃0┃ ┃0┃ ┃0┃ ┃ ┃┗━┛ ┗━┛ ┗━┛ ┗━┛ ┃ ┗∊━━┛ Regards, Elias
Re: Index-of function with structured left-argument
Just from staring at the result, it looks like the result of ⍺⍳⍵ has the same shape as ⍵, and for each item of ⍵ it tells you either the coordinates where it was found in ⍺, or ⍬ if it was not found. (Dunno what it does if ⍺ is a scalar, where ⍬ would be a valid coordinate.) N.B. in Dyalog APL dyadic iota has been extended to high rank arrays in a completely different way: https://help.dyalog.com/17.1/#Language/Primitive%20Functions/Index%20Of.htm Jay. On Tue, 14 Apr 2020 at 09:15, Elias Mårtenson wrote: > The ISO spec doesn't address what the index-of function should do when the > left argument is not a scalar or a one-dimensional array. > > GNU APL extends this, but I don't really understand in what way. How am I > to interpret the output from this? > > * (2 2 ⍴ 104 105 106 107) ⍳ (3 4 ⍴ 100+⍳100)* > ┏→━━┓ > ↓┏⊖┓ ┏⊖┓ ┏⊖┓ ┏⊖┓ ┃ > ┃┃0┃ ┃0┃ ┃0┃ ┃0┃ ┃ > ┃┗━┛ ┗━┛ ┗━┛ ┗━┛ ┃ > ┃┏→━━┓ ┏→━━┓ ┏→━━┓ ┏→━━┓┃ > ┃┃0 0┃ ┃0 1┃ ┃1 0┃ ┃1 1┃┃ > ┃┗━━━┛ ┗━━━┛ ┗━━━┛ ┗━━━┛┃ > ┃┏⊖┓ ┏⊖┓ ┏⊖┓ ┏⊖┓ ┃ > ┃┃0┃ ┃0┃ ┃0┃ ┃0┃ ┃ > ┃┗━┛ ┗━┛ ┗━┛ ┗━┛ ┃ > ┗∊━━┛ > > Regards, > Elias >
Re: Inner join vs. outer join
Hi Elias, which spec are you referring to? Best Regards, Jürgen On 4/14/20 6:06 AM, Elias Mårtenson wrote: I was reading the spec on outer join to see if I could finally fully understand how it works. For reference, the spec refers to the syntax as follows: X a.b Y The function a is referenced twice in the description for this function, both times in the form a/ (i.e. with the reduce operator applied). I then noted that the J version of this function does not apply the reduce operator. I.e. in J, you have to do: X a/.b Y Now, am I correct in my assumption that with this change, there would be no need for the ∘ (null function)? I.e. if APL behaved like J, would the following achieve an outer join? X ⊣.× Y I'm still not sure I fully understand the join operator to the point where I can answer this question. Regards, Elias
Re: Index-of function with structured left-argument
Hi Elias, my best guess is that this is a missing RANK ERROR somewhere. I will look into it. Best Regards, Jürgen On 4/14/20 10:15 AM, Elias Mårtenson wrote: The ISO spec doesn't address what the index-of function should do when the left argument is not a scalar or a one-dimensional array. GNU APL extends this, but I don't really understand in what way. How am I to interpret the output from this? (2 2 ⍴ 104 105 106 107) ⍳ (3 4 ⍴ 100+⍳100) ┏→━━┓ ↓┏⊖┓ ┏⊖┓ ┏⊖┓ ┏⊖┓ ┃ ┃┃0┃ ┃0┃ ┃0┃ ┃0┃ ┃ ┃┗━┛ ┗━┛ ┗━┛ ┗━┛ ┃ ┃┏→━━┓ ┏→━━┓ ┏→━━┓ ┏→━━┓┃ ┃┃0 0┃ ┃0 1┃ ┃1 0┃ ┃1 1┃┃ ┃┗━━━┛ ┗━━━┛ ┗━━━┛ ┗━━━┛┃ ┃┏⊖┓ ┏⊖┓ ┏⊖┓ ┏⊖┓ ┃ ┃┃0┃ ┃0┃ ┃0┃ ┃0┃ ┃ ┃┗━┛ ┗━┛ ┗━┛ ┗━┛ ┃ ┗∊━━┛ Regards, Elias
Re: Inner join vs. outer join
s/join/product/ ? In APL's inner product (X a.b Y), each item of the result corresponds to a row of X combined in some way with a column of Y. So the shape of the result is (¯1↓⍴X),(1↓⍴Y). In APL's outer product (X ∘.b Y), each item of the result corresponds to an item of X combined in some way with an item of Y. So the shape of the result is (⍴X),(⍴Y). J probably does this in a more generic way, and you can certainly implement inner and outer products and variations thereof by using the Rank operator. For example: X (b⍤99⍤0 99) Y ⍝ implements X ∘.b Y (where 99 is an approximation to infinity) X({+⌿⍺(×⍤¯1)⍵}⍤1 99)Y ⍝ implements X +.× Y Jay. On Tue, 14 Apr 2020 at 05:07, Elias Mårtenson wrote: > I was reading the spec on outer join to see if I could finally fully > understand how it works. > > For reference, the spec refers to the syntax as follows: > > X a.b Y > > The function a is referenced twice in the description for this function, > both times in the form a/ (i.e. with the reduce operator applied). > > I then noted that the J version of this function does not apply the reduce > operator. I.e. in J, you have to do: > > X a/.b Y > > Now, am I correct in my assumption that with this change, there would be > no need for the ∘ (null function)? I.e. if APL behaved like J, would the > following achieve an outer join? > > X ⊣.× Y > > I'm still not sure I fully understand the join operator to the point where > I can answer this question. > > Regards, > Elias >
Re: Inner join vs. outer join
Thank you. That makes sense. Jürgen, I was referring to the ISO spec. I noticed that J has somehow generalised the join operation so that the / has to be explicit. That surely makes it more flexible, but I'm not sure what you can do with it, to I turned to the spec. Regards, Elias On Tue, 14 Apr 2020 at 17:51, Jay Foad wrote: > s/join/product/ ? > > In APL's inner product (X a.b Y), each item of the result corresponds to a > row of X combined in some way with a column of Y. So the shape of the > result is (¯1↓⍴X),(1↓⍴Y). > > In APL's outer product (X ∘.b Y), each item of the result corresponds to > an item of X combined in some way with an item of Y. So the shape of the > result is (⍴X),(⍴Y). > > J probably does this in a more generic way, and you can certainly > implement inner and outer products and variations thereof by using the Rank > operator. For example: > X (b⍤99⍤0 99) Y ⍝ implements X ∘.b Y (where 99 is an approximation to > infinity) > X({+⌿⍺(×⍤¯1)⍵}⍤1 99)Y ⍝ implements X +.× Y > > Jay. > > On Tue, 14 Apr 2020 at 05:07, Elias Mårtenson wrote: > >> I was reading the spec on outer join to see if I could finally fully >> understand how it works. >> >> For reference, the spec refers to the syntax as follows: >> >> X a.b Y >> >> The function a is referenced twice in the description for this function, >> both times in the form a/ (i.e. with the reduce operator applied). >> >> I then noted that the J version of this function does not apply the >> reduce operator. I.e. in J, you have to do: >> >> X a/.b Y >> >> Now, am I correct in my assumption that with this change, there would be >> no need for the ∘ (null function)? I.e. if APL behaved like J, would the >> following achieve an outer join? >> >> X ⊣.× Y >> >> I'm still not sure I fully understand the join operator to the point >> where I can answer this question. >> >> Regards, >> Elias >> >
Re: Index-of function with structured left-argument
Hi again, just saw that this is documented in "info apl" section "3.17.2 Generalized dyadic ⍳". Apparently your ⎕IO is 0 which makes it a bit mysterious. Otherwise: A←2 2 ⍴ 104 105 106 107 B←3 4 ⍴ 100+⍳100 A 104 105 106 107 B 101 102 103 104 105 106 107 108 109 110 111 112 4 ⎕CR A⍳B ┏→━━┓ ↓┏⊖┓ ┏⊖┓ ┏⊖┓ ┏→━━┓┃ ┃┃0┃ ┃0┃ ┃0┃ ┃1 1┃┃ ┃┗━┛ ┗━┛ ┗━┛ ┗━━━┛┃ ┃┏→━━┓ ┏→━━┓ ┏→━━┓ ┏⊖┓ ┃ ┃┃1 2┃ ┃2 1┃ ┃2 2┃ ┃0┃ ┃ ┃┗━━━┛ ┗━━━┛ ┗━━━┛ ┗━┛ ┃ ┃┏⊖┓ ┏⊖┓ ┏⊖┓ ┏⊖┓ ┃ ┃┃0┃ ┃0┃ ┃0┃ ┃0┃ ┃ ┃┗━┛ ┗━┛ ┗━┛ ┗━┛ ┃ ┗∊━━┛ Then: - the result has the same shape as A since every element of A is being searched in (the ravel of) B. - The first three and the last five result elements are ⍬ because the A items 101 102 103 (first three) and 108 109 110 111 112 (the last five) were not found in B. Items not found get an index of ⍬ while found ones get the index of B where they (first) occurred in B. Just like in the vector case. The only difference is ⍬ instead of ⎕IO+⍴B for elements not in B. I simply considewred that to be more consistent (and far easier to check) then other alternatives like ⎕IO+⍴B or ⎕IO+⍴,B or ⎕IO+↑⍴B). Best Regards, Jürgen On 4/14/20 11:39 AM, Dr. Jürgen Sauermann wrote: Hi Elias, my best guess is that this is a missing RANK ERROR somewhere. I will look into it. Best Regards, Jürgen On 4/14/20 10:15 AM, Elias Mårtenson wrote: The ISO spec doesn't address what the index-of function should do when the left argument is not a scalar or a one-dimensional array. GNU APL extends this, but I don't really understand in what way. How am I to interpret the output from this? (2 2 ⍴ 104 105 106 107) ⍳ (3 4 ⍴ 100+⍳100) ┏→━━┓ ↓┏⊖┓ ┏⊖┓ ┏⊖┓ ┏⊖┓ ┃ ┃┃0┃ ┃0┃ ┃0┃ ┃0┃ ┃ ┃┗━┛ ┗━┛ ┗━┛ ┗━┛ ┃ ┃┏→━━┓ ┏→━━┓ ┏→━━┓ ┏→━━┓┃ ┃┃0 0┃ ┃0 1┃ ┃1 0┃ ┃1 1┃┃ ┃┗━━━┛ ┗━━━┛ ┗━━━┛ ┗━━━┛┃ ┃┏⊖┓ ┏⊖┓ ┏⊖┓ ┏⊖┓ ┃ ┃┃0┃ ┃0┃ ┃0┃ ┃0┃ ┃ ┃┗━┛ ┗━┛ ┗━┛ ┗━┛ ┃ ┗∊━━┛ Regards, Elias
exercise 2019/02
Hi APLers, let's start with the second challenge: 2 making the grade (https://www.dyalog.com/uploads/files/student_competition/2019_problems_phase1.pdf) "Write a function that, given an array of integer testscores in the inclusive range 0–100, returns anidentically-shaped array of the corresponding lettergrades according to the table to the left.Hint: You may want to investigate the intervalindex function ⍸."(from the exercise) ┌┐ │ 0 64 F│ │65 69 D│ │70 79 C│ │80 89 B│ │90 100 A│ └┘ ⍝ so - ⍸ is not applicable as Dyalog-only, let's try without it. ⍝ create the score card: table ← 1 3 ⍴ 0 64 'F' table ← table ⍪ 65 69 'D' table ← table ⍪ 70 79 'C' table ← table ⍪ 80 89 'B' table ← table ⍪ 90 100 'A' ∇z←getGrade iscore z←({(iscore≥⍺)∧(iscore≤⍵)}/table[;1 2])/table[;3] ∇ ∇grades←findGrade scores grades ← getGrade ¨ scores ⍝ apply getGrade to EACH score ∇ findGrade 2 2 ⍴ 50 72 91 88 F C A B for sure, it would be better, to live without the *external* getGrade function. But trying to incorporate the getGrade as a lambda, I couldn't solve the nested "⍵"s and nested lambdas. Any hint? br & many thanks - Otto -- Dipl. Ing. (FH) Otto Diesenbacher-Reinmüller diesenbacher.net Salzburg, Österreich
Re: exercise 2019/02
On Tue, Apr 14, 2020 at 05:40:26PM +0200, Otto Diesenbacher-Reinmüller wrote: 2 making the grade (...) Any hint? I think all those ranges are mostly a distraction, because it's nowhere said you need to handle out-of-range arguments in any graceful way. I would start with ⍵>table[;2] which is a binary vector for scalar ⍵, and then go from that. My solution would be {table[⎕IO++/⍵∘.>table[;2];3]}. Few years ago I would try to use ¨ too (I'm still relatively new to APL myself), but it kinda feels like writing C in APL and outer product is really more natural here when you think about it. Alternatively you could use dyadic ⍳ to find the first 0 in said vector, which then leads to something like {table[(⍵∘.>table[;2])⍳⍤1⊢0;3]}. -k