1

Define the Hermite Normal form $H$ for a matrix $A\in Z^{n\times n}$ as following:

$$H=UA$$ which in Mathematica is given as {u, h} = HermiteDecomposition[a]

Then for a system of homogeneous equations $Ax = [0]_{n}$ we normally compute a basis for the Nullspace of $A$, so any vector $x$ in $Ker(A)$ satisfies the system.

It results that $$Ax=[0]_{n} \rightarrow U^{-1}Hx =[0]_{n} \rightarrow Hx = [0]_{n}$$

Then computing such a basis for $A$ can be done in terms of $H$, where $H$ is an upper triangular matrix, so at first glance NullSpace runs faster for $H$ instead of $A$.

But I'm not very familiarized with the time-complexity of Mathematica's implementation of HermiteDecomposition and Nullspace (this last one over a prime modulus). I don't think this would be a good idea for big dimensions, this is, big $n$.

The thing is that I need a $\textit{fast}$ and efficient method for computing a basis for the nullspace of $A$ over $F_2$ when $n$ is considerably big. What can I do?


P.D = As a recommendation from MarcoB the time lapses are given with an example matrix of size $100\times 100$:

NullSpace only call: $0.010054$s

HermiteDecomposition + NullSpace: $0.071549$s

LatticeReduce + NullSpace: $0.258836$s

where the NullSpace call is always taken over $F_2$.

kub0x
  • 203
  • 1
  • 6
  • 2
    Well, since both functions HermiteDecomposition and Nullspace are already available, couldn't you just make up some fake number with which to try both out and compare timings (e.g. with RepeatedTiming)? – MarcoB Nov 19 '19 at 20:39
  • I thought the same on my way to home. Will post time lapses as soon as I return to my research. Thanks. – kub0x Nov 19 '19 at 21:04
  • @MarcoB: New day, new tests. Included time lapses for my method with an example squared matrix with $n=100$. When $n=2500$ it takes $1$ minute approximately to compute such a basis over $F_2$, so what can I do to optimize this procedure in Mathematica? Any alternative that I can implement and you can point me to? Thanks for your kind help. – kub0x Nov 20 '19 at 12:03
  • Thank you for running the tests. Please include the specific code and data you used in your question, so others can play around with it and chime in. – MarcoB Nov 20 '19 at 13:51
  • Why not just use NullSpace[mat,Modulus->2]? – Daniel Lichtblau Nov 20 '19 at 15:43
  • I've discarded HermiteDecomposition or LatticeReduce for the time that both take. Yes, I'm using NullSpace with the Modulus option, as I'm working over $F_2$. But for i.e $n=10000\times 10000$ doesn't even finish passed $5$ minutes on my laptop. I've seen a different approach here https://mathematica.stackexchange.com/questions/6776/space-efficient-null-space-of-sparse-array/6778#6778 based on partitioning the matrix into parts then computing separated nullspaces that finally give a vector that nullifies the matrix "mat". – kub0x Nov 20 '19 at 15:48
  • I recall that method, at least on a good day. An alternative, that can be combined with it, is to useResourceFunction["BitStringNullSpace"]. Here is the corresponding documentation page – Daniel Lichtblau Nov 20 '19 at 15:58
  • Memory is a clear boundary I forgot to mention. Now I can solve an arbitrary system witch coefficient matrix of order $10^4\times 10^4$ in $175$ seconds where finding the nullspace of a $3600\times 3600$ matrix with NullSpace over $F_2$ takes $185$ seconds. BitStringNullSpace is what I was looking for Daniel! A million thanks for mentioning it. Consider this thread solved. – kub0x Nov 20 '19 at 17:15
  • Since it is a perfectly reasonable question and it should not go for lack of an answer, I'll post a brief community wiki response. You should feel free to edit it, especially if you want to add a specific example. – Daniel Lichtblau Nov 20 '19 at 17:41

1 Answers1

2

There are at least a few ways to improve matters. First is to use

NullSpace[mat,Modulus->2]

This is still memory hungry though. There is a splitting method, useful when the row count is large, that is shown here.

Another method, which can be used in tandem with splitting, is to use bit strings to represent rows. The null space can then be extracted with ResourceFunction["BitStringNullSpace"], documentation for which is found here.

Daniel Lichtblau
  • 58,970
  • 2
  • 101
  • 199