« first day (1196 days earlier)      last day (1755 days later) » 

01:00
@RGS I shouldn't have stayed up so late, but here it is:
JustifyAB←{
     _←⍤¯1
     spaces←' '=⍵
     keep←~⌽∧\⌽spaces
     trail←(⊃⌽⍴⍵)-+/keep
     inner←+/keep∧spaces
     mod←inner|trail
     enum←+\spaces
     ext←enum≤_ mod
     div←⌊trail÷inner
     repl←,keep×1+spaces×ext+_ div
     (⍴⍵)⍴repl/,⍵
 }
Maybe good content for the Cultivation?
 
2 hours later…
03:29
@Adám Nah, I just like solving puzzles. (I have a full-time job btw.)
@Adám One question about the Dyalog competition: For how long will it be accepting submissions?
 
2 hours later…
RGS
RGS
05:50
@Adám sometimes I also make poor life choices :p
@Adám definitely
06:50
@Bubbler This year's round closes on Friday 31 July, 2020 at 23:00 UTC.
RGS
RGS
07:11
@Adám that's so further down the road :( thinking in terms of internship & competition
@RGS Sorry, I didn't realis you were unaware of the time scales involved. That's why I warned you about the clash.
07:36
@Adám Cool, that's almost three months
RGS
RGS
@Adám don't worry, I was just expressing my sorrow but that is nothing I can't live with
 
3 hours later…
10:53
@Adám in the proposed array notation, what's the expected behavior of (1 2⋄⋄3 4)/[1 2⋄⋄3 4]? (and [a⋄b] is exactly ↑(a⋄b), right?)
@dzaima Empty statements are ignored. Yes, [a⋄b] is exactly ↑(a⋄b)
cool, so that far i've implemented [1 2⋄3 4]. Now on to the big issue with what to do with (1 2 \n )..
oh, rewatching the video remembered about [1⋄2]. still don't like how special-casey it is
@dzaima It is to avoid having to write [(1⋄)⋄2] or [(1⋄)⋄(2⋄)] for 2 1⍴1 2
@Adám i understand why, but that doesn't change the fact that it's special-casey. (imo ⍪1 2 3//⍪(1⋄2⋄3) isn't much worse either)
True, but we wanted a notation that allows you to write common arrays neatly.
So [⋄] in terms of (⋄) is ↑1/¨(⋄)
11:10
@Adám that doesn't apply to me either funnily enough
@dzaima How does one ravel-if-scalar in dzaima/APL?
@Adám by doing the proper thing to do in that case - some sort of conditional
12:10
Can I pick columns using squad? Say mat[;1 2]?
@xpqz (⊂1 2)⌷[2]mat
@xpqz (⊂1 2)⌷⍤1⊢mat
@xpqz If it is the first 2 columns, then I recommend 2↑⍤1⊢mat
Hmm, yes the squad for that feels a bit cumbersome. Is 2↑⍤1⊢mat an idiom?
@xpqz No, but from 18.0 it will be as fast as brackets.
Wow, huge differences between 17.1:
      mat←?100 100⍴100
      ]runtime -c "mat[;1 2]" "2↑⍤1⊢mat" "(⊂1 2)⌷⍤1⊢mat" "(⊂1 2)⌷[2]mat"

  mat[;1 2]     → 9.0E¯7 |     0% ⎕⎕
  2↑⍤1⊢mat      → 9.5E¯7 |    +6% ⎕⎕
  (⊂1 2)⌷⍤1⊢mat → 1.9E¯5 | +1977% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
  (⊂1 2)⌷[2]mat → 1.2E¯6 |   +29% ⎕⎕
And 18.0:
      mat←?100 100⍴100
     ]runtime -c "mat[;1 2]" "2↑⍤1⊢mat" "(⊂1 2)⌷⍤1⊢mat" "(⊂1 2)⌷[2]mat"

  mat[;1 2]     → 9.7E¯7 |   0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
  2↑⍤1⊢mat      → 9.5E¯7 |  -3% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
  (⊂1 2)⌷⍤1⊢mat → 1.2E¯6 | +25% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
  (⊂1 2)⌷[2]mat → 1.2E¯6 | +20% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
