Suppose the finite field $F=GF(2^d)$ contains all $p$-th roots of unity, where $p$ is a prime and $\omega\in F$ is the principal $p$-th root of unity. Let $V=(\omega^{ij})$ be a $p\times p$ Vandermonde matrix.
Let $v:=V(I,J)$ be a submatrix of $V$ whose rows and columns are indexed by $I$ and $J$, respectively. I am interested in checking whether $v$ is singular. I am doing so by computing the determinant. The computation is performed using the FiniteFields
package.
Problem I need to test invertibility for all rows/columns subsets for a given $p$. However, it takes a lot of time to compute a single determinant.
For example, for some index-subsets rows
and cols
with length t
, the functionVandermondeDetGF[13, rows, cols]
takes 0.89 sec when t = 10, 2.31 sec when t = 11, and doesn't even terminate when t = 12. Similar things happen with other values of t
and p
: it is too slow for even double-digit p
and t
.
Questions:
- What am I doing wrong?
- What is the right way to efficiently check matrix-invertibility in finite fields? Can we do LU decomposition?
- Why is it this slow?
Thanks in advance.
Code
(* The dimension of the GF(2) extension containing q roots of unity *)
DimExtOverGF2[qRootsOfUnity_] :=
DimExtOverGF2[qRootsOfUnity] =
Block[{sol},
sol = Reduce[Mod[2^n, qRootsOfUnity] == 1, n, Integers];
Association[ToRules[sol /. {C[1] -> 1}]][n]
];
(* A single entry, v_{ij} *)
VandermondeEntryGF[gf_, power_] :=
VandermondeEntryGF[gf, power] =
FieldExp[gf, power];
(* The matrix V *)
VandermondeMatrixGF[gf_, rows_, cols_] :=
VanderMondeMatrixGF[gf, rows, cols] = Block[{size},
size = Length@disks;
Array[VandermondeEntryGF[gf, rows[[#1]] cols[[#2]]] &,
{size, size}]]
(* Compute the determinant*)
VandermondeDetGF[prime_, rows_, cols_, t_: 1] :=
VandermondeDetGF[prime, rows, cols, t] =
Block[{gf, v, dim, size},
dim = DimExtOverGF2[prime]; (* find dimension*)
gf = GF[2, dim]; (* create finite field *)
(* initialize power table *)
If[PowerListQ@gf == False,
PowerListQ[GF[2, dim]] = True];
Assert[Length@disks == Length@slants];
(* compute determinat of the Vandermonde submatrix*)
v = VanderMondeMatrixGF[gf, rows, cols];
Det[v]
];