computing the powers of a boolean matrix

How can I compute the n’th power of a square boolean matrix without using a loop? I still don’t have the hang of \ (iterate). The following code works, but it’s not very Q-ish:


/square boolean matrix x raised to the y’th power

bpp:{[x;y]

r:I count x;

do[

y;

r:bmp[r;x];

];:r}


/boolean matrix product of x and y

bmp:{[x;y]

xf:`float$x;

yf:flip `float$y;

:1=mod[mmu[xf;yf];2]}

/identity matrix with side = x

I:{

m:(x;x)#til x*x;

r:m=flip m}

given a function to generate a diagonal matrix

diag:{@[count#abs[type x]$0;;:;]'[til count x;x]}

we can build a generic function that raises a matrix to a specified power

mpow:{x mmu[;flip y]/diag count[y]#1f}

combined with a utility function to generate a random matrix

randm:{y cut (x*y)?z}

we can raise a square matrix to a given power

q)mpow[2] randm[5;5] 1f
1.460024 1.527025 0.8595752 1.234829 0.7371883
1.304621 1.878989 1.032634  1.460086 1.447466
1.485854 1.6008   1.199449  1.423057 0.9545839
1.620193 2.098549 1.112103  1.769807 1.553691
1.320887 1.296772 0.7367517 1.157716 0.8935407

we can create a customized function for boolean matrices

bmpow:{“b”$mod[;2f]mpow“f”$y}

and raise a random boolean matrix to any power

q)flip bmpow[;randm[3;3] 0b] each til 3
100b 010b 101b
010b 101b 101b
001b 111b 000b

Great stuff, Nick! diag and mpow are both very helpful.

For my purposes, a simpler bmpow suffices:

bmpow:{1=mod[mpow[x;`float$y];2]}


For example, a typical input matrix would be


1111b

1010b

1100b

1000b


and the 2nd and 3rd powers would be


0001b 1000b

0011b 0100b

0101b 0010b

1111b 0001b


-Stu


=====