mmin

I’ve been trying to grok mmin:

q)3 mmin til 6

0 0 0 1 2 3

q)mmin

k){(x-1)&':/y}

q)k)2&':/!6

0 0 0 1 2 3

which i translate to q:

q)2&':/til 6

so it’s &': with initial value 2 over til 6…

but i don’t see how 2 is a window?

what’s the key to understanding this code?

ta, jack

f/[2;x] means repeat f 2 times over x that is calculate min between every pair two times.

WBR, Andrey.

???, 1 ??? 2015 ?., 11:40:52 UTC+3 ??? effbiae ???:

I’ve been trying to grok mmin:

q)3 mmin til 6

0 0 0 1 2 3

q)mmin

k){(x-1)&':/y}

q)k)2&':/!6

0 0 0 1 2 3

which i translate to q:

q)2&':/til 6

so it’s &': with initial value 2 over til 6…

but i don’t see how 2 is a window?

what’s the key to understanding this code?

ta, jack

Hi Jack,

Repeating the mmin function:

q)mmin

k){(x-1)&':/y}

Let’s say we try 3 mmin 1 5 3

If we break the expression down into two parts:

  1. the min operator combined with the each prior adverb

  2. the x f/y expression, meaning iterate y using f, by x times

For (1), we can combine verbs in brackets to make an adverb. In this case, combining min (&) and each priot (':)

q) minprev:(&':)

&‘: is taking each item of the right operand and applying it to its predecessor

Now for part (2), using our adverb minprev as the function, f, in the x f/y expression.

q)2 minprev\ 1 5 3

1 1 1

Iterate the list1 5 3using    minprev 2 times

And if we change Over into Scan (\ into /) to get the intermediate results as well:


q)2 minprev\ 1 5 3

1 5 3

1 1 3

1 1 1

The original list is returned first: 1 5 3

The first iteration of the function returns
(min 0N 1; min 1 5; min 5 3)

113

The second iteration of the function returns
(min 0N 1; min 1 1; min 1 3)
111

For your original example, using 3 mmin til 6, as you say correctly translates to 2&’:/til 6

Or in terms of the minprev I’ve defined:

3 mmin til 6

becomes

q)2 minprev\ 0 1 2 3 4 5

0 1 2 3 4 5

0 0 1 2 3 4/ 1 iteration

0 0 0 1 2 3/ 2 iterations

Looking just at the final result with Over:

q)2 minprev/ 0 1 2 3 4 5

0 0 0 1 2 3

To calculate the 3, we look at the 3 4 5 (window size 3)

To calculate the 2, we look at the 2 3 4 (window size 3)

etc…

The result only requires n-1 iterations for n sized window.

Thanks,
Matthew McAuley

KDB+ Developer, AquaQ Analytics Ltd

This email, its contents and any files attached are a confidential communication and are intended only for the named addressees indicated in the message.


If you are not the named addressee or if you have received this email in error, you may not, without the consent of AquaQ Analytics, copy, use or rely on any information or attachments in any way. Please notify the sender by return email and delete it from your email system.


Unless separately agreed, AquaQ Analytics does not accept any responsibility for the accuracy or completeness of the contents of this email or its attachments. Please note that any views, opinion or advice contained in this communication are those of the sending individual and not those of AquaQ Analytics and AquaQ Analytics shall have no liability whatsoever in relation to this communication (or its content) unless separately agreed

So I thought the example of the k code for mmin/mmax might lead to finding the indexes of the moving maximum by the same pattern.

So I found:

q)immax:{(x-1){(y;z)(<). x@y,z}[y]':/til count y}
q)x:7 2 3 3 7
q)immax[3;x]

0 0 0 3 4

but it’s much slower than mmax:

q)\ts mmax[10;til 10000]

1 524576

q)\ts immax[10;til 10000]

84 750576

I then discovered that tampering with mmax - replacing | with {x|y} - has quite an effect on time:

q)\ts k){(x-1)|':/y}[10;!10000]

1 524816

q)\ts k){(x-1){x|y}':/y}[10;!10000]

29 619456

Can immax be relatively fast using the pattern of mmax?

[then the problem of finding first moving maximum index can be reduced to two reverses and immax]

Thanks,

Jack