12:28
The +1977% thing stands out; what makes it sub-optimal?
@xpqz If the combo hasn't been special-cased, it ends up splitting, doing an ¨ and mixing:
      ]runtime -c "(⊂1 2)⌷⍤1⊢mat" "↑(⊂⊂1 2)⌷¨↓mat"

  (⊂1 2)⌷⍤1⊢mat  → 1.8E¯5 |  0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
  ↑(⊂⊂1 2)⌷¨↓mat → 1.8E¯5 |  0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
 
1 hour later…
13:52
@Adám dyalog.com/student-competition.htm indicates this year's compeition is live at dyalogaplcompetition.com but the latter is still hosting last year's.
@VladimirSotirov Yeah, I'm sorry about that. It was supposed to go live an hour ago, but we had a power cut, so our IT department is busy getting various systems up again. We are planning to launch tomorrow instead.
thank you for the prompt response!
RGS
RGS
@Adám woops, sorry to hear that :/
14:11
Was doing maintenance on this computer, and working for real as well... I didn't miss this week's Cultivation, did I?
RGS
RGS
@JeffZeitlin nope
@JeffZeitlin No, you've got another 18 mins or so.
How can I tell objects and arrays apart in what is produced by ⎕JSON? Say I have
j←⎕JSON '[{"a":{"b":[1,2,3]},"c":1}]'
and I want to work out if anything has the value 1 (ie the key "c" in the first element of the json list)
@xpqz An object is an array ;-)
14:19
Really?
Isn't it a namespace?
A namespace is a rank-0 array.
RGS
RGS
"Everything is an array"
Doesn't APL live by that motto?
@xpqz 1∊¨j.(⍎¨⎕NL¯2) should do it.
@xpqz Wait, only in the first element? That'd be 1∊(⊃j).(⍎¨⎕NL¯2)
1∊(⊃j).(⍎¨⎕NL¯2)
What is ⎕NL¯2 here?
⎕NL is NameList, and 2 is variables/fields. Negating it gives you a vector of text vectors instead of a matrix.
Welcome to APL Cultivation.
First thing first: Today's subject.
We've had a suggestion for looking closer at what you can do with (Domino: matrix division/inversion).
I also put together a text-justifying function last night that might be interesting to look at.
@all any opinions?
14:32
Happy to do this
RGS
RGS
I guess looking at ⌹ looks like a more standard APL Cultivation; looking at the text-justifying function would be a more exotic lesson... I'm happy with any/both!
@JamesHeslip Define "this".
id be interested in domino but either is fine.
Ah, I meant domino. Does the text-justification use domino?
No, sorry. Let's do domino then.
The name is of course due to its symbol () which isn't really a domino (🁫) but rather a division sign in a quad, the latter representing division/inversion (÷).
You're of course familiar with the ÷ primitive.
Know that matrix multiplication is +.× but we don't have a corresponding operator for matrix division.
You can actually use +.×⍣¯1 for matrix division, but since wasn't always around (and certainly not ⍣¯1) and for notational ease, provides this functionality too.
Matrix inversion, what is that? Anyone volunteer a defintion?
RGS
RGS
14:40
@Adám say A is a matrix. Its inverse inv(A) is a matrix such that A×inv(A) = inv(A)×A = Id
M×inv(M)=I
Yup.
RGS
RGS
(assuming A is square)
So, for now, let's keep to easy-to-remember matrices at hand:
      ⎕←E←2 2⍴2 7 1 8
2 7
1 8
      ⎕←P←2 2⍴3 1 4 1
3 1
4 1
Now if we invert P we get:
      ⌹P
¯1  1
 4 ¯3
And indeed:
      P+.×⌹P
