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}
Nick10
January 18, 2015, 8:25am
2
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
=====