cjm2671
cjm2671

Reputation: 19486

How do I generate a diagonal matrix in KDB?

I'm trying to generate a matrix such that:

I'm trying to modify the example for the identity matrix:

{x=/:x}@til 4

to squeeze in my special function:

shrinkfn: {$[x=y;1;0.5]}

but I'm struggling. What's the best way to do this?

Upvotes: 0

Views: 823

Answers (2)

SeanHehir
SeanHehir

Reputation: 1593

For the sake of variety another option is:

{0.5 1f x=/:x}til 4

This will use the boolean lists (0 or 1b) to index into our two element array and distribute the values accordingly along the matrix.

q){x=/:x}til 4
1000b
0100b
0010b
0001b
q){0.5 1f x=/:x}til 4
1   0.5 0.5 0.5
0.5 1   0.5 0.5
0.5 0.5 1   0.5
0.5 0.5 0.5 1

Upvotes: 1

C.Ross
C.Ross

Reputation: 251

q)m:{x=/:x}@til 4
q)?'[m;1;0.5]
1   0.5 0.5 0.5
0.5 1   0.5 0.5
0.5 0.5 1   0.5
0.5 0.5 0.5 1

Alternative method:

https://code.kx.com/phrases/matrix/#identity-matrix-of-order-x

q)f:{(2#x)#1f,x#.5}
q)f 5
1   0.5 0.5 0.5 0.5
0.5 1   0.5 0.5 0.5
0.5 0.5 1   0.5 0.5
0.5 0.5 0.5 1   0.5
0.5 0.5 0.5 0.5 1

Explanation:

we can use the the following notation to create a matrix:

q)3 3#til 9
0 1 2
3 4 5
6 7 8

when the list runs out of elements it repeats:

q)3 2#til 4
0 1
2 3
0 1

with 5 by 5 matrix the the next diagonal is always 6 places, thus the list is of length 6:

q)5 5#1 .5 .5 .5 .5 .5
1   0.5 0.5 0.5 0.5
0.5 1   0.5 0.5 0.5
0.5 0.5 1   0.5 0.5
0.5 0.5 0.5 1   0.5
0.5 0.5 0.5 0.5 1

Upvotes: 7

Related Questions