How do I convert a list into a matrix in KDB? - kdb

I have a list of the form:
1 2 3 4
I'd like to convert it into a square matrix:
1 2
3 4
Which I think would be:
(1 2;3 4)
What's the canonical way to do this for, for n sized matrices in KDB?

You can use take
q)n: 2
q)(n; n) # 1 2 3 4
1 2
3 4
or for an m x n matrix:
q)m: 2
q)n: 3
q)(m; n) # 1 2 3 4 5 6
1 2 3
4 5 6

You can do:
n cut list
e.g.
q)3 cut til prd 3 3
0 1 2
3 4 5
6 7 8
Edit:
To insert any list into the closest n*n matrix and fill proceeding positions with NA's you can do:
q)f:{a:(ceiling sqrt b:count x); a cut x,((a*a) - b)#0N}
q)/e.g.
q)f til 10
0 1 2 3
4 5 6 7
8 9
q)

Related

(KDB+/q) Get diagonal elements of a matrix

I want to get all the diagonal elements of a matrix in kdb+/q.
E.g.
q)A:(1 2 3; 4 5 6; 7 8 9)
q)A
1 2 3
4 5 6
7 8 9
would return 1 5 9
My idea is to use "." to get the elements.
q) A . 1 1 / one of the diagonal elements
5
q) 2 #' til 3 / indices
0 0
1 1
2 2
But I tried many ways and can't get it working.
Following code returns diagonal elements of matrix
(1 2 3; 4 5 6; 7 8 9) #' til 3
The code
generates continuous list 0, 1, 2 on the right
Gets an element from every list on the left by applying corresponding index on the right (#' adverb)
Generic form looks like:
getDiagonal: {x#'til count x};
getDiagonal (1 2 3; 4 5 6; 7 8 9)

Understanding moving window calcs in kdb

I'm struggling to understand this q code programming idiom from the kx cookbook:
q)swin:{[f;w;s] f each { 1_x,y }\[w#0;s]}
q)swin[avg; 3; til 10]
0 0.33333333 1 2 3 4 5 6 7 8
The notation is confusing. Is there an easy way to break it down as a beginner?
I get that the compact notation for the function is probably equivalent to this
swin:{[f;w;s] f each {[x; y] 1_x, y }\[w#0;s]}
w#0 means repeat 0 w times (w is some filler for the first couple of observations?), and 1_x, y means join x, after dropping the first observation, to y. But I don't understand how this then plays out with f = avg applied with each. Is there a way to understand this easily?
http://code.kx.com/q/ref/adverbs/#converge-iterate
Scan (\) on a binary (two-param) function takes the first argument as the seed value - in this case 3#0 - and iterates through each of the items in the second list - in this case til 10 - applying the function (append new value, drop first).
q){1_x,y}\[3#0;til 10]
0 0 0
0 0 1
0 1 2
1 2 3
2 3 4
3 4 5
4 5 6
5 6 7
6 7 8
7 8 9
So now you have ten lists and you can apply a function to each list - in this case avg but it could be any other function that applies to a list
q)med each {1_x,y}\[3#0;til 10]
0 0 1 2 3 4 5 6 7 8f
q)
q)first each {1_x,y}\[3#0;til 10]
0 0 0 1 2 3 4 5 6 7
q)
q)last each {1_x,y}\[3#0;til 10]
0 1 2 3 4 5 6 7 8 9

How to sum consecutive identical numbers in a list in kdb?

I have a list like this:
a:1 1 1 1 2 3 1 1 4 4 4 5 6 4
How can I sum all of the consecutive identical numbers in a, so that it will become:
a:4 2 3 2 12 5 6 4
There are many ways - one method:
q) a:1 1 1 1 2 3 1 1 4 4 4 5 6 4
q) sum each where[differ a] _ a
4 2 3 2 12 5 6 4
Another method to achieve this using prev & <>:
sum each cut[where a<>prev[a]; a]
4 2 3 2 12 5 6 4

How to duplicate elements of a matrix without using the repmat function

Given the matrix I = [1,2;3,4], I would like to duplicate the elements to create a matrix I2 such that:
I2 = [1 1 1 2 2 2
1 1 1 2 2 2
1 1 1 2 2 2
3 3 3 4 4 4
3 3 3 4 4 4
3 3 3 4 4 4]
Other than using repmat, what other methods or functions are available?
Use kron:
>> N = 3 %// Number of times to replicate a number in each dimension
>> I = [1,2;3,4];
>> kron(I, ones(N))
ans =
1 1 1 2 2 2
1 1 1 2 2 2
1 1 1 2 2 2
3 3 3 4 4 4
3 3 3 4 4 4
3 3 3 4 4 4
This probably deserves some explanation in case you're not aware of what kron does. kron stands for the Kronecker Tensor Product. kron between two matrices A of size m x n and B of size p x q creates an output matrix of size mp x nq such that:
Therefore, for each coefficient in A, we take this value, multiply it with every value in the matrix B and we position these matrices in the same order as we see in A. As such, if we let A = I, and B be the 3 x 3 matrix full of ones, you thus get the above result.
Using indexing:
I = [1, 2; 3, 4]; %// original matrix
n = 3; %// repetition factor
I2 = I(ceil(1/n:1/n:size(I,1)), ceil(1/n:1/n:size(I,2))); %// result
One-liner with bsxfun -
R = 3; %// Number of replications
I2 = reshape(bsxfun(#plus,permute(I,[3 1 4 2]),zeros(R,1,R)),R*size(I,1),[])
Sample run -
I =
3 2 5
9 8 9
I2 =
3 3 3 2 2 2 5 5 5
3 3 3 2 2 2 5 5 5
3 3 3 2 2 2 5 5 5
9 9 9 8 8 8 9 9 9
9 9 9 8 8 8 9 9 9
9 9 9 8 8 8 9 9 9

How to duplicate all inner columns of a matrix and sum pairs of columns in Matlab

Suppose I have a matrix A
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
How do I duplicate the inner columns of A to get a new matrix B
1 2 2 3 3 4 4 5
1 2 2 3 3 4 4 5
1 2 2 3 3 4 4 5
1 2 2 3 3 4 4 5
1 2 2 3 3 4 4 5
Notice the first and last column of A were left alone. Then I need to sum pairs of rows together to get another matrix C:
3 5 7 9
3 5 7 9
3 5 7 9
3 5 7 9
3 5 7 9
The size of my matrices will not always be 5x5 and the elements will not always be so nice, but the matrix will always be square.
I do not need to generate or output matrix B. That was just simply how I initially thought of obtaining my final matrix C.
My goal is to be reasonably efficient, so I would like to accomplish this without a for loop.
How do I accomplish this for arbitrary matrix size nxn ?
Very simple . .
C = A(:,2:end) + A(:,1:end-1)