1 0
0 1
Matrix division as a notation isn't usually used by TMNists (can I say that?), instead opting for multiplication by an inverse.
14:44
TMNists?
Traditional Mathematical Notationists
Ah, right.
The analogy with × and ÷ is pretty obvious, so APL defines A⌹B as (⌹B)+.×A just like a÷b is (÷b)×a
(Remember that matrix multiplication isn't commutative!)
      E⌹P
¯1 1
 5 4
      (⌹P)+.×E
¯1 1
 5 4
So far, there's nothing much controversial here.
However, isn't just for matrices. You can use it on vectors too, or even on a matrix and a vector.
     2 7⌹3 1
1.3
@all What does this ↑ mean?
RGS
RGS
(⌹3 1)+.×2 7
but why ⌹3 1 gives 0.3 0.1 is completely unknown to me...
Good. Let's explore that.
     3 1+.×⌹3 1
1
Makes sense?
RGS
RGS
14:52
⌹v is the vector divided by the square of its norm!
See? I knew it'd be good to have a mathmagician here with us today.
We can even use on scalars, where it behaves just as ÷ except it errors on 0÷0 (where ÷ doesn't error). This is convenient if you want to make sure to catch division-by-zero errors.
For a vector v, does ((⌹v)+.×v)=(v+.×⌹v)?
ooh, so 2 7⌹3 1 is the "length" of the component of 2 7 in the 3 1-direction?
@JeffZeitlin Not just for vectors, even for square matrices. (Also, you mean not =)
@VladimirSotirov Yes. Well spotted. And this kind of leads us towards some of the tricks can do.
A common usage for is to solve equation systems. Consider (in TMN):
2x + 7y = 12
 x + 8y = 15
We can represent this as a matrix (our E) on the left of the equal signs and as a vector (12 15) on the right.
      12 15⌹E
¯1 2
This says x←¯1 and y←2. Let's check the result:
      2 7+.ׯ1 2
12
      1 8+.ׯ1 2
15
Yup.
I'm not sure I follow exactly what was meant by @VladimirSotirov comment 'the "length" of the component of 2 7 in the 3 1-direction'
RGS
RGS
15:04
@JamesHeslip are you familiar with the dot product?
And if I do the "check" with the matrix, I get exactly the same results:
@JamesHeslip Think of 2 7 as a vector in the mathematical sense (not just APL list): it goes N-NE
(2 2 ⍴ 2 7 1 8) +.× ¯1 2
12 15
@RGS In terms of +.×?
@JeffZeitlin Yup, of course. All good, isn't it? :-)
15:05
@Adám I drew a picture in paint of exactly that, but the "3 1-direction"?
@JamesHeslip - Think of graph paper.
A projection
You have a vector that goes from the origin, to 2,7
Did Dyalog make that?
15:07
No, although it should be fairly easy to.
(Oops, I even had a typo in it — fixed now.)
I think I'm missing the point. How does that yield 1.3?
(Sorry, it feels like a rookie question)
@JamesHeslip What is the length of (2,7)?
@JamesHeslip draw the perpendicular segment from the point 2 7 to the line through 0 0 and 3 1. The intersection point has coordinates (2 7⌹3 1)×⌹3 1: ⌹3 1 is the unit vector in the same direction as 3 1; the distance from 0 0 to the point is |2 7⌹3 1.
I would go with ((2*2)+(7*2))*0.5
7.280109889280518
@JamesHeslip Right.
@VladimirSotirov Hold on, are you sure that's right? What notation are you using?
RGS
RGS
15:18
@VladimirSotirov ⌹v is not a unit vector (in general)
The unit vector in the direction of 3 1 is 3 1÷(+/3 1*2)*0.5
wait, so (⌹v)≡ v÷+.×⍨v for vectors?
RGS
RGS
@VladimirSotirov looks like so
ok, cool, thanks! so then the coordinates of the intersection point are (2 7⌹3 1)×3 1, so the "length" in the 3 1-direction is what scalar multiple of 3 1 gives those coordinates?
RGS
RGS
@VladimirSotirov (+1)
15:28
@JamesHeslip Sorry for the delay. Here ↑ is (2 7⌹3 1)×3 1 which gives 3.9 1.3 with the original vectors.
So you can see that (0 0) (3.9 1.3) (2.7) forms a right angle.
RGS
RGS
so to understand v⌹w we need to think of the vector u, which is the shadow that v casts over w. The shadow is (v⌹w) times longer than w :)
in the image, the shadow cast is the (3.9, 1.3)
In other words, if we project 2 7 perpendicularly to the extension of 3 1 we hit a point on 3 1's extension which is 1.3×3 1 from 0 0.
I just poked my terp with what I thought should be a related concept, and got results that I don't understand...
Why don't I get 3.9j1.3 if I divide 2j7 by 3j1?
Another way to look at it is that 2 7⌹3 1 is the factor you need to multiply 3 1 with to get closest to 2 7.
@Adám Ahh, that makes so much sense. Thank you.
RGS
RGS
15:34
@Adám (+1)
@JeffZeitlin complex number division is properly defined and doesn't really match what we are doing with 2-element vectors if I understand correctly
(For the uninitiated, regarding Jeff's question: AjB means A+B×i)
RGS
RGS
just think about the fact that multiplying two complex numbers has little to do with the "corresponding" 2D vectors in terms of vector operations we are used to
(if I'm not missing anything; pls correct me)
OK, I'll accept that; I thought there would be a relationship because basic instruction (elementary school level) always seems to discuss complex numbers as though they were vectors on the complex plane...
@JeffZeitlin if you identify complex numbers with vectors, 2j7÷3j1 is the complex number which when scaled up by the norm of3j1 and rotated by the angle 3j1 makes with the x-axis lands you on 2j7
@JeffZeitlin whereas multilpying real numbers together (or real number by vector) corresponds to sclaing, multiplying complex numbers together in general corresponds to scaling by the magnitude and rotating by the angle from the x-axis
RGS
RGS
@JeffZeitlin we do discuss complex numbers like that, but if you read Vladimir's remark, describing these ^ operations in terms of dot products isn't straightforward
15:39
Got it. So when we're playing with two-component vectors here, we're NOT rotating through an angle.
RGS
RGS
and would probably need some extra trig :)
Phew. Skilled crowd today.
OK, let's see if we can get through some more stuff
So this was actually interesting: in a sense finds the "closest" value.
In fact, when we used it to solve the equation system, it also found the "closest values", which happened to be spot on.
RGS
RGS
@Adám does it perform least squares then? when the system can't be solved exactly
It does. That was my next example.
RGS
RGS
sorry :'(
But please show it
15:44
OK, remember how we found x y≡¯1 2 with 12 15⌹E ?
So clearly, if we add x and y we should get 1:
      12 15 1⌹E⍪1 1
¯1 2
Yes, it still holds, as this means:
2x 7y=12
 x 8y=15
 x  y= 1
But what if we tell APL that the last sum doesn't equal 1?
RGS
RGS
(then you are a bad person!)
      12 15 1.1⌹E⍪1 1
¯0.94129 1.98903
:-D What non-sense is this? It doesn't even fulfil any of the equations:
      2 7+.×x y
12.0406
      1 8+.×x y
14.971
      1 1+.×x y
1.04774
But as you can see, it is pretty close.
This is an over-determined system, so APL found the solution that fits best.
It defines "best" by a very common method called the least squares fit, which can also be used to make other kinds of fits.
What it means is that it tries to minimise the squares of the "errors". In a sense, it smoothes the errors out, which means we can use it for smooth curve-fitting too.
Unfortunately, we won't have enough time to go through many possibilities today, but you can see a few uses if you search APLcart for ⌹ fit. Let's just take the very first one from there: ⊢⌹1,∘⍪⊣
Let's say e.g.
x←0 1 3 4 5
y←0 2 4 7 7
(Yes, this was drawn by APL)
      x(⊢⌹1,∘⍪⊣)y
0.22093 1.45349
This means the best linear fit is y(x)=0.22093x+1.45349
@all I guess we have to stop here. Any questions?
16:01
so 12 15 1.1⌹E⍪1 1 gives x y such that (E⍪1 1)+.× x y is closest to 12 15 1.1?
Yes, that's correct.
cool; thank you! this was very illuminating.
I'm happy you enjoyed it. I'm sorry my linear algebra-fu wasn't as quick at hand as I could have wished for.
Thank you all for participating so engaged!
2 questions: is +.×⍣¯1 an idiom for ⌹?
@VladimirSotirov I'm not sure I understand that question.
16:07
is (v⌹w)≡v+.×⍣¯1⊢w
@VladimirSotirov No, (v⌹w)≡v+.×⍣¯1⍨w
ok. so second/last question: if I want to use an inner product weighted by a list of weights W, as in I think +.×∘(W∘×), would +.×∘(W∘×)⍣¯1⍨ give me weighted matrix divide (for vectors at least)?
RGS
RGS
(@Adám, sorry if I interfeered too much with the APLC lesson; I got a bit carried away)
@RGS Oh no, not at all. I really appreciate it. Maybe you can even help me answer (or at least understand) Vladimir's question?
RGS
RGS
@Adám well, I'm not so sure I understand what we mean by weighted matrix divide... @VladimirSotirov do you want to divide the vector by the square of its norm, as induced by the weights W?
16:29
what I have in mind is this: if do a coordinate transformation where you scale each axis by L, then you have a weighted dot product {⍺+.×L×L×⍵}. I am curious to what extend ⍣¯1 of that will end up behaving like ⌹ in terms of giving closest points relative to this new dot product
it might be possible to justy jot the weights to ⌹ directly rather than going through ⍣¯1 on the modified inner product; that's just a matter of me working out the linear algebra though.
anyway, thank you all for the discussion!
@VladimirSotirov I suggest you try it out. ⍣¯1 is pretty clever.
RGS
RGS
17:17
@Adám like Bubbler said, it can't be done with 6 Q+N and it can be done with 4
I'm trying to come up with an arrangement for 5 OR show it doesn't work
RGS
RGS
17:38
(looks like it doesn't work)
RGS
RGS
18:03
I'm not so sure anymore, got 5Q + 4N on the board
@RGS - If I recall the problem statement, though, there's a mandate for Q=N.
RGS
RGS
What I mean is I'm so close
to getting 5Q+5N
otherwise the problem would've been solved, because I know 6Q+6N is impossible
 
1 hour later…
ngn
ngn
19:16
@Adám @Jarmex -4 bytes: {×1|w←⍵∨(⌈+.5*⍨×⍨-⍨⌈×⌈).5*⍨⍵×⍺:⍺∇1+⍵⋄w,⍵÷w}∘1
19:44
@ngn nice!
 
1 hour later…
20:48
@ngn actually i don't think it quite works - checking for gcd(k,x+y) being an integer rather than y is clever, but i think there might be a miscalculation in your calculation for y as it gives an incorrect answer for f 11755703 - my brain's taking some time processing that calculation for y at the moment to spot the error!
ngn
ngn
@Jarmex strange, on my laptop (dyalog v17.1) it returns the correct result (40 2), but not on tio
@Jarmex but all tests work fine with ⎕fr←1287
without ⎕fr←1287 adam's solution fails for the last test on my laptop, but works fine on tio
@ngn strange, i see the same test failing on dyalog v17.1.36845
      f←{×1|w←⍵∨(⌈+.5*⍨×⍨-⍨⌈×⌈).5*⍨⍵×⍺:⍺∇1+⍵⋄w,⍵÷w}∘1
      f 11755703
3 59
ngn
ngn
@Jarmex i have the exact same version. are you using linux?
yep
ngn
ngn
@Jarmex oh.. my bad. i had set ⎕ct to a different value from the default
21:02
seems to fail when ⎕fr←645, passes when ⎕fr←1287
      ⎕fr←1287
      f←{×1|w←⍵∨(⌈+.5*⍨×⍨-⍨⌈×⌈).5*⍨⍵×⍺:⍺∇1+⍵⋄w,⍵÷w}∘1
      f 11755703
40 2
      ⎕fr←645
      f←{×1|w←⍵∨(⌈+.5*⍨×⍨-⍨⌈×⌈).5*⍨⍵×⍺:⍺∇1+⍵⋄w,⍵÷w}∘1
      f 11755703
3 59
ngn
ngn
@Jarmex great. ⎕fr is considered a "setting", so it doesn't affect your golfing byte count :)
you can put it in the "header" section on tio, or in "input" if you prefer
@ngn excellent! thanks for the additional golfing, someone else golfing code you wrote is quite a good way to learn the tricks!
ngn
ngn
@Jarmex there's also a tips page where you can find more
21:18
@ngn yeah i've been trying to use it where i can, at the moment i'm giving myself a migraine trying to parse things like (⌈+.5*⍨×⍨-⍨⌈×⌈) !
ngn
ngn
@Jarmex yes, apl trains are hard to read (but maybe easier to write) because you have to be constantly aware which functions are at odd/even positions
this one is equivalent to {(⌈⍵)+.5*⍨(×⍨⍵)-⍨(⌈⍵)×⌈⍵}
@ngn that helps, thanks
 
2 hours later…
23:43
@Jarmex I didn't really wrap my head aroung trains until I watched Tacit Techniques with Dyalog version 18.0 Operators available at dyalog.tv/Dyalog19/?v=czWC4tjwzOQ ; it might be helpful if you haven't seen this talk
@VladimirSotirov cheers, i'll give it a watch

« first day (1196 days earlier)      last day (1755 days later) »