Search code examples
kdb

How do I write more advanced functions/objects in KDB?


I'm trying to write something that'll fit a linear regression on x;y as below.

fit: {
  coef: enlist[y] lsq flip[x];
  intercept: avg y;
  rSquared: sum raze[(intercept + (raze coef mmu flip[x]) - y) xexp 2];
  0"intercept";
  0"coef"; }
fit[x;y]

The issue I'm having is:

  • How can I output intercept, coef and rSquared into some kind of single structured data format that I can use in my predict function (not shown). I tried to do

    `intercept`coef!(intercept coef)

but it wouldn't allow it owing to the resultant dictionary not being square.

What's the right way to handle this in KDB?


Solution

  • Here's a trivial example that may help. Suppose I have function f that calculated three variables:

    f:{[x] n1:x+10; n2:x+20; n3:x+30;}
    

    I can have f output all three of these as a list:

    f:{[x] n1:x+10; n2:x+20; n3:x+30;:(n1;n2;n3);}
    

    If I then had a function g that summed three inputs I could feed the output from f into it like:

    q)g:{[x;y;z] x+y+z};
    q)g . f[10]
    

    The . notation will apply the elements of it's right argument to it's left argument as if they were distinct variables.

    You are, of course, free to leave f[10] as a list. In this case your g would need a new definition:

    q)g:{[l] l[0] + l[1] + l[2]}
    q)g[f[10]]
    

    The same could be accomplished with dictionaries but you would replace your numeric indices with symbolic ones.

    q)f:{[x] n1:x+10; n2:x+20; n3:x+30;:`n1`n2`n3!(n1;n2;n3);}
    q)g:{[d] d[`n1] + d[`n2] + d[`n3]}
    q)g[f[10]]